semantifold 0.3.0 → 0.5.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 +61 -15
- package/build/index.d.ts +52 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +60 -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/android.d.ts +49 -0
- package/build/src/backends/android.d.ts.map +1 -0
- package/build/src/backends/android.js +1274 -0
- 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 +160 -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 +33 -0
- package/build/src/backends/kotlin.d.ts.map +1 -0
- package/build/src/backends/kotlin.js +138 -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 +83 -0
- package/build/src/backends/program.d.ts.map +1 -0
- package/build/src/backends/program.js +1309 -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 +2174 -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 +255 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +491 -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 +177 -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 +3108 -178
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +730 -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/android.md +79 -0
- package/docs/architecture.md +47 -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 +238 -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 +17 -7
- package/docs/specification.md +5 -0
- package/docs/standard-library-portability.md +39 -8
- package/docs/swift.md +44 -0
- package/docs/testing.md +381 -4
- package/docs/webassembly.md +52 -0
- package/index.js +66 -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/android.js +1370 -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 +166 -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 +144 -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 +1408 -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 +2314 -115
- 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 +545 -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 +182 -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 +810 -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
|
@@ -1,18 +1,40 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { semanticFailure, unsupportedCapability, unsupportedSyntax } from "../diagnostic.js";
|
|
3
|
-
import {
|
|
3
|
+
import { recordTypeSubstitutions, substituteValueType, typeContainsAnyVariable } from "./generics.js";
|
|
4
|
+
import { hasOnlyUnicodeScalars, isScalarTypeName, scalarType } from "./scalars.js";
|
|
4
5
|
import { adaptedOperationFor } from "./operators.js";
|
|
6
|
+
import { parserRangeFor } from "./provenance.js";
|
|
7
|
+
import { validateEffectGraph } from "./effects.js";
|
|
8
|
+
import { validateResourceLifetimes } from "./lifetime.js";
|
|
9
|
+
const task005Languages = new Set(["php", "ruby", "javascript", "typescript", "java", "dart"]);
|
|
10
|
+
/** @typedef {Map<string, import("./types.js").RecordDeclaration>} RecordRegistry */
|
|
11
|
+
/** @typedef {Map<string, import("./types.js").ClassDeclaration>} ClassRegistry */
|
|
12
|
+
/** @typedef {Map<string, import("./types.js").ErrorDeclaration>} ErrorRegistry */
|
|
13
|
+
/** @type {WeakMap<RecordRegistry, ClassRegistry>} */
|
|
14
|
+
const referenceClassesByRecordRegistry = new WeakMap();
|
|
15
|
+
/** @type {WeakMap<RecordRegistry, Set<string>>} */
|
|
16
|
+
const resourceIdsByRecordRegistry = new WeakMap();
|
|
5
17
|
/**
|
|
6
18
|
* @typedef Binding
|
|
7
19
|
* @property {boolean} mutable - Whether assignment is allowed.
|
|
8
|
-
* @property {import("./types.js").
|
|
20
|
+
* @property {import("./types.js").SemanticBindingType} type - Binding type.
|
|
21
|
+
* @property {import("./types.js").Expression | undefined} knownValue - Current statically known immutable value.
|
|
9
22
|
*/
|
|
10
23
|
/**
|
|
11
24
|
* @typedef Scope
|
|
12
25
|
* @property {Map<string, Binding>} bindings - Bindings declared directly in this scope.
|
|
13
26
|
* @property {Set<string>} pending - Names declared later in this scope.
|
|
27
|
+
* @property {Set<Binding>} presenceProofs - Optional bindings proven present on this path.
|
|
14
28
|
* @property {Scope | undefined} parent - Enclosing lexical scope.
|
|
29
|
+
* @property {Set<string>} typeParameters - Type parameters visible throughout the enclosing declaration.
|
|
15
30
|
* @property {Set<string>} usedNames - All names used by the enclosing function or entry point.
|
|
31
|
+
* @property {import("./types.js").ClassDeclaration | undefined} currentClass - Declaring class for receiver-private access.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* @typedef LoopFlowContext
|
|
35
|
+
* @property {import("./types.js").ForEachStatement | import("./types.js").ForEachMapStatement | import("./types.js").WhileStatement} [nearest] - Nearest active loop.
|
|
36
|
+
* @property {object} owner - Enclosing function or entry-point identity.
|
|
37
|
+
* @property {Map<string, object>} owners - Loop owner by module-local loop identity.
|
|
16
38
|
*/
|
|
17
39
|
/**
|
|
18
40
|
* @typedef SemanticFail
|
|
@@ -22,31 +44,89 @@ import { adaptedOperationFor } from "./operators.js";
|
|
|
22
44
|
* Enforces the coherent release-candidate semantic subset after adaptation.
|
|
23
45
|
* @param {import("./types.js").SemanticModule} module - Adapted semantic module.
|
|
24
46
|
* @param {import("./types.js").SemanticLanguage} language - Source language.
|
|
47
|
+
* @param {{classes?: Map<string, import("./types.js").ClassDeclaration>, functions?: Map<string, import("./types.js").FunctionDeclaration>, records?: Map<string, import("./types.js").RecordDeclaration>, errors?: Map<string, import("./types.js").ErrorDeclaration>, callEffects?: Map<string, Set<string>>}} [visible] - Program imports visible during validation.
|
|
25
48
|
* @returns {import("./types.js").SemanticModule} Validated module.
|
|
26
49
|
*/
|
|
27
|
-
export function validateParsedModule(module, language) {
|
|
28
|
-
|
|
29
|
-
|
|
50
|
+
export function validateParsedModule(module, language, visible = {}) {
|
|
51
|
+
normalizeParsedOwnedReferences(module, visible.classes);
|
|
52
|
+
validateModuleShape(module, language, (detail, location) => unsupportedSyntax(language, detail, location));
|
|
53
|
+
/**
|
|
54
|
+
* Converts one parser failure into a located semantic diagnostic.
|
|
55
|
+
* @type {SemanticFail}
|
|
56
|
+
*/
|
|
57
|
+
const fail = (code, detail, location) => semanticFailure(language, code, detail, location);
|
|
58
|
+
validateModuleTypes(module, language, fail, true, visible);
|
|
59
|
+
validateResourceLifetimes(module, inferEscapingErrorEffects(module, visible.callEffects), fail);
|
|
30
60
|
return module;
|
|
31
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Promotes parser-authored class spellings after all private field types are known.
|
|
64
|
+
* @param {import("./types.js").SemanticModule} module - Parser-authored module.
|
|
65
|
+
* @param {Map<string, import("./types.js").ClassDeclaration>} [visibleClasses] - Imported reference classes.
|
|
66
|
+
* @returns {void}
|
|
67
|
+
*/
|
|
68
|
+
function normalizeParsedOwnedReferences(module, visibleClasses = new Map()) {
|
|
69
|
+
const ownedClassIds = new Set([...visibleClasses.values()].filter(({ ownership }) => ownership?.kind == "ownedResource")
|
|
70
|
+
.map(({ id }) => /** @type {string} */ (id)));
|
|
71
|
+
for (const declaration of module.classes ?? []) {
|
|
72
|
+
const fields = declaration.fields.filter(({ type }) => type?.kind == "OwnedResourceType");
|
|
73
|
+
if (fields.length != 1)
|
|
74
|
+
continue;
|
|
75
|
+
const field = /** @type {import("./types.js").PrivateField & {type: import("./types.js").OwnedResourceType}} */ (fields[0]);
|
|
76
|
+
declaration.ownership = { fieldId: /** @type {string} */ (field.id), kind: "ownedResource", resourceId: field.type.resourceId };
|
|
77
|
+
ownedClassIds.add(/** @type {string} */ (declaration.id));
|
|
78
|
+
}
|
|
79
|
+
/** @type {unknown[]} */
|
|
80
|
+
const pending = [module];
|
|
81
|
+
/** @type {Set<object>} */
|
|
82
|
+
const seen = new Set();
|
|
83
|
+
while (pending.length > 0) {
|
|
84
|
+
const value = pending.pop();
|
|
85
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
86
|
+
continue;
|
|
87
|
+
seen.add(value);
|
|
88
|
+
if (!Array.isArray(value) && Reflect.get(value, "kind") == "ReferenceType" &&
|
|
89
|
+
ownedClassIds.has(Reflect.get(value, "declarationId")))
|
|
90
|
+
Reflect.set(value, "kind", "OwnedReferenceType");
|
|
91
|
+
for (const [key, child] of Object.entries(value)) {
|
|
92
|
+
if (["location", "sourceProvenance"].includes(key))
|
|
93
|
+
continue;
|
|
94
|
+
if (child && typeof child == "object")
|
|
95
|
+
pending.push(child);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
32
99
|
/**
|
|
33
100
|
* Validates scalar types and bindings for a caller-supplied semantic module before emission.
|
|
34
101
|
* @param {import("./types.js").SemanticModule} module - Semantic module.
|
|
35
|
-
* @param {import("./types.js").
|
|
102
|
+
* @param {import("./types.js").BackendLanguage} language - Backend language or binary target.
|
|
103
|
+
* @param {{classes?: Map<string, import("./types.js").ClassDeclaration>, functions?: Map<string, import("./types.js").FunctionDeclaration>, records?: Map<string, import("./types.js").RecordDeclaration>, errors?: Map<string, import("./types.js").ErrorDeclaration>, callEffects?: Map<string, Set<string>>}} [visible] - Resolved program imports.
|
|
36
104
|
* @returns {void}
|
|
37
105
|
*/
|
|
38
|
-
export function validateBackendTypes(module, language) {
|
|
39
|
-
|
|
106
|
+
export function validateBackendTypes(module, language, visible = {}) {
|
|
107
|
+
/**
|
|
108
|
+
* Converts one backend validation failure into an unsupported-capability diagnostic.
|
|
109
|
+
* @type {SemanticFail}
|
|
110
|
+
*/
|
|
111
|
+
const fail = (_code, detail, location) => unsupportedCapability(language, detail, location);
|
|
112
|
+
validateModuleTypes(module, language, fail, false, visible);
|
|
113
|
+
validateResourceLifetimes(module, inferEscapingErrorEffects(module, visible.callEffects), fail);
|
|
40
114
|
}
|
|
41
115
|
/**
|
|
42
116
|
* Checks parser-authored block and statement layouts before semantic validation.
|
|
43
117
|
* @param {import("./types.js").SemanticModule} module - Semantic module.
|
|
118
|
+
* @param {import("./types.js").SemanticLanguage} language - Source language.
|
|
44
119
|
* @param {(detail: string, location: import("./types.js").SourceLocation) => never} fail - Shape failure.
|
|
45
120
|
* @returns {void}
|
|
46
121
|
*/
|
|
47
|
-
function validateModuleShape(module, fail) {
|
|
122
|
+
function validateModuleShape(module, language, fail) {
|
|
123
|
+
for (const declaration of module.classes ?? []) {
|
|
124
|
+
validateBlockShape(declaration.constructor?.body, "constructor body", fail);
|
|
125
|
+
for (const method of declaration.methods ?? [])
|
|
126
|
+
validateBlockShape(method.body, "method body", fail);
|
|
127
|
+
}
|
|
48
128
|
for (const functionDeclaration of module.functions) {
|
|
49
|
-
if (functionDeclaration.parameters.length != 2) {
|
|
129
|
+
if (!task005Languages.has(language) && functionDeclaration.parameters.length != 2) {
|
|
50
130
|
fail("function parameter count other than two", functionDeclaration.location);
|
|
51
131
|
}
|
|
52
132
|
validateBlockShape(functionDeclaration.body, "function body", fail);
|
|
@@ -65,7 +145,7 @@ function validateBlockShape(block, detail, fail) {
|
|
|
65
145
|
fail(`${detail} without Block`, block?.location ?? /** @type {never} */ (undefined));
|
|
66
146
|
}
|
|
67
147
|
for (const statement of block.statements) {
|
|
68
|
-
if (!["AssignmentStatement", "IfStatement", "LocalDeclaration", "PrintStatement", "ReturnStatement"].includes(statement.kind)) {
|
|
148
|
+
if (!["AssignmentStatement", "BreakStatement", "ContinueStatement", "ExpressionStatement", "ForEachMapStatement", "ForEachStatement", "IfStatement", "LocalDeclaration", "PrivateFieldWriteStatement", "PrintStatement", "RaiseStatement", "ReturnStatement", "TryStatement", "WhileStatement"].includes(statement.kind)) {
|
|
69
149
|
fail(`${detail} statement ${statement.kind}`, statement.location);
|
|
70
150
|
}
|
|
71
151
|
if (statement.kind == "IfStatement") {
|
|
@@ -73,130 +153,1124 @@ function validateBlockShape(block, detail, fail) {
|
|
|
73
153
|
if (statement.alternate)
|
|
74
154
|
validateBlockShape(statement.alternate, "if alternate", fail);
|
|
75
155
|
}
|
|
156
|
+
if (statement.kind == "ForEachStatement" || statement.kind == "ForEachMapStatement" || statement.kind == "WhileStatement") {
|
|
157
|
+
validateBlockShape(statement.body, "loop body", fail);
|
|
158
|
+
}
|
|
159
|
+
if (statement.kind == "TryStatement") {
|
|
160
|
+
validateBlockShape(statement.body, "try body", fail);
|
|
161
|
+
validateBlockShape(statement.catchBody, "catch body", fail);
|
|
162
|
+
}
|
|
76
163
|
}
|
|
77
164
|
}
|
|
78
165
|
/**
|
|
79
166
|
* Validates declarations and expression types within lexical scopes.
|
|
80
167
|
* @param {import("./types.js").SemanticModule} module - Semantic module.
|
|
168
|
+
* @param {string} language - Source or backend language identity.
|
|
81
169
|
* @param {SemanticFail} fail - Diagnostic callback.
|
|
82
170
|
* @param {boolean} normalizeOperations - Whether to replace transient frontend operation intent.
|
|
171
|
+
* @param {{classes?: Map<string, import("./types.js").ClassDeclaration>, functions?: Map<string, import("./types.js").FunctionDeclaration>, records?: Map<string, import("./types.js").RecordDeclaration>, errors?: Map<string, import("./types.js").ErrorDeclaration>, callEffects?: Map<string, Set<string>>}} [visible] - Program imports visible during validation.
|
|
83
172
|
* @returns {void}
|
|
84
173
|
*/
|
|
85
|
-
function validateModuleTypes(module, fail, normalizeOperations) {
|
|
174
|
+
function validateModuleTypes(module, language, fail, normalizeOperations, visible = {}) {
|
|
175
|
+
const classes = registerClassDeclarations(module.classes ?? [], fail, normalizeOperations, visible.classes);
|
|
176
|
+
const records = validateRecordDeclarations(module.records ?? [], fail, normalizeOperations, visible.records, classes);
|
|
177
|
+
const errors = validateErrorDeclarations(module.errors ?? [], fail, normalizeOperations, visible.errors);
|
|
86
178
|
/** @type {Map<string, import("./types.js").FunctionDeclaration>} */
|
|
87
|
-
const functions = new Map();
|
|
88
|
-
|
|
179
|
+
const functions = new Map(visible.functions ?? []);
|
|
180
|
+
const declarationIds = new Set([...functions.values()].flatMap(({ id }) => typeof id == "string" ? [id] : []));
|
|
181
|
+
for (const [index, functionDeclaration] of module.functions.entries()) {
|
|
182
|
+
if (normalizeOperations)
|
|
183
|
+
functionDeclaration.id = `function:${index}`;
|
|
184
|
+
if (typeof functionDeclaration.id != "string" || !/^(?:[a-z][a-z0-9._-]*#)?function:[0-9]+$/u.test(functionDeclaration.id) ||
|
|
185
|
+
declarationIds.has(functionDeclaration.id)) {
|
|
186
|
+
fail("DUPLICATE_BINDING", "Duplicate or invalid function declaration identity.", functionDeclaration.location);
|
|
187
|
+
}
|
|
89
188
|
if (functions.has(functionDeclaration.name)) {
|
|
90
|
-
fail("DUPLICATE_BINDING", `duplicate function '${functionDeclaration.name}'.`, functionDeclaration
|
|
189
|
+
fail("DUPLICATE_BINDING", `duplicate function '${functionDeclaration.name}'.`, roleLocation(functionDeclaration, "name"));
|
|
91
190
|
}
|
|
191
|
+
declarationIds.add(functionDeclaration.id);
|
|
192
|
+
validateTypeParameters(functionDeclaration, fail, normalizeOperations);
|
|
92
193
|
functions.set(functionDeclaration.name, functionDeclaration);
|
|
93
194
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
195
|
+
validateEffectGraph(module, language, functions, fail, normalizeOperations, classes);
|
|
196
|
+
const capabilityResources = (module.capabilities ?? []).flatMap(({ resources }) => resources);
|
|
197
|
+
const capabilityFailures = (module.capabilities ?? []).flatMap(({ failures }) => failures);
|
|
198
|
+
resourceIdsByRecordRegistry.set(records, new Set(capabilityResources.map(({ id }) => id)));
|
|
199
|
+
const existingErrorNames = new Set([...errors.values()].map(({ name }) => name));
|
|
200
|
+
for (const failure of capabilityFailures) {
|
|
201
|
+
if (errors.has(failure.id) || existingErrorNames.has(failure.name)) {
|
|
202
|
+
fail("DUPLICATE_ERROR", `Duplicate capability failure '${failure.name}'.`, module.location);
|
|
203
|
+
}
|
|
204
|
+
errors.set(failure.id, /** @type {import("./types.js").ErrorDeclaration} */ ( /** @type {unknown} */(failure)));
|
|
205
|
+
existingErrorNames.add(failure.name);
|
|
206
|
+
}
|
|
207
|
+
const loopOwners = prepareLoopIdentities(module, normalizeOperations, fail);
|
|
208
|
+
const reservedValueNames = new Set([
|
|
209
|
+
...functions.keys(),
|
|
210
|
+
...[...records.values()].map((declaration) => declaration.name),
|
|
211
|
+
...[...classes.values()].map((declaration) => declaration.name),
|
|
212
|
+
...[...errors.values()].map((declaration) => declaration.name),
|
|
213
|
+
...capabilityResources.map(({ name }) => name)
|
|
214
|
+
]);
|
|
215
|
+
const nominalNames = new Set();
|
|
216
|
+
for (const declaration of [...module.records ?? [], ...module.classes ?? [], ...module.errors ?? []]) {
|
|
217
|
+
if (nominalNames.has(declaration.name)) {
|
|
218
|
+
fail("DUPLICATE_BINDING", `Duplicate nominal declaration '${declaration.name}'.`, roleLocation(declaration, "name"));
|
|
219
|
+
}
|
|
220
|
+
nominalNames.add(declaration.name);
|
|
221
|
+
}
|
|
222
|
+
for (const declaration of [...capabilityResources, ...capabilityFailures]) {
|
|
223
|
+
if (nominalNames.has(declaration.name)) {
|
|
224
|
+
fail("DUPLICATE_BINDING", `Duplicate nominal declaration '${declaration.name}'.`, module.location);
|
|
225
|
+
}
|
|
226
|
+
nominalNames.add(declaration.name);
|
|
227
|
+
}
|
|
228
|
+
const localFunctionNames = new Set(module.functions.map(({ name }) => name));
|
|
229
|
+
const callEffects = inferCallEffects(functions, visible.callEffects, localFunctionNames);
|
|
230
|
+
for (const declaration of module.classes ?? []) {
|
|
231
|
+
validateClassDeclaration(declaration, functions, records, errors, callEffects, reservedValueNames, fail, normalizeOperations, loopOwners);
|
|
232
|
+
}
|
|
233
|
+
for (const functionDeclaration of module.functions) {
|
|
234
|
+
validateFunction(functionDeclaration, functions, records, errors, callEffects, reservedValueNames, fail, normalizeOperations, loopOwners);
|
|
235
|
+
}
|
|
236
|
+
const entryScope = createScope(undefined, module.entryPoint.body.statements, reservedValueNames);
|
|
237
|
+
validateBlock(module.entryPoint.body, entryScope, undefined, functions, records, errors, callEffects, fail, normalizeOperations, { owner: module.entryPoint, owners: loopOwners });
|
|
238
|
+
if (normalizeOperations)
|
|
239
|
+
validateEffectGraph(module, language, functions, fail, true, classes);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Assigns parser-authored loop/control identities and validates caller-owned identities without crossing a function boundary.
|
|
243
|
+
* @param {import("./types.js").SemanticModule} module - Semantic module.
|
|
244
|
+
* @param {boolean} normalizeOperations - Whether parser-authored identities are assigned.
|
|
245
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
246
|
+
* @returns {Map<string, object>} Loop owner by identity.
|
|
247
|
+
*/
|
|
248
|
+
function prepareLoopIdentities(module, normalizeOperations, fail) {
|
|
249
|
+
const owners = new Map();
|
|
250
|
+
let nextLoop = 0;
|
|
251
|
+
const classOwners = (module.classes ?? []).flatMap((declaration) => [declaration.constructor, ...declaration.methods]);
|
|
252
|
+
for (const owner of [...classOwners, ...module.functions, module.entryPoint])
|
|
253
|
+
visit(owner.body, owner, []);
|
|
254
|
+
return owners;
|
|
255
|
+
/**
|
|
256
|
+
* Visits one block in lexical semantic order.
|
|
257
|
+
* @param {import("./types.js").Block} block - Candidate block.
|
|
258
|
+
* @param {object} owner - Enclosing function or entry point.
|
|
259
|
+
* @param {(import("./types.js").ForEachStatement | import("./types.js").ForEachMapStatement | import("./types.js").WhileStatement)[]} active - Active loops.
|
|
260
|
+
* @returns {void}
|
|
261
|
+
*/
|
|
262
|
+
function visit(block, owner, active) {
|
|
263
|
+
if (!block || !Array.isArray(block.statements))
|
|
264
|
+
return;
|
|
265
|
+
for (const statement of block.statements) {
|
|
266
|
+
if (!statement || typeof statement != "object")
|
|
267
|
+
continue;
|
|
268
|
+
if (["ForEachStatement", "ForEachMapStatement", "WhileStatement"].includes(statement.kind)) {
|
|
269
|
+
const loop = /** @type {import("./types.js").ForEachStatement | import("./types.js").ForEachMapStatement | import("./types.js").WhileStatement} */ (statement);
|
|
270
|
+
if (normalizeOperations)
|
|
271
|
+
loop.id = `loop:${nextLoop}`;
|
|
272
|
+
nextLoop += 1;
|
|
273
|
+
if (typeof loop.id != "string" || !/^loop:[0-9]+$/u.test(loop.id) || owners.has(loop.id)) {
|
|
274
|
+
fail("INVALID_LOOP_TARGET", "Duplicate or invalid loop identity.", loop.location);
|
|
275
|
+
}
|
|
276
|
+
owners.set(loop.id, owner);
|
|
277
|
+
visit(loop.body, owner, [...active, loop]);
|
|
278
|
+
}
|
|
279
|
+
else if (statement.kind == "BreakStatement" || statement.kind == "ContinueStatement") {
|
|
280
|
+
if (normalizeOperations && active.length > 0)
|
|
281
|
+
statement.targetLoopId = /** @type {string} */ (active.at(-1)?.id);
|
|
282
|
+
}
|
|
283
|
+
else if (statement.kind == "IfStatement") {
|
|
284
|
+
visit(statement.consequent, owner, active);
|
|
285
|
+
if (statement.alternate)
|
|
286
|
+
visit(statement.alternate, owner, active);
|
|
287
|
+
}
|
|
288
|
+
else if (statement.kind == "TryStatement") {
|
|
289
|
+
visit(statement.body, owner, active);
|
|
290
|
+
visit(statement.catchBody, owner, active);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Derives validator-only unchecked-error effects for a validated module's local functions.
|
|
297
|
+
* These effects never enter semantic function declarations or public signatures.
|
|
298
|
+
* @param {import("./types.js").SemanticModule} module - Validated semantic module.
|
|
299
|
+
* @param {{functions?: Map<string, import("./types.js").FunctionDeclaration>, callEffects?: Map<string, Set<string>>}} [visible] - Imported functions and already-resolved effects by local binding.
|
|
300
|
+
* @returns {Map<string, Set<string>>} Local function effects by source-visible name.
|
|
301
|
+
*/
|
|
302
|
+
export function moduleUncheckedErrorEffects(module, visible = {}) {
|
|
303
|
+
const functions = new Map(visible.functions ?? []);
|
|
304
|
+
for (const declaration of module.functions)
|
|
305
|
+
functions.set(declaration.name, declaration);
|
|
306
|
+
const localFunctionNames = new Set(module.functions.map(({ name }) => name));
|
|
307
|
+
const effects = inferCallEffects(functions, visible.callEffects, localFunctionNames);
|
|
308
|
+
return new Map(module.functions.map((declaration) => [declaration.name, new Set(effects.get(declaration.name) ?? [])]));
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Assigns and validates the closed nominal identities owned by reference classes.
|
|
312
|
+
* @param {unknown} declarations - Candidate declarations.
|
|
313
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
314
|
+
* @param {boolean} normalizeOperations - Whether parser-authored identities are assigned.
|
|
315
|
+
* @param {Map<string, import("./types.js").ClassDeclaration>} [visibleClasses] - Imported classes by identity.
|
|
316
|
+
* @returns {ClassRegistry} Classes by stable identity.
|
|
317
|
+
*/
|
|
318
|
+
function registerClassDeclarations(declarations, fail, normalizeOperations, visibleClasses = new Map()) {
|
|
319
|
+
if (!Array.isArray(declarations)) {
|
|
320
|
+
return fail("TYPE_MISMATCH", "Reference class declarations must be an ordered array.", /** @type {never} */ (undefined));
|
|
321
|
+
}
|
|
322
|
+
/** @type {ClassRegistry} */
|
|
323
|
+
const classes = new Map(visibleClasses);
|
|
324
|
+
const names = new Set([...visibleClasses.values()].map(({ name }) => name));
|
|
325
|
+
for (let classIndex = 0; classIndex < declarations.length; classIndex += 1) {
|
|
326
|
+
const declaration = /** @type {import("./types.js").ClassDeclaration} */ (declarations[classIndex]);
|
|
327
|
+
if (!declaration || declaration.kind != "ClassDeclaration" || !Array.isArray(declaration.fields) ||
|
|
328
|
+
!Array.isArray(declaration.methods) || !declaration.constructor || declaration.constructor.kind != "ConstructorDeclaration") {
|
|
329
|
+
return fail("DUPLICATE_CLASS", "Malformed or invalid reference class declaration.", declaration?.location);
|
|
330
|
+
}
|
|
331
|
+
if (declaration.fields.length == 0) {
|
|
332
|
+
fail("INCOMPLETE_INITIALIZATION", "Reference classes must declare private instance state.", declaration.location);
|
|
333
|
+
}
|
|
334
|
+
if (normalizeOperations)
|
|
335
|
+
declaration.id = `class:${classIndex}`;
|
|
336
|
+
if (typeof declaration.id != "string" || !/^(?:[a-z][a-z0-9._-]*#)?class:[0-9]+$/u.test(declaration.id) ||
|
|
337
|
+
classes.has(declaration.id) || typeof declaration.name != "string" || declaration.name.length == 0 || names.has(declaration.name)) {
|
|
338
|
+
fail("DUPLICATE_CLASS", `Duplicate or invalid reference class '${String(declaration.name)}'.`, roleLocation(declaration, "name"));
|
|
339
|
+
}
|
|
340
|
+
names.add(declaration.name);
|
|
341
|
+
classes.set(declaration.id, declaration);
|
|
342
|
+
const fieldNames = new Set();
|
|
343
|
+
for (let fieldIndex = 0; fieldIndex < declaration.fields.length; fieldIndex += 1) {
|
|
344
|
+
const field = declaration.fields[fieldIndex];
|
|
345
|
+
const expectedId = `${declaration.id}:field:${fieldIndex}`;
|
|
346
|
+
if (!field || field.kind != "PrivateField") {
|
|
347
|
+
fail("DUPLICATE_PRIVATE_FIELD", "Malformed or invalid private field.", field?.location ?? declaration.location);
|
|
348
|
+
}
|
|
349
|
+
if (normalizeOperations)
|
|
350
|
+
field.id = expectedId;
|
|
351
|
+
if (field.id != expectedId || typeof field.name != "string" || field.name.length == 0 || fieldNames.has(field.name)) {
|
|
352
|
+
fail("DUPLICATE_PRIVATE_FIELD", `Duplicate or invalid private field '${String(field.name)}'.`, roleLocation(field, "name"));
|
|
353
|
+
}
|
|
354
|
+
fieldNames.add(field.name);
|
|
355
|
+
}
|
|
356
|
+
const invalidOwnedField = declaration.fields.find(({ type }) => containsOwnedType(type) && type.kind != "OwnedResourceType");
|
|
357
|
+
if (invalidOwnedField) {
|
|
358
|
+
fail("RESOURCE_ALIAS", `Class '${declaration.name}' may contain ownership only in one direct resource field.`, invalidOwnedField.location);
|
|
359
|
+
}
|
|
360
|
+
const ownedFields = declaration.fields.filter(({ type }) => type?.kind == "OwnedResourceType");
|
|
361
|
+
if (ownedFields.length > 1) {
|
|
362
|
+
fail("RESOURCE_ALIAS", `Class '${declaration.name}' may own exactly one direct resource field.`, declaration.location);
|
|
363
|
+
}
|
|
364
|
+
if (ownedFields.length == 1) {
|
|
365
|
+
const field = /** @type {import("./types.js").PrivateField & {type: import("./types.js").OwnedResourceType}} */ (ownedFields[0]);
|
|
366
|
+
const expected = { fieldId: /** @type {string} */ (field.id), kind: /** @type {const} */ ("ownedResource"),
|
|
367
|
+
resourceId: field.type.resourceId };
|
|
368
|
+
if (normalizeOperations)
|
|
369
|
+
declaration.ownership = expected;
|
|
370
|
+
else if (JSON.stringify(declaration.ownership) != JSON.stringify(expected)) {
|
|
371
|
+
fail("RESOURCE_TYPE_MISMATCH", `Class '${declaration.name}' has malformed resource ownership metadata.`, declaration.location);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
else if (declaration.ownership?.kind == "ownedResource") {
|
|
375
|
+
fail("RESOURCE_TYPE_MISMATCH", `Class '${declaration.name}' does not contain its declared resource field.`, declaration.location);
|
|
376
|
+
}
|
|
377
|
+
const constructorId = `${declaration.id}:constructor`;
|
|
378
|
+
if (normalizeOperations)
|
|
379
|
+
declaration.constructor.id = constructorId;
|
|
380
|
+
if (declaration.constructor.id != constructorId || !Array.isArray(declaration.constructor.parameters) ||
|
|
381
|
+
!declaration.constructor.body || declaration.constructor.body.kind != "Block") {
|
|
382
|
+
fail("DUPLICATE_CONSTRUCTOR", "Malformed or invalid constructor declaration.", declaration.constructor.location);
|
|
383
|
+
}
|
|
384
|
+
const methodNames = new Set();
|
|
385
|
+
for (let methodIndex = 0; methodIndex < declaration.methods.length; methodIndex += 1) {
|
|
386
|
+
const method = declaration.methods[methodIndex];
|
|
387
|
+
const expectedId = `${declaration.id}:method:${methodIndex}`;
|
|
388
|
+
if (!method || method.kind != "MethodDeclaration") {
|
|
389
|
+
fail("DUPLICATE_METHOD", "Malformed or invalid method declaration.", method?.location ?? declaration.location);
|
|
390
|
+
}
|
|
391
|
+
if (normalizeOperations)
|
|
392
|
+
method.id = expectedId;
|
|
393
|
+
if (method.id != expectedId || typeof method.name != "string" || method.name.length == 0 || methodNames.has(method.name) ||
|
|
394
|
+
!Array.isArray(method.parameters) || !method.body || method.body.kind != "Block") {
|
|
395
|
+
fail("DUPLICATE_METHOD", `Duplicate or invalid method '${String(method.name)}'.`, roleLocation(method, "name"));
|
|
396
|
+
}
|
|
397
|
+
methodNames.add(method.name);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return classes;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Validates exact construction, private state, and method bodies for one class.
|
|
404
|
+
* @param {import("./types.js").ClassDeclaration} declaration - Class declaration.
|
|
405
|
+
* @param {Map<string, import("./types.js").FunctionDeclaration>} functions - Function signatures.
|
|
406
|
+
* @param {RecordRegistry} records - Record and reference-class registries.
|
|
407
|
+
* @param {ErrorRegistry} errors - Error declarations.
|
|
408
|
+
* @param {Map<string, Set<string>>} callEffects - Function call effects.
|
|
409
|
+
* @param {Set<string>} reservedValueNames - Module-reserved names.
|
|
410
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
411
|
+
* @param {boolean} normalizeOperations - Whether parser-authored resolutions are assigned.
|
|
412
|
+
* @param {Map<string, object>} loopOwners - Loop ownership registry.
|
|
413
|
+
* @returns {void}
|
|
414
|
+
*/
|
|
415
|
+
function validateClassDeclaration(declaration, functions, records, errors, callEffects, reservedValueNames, fail, normalizeOperations, loopOwners) {
|
|
416
|
+
for (const field of declaration.fields) {
|
|
417
|
+
validateValueTypeReference(field.type, field.location, fail, undefined, records);
|
|
418
|
+
}
|
|
419
|
+
const constructor = declaration.constructor;
|
|
420
|
+
const acquisitionStatement = constructor.body.statements[0];
|
|
421
|
+
const acquisitionExpression = acquisitionStatement?.kind == "PrivateFieldWriteStatement"
|
|
422
|
+
? acquisitionStatement.expression : undefined;
|
|
423
|
+
const ownedAcquisition = declaration.ownership?.kind == "ownedResource" && declaration.fields.length == 1 &&
|
|
424
|
+
constructor.body.statements.length == 1 && acquisitionStatement?.kind == "PrivateFieldWriteStatement" &&
|
|
425
|
+
acquisitionStatement.field == declaration.ownership.fieldId && acquisitionStatement.receiver.kind == "ReceiverExpression" &&
|
|
426
|
+
acquisitionStatement.receiver.classId == declaration.id && acquisitionExpression?.kind == "EffectCallExpression" &&
|
|
427
|
+
acquisitionExpression.resolution.resourceFlow.kind == "acquire" &&
|
|
428
|
+
acquisitionExpression.resolution.resourceFlow.resourceId == declaration.ownership.resourceId;
|
|
429
|
+
if (syntacticBlockEffects(constructor.body, callEffects).size > 0 && !ownedAcquisition) {
|
|
430
|
+
fail("UNSUPPORTED_STATEMENT", "Reference constructors cannot expose unchecked-error effects in Task 033.", constructor.location);
|
|
431
|
+
}
|
|
432
|
+
if (!ownedAcquisition &&
|
|
433
|
+
(constructor.parameters.length != declaration.fields.length || constructor.body.statements.length != declaration.fields.length)) {
|
|
434
|
+
fail("INCOMPLETE_INITIALIZATION", `Constructor for '${declaration.name}' must initialize every private field exactly once in declaration order.`, constructor.location);
|
|
435
|
+
}
|
|
436
|
+
const constructorScope = createScope(undefined, constructor.body.statements, reservedValueNames, new Set(), declaration);
|
|
437
|
+
for (let index = 0; index < constructor.parameters.length; index += 1) {
|
|
438
|
+
const parameter = constructor.parameters[index];
|
|
439
|
+
const field = declaration.fields[index];
|
|
440
|
+
const type = validateValueTypeReference(parameter.type, parameter.location, fail, undefined, records);
|
|
441
|
+
if (!ownedAcquisition && !sameType(type, field.type)) {
|
|
442
|
+
fail("TYPE_MISMATCH", `Constructor parameter '${parameter.name}' must exactly match private field '${field.name}'.`, parameter.location);
|
|
443
|
+
}
|
|
444
|
+
declareBinding(parameter.name, { knownValue: undefined, mutable: false, type }, roleLocation(parameter, "name"), constructorScope, fail);
|
|
445
|
+
if (ownedAcquisition)
|
|
446
|
+
continue;
|
|
447
|
+
const statement = constructor.body.statements[index];
|
|
448
|
+
const initializer = statement?.kind == "PrivateFieldWriteStatement"
|
|
449
|
+
? statement.expression.kind == "OwnedMoveExpression" ? statement.expression.expression : statement.expression
|
|
450
|
+
: undefined;
|
|
451
|
+
if (!statement || statement.kind != "PrivateFieldWriteStatement" || statement.field != field.id ||
|
|
452
|
+
statement.receiver?.kind != "ReceiverExpression" || statement.receiver.classId != declaration.id ||
|
|
453
|
+
initializer?.kind != "IdentifierExpression" || initializer.name != parameter.name) {
|
|
454
|
+
fail("INCOMPLETE_INITIALIZATION", `Constructor for '${declaration.name}' must initialize '${field.name}' from its corresponding parameter.`, statement?.location ?? constructor.location);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
validateBlock(constructor.body, constructorScope, { kind: "TypeReference", name: "void" }, functions, records, errors, callEffects, fail, normalizeOperations, { owner: constructor, owners: loopOwners });
|
|
458
|
+
for (const method of declaration.methods) {
|
|
459
|
+
const unsupportedMethodEffects = [...syntacticBlockEffects(method.body, callEffects)]
|
|
460
|
+
.filter((id) => !/^(?:module:[0-9]+\/)?capability:[0-9]+\/failure:[0-9]+$/u.test(id));
|
|
461
|
+
if (declaration.ownership?.kind != "ownedResource" && unsupportedMethodEffects.length > 0) {
|
|
462
|
+
fail("UNSUPPORTED_STATEMENT", `Reference method '${method.name}' cannot expose unchecked-error effects in Task 033.`, method.location);
|
|
463
|
+
}
|
|
464
|
+
const scope = createScope(undefined, method.body.statements, reservedValueNames, new Set(), declaration);
|
|
465
|
+
for (const parameter of method.parameters) {
|
|
466
|
+
const type = validateValueTypeReference(parameter.type, parameter.location, fail, undefined, records);
|
|
467
|
+
declareBinding(parameter.name, { knownValue: undefined, mutable: false, type }, roleLocation(parameter, "name"), scope, fail);
|
|
468
|
+
}
|
|
469
|
+
const returnType = validateReturnTypeReference(method.returnType, method.location, fail, records);
|
|
470
|
+
const flow = validateBlock(method.body, scope, returnType, functions, records, errors, callEffects, fail, normalizeOperations, { owner: method, owners: loopOwners });
|
|
471
|
+
if (declaration.ownership?.kind == "ownedResource")
|
|
472
|
+
ownedMethodResourceFlow(declaration, method, fail);
|
|
473
|
+
if (!isVoidType(returnType) && flow.normal) {
|
|
474
|
+
fail("MISSING_RETURN", `Method '${method.name}' does not return on every reachable path.`, method.location);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Validates nominal unchecked-error declarations.
|
|
480
|
+
* @param {unknown} declarations - Candidate declarations.
|
|
481
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
482
|
+
* @param {boolean} normalizeOperations - Whether parser-authored identities are assigned.
|
|
483
|
+
* @param {Map<string, import("./types.js").ErrorDeclaration>} [visibleErrors] - Imported error declarations by identity.
|
|
484
|
+
* @returns {ErrorRegistry} Validated declarations by identity.
|
|
485
|
+
*/
|
|
486
|
+
function validateErrorDeclarations(declarations, fail, normalizeOperations, visibleErrors = new Map()) {
|
|
487
|
+
if (!Array.isArray(declarations))
|
|
488
|
+
return fail("TYPE_MISMATCH", "Error declarations must be an ordered array.", /** @type {never} */ (undefined));
|
|
489
|
+
/** @type {ErrorRegistry} */
|
|
490
|
+
const errors = new Map(visibleErrors);
|
|
491
|
+
const names = new Set();
|
|
492
|
+
for (let index = 0; index < declarations.length; index += 1) {
|
|
493
|
+
const declaration = declarations[index];
|
|
494
|
+
if (!declaration || declaration.kind != "ErrorDeclaration") {
|
|
495
|
+
return fail("TYPE_MISMATCH", "Malformed error declaration.", declaration?.location);
|
|
496
|
+
}
|
|
497
|
+
if (normalizeOperations)
|
|
498
|
+
declaration.id = `error:${index}`;
|
|
499
|
+
if (typeof declaration.id != "string" || !/^(?:[a-z][a-z0-9._-]*#)?error:[0-9]+$/u.test(declaration.id) || errors.has(declaration.id)) {
|
|
500
|
+
fail("DUPLICATE_ERROR", "Duplicate or invalid error declaration identity.", declaration.location);
|
|
501
|
+
}
|
|
502
|
+
if (typeof declaration.name != "string" || names.has(declaration.name)) {
|
|
503
|
+
fail("DUPLICATE_ERROR", `Duplicate or invalid error '${String(declaration.name)}'.`, roleLocation(declaration, "name"));
|
|
504
|
+
}
|
|
505
|
+
names.add(declaration.name);
|
|
506
|
+
errors.set(declaration.id, declaration);
|
|
507
|
+
}
|
|
508
|
+
return errors;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Assigns and validates one declaration's invariant unbounded type parameters.
|
|
512
|
+
* @param {import("./types.js").FunctionDeclaration | import("./types.js").RecordDeclaration} declaration - Owning declaration.
|
|
513
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
514
|
+
* @param {boolean} normalizeOperations - Whether parser-authored identities are assigned.
|
|
515
|
+
* @returns {void}
|
|
516
|
+
*/
|
|
517
|
+
function validateTypeParameters(declaration, fail, normalizeOperations) {
|
|
518
|
+
if (declaration.typeParameters === undefined)
|
|
519
|
+
return;
|
|
520
|
+
if (!Array.isArray(declaration.typeParameters)) {
|
|
521
|
+
fail("TYPE_MISMATCH", "Type parameters must be a dense ordered array.", declaration.location);
|
|
522
|
+
}
|
|
523
|
+
const names = new Set();
|
|
524
|
+
for (let index = 0; index < declaration.typeParameters.length; index += 1) {
|
|
525
|
+
const parameter = declaration.typeParameters[index];
|
|
526
|
+
const keys = parameter && typeof parameter == "object" && !Array.isArray(parameter)
|
|
527
|
+
? Object.keys(parameter).filter((key) => key != "sourceProvenance").sort().join(",") : "";
|
|
528
|
+
if (!Object.hasOwn(declaration.typeParameters, index) || !parameter || parameter.kind != "TypeParameter" ||
|
|
529
|
+
keys != "id,kind,location,name" || typeof parameter.name != "string" || parameter.name.length == 0) {
|
|
530
|
+
fail("TYPE_MISMATCH", "Malformed type parameter declaration.", parameter?.location ?? declaration.location);
|
|
531
|
+
}
|
|
532
|
+
if (names.has(parameter.name)) {
|
|
533
|
+
fail("DUPLICATE_TYPE_PARAMETER", `Duplicate type parameter '${parameter.name}'.`, roleLocation(parameter, "name"));
|
|
534
|
+
}
|
|
535
|
+
names.add(parameter.name);
|
|
536
|
+
const expectedId = `${declaration.id}:type:${index}`;
|
|
537
|
+
if (normalizeOperations)
|
|
538
|
+
parameter.id = expectedId;
|
|
539
|
+
if (parameter.id != expectedId) {
|
|
540
|
+
fail("DUPLICATE_TYPE_PARAMETER", "Duplicate or invalid type parameter identity.", parameter.location);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Returns the closed identity scope owned by one validated declaration.
|
|
546
|
+
* @param {import("./types.js").FunctionDeclaration | import("./types.js").RecordDeclaration} declaration - Declaration.
|
|
547
|
+
* @returns {Set<string>} Type-parameter identities.
|
|
548
|
+
*/
|
|
549
|
+
function declarationTypeParameterIds(declaration) {
|
|
550
|
+
return new Set((declaration.typeParameters ?? []).map(({ id }) => /** @type {string} */ (id)));
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Validates nominal declarations and returns their stable identity registry.
|
|
554
|
+
* @param {unknown} declarations - Candidate ordered declarations.
|
|
555
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
556
|
+
* @param {boolean} normalizeOperations - Whether parser-authored identities are assigned.
|
|
557
|
+
* @param {Map<string, import("./types.js").RecordDeclaration>} [visibleRecords] - Imported record declarations by identity.
|
|
558
|
+
* @param {ClassRegistry} [classes] - Module reference classes by identity.
|
|
559
|
+
* @returns {RecordRegistry} Validated declarations by identity.
|
|
560
|
+
*/
|
|
561
|
+
function validateRecordDeclarations(declarations, fail, normalizeOperations, visibleRecords = new Map(), classes = new Map()) {
|
|
562
|
+
if (!Array.isArray(declarations))
|
|
563
|
+
return fail("TYPE_MISMATCH", "Record declarations must be an ordered array.", /** @type {never} */ (undefined));
|
|
564
|
+
/** @type {RecordRegistry} */
|
|
565
|
+
const records = new Map(visibleRecords);
|
|
566
|
+
referenceClassesByRecordRegistry.set(records, classes);
|
|
567
|
+
const names = new Set();
|
|
568
|
+
for (let recordIndex = 0; recordIndex < declarations.length; recordIndex += 1) {
|
|
569
|
+
const declaration = declarations[recordIndex];
|
|
570
|
+
if (!declaration || declaration.kind != "RecordDeclaration" || !Array.isArray(declaration.fields)) {
|
|
571
|
+
return fail("TYPE_MISMATCH", "Malformed record declaration.", declaration?.location);
|
|
572
|
+
}
|
|
573
|
+
if (normalizeOperations)
|
|
574
|
+
declaration.id = `record:${recordIndex}`;
|
|
575
|
+
if (typeof declaration.id != "string" || !/^(?:[a-z][a-z0-9._-]*#)?record:[0-9]+$/u.test(declaration.id) || records.has(declaration.id)) {
|
|
576
|
+
fail("DUPLICATE_RECORD", "Duplicate or invalid record declaration identity.", declaration.location);
|
|
577
|
+
}
|
|
578
|
+
if (names.has(declaration.name)) {
|
|
579
|
+
fail("DUPLICATE_RECORD", `Duplicate record '${declaration.name}'.`, roleLocation(declaration, "name"));
|
|
580
|
+
}
|
|
581
|
+
names.add(declaration.name);
|
|
582
|
+
validateTypeParameters(declaration, fail, normalizeOperations);
|
|
583
|
+
records.set(declaration.id, declaration);
|
|
584
|
+
}
|
|
585
|
+
for (const declaration of declarations) {
|
|
586
|
+
const fieldNames = new Set();
|
|
587
|
+
const typeParameters = declarationTypeParameterIds(declaration);
|
|
588
|
+
for (let fieldIndex = 0; fieldIndex < declaration.fields.length; fieldIndex += 1) {
|
|
589
|
+
const field = declaration.fields[fieldIndex];
|
|
590
|
+
if (!field || field.kind != "RecordField")
|
|
591
|
+
fail("TYPE_MISMATCH", "Malformed record field.", field?.location ?? declaration.location);
|
|
592
|
+
if (normalizeOperations)
|
|
593
|
+
field.id = `${declaration.id}:field:${fieldIndex}`;
|
|
594
|
+
if (typeof field.id != "string" || field.id != `${declaration.id}:field:${fieldIndex}`) {
|
|
595
|
+
fail("DUPLICATE_FIELD", "Duplicate or invalid record field identity.", field.location);
|
|
596
|
+
}
|
|
597
|
+
if (fieldNames.has(field.name))
|
|
598
|
+
fail("DUPLICATE_FIELD", `Duplicate field '${field.name}'.`, roleLocation(field, "name"));
|
|
599
|
+
fieldNames.add(field.name);
|
|
600
|
+
if (containsOwnedType(field.type)) {
|
|
601
|
+
fail("RESOURCE_ALIAS", "Owned resources cannot be stored in immutable records.", field.location);
|
|
602
|
+
}
|
|
603
|
+
validateValueTypeReference(field.type, field.location, fail, undefined, records, typeParameters);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
validateDirectRecordRecursion(declarations, records, fail);
|
|
607
|
+
return records;
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Rejects cycles composed solely of unmediated record fields.
|
|
611
|
+
* @param {import("./types.js").RecordDeclaration[]} declarations - Valid declarations.
|
|
612
|
+
* @param {RecordRegistry} records - Declarations by identity.
|
|
613
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
614
|
+
* @returns {void}
|
|
615
|
+
*/
|
|
616
|
+
function validateDirectRecordRecursion(declarations, records, fail) {
|
|
617
|
+
const complete = new Set();
|
|
618
|
+
/**
|
|
619
|
+
* Visits one declaration along an unmediated record path.
|
|
620
|
+
* @param {import("./types.js").RecordDeclaration} declaration - Current declaration.
|
|
621
|
+
* @param {Set<string>} active - Declaration identities active on this path.
|
|
622
|
+
* @returns {void}
|
|
623
|
+
*/
|
|
624
|
+
function visit(declaration, active) {
|
|
625
|
+
if (complete.has(/** @type {string} */ (declaration.id)))
|
|
626
|
+
return;
|
|
627
|
+
const next = new Set(active);
|
|
628
|
+
next.add(/** @type {string} */ (declaration.id));
|
|
629
|
+
for (const field of declaration.fields) {
|
|
630
|
+
if (field.type.kind != "RecordType")
|
|
631
|
+
continue;
|
|
632
|
+
if (next.has(field.type.declarationId)) {
|
|
633
|
+
fail("ILLEGAL_RECORD_RECURSION", `Direct value-recursive field '${field.name}'.`, typeLocation(field.type, field.location));
|
|
634
|
+
}
|
|
635
|
+
const referenced = records.get(field.type.declarationId);
|
|
636
|
+
if (referenced)
|
|
637
|
+
visit(referenced, next);
|
|
638
|
+
}
|
|
639
|
+
complete.add(/** @type {string} */ (declaration.id));
|
|
640
|
+
}
|
|
641
|
+
for (const declaration of declarations)
|
|
642
|
+
visit(declaration, new Set());
|
|
99
643
|
}
|
|
100
644
|
/**
|
|
101
645
|
* Validates one non-void function and its complete control flow.
|
|
102
646
|
* @param {import("./types.js").FunctionDeclaration} declaration - Function declaration.
|
|
103
647
|
* @param {Map<string, import("./types.js").FunctionDeclaration>} functions - Function signatures.
|
|
648
|
+
* @param {RecordRegistry} records - Record declarations by identity.
|
|
649
|
+
* @param {ErrorRegistry} errors - Error declarations by identity.
|
|
650
|
+
* @param {Map<string, Set<string>>} callEffects - Internally inferred unchecked-error effects.
|
|
651
|
+
* @param {Set<string>} reservedValueNames - Module functions and nominal constructors unavailable to lexical bindings.
|
|
104
652
|
* @param {SemanticFail} fail - Diagnostic callback.
|
|
105
653
|
* @param {boolean} normalizeOperations - Whether to replace transient frontend operation intent.
|
|
654
|
+
* @param {Map<string, object>} loopOwners - Loop owner by module-local identity.
|
|
106
655
|
* @returns {void}
|
|
107
656
|
*/
|
|
108
|
-
function validateFunction(declaration, functions, fail, normalizeOperations) {
|
|
109
|
-
const
|
|
657
|
+
function validateFunction(declaration, functions, records, errors, callEffects, reservedValueNames, fail, normalizeOperations, loopOwners) {
|
|
658
|
+
const typeParameters = declarationTypeParameterIds(declaration);
|
|
659
|
+
const scope = createScope(undefined, declaration.body.statements, reservedValueNames, typeParameters);
|
|
110
660
|
for (const parameter of declaration.parameters) {
|
|
111
|
-
const type =
|
|
112
|
-
declareBinding(parameter.name, { mutable: false, type }, parameter
|
|
661
|
+
const type = validateValueTypeReference(parameter.type, parameter.location, fail, undefined, records, typeParameters);
|
|
662
|
+
declareBinding(parameter.name, { knownValue: undefined, mutable: false, type }, roleLocation(parameter, "name"), scope, fail);
|
|
113
663
|
}
|
|
114
|
-
const returnType =
|
|
115
|
-
const returns = validateBlock(declaration.body, scope, returnType, functions, fail, normalizeOperations);
|
|
116
|
-
if (!returns)
|
|
664
|
+
const returnType = validateReturnTypeReference(declaration.returnType, declaration.location, fail, records, typeParameters);
|
|
665
|
+
const returns = validateBlock(declaration.body, scope, returnType, functions, records, errors, callEffects, fail, normalizeOperations, { owner: declaration, owners: loopOwners });
|
|
666
|
+
if (!isVoidType(returnType) && returns.normal) {
|
|
117
667
|
fail("MISSING_RETURN", `Function '${declaration.name}' does not return on every reachable path.`, declaration.location);
|
|
668
|
+
}
|
|
118
669
|
}
|
|
119
670
|
/**
|
|
120
671
|
* Validates one ordered block and reports whether every path returns.
|
|
121
672
|
* @param {import("./types.js").Block} block - Semantic block.
|
|
122
673
|
* @param {Scope} scope - Scope belonging to this block.
|
|
123
|
-
* @param {import("./types.js").
|
|
674
|
+
* @param {import("./types.js").SemanticFunctionReturnType | undefined} returnType - Function return type, absent for entry points.
|
|
124
675
|
* @param {Map<string, import("./types.js").FunctionDeclaration>} functions - Function signatures.
|
|
676
|
+
* @param {RecordRegistry} records - Record declarations by identity.
|
|
677
|
+
* @param {ErrorRegistry} errors - Error declarations by identity.
|
|
678
|
+
* @param {Map<string, Set<string>>} callEffects - Internally inferred unchecked-error effects.
|
|
125
679
|
* @param {SemanticFail} fail - Diagnostic callback.
|
|
126
680
|
* @param {boolean} normalizeOperations - Whether to replace transient frontend operation intent.
|
|
127
|
-
* @
|
|
681
|
+
* @param {LoopFlowContext} loopContext - Active loop and owner identities.
|
|
682
|
+
* @returns {{normal: boolean, raises: Set<string>}} Reachable normal continuation and escaping error identities.
|
|
128
683
|
*/
|
|
129
|
-
function validateBlock(block, scope, returnType, functions, fail, normalizeOperations) {
|
|
130
|
-
let
|
|
684
|
+
function validateBlock(block, scope, returnType, functions, records, errors, callEffects, fail, normalizeOperations, loopContext) {
|
|
685
|
+
let normal = true;
|
|
686
|
+
const raises = new Set();
|
|
131
687
|
for (const statement of block.statements) {
|
|
132
|
-
if (
|
|
688
|
+
if (!normal)
|
|
133
689
|
fail("UNREACHABLE_STATEMENT", "Statement is unreachable.", statement.location);
|
|
134
690
|
if (statement.kind == "LocalDeclaration") {
|
|
135
|
-
const declaredType =
|
|
136
|
-
|
|
691
|
+
const declaredType = validateValueTypeReference(statement.type, statement.location, fail, undefined, records, scope.typeParameters);
|
|
692
|
+
statement.initializer = normalizeOwnedMove(statement.initializer, declaredType, normalizeOperations, fail);
|
|
693
|
+
const initializerType = inferValueExpressionType(statement.initializer, scope, functions, records, fail, normalizeOperations, "an initializer", declaredType);
|
|
137
694
|
scope.pending.delete(statement.name);
|
|
138
|
-
if (initializerType
|
|
139
|
-
|
|
695
|
+
if (!sameType(initializerType, declaredType)) {
|
|
696
|
+
if (initializerType.kind == "OptionalType" && declaredType.kind != "OptionalType") {
|
|
697
|
+
fail("FAILURE_ABSENCE_CONFLATION", "Optional absence cannot be coerced into a value or typed failure.", statement.initializer.location);
|
|
698
|
+
}
|
|
699
|
+
fail("TYPE_MISMATCH", `Initializer type ${typeDescription(initializerType)}; expected ${typeDescription(declaredType)}.`, statement.initializer.location);
|
|
140
700
|
}
|
|
141
|
-
declareBinding(statement.name, {
|
|
701
|
+
declareBinding(statement.name, {
|
|
702
|
+
knownValue: knownValueForExpression(statement.initializer, scope),
|
|
703
|
+
mutable: statement.mutable,
|
|
704
|
+
type: declaredType
|
|
705
|
+
}, roleLocation(statement, "name"), scope, fail);
|
|
706
|
+
addExpressionEffects(raises, statement.initializer, callEffects);
|
|
142
707
|
continue;
|
|
143
708
|
}
|
|
144
709
|
if (statement.kind == "AssignmentStatement") {
|
|
145
|
-
const expressionType = inferExpressionType(statement.expression, scope, functions, fail, normalizeOperations);
|
|
146
710
|
const binding = resolveBinding(statement.target.name, statement.target.location, scope, fail);
|
|
711
|
+
if (binding.type.kind == "ErrorType") {
|
|
712
|
+
fail("IMMUTABLE_ASSIGNMENT", `Cannot assign to immutable catch binding '${statement.target.name}'.`, statement.target.location);
|
|
713
|
+
}
|
|
714
|
+
if (binding.type.kind == "OwnedResourceType" || binding.type.kind == "OwnedReferenceType") {
|
|
715
|
+
fail("RESOURCE_ALIAS", "Owned resources cannot be reassigned or aliased.", statement.location);
|
|
716
|
+
}
|
|
717
|
+
const expressionType = inferValueExpressionType(statement.expression, scope, functions, records, fail, normalizeOperations, "an assignment", binding.type);
|
|
147
718
|
if (!binding.mutable) {
|
|
148
719
|
fail("IMMUTABLE_ASSIGNMENT", `Cannot assign to immutable binding '${statement.target.name}'.`, statement.target.location);
|
|
149
720
|
}
|
|
150
|
-
if (expressionType
|
|
151
|
-
fail("TYPE_MISMATCH", `Assignment type ${expressionType}; expected ${binding.type}.`, statement.expression.location);
|
|
721
|
+
if (!sameType(expressionType, binding.type)) {
|
|
722
|
+
fail("TYPE_MISMATCH", `Assignment type ${typeDescription(expressionType)}; expected ${typeDescription(binding.type)}.`, statement.expression.location);
|
|
152
723
|
}
|
|
724
|
+
binding.knownValue = knownValueForExpression(statement.expression, scope);
|
|
725
|
+
scope.presenceProofs.delete(binding);
|
|
726
|
+
addExpressionEffects(raises, statement.expression, callEffects);
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
729
|
+
if (statement.kind == "PrivateFieldWriteStatement") {
|
|
730
|
+
const declaration = scope.currentClass;
|
|
731
|
+
if (!declaration || !statement.receiver || statement.receiver.kind != "ReceiverExpression" ||
|
|
732
|
+
statement.receiver.classId != declaration.id) {
|
|
733
|
+
fail("ILLEGAL_PRIVATE_ACCESS", "Private field receiver must be the declaring class receiver.", statement.location);
|
|
734
|
+
}
|
|
735
|
+
const field = declaration.fields.find((candidate) => candidate.id == statement.field);
|
|
736
|
+
if (!field)
|
|
737
|
+
fail("ILLEGAL_PRIVATE_ACCESS", "Private field identity is not owned by the declaring class.", statement.location);
|
|
738
|
+
statement.expression = normalizeOwnedMove(statement.expression, field.type, normalizeOperations, fail);
|
|
739
|
+
const expressionType = inferValueExpressionType(statement.expression, scope, functions, records, fail, normalizeOperations, "a private field assignment", field.type);
|
|
740
|
+
if (!sameType(expressionType, field.type)) {
|
|
741
|
+
fail("TYPE_MISMATCH", `Private field assignment type ${typeDescription(expressionType)}; expected ${typeDescription(field.type)}.`, statement.expression.location);
|
|
742
|
+
}
|
|
743
|
+
addExpressionEffects(raises, statement.expression, callEffects);
|
|
153
744
|
continue;
|
|
154
745
|
}
|
|
155
746
|
if (statement.kind == "PrintStatement") {
|
|
156
|
-
|
|
747
|
+
const printedType = inferValueExpressionType(statement.expression, scope, functions, records, fail, normalizeOperations, "a print value");
|
|
748
|
+
if (printedType.kind == "OwnedResourceType" || printedType.kind == "OwnedReferenceType") {
|
|
749
|
+
fail("BORROW_ESCAPE", "Owned values cannot escape through printing or serialization.", statement.expression.location);
|
|
750
|
+
}
|
|
751
|
+
if (printedType.kind != "TypeReference") {
|
|
752
|
+
fail("TYPE_MISMATCH", "Collections and records cannot be printed directly.", statement.expression.location);
|
|
753
|
+
}
|
|
754
|
+
addExpressionEffects(raises, statement.expression, callEffects);
|
|
755
|
+
continue;
|
|
756
|
+
}
|
|
757
|
+
if (statement.kind == "ExpressionStatement") {
|
|
758
|
+
if (!statement.expression || !["CallExpression", "EffectCallExpression", "MethodCallExpression"].includes(statement.expression.kind)) {
|
|
759
|
+
fail("TYPE_MISMATCH", "Expression statement must contain a direct or receiver call.", statement.location);
|
|
760
|
+
}
|
|
761
|
+
const expressionType = inferExpressionType(statement.expression, scope, functions, records, fail, normalizeOperations);
|
|
762
|
+
if (expressionType != "void") {
|
|
763
|
+
fail("TYPE_MISMATCH", "Expression statements may contain only void calls.", statement.expression.location);
|
|
764
|
+
}
|
|
765
|
+
addExpressionEffects(raises, statement.expression, callEffects);
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
if (statement.kind == "BreakStatement" || statement.kind == "ContinueStatement") {
|
|
769
|
+
const control = statement.kind == "BreakStatement" ? "break" : "continue";
|
|
770
|
+
if (!loopContext.nearest) {
|
|
771
|
+
if (typeof statement.targetLoopId == "string" && loopContext.owners.has(statement.targetLoopId) &&
|
|
772
|
+
loopContext.owners.get(statement.targetLoopId) !== loopContext.owner) {
|
|
773
|
+
fail("CROSS_FUNCTION_LOOP_TARGET", `${control[0].toUpperCase()}${control.slice(1)} target crosses a function boundary.`, statement.location);
|
|
774
|
+
}
|
|
775
|
+
fail(`ILLEGAL_${control.toUpperCase()}_CONTEXT`, `${control[0].toUpperCase()}${control.slice(1)} statement outside a loop.`, statement.location);
|
|
776
|
+
}
|
|
777
|
+
if (typeof statement.targetLoopId != "string" || !loopContext.owners.has(statement.targetLoopId)) {
|
|
778
|
+
fail("INVALID_LOOP_TARGET", `${control[0].toUpperCase()}${control.slice(1)} has an invalid loop target identity.`, statement.location);
|
|
779
|
+
}
|
|
780
|
+
if (loopContext.owners.get(statement.targetLoopId) !== loopContext.owner) {
|
|
781
|
+
fail("CROSS_FUNCTION_LOOP_TARGET", `${control[0].toUpperCase()}${control.slice(1)} target crosses a function boundary.`, statement.location);
|
|
782
|
+
}
|
|
783
|
+
if (statement.targetLoopId != loopContext.nearest.id) {
|
|
784
|
+
fail("INVALID_LOOP_TARGET", `${control[0].toUpperCase()}${control.slice(1)} must target the nearest enclosing loop.`, statement.location);
|
|
785
|
+
}
|
|
786
|
+
normal = false;
|
|
157
787
|
continue;
|
|
158
788
|
}
|
|
159
789
|
if (statement.kind == "ReturnStatement") {
|
|
160
790
|
if (!returnType)
|
|
161
791
|
fail("ILLEGAL_RETURN_CONTEXT", "Return statement outside a function.", statement.location);
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
792
|
+
if (isVoidType(returnType)) {
|
|
793
|
+
if (statement.expression) {
|
|
794
|
+
fail("VOID_RETURN_VALUE", "Void function cannot return a value.", statement.expression.location);
|
|
795
|
+
}
|
|
165
796
|
}
|
|
166
|
-
|
|
797
|
+
else {
|
|
798
|
+
if (!statement.expression) {
|
|
799
|
+
fail("MISSING_RETURN_VALUE", `Function return requires a ${typeDescription(returnType)} value.`, statement.location);
|
|
800
|
+
}
|
|
801
|
+
statement.expression = normalizeOwnedMove(statement.expression, returnType, normalizeOperations, fail);
|
|
802
|
+
const actualType = inferValueExpressionType(statement.expression, scope, functions, records, fail, normalizeOperations, "a returned value", returnType);
|
|
803
|
+
if (!sameType(actualType, returnType)) {
|
|
804
|
+
fail("TYPE_MISMATCH", `Return type ${typeDescription(actualType)}; expected ${typeDescription(returnType)}.`, statement.expression.location);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
if (statement.expression)
|
|
808
|
+
addExpressionEffects(raises, statement.expression, callEffects);
|
|
809
|
+
normal = false;
|
|
167
810
|
continue;
|
|
168
811
|
}
|
|
169
812
|
if (statement.kind == "IfStatement") {
|
|
170
|
-
const conditionType =
|
|
171
|
-
if (conditionType
|
|
172
|
-
fail("NON_BOOLEAN_CONDITION", `If condition type ${conditionType}; expected boolean.`, statement.condition.location);
|
|
813
|
+
const conditionType = inferValueExpressionType(statement.condition, scope, functions, records, fail, normalizeOperations, "a condition");
|
|
814
|
+
if (!isScalarType(conditionType, "boolean")) {
|
|
815
|
+
fail("NON_BOOLEAN_CONDITION", `If condition type ${typeDescription(conditionType)}; expected boolean.`, statement.condition.location);
|
|
173
816
|
}
|
|
817
|
+
const visibleBindings = bindingsVisibleFrom(scope);
|
|
818
|
+
const initialKnownValues = visibleBindings.map((binding) => binding.knownValue);
|
|
174
819
|
const consequentScope = createScope(scope, statement.consequent.statements);
|
|
175
|
-
const
|
|
176
|
-
|
|
820
|
+
const alternateScope = createScope(scope, statement.alternate?.statements ?? []);
|
|
821
|
+
applyPresenceNarrowing(statement.condition, scope, consequentScope, true);
|
|
822
|
+
applyPresenceNarrowing(statement.condition, scope, alternateScope, false);
|
|
823
|
+
const consequentReturns = validateBlock(statement.consequent, consequentScope, returnType, functions, records, errors, callEffects, fail, normalizeOperations, loopContext);
|
|
824
|
+
const consequentKnownValues = visibleBindings.map((binding) => binding.knownValue);
|
|
825
|
+
visibleBindings.forEach((binding, index) => {
|
|
826
|
+
binding.knownValue = initialKnownValues[index];
|
|
827
|
+
});
|
|
828
|
+
let alternateReturns = { normal: true, raises: new Set() };
|
|
177
829
|
if (statement.alternate) {
|
|
178
|
-
|
|
179
|
-
|
|
830
|
+
alternateReturns = validateBlock(statement.alternate, alternateScope, returnType, functions, records, errors, callEffects, fail, normalizeOperations, loopContext);
|
|
831
|
+
}
|
|
832
|
+
const alternateKnownValues = visibleBindings.map((binding) => binding.knownValue);
|
|
833
|
+
visibleBindings.forEach((binding, index) => {
|
|
834
|
+
if (!consequentReturns.normal && alternateReturns.normal)
|
|
835
|
+
binding.knownValue = alternateKnownValues[index];
|
|
836
|
+
else if (consequentReturns.normal && !alternateReturns.normal)
|
|
837
|
+
binding.knownValue = consequentKnownValues[index];
|
|
838
|
+
else if (consequentReturns.normal && alternateReturns.normal && consequentKnownValues[index] === alternateKnownValues[index]) {
|
|
839
|
+
binding.knownValue = consequentKnownValues[index];
|
|
840
|
+
}
|
|
841
|
+
else
|
|
842
|
+
binding.knownValue = undefined;
|
|
843
|
+
});
|
|
844
|
+
const continuingProofs = !consequentReturns.normal && alternateReturns.normal
|
|
845
|
+
? alternateScope.presenceProofs
|
|
846
|
+
: consequentReturns.normal && !alternateReturns.normal
|
|
847
|
+
? consequentScope.presenceProofs
|
|
848
|
+
: consequentReturns.normal && alternateReturns.normal
|
|
849
|
+
? new Set([...consequentScope.presenceProofs].filter((binding) => alternateScope.presenceProofs.has(binding)))
|
|
850
|
+
: new Set();
|
|
851
|
+
const visibleSet = new Set(visibleBindings);
|
|
852
|
+
scope.presenceProofs.clear();
|
|
853
|
+
for (const binding of continuingProofs) {
|
|
854
|
+
if (visibleSet.has(binding))
|
|
855
|
+
scope.presenceProofs.add(binding);
|
|
856
|
+
}
|
|
857
|
+
addExpressionEffects(raises, statement.condition, callEffects);
|
|
858
|
+
addAll(raises, consequentReturns.raises);
|
|
859
|
+
addAll(raises, alternateReturns.raises);
|
|
860
|
+
normal = consequentReturns.normal || alternateReturns.normal;
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
863
|
+
if (statement.kind == "WhileStatement") {
|
|
864
|
+
const assignedOuterBindings = outerMutableBindingsAssignedBy(statement.body, scope);
|
|
865
|
+
for (const binding of assignedOuterBindings) {
|
|
866
|
+
binding.knownValue = undefined;
|
|
867
|
+
scope.presenceProofs.delete(binding);
|
|
868
|
+
}
|
|
869
|
+
const conditionType = inferValueExpressionType(statement.condition, scope, functions, records, fail, normalizeOperations, "a condition-controlled loop condition");
|
|
870
|
+
if (!isScalarType(conditionType, "boolean")) {
|
|
871
|
+
fail("NON_BOOLEAN_CONDITION", `While condition type ${typeDescription(conditionType)}; expected boolean.`, statement.condition.location);
|
|
872
|
+
}
|
|
873
|
+
const loopScope = createScope(scope, statement.body.statements);
|
|
874
|
+
applyPresenceNarrowing(statement.condition, scope, loopScope, true);
|
|
875
|
+
const bodyFlow = validateBlock(statement.body, loopScope, returnType, functions, records, errors, callEffects, fail, normalizeOperations, { nearest: statement, owner: loopContext.owner, owners: loopContext.owners });
|
|
876
|
+
addExpressionEffects(raises, statement.condition, callEffects);
|
|
877
|
+
addAll(raises, bodyFlow.raises);
|
|
878
|
+
for (const binding of assignedOuterBindings) {
|
|
879
|
+
binding.knownValue = undefined;
|
|
880
|
+
scope.presenceProofs.delete(binding);
|
|
881
|
+
}
|
|
882
|
+
continue;
|
|
883
|
+
}
|
|
884
|
+
if (statement.kind == "ForEachStatement") {
|
|
885
|
+
const listType = inferValueExpressionType(statement.list, scope, functions, records, fail, normalizeOperations, "an iteration collection");
|
|
886
|
+
if (listType.kind != "ListType") {
|
|
887
|
+
fail("TYPE_MISMATCH", `Iteration collection type ${typeDescription(listType)}; expected list.`, statement.list.location);
|
|
888
|
+
}
|
|
889
|
+
if (!statement.valueBinding || statement.valueBinding.kind != "ValueBinding") {
|
|
890
|
+
fail("TYPE_MISMATCH", "Iteration requires one typed value binding.", statement.location);
|
|
891
|
+
}
|
|
892
|
+
if (statement.valueBinding.mutable !== false) {
|
|
893
|
+
fail("TYPE_MISMATCH", "Iteration binding must be immutable.", statement.valueBinding.location ?? statement.location);
|
|
894
|
+
}
|
|
895
|
+
const bindingType = validateValueTypeReference(statement.valueBinding.type, statement.valueBinding.location, fail, undefined, records, scope.typeParameters);
|
|
896
|
+
if (!sameType(bindingType, listType.elementType)) {
|
|
897
|
+
fail("TYPE_MISMATCH", `Iteration binding type ${typeDescription(bindingType)}; expected ${typeDescription(listType.elementType)}.`, typeLocation(statement.valueBinding.type, statement.valueBinding.location));
|
|
898
|
+
}
|
|
899
|
+
const assignedOuterBindings = outerMutableBindingsAssignedBy(statement.body, scope);
|
|
900
|
+
for (const binding of assignedOuterBindings) {
|
|
901
|
+
binding.knownValue = undefined;
|
|
902
|
+
scope.presenceProofs.delete(binding);
|
|
903
|
+
}
|
|
904
|
+
const loopScope = createScope(scope, statement.body.statements);
|
|
905
|
+
declareBinding(statement.valueBinding.name, {
|
|
906
|
+
knownValue: undefined,
|
|
907
|
+
mutable: false,
|
|
908
|
+
type: bindingType
|
|
909
|
+
}, roleLocation(statement.valueBinding, "name"), loopScope, fail);
|
|
910
|
+
const bodyFlow = validateBlock(statement.body, loopScope, returnType, functions, records, errors, callEffects, fail, normalizeOperations, { nearest: statement, owner: loopContext.owner, owners: loopContext.owners });
|
|
911
|
+
addExpressionEffects(raises, statement.list, callEffects);
|
|
912
|
+
addAll(raises, bodyFlow.raises);
|
|
913
|
+
for (const binding of assignedOuterBindings) {
|
|
914
|
+
binding.knownValue = undefined;
|
|
915
|
+
scope.presenceProofs.delete(binding);
|
|
916
|
+
}
|
|
917
|
+
continue;
|
|
918
|
+
}
|
|
919
|
+
if (statement.kind == "ForEachMapStatement") {
|
|
920
|
+
const mapType = inferValueExpressionType(statement.map, scope, functions, records, fail, normalizeOperations, "a map iteration collection");
|
|
921
|
+
if (mapType.kind != "OrderedMapType") {
|
|
922
|
+
fail("TYPE_MISMATCH", `Map iteration collection type ${typeDescription(mapType)}; expected ordered map.`, statement.map.location);
|
|
923
|
+
}
|
|
924
|
+
if (!statement.keyBinding || statement.keyBinding.kind != "ValueBinding" ||
|
|
925
|
+
!statement.valueBinding || statement.valueBinding.kind != "ValueBinding") {
|
|
926
|
+
fail("TYPE_MISMATCH", "Map iteration requires exact key and value bindings.", statement.location);
|
|
927
|
+
}
|
|
928
|
+
if (statement.keyBinding.mutable !== false || statement.valueBinding.mutable !== false) {
|
|
929
|
+
fail("TYPE_MISMATCH", "Map iteration bindings must be immutable.", statement.keyBinding.mutable !== false ? statement.keyBinding.location : statement.valueBinding.location);
|
|
930
|
+
}
|
|
931
|
+
const keyType = validateValueTypeReference(statement.keyBinding.type, statement.keyBinding.location, fail, undefined, records, scope.typeParameters);
|
|
932
|
+
const valueType = validateValueTypeReference(statement.valueBinding.type, statement.valueBinding.location, fail, undefined, records, scope.typeParameters);
|
|
933
|
+
if (!sameType(keyType, mapType.keyType)) {
|
|
934
|
+
fail("TYPE_MISMATCH", `Map iteration key binding type ${typeDescription(keyType)}; expected ${typeDescription(mapType.keyType)}.`, typeLocation(statement.keyBinding.type, statement.keyBinding.location));
|
|
935
|
+
}
|
|
936
|
+
if (!sameType(valueType, mapType.valueType)) {
|
|
937
|
+
fail("TYPE_MISMATCH", `Map iteration value binding type ${typeDescription(valueType)}; expected ${typeDescription(mapType.valueType)}.`, typeLocation(statement.valueBinding.type, statement.valueBinding.location));
|
|
938
|
+
}
|
|
939
|
+
const assignedOuterBindings = outerMutableBindingsAssignedBy(statement.body, scope);
|
|
940
|
+
for (const binding of assignedOuterBindings) {
|
|
941
|
+
binding.knownValue = undefined;
|
|
942
|
+
scope.presenceProofs.delete(binding);
|
|
943
|
+
}
|
|
944
|
+
const loopScope = createScope(scope, statement.body.statements);
|
|
945
|
+
declareBinding(statement.keyBinding.name, { knownValue: undefined, mutable: false, type: keyType }, roleLocation(statement.keyBinding, "name"), loopScope, fail);
|
|
946
|
+
declareBinding(statement.valueBinding.name, { knownValue: undefined, mutable: false, type: valueType }, roleLocation(statement.valueBinding, "name"), loopScope, fail);
|
|
947
|
+
const bodyFlow = validateBlock(statement.body, loopScope, returnType, functions, records, errors, callEffects, fail, normalizeOperations, { nearest: statement, owner: loopContext.owner, owners: loopContext.owners });
|
|
948
|
+
addExpressionEffects(raises, statement.map, callEffects);
|
|
949
|
+
addAll(raises, bodyFlow.raises);
|
|
950
|
+
for (const binding of assignedOuterBindings) {
|
|
951
|
+
binding.knownValue = undefined;
|
|
952
|
+
scope.presenceProofs.delete(binding);
|
|
953
|
+
}
|
|
954
|
+
continue;
|
|
955
|
+
}
|
|
956
|
+
if (statement.kind == "RaiseStatement") {
|
|
957
|
+
if (!statement.error || statement.error.kind != "ErrorConstruction") {
|
|
958
|
+
fail("NON_ERROR_RAISE", "Raise requires one constructed semantic error.", statement.location);
|
|
959
|
+
}
|
|
960
|
+
const raisedType = validateErrorType(statement.error.error, statement.error.location, errors, fail);
|
|
961
|
+
const messageType = inferValueExpressionType(statement.error.message, scope, functions, records, fail, normalizeOperations, "an error message", scalarType("string"));
|
|
962
|
+
if (!isScalarType(messageType, "string")) {
|
|
963
|
+
fail("NON_ERROR_RAISE", `Error message type ${typeDescription(messageType)}; expected string.`, statement.error.message.location);
|
|
964
|
+
}
|
|
965
|
+
addExpressionEffects(raises, statement.error.message, callEffects);
|
|
966
|
+
raises.add(raisedType.declarationId);
|
|
967
|
+
normal = false;
|
|
968
|
+
continue;
|
|
969
|
+
}
|
|
970
|
+
if (statement.kind == "TryStatement") {
|
|
971
|
+
const caughtType = validateErrorType(statement.catchType, statement.location, errors, fail);
|
|
972
|
+
if (!statement.catchBinding || statement.catchBinding.kind != "CatchBinding" || statement.catchBinding.mutable !== false) {
|
|
973
|
+
fail("INVALID_ERROR_HANDLER", "Catch requires one immutable typed binding.", statement.catchBinding?.location ?? statement.location);
|
|
974
|
+
}
|
|
975
|
+
const bindingType = validateErrorType(statement.catchBinding.type, statement.catchBinding.location, errors, fail);
|
|
976
|
+
if (bindingType.declarationId != caughtType.declarationId) {
|
|
977
|
+
fail("INVALID_ERROR_HANDLER", "Catch binding type must exactly match its handler type.", statement.catchBinding.location);
|
|
978
|
+
}
|
|
979
|
+
const bodyAssignedOuterBindings = outerMutableBindingsAssignedBy(statement.body, scope);
|
|
980
|
+
const assignedOuterBindings = new Set(bodyAssignedOuterBindings);
|
|
981
|
+
outerMutableBindingsAssignedBy(statement.catchBody, scope, assignedOuterBindings);
|
|
982
|
+
const bodyScope = createScope(scope, statement.body.statements);
|
|
983
|
+
const bodyFlow = validateBlock(statement.body, bodyScope, returnType, functions, records, errors, callEffects, fail, normalizeOperations, loopContext);
|
|
984
|
+
const catchScope = createScope(scope, statement.catchBody.statements);
|
|
985
|
+
for (const binding of bodyAssignedOuterBindings) {
|
|
986
|
+
binding.knownValue = undefined;
|
|
987
|
+
catchScope.presenceProofs.delete(binding);
|
|
988
|
+
}
|
|
989
|
+
declareBinding(statement.catchBinding.name, {
|
|
990
|
+
knownValue: undefined,
|
|
991
|
+
mutable: false,
|
|
992
|
+
type: bindingType
|
|
993
|
+
}, roleLocation(statement.catchBinding, "name"), catchScope, fail);
|
|
994
|
+
const catchFlow = validateBlock(statement.catchBody, catchScope, returnType, functions, records, errors, callEffects, fail, normalizeOperations, loopContext);
|
|
995
|
+
if (!bodyFlow.raises.has(caughtType.declarationId)) {
|
|
996
|
+
fail("UNREACHABLE_HANDLER", `Handler for '${errors.get(caughtType.declarationId)?.name}' cannot be reached.`, typeLocation(statement.catchType, statement.location));
|
|
997
|
+
}
|
|
998
|
+
bodyFlow.raises.delete(caughtType.declarationId);
|
|
999
|
+
addAll(raises, bodyFlow.raises);
|
|
1000
|
+
addAll(raises, catchFlow.raises);
|
|
1001
|
+
normal = bodyFlow.normal || catchFlow.normal;
|
|
1002
|
+
for (const binding of assignedOuterBindings) {
|
|
1003
|
+
binding.knownValue = undefined;
|
|
1004
|
+
scope.presenceProofs.delete(binding);
|
|
180
1005
|
}
|
|
181
|
-
alwaysReturns = consequentReturns && alternateReturns;
|
|
182
1006
|
continue;
|
|
183
1007
|
}
|
|
184
1008
|
const unexpected = /** @type {{kind: string, location: import("./types.js").SourceLocation}} */ (statement);
|
|
185
1009
|
fail("UNSUPPORTED_STATEMENT", unexpected.kind, unexpected.location);
|
|
186
1010
|
}
|
|
187
|
-
return
|
|
1011
|
+
return { normal, raises };
|
|
1012
|
+
}
|
|
1013
|
+
/**
|
|
1014
|
+
* Validates one exact nominal error type.
|
|
1015
|
+
* @param {unknown} type - Candidate type.
|
|
1016
|
+
* @param {import("./types.js").SourceLocation} location - Owning location.
|
|
1017
|
+
* @param {ErrorRegistry} errors - Visible error declarations.
|
|
1018
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
1019
|
+
* @returns {import("./types.js").ErrorType} Validated type.
|
|
1020
|
+
*/
|
|
1021
|
+
function validateErrorType(type, location, errors, fail) {
|
|
1022
|
+
if (!type || typeof type != "object" || Array.isArray(type)) {
|
|
1023
|
+
return fail("UNKNOWN_ERROR", "Handler or raise is missing an exact error type.", location);
|
|
1024
|
+
}
|
|
1025
|
+
const candidate = /** @type {import("./types.js").ErrorType} */ (type);
|
|
1026
|
+
if (candidate.kind != "ErrorType" ||
|
|
1027
|
+
Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",") != "declarationId,kind" ||
|
|
1028
|
+
typeof candidate.declarationId != "string" || !errors.has(candidate.declarationId)) {
|
|
1029
|
+
fail("UNKNOWN_ERROR", `Unknown error declaration '${String(candidate.declarationId)}'.`, typeLocation(candidate, location));
|
|
1030
|
+
}
|
|
1031
|
+
return candidate;
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Adds every source value to one set.
|
|
1035
|
+
* @param {Set<string>} target - Destination identities.
|
|
1036
|
+
* @param {Set<string>} source - Source identities.
|
|
1037
|
+
* @returns {void}
|
|
1038
|
+
*/
|
|
1039
|
+
function addAll(target, source) {
|
|
1040
|
+
for (const value of source)
|
|
1041
|
+
target.add(value);
|
|
1042
|
+
}
|
|
1043
|
+
/**
|
|
1044
|
+
* Adds unchecked errors raised while evaluating one expression.
|
|
1045
|
+
* @param {Set<string>} target - Destination identities.
|
|
1046
|
+
* @param {unknown} expression - Candidate semantic expression.
|
|
1047
|
+
* @param {Map<string, Set<string>>} callEffects - Inferred call effects.
|
|
1048
|
+
* @param {Map<string, Set<string>>} [methodEffects] - Inferred effects by resolved method identity.
|
|
1049
|
+
* @returns {void}
|
|
1050
|
+
*/
|
|
1051
|
+
function addExpressionEffects(target, expression, callEffects, methodEffects = new Map()) {
|
|
1052
|
+
const pending = [expression];
|
|
1053
|
+
const seen = new Set();
|
|
1054
|
+
while (pending.length > 0) {
|
|
1055
|
+
const value = pending.pop();
|
|
1056
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
1057
|
+
continue;
|
|
1058
|
+
seen.add(value);
|
|
1059
|
+
if (Reflect.get(value, "kind") == "CallExpression")
|
|
1060
|
+
addAll(target, callEffects.get(Reflect.get(value, "callee")) ?? new Set());
|
|
1061
|
+
if (Reflect.get(value, "kind") == "MethodCallExpression" || Reflect.get(value, "kind") == "ReferenceConstruction") {
|
|
1062
|
+
const failures = Reflect.get(value, "failureIds");
|
|
1063
|
+
if (Array.isArray(failures))
|
|
1064
|
+
for (const failure of failures)
|
|
1065
|
+
if (typeof failure == "string")
|
|
1066
|
+
target.add(failure);
|
|
1067
|
+
if (Reflect.get(value, "kind") == "MethodCallExpression") {
|
|
1068
|
+
addAll(target, methodEffects.get(Reflect.get(value, "method")) ?? new Set());
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
if (Reflect.get(value, "kind") == "EffectCallExpression") {
|
|
1072
|
+
const resolution = Reflect.get(value, "resolution");
|
|
1073
|
+
const failures = resolution && typeof resolution == "object" ? Reflect.get(resolution, "failureIds") : undefined;
|
|
1074
|
+
if (Array.isArray(failures))
|
|
1075
|
+
for (const failure of failures)
|
|
1076
|
+
if (typeof failure == "string")
|
|
1077
|
+
target.add(failure);
|
|
1078
|
+
}
|
|
1079
|
+
for (const [key, child] of Object.entries(value)) {
|
|
1080
|
+
if (["location", "sourceProvenance", "resolution"].includes(key))
|
|
1081
|
+
continue;
|
|
1082
|
+
if (Array.isArray(child))
|
|
1083
|
+
pending.push(...child);
|
|
1084
|
+
else if (child && typeof child == "object")
|
|
1085
|
+
pending.push(child);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Derives unchecked-error propagation over the resolved finite function graph.
|
|
1091
|
+
* This is validator state, never a checked effect in the public function signature.
|
|
1092
|
+
* @param {Map<string, import("./types.js").FunctionDeclaration>} functions - Resolved functions.
|
|
1093
|
+
* @param {Map<string, Set<string>>} [seedEffects] - Dependency effects keyed by local import name.
|
|
1094
|
+
* @param {Set<string>} [localFunctionNames] - Functions whose bodies belong to the current module.
|
|
1095
|
+
* @returns {Map<string, Set<string>>} Escaping error identities by source-visible function name.
|
|
1096
|
+
*/
|
|
1097
|
+
function inferCallEffects(functions, seedEffects = new Map(), localFunctionNames = new Set(functions.keys())) {
|
|
1098
|
+
const effects = new Map([...functions.keys()].map((name) => [name, new Set(seedEffects.get(name) ?? [])]));
|
|
1099
|
+
let changed = true;
|
|
1100
|
+
while (changed) {
|
|
1101
|
+
changed = false;
|
|
1102
|
+
for (const name of localFunctionNames) {
|
|
1103
|
+
const declaration = functions.get(name);
|
|
1104
|
+
if (!declaration)
|
|
1105
|
+
continue;
|
|
1106
|
+
const next = syntacticBlockEffects(declaration.body, effects);
|
|
1107
|
+
const current = /** @type {Set<string>} */ (effects.get(name));
|
|
1108
|
+
for (const error of next) {
|
|
1109
|
+
if (!current.has(error)) {
|
|
1110
|
+
current.add(error);
|
|
1111
|
+
changed = true;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
return effects;
|
|
1117
|
+
}
|
|
1118
|
+
/**
|
|
1119
|
+
* Computes escaping identities from one block for the call-effect fixed point.
|
|
1120
|
+
* @param {unknown} block - Candidate block.
|
|
1121
|
+
* @param {Map<string, Set<string>>} callEffects - Current fixed-point state.
|
|
1122
|
+
* @param {Map<string, Set<string>>} [methodEffects] - Current method fixed-point state.
|
|
1123
|
+
* @returns {Set<string>} Escaping identities.
|
|
1124
|
+
*/
|
|
1125
|
+
function syntacticBlockEffects(block, callEffects, methodEffects = new Map()) {
|
|
1126
|
+
const result = new Set();
|
|
1127
|
+
const statements = Reflect.get(/** @type {object} */ (block ?? {}), "statements");
|
|
1128
|
+
if (!Array.isArray(statements))
|
|
1129
|
+
return result;
|
|
1130
|
+
for (const statement of statements) {
|
|
1131
|
+
if (!statement || typeof statement != "object")
|
|
1132
|
+
continue;
|
|
1133
|
+
const kind = Reflect.get(statement, "kind");
|
|
1134
|
+
if (kind == "RaiseStatement") {
|
|
1135
|
+
const construction = Reflect.get(statement, "error");
|
|
1136
|
+
const type = construction && typeof construction == "object" ? Reflect.get(construction, "error") : undefined;
|
|
1137
|
+
const declarationId = type && typeof type == "object" ? Reflect.get(type, "declarationId") : undefined;
|
|
1138
|
+
if (typeof declarationId == "string")
|
|
1139
|
+
result.add(declarationId);
|
|
1140
|
+
if (construction && typeof construction == "object") {
|
|
1141
|
+
addExpressionEffects(result, Reflect.get(construction, "message"), callEffects, methodEffects);
|
|
1142
|
+
}
|
|
1143
|
+
continue;
|
|
1144
|
+
}
|
|
1145
|
+
if (kind == "TryStatement") {
|
|
1146
|
+
const bodyEffects = syntacticBlockEffects(Reflect.get(statement, "body"), callEffects, methodEffects);
|
|
1147
|
+
const catchType = Reflect.get(statement, "catchType");
|
|
1148
|
+
const caughtId = catchType && typeof catchType == "object" ? Reflect.get(catchType, "declarationId") : undefined;
|
|
1149
|
+
if (typeof caughtId == "string" && bodyEffects.delete(caughtId)) {
|
|
1150
|
+
addAll(bodyEffects, syntacticBlockEffects(Reflect.get(statement, "catchBody"), callEffects, methodEffects));
|
|
1151
|
+
}
|
|
1152
|
+
addAll(result, bodyEffects);
|
|
1153
|
+
continue;
|
|
1154
|
+
}
|
|
1155
|
+
if (kind == "IfStatement") {
|
|
1156
|
+
addExpressionEffects(result, Reflect.get(statement, "condition"), callEffects, methodEffects);
|
|
1157
|
+
addAll(result, syntacticBlockEffects(Reflect.get(statement, "consequent"), callEffects, methodEffects));
|
|
1158
|
+
addAll(result, syntacticBlockEffects(Reflect.get(statement, "alternate"), callEffects, methodEffects));
|
|
1159
|
+
continue;
|
|
1160
|
+
}
|
|
1161
|
+
if (kind == "ForEachStatement" || kind == "ForEachMapStatement") {
|
|
1162
|
+
addExpressionEffects(result, Reflect.get(statement, kind == "ForEachStatement" ? "list" : "map"), callEffects, methodEffects);
|
|
1163
|
+
addAll(result, syntacticBlockEffects(Reflect.get(statement, "body"), callEffects, methodEffects));
|
|
1164
|
+
continue;
|
|
1165
|
+
}
|
|
1166
|
+
if (kind == "WhileStatement") {
|
|
1167
|
+
addExpressionEffects(result, Reflect.get(statement, "condition"), callEffects, methodEffects);
|
|
1168
|
+
addAll(result, syntacticBlockEffects(Reflect.get(statement, "body"), callEffects, methodEffects));
|
|
1169
|
+
continue;
|
|
1170
|
+
}
|
|
1171
|
+
for (const key of ["expression", "initializer"]) {
|
|
1172
|
+
addExpressionEffects(result, Reflect.get(statement, key), callEffects, methodEffects);
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
return result;
|
|
1176
|
+
}
|
|
1177
|
+
/**
|
|
1178
|
+
* Derives the escaping user-defined error sets for local functions and resolved class methods.
|
|
1179
|
+
* The fixed point is computed over every unchecked error; capability failures are projected out
|
|
1180
|
+
* because call sites already carry their capability-failure boundary through resolution metadata.
|
|
1181
|
+
* @param {import("./types.js").SemanticModule} module - Resolved module.
|
|
1182
|
+
* @param {Map<string, Set<string>>} [seedEffects] - Dependency effects keyed by local import name.
|
|
1183
|
+
* @returns {{functions: Map<string, Set<string>>, methods: Map<string, Set<string>>}} Escaping user-defined error identities by function name and method identity.
|
|
1184
|
+
*/
|
|
1185
|
+
export function inferEscapingErrorEffects(module, seedEffects = new Map()) {
|
|
1186
|
+
const functions = new Map(module.functions.map((declaration) => [declaration.name, declaration]));
|
|
1187
|
+
const functionEffects = new Map([...functions.keys()].map((name) => [name, new Set(seedEffects.get(name) ?? [])]));
|
|
1188
|
+
const classes = module.classes ?? [];
|
|
1189
|
+
const methodEffects = new Map();
|
|
1190
|
+
const capabilityFailureIds = new Set((module.capabilities ?? []).flatMap(({ failures }) => failures).map(({ id }) => id));
|
|
1191
|
+
for (const declaration of classes)
|
|
1192
|
+
for (const method of declaration.methods)
|
|
1193
|
+
methodEffects.set(method.id, new Set());
|
|
1194
|
+
let changed = true;
|
|
1195
|
+
while (changed) {
|
|
1196
|
+
changed = false;
|
|
1197
|
+
for (const declaration of module.functions) {
|
|
1198
|
+
const current = /** @type {Set<string>} */ (functionEffects.get(declaration.name));
|
|
1199
|
+
for (const error of syntacticBlockEffects(declaration.body, functionEffects, methodEffects)) {
|
|
1200
|
+
if (!current.has(error)) {
|
|
1201
|
+
current.add(error);
|
|
1202
|
+
changed = true;
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
for (const declaration of classes) {
|
|
1207
|
+
for (const method of declaration.methods) {
|
|
1208
|
+
const current = /** @type {Set<string>} */ (methodEffects.get(method.id));
|
|
1209
|
+
for (const error of syntacticBlockEffects(method.body, functionEffects, methodEffects)) {
|
|
1210
|
+
if (!current.has(error)) {
|
|
1211
|
+
current.add(error);
|
|
1212
|
+
changed = true;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
for (const effects of [functionEffects, methodEffects]) {
|
|
1219
|
+
for (const errors of effects.values()) {
|
|
1220
|
+
for (const error of [...errors])
|
|
1221
|
+
if (capabilityFailureIds.has(error))
|
|
1222
|
+
errors.delete(error);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
return { functions: functionEffects, methods: methodEffects };
|
|
188
1226
|
}
|
|
189
1227
|
/**
|
|
190
1228
|
* Creates a lexical scope with declarations marked pending until visited.
|
|
191
1229
|
* @param {Scope | undefined} parent - Enclosing scope.
|
|
192
1230
|
* @param {{kind: string, name?: string}[]} statements - Scope statements.
|
|
193
1231
|
* @param {Set<string>} [reservedNames] - Names unavailable to root bindings.
|
|
1232
|
+
* @param {Set<string>} [typeParameters] - Declaration-scoped type parameters.
|
|
1233
|
+
* @param {import("./types.js").ClassDeclaration} [currentClass] - Declaring class for receiver-private access.
|
|
194
1234
|
* @returns {Scope} Scope.
|
|
195
1235
|
*/
|
|
196
|
-
function createScope(parent, statements, reservedNames = new Set()) {
|
|
1236
|
+
function createScope(parent, statements, reservedNames = new Set(), typeParameters = parent?.typeParameters ?? new Set(), currentClass = parent?.currentClass) {
|
|
197
1237
|
const pending = new Set(statements.filter((statement) => statement.kind == "LocalDeclaration")
|
|
198
1238
|
.map((statement) => /** @type {{name: string}} */ (statement).name));
|
|
199
|
-
return {
|
|
1239
|
+
return {
|
|
1240
|
+
bindings: new Map(),
|
|
1241
|
+
currentClass,
|
|
1242
|
+
parent,
|
|
1243
|
+
pending,
|
|
1244
|
+
presenceProofs: new Set(parent?.presenceProofs ?? []),
|
|
1245
|
+
typeParameters,
|
|
1246
|
+
usedNames: parent?.usedNames ?? new Set(reservedNames)
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Applies a simple-identifier presence proof to exactly the branch where the test is true.
|
|
1251
|
+
* @param {import("./types.js").Expression} condition - Validated branch condition.
|
|
1252
|
+
* @param {Scope} sourceScope - Scope containing the tested binding.
|
|
1253
|
+
* @param {Scope} branchScope - Branch-local proof scope.
|
|
1254
|
+
* @param {boolean} branchWhenTrue - Whether this is the condition's true branch.
|
|
1255
|
+
* @returns {void}
|
|
1256
|
+
*/
|
|
1257
|
+
function applyPresenceNarrowing(condition, sourceScope, branchScope, branchWhenTrue) {
|
|
1258
|
+
let test = condition;
|
|
1259
|
+
let presentWhenTrue = true;
|
|
1260
|
+
if (condition.kind == "UnaryExpression" && condition.operation == "BooleanNot" &&
|
|
1261
|
+
condition.operand.kind == "OptionalIsPresent") {
|
|
1262
|
+
test = condition.operand;
|
|
1263
|
+
presentWhenTrue = false;
|
|
1264
|
+
}
|
|
1265
|
+
if (test.kind != "OptionalIsPresent")
|
|
1266
|
+
return;
|
|
1267
|
+
const binding = findBinding(test.operand.name, sourceScope);
|
|
1268
|
+
if (!binding)
|
|
1269
|
+
return;
|
|
1270
|
+
if (branchWhenTrue == presentWhenTrue)
|
|
1271
|
+
branchScope.presenceProofs.add(binding);
|
|
1272
|
+
else
|
|
1273
|
+
branchScope.presenceProofs.delete(binding);
|
|
200
1274
|
}
|
|
201
1275
|
/**
|
|
202
1276
|
* Adds one binding while rejecting duplicates and shadowing.
|
|
@@ -233,71 +1307,698 @@ function resolveBinding(name, location, scope, fail) {
|
|
|
233
1307
|
return fail("UNRESOLVED_BINDING", `Unknown binding '${name}'.`, location);
|
|
234
1308
|
}
|
|
235
1309
|
/**
|
|
236
|
-
* Validates one semantic type reference.
|
|
1310
|
+
* Validates one semantic value type reference.
|
|
237
1311
|
* @param {unknown} type - Candidate semantic type reference.
|
|
238
1312
|
* @param {import("./types.js").SourceLocation} location - Owning source location.
|
|
239
1313
|
* @param {SemanticFail} fail - Diagnostic callback.
|
|
240
|
-
* @
|
|
1314
|
+
* @param {Set<object>} [seen] - Active recursive type path.
|
|
1315
|
+
* @param {RecordRegistry} [records] - Record declarations by identity.
|
|
1316
|
+
* @param {Set<string>} [typeParameters] - Type-variable identities in declaration scope.
|
|
1317
|
+
* @returns {import("./types.js").SemanticValueType} Validated value type.
|
|
241
1318
|
*/
|
|
242
|
-
function
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
if (candidate.kind != "TypeReference" || !isScalarTypeName(candidate.name)) {
|
|
248
|
-
fail("TYPE_MISMATCH", "Unsupported scalar type.", location);
|
|
249
|
-
}
|
|
250
|
-
return candidate.name;
|
|
1319
|
+
function validateValueTypeReference(type, location, fail, seen, records = new Map(), typeParameters = new Set()) {
|
|
1320
|
+
const candidate = validateTypeReference(type, location, fail, seen, records, typeParameters);
|
|
1321
|
+
if (isVoidType(candidate))
|
|
1322
|
+
return fail("VOID_AS_VALUE", "Void is valid only as a function return type.", typeLocation(type, location));
|
|
1323
|
+
return candidate;
|
|
251
1324
|
}
|
|
252
1325
|
/**
|
|
253
|
-
*
|
|
254
|
-
* @param {
|
|
255
|
-
* @param {
|
|
256
|
-
* @param {Map<string, import("./types.js").FunctionDeclaration>} functions - Module function signatures.
|
|
1326
|
+
* Validates one function return type reference.
|
|
1327
|
+
* @param {unknown} type - Candidate semantic return type reference.
|
|
1328
|
+
* @param {import("./types.js").SourceLocation} location - Owning source location.
|
|
257
1329
|
* @param {SemanticFail} fail - Diagnostic callback.
|
|
258
|
-
* @param {
|
|
259
|
-
* @
|
|
1330
|
+
* @param {RecordRegistry} [records] - Record declarations by identity.
|
|
1331
|
+
* @param {Set<string>} [typeParameters] - Type-variable identities in declaration scope.
|
|
1332
|
+
* @returns {import("./types.js").SemanticFunctionReturnType} Validated return type.
|
|
260
1333
|
*/
|
|
261
|
-
function
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
1334
|
+
function validateReturnTypeReference(type, location, fail, records = new Map(), typeParameters = new Set()) {
|
|
1335
|
+
return validateTypeReference(type, location, fail, new Set(), records, typeParameters);
|
|
1336
|
+
}
|
|
1337
|
+
/**
|
|
1338
|
+
* Validates one recursive semantic type-reference shape.
|
|
1339
|
+
* @param {unknown} type - Candidate semantic type reference.
|
|
1340
|
+
* @param {import("./types.js").SourceLocation} location - Owning source location.
|
|
1341
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
1342
|
+
* @param {Set<object>} [seen] - Active recursive type path.
|
|
1343
|
+
* @param {RecordRegistry} [records] - Record declarations by identity.
|
|
1344
|
+
* @param {Set<string>} [typeParameters] - Type-variable identities in declaration scope.
|
|
1345
|
+
* @returns {import("./types.js").SemanticFunctionReturnType} Validated type.
|
|
1346
|
+
*/
|
|
1347
|
+
function validateTypeReference(type, location, fail, seen = new Set(), records = new Map(), typeParameters = new Set()) {
|
|
1348
|
+
if (!type || typeof type != "object" || Array.isArray(type)) {
|
|
1349
|
+
return fail("TYPE_MISMATCH", "Unsupported semantic type.", location);
|
|
1350
|
+
}
|
|
1351
|
+
const candidate = /** @type {import("./types.js").SemanticFunctionReturnType} */ (type);
|
|
1352
|
+
if (["ListType", "MapType", "OptionalType", "OrderedMapType", "RecordType"].includes(candidate.kind) &&
|
|
1353
|
+
containsOwnedType(candidate)) {
|
|
1354
|
+
fail("RESOURCE_ALIAS", "Owned resources and references cannot be nested in value or generic types.", typeLocation(candidate, location));
|
|
1355
|
+
}
|
|
1356
|
+
if (candidate.kind == "TypeReference") {
|
|
1357
|
+
if (!isScalarTypeName(candidate.name) && candidate.name != "void") {
|
|
1358
|
+
fail("TYPE_MISMATCH", "Unsupported scalar or void return type.", typeLocation(candidate, location));
|
|
1359
|
+
}
|
|
1360
|
+
return candidate;
|
|
1361
|
+
}
|
|
1362
|
+
if (candidate.kind == "TypeVariableReference") {
|
|
1363
|
+
if (Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",") != "kind,location,parameterId" ||
|
|
1364
|
+
typeof candidate.parameterId != "string" || !typeParameters.has(candidate.parameterId)) {
|
|
1365
|
+
fail("FREE_TYPE_VARIABLE", `Free or unknown type variable '${String(candidate.parameterId)}'.`, typeLocation(candidate, location));
|
|
1366
|
+
}
|
|
1367
|
+
return candidate;
|
|
1368
|
+
}
|
|
1369
|
+
if (candidate.kind == "RecordType") {
|
|
1370
|
+
const keys = Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1371
|
+
const declaration = records.get(candidate.declarationId);
|
|
1372
|
+
if (!(["arguments,declarationId,kind", "declarationId,kind"].includes(keys)) ||
|
|
1373
|
+
typeof candidate.declarationId != "string" || !declaration) {
|
|
1374
|
+
fail("UNKNOWN_RECORD", `Unknown record declaration '${String(candidate.declarationId)}'.`, typeLocation(candidate, location));
|
|
1375
|
+
}
|
|
1376
|
+
const expectedArity = declaration.typeParameters?.length ?? 0;
|
|
1377
|
+
if (expectedArity > 0 && candidate.arguments === undefined) {
|
|
1378
|
+
fail("RAW_GENERIC_APPLICATION", `Generic record '${declaration.name}' requires ${expectedArity} type arguments.`, typeLocation(candidate, location));
|
|
1379
|
+
}
|
|
1380
|
+
if (expectedArity == 0 && candidate.arguments !== undefined) {
|
|
1381
|
+
fail("GENERIC_ARITY_MISMATCH", `Non-generic record '${declaration.name}' does not accept type arguments.`, typeLocation(candidate, location));
|
|
1382
|
+
}
|
|
1383
|
+
const candidateArguments = candidate.arguments;
|
|
1384
|
+
if (candidateArguments !== undefined && (!Array.isArray(candidateArguments) ||
|
|
1385
|
+
candidateArguments.some((_argument, index) => !Object.hasOwn(candidateArguments, index)))) {
|
|
1386
|
+
fail("TYPE_MISMATCH", "Generic record arguments must be a dense ordered array.", typeLocation(candidate, location));
|
|
1387
|
+
}
|
|
1388
|
+
const arguments_ = candidate.arguments ?? [];
|
|
1389
|
+
if (arguments_.length != expectedArity) {
|
|
1390
|
+
fail("GENERIC_ARITY_MISMATCH", `Record '${declaration.name}' has ${arguments_.length} type arguments; expected ${expectedArity}.`, typeLocation(candidate, location));
|
|
1391
|
+
}
|
|
1392
|
+
if (seen.has(candidate)) {
|
|
1393
|
+
return fail("TYPE_MISMATCH", "Recursive generic applications cannot contain cycles.", typeLocation(candidate, location));
|
|
1394
|
+
}
|
|
1395
|
+
seen.add(candidate);
|
|
1396
|
+
for (const argument of arguments_) {
|
|
1397
|
+
validateValueTypeReference(argument, typeLocation(argument, location), fail, seen, records, typeParameters);
|
|
1398
|
+
}
|
|
1399
|
+
seen.delete(candidate);
|
|
1400
|
+
return candidate;
|
|
1401
|
+
}
|
|
1402
|
+
if (candidate.kind == "ReferenceType") {
|
|
1403
|
+
const classes = referenceClassesFor(records);
|
|
1404
|
+
if (Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",") != "declarationId,kind" ||
|
|
1405
|
+
typeof candidate.declarationId != "string" || !classes.has(candidate.declarationId)) {
|
|
1406
|
+
fail("UNKNOWN_CLASS", `Unknown reference class declaration '${String(candidate.declarationId)}'.`, typeLocation(candidate, location));
|
|
1407
|
+
}
|
|
1408
|
+
return candidate;
|
|
1409
|
+
}
|
|
1410
|
+
if (candidate.kind == "OwnedResourceType") {
|
|
1411
|
+
if (Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",") != "kind,resourceId" ||
|
|
1412
|
+
typeof candidate.resourceId != "string" || !resourceIdsByRecordRegistry.get(records)?.has(candidate.resourceId)) {
|
|
1413
|
+
fail("RESOURCE_TYPE_MISMATCH", `Unknown owned resource '${String(candidate.resourceId)}'.`, typeLocation(candidate, location));
|
|
1414
|
+
}
|
|
1415
|
+
return candidate;
|
|
1416
|
+
}
|
|
1417
|
+
if (candidate.kind == "OwnedReferenceType") {
|
|
1418
|
+
const classes = referenceClassesFor(records);
|
|
1419
|
+
if (Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",") != "declarationId,kind" ||
|
|
1420
|
+
typeof candidate.declarationId != "string" || classes.get(candidate.declarationId)?.ownership?.kind != "ownedResource") {
|
|
1421
|
+
fail("RESOURCE_TYPE_MISMATCH", `Unknown owned reference '${String(candidate.declarationId)}'.`, typeLocation(candidate, location));
|
|
1422
|
+
}
|
|
1423
|
+
return candidate;
|
|
1424
|
+
}
|
|
1425
|
+
if (candidate.kind == "ListType") {
|
|
1426
|
+
if (seen.has(candidate))
|
|
1427
|
+
return fail("TYPE_MISMATCH", "Recursive collection types cannot contain cycles.", typeLocation(candidate, location));
|
|
1428
|
+
seen.add(candidate);
|
|
1429
|
+
const elementType = validateValueTypeReference(candidate.elementType, typeLocation(candidate, location, "elementType"), fail, seen, records, typeParameters);
|
|
1430
|
+
seen.delete(candidate);
|
|
1431
|
+
if (candidate.elementType !== elementType)
|
|
1432
|
+
candidate.elementType = elementType;
|
|
1433
|
+
return candidate;
|
|
1434
|
+
}
|
|
1435
|
+
if (candidate.kind == "MapType" || candidate.kind == "OrderedMapType") {
|
|
1436
|
+
const expectedFields = candidate.kind == "OrderedMapType" ? "keyType,kind,order,valueType" : "keyType,kind,valueType";
|
|
1437
|
+
if (Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",") != expectedFields) {
|
|
1438
|
+
return fail("TYPE_MISMATCH", `Malformed ${candidate.kind == "OrderedMapType" ? "ordered map" : "map"} type.`, typeLocation(candidate, location));
|
|
1439
|
+
}
|
|
1440
|
+
if (candidate.kind == "OrderedMapType" && candidate.order != "insertion") {
|
|
1441
|
+
return fail("TYPE_MISMATCH", "Ordered map type requires insertion order.", typeLocation(candidate, location));
|
|
1442
|
+
}
|
|
1443
|
+
if (seen.has(candidate))
|
|
1444
|
+
return fail("TYPE_MISMATCH", "Recursive collection types cannot contain cycles.", typeLocation(candidate, location));
|
|
1445
|
+
seen.add(candidate);
|
|
1446
|
+
const keyType = validateValueTypeReference(candidate.keyType, typeLocation(candidate, location, "keyType"), fail, seen, records, typeParameters);
|
|
1447
|
+
if (!isScalarType(keyType, "string")) {
|
|
1448
|
+
fail("TYPE_MISMATCH", `Map key type ${typeDescription(keyType)}; expected string.`, typeLocation(candidate.keyType, location));
|
|
1449
|
+
}
|
|
1450
|
+
const valueType = validateValueTypeReference(candidate.valueType, typeLocation(candidate, location, "valueType"), fail, seen, records, typeParameters);
|
|
1451
|
+
seen.delete(candidate);
|
|
1452
|
+
if (candidate.keyType !== keyType)
|
|
1453
|
+
candidate.keyType = /** @type {import("./types.js").TypeReference} */ (keyType);
|
|
1454
|
+
if (candidate.valueType !== valueType)
|
|
1455
|
+
candidate.valueType = valueType;
|
|
1456
|
+
return candidate;
|
|
1457
|
+
}
|
|
1458
|
+
if (candidate.kind == "OptionalType") {
|
|
1459
|
+
if (Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",") != "kind,valueType") {
|
|
1460
|
+
return fail("TYPE_MISMATCH", "Malformed optional type.", typeLocation(candidate, location));
|
|
1461
|
+
}
|
|
1462
|
+
if (seen.has(candidate))
|
|
1463
|
+
return fail("TYPE_MISMATCH", "Recursive optional types cannot contain cycles.", typeLocation(candidate, location));
|
|
1464
|
+
seen.add(candidate);
|
|
1465
|
+
const valueType = validateValueTypeReference(candidate.valueType, typeLocation(candidate, location, "valueType"), fail, seen, records, typeParameters);
|
|
1466
|
+
seen.delete(candidate);
|
|
1467
|
+
if (valueType.kind == "OptionalType") {
|
|
1468
|
+
fail("INVALID_OPTIONAL_CONSTITUENT", "Optional values cannot directly contain another optional.", typeLocation(candidate, location, "valueType"));
|
|
1469
|
+
}
|
|
1470
|
+
if (candidate.valueType !== valueType)
|
|
1471
|
+
candidate.valueType = valueType;
|
|
1472
|
+
return candidate;
|
|
1473
|
+
}
|
|
1474
|
+
return fail("TYPE_MISMATCH", "Unsupported semantic type.", typeLocation(candidate, location));
|
|
1475
|
+
}
|
|
1476
|
+
/**
|
|
1477
|
+
* Retrieves the reference-class registry attached to the record validation context.
|
|
1478
|
+
* @param {RecordRegistry} records - Record validation registry.
|
|
1479
|
+
* @returns {ClassRegistry} Reference classes.
|
|
1480
|
+
*/
|
|
1481
|
+
function referenceClassesFor(records) {
|
|
1482
|
+
return referenceClassesByRecordRegistry.get(records) ?? new Map();
|
|
1483
|
+
}
|
|
1484
|
+
/**
|
|
1485
|
+
* Infers a value expression and rejects the non-value result of a void call.
|
|
1486
|
+
* @param {import("./types.js").Expression} expression - Semantic expression.
|
|
1487
|
+
* @param {Scope} scope - Visible lexical scope.
|
|
1488
|
+
* @param {Map<string, import("./types.js").FunctionDeclaration>} functions - Module function signatures.
|
|
1489
|
+
* @param {RecordRegistry} records - Record declarations by identity.
|
|
1490
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
1491
|
+
* @param {boolean} normalizeOperations - Whether to normalize frontend intent and call resolution.
|
|
1492
|
+
* @param {string} context - Value context for diagnostics.
|
|
1493
|
+
* @param {import("./types.js").SemanticValueType} [expectedType] - Contextual collection type.
|
|
1494
|
+
* @param {boolean} [inferCollectionElements] - Whether a generic-call evidence pass may infer nonempty collection literals.
|
|
1495
|
+
* @returns {import("./types.js").SemanticValueType} Expression value type.
|
|
1496
|
+
*/
|
|
1497
|
+
function inferValueExpressionType(expression, scope, functions, records, fail, normalizeOperations, context, expectedType, inferCollectionElements = false) {
|
|
1498
|
+
const allowOwnedBorrow = context == "an effect argument" || context == "a method receiver";
|
|
1499
|
+
const type = inferExpressionType(expression, scope, functions, records, fail, normalizeOperations, expectedType, inferCollectionElements, allowOwnedBorrow);
|
|
1500
|
+
if (type == "void")
|
|
1501
|
+
return fail("VOID_AS_VALUE", `Void call cannot be used as ${context}.`, expression.location);
|
|
1502
|
+
if (type.kind == "ErrorType")
|
|
1503
|
+
return fail("TYPE_MISMATCH", `Error value cannot be used as ${context}.`, expression.location);
|
|
1504
|
+
return type;
|
|
1505
|
+
}
|
|
1506
|
+
/**
|
|
1507
|
+
* Infers and validates one expression.
|
|
1508
|
+
* @param {import("./types.js").Expression} expression - Semantic expression.
|
|
1509
|
+
* @param {Scope} scope - Visible lexical scope.
|
|
1510
|
+
* @param {Map<string, import("./types.js").FunctionDeclaration>} functions - Module function signatures.
|
|
1511
|
+
* @param {RecordRegistry} records - Record declarations by identity.
|
|
1512
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
1513
|
+
* @param {boolean} normalizeOperations - Whether to replace transient frontend operation intent.
|
|
1514
|
+
* @param {import("./types.js").SemanticValueType} [expectedType] - Contextual collection type.
|
|
1515
|
+
* @param {boolean} [inferCollectionElements] - Whether a generic-call evidence pass may infer nonempty collection literals.
|
|
1516
|
+
* @param {boolean} [allowOwnedBorrow] - Whether this exact call position admits an immediate borrow.
|
|
1517
|
+
* @returns {import("./types.js").SemanticBindingType | "void"} Expression type.
|
|
1518
|
+
*/
|
|
1519
|
+
function inferExpressionType(expression, scope, functions, records, fail, normalizeOperations, expectedType, inferCollectionElements = false, allowOwnedBorrow = false) {
|
|
1520
|
+
if (expression.kind == "IdentifierExpression")
|
|
1521
|
+
return resolveBinding(expression.name, expression.location, scope, fail).type;
|
|
1522
|
+
if (expression.kind == "ReceiverExpression") {
|
|
1523
|
+
if (!scope.currentClass || expression.classId != scope.currentClass.id) {
|
|
1524
|
+
return fail("ILLEGAL_PRIVATE_ACCESS", "Receiver expression is valid only inside its declaring class.", expression.location);
|
|
1525
|
+
}
|
|
1526
|
+
return { declarationId: /** @type {string} */ (scope.currentClass.id), kind: "ReferenceType" };
|
|
1527
|
+
}
|
|
1528
|
+
if (expression.kind == "PrivateFieldRead") {
|
|
1529
|
+
const declaration = scope.currentClass;
|
|
1530
|
+
if (!declaration || !expression.receiver || expression.receiver.kind != "ReceiverExpression" ||
|
|
1531
|
+
expression.receiver.classId != declaration.id) {
|
|
1532
|
+
return fail("ILLEGAL_PRIVATE_ACCESS", "Private field receiver must be the declaring class receiver.", expression.location);
|
|
1533
|
+
}
|
|
1534
|
+
const field = declaration.fields.find((candidate) => candidate.id == expression.field);
|
|
1535
|
+
if (!field)
|
|
1536
|
+
return fail("ILLEGAL_PRIVATE_ACCESS", "Private field identity is not owned by the declaring class.", expression.location);
|
|
1537
|
+
return field.type;
|
|
1538
|
+
}
|
|
1539
|
+
if (expression.kind == "OwnedBorrowExpression") {
|
|
1540
|
+
if (!allowOwnedBorrow) {
|
|
1541
|
+
return fail("BORROW_ESCAPE", "BORROW_ESCAPE: Owned borrows are valid only as immediate capability arguments or method receivers.", expression.location);
|
|
1542
|
+
}
|
|
1543
|
+
if (expression.mode != "shared" && expression.mode != "exclusive") {
|
|
1544
|
+
return fail("INVALID_RESOURCE_BORROW", "INVALID_RESOURCE_BORROW: Owned borrow mode must be shared or exclusive.", expression.location);
|
|
1545
|
+
}
|
|
1546
|
+
const borrowed = inferValueExpressionType(expression.expression, scope, functions, records, fail, normalizeOperations, "an owned borrow");
|
|
1547
|
+
if (borrowed.kind != "OwnedResourceType" && borrowed.kind != "OwnedReferenceType") {
|
|
1548
|
+
return fail("INVALID_RESOURCE_BORROW", "Borrowed expression must be an owned resource or owned reference.", expression.location);
|
|
1549
|
+
}
|
|
1550
|
+
if (!sameType(borrowed, expression.type)) {
|
|
1551
|
+
fail("RESOURCE_TYPE_MISMATCH", "Borrow metadata does not match its resource place.", expression.location);
|
|
1552
|
+
}
|
|
1553
|
+
return borrowed;
|
|
1554
|
+
}
|
|
1555
|
+
if (expression.kind == "OwnedMoveExpression") {
|
|
1556
|
+
const moved = inferValueExpressionType(expression.expression, scope, functions, records, fail, normalizeOperations, "an owned move");
|
|
1557
|
+
if (moved.kind != "OwnedResourceType" && moved.kind != "OwnedReferenceType") {
|
|
1558
|
+
return fail("INVALID_RESOURCE_TRANSFER", "Moved expression must be an owned resource or owned reference.", expression.location);
|
|
1559
|
+
}
|
|
1560
|
+
if (!sameType(moved, expression.type)) {
|
|
1561
|
+
fail("RESOURCE_TYPE_MISMATCH", "Move metadata does not match its resource place.", expression.location);
|
|
1562
|
+
}
|
|
1563
|
+
return moved;
|
|
1564
|
+
}
|
|
1565
|
+
if (expression.kind == "ErrorMessageRead") {
|
|
1566
|
+
if (!expression.receiver || expression.receiver.kind != "IdentifierExpression") {
|
|
1567
|
+
return fail("INVALID_MEMBER_RECEIVER", "Error message receiver must be one catch binding.", expression.location);
|
|
1568
|
+
}
|
|
1569
|
+
const receiver = resolveBinding(expression.receiver.name, expression.receiver.location, scope, fail);
|
|
1570
|
+
if (receiver.type.kind != "ErrorType") {
|
|
1571
|
+
return fail("INVALID_MEMBER_RECEIVER", "Message member requires a typed error catch binding.", expression.receiver.location);
|
|
1572
|
+
}
|
|
1573
|
+
return scalarType("string");
|
|
1574
|
+
}
|
|
1575
|
+
if (expression.kind == "IntegerLiteral") {
|
|
1576
|
+
if (!Number.isSafeInteger(expression.value))
|
|
1577
|
+
fail("TYPE_MISMATCH", "Non-safe integer literal.", expression.location);
|
|
1578
|
+
return scalarType("integer");
|
|
1579
|
+
}
|
|
1580
|
+
if (expression.kind == "BooleanLiteral") {
|
|
1581
|
+
if (typeof Reflect.get(expression, "value") != "boolean") {
|
|
271
1582
|
fail("TYPE_MISMATCH", "Invalid boolean literal value.", expression.location);
|
|
272
1583
|
}
|
|
273
|
-
return "boolean";
|
|
1584
|
+
return scalarType("boolean");
|
|
274
1585
|
}
|
|
275
1586
|
if (expression.kind == "StringLiteral") {
|
|
276
1587
|
const value = Reflect.get(expression, "value");
|
|
277
1588
|
if (typeof value != "string" || !hasOnlyUnicodeScalars(value)) {
|
|
278
1589
|
fail("TYPE_MISMATCH", "Invalid Unicode string literal.", expression.location);
|
|
279
1590
|
}
|
|
280
|
-
return "string";
|
|
1591
|
+
return scalarType("string");
|
|
1592
|
+
}
|
|
1593
|
+
if (expression.kind == "OptionalNone") {
|
|
1594
|
+
if (!expectedType || expectedType.kind != "OptionalType") {
|
|
1595
|
+
return fail("MISSING_TYPE", "Optional absence requires an explicit optional type.", expression.location);
|
|
1596
|
+
}
|
|
1597
|
+
return expectedType;
|
|
1598
|
+
}
|
|
1599
|
+
if (expression.kind == "OptionalSome") {
|
|
1600
|
+
if (!expectedType || expectedType.kind != "OptionalType") {
|
|
1601
|
+
const valueType = inferValueExpressionType(expression.value, scope, functions, records, fail, normalizeOperations, "an optional present value");
|
|
1602
|
+
if (valueType.kind == "OptionalType") {
|
|
1603
|
+
return fail("INVALID_OPTIONAL_CONSTITUENT", "Optional values cannot directly contain another optional.", expression.value.location);
|
|
1604
|
+
}
|
|
1605
|
+
return { kind: "OptionalType", valueType };
|
|
1606
|
+
}
|
|
1607
|
+
const valueType = inferValueExpressionType(expression.value, scope, functions, records, fail, normalizeOperations, "an optional present value", expectedType.valueType);
|
|
1608
|
+
if (!sameType(valueType, expectedType.valueType)) {
|
|
1609
|
+
fail("TYPE_MISMATCH", `Optional present type ${typeDescription(valueType)}; expected ${typeDescription(expectedType.valueType)}.`, expression.value.location);
|
|
1610
|
+
}
|
|
1611
|
+
return expectedType;
|
|
1612
|
+
}
|
|
1613
|
+
if (expression.kind == "OptionalIsPresent") {
|
|
1614
|
+
if (!expression.operand || expression.operand.kind != "IdentifierExpression") {
|
|
1615
|
+
return fail("TYPE_MISMATCH", "Optional presence test requires one simple identifier.", expression.location);
|
|
1616
|
+
}
|
|
1617
|
+
const operandType = resolveBinding(expression.operand.name, expression.operand.location, scope, fail).type;
|
|
1618
|
+
if (operandType.kind != "OptionalType") {
|
|
1619
|
+
return fail("TYPE_MISMATCH", `Presence test received ${typeDescription(operandType)}; expected optional.`, expression.operand.location);
|
|
1620
|
+
}
|
|
1621
|
+
return scalarType("boolean");
|
|
1622
|
+
}
|
|
1623
|
+
if (expression.kind == "OptionalUnwrap") {
|
|
1624
|
+
if (!expression.operand || expression.operand.kind != "IdentifierExpression") {
|
|
1625
|
+
return fail("TYPE_MISMATCH", "Optional unwrap requires one simple identifier.", expression.location);
|
|
1626
|
+
}
|
|
1627
|
+
const binding = resolveBinding(expression.operand.name, expression.operand.location, scope, fail);
|
|
1628
|
+
if (binding.type.kind != "OptionalType") {
|
|
1629
|
+
return fail("TYPE_MISMATCH", `Optional unwrap received ${typeDescription(binding.type)}; expected optional.`, expression.operand.location);
|
|
1630
|
+
}
|
|
1631
|
+
if (!scope.presenceProofs.has(binding)) {
|
|
1632
|
+
return fail("UNCHECKED_OPTIONAL_UNWRAP", `Optional binding '${expression.operand.name}' is not proven present.`, expression.location);
|
|
1633
|
+
}
|
|
1634
|
+
return binding.type.valueType;
|
|
1635
|
+
}
|
|
1636
|
+
if (expression.kind == "ListLiteral") {
|
|
1637
|
+
if (!Array.isArray(expression.elements)) {
|
|
1638
|
+
return fail("TYPE_MISMATCH", "List literal elements must be a dense source-ordered array.", expression.location);
|
|
1639
|
+
}
|
|
1640
|
+
if ((!expectedType || expectedType.kind != "ListType") &&
|
|
1641
|
+
(!inferCollectionElements || expression.elements.length == 0)) {
|
|
1642
|
+
return fail("MISSING_TYPE", "List literal requires an explicit recursive list type.", expression.location);
|
|
1643
|
+
}
|
|
1644
|
+
/** @type {import("./types.js").SemanticValueType | undefined} */
|
|
1645
|
+
let inferredElementType;
|
|
1646
|
+
for (let index = 0; index < expression.elements.length; index++) {
|
|
1647
|
+
if (!Object.hasOwn(expression.elements, index)) {
|
|
1648
|
+
fail("TYPE_MISMATCH", "Sparse list literals are outside the implemented subset.", expression.location);
|
|
1649
|
+
}
|
|
1650
|
+
const element = expression.elements[index];
|
|
1651
|
+
const actual = inferValueExpressionType(element, scope, functions, records, fail, normalizeOperations, "a list element", expectedType?.kind == "ListType" ? expectedType.elementType : inferredElementType, inferCollectionElements);
|
|
1652
|
+
inferredElementType ??= actual;
|
|
1653
|
+
const requiredElementType = expectedType?.kind == "ListType" ? expectedType.elementType : inferredElementType;
|
|
1654
|
+
if (!sameType(actual, requiredElementType)) {
|
|
1655
|
+
fail("TYPE_MISMATCH", `List element type ${typeDescription(actual)}; expected ${typeDescription(requiredElementType)}.`, element.location);
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
return expectedType?.kind == "ListType"
|
|
1659
|
+
? expectedType
|
|
1660
|
+
: { elementType: /** @type {import("./types.js").SemanticValueType} */ (inferredElementType), kind: "ListType" };
|
|
1661
|
+
}
|
|
1662
|
+
if (expression.kind == "MapLiteral") {
|
|
1663
|
+
if (expectedType && expectedType.kind != "MapType") {
|
|
1664
|
+
return fail("TYPE_MISMATCH", `Map literal context ${typeDescription(expectedType)}; expected map.`, expression.location);
|
|
1665
|
+
}
|
|
1666
|
+
if (!expectedType && !inferCollectionElements) {
|
|
1667
|
+
return fail("MISSING_TYPE", "Map literal requires an explicit recursive map type.", expression.location);
|
|
1668
|
+
}
|
|
1669
|
+
if (expectedType?.kind == "MapType" && !isScalarType(expectedType.keyType, "string")) {
|
|
1670
|
+
return fail("TYPE_MISMATCH", "Map key type must be string.", typeLocation(expectedType.keyType, expression.location));
|
|
1671
|
+
}
|
|
1672
|
+
const entries = validateMapLiteralEntries(expression, scope, functions, records, fail, normalizeOperations, inferCollectionElements);
|
|
1673
|
+
if (!expectedType && entries.length == 0) {
|
|
1674
|
+
return fail("MISSING_TYPE", "Empty map literal requires an explicit recursive map type.", expression.location);
|
|
1675
|
+
}
|
|
1676
|
+
/** @type {import("./types.js").SemanticValueType | undefined} */
|
|
1677
|
+
let inferredValueType;
|
|
1678
|
+
for (const entry of entries) {
|
|
1679
|
+
const actual = inferValueExpressionType(entry.value, scope, functions, records, fail, normalizeOperations, "a map value", expectedType?.kind == "MapType" ? expectedType.valueType : inferredValueType, inferCollectionElements);
|
|
1680
|
+
inferredValueType ??= actual;
|
|
1681
|
+
const requiredValueType = expectedType?.kind == "MapType" ? expectedType.valueType : inferredValueType;
|
|
1682
|
+
if (!sameType(actual, requiredValueType)) {
|
|
1683
|
+
fail("TYPE_MISMATCH", `Map value type ${typeDescription(actual)}; expected ${typeDescription(requiredValueType)}.`, entry.value.location);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
return expectedType?.kind == "MapType" ? expectedType : {
|
|
1687
|
+
keyType: scalarType("string"),
|
|
1688
|
+
kind: "MapType",
|
|
1689
|
+
valueType: /** @type {import("./types.js").SemanticValueType} */ (inferredValueType)
|
|
1690
|
+
};
|
|
1691
|
+
}
|
|
1692
|
+
if (expression.kind == "OrderedMapLiteral") {
|
|
1693
|
+
if (expectedType && expectedType.kind != "OrderedMapType") {
|
|
1694
|
+
return fail("TYPE_MISMATCH", `Ordered-map literal context ${typeDescription(expectedType)}; expected ordered map.`, expression.location);
|
|
1695
|
+
}
|
|
1696
|
+
if (!expectedType && !inferCollectionElements) {
|
|
1697
|
+
return fail("MISSING_TYPE", "Ordered-map literal requires an explicit recursive ordered-map type.", expression.location);
|
|
1698
|
+
}
|
|
1699
|
+
if (expectedType?.kind == "OrderedMapType" && !isScalarType(expectedType.keyType, "string")) {
|
|
1700
|
+
return fail("TYPE_MISMATCH", "Ordered-map key type must be string.", typeLocation(expectedType.keyType, expression.location));
|
|
1701
|
+
}
|
|
1702
|
+
const entries = validateMapLiteralEntries(expression, scope, functions, records, fail, normalizeOperations, inferCollectionElements);
|
|
1703
|
+
if (!expectedType && entries.length == 0) {
|
|
1704
|
+
return fail("MISSING_TYPE", "Empty ordered-map literal requires an explicit recursive ordered-map type.", expression.location);
|
|
1705
|
+
}
|
|
1706
|
+
/** @type {import("./types.js").SemanticValueType | undefined} */
|
|
1707
|
+
let inferredValueType;
|
|
1708
|
+
for (const entry of entries) {
|
|
1709
|
+
const actual = inferValueExpressionType(entry.value, scope, functions, records, fail, normalizeOperations, "an ordered-map value", expectedType?.kind == "OrderedMapType" ? expectedType.valueType : inferredValueType, inferCollectionElements);
|
|
1710
|
+
inferredValueType ??= actual;
|
|
1711
|
+
const requiredValueType = expectedType?.kind == "OrderedMapType" ? expectedType.valueType : inferredValueType;
|
|
1712
|
+
if (!sameType(actual, requiredValueType)) {
|
|
1713
|
+
fail("TYPE_MISMATCH", `Ordered-map value type ${typeDescription(actual)}; expected ${typeDescription(requiredValueType)}.`, entry.value.location);
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
return expectedType?.kind == "OrderedMapType" ? expectedType : {
|
|
1717
|
+
keyType: scalarType("string"),
|
|
1718
|
+
kind: "OrderedMapType",
|
|
1719
|
+
order: "insertion",
|
|
1720
|
+
valueType: /** @type {import("./types.js").SemanticValueType} */ (inferredValueType)
|
|
1721
|
+
};
|
|
1722
|
+
}
|
|
1723
|
+
if (expression.kind == "ListIndexExpression") {
|
|
1724
|
+
const collectionType = inferValueExpressionType(expression.collection, scope, functions, records, fail, normalizeOperations, "a list receiver");
|
|
1725
|
+
const indexType = inferValueExpressionType(expression.index, scope, functions, records, fail, normalizeOperations, "a list index", scalarType("integer"));
|
|
1726
|
+
if (collectionType.kind != "ListType") {
|
|
1727
|
+
return fail("TYPE_MISMATCH", `List index receiver type ${typeDescription(collectionType)}; expected list.`, expression.collection.location);
|
|
1728
|
+
}
|
|
1729
|
+
if (!isScalarType(indexType, "integer")) {
|
|
1730
|
+
fail("TYPE_MISMATCH", `List index type ${typeDescription(indexType)}; expected integer.`, expression.index.location);
|
|
1731
|
+
}
|
|
1732
|
+
const knownCollection = knownValueForExpression(expression.collection, scope);
|
|
1733
|
+
const knownIndex = knownValueForExpression(expression.index, scope);
|
|
1734
|
+
if (knownCollection?.kind == "ListLiteral" && knownIndex?.kind == "IntegerLiteral" &&
|
|
1735
|
+
(knownIndex.value < 0 || knownIndex.value >= knownCollection.elements.length)) {
|
|
1736
|
+
fail("INDEX_OUT_OF_BOUNDS", `List index ${knownIndex.value} is outside a literal list of size ${knownCollection.elements.length}.`, expression.location);
|
|
1737
|
+
}
|
|
1738
|
+
const proven = provenListElement(expression.collection, expression.index, scope);
|
|
1739
|
+
validateAccessTotality(expression, proven !== undefined, normalizeOperations, fail);
|
|
1740
|
+
return collectionType.elementType;
|
|
1741
|
+
}
|
|
1742
|
+
if (expression.kind == "MapLookupExpression") {
|
|
1743
|
+
const collectionType = inferValueExpressionType(expression.collection, scope, functions, records, fail, normalizeOperations, "a map receiver");
|
|
1744
|
+
const keyType = inferValueExpressionType(expression.key, scope, functions, records, fail, normalizeOperations, "a map key", scalarType("string"));
|
|
1745
|
+
if (collectionType.kind != "MapType" && collectionType.kind != "OrderedMapType") {
|
|
1746
|
+
return fail("TYPE_MISMATCH", `Map lookup receiver type ${typeDescription(collectionType)}; expected map.`, expression.collection.location);
|
|
1747
|
+
}
|
|
1748
|
+
if (!isScalarType(keyType, "string")) {
|
|
1749
|
+
fail("TYPE_MISMATCH", `Map lookup key type ${typeDescription(keyType)}; expected string.`, expression.key.location);
|
|
1750
|
+
}
|
|
1751
|
+
const knownCollection = knownValueForExpression(expression.collection, scope);
|
|
1752
|
+
const knownKey = knownValueForExpression(expression.key, scope);
|
|
1753
|
+
if ((knownCollection?.kind == "MapLiteral" || knownCollection?.kind == "OrderedMapLiteral") &&
|
|
1754
|
+
knownKey?.kind == "StringLiteral" &&
|
|
1755
|
+
!knownCollection.entries.some((entry) => entry.key.value == knownKey.value)) {
|
|
1756
|
+
fail("MISSING_MAP_KEY", `Map key '${knownKey.value}' is absent from the literal initializer.`, expression.location);
|
|
1757
|
+
}
|
|
1758
|
+
const proven = provenMapValue(expression.collection, expression.key, scope);
|
|
1759
|
+
validateAccessTotality(expression, proven !== undefined, normalizeOperations, fail);
|
|
1760
|
+
return collectionType.valueType;
|
|
1761
|
+
}
|
|
1762
|
+
if (expression.kind == "CollectionSizeExpression") {
|
|
1763
|
+
const collectionType = inferValueExpressionType(expression.collection, scope, functions, records, fail, normalizeOperations, "a collection-size receiver");
|
|
1764
|
+
if (collectionType.kind != "ListType" && collectionType.kind != "MapType" && collectionType.kind != "OrderedMapType") {
|
|
1765
|
+
return fail("TYPE_MISMATCH", `Collection size receiver type ${typeDescription(collectionType)}; expected list or map.`, expression.collection.location);
|
|
1766
|
+
}
|
|
1767
|
+
const collectionKind = collectionType.kind == "ListType" ? "list" : "map";
|
|
1768
|
+
if (normalizeOperations) {
|
|
1769
|
+
if (expression.collectionKind !== undefined && expression.collectionKind != collectionKind) {
|
|
1770
|
+
fail("TYPE_MISMATCH", "Collection size operation does not match its receiver type.", expression.location);
|
|
1771
|
+
}
|
|
1772
|
+
expression.collectionKind = collectionKind;
|
|
1773
|
+
}
|
|
1774
|
+
else if (expression.collectionKind != collectionKind) {
|
|
1775
|
+
fail("TYPE_MISMATCH", "Collection size kind does not match its receiver type.", expression.location);
|
|
1776
|
+
}
|
|
1777
|
+
return scalarType("integer");
|
|
1778
|
+
}
|
|
1779
|
+
if (expression.kind == "EffectCallExpression") {
|
|
1780
|
+
if (!Array.isArray(expression.arguments) || expression.arguments.length != expression.resolution.parameterTypes.length) {
|
|
1781
|
+
return fail("TYPE_MISMATCH", "Effect call argument count does not match its authorized operation.", expression.location);
|
|
1782
|
+
}
|
|
1783
|
+
const resourceFlow = expression.resolution.resourceFlow;
|
|
1784
|
+
if (resourceFlow.kind == "borrow" || resourceFlow.kind == "close") {
|
|
1785
|
+
const borrow = expression.arguments[resourceFlow.parameterIndex];
|
|
1786
|
+
const expectedMode = resourceFlow.kind == "close" ? "exclusive" : "shared";
|
|
1787
|
+
if (borrow?.kind != "OwnedBorrowExpression" || borrow.mode != expectedMode) {
|
|
1788
|
+
fail("INVALID_RESOURCE_BORROW", `INVALID_RESOURCE_BORROW: ${resourceFlow.kind} requires an immediate ${expectedMode} borrow.`, borrow?.location ?? expression.location);
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
for (let index = 0; index < expression.arguments.length; index += 1) {
|
|
1792
|
+
const expected = identityAsValueType(expression.resolution.parameterTypes[index], expression.arguments[index].location, fail);
|
|
1793
|
+
const actual = inferValueExpressionType(expression.arguments[index], scope, functions, records, fail, normalizeOperations, "an effect argument", expected);
|
|
1794
|
+
if (!sameType(actual, expected)) {
|
|
1795
|
+
fail("RESOURCE_TYPE_MISMATCH", `Effect argument type ${typeDescription(actual)}; expected ${typeDescription(expected)}.`, expression.arguments[index].location);
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
if (expression.resolution.returnType == "void")
|
|
1799
|
+
return "void";
|
|
1800
|
+
return identityAsValueType(expression.resolution.returnType, expression.location, fail);
|
|
1801
|
+
}
|
|
1802
|
+
if (expression.kind == "ReferenceConstruction") {
|
|
1803
|
+
const referenceType = validateValueTypeReference(expression.reference, expression.location, fail, undefined, records, scope.typeParameters);
|
|
1804
|
+
if (referenceType.kind != "ReferenceType" && referenceType.kind != "OwnedReferenceType") {
|
|
1805
|
+
return fail("TYPE_MISMATCH", "Reference construction requires a nominal reference class type.", expression.location);
|
|
1806
|
+
}
|
|
1807
|
+
const declaration = referenceClassesFor(records).get(referenceType.declarationId);
|
|
1808
|
+
if (!declaration)
|
|
1809
|
+
return fail("UNKNOWN_CLASS", `Unknown reference class '${referenceType.declarationId}'.`, expression.location);
|
|
1810
|
+
if (!isDenseArray(expression.arguments)) {
|
|
1811
|
+
return fail("TYPE_MISMATCH", "Constructor arguments must be a dense ordered array.", expression.location);
|
|
1812
|
+
}
|
|
1813
|
+
if (expression.arguments.length != declaration.constructor.parameters.length) {
|
|
1814
|
+
return fail("CONSTRUCTOR_ARITY_MISMATCH", `Constructor for '${declaration.name}' has ${expression.arguments.length} arguments; expected ${declaration.constructor.parameters.length}.`, expression.location);
|
|
1815
|
+
}
|
|
1816
|
+
const parameterTypes = declaration.constructor.parameters.map((parameter) => validateValueTypeReference(parameter.type, parameter.location, fail, undefined, records));
|
|
1817
|
+
for (let index = 0; index < expression.arguments.length; index += 1) {
|
|
1818
|
+
expression.arguments[index] = normalizeOwnedMove(expression.arguments[index], parameterTypes[index], normalizeOperations, fail);
|
|
1819
|
+
const actual = inferValueExpressionType(expression.arguments[index], scope, functions, records, fail, normalizeOperations, "a constructor argument", parameterTypes[index]);
|
|
1820
|
+
if (!sameType(actual, parameterTypes[index])) {
|
|
1821
|
+
fail("TYPE_MISMATCH", `Constructor argument type ${typeDescription(actual)}; expected ${typeDescription(parameterTypes[index])}.`, expression.arguments[index].location);
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
const resolution = {
|
|
1825
|
+
declarationId: /** @type {string} */ (declaration.constructor.id),
|
|
1826
|
+
kind: /** @type {const} */ ("ResolvedConstructorSignature"),
|
|
1827
|
+
parameterTypes: parameterTypes.map((type) => /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type)))
|
|
1828
|
+
};
|
|
1829
|
+
if (normalizeOperations)
|
|
1830
|
+
expression.resolution = resolution;
|
|
1831
|
+
else
|
|
1832
|
+
validateReferenceResolution(expression.resolution, resolution, expression.location, fail, "constructor");
|
|
1833
|
+
return referenceType;
|
|
1834
|
+
}
|
|
1835
|
+
if (expression.kind == "MethodCallExpression") {
|
|
1836
|
+
const receiverType = inferValueExpressionType(expression.receiver, scope, functions, records, fail, normalizeOperations, "a method receiver");
|
|
1837
|
+
if (receiverType.kind != "ReferenceType" && receiverType.kind != "OwnedReferenceType") {
|
|
1838
|
+
return fail("INVALID_METHOD_RECEIVER", "Method call receiver must have a reference class type.", expression.receiver.location);
|
|
1839
|
+
}
|
|
1840
|
+
const declaration = referenceClassesFor(records).get(receiverType.declarationId);
|
|
1841
|
+
if (!declaration)
|
|
1842
|
+
return fail("UNKNOWN_CLASS", `Unknown reference class '${receiverType.declarationId}'.`, expression.receiver.location);
|
|
1843
|
+
const method = declaration.methods.find((candidate) => candidate.id == expression.method) ??
|
|
1844
|
+
(normalizeOperations ? declaration.methods.find((candidate) => candidate.name == expression.method) : undefined);
|
|
1845
|
+
if (!method)
|
|
1846
|
+
return fail("UNKNOWN_METHOD", `Class '${declaration.name}' has no method '${expression.method}'.`, roleLocation(expression, "member"));
|
|
1847
|
+
if (normalizeOperations)
|
|
1848
|
+
expression.method = /** @type {string} */ (method.id);
|
|
1849
|
+
if (!isDenseArray(expression.arguments))
|
|
1850
|
+
return fail("TYPE_MISMATCH", "Method arguments must be a dense ordered array.", expression.location);
|
|
1851
|
+
if (expression.arguments.length != method.parameters.length) {
|
|
1852
|
+
return fail("METHOD_ARITY_MISMATCH", `Method '${method.name}' has ${expression.arguments.length} arguments; expected ${method.parameters.length}.`, expression.location);
|
|
1853
|
+
}
|
|
1854
|
+
const parameterTypes = method.parameters.map((parameter) => validateValueTypeReference(parameter.type, parameter.location, fail, undefined, records));
|
|
1855
|
+
for (let index = 0; index < expression.arguments.length; index += 1) {
|
|
1856
|
+
expression.arguments[index] = normalizeOwnedMove(expression.arguments[index], parameterTypes[index], normalizeOperations, fail);
|
|
1857
|
+
const actual = inferValueExpressionType(expression.arguments[index], scope, functions, records, fail, normalizeOperations, "a method argument", parameterTypes[index]);
|
|
1858
|
+
if (!sameType(actual, parameterTypes[index])) {
|
|
1859
|
+
fail("TYPE_MISMATCH", `Method argument type ${typeDescription(actual)}; expected ${typeDescription(parameterTypes[index])}.`, expression.arguments[index].location);
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
const returnType = validateReturnTypeReference(method.returnType, method.location, fail, records);
|
|
1863
|
+
const resourceFlow = declaration.ownership?.kind == "ownedResource"
|
|
1864
|
+
? ownedMethodResourceFlow(declaration, method, fail) : undefined;
|
|
1865
|
+
const resolution = {
|
|
1866
|
+
declarationId: /** @type {string} */ (method.id),
|
|
1867
|
+
kind: /** @type {const} */ ("ResolvedMethodSignature"),
|
|
1868
|
+
parameterTypes: parameterTypes.map((type) => /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type))),
|
|
1869
|
+
returnType: typeIdentity(returnType),
|
|
1870
|
+
...(resourceFlow ? { resourceFlow } : {})
|
|
1871
|
+
};
|
|
1872
|
+
if (expression.receiver.kind == "OwnedBorrowExpression" && resourceFlow) {
|
|
1873
|
+
const expectedMode = resourceFlow.kind == "terminal" ? "exclusive" : "shared";
|
|
1874
|
+
if (expression.receiver.mode != expectedMode) {
|
|
1875
|
+
fail("INVALID_RESOURCE_BORROW", `INVALID_RESOURCE_BORROW: Owned method requires an immediate ${expectedMode} receiver borrow.`, expression.receiver.location);
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
if (receiverType.kind == "OwnedReferenceType" && expression.receiver.kind != "OwnedBorrowExpression") {
|
|
1879
|
+
if (!normalizeOperations)
|
|
1880
|
+
fail("INVALID_RESOURCE_BORROW", "Owned method receiver requires an immediate borrow.", expression.receiver.location);
|
|
1881
|
+
if (expression.receiver.kind != "IdentifierExpression") {
|
|
1882
|
+
fail("BORROW_ESCAPE", "Owned method receiver borrow must name one immediate binding.", expression.receiver.location);
|
|
1883
|
+
}
|
|
1884
|
+
expression.receiver = {
|
|
1885
|
+
expression: expression.receiver,
|
|
1886
|
+
kind: "OwnedBorrowExpression",
|
|
1887
|
+
location: expression.receiver.location,
|
|
1888
|
+
mode: resourceFlow?.kind == "terminal" ? "exclusive" : "shared",
|
|
1889
|
+
sourceProvenance: expression.receiver.sourceProvenance,
|
|
1890
|
+
type: receiverType
|
|
1891
|
+
};
|
|
1892
|
+
}
|
|
1893
|
+
if (normalizeOperations)
|
|
1894
|
+
expression.resolution = resolution;
|
|
1895
|
+
else
|
|
1896
|
+
validateReferenceResolution(expression.resolution, resolution, expression.location, fail, "method");
|
|
1897
|
+
return isVoidType(returnType) ? "void" : returnType;
|
|
1898
|
+
}
|
|
1899
|
+
if (expression.kind == "RecordConstruction") {
|
|
1900
|
+
const recordType = validateValueTypeReference(expression.record, expression.location, fail, undefined, records, scope.typeParameters);
|
|
1901
|
+
if (recordType.kind != "RecordType") {
|
|
1902
|
+
return fail("TYPE_MISMATCH", "Record construction requires a nominal record type.", expression.location);
|
|
1903
|
+
}
|
|
1904
|
+
const declaration = records.get(recordType.declarationId);
|
|
1905
|
+
if (!declaration)
|
|
1906
|
+
return fail("UNKNOWN_RECORD", `Unknown record declaration '${recordType.declarationId}'.`, expression.location);
|
|
1907
|
+
if (!Array.isArray(expression.arguments) || expression.arguments.some((_argument, index) => !Object.hasOwn(expression.arguments, index))) {
|
|
1908
|
+
return fail("TYPE_MISMATCH", "Record construction arguments must be a dense ordered array.", expression.location);
|
|
1909
|
+
}
|
|
1910
|
+
if (expression.arguments.length != declaration.fields.length) {
|
|
1911
|
+
return fail("RECORD_ARITY_MISMATCH", `Record '${declaration.name}' construction has ${expression.arguments.length} arguments; expected ${declaration.fields.length}.`, expression.location);
|
|
1912
|
+
}
|
|
1913
|
+
const substitutions = recordTypeSubstitutions(recordType, declaration);
|
|
1914
|
+
for (let index = 0; index < expression.arguments.length; index += 1) {
|
|
1915
|
+
const argument = expression.arguments[index];
|
|
1916
|
+
const field = declaration.fields[index];
|
|
1917
|
+
const fieldType = substituteValueType(field.type, substitutions);
|
|
1918
|
+
const actual = inferValueExpressionType(argument, scope, functions, records, fail, normalizeOperations, `record field '${field.name}'`, fieldType);
|
|
1919
|
+
if (!sameType(actual, fieldType)) {
|
|
1920
|
+
fail("TYPE_MISMATCH", `Record field '${field.name}' argument type ${typeDescription(actual)}; expected ${typeDescription(fieldType)}.`, argument.location);
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
return recordType;
|
|
1924
|
+
}
|
|
1925
|
+
if (expression.kind == "MemberRead") {
|
|
1926
|
+
const receiverType = inferValueExpressionType(expression.receiver, scope, functions, records, fail, normalizeOperations, "a member receiver");
|
|
1927
|
+
if (receiverType.kind != "RecordType") {
|
|
1928
|
+
return fail("INVALID_MEMBER_RECEIVER", `Member receiver type ${typeDescription(receiverType)}; expected record.`, expression.receiver.location);
|
|
1929
|
+
}
|
|
1930
|
+
const declaration = records.get(receiverType.declarationId);
|
|
1931
|
+
if (!declaration)
|
|
1932
|
+
return fail("UNKNOWN_RECORD", `Unknown record declaration '${receiverType.declarationId}'.`, expression.receiver.location);
|
|
1933
|
+
const field = declaration.fields.find((candidate) => candidate.id == expression.field) ??
|
|
1934
|
+
(normalizeOperations ? declaration.fields.find((candidate) => candidate.name == expression.field) : undefined);
|
|
1935
|
+
if (!field)
|
|
1936
|
+
fail("UNKNOWN_FIELD", `Record '${declaration.name}' has no field '${expression.field}'.`, roleLocation(expression, "member"));
|
|
1937
|
+
if (normalizeOperations)
|
|
1938
|
+
expression.field = /** @type {string} */ (field.id);
|
|
1939
|
+
return substituteValueType(field.type, recordTypeSubstitutions(receiverType, declaration));
|
|
281
1940
|
}
|
|
282
1941
|
if (expression.kind == "CallExpression") {
|
|
283
1942
|
const functionDeclaration = functions.get(expression.callee);
|
|
284
|
-
if (!functionDeclaration)
|
|
285
|
-
return fail("UNRESOLVED_BINDING", `Unknown function '${expression.callee}'.`, expression
|
|
1943
|
+
if (!functionDeclaration) {
|
|
1944
|
+
return fail("UNRESOLVED_BINDING", `Unknown function '${expression.callee}'.`, roleLocation(expression, "callee"));
|
|
1945
|
+
}
|
|
286
1946
|
if (expression.arguments.length != functionDeclaration.parameters.length) {
|
|
287
1947
|
return fail("TYPE_MISMATCH", `Call argument count for '${expression.callee}'.`, expression.location);
|
|
288
1948
|
}
|
|
1949
|
+
const declarationTypeParameters = declarationTypeParameterIds(functionDeclaration);
|
|
1950
|
+
/** @type {Map<string, import("./types.js").SemanticValueType>} */
|
|
1951
|
+
const substitutions = new Map();
|
|
1952
|
+
const parameterTypes = functionDeclaration.parameters.map((parameter) => validateValueTypeReference(parameter.type, parameter.location, fail, undefined, records, declarationTypeParameters));
|
|
1953
|
+
for (let index = 0; index < expression.arguments.length; index += 1) {
|
|
1954
|
+
expression.arguments[index] = normalizeOwnedMove(expression.arguments[index], parameterTypes[index], normalizeOperations, fail);
|
|
1955
|
+
}
|
|
289
1956
|
for (let index = 0; index < expression.arguments.length; index++) {
|
|
290
1957
|
const argument = expression.arguments[index];
|
|
291
|
-
const
|
|
292
|
-
const
|
|
293
|
-
if (
|
|
294
|
-
|
|
1958
|
+
const expectedType = parameterTypes[index];
|
|
1959
|
+
const gathersGenericEvidence = typeContainsAnyVariable(expectedType);
|
|
1960
|
+
if (gathersGenericEvidence) {
|
|
1961
|
+
inferGenericArgumentEvidence(expectedType, argument, substitutions, scope, functions, records, fail, normalizeOperations);
|
|
1962
|
+
continue;
|
|
1963
|
+
}
|
|
1964
|
+
const actualType = inferValueExpressionType(argument, scope, functions, records, fail, normalizeOperations, "a call argument", expectedType);
|
|
1965
|
+
if ((functionDeclaration.typeParameters?.length ?? 0) > 0) {
|
|
1966
|
+
inferTypeArguments(expectedType, actualType, substitutions, argument.location, fail);
|
|
1967
|
+
}
|
|
1968
|
+
else if (!sameType(actualType, expectedType)) {
|
|
1969
|
+
fail("TYPE_MISMATCH", `Call argument type ${typeDescription(actualType)}; expected ${typeDescription(expectedType)}.`, argument.location);
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
for (const parameter of functionDeclaration.typeParameters ?? []) {
|
|
1973
|
+
if (!substitutions.has(/** @type {string} */ (parameter.id))) {
|
|
1974
|
+
const evidenceFreeIndex = parameterTypes.findIndex((type) => typeContainsVariable(type, /** @type {string} */ (parameter.id)));
|
|
1975
|
+
if (evidenceFreeIndex >= 0) {
|
|
1976
|
+
fail("GENERIC_INFERENCE_FAILURE", "Cannot infer a type parameter from an evidence-free call argument.", expression.arguments[evidenceFreeIndex].location);
|
|
1977
|
+
}
|
|
1978
|
+
fail("GENERIC_INFERENCE_FAILURE", `Cannot infer type parameter '${parameter.name}' from call arguments.`, expression.location);
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
if ([...substitutions.values()].some((type) => containsOwnedType(type))) {
|
|
1982
|
+
fail("RESOURCE_ALIAS", "Owned resources and references cannot be inferred as generic arguments.", expression.location);
|
|
1983
|
+
}
|
|
1984
|
+
for (let index = 0; index < functionDeclaration.parameters.length; index += 1) {
|
|
1985
|
+
const expected = substituteValueType(functionDeclaration.parameters[index].type, substitutions);
|
|
1986
|
+
const actual = inferValueExpressionType(expression.arguments[index], scope, functions, records, fail, normalizeOperations, "a call argument", expected);
|
|
1987
|
+
if (!sameType(actual, expected)) {
|
|
1988
|
+
fail("TYPE_MISMATCH", `Call argument type ${typeDescription(actual)}; expected ${typeDescription(expected)}.`, expression.arguments[index].location);
|
|
295
1989
|
}
|
|
296
1990
|
}
|
|
297
|
-
|
|
1991
|
+
const resolution = signatureFor(functionDeclaration, records, fail, substitutions);
|
|
1992
|
+
if (normalizeOperations)
|
|
1993
|
+
expression.resolution = resolution;
|
|
1994
|
+
else
|
|
1995
|
+
validateResolution(expression.resolution, resolution, expression.location, fail);
|
|
1996
|
+
const returnType = substituteReturnType(validateReturnTypeReference(functionDeclaration.returnType, functionDeclaration.location, fail, records, declarationTypeParameters), substitutions);
|
|
1997
|
+
return isVoidType(returnType) ? "void" : returnType;
|
|
298
1998
|
}
|
|
299
1999
|
if (expression.kind == "UnaryExpression") {
|
|
300
|
-
const
|
|
2000
|
+
const operand = inferValueExpressionType(expression.operand, scope, functions, records, fail, normalizeOperations, "a unary operand");
|
|
2001
|
+
const operandType = scalarNameForOperation(operand, expression.operand.location, fail);
|
|
301
2002
|
const operation = normalizeOperations
|
|
302
2003
|
? normalizeUnaryOperation(adaptedOperationFor(expression), operandType, expression.operand.location, fail)
|
|
303
2004
|
: expression.operation;
|
|
@@ -312,11 +2013,13 @@ function inferExpressionType(expression, scope, functions, fail, normalizeOperat
|
|
|
312
2013
|
if (expression.type != signature.result) {
|
|
313
2014
|
return fail("TYPE_MISMATCH", `${operation} result type ${String(expression.type)}; expected ${signature.result}.`, expression.location);
|
|
314
2015
|
}
|
|
315
|
-
return signature.result;
|
|
2016
|
+
return scalarType(signature.result);
|
|
316
2017
|
}
|
|
317
2018
|
if (expression.kind == "BinaryExpression") {
|
|
318
|
-
const
|
|
319
|
-
const
|
|
2019
|
+
const left = inferValueExpressionType(expression.left, scope, functions, records, fail, normalizeOperations, "a binary operand");
|
|
2020
|
+
const right = inferValueExpressionType(expression.right, scope, functions, records, fail, normalizeOperations, "a binary operand");
|
|
2021
|
+
const leftType = scalarNameForOperation(left, expression.left.location, fail);
|
|
2022
|
+
const rightType = scalarNameForOperation(right, expression.right.location, fail);
|
|
320
2023
|
const operation = normalizeOperations
|
|
321
2024
|
? normalizeBinaryOperation(adaptedOperationFor(expression), leftType, rightType, expression.left.location, expression.right.location, expression.location, fail)
|
|
322
2025
|
: expression.operation;
|
|
@@ -334,11 +2037,786 @@ function inferExpressionType(expression, scope, functions, fail, normalizeOperat
|
|
|
334
2037
|
if (expression.type != signature.result) {
|
|
335
2038
|
return fail("TYPE_MISMATCH", `${operation} result type ${String(expression.type)}; expected ${signature.result}.`, expression.location);
|
|
336
2039
|
}
|
|
337
|
-
return signature.result;
|
|
2040
|
+
return scalarType(signature.result);
|
|
338
2041
|
}
|
|
339
2042
|
const unexpected = /** @type {{kind: string, location: import("./types.js").SourceLocation}} */ (expression);
|
|
340
2043
|
return fail("TYPE_MISMATCH", unexpected.kind, unexpected.location);
|
|
341
2044
|
}
|
|
2045
|
+
/**
|
|
2046
|
+
* Validates map layout and fixed string keys independently of contextual value inference.
|
|
2047
|
+
* @param {import("./types.js").MapLiteral | import("./types.js").OrderedMapLiteral} expression - Candidate map literal.
|
|
2048
|
+
* @param {Scope} scope - Visible lexical scope.
|
|
2049
|
+
* @param {Map<string, import("./types.js").FunctionDeclaration>} functions - Module function signatures.
|
|
2050
|
+
* @param {RecordRegistry} records - Record declarations by identity.
|
|
2051
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
2052
|
+
* @param {boolean} normalizeOperations - Whether to normalize frontend intent.
|
|
2053
|
+
* @param {boolean} inferCollectionElements - Whether nested collection evidence may be inferred.
|
|
2054
|
+
* @returns {import("./types.js").MapEntry[]} Validated dense entries.
|
|
2055
|
+
*/
|
|
2056
|
+
function validateMapLiteralEntries(expression, scope, functions, records, fail, normalizeOperations, inferCollectionElements) {
|
|
2057
|
+
if (!Array.isArray(expression.entries)) {
|
|
2058
|
+
return fail("TYPE_MISMATCH", "Map literal entries must be a dense source-ordered array.", expression.location);
|
|
2059
|
+
}
|
|
2060
|
+
if (!isDenseArray(expression.entries)) {
|
|
2061
|
+
return fail("TYPE_MISMATCH", "Sparse map literals are outside the implemented subset.", expression.location);
|
|
2062
|
+
}
|
|
2063
|
+
const keys = new Set();
|
|
2064
|
+
for (const entry of expression.entries) {
|
|
2065
|
+
if (!entry || entry.kind != "MapEntry" || !entry.key || entry.key.kind != "StringLiteral") {
|
|
2066
|
+
fail("TYPE_MISMATCH", "Map entries require literal string keys.", entry?.location ?? expression.location);
|
|
2067
|
+
}
|
|
2068
|
+
inferValueExpressionType(entry.key, scope, functions, records, fail, normalizeOperations, "a map key", scalarType("string"), inferCollectionElements);
|
|
2069
|
+
if (isNumericString(entry.key.value)) {
|
|
2070
|
+
fail("INVALID_MAP_KEY", "Map initializer keys must be nonnumeric strings.", entry.key.location);
|
|
2071
|
+
}
|
|
2072
|
+
if (keys.has(entry.key.value)) {
|
|
2073
|
+
fail("DUPLICATE_MAP_KEY", `Duplicate ${expression.kind == "OrderedMapLiteral" ? "ordered-map" : "map"} key '${entry.key.value}'.`, entry.key.location);
|
|
2074
|
+
}
|
|
2075
|
+
keys.add(entry.key.value);
|
|
2076
|
+
}
|
|
2077
|
+
return expression.entries;
|
|
2078
|
+
}
|
|
2079
|
+
/**
|
|
2080
|
+
* Collects argument-only generic evidence while deferring recursively contextual literals.
|
|
2081
|
+
* The complete argument is validated against its closed substituted type after inference.
|
|
2082
|
+
* @param {import("./types.js").SemanticValueType} formal - Open declaration parameter type.
|
|
2083
|
+
* @param {import("./types.js").Expression} expression - Call argument or nested collection value.
|
|
2084
|
+
* @param {Map<string, import("./types.js").SemanticValueType>} substitutions - Inference state.
|
|
2085
|
+
* @param {Scope} scope - Visible lexical scope.
|
|
2086
|
+
* @param {Map<string, import("./types.js").FunctionDeclaration>} functions - Module function signatures.
|
|
2087
|
+
* @param {RecordRegistry} records - Record declarations by identity.
|
|
2088
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
2089
|
+
* @param {boolean} normalizeOperations - Whether to normalize frontend intent.
|
|
2090
|
+
* @returns {void}
|
|
2091
|
+
*/
|
|
2092
|
+
function inferGenericArgumentEvidence(formal, expression, substitutions, scope, functions, records, fail, normalizeOperations) {
|
|
2093
|
+
if (expression.kind == "OptionalNone")
|
|
2094
|
+
return;
|
|
2095
|
+
if (formal.kind == "OptionalType" && expression.kind == "OptionalSome") {
|
|
2096
|
+
inferGenericArgumentEvidence(formal.valueType, expression.value, substitutions, scope, functions, records, fail, normalizeOperations);
|
|
2097
|
+
return;
|
|
2098
|
+
}
|
|
2099
|
+
if (formal.kind == "ListType" && expression.kind == "ListLiteral") {
|
|
2100
|
+
if (!Array.isArray(expression.elements)) {
|
|
2101
|
+
fail("TYPE_MISMATCH", "List literal elements must be a dense source-ordered array.", expression.location);
|
|
2102
|
+
}
|
|
2103
|
+
if (!isDenseArray(expression.elements)) {
|
|
2104
|
+
fail("TYPE_MISMATCH", "Sparse list literals are outside the implemented subset.", expression.location);
|
|
2105
|
+
}
|
|
2106
|
+
for (const element of expression.elements) {
|
|
2107
|
+
inferGenericArgumentEvidence(formal.elementType, element, substitutions, scope, functions, records, fail, normalizeOperations);
|
|
2108
|
+
}
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2111
|
+
if ((formal.kind == "MapType" && expression.kind == "MapLiteral") ||
|
|
2112
|
+
(formal.kind == "OrderedMapType" && expression.kind == "OrderedMapLiteral")) {
|
|
2113
|
+
const entries = validateMapLiteralEntries(expression, scope, functions, records, fail, normalizeOperations, true);
|
|
2114
|
+
for (const entry of entries) {
|
|
2115
|
+
inferGenericArgumentEvidence(formal.valueType, entry.value, substitutions, scope, functions, records, fail, normalizeOperations);
|
|
2116
|
+
}
|
|
2117
|
+
return;
|
|
2118
|
+
}
|
|
2119
|
+
const actual = inferValueExpressionType(expression, scope, functions, records, fail, normalizeOperations, "a call argument", undefined, true);
|
|
2120
|
+
inferTypeArguments(formal, actual, substitutions, expression.location, fail);
|
|
2121
|
+
}
|
|
2122
|
+
/**
|
|
2123
|
+
* Unifies one declaration-owned formal type with one argument type.
|
|
2124
|
+
* @param {import("./types.js").SemanticValueType} formal - Generic signature type.
|
|
2125
|
+
* @param {import("./types.js").SemanticValueType} actual - Inferred argument type.
|
|
2126
|
+
* @param {Map<string, import("./types.js").SemanticValueType>} substitutions - Inference state.
|
|
2127
|
+
* @param {import("./types.js").SourceLocation} location - Argument location.
|
|
2128
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
2129
|
+
* @returns {void}
|
|
2130
|
+
*/
|
|
2131
|
+
function inferTypeArguments(formal, actual, substitutions, location, fail) {
|
|
2132
|
+
if (formal.kind == "TypeVariableReference") {
|
|
2133
|
+
const prior = substitutions.get(formal.parameterId);
|
|
2134
|
+
if (prior) {
|
|
2135
|
+
if (!sameType(prior, actual)) {
|
|
2136
|
+
fail("GENERIC_INFERENCE_CONFLICT", `Conflicting inference for type parameter '${formal.parameterId}'.`, location);
|
|
2137
|
+
}
|
|
2138
|
+
return;
|
|
2139
|
+
}
|
|
2140
|
+
if (!(actual.kind == "TypeVariableReference" && actual.parameterId == formal.parameterId) &&
|
|
2141
|
+
typeContainsVariable(actual, formal.parameterId)) {
|
|
2142
|
+
fail("GENERIC_INFERENCE_RECURSION", `Recursive inference for type parameter '${formal.parameterId}'.`, location);
|
|
2143
|
+
}
|
|
2144
|
+
substitutions.set(formal.parameterId, actual);
|
|
2145
|
+
return;
|
|
2146
|
+
}
|
|
2147
|
+
if (formal.kind != actual.kind) {
|
|
2148
|
+
fail("TYPE_MISMATCH", `Call argument type ${typeDescription(actual)}; expected ${typeDescription(formal)}.`, location);
|
|
2149
|
+
}
|
|
2150
|
+
if (formal.kind == "TypeReference") {
|
|
2151
|
+
if (!sameType(formal, actual)) {
|
|
2152
|
+
fail("TYPE_MISMATCH", `Call argument type ${typeDescription(actual)}; expected ${typeDescription(formal)}.`, location);
|
|
2153
|
+
}
|
|
2154
|
+
return;
|
|
2155
|
+
}
|
|
2156
|
+
if (formal.kind == "ReferenceType" && actual.kind == "ReferenceType") {
|
|
2157
|
+
if (formal.declarationId != actual.declarationId) {
|
|
2158
|
+
fail("TYPE_MISMATCH", `Call argument type ${typeDescription(actual)}; expected ${typeDescription(formal)}.`, location);
|
|
2159
|
+
}
|
|
2160
|
+
return;
|
|
2161
|
+
}
|
|
2162
|
+
if (formal.kind == "RecordType" && actual.kind == "RecordType") {
|
|
2163
|
+
if (formal.declarationId != actual.declarationId || (formal.arguments?.length ?? 0) != (actual.arguments?.length ?? 0)) {
|
|
2164
|
+
fail("TYPE_MISMATCH", `Call argument type ${typeDescription(actual)}; expected ${typeDescription(formal)}.`, location);
|
|
2165
|
+
}
|
|
2166
|
+
for (let index = 0; index < (formal.arguments?.length ?? 0); index += 1) {
|
|
2167
|
+
inferTypeArguments(/** @type {import("./types.js").SemanticValueType} */ (formal.arguments?.[index]),
|
|
2168
|
+
/** @type {import("./types.js").SemanticValueType} */ (actual.arguments?.[index]), substitutions, location, fail);
|
|
2169
|
+
}
|
|
2170
|
+
return;
|
|
2171
|
+
}
|
|
2172
|
+
if (formal.kind == "ListType" && actual.kind == "ListType") {
|
|
2173
|
+
inferTypeArguments(formal.elementType, actual.elementType, substitutions, location, fail);
|
|
2174
|
+
return;
|
|
2175
|
+
}
|
|
2176
|
+
if (formal.kind == "OptionalType" && actual.kind == "OptionalType") {
|
|
2177
|
+
inferTypeArguments(formal.valueType, actual.valueType, substitutions, location, fail);
|
|
2178
|
+
return;
|
|
2179
|
+
}
|
|
2180
|
+
if ((formal.kind == "MapType" && actual.kind == "MapType") ||
|
|
2181
|
+
(formal.kind == "OrderedMapType" && actual.kind == "OrderedMapType")) {
|
|
2182
|
+
inferTypeArguments(formal.keyType, actual.keyType, substitutions, location, fail);
|
|
2183
|
+
inferTypeArguments(formal.valueType, actual.valueType, substitutions, location, fail);
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
/**
|
|
2187
|
+
* Checks the occurs constraint for first-order inference.
|
|
2188
|
+
* @param {import("./types.js").SemanticValueType} type - Candidate inferred type.
|
|
2189
|
+
* @param {string} parameterId - Parameter being inferred.
|
|
2190
|
+
* @returns {boolean} Whether the type recursively contains the parameter.
|
|
2191
|
+
*/
|
|
2192
|
+
function typeContainsVariable(type, parameterId) {
|
|
2193
|
+
if (type.kind == "TypeVariableReference")
|
|
2194
|
+
return type.parameterId == parameterId;
|
|
2195
|
+
if (type.kind == "RecordType")
|
|
2196
|
+
return type.arguments?.some((argument) => typeContainsVariable(argument, parameterId)) ?? false;
|
|
2197
|
+
if (type.kind == "ListType")
|
|
2198
|
+
return typeContainsVariable(type.elementType, parameterId);
|
|
2199
|
+
if (type.kind == "MapType" || type.kind == "OrderedMapType") {
|
|
2200
|
+
return typeContainsVariable(type.keyType, parameterId) || typeContainsVariable(type.valueType, parameterId);
|
|
2201
|
+
}
|
|
2202
|
+
if (type.kind == "OptionalType")
|
|
2203
|
+
return typeContainsVariable(type.valueType, parameterId);
|
|
2204
|
+
return false;
|
|
2205
|
+
}
|
|
2206
|
+
/**
|
|
2207
|
+
* Applies substitutions to a value or void return type.
|
|
2208
|
+
* @param {import("./types.js").SemanticFunctionReturnType} type - Open return type.
|
|
2209
|
+
* @param {Map<string, import("./types.js").SemanticValueType>} substitutions - Closed substitutions.
|
|
2210
|
+
* @returns {import("./types.js").SemanticFunctionReturnType} Substituted return type.
|
|
2211
|
+
*/
|
|
2212
|
+
function substituteReturnType(type, substitutions) {
|
|
2213
|
+
return isVoidType(type) ? type : substituteValueType(type, substitutions);
|
|
2214
|
+
}
|
|
2215
|
+
/**
|
|
2216
|
+
* Builds the exact semantic signature bound to one declaration.
|
|
2217
|
+
* @param {import("./types.js").FunctionDeclaration} declaration - Resolved declaration.
|
|
2218
|
+
* @param {RecordRegistry} records - Record declarations by identity.
|
|
2219
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
2220
|
+
* @param {Map<string, import("./types.js").SemanticValueType>} [substitutions] - Inferred generic substitutions.
|
|
2221
|
+
* @returns {import("./types.js").ResolvedFunctionSignature} Detached signature binding.
|
|
2222
|
+
*/
|
|
2223
|
+
function signatureFor(declaration, records, fail, substitutions = new Map()) {
|
|
2224
|
+
const typeParameters = declarationTypeParameterIds(declaration);
|
|
2225
|
+
const declaredParameters = declaration.typeParameters ?? [];
|
|
2226
|
+
const parameterTypes = declaration.parameters.map((parameter) => substituteValueType(validateValueTypeReference(parameter.type, parameter.location, fail, undefined, records, typeParameters), substitutions));
|
|
2227
|
+
const returnType = substituteReturnType(validateReturnTypeReference(declaration.returnType, declaration.location, fail, records, typeParameters), substitutions);
|
|
2228
|
+
return {
|
|
2229
|
+
declarationId: /** @type {string} */ (declaration.id),
|
|
2230
|
+
kind: "ResolvedFunctionSignature",
|
|
2231
|
+
parameterTypes: parameterTypes.map((type) => /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type))),
|
|
2232
|
+
returnType: typeIdentity(returnType),
|
|
2233
|
+
...(declaredParameters.length > 0 ? {
|
|
2234
|
+
typeArguments: declaredParameters.map((parameter) =>
|
|
2235
|
+
/** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(/** @type {import("./types.js").SemanticValueType} */ (substitutions.get(/** @type {string} */ (parameter.id))))))
|
|
2236
|
+
} : {})
|
|
2237
|
+
};
|
|
2238
|
+
}
|
|
2239
|
+
/**
|
|
2240
|
+
* Validates an externally supplied call binding against the declaration collected for this module.
|
|
2241
|
+
* @param {unknown} actual - Candidate call resolution.
|
|
2242
|
+
* @param {import("./types.js").ResolvedFunctionSignature} expected - Exact declaration signature.
|
|
2243
|
+
* @param {import("./types.js").SourceLocation} location - Call location.
|
|
2244
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
2245
|
+
* @returns {void}
|
|
2246
|
+
*/
|
|
2247
|
+
function validateResolution(actual, expected, location, fail) {
|
|
2248
|
+
const expectedKeys = expected.typeArguments ? "declarationId,kind,parameterTypes,returnType,typeArguments" :
|
|
2249
|
+
"declarationId,kind,parameterTypes,returnType";
|
|
2250
|
+
if (!actual || typeof actual != "object" || Array.isArray(actual) ||
|
|
2251
|
+
Object.keys(actual).sort().join(",") != expectedKeys) {
|
|
2252
|
+
fail("TYPE_MISMATCH", "Call is missing an exact resolved function signature.", location);
|
|
2253
|
+
}
|
|
2254
|
+
const candidate = /** @type {import("./types.js").ResolvedFunctionSignature} */ (actual);
|
|
2255
|
+
if (candidate.kind != "ResolvedFunctionSignature" || typeof candidate.declarationId != "string" ||
|
|
2256
|
+
!Array.isArray(candidate.parameterTypes) || !validTypeIdentity(candidate.returnType, true) ||
|
|
2257
|
+
candidate.declarationId != expected.declarationId ||
|
|
2258
|
+
!sameTypeIdentity(candidate.returnType, expected.returnType) || candidate.parameterTypes.length != expected.parameterTypes.length) {
|
|
2259
|
+
fail("TYPE_MISMATCH", "Call resolution does not match its declaration signature.", location);
|
|
2260
|
+
}
|
|
2261
|
+
if (expected.typeArguments) {
|
|
2262
|
+
const candidateTypeArguments = candidate.typeArguments;
|
|
2263
|
+
if (!isDenseArray(candidateTypeArguments) || candidateTypeArguments.length != expected.typeArguments.length ||
|
|
2264
|
+
candidateTypeArguments.some((type, index) => !validTypeIdentity(type, false) || !sameTypeIdentity(type, expected.typeArguments?.[index]))) {
|
|
2265
|
+
fail("TYPE_MISMATCH", "Call resolution does not match its inferred type arguments.", location);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
for (let index = 0; index < candidate.parameterTypes.length; index++) {
|
|
2269
|
+
const type = candidate.parameterTypes[index];
|
|
2270
|
+
if (!Object.hasOwn(candidate.parameterTypes, index) || !validTypeIdentity(type, false) ||
|
|
2271
|
+
!sameTypeIdentity(type, expected.parameterTypes[index])) {
|
|
2272
|
+
fail("TYPE_MISMATCH", "Call resolution does not match its declaration signature.", location);
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
/**
|
|
2277
|
+
* Validates exact caller-owned constructor or method resolution metadata.
|
|
2278
|
+
* @param {unknown} actual - Candidate resolution.
|
|
2279
|
+
* @param {import("./types.js").ResolvedConstructorSignature | import("./types.js").ResolvedMethodSignature} expected - Exact resolution.
|
|
2280
|
+
* @param {import("./types.js").SourceLocation} location - Expression location.
|
|
2281
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
2282
|
+
* @param {"constructor" | "method"} role - Resolution role.
|
|
2283
|
+
* @returns {void}
|
|
2284
|
+
*/
|
|
2285
|
+
function validateReferenceResolution(actual, expected, location, fail, role) {
|
|
2286
|
+
const expectedMethod = role == "method" ? /** @type {import("./types.js").ResolvedMethodSignature} */ (expected) : undefined;
|
|
2287
|
+
const expectedKeys = role == "constructor" ? "declarationId,kind,parameterTypes" :
|
|
2288
|
+
expectedMethod?.resourceFlow ? "declarationId,kind,parameterTypes,resourceFlow,returnType" :
|
|
2289
|
+
"declarationId,kind,parameterTypes,returnType";
|
|
2290
|
+
if (!actual || typeof actual != "object" || Array.isArray(actual) || Object.keys(actual).sort().join(",") != expectedKeys) {
|
|
2291
|
+
fail("TYPE_MISMATCH", `Reference ${role} call is missing an exact resolved ${role} signature.`, location);
|
|
2292
|
+
}
|
|
2293
|
+
const candidate = /** @type {Record<string, unknown>} */ (actual);
|
|
2294
|
+
if (candidate.kind != expected.kind || candidate.declarationId != expected.declarationId ||
|
|
2295
|
+
!isDenseArray(candidate.parameterTypes) || candidate.parameterTypes.length != expected.parameterTypes.length ||
|
|
2296
|
+
candidate.parameterTypes.some((type, index) => !validTypeIdentity(type, false) ||
|
|
2297
|
+
!sameTypeIdentity(type, expected.parameterTypes[index])) ||
|
|
2298
|
+
role == "method" && (!validTypeIdentity(candidate.returnType, true) ||
|
|
2299
|
+
!sameTypeIdentity(candidate.returnType, /** @type {import("./types.js").ResolvedMethodSignature} */ (expected).returnType) ||
|
|
2300
|
+
JSON.stringify(candidate.resourceFlow) != JSON.stringify(expectedMethod?.resourceFlow))) {
|
|
2301
|
+
fail("TYPE_MISMATCH", `Resolved ${role} signature does not match its declaration.`, location);
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
/**
|
|
2305
|
+
* Makes a source identifier's ownership transfer explicit in normalized IR.
|
|
2306
|
+
* @param {import("./types.js").Expression} expression - Candidate transfer expression.
|
|
2307
|
+
* @param {import("./types.js").SemanticFunctionReturnType} expected - Destination type.
|
|
2308
|
+
* @param {boolean} normalize - Whether parser intent may be normalized.
|
|
2309
|
+
* @param {SemanticFail} fail - Located failure.
|
|
2310
|
+
* @returns {import("./types.js").Expression} Explicit expression.
|
|
2311
|
+
*/
|
|
2312
|
+
function normalizeOwnedMove(expression, expected, normalize, fail) {
|
|
2313
|
+
if (expected.kind != "OwnedResourceType" && expected.kind != "OwnedReferenceType")
|
|
2314
|
+
return expression;
|
|
2315
|
+
if (expression.kind == "OwnedMoveExpression")
|
|
2316
|
+
return expression;
|
|
2317
|
+
if (expression.kind == "PrivateFieldRead") {
|
|
2318
|
+
return fail("INVALID_RESOURCE_TRANSFER", "Private resource fields cannot be moved or exposed; transfer the owning reference.", expression.location);
|
|
2319
|
+
}
|
|
2320
|
+
if (expression.kind != "IdentifierExpression")
|
|
2321
|
+
return expression;
|
|
2322
|
+
if (!normalize)
|
|
2323
|
+
return fail("RESOURCE_MOVE_REQUIRED", "Owned transfer requires an explicit move expression.", expression.location);
|
|
2324
|
+
return {
|
|
2325
|
+
expression,
|
|
2326
|
+
kind: "OwnedMoveExpression",
|
|
2327
|
+
location: expression.location,
|
|
2328
|
+
sourceProvenance: expression.sourceProvenance,
|
|
2329
|
+
type: expected
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2332
|
+
/**
|
|
2333
|
+
* Classifies the deliberately bounded Task 034 receiver transition.
|
|
2334
|
+
* @param {import("./types.js").ClassDeclaration} declaration - Owned class.
|
|
2335
|
+
* @param {import("./types.js").MethodDeclaration} method - Candidate method.
|
|
2336
|
+
* @param {SemanticFail} fail - Located failure.
|
|
2337
|
+
* @returns {{kind: "preserve" | "terminal", terminalFailureId?: string}} Receiver transition.
|
|
2338
|
+
*/
|
|
2339
|
+
function ownedMethodResourceFlow(declaration, method, fail) {
|
|
2340
|
+
const effectStatements = method.body.statements.flatMap((statement) => {
|
|
2341
|
+
const expression = statement.kind == "ExpressionStatement" || statement.kind == "ReturnStatement" ? statement.expression :
|
|
2342
|
+
statement.kind == "LocalDeclaration" ? statement.initializer : undefined;
|
|
2343
|
+
return expression?.kind == "EffectCallExpression" ? [expression] : [];
|
|
2344
|
+
});
|
|
2345
|
+
const allEffects = methodEffectExpressions(method.body);
|
|
2346
|
+
if (allEffects.length == 0)
|
|
2347
|
+
return { kind: "preserve" };
|
|
2348
|
+
if (method.body.statements.length != 1 || effectStatements.length != 1 || allEffects.length != 1 ||
|
|
2349
|
+
allEffects[0] !== effectStatements[0]) {
|
|
2350
|
+
return fail("UNSUPPORTED_STATEMENT", `Owned method '${method.name}' must contain one direct resource operation or only pure statements.`, method.location);
|
|
2351
|
+
}
|
|
2352
|
+
const operation = effectStatements[0];
|
|
2353
|
+
const flow = operation.resolution.resourceFlow;
|
|
2354
|
+
if (flow.kind == "none" || flow.kind == "acquire")
|
|
2355
|
+
return { kind: "preserve" };
|
|
2356
|
+
const argument = operation.arguments[flow.parameterIndex];
|
|
2357
|
+
const owned = declaration.ownership?.kind == "ownedResource" ? declaration.ownership : undefined;
|
|
2358
|
+
const borrowedParameterName = argument?.kind == "OwnedBorrowExpression" && argument.expression.kind == "IdentifierExpression"
|
|
2359
|
+
? argument.expression.name : undefined;
|
|
2360
|
+
const borrowedParameter = borrowedParameterName !== undefined &&
|
|
2361
|
+
method.parameters.some((parameter) => parameter.name == borrowedParameterName && containsOwnedType(parameter.type));
|
|
2362
|
+
if (borrowedParameter)
|
|
2363
|
+
return { kind: "preserve" };
|
|
2364
|
+
if (!argument || argument.kind != "OwnedBorrowExpression" || argument.expression.kind != "PrivateFieldRead" ||
|
|
2365
|
+
argument.expression.field != owned?.fieldId) {
|
|
2366
|
+
return fail("INVALID_RESOURCE_BORROW", `Owned method '${method.name}' must operate on its private resource field.`, operation.location);
|
|
2367
|
+
}
|
|
2368
|
+
return { kind: flow.kind == "close" ? "terminal" : "preserve", terminalFailureId: flow.terminalFailureId };
|
|
2369
|
+
}
|
|
2370
|
+
/**
|
|
2371
|
+
* Collects every host-effect site nested in one owned method body.
|
|
2372
|
+
* @param {import("./types.js").Block} block - Method body.
|
|
2373
|
+
* @returns {import("./types.js").Expression[]} Effectful expressions.
|
|
2374
|
+
*/
|
|
2375
|
+
function methodEffectExpressions(block) {
|
|
2376
|
+
/** @type {import("./types.js").Expression[]} */
|
|
2377
|
+
const effects = [];
|
|
2378
|
+
const pending = [/** @type {unknown} */ (block)];
|
|
2379
|
+
const seen = new Set();
|
|
2380
|
+
while (pending.length > 0) {
|
|
2381
|
+
const value = pending.pop();
|
|
2382
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
2383
|
+
continue;
|
|
2384
|
+
seen.add(value);
|
|
2385
|
+
if (!Array.isArray(value) && (Reflect.get(value, "kind") == "EffectCallExpression" ||
|
|
2386
|
+
typeof Reflect.get(value, "effectSiteId") == "string")) {
|
|
2387
|
+
effects.push(/** @type {import("./types.js").Expression} */ (value));
|
|
2388
|
+
}
|
|
2389
|
+
for (const [key, child] of Object.entries(value)) {
|
|
2390
|
+
if (["location", "resolution", "sourceProvenance"].includes(key))
|
|
2391
|
+
continue;
|
|
2392
|
+
if (Array.isArray(child))
|
|
2393
|
+
pending.push(...child);
|
|
2394
|
+
else if (child && typeof child == "object")
|
|
2395
|
+
pending.push(child);
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
return effects;
|
|
2399
|
+
}
|
|
2400
|
+
/**
|
|
2401
|
+
* Rehydrates a closed capability type identity for ordinary expression checks.
|
|
2402
|
+
* @param {import("./types.js").FunctionReturnTypeIdentity} identity - Closed identity.
|
|
2403
|
+
* @param {import("./types.js").SourceLocation} location - Diagnostic location.
|
|
2404
|
+
* @param {SemanticFail} fail - Located failure.
|
|
2405
|
+
* @returns {import("./types.js").SemanticValueType} Value type.
|
|
2406
|
+
*/
|
|
2407
|
+
function identityAsValueType(identity, location, fail) {
|
|
2408
|
+
if (typeof identity == "string") {
|
|
2409
|
+
if (!isScalarTypeName(identity))
|
|
2410
|
+
return fail("TYPE_MISMATCH", "Void or invalid identity used as an effect value type.", location);
|
|
2411
|
+
return scalarType(identity);
|
|
2412
|
+
}
|
|
2413
|
+
if (!identity || typeof identity != "object" || Array.isArray(identity)) {
|
|
2414
|
+
return fail("TYPE_MISMATCH", "Malformed effect type identity.", location);
|
|
2415
|
+
}
|
|
2416
|
+
const candidate = /** @type {Exclude<import("./types.js").SemanticTypeIdentity, string>} */ (identity);
|
|
2417
|
+
if (candidate.kind == "OwnedResourceType")
|
|
2418
|
+
return { kind: "OwnedResourceType", resourceId: candidate.resourceId };
|
|
2419
|
+
if (candidate.kind == "OwnedReferenceType")
|
|
2420
|
+
return { declarationId: candidate.declarationId, kind: "OwnedReferenceType" };
|
|
2421
|
+
if (candidate.kind == "OptionalType")
|
|
2422
|
+
return { kind: "OptionalType", valueType: identityAsValueType(candidate.valueType, location, fail) };
|
|
2423
|
+
return fail("TYPE_MISMATCH", "Unsupported effect type identity.", location);
|
|
2424
|
+
}
|
|
2425
|
+
/**
|
|
2426
|
+
* Converts a semantic type to its detached call-resolution identity.
|
|
2427
|
+
* @param {import("./types.js").SemanticFunctionReturnType} type - Validated semantic type.
|
|
2428
|
+
* @returns {import("./types.js").FunctionReturnTypeIdentity} Detached identity.
|
|
2429
|
+
*/
|
|
2430
|
+
function typeIdentity(type) {
|
|
2431
|
+
if (type.kind == "TypeReference")
|
|
2432
|
+
return type.name;
|
|
2433
|
+
if (type.kind == "TypeVariableReference")
|
|
2434
|
+
return { kind: "TypeVariableReference", parameterId: type.parameterId };
|
|
2435
|
+
if (type.kind == "RecordType")
|
|
2436
|
+
return {
|
|
2437
|
+
declarationId: type.declarationId,
|
|
2438
|
+
kind: "RecordType",
|
|
2439
|
+
...(type.arguments ? { arguments: type.arguments.map((argument) =>
|
|
2440
|
+
/** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(argument))) } : {})
|
|
2441
|
+
};
|
|
2442
|
+
if (type.kind == "ReferenceType")
|
|
2443
|
+
return { declarationId: type.declarationId, kind: "ReferenceType" };
|
|
2444
|
+
if (type.kind == "OwnedResourceType")
|
|
2445
|
+
return { kind: "OwnedResourceType", resourceId: type.resourceId };
|
|
2446
|
+
if (type.kind == "OwnedReferenceType")
|
|
2447
|
+
return { declarationId: type.declarationId, kind: "OwnedReferenceType" };
|
|
2448
|
+
if (type.kind == "ListType")
|
|
2449
|
+
return { elementType: /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type.elementType)), kind: "ListType" };
|
|
2450
|
+
if (type.kind == "OptionalType")
|
|
2451
|
+
return { kind: "OptionalType", valueType: /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type.valueType)) };
|
|
2452
|
+
if (type.kind == "OrderedMapType")
|
|
2453
|
+
return {
|
|
2454
|
+
keyType: /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type.keyType)),
|
|
2455
|
+
kind: "OrderedMapType",
|
|
2456
|
+
order: "insertion",
|
|
2457
|
+
valueType: /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type.valueType))
|
|
2458
|
+
};
|
|
2459
|
+
return {
|
|
2460
|
+
keyType: /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type.keyType)),
|
|
2461
|
+
kind: "MapType",
|
|
2462
|
+
valueType: /** @type {import("./types.js").SemanticTypeIdentity} */ (typeIdentity(type.valueType))
|
|
2463
|
+
};
|
|
2464
|
+
}
|
|
2465
|
+
/**
|
|
2466
|
+
* Checks one externally supplied recursive type identity.
|
|
2467
|
+
* @param {unknown} type - Candidate identity.
|
|
2468
|
+
* @param {boolean} allowVoid - Whether void is permitted.
|
|
2469
|
+
* @param {Set<object>} [seen] - Active recursion path.
|
|
2470
|
+
* @returns {boolean} Whether the identity is closed and acyclic.
|
|
2471
|
+
*/
|
|
2472
|
+
function validTypeIdentity(type, allowVoid, seen = new Set()) {
|
|
2473
|
+
if (typeof type == "string")
|
|
2474
|
+
return isScalarTypeName(type) || allowVoid && type == "void";
|
|
2475
|
+
if (!type || typeof type != "object" || Array.isArray(type) || seen.has(type))
|
|
2476
|
+
return false;
|
|
2477
|
+
seen.add(type);
|
|
2478
|
+
const candidate = /** @type {Record<string, unknown>} */ (type);
|
|
2479
|
+
let valid = false;
|
|
2480
|
+
if (candidate.kind == "ListType" && Object.keys(candidate).sort().join(",") == "elementType,kind") {
|
|
2481
|
+
valid = validTypeIdentity(candidate.elementType, false, seen);
|
|
2482
|
+
}
|
|
2483
|
+
else if (candidate.kind == "MapType" && Object.keys(candidate).sort().join(",") == "keyType,kind,valueType") {
|
|
2484
|
+
valid = candidate.keyType == "string" && validTypeIdentity(candidate.valueType, false, seen);
|
|
2485
|
+
}
|
|
2486
|
+
else if (candidate.kind == "OrderedMapType" &&
|
|
2487
|
+
Object.keys(candidate).sort().join(",") == "keyType,kind,order,valueType") {
|
|
2488
|
+
valid = candidate.keyType == "string" && candidate.order == "insertion" &&
|
|
2489
|
+
validTypeIdentity(candidate.valueType, false, seen);
|
|
2490
|
+
}
|
|
2491
|
+
else if (candidate.kind == "OptionalType" && Object.keys(candidate).sort().join(",") == "kind,valueType") {
|
|
2492
|
+
valid = validTypeIdentity(candidate.valueType, false, seen) &&
|
|
2493
|
+
!(candidate.valueType && typeof candidate.valueType == "object" && Reflect.get(candidate.valueType, "kind") == "OptionalType");
|
|
2494
|
+
}
|
|
2495
|
+
else if (candidate.kind == "TypeVariableReference" && Object.keys(candidate).sort().join(",") == "kind,parameterId") {
|
|
2496
|
+
valid = typeof candidate.parameterId == "string" && /^(?:[a-z][a-z0-9._-]*#)?(?:record|function):[0-9]+:type:[0-9]+$/u.test(candidate.parameterId);
|
|
2497
|
+
}
|
|
2498
|
+
else if (candidate.kind == "RecordType" &&
|
|
2499
|
+
["arguments,declarationId,kind", "declarationId,kind"].includes(Object.keys(candidate).sort().join(","))) {
|
|
2500
|
+
const candidateArguments = candidate.arguments;
|
|
2501
|
+
valid = typeof candidate.declarationId == "string" && /^(?:[a-z][a-z0-9._-]*#)?record:[0-9]+$/u.test(candidate.declarationId) &&
|
|
2502
|
+
(candidateArguments === undefined || isDenseArray(candidateArguments) &&
|
|
2503
|
+
candidateArguments.every((argument) => validTypeIdentity(argument, false, seen)));
|
|
2504
|
+
}
|
|
2505
|
+
else if (candidate.kind == "ReferenceType" && Object.keys(candidate).sort().join(",") == "declarationId,kind") {
|
|
2506
|
+
valid = typeof candidate.declarationId == "string" &&
|
|
2507
|
+
/^(?:[a-z][a-z0-9._-]*#)?class:[0-9]+$/u.test(candidate.declarationId);
|
|
2508
|
+
}
|
|
2509
|
+
else if (candidate.kind == "OwnedResourceType" && Object.keys(candidate).sort().join(",") == "kind,resourceId") {
|
|
2510
|
+
valid = typeof candidate.resourceId == "string" && /^(?:module:[0-9]+\/)?capability:[0-9]+\/resource:[0-9]+$/u
|
|
2511
|
+
.test(candidate.resourceId);
|
|
2512
|
+
}
|
|
2513
|
+
else if (candidate.kind == "OwnedReferenceType" && Object.keys(candidate).sort().join(",") == "declarationId,kind") {
|
|
2514
|
+
valid = typeof candidate.declarationId == "string" && /^(?:[a-z][a-z0-9._-]*#)?class:[0-9]+$/u.test(candidate.declarationId);
|
|
2515
|
+
}
|
|
2516
|
+
seen.delete(type);
|
|
2517
|
+
return valid;
|
|
2518
|
+
}
|
|
2519
|
+
/**
|
|
2520
|
+
* Checks array identity without relying on iteration methods that skip sparse slots.
|
|
2521
|
+
* @param {unknown} value - Candidate array.
|
|
2522
|
+
* @returns {value is unknown[]} Whether every indexed slot is present.
|
|
2523
|
+
*/
|
|
2524
|
+
function isDenseArray(value) {
|
|
2525
|
+
if (!Array.isArray(value))
|
|
2526
|
+
return false;
|
|
2527
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
2528
|
+
if (!Object.hasOwn(value, index))
|
|
2529
|
+
return false;
|
|
2530
|
+
}
|
|
2531
|
+
return true;
|
|
2532
|
+
}
|
|
2533
|
+
/**
|
|
2534
|
+
* Compares two closed type identities structurally.
|
|
2535
|
+
* @param {unknown} left - First identity.
|
|
2536
|
+
* @param {unknown} right - Second identity.
|
|
2537
|
+
* @returns {boolean} Whether the identities are equal.
|
|
2538
|
+
*/
|
|
2539
|
+
function sameTypeIdentity(left, right) {
|
|
2540
|
+
if (typeof left == "string" || typeof right == "string")
|
|
2541
|
+
return left === right;
|
|
2542
|
+
if (!left || !right || typeof left != "object" || typeof right != "object")
|
|
2543
|
+
return false;
|
|
2544
|
+
const leftType = /** @type {Record<string, unknown>} */ (left);
|
|
2545
|
+
const rightType = /** @type {Record<string, unknown>} */ (right);
|
|
2546
|
+
if (leftType.kind != rightType.kind)
|
|
2547
|
+
return false;
|
|
2548
|
+
if (leftType.kind == "ListType")
|
|
2549
|
+
return sameTypeIdentity(leftType.elementType, rightType.elementType);
|
|
2550
|
+
if (leftType.kind == "OptionalType")
|
|
2551
|
+
return sameTypeIdentity(leftType.valueType, rightType.valueType);
|
|
2552
|
+
if (leftType.kind == "TypeVariableReference")
|
|
2553
|
+
return leftType.parameterId == rightType.parameterId;
|
|
2554
|
+
if (leftType.kind == "RecordType") {
|
|
2555
|
+
const leftArguments = Array.isArray(leftType.arguments) ? leftType.arguments : [];
|
|
2556
|
+
const rightArguments = Array.isArray(rightType.arguments) ? rightType.arguments : [];
|
|
2557
|
+
return leftType.declarationId == rightType.declarationId && leftArguments.length == rightArguments.length &&
|
|
2558
|
+
leftArguments.every((argument, index) => sameTypeIdentity(argument, rightArguments[index]));
|
|
2559
|
+
}
|
|
2560
|
+
if (leftType.kind == "ReferenceType")
|
|
2561
|
+
return leftType.declarationId == rightType.declarationId;
|
|
2562
|
+
if (leftType.kind == "OwnedResourceType")
|
|
2563
|
+
return leftType.resourceId == rightType.resourceId;
|
|
2564
|
+
if (leftType.kind == "OwnedReferenceType")
|
|
2565
|
+
return leftType.declarationId == rightType.declarationId;
|
|
2566
|
+
if (leftType.kind == "MapType" || leftType.kind == "OrderedMapType") {
|
|
2567
|
+
return sameTypeIdentity(leftType.keyType, rightType.keyType) && sameTypeIdentity(leftType.valueType, rightType.valueType);
|
|
2568
|
+
}
|
|
2569
|
+
return false;
|
|
2570
|
+
}
|
|
2571
|
+
/**
|
|
2572
|
+
* Compares two validated semantic types structurally.
|
|
2573
|
+
* @param {import("./types.js").SemanticFunctionReturnType} left - First type.
|
|
2574
|
+
* @param {import("./types.js").SemanticFunctionReturnType} right - Second type.
|
|
2575
|
+
* @returns {boolean} Whether the types are equal.
|
|
2576
|
+
*/
|
|
2577
|
+
function sameType(left, right) {
|
|
2578
|
+
return sameTypeIdentity(typeIdentity(left), typeIdentity(right));
|
|
2579
|
+
}
|
|
2580
|
+
/**
|
|
2581
|
+
* Formats one validated semantic type for diagnostics.
|
|
2582
|
+
* @param {import("./types.js").SemanticFunctionReturnType | import("./types.js").ErrorType} type - Semantic type.
|
|
2583
|
+
* @returns {string} Stable recursive spelling.
|
|
2584
|
+
*/
|
|
2585
|
+
function typeDescription(type) {
|
|
2586
|
+
if (type.kind == "TypeReference")
|
|
2587
|
+
return type.name;
|
|
2588
|
+
if (type.kind == "TypeVariableReference")
|
|
2589
|
+
return `type-variable<${type.parameterId}>`;
|
|
2590
|
+
if (type.kind == "RecordType")
|
|
2591
|
+
return `record<${type.declarationId}${type.arguments?.length
|
|
2592
|
+
? `, ${type.arguments.map(typeDescription).join(", ")}` : ""}>`;
|
|
2593
|
+
if (type.kind == "ReferenceType")
|
|
2594
|
+
return `reference<${type.declarationId}>`;
|
|
2595
|
+
if (type.kind == "OwnedResourceType")
|
|
2596
|
+
return `owned-resource<${type.resourceId}>`;
|
|
2597
|
+
if (type.kind == "OwnedReferenceType")
|
|
2598
|
+
return `owned-reference<${type.declarationId}>`;
|
|
2599
|
+
if (type.kind == "ErrorType")
|
|
2600
|
+
return `error<${type.declarationId}>`;
|
|
2601
|
+
if (type.kind == "ListType")
|
|
2602
|
+
return `list<${typeDescription(type.elementType)}>`;
|
|
2603
|
+
if (type.kind == "OptionalType")
|
|
2604
|
+
return `optional<${typeDescription(type.valueType)}>`;
|
|
2605
|
+
if (type.kind == "OrderedMapType")
|
|
2606
|
+
return `ordered-map<string, ${typeDescription(type.valueType)}, insertion>`;
|
|
2607
|
+
return `map<string, ${typeDescription(type.valueType)}>`;
|
|
2608
|
+
}
|
|
2609
|
+
/**
|
|
2610
|
+
* Checks whether a type graph contains linear ownership.
|
|
2611
|
+
* @param {unknown} type - Candidate semantic type.
|
|
2612
|
+
* @param {Set<object>} [seen] - Visited type containers.
|
|
2613
|
+
* @returns {boolean} Whether ownership occurs at any depth.
|
|
2614
|
+
*/
|
|
2615
|
+
function containsOwnedType(type, seen = new Set()) {
|
|
2616
|
+
if (!type || typeof type != "object" || Array.isArray(type) || seen.has(type))
|
|
2617
|
+
return false;
|
|
2618
|
+
seen.add(type);
|
|
2619
|
+
const kind = Reflect.get(type, "kind");
|
|
2620
|
+
if (kind == "OwnedResourceType" || kind == "OwnedReferenceType")
|
|
2621
|
+
return true;
|
|
2622
|
+
if (kind == "ListType")
|
|
2623
|
+
return containsOwnedType(Reflect.get(type, "elementType"), seen);
|
|
2624
|
+
if (kind == "OptionalType")
|
|
2625
|
+
return containsOwnedType(Reflect.get(type, "valueType"), seen);
|
|
2626
|
+
if (kind == "MapType" || kind == "OrderedMapType") {
|
|
2627
|
+
return containsOwnedType(Reflect.get(type, "keyType"), seen) || containsOwnedType(Reflect.get(type, "valueType"), seen);
|
|
2628
|
+
}
|
|
2629
|
+
if (kind == "RecordType") {
|
|
2630
|
+
const arguments_ = Reflect.get(type, "arguments");
|
|
2631
|
+
return Array.isArray(arguments_) && arguments_.some((argument) => containsOwnedType(argument, seen));
|
|
2632
|
+
}
|
|
2633
|
+
return false;
|
|
2634
|
+
}
|
|
2635
|
+
/**
|
|
2636
|
+
* Checks one scalar semantic type.
|
|
2637
|
+
* @param {import("./types.js").SemanticFunctionReturnType} type - Semantic type.
|
|
2638
|
+
* @param {import("./types.js").SemanticTypeName} [name] - Optional required scalar.
|
|
2639
|
+
* @returns {type is import("./types.js").TypeReference} Whether it is the requested scalar.
|
|
2640
|
+
*/
|
|
2641
|
+
function isScalarType(type, name) {
|
|
2642
|
+
return type.kind == "TypeReference" && isScalarTypeName(type.name) && (name === undefined || type.name == name);
|
|
2643
|
+
}
|
|
2644
|
+
/**
|
|
2645
|
+
* Checks the sole non-value return type.
|
|
2646
|
+
* @param {import("./types.js").SemanticFunctionReturnType} type - Semantic type.
|
|
2647
|
+
* @returns {type is import("./types.js").FunctionReturnTypeReference} Whether it is void.
|
|
2648
|
+
*/
|
|
2649
|
+
function isVoidType(type) {
|
|
2650
|
+
return type.kind == "TypeReference" && type.name == "void";
|
|
2651
|
+
}
|
|
2652
|
+
/**
|
|
2653
|
+
* Requires a scalar type for the pre-collection operator contract.
|
|
2654
|
+
* @param {import("./types.js").SemanticValueType} type - Operand type.
|
|
2655
|
+
* @param {import("./types.js").SourceLocation} location - Operand location.
|
|
2656
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
2657
|
+
* @returns {import("./types.js").SemanticTypeName} Scalar name.
|
|
2658
|
+
*/
|
|
2659
|
+
function scalarNameForOperation(type, location, fail) {
|
|
2660
|
+
if (!isScalarType(type)) {
|
|
2661
|
+
return fail("INVALID_OPERAND_TYPE", `Scalar operation received ${typeDescription(type)}.`, location);
|
|
2662
|
+
}
|
|
2663
|
+
return type.name;
|
|
2664
|
+
}
|
|
2665
|
+
/**
|
|
2666
|
+
* Enforces that a total collection access is proven or uses a source operation that fails on absence.
|
|
2667
|
+
* @param {import("./types.js").ListIndexExpression | import("./types.js").MapLookupExpression} expression - Access.
|
|
2668
|
+
* @param {boolean} proven - Whether static literal propagation proves presence.
|
|
2669
|
+
* @param {boolean} normalizeOperations - Whether this is frontend admission.
|
|
2670
|
+
* @param {SemanticFail} fail - Diagnostic callback.
|
|
2671
|
+
* @returns {void}
|
|
2672
|
+
*/
|
|
2673
|
+
function validateAccessTotality(expression, proven, normalizeOperations, fail) {
|
|
2674
|
+
if (proven) {
|
|
2675
|
+
if (normalizeOperations)
|
|
2676
|
+
expression.totality = "proven";
|
|
2677
|
+
else if (expression.totality != "proven" && expression.totality != "fail-on-absence") {
|
|
2678
|
+
fail("UNCHECKED_COLLECTION_ACCESS", "Collection access lacks a totality guarantee.", expression.location);
|
|
2679
|
+
}
|
|
2680
|
+
return;
|
|
2681
|
+
}
|
|
2682
|
+
if (expression.totality != "fail-on-absence") {
|
|
2683
|
+
fail("UNCHECKED_COLLECTION_ACCESS", "Collection access is not statically proven and does not fail on absence.", expression.location);
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
/**
|
|
2687
|
+
* Resolves a binding without producing a diagnostic.
|
|
2688
|
+
* @param {string} name - Binding name.
|
|
2689
|
+
* @param {Scope} scope - Visible scope.
|
|
2690
|
+
* @returns {Binding | undefined} Binding when visible.
|
|
2691
|
+
*/
|
|
2692
|
+
function findBinding(name, scope) {
|
|
2693
|
+
for (let current = /** @type {Scope | undefined} */ (scope); current; current = current.parent) {
|
|
2694
|
+
const binding = current.bindings.get(name);
|
|
2695
|
+
if (binding)
|
|
2696
|
+
return binding;
|
|
2697
|
+
}
|
|
2698
|
+
return undefined;
|
|
2699
|
+
}
|
|
2700
|
+
/**
|
|
2701
|
+
* Returns the existing bindings whose known values must be merged across a conditional.
|
|
2702
|
+
* @param {Scope} scope - Visible scope.
|
|
2703
|
+
* @returns {Binding[]} Nearest-to-farthest bindings.
|
|
2704
|
+
*/
|
|
2705
|
+
function bindingsVisibleFrom(scope) {
|
|
2706
|
+
const bindings = [];
|
|
2707
|
+
for (let current = /** @type {Scope | undefined} */ (scope); current; current = current.parent) {
|
|
2708
|
+
bindings.push(...current.bindings.values());
|
|
2709
|
+
}
|
|
2710
|
+
return bindings;
|
|
2711
|
+
}
|
|
2712
|
+
/**
|
|
2713
|
+
* Finds visible mutable bindings that a loop body may assign on any nested path.
|
|
2714
|
+
* The set is computed after validating the list expression because collection evaluation precedes body effects.
|
|
2715
|
+
* @param {import("./types.js").Block} block - Candidate loop body.
|
|
2716
|
+
* @param {Scope} outerScope - Scope visible before entering the loop.
|
|
2717
|
+
* @param {Set<Binding>} [assigned] - Accumulated binding identities.
|
|
2718
|
+
* @returns {Set<Binding>} Exactly the visible mutable bindings targeted by nested assignments.
|
|
2719
|
+
*/
|
|
2720
|
+
function outerMutableBindingsAssignedBy(block, outerScope, assigned = new Set()) {
|
|
2721
|
+
for (const statement of block.statements) {
|
|
2722
|
+
if (statement.kind == "AssignmentStatement") {
|
|
2723
|
+
const binding = findBinding(statement.target.name, outerScope);
|
|
2724
|
+
if (binding?.mutable)
|
|
2725
|
+
assigned.add(binding);
|
|
2726
|
+
}
|
|
2727
|
+
else if (statement.kind == "IfStatement") {
|
|
2728
|
+
outerMutableBindingsAssignedBy(statement.consequent, outerScope, assigned);
|
|
2729
|
+
if (statement.alternate)
|
|
2730
|
+
outerMutableBindingsAssignedBy(statement.alternate, outerScope, assigned);
|
|
2731
|
+
}
|
|
2732
|
+
else if (statement.kind == "ForEachStatement" || statement.kind == "ForEachMapStatement" || statement.kind == "WhileStatement") {
|
|
2733
|
+
outerMutableBindingsAssignedBy(statement.body, outerScope, assigned);
|
|
2734
|
+
}
|
|
2735
|
+
else if (statement.kind == "TryStatement") {
|
|
2736
|
+
outerMutableBindingsAssignedBy(statement.body, outerScope, assigned);
|
|
2737
|
+
outerMutableBindingsAssignedBy(statement.catchBody, outerScope, assigned);
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
return assigned;
|
|
2741
|
+
}
|
|
2742
|
+
/**
|
|
2743
|
+
* Propagates only immutable values whose exact collection contents remain known.
|
|
2744
|
+
* @param {import("./types.js").Expression} expression - Expression.
|
|
2745
|
+
* @param {Scope} scope - Visible scope.
|
|
2746
|
+
* @returns {import("./types.js").Expression | undefined} Known value.
|
|
2747
|
+
*/
|
|
2748
|
+
function knownValueForExpression(expression, scope) {
|
|
2749
|
+
if (["IntegerLiteral", "BooleanLiteral", "StringLiteral", "ListLiteral", "MapLiteral", "OrderedMapLiteral"].includes(expression.kind))
|
|
2750
|
+
return expression;
|
|
2751
|
+
if (expression.kind == "IdentifierExpression")
|
|
2752
|
+
return findBinding(expression.name, scope)?.knownValue;
|
|
2753
|
+
if (expression.kind == "ListIndexExpression")
|
|
2754
|
+
return provenListElement(expression.collection, expression.index, scope);
|
|
2755
|
+
if (expression.kind == "MapLookupExpression")
|
|
2756
|
+
return provenMapValue(expression.collection, expression.key, scope);
|
|
2757
|
+
return undefined;
|
|
2758
|
+
}
|
|
2759
|
+
/**
|
|
2760
|
+
* Finds the statically selected list element.
|
|
2761
|
+
* @param {import("./types.js").Expression} collection - List receiver.
|
|
2762
|
+
* @param {import("./types.js").Expression} index - Index expression.
|
|
2763
|
+
* @param {Scope} scope - Visible scope.
|
|
2764
|
+
* @returns {import("./types.js").Expression | undefined} Proven element.
|
|
2765
|
+
*/
|
|
2766
|
+
function provenListElement(collection, index, scope) {
|
|
2767
|
+
const knownCollection = knownValueForExpression(collection, scope);
|
|
2768
|
+
const knownIndex = knownValueForExpression(index, scope);
|
|
2769
|
+
if (knownCollection?.kind != "ListLiteral" || knownIndex?.kind != "IntegerLiteral" ||
|
|
2770
|
+
knownIndex.value < 0 || knownIndex.value >= knownCollection.elements.length)
|
|
2771
|
+
return undefined;
|
|
2772
|
+
return knownCollection.elements[knownIndex.value];
|
|
2773
|
+
}
|
|
2774
|
+
/**
|
|
2775
|
+
* Finds the statically selected map value.
|
|
2776
|
+
* @param {import("./types.js").Expression} collection - Map receiver.
|
|
2777
|
+
* @param {import("./types.js").Expression} key - Key expression.
|
|
2778
|
+
* @param {Scope} scope - Visible scope.
|
|
2779
|
+
* @returns {import("./types.js").Expression | undefined} Proven value.
|
|
2780
|
+
*/
|
|
2781
|
+
function provenMapValue(collection, key, scope) {
|
|
2782
|
+
const knownCollection = knownValueForExpression(collection, scope);
|
|
2783
|
+
const knownKey = knownValueForExpression(key, scope);
|
|
2784
|
+
if (knownCollection?.kind != "MapLiteral" && knownCollection?.kind != "OrderedMapLiteral" ||
|
|
2785
|
+
knownKey?.kind != "StringLiteral")
|
|
2786
|
+
return undefined;
|
|
2787
|
+
return knownCollection.entries.find((entry) => entry.key.value == knownKey.value)?.value;
|
|
2788
|
+
}
|
|
2789
|
+
/**
|
|
2790
|
+
* Identifies numeric strings independently from any target's key coercions.
|
|
2791
|
+
* @param {string} value - Literal key.
|
|
2792
|
+
* @returns {boolean} Whether it is numeric.
|
|
2793
|
+
*/
|
|
2794
|
+
function isNumericString(value) {
|
|
2795
|
+
return /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/iu.test(value.trim());
|
|
2796
|
+
}
|
|
2797
|
+
/**
|
|
2798
|
+
* Selects an exact semantic token location when parser provenance is available.
|
|
2799
|
+
* @param {{location: import("./types.js").SourceLocation, sourceProvenance?: import("./types.js").SemanticNodeSourceProvenance}} node - Located semantic node.
|
|
2800
|
+
* @param {string} role - Token role.
|
|
2801
|
+
* @returns {import("./types.js").SourceLocation} Exact or owning location.
|
|
2802
|
+
*/
|
|
2803
|
+
function roleLocation(node, role) {
|
|
2804
|
+
return node.sourceProvenance?.ranges[role] ?? parserRangeFor(node, role) ?? node.location;
|
|
2805
|
+
}
|
|
2806
|
+
/**
|
|
2807
|
+
* Selects the exact type token or the owning declaration location.
|
|
2808
|
+
* @param {unknown} type - Candidate type reference.
|
|
2809
|
+
* @param {import("./types.js").SourceLocation} ownerLocation - Owning declaration location.
|
|
2810
|
+
* @param {string} [role] - Recursive type role.
|
|
2811
|
+
* @returns {import("./types.js").SourceLocation} Exact type location when known.
|
|
2812
|
+
*/
|
|
2813
|
+
function typeLocation(type, ownerLocation, role = "type") {
|
|
2814
|
+
if (!type || typeof type != "object" || Array.isArray(type))
|
|
2815
|
+
return ownerLocation;
|
|
2816
|
+
const candidate = /** @type {import("./types.js").SemanticFunctionReturnType} */ (type);
|
|
2817
|
+
return candidate.sourceProvenance?.ranges[role] ?? parserRangeFor(candidate, role) ??
|
|
2818
|
+
candidate.sourceProvenance?.ranges.type ?? parserRangeFor(candidate, "type") ?? ownerLocation;
|
|
2819
|
+
}
|
|
342
2820
|
/** @type {Readonly<Record<import("./types.js").SemanticUnaryOperation, {operand: import("./types.js").SemanticTypeName, result: import("./types.js").SemanticTypeName}>>} */
|
|
343
2821
|
const unaryOperationSignatures = Object.freeze({
|
|
344
2822
|
BooleanNot: Object.freeze({ operand: "boolean", result: "boolean" }),
|
|
@@ -469,4 +2947,4 @@ function setNormalizedOperation(expression, operation, type) {
|
|
|
469
2947
|
Reflect.set(expression, "operation", operation);
|
|
470
2948
|
Reflect.set(expression, "type", type);
|
|
471
2949
|
}
|
|
472
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VtYW50aWMvdmFsaWRhdGUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxlQUFlLEVBQUUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUMxRixPQUFPLEVBQUMscUJBQXFCLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFDcEUsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sZ0JBQWdCLENBQUE7QUFFbEQ7Ozs7R0FJRztBQUVIOzs7Ozs7R0FNRztBQUVIOzs7R0FHRztBQUVIOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxRQUFRO0lBQ25ELG1CQUFtQixDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQTtJQUNoRyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO0lBRWhILE9BQU8sTUFBTSxDQUFBO0FBQ2YsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxRQUFRO0lBQ25ELG1CQUFtQixDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFBO0FBQ3BILENBQUM7QUFFRDs7Ozs7R0FLRztB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RyxFQUFFLFlBQVksQ0FBQyxDQUFBO0FBQzNHLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFTLHNCQUFzQixDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsSUFBSTtJQUN6RCxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsU0FBUyxDQUFDLENBQUE7SUFDL0MsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFBO0FBQ3ZDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtzZW1hbnRpY0ZhaWx1cmUsIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eSwgdW5zdXBwb3J0ZWRTeW50YXh9IGZyb20gXCIuLi9kaWFnbm9zdGljLmpzXCJcbmltcG9ydCB7aGFzT25seVVuaWNvZGVTY2FsYXJzLCBpc1NjYWxhclR5cGVOYW1lfSBmcm9tIFwiLi9zY2FsYXJzLmpzXCJcbmltcG9ydCB7YWRhcHRlZE9wZXJhdGlvbkZvcn0gZnJvbSBcIi4vb3BlcmF0b3JzLmpzXCJcblxuLyoqXG4gKiBAdHlwZWRlZiBCaW5kaW5nXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IG11dGFibGUgLSBXaGV0aGVyIGFzc2lnbm1lbnQgaXMgYWxsb3dlZC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVOYW1lfSB0eXBlIC0gQmluZGluZyB0eXBlLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgU2NvcGVcbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgQmluZGluZz59IGJpbmRpbmdzIC0gQmluZGluZ3MgZGVjbGFyZWQgZGlyZWN0bHkgaW4gdGhpcyBzY29wZS5cbiAqIEBwcm9wZXJ0eSB7U2V0PHN0cmluZz59IHBlbmRpbmcgLSBOYW1lcyBkZWNsYXJlZCBsYXRlciBpbiB0aGlzIHNjb3BlLlxuICogQHByb3BlcnR5IHtTY29wZSB8IHVuZGVmaW5lZH0gcGFyZW50IC0gRW5jbG9zaW5nIGxleGljYWwgc2NvcGUuXG4gKiBAcHJvcGVydHkge1NldDxzdHJpbmc+fSB1c2VkTmFtZXMgLSBBbGwgbmFtZXMgdXNlZCBieSB0aGUgZW5jbG9zaW5nIGZ1bmN0aW9uIG9yIGVudHJ5IHBvaW50LlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgU2VtYW50aWNGYWlsXG4gKiBAdHlwZSB7KGNvZGU6IHN0cmluZywgZGV0YWlsOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uKSA9PiBuZXZlcn1cbiAqL1xuXG4vKipcbiAqIEVuZm9yY2VzIHRoZSBjb2hlcmVudCByZWxlYXNlLWNhbmRpZGF0ZSBzZW1hbnRpYyBzdWJzZXQgYWZ0ZXIgYWRhcHRhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gQWRhcHRlZCBzZW1hbnRpYyBtb2R1bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBTb3VyY2UgbGFuZ3VhZ2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gVmFsaWRhdGVkIG1vZHVsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUGFyc2VkTW9kdWxlKG1vZHVsZSwgbGFuZ3VhZ2UpIHtcbiAgdmFsaWRhdGVNb2R1bGVTaGFwZShtb2R1bGUsIChkZXRhaWwsIGxvY2F0aW9uKSA9PiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgZGV0YWlsLCBsb2NhdGlvbikpXG4gIHZhbGlkYXRlTW9kdWxlVHlwZXMobW9kdWxlLCAoY29kZSwgZGV0YWlsLCBsb2NhdGlvbikgPT4gc2VtYW50aWNGYWlsdXJlKGxhbmd1YWdlLCBjb2RlLCBkZXRhaWwsIGxvY2F0aW9uKSwgdHJ1ZSlcblxuICByZXR1cm4gbW9kdWxlXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIHNjYWxhciB0eXBlcyBhbmQgYmluZGluZ3MgZm9yIGEgY2FsbGVyLXN1cHBsaWVkIHNlbWFudGljIG1vZHVsZSBiZWZvcmUgZW1pc3Npb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIEJhY2tlbmQgbGFuZ3VhZ2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQmFja2VuZFR5cGVzKG1vZHVsZSwgbGFuZ3VhZ2UpIHtcbiAgdmFsaWRhdGVNb2R1bGVUeXBlcyhtb2R1bGUsIChfY29kZSwgZGV0YWlsLCBsb2NhdGlvbikgPT4gdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBkZXRhaWwsIGxvY2F0aW9uKSwgZmFsc2UpXG59XG5cbi8qKlxuICogQ2hlY2tzIHBhcnNlci1hdXRob3JlZCBibG9jayBhbmQgc3RhdGVtZW50IGxheW91dHMgYmVmb3JlIHNlbWFudGljIHZhbGlkYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7KGRldGFpbDogc3RyaW5nLCBsb2NhdGlvbjogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbikgPT4gbmV2ZXJ9IGZhaWwgLSBTaGFwZSBmYWlsdXJlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlTW9kdWxlU2hhcGUobW9kdWxlLCBmYWlsKSB7XG4gIGZvciAoY29uc3QgZnVuY3Rpb25EZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSB7XG4gICAgaWYgKGZ1bmN0aW9uRGVjbGFyYXRpb24ucGFyYW1ldGVycy5sZW5ndGggIT0gMikge1xuICAgICAgZmFpbChcImZ1bmN0aW9uIHBhcmFtZXRlciBjb3VudCBvdGhlciB0aGFuIHR3b1wiLCBmdW5jdGlvbkRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICAgIH1cblxuICAgIHZhbGlkYXRlQmxvY2tTaGFwZShmdW5jdGlvbkRlY2xhcmF0aW9uLmJvZHksIFwiZnVuY3Rpb24gYm9keVwiLCBmYWlsKVxuICB9XG5cbiAgdmFsaWRhdGVCbG9ja1NoYXBlKG1vZHVsZS5lbnRyeVBvaW50LmJvZHksIFwiZW50cnkgcG9pbnRcIiwgZmFpbClcbn1cblxuLyoqXG4gKiBDaGVja3Mgb25lIHJlY3Vyc2l2ZWx5IG5lc3RlZCBzZW1hbnRpYyBibG9jayBwcm9kdWNlZCBieSBhIGZyb250ZW5kLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJsb2NrfSBibG9jayAtIFNlbWFudGljIGJsb2NrLlxuICogQHBhcmFtIHtzdHJpbmd9IGRldGFpbCAtIERpYWdub3N0aWMgZGV0YWlsLlxuICogQHBhcmFtIHsoZGV0YWlsOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uKSA9PiBuZXZlcn0gZmFpbCAtIFNoYXBlIGZhaWx1cmUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVCbG9ja1NoYXBlKGJsb2NrLCBkZXRhaWwsIGZhaWwpIHtcbiAgaWYgKCFibG9jayB8fCBibG9jay5raW5kICE9IFwiQmxvY2tcIiB8fCAhQXJyYXkuaXNBcnJheShibG9jay5zdGF0ZW1lbnRzKSkge1xuICAgIGZhaWwoYCR7ZGV0YWlsfSB3aXRob3V0IEJsb2NrYCwgYmxvY2s/LmxvY2F0aW9uID8/IC8qKiBAdHlwZSB7bmV2ZXJ9ICovICh1bmRlZmluZWQpKVxuICB9XG5cbiAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgYmxvY2suc3RhdGVtZW50cykge1xuICAgIGlmICghW1wiQXNzaWdubWVudFN0YXRlbWVudFwiLCBcIklmU3RhdGVtZW50XCIsIFwiTG9jYWxEZWNsYXJhdGlvblwiLCBcIlByaW50U3RhdGVtZW50XCIsIFwiUmV0dXJuU3RhdGVtZW50XCJdLmluY2x1ZGVzKHN0YXRlbWVudC5raW5kKSkge1xuICAgICAgZmFpbChgJHtkZXRhaWx9IHN0YXRlbWVudCAke3N0YXRlbWVudC5raW5kfWAsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgdmFsaWRhdGVCbG9ja1NoYXBlKHN0YXRlbWVudC5jb25zZXF1ZW50LCBcImlmIGNvbnNlcXVlbnRcIiwgZmFpbClcbiAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSB2YWxpZGF0ZUJsb2NrU2hhcGUoc3RhdGVtZW50LmFsdGVybmF0ZSwgXCJpZiBhbHRlcm5hdGVcIiwgZmFpbClcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgZGVjbGFyYXRpb25zIGFuZCBleHByZXNzaW9uIHR5cGVzIHdpdGhpbiBsZXhpY2FsIHNjb3Blcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gU2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtTZW1hbnRpY0ZhaWx9IGZhaWwgLSBEaWFnbm9zdGljIGNhbGxiYWNrLlxuICogQHBhcmFtIHtib29sZWFufSBub3JtYWxpemVPcGVyYXRpb25zIC0gV2hldGhlciB0byByZXBsYWNlIHRyYW5zaWVudCBmcm9udGVuZCBvcGVyYXRpb24gaW50ZW50LlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlTW9kdWxlVHlwZXMobW9kdWxlLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zKSB7XG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uPn0gKi9cbiAgY29uc3QgZnVuY3Rpb25zID0gbmV3IE1hcCgpXG5cbiAgZm9yIChjb25zdCBmdW5jdGlvbkRlY2xhcmF0aW9uIG9mIG1vZHVsZS5mdW5jdGlvbnMpIHtcbiAgICBpZiAoZnVuY3Rpb25zLmhhcyhmdW5jdGlvbkRlY2xhcmF0aW9uLm5hbWUpKSB7XG4gICAgICBmYWlsKFwiRFVQTElDQVRFX0JJTkRJTkdcIiwgYGR1cGxpY2F0ZSBmdW5jdGlvbiAnJHtmdW5jdGlvbkRlY2xhcmF0aW9uLm5hbWV9Jy5gLCBmdW5jdGlvbkRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBmdW5jdGlvbnMuc2V0KGZ1bmN0aW9uRGVjbGFyYXRpb24ubmFtZSwgZnVuY3Rpb25EZWNsYXJhdGlvbilcbiAgfVxuXG4gIGZvciAoY29uc3QgZnVuY3Rpb25EZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSB2YWxpZGF0ZUZ1bmN0aW9uKGZ1bmN0aW9uRGVjbGFyYXRpb24sIGZ1bmN0aW9ucywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucylcblxuICBjb25zdCBjYWxsYWJsZU5hbWVzID0gbmV3IFNldChmdW5jdGlvbnMua2V5cygpKVxuXG4gIGNvbnN0IGVudHJ5U2NvcGUgPSBjcmVhdGVTY29wZSh1bmRlZmluZWQsIG1vZHVsZS5lbnRyeVBvaW50LmJvZHkuc3RhdGVtZW50cywgY2FsbGFibGVOYW1lcylcblxuICB2YWxpZGF0ZUJsb2NrKG1vZHVsZS5lbnRyeVBvaW50LmJvZHksIGVudHJ5U2NvcGUsIHVuZGVmaW5lZCwgZnVuY3Rpb25zLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zKVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBvbmUgbm9uLXZvaWQgZnVuY3Rpb24gYW5kIGl0cyBjb21wbGV0ZSBjb250cm9sIGZsb3cuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbn0gZGVjbGFyYXRpb24gLSBGdW5jdGlvbiBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uPn0gZnVuY3Rpb25zIC0gRnVuY3Rpb24gc2lnbmF0dXJlcy5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gbm9ybWFsaXplT3BlcmF0aW9ucyAtIFdoZXRoZXIgdG8gcmVwbGFjZSB0cmFuc2llbnQgZnJvbnRlbmQgb3BlcmF0aW9uIGludGVudC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUZ1bmN0aW9uKGRlY2xhcmF0aW9uLCBmdW5jdGlvbnMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMpIHtcbiAgY29uc3Qgc2NvcGUgPSBjcmVhdGVTY29wZSh1bmRlZmluZWQsIGRlY2xhcmF0aW9uLmJvZHkuc3RhdGVtZW50cywgbmV3IFNldChmdW5jdGlvbnMua2V5cygpKSlcblxuICBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzKSB7XG4gICAgY29uc3QgdHlwZSA9IHZhbGlkYXRlVHlwZVJlZmVyZW5jZShwYXJhbWV0ZXIudHlwZSwgcGFyYW1ldGVyLmxvY2F0aW9uLCBmYWlsKVxuXG4gICAgZGVjbGFyZUJpbmRpbmcocGFyYW1ldGVyLm5hbWUsIHttdXRhYmxlOiBmYWxzZSwgdHlwZX0sIHBhcmFtZXRlci5sb2NhdGlvbiwgc2NvcGUsIGZhaWwpXG4gIH1cblxuICBjb25zdCByZXR1cm5UeXBlID0gdmFsaWRhdGVUeXBlUmVmZXJlbmNlKGRlY2xhcmF0aW9uLnJldHVyblR5cGUsIGRlY2xhcmF0aW9uLmxvY2F0aW9uLCBmYWlsKVxuICBjb25zdCByZXR1cm5zID0gdmFsaWRhdGVCbG9jayhkZWNsYXJhdGlvbi5ib2R5LCBzY29wZSwgcmV0dXJuVHlwZSwgZnVuY3Rpb25zLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zKVxuXG4gIGlmICghcmV0dXJucykgZmFpbChcIk1JU1NJTkdfUkVUVVJOXCIsIGBGdW5jdGlvbiAnJHtkZWNsYXJhdGlvbi5uYW1lfScgZG9lcyBub3QgcmV0dXJuIG9uIGV2ZXJ5IHJlYWNoYWJsZSBwYXRoLmAsIGRlY2xhcmF0aW9uLmxvY2F0aW9uKVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBvbmUgb3JkZXJlZCBibG9jayBhbmQgcmVwb3J0cyB3aGV0aGVyIGV2ZXJ5IHBhdGggcmV0dXJucy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBTZW1hbnRpYyBibG9jay5cbiAqIEBwYXJhbSB7U2NvcGV9IHNjb3BlIC0gU2NvcGUgYmVsb25naW5nIHRvIHRoaXMgYmxvY2suXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZSB8IHVuZGVmaW5lZH0gcmV0dXJuVHlwZSAtIEZ1bmN0aW9uIHJldHVybiB0eXBlLCBhYnNlbnQgZm9yIGVudHJ5IHBvaW50cy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uPn0gZnVuY3Rpb25zIC0gRnVuY3Rpb24gc2lnbmF0dXJlcy5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gbm9ybWFsaXplT3BlcmF0aW9ucyAtIFdoZXRoZXIgdG8gcmVwbGFjZSB0cmFuc2llbnQgZnJvbnRlbmQgb3BlcmF0aW9uIGludGVudC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIGV2ZXJ5IHBhdGggdGhyb3VnaCB0aGUgYmxvY2sgcmV0dXJucy5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVCbG9jayhibG9jaywgc2NvcGUsIHJldHVyblR5cGUsIGZ1bmN0aW9ucywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucykge1xuICBsZXQgYWx3YXlzUmV0dXJucyA9IGZhbHNlXG5cbiAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgYmxvY2suc3RhdGVtZW50cykge1xuICAgIGlmIChhbHdheXNSZXR1cm5zKSBmYWlsKFwiVU5SRUFDSEFCTEVfU1RBVEVNRU5UXCIsIFwiU3RhdGVtZW50IGlzIHVucmVhY2hhYmxlLlwiLCBzdGF0ZW1lbnQubG9jYXRpb24pXG5cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIpIHtcbiAgICAgIGNvbnN0IGRlY2xhcmVkVHlwZSA9IHZhbGlkYXRlVHlwZVJlZmVyZW5jZShzdGF0ZW1lbnQudHlwZSwgc3RhdGVtZW50LmxvY2F0aW9uLCBmYWlsKVxuICAgICAgY29uc3QgaW5pdGlhbGl6ZXJUeXBlID0gaW5mZXJFeHByZXNzaW9uVHlwZShzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIsIHNjb3BlLCBmdW5jdGlvbnMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMpXG5cbiAgICAgIHNjb3BlLnBlbmRpbmcuZGVsZXRlKHN0YXRlbWVudC5uYW1lKVxuICAgICAgaWYgKGluaXRpYWxpemVyVHlwZSAhPSBkZWNsYXJlZFR5cGUpIHtcbiAgICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYEluaXRpYWxpemVyIHR5cGUgJHtpbml0aWFsaXplclR5cGV9OyBleHBlY3RlZCAke2RlY2xhcmVkVHlwZX0uYCwgc3RhdGVtZW50LmluaXRpYWxpemVyLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgZGVjbGFyZUJpbmRpbmcoc3RhdGVtZW50Lm5hbWUsIHttdXRhYmxlOiBzdGF0ZW1lbnQubXV0YWJsZSwgdHlwZTogZGVjbGFyZWRUeXBlfSwgc3RhdGVtZW50LmxvY2F0aW9uLCBzY29wZSwgZmFpbClcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIikge1xuICAgICAgY29uc3QgZXhwcmVzc2lvblR5cGUgPSBpbmZlckV4cHJlc3Npb25UeXBlKHN0YXRlbWVudC5leHByZXNzaW9uLCBzY29wZSwgZnVuY3Rpb25zLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zKVxuICAgICAgY29uc3QgYmluZGluZyA9IHJlc29sdmVCaW5kaW5nKHN0YXRlbWVudC50YXJnZXQubmFtZSwgc3RhdGVtZW50LnRhcmdldC5sb2NhdGlvbiwgc2NvcGUsIGZhaWwpXG5cbiAgICAgIGlmICghYmluZGluZy5tdXRhYmxlKSB7XG4gICAgICAgIGZhaWwoXCJJTU1VVEFCTEVfQVNTSUdOTUVOVFwiLCBgQ2Fubm90IGFzc2lnbiB0byBpbW11dGFibGUgYmluZGluZyAnJHtzdGF0ZW1lbnQudGFyZ2V0Lm5hbWV9Jy5gLCBzdGF0ZW1lbnQudGFyZ2V0LmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKGV4cHJlc3Npb25UeXBlICE9IGJpbmRpbmcudHlwZSkge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgQXNzaWdubWVudCB0eXBlICR7ZXhwcmVzc2lvblR5cGV9OyBleHBlY3RlZCAke2JpbmRpbmcudHlwZX0uYCwgc3RhdGVtZW50LmV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJQcmludFN0YXRlbWVudFwiKSB7XG4gICAgICBpbmZlckV4cHJlc3Npb25UeXBlKHN0YXRlbWVudC5leHByZXNzaW9uLCBzY29wZSwgZnVuY3Rpb25zLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zKVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIpIHtcbiAgICAgIGlmICghcmV0dXJuVHlwZSkgZmFpbChcIklMTEVHQUxfUkVUVVJOX0NPTlRFWFRcIiwgXCJSZXR1cm4gc3RhdGVtZW50IG91dHNpZGUgYSBmdW5jdGlvbi5cIiwgc3RhdGVtZW50LmxvY2F0aW9uKVxuICAgICAgY29uc3QgYWN0dWFsVHlwZSA9IGluZmVyRXhwcmVzc2lvblR5cGUoc3RhdGVtZW50LmV4cHJlc3Npb24sIHNjb3BlLCBmdW5jdGlvbnMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMpXG5cbiAgICAgIGlmIChhY3R1YWxUeXBlICE9IHJldHVyblR5cGUpIHtcbiAgICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYFJldHVybiB0eXBlICR7YWN0dWFsVHlwZX07IGV4cGVjdGVkICR7cmV0dXJuVHlwZX0uYCwgc3RhdGVtZW50LmV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBhbHdheXNSZXR1cm5zID0gdHJ1ZVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgY29uc3QgY29uZGl0aW9uVHlwZSA9IGluZmVyRXhwcmVzc2lvblR5cGUoc3RhdGVtZW50LmNvbmRpdGlvbiwgc2NvcGUsIGZ1bmN0aW9ucywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucylcblxuICAgICAgaWYgKGNvbmRpdGlvblR5cGUgIT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgZmFpbChcIk5PTl9CT09MRUFOX0NPTkRJVElPTlwiLCBgSWYgY29uZGl0aW9uIHR5cGUgJHtjb25kaXRpb25UeXBlfTsgZXhwZWN0ZWQgYm9vbGVhbi5gLCBzdGF0ZW1lbnQuY29uZGl0aW9uLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY29uc3QgY29uc2VxdWVudFNjb3BlID0gY3JlYXRlU2NvcGUoc2NvcGUsIHN0YXRlbWVudC5jb25zZXF1ZW50LnN0YXRlbWVudHMpXG4gICAgICBjb25zdCBjb25zZXF1ZW50UmV0dXJucyA9IHZhbGlkYXRlQmxvY2soc3RhdGVtZW50LmNvbnNlcXVlbnQsIGNvbnNlcXVlbnRTY29wZSwgcmV0dXJuVHlwZSwgZnVuY3Rpb25zLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zKVxuICAgICAgbGV0IGFsdGVybmF0ZVJldHVybnMgPSBmYWxzZVxuXG4gICAgICBpZiAoc3RhdGVtZW50LmFsdGVybmF0ZSkge1xuICAgICAgICBjb25zdCBhbHRlcm5hdGVTY29wZSA9IGNyZWF0ZVNjb3BlKHNjb3BlLCBzdGF0ZW1lbnQuYWx0ZXJuYXRlLnN0YXRlbWVudHMpXG5cbiAgICAgICAgYWx0ZXJuYXRlUmV0dXJucyA9IHZhbGlkYXRlQmxvY2soc3RhdGVtZW50LmFsdGVybmF0ZSwgYWx0ZXJuYXRlU2NvcGUsIHJldHVyblR5cGUsIGZ1bmN0aW9ucywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucylcbiAgICAgIH1cbiAgICAgIGFsd2F5c1JldHVybnMgPSBjb25zZXF1ZW50UmV0dXJucyAmJiBhbHRlcm5hdGVSZXR1cm5zXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGNvbnN0IHVuZXhwZWN0ZWQgPSAvKiogQHR5cGUge3traW5kOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufX0gKi8gKHN0YXRlbWVudClcblxuICAgIGZhaWwoXCJVTlNVUFBPUlRFRF9TVEFURU1FTlRcIiwgdW5leHBlY3RlZC5raW5kLCB1bmV4cGVjdGVkLmxvY2F0aW9uKVxuICB9XG5cbiAgcmV0dXJuIGFsd2F5c1JldHVybnNcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbGV4aWNhbCBzY29wZSB3aXRoIGRlY2xhcmF0aW9ucyBtYXJrZWQgcGVuZGluZyB1bnRpbCB2aXNpdGVkLlxuICogQHBhcmFtIHtTY29wZSB8IHVuZGVmaW5lZH0gcGFyZW50IC0gRW5jbG9zaW5nIHNjb3BlLlxuICogQHBhcmFtIHt7a2luZDogc3RyaW5nLCBuYW1lPzogc3RyaW5nfVtdfSBzdGF0ZW1lbnRzIC0gU2NvcGUgc3RhdGVtZW50cy5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IFtyZXNlcnZlZE5hbWVzXSAtIE5hbWVzIHVuYXZhaWxhYmxlIHRvIHJvb3QgYmluZGluZ3MuXG4gKiBAcmV0dXJucyB7U2NvcGV9IFNjb3BlLlxuICovXG5mdW5jdGlvbiBjcmVhdGVTY29wZShwYXJlbnQsIHN0YXRlbWVudHMsIHJlc2VydmVkTmFtZXMgPSBuZXcgU2V0KCkpIHtcbiAgY29uc3QgcGVuZGluZyA9IG5ldyBTZXQoc3RhdGVtZW50cy5maWx0ZXIoKHN0YXRlbWVudCkgPT4gc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIpXG4gICAgLm1hcCgoc3RhdGVtZW50KSA9PiAvKiogQHR5cGUge3tuYW1lOiBzdHJpbmd9fSAqLyAoc3RhdGVtZW50KS5uYW1lKSlcblxuICByZXR1cm4ge2JpbmRpbmdzOiBuZXcgTWFwKCksIHBhcmVudCwgcGVuZGluZywgdXNlZE5hbWVzOiBwYXJlbnQ/LnVzZWROYW1lcyA/PyBuZXcgU2V0KHJlc2VydmVkTmFtZXMpfVxufVxuXG4vKipcbiAqIEFkZHMgb25lIGJpbmRpbmcgd2hpbGUgcmVqZWN0aW5nIGR1cGxpY2F0ZXMgYW5kIHNoYWRvd2luZy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gQmluZGluZyBuYW1lLlxuICogQHBhcmFtIHtCaW5kaW5nfSBiaW5kaW5nIC0gQmluZGluZyBtZXRhZGF0YS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbG9jYXRpb24gLSBEZWNsYXJhdGlvbiBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7U2NvcGV9IHNjb3BlIC0gQ3VycmVudCBzY29wZS5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBkZWNsYXJlQmluZGluZyhuYW1lLCBiaW5kaW5nLCBsb2NhdGlvbiwgc2NvcGUsIGZhaWwpIHtcbiAgaWYgKHNjb3BlLnVzZWROYW1lcy5oYXMobmFtZSkpIGZhaWwoXCJEVVBMSUNBVEVfQklORElOR1wiLCBgRHVwbGljYXRlIG9yIHNoYWRvd2VkIGJpbmRpbmcgJyR7bmFtZX0nLmAsIGxvY2F0aW9uKVxuXG4gIHNjb3BlLmJpbmRpbmdzLnNldChuYW1lLCBiaW5kaW5nKVxuICBzY29wZS51c2VkTmFtZXMuYWRkKG5hbWUpXG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25lIGlkZW50aWZpZXIgYW5kIGRpc3Rpbmd1aXNoZXMgdXNlLWJlZm9yZS1kZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gQmluZGluZyBuYW1lLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIFJlZmVyZW5jZSBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7U2NvcGV9IHNjb3BlIC0gQ3VycmVudCBzY29wZS5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEByZXR1cm5zIHtCaW5kaW5nfSBCaW5kaW5nLlxuICovXG5mdW5jdGlvbiByZXNvbHZlQmluZGluZyhuYW1lLCBsb2NhdGlvbiwgc2NvcGUsIGZhaWwpIHtcbiAgZm9yIChsZXQgY3VycmVudCA9IC8qKiBAdHlwZSB7U2NvcGUgfCB1bmRlZmluZWR9ICovIChzY29wZSk7IGN1cnJlbnQ7IGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudCkge1xuICAgIGNvbnN0IGJpbmRpbmcgPSBjdXJyZW50LmJpbmRpbmdzLmdldChuYW1lKVxuXG4gICAgaWYgKGJpbmRpbmcpIHJldHVybiBiaW5kaW5nXG4gICAgaWYgKGN1cnJlbnQucGVuZGluZy5oYXMobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVVNFX0JFRk9SRV9ERUNMQVJBVElPTlwiLCBgQmluZGluZyAnJHtuYW1lfScgaXMgdXNlZCBiZWZvcmUgaXRzIGRlY2xhcmF0aW9uLmAsIGxvY2F0aW9uKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWlsKFwiVU5SRVNPTFZFRF9CSU5ESU5HXCIsIGBVbmtub3duIGJpbmRpbmcgJyR7bmFtZX0nLmAsIGxvY2F0aW9uKVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBvbmUgc2VtYW50aWMgdHlwZSByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge3Vua25vd259IHR5cGUgLSBDYW5kaWRhdGUgc2VtYW50aWMgdHlwZSByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gT3duaW5nIHNvdXJjZSBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWV9IFZhbGlkYXRlZCBzY2FsYXIgbmFtZS5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVUeXBlUmVmZXJlbmNlKHR5cGUsIGxvY2F0aW9uLCBmYWlsKSB7XG4gIGlmICghdHlwZSB8fCB0eXBlb2YgdHlwZSAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkodHlwZSkpIHtcbiAgICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJVbnN1cHBvcnRlZCBzY2FsYXIgdHlwZS5cIiwgbG9jYXRpb24pXG4gIH1cblxuICBjb25zdCBjYW5kaWRhdGUgPSAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKHR5cGUpXG5cbiAgaWYgKGNhbmRpZGF0ZS5raW5kICE9IFwiVHlwZVJlZmVyZW5jZVwiIHx8ICFpc1NjYWxhclR5cGVOYW1lKGNhbmRpZGF0ZS5uYW1lKSkge1xuICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiVW5zdXBwb3J0ZWQgc2NhbGFyIHR5cGUuXCIsIGxvY2F0aW9uKVxuICB9XG5cbiAgcmV0dXJuIGNhbmRpZGF0ZS5uYW1lXG59XG5cbi8qKlxuICogSW5mZXJzIGFuZCB2YWxpZGF0ZXMgb25lIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gZXhwcmVzc2lvbiAtIFNlbWFudGljIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge1Njb3BlfSBzY29wZSAtIFZpc2libGUgbGV4aWNhbCBzY29wZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uPn0gZnVuY3Rpb25zIC0gTW9kdWxlIGZ1bmN0aW9uIHNpZ25hdHVyZXMuXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5vcm1hbGl6ZU9wZXJhdGlvbnMgLSBXaGV0aGVyIHRvIHJlcGxhY2UgdHJhbnNpZW50IGZyb250ZW5kIG9wZXJhdGlvbiBpbnRlbnQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVOYW1lfSBFeHByZXNzaW9uIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGluZmVyRXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbiwgc2NvcGUsIGZ1bmN0aW9ucywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucykge1xuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIikgcmV0dXJuIHJlc29sdmVCaW5kaW5nKGV4cHJlc3Npb24ubmFtZSwgZXhwcmVzc2lvbi5sb2NhdGlvbiwgc2NvcGUsIGZhaWwpLnR5cGVcblxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiSW50ZWdlckxpdGVyYWxcIikge1xuICAgIGlmICghTnVtYmVyLmlzU2FmZUludGVnZXIoZXhwcmVzc2lvbi52YWx1ZSkpIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiTm9uLXNhZmUgaW50ZWdlciBsaXRlcmFsLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIHJldHVybiBcImludGVnZXJcIlxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCb29sZWFuTGl0ZXJhbFwiKSB7XG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0LmdldChleHByZXNzaW9uLCBcInZhbHVlXCIpICE9IFwiYm9vbGVhblwiKSB7XG4gICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIkludmFsaWQgYm9vbGVhbiBsaXRlcmFsIHZhbHVlLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICByZXR1cm4gXCJib29sZWFuXCJcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiU3RyaW5nTGl0ZXJhbFwiKSB7XG4gICAgY29uc3QgdmFsdWUgPSBSZWZsZWN0LmdldChleHByZXNzaW9uLCBcInZhbHVlXCIpXG5cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9IFwic3RyaW5nXCIgfHwgIWhhc09ubHlVbmljb2RlU2NhbGFycyh2YWx1ZSkpIHtcbiAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiSW52YWxpZCBVbmljb2RlIHN0cmluZyBsaXRlcmFsLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICByZXR1cm4gXCJzdHJpbmdcIlxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgY29uc3QgZnVuY3Rpb25EZWNsYXJhdGlvbiA9IGZ1bmN0aW9ucy5nZXQoZXhwcmVzc2lvbi5jYWxsZWUpXG5cbiAgICBpZiAoIWZ1bmN0aW9uRGVjbGFyYXRpb24pIHJldHVybiBmYWlsKFwiVU5SRVNPTFZFRF9CSU5ESU5HXCIsIGBVbmtub3duIGZ1bmN0aW9uICcke2V4cHJlc3Npb24uY2FsbGVlfScuYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICBpZiAoZXhwcmVzc2lvbi5hcmd1bWVudHMubGVuZ3RoICE9IGZ1bmN0aW9uRGVjbGFyYXRpb24ucGFyYW1ldGVycy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgQ2FsbCBhcmd1bWVudCBjb3VudCBmb3IgJyR7ZXhwcmVzc2lvbi5jYWxsZWV9Jy5gLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgZXhwcmVzc2lvbi5hcmd1bWVudHMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCBhcmd1bWVudCA9IGV4cHJlc3Npb24uYXJndW1lbnRzW2luZGV4XVxuICAgICAgY29uc3QgYWN0dWFsVHlwZSA9IGluZmVyRXhwcmVzc2lvblR5cGUoYXJndW1lbnQsIHNjb3BlLCBmdW5jdGlvbnMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMpXG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB2YWxpZGF0ZVR5cGVSZWZlcmVuY2UoZnVuY3Rpb25EZWNsYXJhdGlvbi5wYXJhbWV0ZXJzW2luZGV4XS50eXBlLCBmdW5jdGlvbkRlY2xhcmF0aW9uLnBhcmFtZXRlcnNbaW5kZXhdLmxvY2F0aW9uLCBmYWlsKVxuXG4gICAgICBpZiAoYWN0dWFsVHlwZSAhPSBleHBlY3RlZFR5cGUpIHtcbiAgICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYENhbGwgYXJndW1lbnQgdHlwZSAke2FjdHVhbFR5cGV9OyBleHBlY3RlZCAke2V4cGVjdGVkVHlwZX0uYCwgYXJndW1lbnQubG9jYXRpb24pXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB2YWxpZGF0ZVR5cGVSZWZlcmVuY2UoZnVuY3Rpb25EZWNsYXJhdGlvbi5yZXR1cm5UeXBlLCBmdW5jdGlvbkRlY2xhcmF0aW9uLmxvY2F0aW9uLCBmYWlsKVxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJVbmFyeUV4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IG9wZXJhbmRUeXBlID0gaW5mZXJFeHByZXNzaW9uVHlwZShleHByZXNzaW9uLm9wZXJhbmQsIHNjb3BlLCBmdW5jdGlvbnMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMpXG4gICAgY29uc3Qgb3BlcmF0aW9uID0gbm9ybWFsaXplT3BlcmF0aW9uc1xuICAgICAgPyBub3JtYWxpemVVbmFyeU9wZXJhdGlvbihhZGFwdGVkT3BlcmF0aW9uRm9yKGV4cHJlc3Npb24pLCBvcGVyYW5kVHlwZSwgZXhwcmVzc2lvbi5vcGVyYW5kLmxvY2F0aW9uLCBmYWlsKVxuICAgICAgOiBleHByZXNzaW9uLm9wZXJhdGlvblxuXG4gICAgaWYgKG5vcm1hbGl6ZU9wZXJhdGlvbnMpIHNldE5vcm1hbGl6ZWRPcGVyYXRpb24oZXhwcmVzc2lvbiwgb3BlcmF0aW9uLCB1bmFyeU9wZXJhdGlvblNpZ25hdHVyZXNbb3BlcmF0aW9uXS5yZXN1bHQpXG5cbiAgICBjb25zdCBzaWduYXR1cmUgPSB1bmFyeU9wZXJhdGlvblNpZ25hdHVyZXNbb3BlcmF0aW9uXVxuXG4gICAgaWYgKCFzaWduYXR1cmUpIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgVW5rbm93biB1bmFyeSBvcGVyYXRpb24gJHtTdHJpbmcob3BlcmF0aW9uKX0uYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICBpZiAob3BlcmFuZFR5cGUgIT0gc2lnbmF0dXJlLm9wZXJhbmQpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiSU5WQUxJRF9PUEVSQU5EX1RZUEVcIiwgYCR7b3BlcmF0aW9ufSByZXF1aXJlcyAke3NpZ25hdHVyZS5vcGVyYW5kfTsgcmVjZWl2ZWQgJHtvcGVyYW5kVHlwZX0uYCwgZXhwcmVzc2lvbi5vcGVyYW5kLmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoZXhwcmVzc2lvbi50eXBlICE9IHNpZ25hdHVyZS5yZXN1bHQpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgJHtvcGVyYXRpb259IHJlc3VsdCB0eXBlICR7U3RyaW5nKGV4cHJlc3Npb24udHlwZSl9OyBleHBlY3RlZCAke3NpZ25hdHVyZS5yZXN1bHR9LmAsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIHJldHVybiBzaWduYXR1cmUucmVzdWx0XG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IGxlZnRUeXBlID0gaW5mZXJFeHByZXNzaW9uVHlwZShleHByZXNzaW9uLmxlZnQsIHNjb3BlLCBmdW5jdGlvbnMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMpXG4gICAgY29uc3QgcmlnaHRUeXBlID0gaW5mZXJFeHByZXNzaW9uVHlwZShleHByZXNzaW9uLnJpZ2h0LCBzY29wZSwgZnVuY3Rpb25zLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zKVxuICAgIGNvbnN0IG9wZXJhdGlvbiA9IG5vcm1hbGl6ZU9wZXJhdGlvbnNcbiAgICAgID8gbm9ybWFsaXplQmluYXJ5T3BlcmF0aW9uKGFkYXB0ZWRPcGVyYXRpb25Gb3IoZXhwcmVzc2lvbiksIGxlZnRUeXBlLCByaWdodFR5cGUsIGV4cHJlc3Npb24ubGVmdC5sb2NhdGlvbiwgZXhwcmVzc2lvbi5yaWdodC5sb2NhdGlvbiwgZXhwcmVzc2lvbi5sb2NhdGlvbiwgZmFpbClcbiAgICAgIDogZXhwcmVzc2lvbi5vcGVyYXRpb25cblxuICAgIGlmIChub3JtYWxpemVPcGVyYXRpb25zKSBzZXROb3JtYWxpemVkT3BlcmF0aW9uKGV4cHJlc3Npb24sIG9wZXJhdGlvbiwgYmluYXJ5T3BlcmF0aW9uU2lnbmF0dXJlc1tvcGVyYXRpb25dLnJlc3VsdClcblxuICAgIGNvbnN0IHNpZ25hdHVyZSA9IGJpbmFyeU9wZXJhdGlvblNpZ25hdHVyZXNbb3BlcmF0aW9uXVxuXG4gICAgaWYgKCFzaWduYXR1cmUpIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgVW5rbm93biBiaW5hcnkgb3BlcmF0aW9uICR7U3RyaW5nKG9wZXJhdGlvbil9LmAsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgaWYgKGxlZnRUeXBlICE9IHNpZ25hdHVyZS5sZWZ0KSB7XG4gICAgICByZXR1cm4gZmFpbChcIklOVkFMSURfT1BFUkFORF9UWVBFXCIsIGAke29wZXJhdGlvbn0gcmVxdWlyZXMgJHtzaWduYXR1cmUubGVmdH0gbGVmdCBvcGVyYW5kOyByZWNlaXZlZCAke2xlZnRUeXBlfS5gLCBleHByZXNzaW9uLmxlZnQubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChyaWdodFR5cGUgIT0gc2lnbmF0dXJlLnJpZ2h0KSB7XG4gICAgICByZXR1cm4gZmFpbChcIklOVkFMSURfT1BFUkFORF9UWVBFXCIsIGAke29wZXJhdGlvbn0gcmVxdWlyZXMgJHtzaWduYXR1cmUucmlnaHR9IHJpZ2h0IG9wZXJhbmQ7IHJlY2VpdmVkICR7cmlnaHRUeXBlfS5gLCBleHByZXNzaW9uLnJpZ2h0LmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoZXhwcmVzc2lvbi50eXBlICE9IHNpZ25hdHVyZS5yZXN1bHQpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgJHtvcGVyYXRpb259IHJlc3VsdCB0eXBlICR7U3RyaW5nKGV4cHJlc3Npb24udHlwZSl9OyBleHBlY3RlZCAke3NpZ25hdHVyZS5yZXN1bHR9LmAsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIHJldHVybiBzaWduYXR1cmUucmVzdWx0XG4gIH1cblxuICBjb25zdCB1bmV4cGVjdGVkID0gLyoqIEB0eXBlIHt7a2luZDogc3RyaW5nLCBsb2NhdGlvbjogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn19ICovIChleHByZXNzaW9uKVxuXG4gIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCB1bmV4cGVjdGVkLmtpbmQsIHVuZXhwZWN0ZWQubG9jYXRpb24pXG59XG5cbi8qKiBAdHlwZSB7UmVhZG9ubHk8UmVjb3JkPGltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNVbmFyeU9wZXJhdGlvbiwge29wZXJhbmQ6IGltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZSwgcmVzdWx0OiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWV9Pj59ICovXG5jb25zdCB1bmFyeU9wZXJhdGlvblNpZ25hdHVyZXMgPSBPYmplY3QuZnJlZXplKHtcbiAgQm9vbGVhbk5vdDogT2JqZWN0LmZyZWV6ZSh7b3BlcmFuZDogXCJib29sZWFuXCIsIHJlc3VsdDogXCJib29sZWFuXCJ9KSxcbiAgSW50ZWdlck5lZ2F0ZTogT2JqZWN0LmZyZWV6ZSh7b3BlcmFuZDogXCJpbnRlZ2VyXCIsIHJlc3VsdDogXCJpbnRlZ2VyXCJ9KVxufSlcblxuLyoqIEB0eXBlIHtSZWFkb25seTxSZWNvcmQ8aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY0JpbmFyeU9wZXJhdGlvbiwge2xlZnQ6IGltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZSwgcmlnaHQ6IGltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZSwgcmVzdWx0OiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWV9Pj59ICovXG5jb25zdCBiaW5hcnlPcGVyYXRpb25TaWduYXR1cmVzID0gT2JqZWN0LmZyZWV6ZSh7XG4gIEJvb2xlYW5BbmQ6IE9iamVjdC5mcmVlemUoe2xlZnQ6IFwiYm9vbGVhblwiLCByZXN1bHQ6IFwiYm9vbGVhblwiLCByaWdodDogXCJib29sZWFuXCJ9KSxcbiAgQm9vbGVhbkVxdWFsOiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcImJvb2xlYW5cIiwgcmVzdWx0OiBcImJvb2xlYW5cIiwgcmlnaHQ6IFwiYm9vbGVhblwifSksXG4gIEJvb2xlYW5Ob3RFcXVhbDogT2JqZWN0LmZyZWV6ZSh7bGVmdDogXCJib29sZWFuXCIsIHJlc3VsdDogXCJib29sZWFuXCIsIHJpZ2h0OiBcImJvb2xlYW5cIn0pLFxuICBCb29sZWFuT3I6IE9iamVjdC5mcmVlemUoe2xlZnQ6IFwiYm9vbGVhblwiLCByZXN1bHQ6IFwiYm9vbGVhblwiLCByaWdodDogXCJib29sZWFuXCJ9KSxcbiAgSW50ZWdlckFkZDogT2JqZWN0LmZyZWV6ZSh7bGVmdDogXCJpbnRlZ2VyXCIsIHJlc3VsdDogXCJpbnRlZ2VyXCIsIHJpZ2h0OiBcImludGVnZXJcIn0pLFxuICBJbnRlZ2VyRXF1YWw6IE9iamVjdC5mcmVlemUoe2xlZnQ6IFwiaW50ZWdlclwiLCByZXN1bHQ6IFwiYm9vbGVhblwiLCByaWdodDogXCJpbnRlZ2VyXCJ9KSxcbiAgSW50ZWdlckdyZWF0ZXJUaGFuOiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcImludGVnZXJcIiwgcmVzdWx0OiBcImJvb2xlYW5cIiwgcmlnaHQ6IFwiaW50ZWdlclwifSksXG4gIEludGVnZXJHcmVhdGVyVGhhbk9yRXF1YWw6IE9iamVjdC5mcmVlemUoe2xlZnQ6IFwiaW50ZWdlclwiLCByZXN1bHQ6IFwiYm9vbGVhblwiLCByaWdodDogXCJpbnRlZ2VyXCJ9KSxcbiAgSW50ZWdlckxlc3NUaGFuOiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcImludGVnZXJcIiwgcmVzdWx0OiBcImJvb2xlYW5cIiwgcmlnaHQ6IFwiaW50ZWdlclwifSksXG4gIEludGVnZXJMZXNzVGhhbk9yRXF1YWw6IE9iamVjdC5mcmVlemUoe2xlZnQ6IFwiaW50ZWdlclwiLCByZXN1bHQ6IFwiYm9vbGVhblwiLCByaWdodDogXCJpbnRlZ2VyXCJ9KSxcbiAgSW50ZWdlck11bHRpcGx5OiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcImludGVnZXJcIiwgcmVzdWx0OiBcImludGVnZXJcIiwgcmlnaHQ6IFwiaW50ZWdlclwifSksXG4gIEludGVnZXJOb3RFcXVhbDogT2JqZWN0LmZyZWV6ZSh7bGVmdDogXCJpbnRlZ2VyXCIsIHJlc3VsdDogXCJib29sZWFuXCIsIHJpZ2h0OiBcImludGVnZXJcIn0pLFxuICBJbnRlZ2VyU3VidHJhY3Q6IE9iamVjdC5mcmVlemUoe2xlZnQ6IFwiaW50ZWdlclwiLCByZXN1bHQ6IFwiaW50ZWdlclwiLCByaWdodDogXCJpbnRlZ2VyXCJ9KSxcbiAgU3RyaW5nQ29uY2F0OiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcInN0cmluZ1wiLCByZXN1bHQ6IFwic3RyaW5nXCIsIHJpZ2h0OiBcInN0cmluZ1wifSksXG4gIFN0cmluZ0VxdWFsOiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcInN0cmluZ1wiLCByZXN1bHQ6IFwiYm9vbGVhblwiLCByaWdodDogXCJzdHJpbmdcIn0pLFxuICBTdHJpbmdOb3RFcXVhbDogT2JqZWN0LmZyZWV6ZSh7bGVmdDogXCJzdHJpbmdcIiwgcmVzdWx0OiBcImJvb2xlYW5cIiwgcmlnaHQ6IFwic3RyaW5nXCJ9KVxufSlcblxuLyoqXG4gKiBTZWxlY3RzIG9uZSB0eXBlZCB1bmFyeSBtZWFuaW5nIGZyb20gcGFyc2VyLW5vcm1hbGl6ZWQgc291cmNlIGludGVudC5cbiAqIEBwYXJhbSB7dW5rbm93bn0gc291cmNlT3BlcmF0aW9uIC0gVHJhbnNpZW50IGZyb250ZW5kIG9wZXJhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVOYW1lfSBvcGVyYW5kVHlwZSAtIFJlc29sdmVkIG9wZXJhbmQgdHlwZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbG9jYXRpb24gLSBPcGVyYW5kIGxvY2F0aW9uLlxuICogQHBhcmFtIHtTZW1hbnRpY0ZhaWx9IGZhaWwgLSBEaWFnbm9zdGljIGNhbGxiYWNrLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNVbmFyeU9wZXJhdGlvbn0gU2VtYW50aWMgb3BlcmF0aW9uLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVVbmFyeU9wZXJhdGlvbihzb3VyY2VPcGVyYXRpb24sIG9wZXJhbmRUeXBlLCBsb2NhdGlvbiwgZmFpbCkge1xuICBpZiAoc291cmNlT3BlcmF0aW9uID09IFwiTmVnYXRlXCIpIHtcbiAgICBpZiAob3BlcmFuZFR5cGUgIT0gXCJpbnRlZ2VyXCIpIGZhaWwoXCJJTlZBTElEX09QRVJBTkRfVFlQRVwiLCBgSW50ZWdlciBuZWdhdGlvbiByZXF1aXJlcyBpbnRlZ2VyOyByZWNlaXZlZCAke29wZXJhbmRUeXBlfS5gLCBsb2NhdGlvbilcbiAgICByZXR1cm4gXCJJbnRlZ2VyTmVnYXRlXCJcbiAgfVxuICBpZiAoc291cmNlT3BlcmF0aW9uID09IFwiTm90XCIpIHtcbiAgICBpZiAob3BlcmFuZFR5cGUgIT0gXCJib29sZWFuXCIpIGZhaWwoXCJJTlZBTElEX09QRVJBTkRfVFlQRVwiLCBgQm9vbGVhbiBub3QgcmVxdWlyZXMgYm9vbGVhbjsgcmVjZWl2ZWQgJHtvcGVyYW5kVHlwZX0uYCwgbG9jYXRpb24pXG4gICAgcmV0dXJuIFwiQm9vbGVhbk5vdFwiXG4gIH1cblxuICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYFVua25vd24gdW5hcnkgc291cmNlIG9wZXJhdGlvbiAke1N0cmluZyhzb3VyY2VPcGVyYXRpb24pfS5gLCBsb2NhdGlvbilcbn1cblxuLyoqXG4gKiBTZWxlY3RzIG9uZSB0eXBlZCBiaW5hcnkgbWVhbmluZyBmcm9tIHBhcnNlci1ub3JtYWxpemVkIHNvdXJjZSBpbnRlbnQuXG4gKiBAcGFyYW0ge3Vua25vd259IHNvdXJjZU9wZXJhdGlvbiAtIFRyYW5zaWVudCBmcm9udGVuZCBvcGVyYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZX0gbGVmdFR5cGUgLSBSZXNvbHZlZCBsZWZ0IHR5cGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZX0gcmlnaHRUeXBlIC0gUmVzb2x2ZWQgcmlnaHQgdHlwZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbGVmdExvY2F0aW9uIC0gTGVmdCBvcGVyYW5kIGxvY2F0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSByaWdodExvY2F0aW9uIC0gUmlnaHQgb3BlcmFuZCBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gZXhwcmVzc2lvbkxvY2F0aW9uIC0gV2hvbGUgb3BlcmF0aW9uIGxvY2F0aW9uLlxuICogQHBhcmFtIHtTZW1hbnRpY0ZhaWx9IGZhaWwgLSBEaWFnbm9zdGljIGNhbGxiYWNrLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNCaW5hcnlPcGVyYXRpb259IFNlbWFudGljIG9wZXJhdGlvbi5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplQmluYXJ5T3BlcmF0aW9uKHNvdXJjZU9wZXJhdGlvbiwgbGVmdFR5cGUsIHJpZ2h0VHlwZSwgbGVmdExvY2F0aW9uLCByaWdodExvY2F0aW9uLCBleHByZXNzaW9uTG9jYXRpb24sIGZhaWwpIHtcbiAgaWYgKHNvdXJjZU9wZXJhdGlvbiA9PSBcIlBocEFkZFwiKSB7XG4gICAgaWYgKGxlZnRUeXBlID09IFwic3RyaW5nXCIgJiYgcmlnaHRUeXBlID09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVU5TVVBQT1JURURfU1lOVEFYXCIsIFwiUEhQIGJpbmFyeSArIGRvZXMgbm90IGNvbmNhdGVuYXRlIHN0cmluZ3M7IHVzZSAuIGluc3RlYWQuXCIsIGV4cHJlc3Npb25Mb2NhdGlvbilcbiAgICB9XG5cbiAgICBzb3VyY2VPcGVyYXRpb24gPSBcIkFkZFwiXG4gIH1cblxuICBpZiAoc291cmNlT3BlcmF0aW9uID09IFwiU3RyaW5nQ29uY2F0XCIpIHtcbiAgICBpZiAobGVmdFR5cGUgIT0gXCJzdHJpbmdcIikgZmFpbChcIklOVkFMSURfT1BFUkFORF9UWVBFXCIsIGBTdHJpbmcgY29uY2F0ZW5hdGlvbiByZXF1aXJlcyBzdHJpbmc7IHJlY2VpdmVkICR7bGVmdFR5cGV9LmAsIGxlZnRMb2NhdGlvbilcbiAgICBpZiAocmlnaHRUeXBlICE9IFwic3RyaW5nXCIpIGZhaWwoXCJJTlZBTElEX09QRVJBTkRfVFlQRVwiLCBgU3RyaW5nIGNvbmNhdGVuYXRpb24gcmVxdWlyZXMgc3RyaW5nOyByZWNlaXZlZCAke3JpZ2h0VHlwZX0uYCwgcmlnaHRMb2NhdGlvbilcbiAgICByZXR1cm4gXCJTdHJpbmdDb25jYXRcIlxuICB9XG5cbiAgaWYgKHNvdXJjZU9wZXJhdGlvbiA9PSBcIkFkZFwiKSB7XG4gICAgaWYgKGxlZnRUeXBlID09IFwiaW50ZWdlclwiICYmIHJpZ2h0VHlwZSA9PSBcImludGVnZXJcIikgcmV0dXJuIFwiSW50ZWdlckFkZFwiXG4gICAgaWYgKGxlZnRUeXBlID09IFwic3RyaW5nXCIgJiYgcmlnaHRUeXBlID09IFwic3RyaW5nXCIpIHJldHVybiBcIlN0cmluZ0NvbmNhdFwiXG5cbiAgICBjb25zdCBsb2NhdGlvbiA9IGxlZnRUeXBlID09IFwiaW50ZWdlclwiIHx8IGxlZnRUeXBlID09IFwic3RyaW5nXCIgPyByaWdodExvY2F0aW9uIDogbGVmdExvY2F0aW9uXG5cbiAgICByZXR1cm4gZmFpbChcIklOVkFMSURfT1BFUkFORF9UWVBFXCIsIGBBZGRpdGlvbiByZXF1aXJlcyB0d28gaW50ZWdlcnMgb3IgdHdvIHN0cmluZ3M7IHJlY2VpdmVkICR7bGVmdFR5cGV9IGFuZCAke3JpZ2h0VHlwZX0uYCwgbG9jYXRpb24pXG4gIH1cblxuICBjb25zdCBmaXhlZE9wZXJhdGlvbnMgPSAvKiogQHR5cGUge2NvbnN0fSAqLyAoe1xuICAgIEFuZDogW1wiYm9vbGVhblwiLCBcIkJvb2xlYW5BbmRcIl0sXG4gICAgR3JlYXRlclRoYW46IFtcImludGVnZXJcIiwgXCJJbnRlZ2VyR3JlYXRlclRoYW5cIl0sXG4gICAgR3JlYXRlclRoYW5PckVxdWFsOiBbXCJpbnRlZ2VyXCIsIFwiSW50ZWdlckdyZWF0ZXJUaGFuT3JFcXVhbFwiXSxcbiAgICBMZXNzVGhhbjogW1wiaW50ZWdlclwiLCBcIkludGVnZXJMZXNzVGhhblwiXSxcbiAgICBMZXNzVGhhbk9yRXF1YWw6IFtcImludGVnZXJcIiwgXCJJbnRlZ2VyTGVzc1RoYW5PckVxdWFsXCJdLFxuICAgIE11bHRpcGx5OiBbXCJpbnRlZ2VyXCIsIFwiSW50ZWdlck11bHRpcGx5XCJdLFxuICAgIE9yOiBbXCJib29sZWFuXCIsIFwiQm9vbGVhbk9yXCJdLFxuICAgIFN1YnRyYWN0OiBbXCJpbnRlZ2VyXCIsIFwiSW50ZWdlclN1YnRyYWN0XCJdXG4gIH0pXG4gIGNvbnN0IGZpeGVkID0gUmVmbGVjdC5nZXQoZml4ZWRPcGVyYXRpb25zLCBTdHJpbmcoc291cmNlT3BlcmF0aW9uKSlcblxuICBpZiAoZml4ZWQpIHtcbiAgICBjb25zdCBbcmVxdWlyZWRUeXBlLCBvcGVyYXRpb25dID0gZml4ZWRcblxuICAgIGlmIChsZWZ0VHlwZSAhPSByZXF1aXJlZFR5cGUpIGZhaWwoXCJJTlZBTElEX09QRVJBTkRfVFlQRVwiLCBgJHtTdHJpbmcoc291cmNlT3BlcmF0aW9uKX0gcmVxdWlyZXMgJHtyZXF1aXJlZFR5cGV9OyByZWNlaXZlZCAke2xlZnRUeXBlfS5gLCBsZWZ0TG9jYXRpb24pXG4gICAgaWYgKHJpZ2h0VHlwZSAhPSByZXF1aXJlZFR5cGUpIGZhaWwoXCJJTlZBTElEX09QRVJBTkRfVFlQRVwiLCBgJHtTdHJpbmcoc291cmNlT3BlcmF0aW9uKX0gcmVxdWlyZXMgJHtyZXF1aXJlZFR5cGV9OyByZWNlaXZlZCAke3JpZ2h0VHlwZX0uYCwgcmlnaHRMb2NhdGlvbilcblxuICAgIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNCaW5hcnlPcGVyYXRpb259ICovIChvcGVyYXRpb24pXG4gIH1cblxuICBpZiAoc291cmNlT3BlcmF0aW9uID09IFwiSmF2YUVxdWFsXCIgfHwgc291cmNlT3BlcmF0aW9uID09IFwiSmF2YU5vdEVxdWFsXCIpIHtcbiAgICBpZiAobGVmdFR5cGUgPT0gXCJzdHJpbmdcIiB8fCByaWdodFR5cGUgPT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIGZhaWwoXCJVTlNVUFBPUlRFRF9TWU5UQVhcIiwgXCJKYXZhIHJlZmVyZW5jZSBlcXVhbGl0eSBpcyBvdXRzaWRlIHRoZSBpbXBsZW1lbnRlZCBzZW1hbnRpYyBzdWJzZXQuXCIsIGV4cHJlc3Npb25Mb2NhdGlvbilcbiAgICB9XG5cbiAgICBzb3VyY2VPcGVyYXRpb24gPSBzb3VyY2VPcGVyYXRpb24gPT0gXCJKYXZhRXF1YWxcIiA/IFwiRXF1YWxcIiA6IFwiTm90RXF1YWxcIlxuICB9XG5cbiAgaWYgKHNvdXJjZU9wZXJhdGlvbiA9PSBcIlN0cmluZ0VxdWFsXCIgfHwgc291cmNlT3BlcmF0aW9uID09IFwiU3RyaW5nTm90RXF1YWxcIikge1xuICAgIGlmIChsZWZ0VHlwZSAhPSBcInN0cmluZ1wiKSBmYWlsKFwiSU5WQUxJRF9PUEVSQU5EX1RZUEVcIiwgYFN0cmluZyBlcXVhbGl0eSByZXF1aXJlcyBzdHJpbmc7IHJlY2VpdmVkICR7bGVmdFR5cGV9LmAsIGxlZnRMb2NhdGlvbilcbiAgICBpZiAocmlnaHRUeXBlICE9IFwic3RyaW5nXCIpIGZhaWwoXCJJTlZBTElEX09QRVJBTkRfVFlQRVwiLCBgU3RyaW5nIGVxdWFsaXR5IHJlcXVpcmVzIHN0cmluZzsgcmVjZWl2ZWQgJHtyaWdodFR5cGV9LmAsIHJpZ2h0TG9jYXRpb24pXG5cbiAgICByZXR1cm4gLyoqIEB0eXBlIHtcIlN0cmluZ0VxdWFsXCIgfCBcIlN0cmluZ05vdEVxdWFsXCJ9ICovIChzb3VyY2VPcGVyYXRpb24pXG4gIH1cblxuICBpZiAoc291cmNlT3BlcmF0aW9uID09IFwiRXF1YWxcIiB8fCBzb3VyY2VPcGVyYXRpb24gPT0gXCJOb3RFcXVhbFwiKSB7XG4gICAgaWYgKGxlZnRUeXBlICE9IHJpZ2h0VHlwZSkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJNSVNNQVRDSEVEX0VRVUFMSVRZX1RZUEVTXCIsIGBFcXVhbGl0eSByZXF1aXJlcyBtYXRjaGluZyBzY2FsYXIgdHlwZXM7IHJlY2VpdmVkICR7bGVmdFR5cGV9IGFuZCAke3JpZ2h0VHlwZX0uYCwgcmlnaHRMb2NhdGlvbilcbiAgICB9XG5cbiAgICBjb25zdCBwcmVmaXggPSBsZWZ0VHlwZSA9PSBcImludGVnZXJcIiA/IFwiSW50ZWdlclwiIDogbGVmdFR5cGUgPT0gXCJib29sZWFuXCIgPyBcIkJvb2xlYW5cIiA6IFwiU3RyaW5nXCJcblxuICAgIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNCaW5hcnlPcGVyYXRpb259ICovIChgJHtwcmVmaXh9JHtzb3VyY2VPcGVyYXRpb259YClcbiAgfVxuXG4gIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgVW5rbm93biBiaW5hcnkgc291cmNlIG9wZXJhdGlvbiAke1N0cmluZyhzb3VyY2VPcGVyYXRpb24pfS5gLCBsZWZ0TG9jYXRpb24pXG59XG5cbi8qKlxuICogUmVwbGFjZXMgdHJhbnNpZW50IGZyb250ZW5kIGludGVudCB3aXRoIHRoZSBwdWJsaWMgdHlwZWQgb3BlcmF0aW9uIGZpZWxkcy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBleHByZXNzaW9uIC0gTXV0YWJsZSBhZGFwdGVkIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNVbmFyeU9wZXJhdGlvbiB8IGltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNCaW5hcnlPcGVyYXRpb259IG9wZXJhdGlvbiAtIFR5cGVkIG9wZXJhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVOYW1lfSB0eXBlIC0gRXhwbGljaXQgcmVzdWx0IHR5cGUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gc2V0Tm9ybWFsaXplZE9wZXJhdGlvbihleHByZXNzaW9uLCBvcGVyYXRpb24sIHR5cGUpIHtcbiAgUmVmbGVjdC5zZXQoZXhwcmVzc2lvbiwgXCJvcGVyYXRpb25cIiwgb3BlcmF0aW9uKVxuICBSZWZsZWN0LnNldChleHByZXNzaW9uLCBcInR5cGVcIiwgdHlwZSlcbn1cbiJdfQ==
|
|
2950
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VtYW50aWMvdmFsaWRhdGUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxlQUFlLEVBQUUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUMxRixPQUFPLEVBQUMsdUJBQXVCLEVBQUUsbUJBQW1CLEVBQUUsdUJBQXVCLEVBQUMsTUFBTSxlQUFlLENBQUE7QUFDbkcsT0FBTyxFQUFDLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLFVBQVUsRUFBQyxNQUFNLGNBQWMsQ0FBQTtBQUNoRixPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQTtBQUNsRCxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0saUJBQWlCLENBQUE7QUFDOUMsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sY0FBYyxDQUFBO0FBQ2hELE9BQU8sRUFBQyx5QkFBeUIsRUFBQyxNQUFNLGVBQWUsQ0FBQTtBQUV2RCxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0FBRTdGLG9GQUFvRjtBQUNwRixrRkFBa0Y7QUFDbEYsa0ZBQWtGO0FBQ2xGLHFEQUFxRDtBQUNyRCxNQUFNLGdDQUFnQyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7QUFDdEQsbURBQW1EO0FBQ25ELE1BQU0sMkJBQTJCLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQTtBQUVqRDs7Ozs7R0FLRztBQUVIOzs7Ozs7Ozs7R0FTRztBQUVIOzs7OztHQUtHO0FBRUg7OztHQUdHO0FBRUg7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsT0FBTyxHQUFHLEVB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LEVBQUUsbUNBQW1DLE1BQU0sQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxDQUFBO0FBQzNHLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFTLHNCQUFzQixDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsSUFBSTtJQUN6RCxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsU0FBUyxDQUFDLENBQUE7SUFDL0MsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFBO0FBQ3ZDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtzZW1hbnRpY0ZhaWx1cmUsIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eSwgdW5zdXBwb3J0ZWRTeW50YXh9IGZyb20gXCIuLi9kaWFnbm9zdGljLmpzXCJcbmltcG9ydCB7cmVjb3JkVHlwZVN1YnN0aXR1dGlvbnMsIHN1YnN0aXR1dGVWYWx1ZVR5cGUsIHR5cGVDb250YWluc0FueVZhcmlhYmxlfSBmcm9tIFwiLi9nZW5lcmljcy5qc1wiXG5pbXBvcnQge2hhc09ubHlVbmljb2RlU2NhbGFycywgaXNTY2FsYXJUeXBlTmFtZSwgc2NhbGFyVHlwZX0gZnJvbSBcIi4vc2NhbGFycy5qc1wiXG5pbXBvcnQge2FkYXB0ZWRPcGVyYXRpb25Gb3J9IGZyb20gXCIuL29wZXJhdG9ycy5qc1wiXG5pbXBvcnQge3BhcnNlclJhbmdlRm9yfSBmcm9tIFwiLi9wcm92ZW5hbmNlLmpzXCJcbmltcG9ydCB7dmFsaWRhdGVFZmZlY3RHcmFwaH0gZnJvbSBcIi4vZWZmZWN0cy5qc1wiXG5pbXBvcnQge3ZhbGlkYXRlUmVzb3VyY2VMaWZldGltZXN9IGZyb20gXCIuL2xpZmV0aW1lLmpzXCJcblxuY29uc3QgdGFzazAwNUxhbmd1YWdlcyA9IG5ldyBTZXQoW1wicGhwXCIsIFwicnVieVwiLCBcImphdmFzY3JpcHRcIiwgXCJ0eXBlc2NyaXB0XCIsIFwiamF2YVwiLCBcImRhcnRcIl0pXG5cbi8qKiBAdHlwZWRlZiB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbj59IFJlY29yZFJlZ2lzdHJ5ICovXG4vKiogQHR5cGVkZWYge01hcDxzdHJpbmcsIGltcG9ydChcIi4vdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbj59IENsYXNzUmVnaXN0cnkgKi9cbi8qKiBAdHlwZWRlZiB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uPn0gRXJyb3JSZWdpc3RyeSAqL1xuLyoqIEB0eXBlIHtXZWFrTWFwPFJlY29yZFJlZ2lzdHJ5LCBDbGFzc1JlZ2lzdHJ5Pn0gKi9cbmNvbnN0IHJlZmVyZW5jZUNsYXNzZXNCeVJlY29yZFJlZ2lzdHJ5ID0gbmV3IFdlYWtNYXAoKVxuLyoqIEB0eXBlIHtXZWFrTWFwPFJlY29yZFJlZ2lzdHJ5LCBTZXQ8c3RyaW5nPj59ICovXG5jb25zdCByZXNvdXJjZUlkc0J5UmVjb3JkUmVnaXN0cnkgPSBuZXcgV2Vha01hcCgpXG5cbi8qKlxuICogQHR5cGVkZWYgQmluZGluZ1xuICogQHByb3BlcnR5IHtib29sZWFufSBtdXRhYmxlIC0gV2hldGhlciBhc3NpZ25tZW50IGlzIGFsbG93ZWQuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNCaW5kaW5nVHlwZX0gdHlwZSAtIEJpbmRpbmcgdHlwZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FeHByZXNzaW9uIHwgdW5kZWZpbmVkfSBrbm93blZhbHVlIC0gQ3VycmVudCBzdGF0aWNhbGx5IGtub3duIGltbXV0YWJsZSB2YWx1ZS5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIFNjb3BlXG4gKiBAcHJvcGVydHkge01hcDxzdHJpbmcsIEJpbmRpbmc+fSBiaW5kaW5ncyAtIEJpbmRpbmdzIGRlY2xhcmVkIGRpcmVjdGx5IGluIHRoaXMgc2NvcGUuXG4gKiBAcHJvcGVydHkge1NldDxzdHJpbmc+fSBwZW5kaW5nIC0gTmFtZXMgZGVjbGFyZWQgbGF0ZXIgaW4gdGhpcyBzY29wZS5cbiAqIEBwcm9wZXJ0eSB7U2V0PEJpbmRpbmc+fSBwcmVzZW5jZVByb29mcyAtIE9wdGlvbmFsIGJpbmRpbmdzIHByb3ZlbiBwcmVzZW50IG9uIHRoaXMgcGF0aC5cbiAqIEBwcm9wZXJ0eSB7U2NvcGUgfCB1bmRlZmluZWR9IHBhcmVudCAtIEVuY2xvc2luZyBsZXhpY2FsIHNjb3BlLlxuICogQHByb3BlcnR5IHtTZXQ8c3RyaW5nPn0gdHlwZVBhcmFtZXRlcnMgLSBUeXBlIHBhcmFtZXRlcnMgdmlzaWJsZSB0aHJvdWdob3V0IHRoZSBlbmNsb3NpbmcgZGVjbGFyYXRpb24uXG4gKiBAcHJvcGVydHkge1NldDxzdHJpbmc+fSB1c2VkTmFtZXMgLSBBbGwgbmFtZXMgdXNlZCBieSB0aGUgZW5jbG9zaW5nIGZ1bmN0aW9uIG9yIGVudHJ5IHBvaW50LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24gfCB1bmRlZmluZWR9IGN1cnJlbnRDbGFzcyAtIERlY2xhcmluZyBjbGFzcyBmb3IgcmVjZWl2ZXItcHJpdmF0ZSBhY2Nlc3MuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBMb29wRmxvd0NvbnRleHRcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Gb3JFYWNoU3RhdGVtZW50IHwgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Gb3JFYWNoTWFwU3RhdGVtZW50IHwgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5XaGlsZVN0YXRlbWVudH0gW25lYXJlc3RdIC0gTmVhcmVzdCBhY3RpdmUgbG9vcC5cbiAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBvd25lciAtIEVuY2xvc2luZyBmdW5jdGlvbiBvciBlbnRyeS1wb2ludCBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgb2JqZWN0Pn0gb3duZXJzIC0gTG9vcCBvd25lciBieSBtb2R1bGUtbG9jYWwgbG9vcCBpZGVudGl0eS5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIFNlbWFudGljRmFpbFxuICogQHR5cGUgeyhjb2RlOiBzdHJpbmcsIGRldGFpbDogc3RyaW5nLCBsb2NhdGlvbjogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbikgPT4gbmV2ZXJ9XG4gKi9cblxuLyoqXG4gKiBFbmZvcmNlcyB0aGUgY29oZXJlbnQgcmVsZWFzZS1jYW5kaWRhdGUgc2VtYW50aWMgc3Vic2V0IGFmdGVyIGFkYXB0YXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIEFkYXB0ZWQgc2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gU291cmNlIGxhbmd1YWdlLlxuICogQHBhcmFtIHt7Y2xhc3Nlcz86IE1hcDxzdHJpbmcsIGltcG9ydChcIi4vdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbj4sIGZ1bmN0aW9ucz86IE1hcDxzdHJpbmcsIGltcG9ydChcIi4vdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbj4sIHJlY29yZHM/OiBNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uPiwgZXJyb3JzPzogTWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uPiwgY2FsbEVmZmVjdHM/OiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj59fSBbdmlzaWJsZV0gLSBQcm9ncmFtIGltcG9ydHMgdmlzaWJsZSBkdXJpbmcgdmFsaWRhdGlvbi5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBWYWxpZGF0ZWQgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVQYXJzZWRNb2R1bGUobW9kdWxlLCBsYW5ndWFnZSwgdmlzaWJsZSA9IHt9KSB7XG4gIG5vcm1hbGl6ZVBhcnNlZE93bmVkUmVmZXJlbmNlcyhtb2R1bGUsIHZpc2libGUuY2xhc3NlcylcbiAgdmFsaWRhdGVNb2R1bGVTaGFwZShtb2R1bGUsIGxhbmd1YWdlLCAoZGV0YWlsLCBsb2NhdGlvbikgPT4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGRldGFpbCwgbG9jYXRpb24pKVxuICAvKipcbiAgICogQ29udmVydHMgb25lIHBhcnNlciBmYWlsdXJlIGludG8gYSBsb2NhdGVkIHNlbWFudGljIGRpYWdub3N0aWMuXG4gICAqIEB0eXBlIHtTZW1hbnRpY0ZhaWx9XG4gICAqL1xuICBjb25zdCBmYWlsID0gKGNvZGUsIGRldGFpbCwgbG9jYXRpb24pID0+IHNlbWFudGljRmFpbHVyZShsYW5ndWFnZSwgY29kZSwgZGV0YWlsLCBsb2NhdGlvbilcblxuICB2YWxpZGF0ZU1vZHVsZVR5cGVzKG1vZHVsZSwgbGFuZ3VhZ2UsIGZhaWwsIHRydWUsIHZpc2libGUpXG4gIHZhbGlkYXRlUmVzb3VyY2VMaWZldGltZXMobW9kdWxlLCBpbmZlckVzY2FwaW5nRXJyb3JFZmZlY3RzKG1vZHVsZSwgdmlzaWJsZS5jYWxsRWZmZWN0cyksIGZhaWwpXG5cbiAgcmV0dXJuIG1vZHVsZVxufVxuXG4vKipcbiAqIFByb21vdGVzIHBhcnNlci1hdXRob3JlZCBjbGFzcyBzcGVsbGluZ3MgYWZ0ZXIgYWxsIHByaXZhdGUgZmllbGQgdHlwZXMgYXJlIGtub3duLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBQYXJzZXItYXV0aG9yZWQgbW9kdWxlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24+fSBbdmlzaWJsZUNsYXNzZXNdIC0gSW1wb3J0ZWQgcmVmZXJlbmNlIGNsYXNzZXMuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplUGFyc2VkT3duZWRSZWZlcmVuY2VzKG1vZHVsZSwgdmlzaWJsZUNsYXNzZXMgPSBuZXcgTWFwKCkpIHtcbiAgY29uc3Qgb3duZWRDbGFzc0lkcyA9IG5ldyBTZXQoWy4uLnZpc2libGVDbGFzc2VzLnZhbHVlcygpXS5maWx0ZXIoKHtvd25lcnNoaXB9KSA9PiBvd25lcnNoaXA/LmtpbmQgPT0gXCJvd25lZFJlc291cmNlXCIpXG4gICAgLm1hcCgoe2lkfSkgPT4gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChpZCkpKVxuXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmNsYXNzZXMgPz8gW10pIHtcbiAgICBjb25zdCBmaWVsZHMgPSBkZWNsYXJhdGlvbi5maWVsZHMuZmlsdGVyKCh7dHlwZX0pID0+IHR5cGU/LmtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiKVxuICAgIGlmIChmaWVsZHMubGVuZ3RoICE9IDEpIGNvbnRpbnVlXG4gICAgY29uc3QgZmllbGQgPSAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuUHJpdmF0ZUZpZWxkICYge3R5cGU6IGltcG9ydChcIi4vdHlwZXMuanNcIikuT3duZWRSZXNvdXJjZVR5cGV9fSAqLyAoZmllbGRzWzBdKVxuXG4gICAgZGVjbGFyYXRpb24ub3duZXJzaGlwID0ge2ZpZWxkSWQ6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZmllbGQuaWQpLCBraW5kOiBcIm93bmVkUmVzb3VyY2VcIiwgcmVzb3VyY2VJZDogZmllbGQudHlwZS5yZXNvdXJjZUlkfVxuICAgIG93bmVkQ2xhc3NJZHMuYWRkKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpKVxuICB9XG4gIC8qKiBAdHlwZSB7dW5rbm93bltdfSAqL1xuICBjb25zdCBwZW5kaW5nID0gW21vZHVsZV1cbiAgLyoqIEB0eXBlIHtTZXQ8b2JqZWN0Pn0gKi9cbiAgY29uc3Qgc2VlbiA9IG5ldyBTZXQoKVxuXG4gIHdoaWxlIChwZW5kaW5nLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCB2YWx1ZSA9IHBlbmRpbmcucG9wKClcbiAgICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKHZhbHVlKSkgY29udGludWVcbiAgICBzZWVuLmFkZCh2YWx1ZSlcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpICYmIFJlZmxlY3QuZ2V0KHZhbHVlLCBcImtpbmRcIikgPT0gXCJSZWZlcmVuY2VUeXBlXCIgJiZcbiAgICAgIG93bmVkQ2xhc3NJZHMuaGFzKFJlZmxlY3QuZ2V0KHZhbHVlLCBcImRlY2xhcmF0aW9uSWRcIikpKSBSZWZsZWN0LnNldCh2YWx1ZSwgXCJraW5kXCIsIFwiT3duZWRSZWZlcmVuY2VUeXBlXCIpXG4gICAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG4gICAgICBpZiAoW1wibG9jYXRpb25cIiwgXCJzb3VyY2VQcm92ZW5hbmNlXCJdLmluY2x1ZGVzKGtleSkpIGNvbnRpbnVlXG4gICAgICBpZiAoY2hpbGQgJiYgdHlwZW9mIGNoaWxkID09IFwib2JqZWN0XCIpIHBlbmRpbmcucHVzaChjaGlsZClcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgc2NhbGFyIHR5cGVzIGFuZCBiaW5kaW5ncyBmb3IgYSBjYWxsZXItc3VwcGxpZWQgc2VtYW50aWMgbW9kdWxlIGJlZm9yZSBlbWlzc2lvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gU2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJhY2tlbmRMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBCYWNrZW5kIGxhbmd1YWdlIG9yIGJpbmFyeSB0YXJnZXQuXG4gKiBAcGFyYW0ge3tjbGFzc2VzPzogTWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uPiwgZnVuY3Rpb25zPzogTWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uPiwgcmVjb3Jkcz86IE1hcDxzdHJpbmcsIGltcG9ydChcIi4vdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24+LCBlcnJvcnM/OiBNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+LCBjYWxsRWZmZWN0cz86IE1hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn19IFt2aXNpYmxlXSAtIFJlc29sdmVkIHByb2dyYW0gaW1wb3J0cy5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVCYWNrZW5kVHlwZXMobW9kdWxlLCBsYW5ndWFnZSwgdmlzaWJsZSA9IHt9KSB7XG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgYmFja2VuZCB2YWxpZGF0aW9uIGZhaWx1cmUgaW50byBhbiB1bnN1cHBvcnRlZC1jYXBhYmlsaXR5IGRpYWdub3N0aWMuXG4gICAqIEB0eXBlIHtTZW1hbnRpY0ZhaWx9XG4gICAqL1xuICBjb25zdCBmYWlsID0gKF9jb2RlLCBkZXRhaWwsIGxvY2F0aW9uKSA9PiB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGRldGFpbCwgbG9jYXRpb24pXG5cbiAgdmFsaWRhdGVNb2R1bGVUeXBlcyhtb2R1bGUsIGxhbmd1YWdlLCBmYWlsLCBmYWxzZSwgdmlzaWJsZSlcbiAgdmFsaWRhdGVSZXNvdXJjZUxpZmV0aW1lcyhtb2R1bGUsIGluZmVyRXNjYXBpbmdFcnJvckVmZmVjdHMobW9kdWxlLCB2aXNpYmxlLmNhbGxFZmZlY3RzKSwgZmFpbClcbn1cblxuLyoqXG4gKiBDaGVja3MgcGFyc2VyLWF1dGhvcmVkIGJsb2NrIGFuZCBzdGF0ZW1lbnQgbGF5b3V0cyBiZWZvcmUgc2VtYW50aWMgdmFsaWRhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gU2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gU291cmNlIGxhbmd1YWdlLlxuICogQHBhcmFtIHsoZGV0YWlsOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uKSA9PiBuZXZlcn0gZmFpbCAtIFNoYXBlIGZhaWx1cmUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVNb2R1bGVTaGFwZShtb2R1bGUsIGxhbmd1YWdlLCBmYWlsKSB7XG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmNsYXNzZXMgPz8gW10pIHtcbiAgICB2YWxpZGF0ZUJsb2NrU2hhcGUoZGVjbGFyYXRpb24uY29uc3RydWN0b3I/LmJvZHksIFwiY29uc3RydWN0b3IgYm9keVwiLCBmYWlsKVxuICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIGRlY2xhcmF0aW9uLm1ldGhvZHMgPz8gW10pIHZhbGlkYXRlQmxvY2tTaGFwZShtZXRob2QuYm9keSwgXCJtZXRob2QgYm9keVwiLCBmYWlsKVxuICB9XG4gIGZvciAoY29uc3QgZnVuY3Rpb25EZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSB7XG4gICAgaWYgKCF0YXNrMDA1TGFuZ3VhZ2VzLmhhcyhsYW5ndWFnZSkgJiYgZnVuY3Rpb25EZWNsYXJhdGlvbi5wYXJhbWV0ZXJzLmxlbmd0aCAhPSAyKSB7XG4gICAgICBmYWlsKFwiZnVuY3Rpb24gcGFyYW1ldGVyIGNvdW50IG90aGVyIHRoYW4gdHdvXCIsIGZ1bmN0aW9uRGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgfVxuXG4gICAgdmFsaWRhdGVCbG9ja1NoYXBlKGZ1bmN0aW9uRGVjbGFyYXRpb24uYm9keSwgXCJmdW5jdGlvbiBib2R5XCIsIGZhaWwpXG4gIH1cblxuICB2YWxpZGF0ZUJsb2NrU2hhcGUobW9kdWxlLmVudHJ5UG9pbnQuYm9keSwgXCJlbnRyeSBwb2ludFwiLCBmYWlsKVxufVxuXG4vKipcbiAqIENoZWNrcyBvbmUgcmVjdXJzaXZlbHkgbmVzdGVkIHNlbWFudGljIGJsb2NrIHByb2R1Y2VkIGJ5IGEgZnJvbnRlbmQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQmxvY2t9IGJsb2NrIC0gU2VtYW50aWMgYmxvY2suXG4gKiBAcGFyYW0ge3N0cmluZ30gZGV0YWlsIC0gRGlhZ25vc3RpYyBkZXRhaWwuXG4gKiBAcGFyYW0geyhkZXRhaWw6IHN0cmluZywgbG9jYXRpb246IGltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24pID0+IG5ldmVyfSBmYWlsIC0gU2hhcGUgZmFpbHVyZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUJsb2NrU2hhcGUoYmxvY2ssIGRldGFpbCwgZmFpbCkge1xuICBpZiAoIWJsb2NrIHx8IGJsb2NrLmtpbmQgIT0gXCJCbG9ja1wiIHx8ICFBcnJheS5pc0FycmF5KGJsb2NrLnN0YXRlbWVudHMpKSB7XG4gICAgZmFpbChgJHtkZXRhaWx9IHdpdGhvdXQgQmxvY2tgLCBibG9jaz8ubG9jYXRpb24gPz8gLyoqIEB0eXBlIHtuZXZlcn0gKi8gKHVuZGVmaW5lZCkpXG4gIH1cblxuICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBibG9jay5zdGF0ZW1lbnRzKSB7XG4gICAgaWYgKCFbXCJBc3NpZ25tZW50U3RhdGVtZW50XCIsIFwiQnJlYWtTdGF0ZW1lbnRcIiwgXCJDb250aW51ZVN0YXRlbWVudFwiLCBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIiwgXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIsIFwiRm9yRWFjaFN0YXRlbWVudFwiLCBcIklmU3RhdGVtZW50XCIsIFwiTG9jYWxEZWNsYXJhdGlvblwiLCBcIlByaXZhdGVGaWVsZFdyaXRlU3RhdGVtZW50XCIsIFwiUHJpbnRTdGF0ZW1lbnRcIiwgXCJSYWlzZVN0YXRlbWVudFwiLCBcIlJldHVyblN0YXRlbWVudFwiLCBcIlRyeVN0YXRlbWVudFwiLCBcIldoaWxlU3RhdGVtZW50XCJdLmluY2x1ZGVzKHN0YXRlbWVudC5raW5kKSkge1xuICAgICAgZmFpbChgJHtkZXRhaWx9IHN0YXRlbWVudCAke3N0YXRlbWVudC5raW5kfWAsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgdmFsaWRhdGVCbG9ja1NoYXBlKHN0YXRlbWVudC5jb25zZXF1ZW50LCBcImlmIGNvbnNlcXVlbnRcIiwgZmFpbClcbiAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSB2YWxpZGF0ZUJsb2NrU2hhcGUoc3RhdGVtZW50LmFsdGVybmF0ZSwgXCJpZiBhbHRlcm5hdGVcIiwgZmFpbClcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiV2hpbGVTdGF0ZW1lbnRcIikge1xuICAgICAgdmFsaWRhdGVCbG9ja1NoYXBlKHN0YXRlbWVudC5ib2R5LCBcImxvb3AgYm9keVwiLCBmYWlsKVxuICAgIH1cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJUcnlTdGF0ZW1lbnRcIikge1xuICAgICAgdmFsaWRhdGVCbG9ja1NoYXBlKHN0YXRlbWVudC5ib2R5LCBcInRyeSBib2R5XCIsIGZhaWwpXG4gICAgICB2YWxpZGF0ZUJsb2NrU2hhcGUoc3RhdGVtZW50LmNhdGNoQm9keSwgXCJjYXRjaCBib2R5XCIsIGZhaWwpXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIGRlY2xhcmF0aW9ucyBhbmQgZXhwcmVzc2lvbiB0eXBlcyB3aXRoaW4gbGV4aWNhbCBzY29wZXMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBsYW5ndWFnZSAtIFNvdXJjZSBvciBiYWNrZW5kIGxhbmd1YWdlIGlkZW50aXR5LlxuICogQHBhcmFtIHtTZW1hbnRpY0ZhaWx9IGZhaWwgLSBEaWFnbm9zdGljIGNhbGxiYWNrLlxuICogQHBhcmFtIHtib29sZWFufSBub3JtYWxpemVPcGVyYXRpb25zIC0gV2hldGhlciB0byByZXBsYWNlIHRyYW5zaWVudCBmcm9udGVuZCBvcGVyYXRpb24gaW50ZW50LlxuICogQHBhcmFtIHt7Y2xhc3Nlcz86IE1hcDxzdHJpbmcsIGltcG9ydChcIi4vdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbj4sIGZ1bmN0aW9ucz86IE1hcDxzdHJpbmcsIGltcG9ydChcIi4vdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbj4sIHJlY29yZHM/OiBNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uPiwgZXJyb3JzPzogTWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uPiwgY2FsbEVmZmVjdHM/OiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj59fSBbdmlzaWJsZV0gLSBQcm9ncmFtIGltcG9ydHMgdmlzaWJsZSBkdXJpbmcgdmFsaWRhdGlvbi5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZU1vZHVsZVR5cGVzKG1vZHVsZSwgbGFuZ3VhZ2UsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIHZpc2libGUgPSB7fSkge1xuICBjb25zdCBjbGFzc2VzID0gcmVnaXN0ZXJDbGFzc0RlY2xhcmF0aW9ucyhtb2R1bGUuY2xhc3NlcyA/PyBbXSwgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgdmlzaWJsZS5jbGFzc2VzKVxuICBjb25zdCByZWNvcmRzID0gdmFsaWRhdGVSZWNvcmREZWNsYXJhdGlvbnMobW9kdWxlLnJlY29yZHMgPz8gW10sIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIHZpc2libGUucmVjb3JkcywgY2xhc3NlcylcbiAgY29uc3QgZXJyb3JzID0gdmFsaWRhdGVFcnJvckRlY2xhcmF0aW9ucyhtb2R1bGUuZXJyb3JzID8/IFtdLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCB2aXNpYmxlLmVycm9ycylcbiAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb24+fSAqL1xuICBjb25zdCBmdW5jdGlvbnMgPSBuZXcgTWFwKHZpc2libGUuZnVuY3Rpb25zID8/IFtdKVxuICBjb25zdCBkZWNsYXJhdGlvbklkcyA9IG5ldyBTZXQoWy4uLmZ1bmN0aW9ucy52YWx1ZXMoKV0uZmxhdE1hcCgoe2lkfSkgPT4gdHlwZW9mIGlkID09IFwic3RyaW5nXCIgPyBbaWRdIDogW10pKVxuXG4gIGZvciAoY29uc3QgW2luZGV4LCBmdW5jdGlvbkRlY2xhcmF0aW9uXSBvZiBtb2R1bGUuZnVuY3Rpb25zLmVudHJpZXMoKSkge1xuICAgIGlmIChub3JtYWxpemVPcGVyYXRpb25zKSBmdW5jdGlvbkRlY2xhcmF0aW9uLmlkID0gYGZ1bmN0aW9uOiR7aW5kZXh9YFxuICAgIGlmICh0eXBlb2YgZnVuY3Rpb25EZWNsYXJhdGlvbi5pZCAhPSBcInN0cmluZ1wiIHx8ICEvXig/OlthLXpdW2EtejAtOS5fLV0qIyk/ZnVuY3Rpb246WzAtOV0rJC91LnRlc3QoZnVuY3Rpb25EZWNsYXJhdGlvbi5pZCkgfHxcbiAgICAgIGRlY2xhcmF0aW9uSWRzLmhhcyhmdW5jdGlvbkRlY2xhcmF0aW9uLmlkKSkge1xuICAgICAgZmFpbChcIkRVUExJQ0FURV9CSU5ESU5HXCIsIFwiRHVwbGljYXRlIG9yIGludmFsaWQgZnVuY3Rpb24gZGVjbGFyYXRpb24gaWRlbnRpdHkuXCIsIGZ1bmN0aW9uRGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChmdW5jdGlvbnMuaGFzKGZ1bmN0aW9uRGVjbGFyYXRpb24ubmFtZSkpIHtcbiAgICAgIGZhaWwoXCJEVVBMSUNBVEVfQklORElOR1wiLCBgZHVwbGljYXRlIGZ1bmN0aW9uICcke2Z1bmN0aW9uRGVjbGFyYXRpb24ubmFtZX0nLmAsIHJvbGVMb2NhdGlvbihmdW5jdGlvbkRlY2xhcmF0aW9uLCBcIm5hbWVcIikpXG4gICAgfVxuICAgIGRlY2xhcmF0aW9uSWRzLmFkZChmdW5jdGlvbkRlY2xhcmF0aW9uLmlkKVxuICAgIHZhbGlkYXRlVHlwZVBhcmFtZXRlcnMoZnVuY3Rpb25EZWNsYXJhdGlvbiwgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucylcbiAgICBmdW5jdGlvbnMuc2V0KGZ1bmN0aW9uRGVjbGFyYXRpb24ubmFtZSwgZnVuY3Rpb25EZWNsYXJhdGlvbilcbiAgfVxuXG4gIHZhbGlkYXRlRWZmZWN0R3JhcGgobW9kdWxlLCBsYW5ndWFnZSwgZnVuY3Rpb25zLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCBjbGFzc2VzKVxuICBjb25zdCBjYXBhYmlsaXR5UmVzb3VyY2VzID0gKG1vZHVsZS5jYXBhYmlsaXRpZXMgPz8gW10pLmZsYXRNYXAoKHtyZXNvdXJjZXN9KSA9PiByZXNvdXJjZXMpXG4gIGNvbnN0IGNhcGFiaWxpdHlGYWlsdXJlcyA9IChtb2R1bGUuY2FwYWJpbGl0aWVzID8/IFtdKS5mbGF0TWFwKCh7ZmFpbHVyZXN9KSA9PiBmYWlsdXJlcylcblxuICByZXNvdXJjZUlkc0J5UmVjb3JkUmVnaXN0cnkuc2V0KHJlY29yZHMsIG5ldyBTZXQoY2FwYWJpbGl0eVJlc291cmNlcy5tYXAoKHtpZH0pID0+IGlkKSkpXG4gIGNvbnN0IGV4aXN0aW5nRXJyb3JOYW1lcyA9IG5ldyBTZXQoWy4uLmVycm9ycy52YWx1ZXMoKV0ubWFwKCh7bmFtZX0pID0+IG5hbWUpKVxuICBmb3IgKGNvbnN0IGZhaWx1cmUgb2YgY2FwYWJpbGl0eUZhaWx1cmVzKSB7XG4gICAgaWYgKGVycm9ycy5oYXMoZmFpbHVyZS5pZCkgfHwgZXhpc3RpbmdFcnJvck5hbWVzLmhhcyhmYWlsdXJlLm5hbWUpKSB7XG4gICAgICBmYWlsKFwiRFVQTElDQVRFX0VSUk9SXCIsIGBEdXBsaWNhdGUgY2FwYWJpbGl0eSBmYWlsdXJlICcke2ZhaWx1cmUubmFtZX0nLmAsIG1vZHVsZS5sb2NhdGlvbilcbiAgICB9XG4gICAgZXJyb3JzLnNldChmYWlsdXJlLmlkLCAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXJyb3JEZWNsYXJhdGlvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKGZhaWx1cmUpKSlcbiAgICBleGlzdGluZ0Vycm9yTmFtZXMuYWRkKGZhaWx1cmUubmFtZSlcbiAgfVxuXG4gIGNvbnN0IGxvb3BPd25lcnMgPSBwcmVwYXJlTG9vcElkZW50aXRpZXMobW9kdWxlLCBub3JtYWxpemVPcGVyYXRpb25zLCBmYWlsKVxuXG4gIGNvbnN0IHJlc2VydmVkVmFsdWVOYW1lcyA9IG5ldyBTZXQoW1xuICAgIC4uLmZ1bmN0aW9ucy5rZXlzKCksXG4gICAgLi4uWy4uLnJlY29yZHMudmFsdWVzKCldLm1hcCgoZGVjbGFyYXRpb24pID0+IGRlY2xhcmF0aW9uLm5hbWUpLFxuICAgIC4uLlsuLi5jbGFzc2VzLnZhbHVlcygpXS5tYXAoKGRlY2xhcmF0aW9uKSA9PiBkZWNsYXJhdGlvbi5uYW1lKSxcbiAgICAuLi5bLi4uZXJyb3JzLnZhbHVlcygpXS5tYXAoKGRlY2xhcmF0aW9uKSA9PiBkZWNsYXJhdGlvbi5uYW1lKSxcbiAgICAuLi5jYXBhYmlsaXR5UmVzb3VyY2VzLm1hcCgoe25hbWV9KSA9PiBuYW1lKVxuICBdKVxuXG4gIGNvbnN0IG5vbWluYWxOYW1lcyA9IG5ldyBTZXQoKVxuXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgWy4uLm1vZHVsZS5yZWNvcmRzID8/IFtdLCAuLi5tb2R1bGUuY2xhc3NlcyA/PyBbXSwgLi4ubW9kdWxlLmVycm9ycyA/PyBbXV0pIHtcbiAgICBpZiAobm9taW5hbE5hbWVzLmhhcyhkZWNsYXJhdGlvbi5uYW1lKSkge1xuICAgICAgZmFpbChcIkRVUExJQ0FURV9CSU5ESU5HXCIsIGBEdXBsaWNhdGUgbm9taW5hbCBkZWNsYXJhdGlvbiAnJHtkZWNsYXJhdGlvbi5uYW1lfScuYCwgcm9sZUxvY2F0aW9uKGRlY2xhcmF0aW9uLCBcIm5hbWVcIikpXG4gICAgfVxuICAgIG5vbWluYWxOYW1lcy5hZGQoZGVjbGFyYXRpb24ubmFtZSlcbiAgfVxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIFsuLi5jYXBhYmlsaXR5UmVzb3VyY2VzLCAuLi5jYXBhYmlsaXR5RmFpbHVyZXNdKSB7XG4gICAgaWYgKG5vbWluYWxOYW1lcy5oYXMoZGVjbGFyYXRpb24ubmFtZSkpIHtcbiAgICAgIGZhaWwoXCJEVVBMSUNBVEVfQklORElOR1wiLCBgRHVwbGljYXRlIG5vbWluYWwgZGVjbGFyYXRpb24gJyR7ZGVjbGFyYXRpb24ubmFtZX0nLmAsIG1vZHVsZS5sb2NhdGlvbilcbiAgICB9XG4gICAgbm9taW5hbE5hbWVzLmFkZChkZWNsYXJhdGlvbi5uYW1lKVxuICB9XG4gIGNvbnN0IGxvY2FsRnVuY3Rpb25OYW1lcyA9IG5ldyBTZXQobW9kdWxlLmZ1bmN0aW9ucy5tYXAoKHtuYW1lfSkgPT4gbmFtZSkpXG4gIGNvbnN0IGNhbGxFZmZlY3RzID0gaW5mZXJDYWxsRWZmZWN0cyhmdW5jdGlvbnMsIHZpc2libGUuY2FsbEVmZmVjdHMsIGxvY2FsRnVuY3Rpb25OYW1lcylcblxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5jbGFzc2VzID8/IFtdKSB7XG4gICAgdmFsaWRhdGVDbGFzc0RlY2xhcmF0aW9uKGRlY2xhcmF0aW9uLCBmdW5jdGlvbnMsIHJlY29yZHMsIGVycm9ycywgY2FsbEVmZmVjdHMsIHJlc2VydmVkVmFsdWVOYW1lcywgZmFpbCxcbiAgICAgIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIGxvb3BPd25lcnMpXG4gIH1cblxuICBmb3IgKGNvbnN0IGZ1bmN0aW9uRGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykge1xuICAgIHZhbGlkYXRlRnVuY3Rpb24oZnVuY3Rpb25EZWNsYXJhdGlvbiwgZnVuY3Rpb25zLCByZWNvcmRzLCBlcnJvcnMsIGNhbGxFZmZlY3RzLCByZXNlcnZlZFZhbHVlTmFtZXMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIGxvb3BPd25lcnMpXG4gIH1cblxuICBjb25zdCBlbnRyeVNjb3BlID0gY3JlYXRlU2NvcGUodW5kZWZpbmVkLCBtb2R1bGUuZW50cnlQb2ludC5ib2R5LnN0YXRlbWVudHMsIHJlc2VydmVkVmFsdWVOYW1lcylcblxuICB2YWxpZGF0ZUJsb2NrKG1vZHVsZS5lbnRyeVBvaW50LmJvZHksIGVudHJ5U2NvcGUsIHVuZGVmaW5lZCwgZnVuY3Rpb25zLCByZWNvcmRzLCBlcnJvcnMsIGNhbGxFZmZlY3RzLCBmYWlsLFxuICAgIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIHtvd25lcjogbW9kdWxlLmVudHJ5UG9pbnQsIG93bmVyczogbG9vcE93bmVyc30pXG4gIGlmIChub3JtYWxpemVPcGVyYXRpb25zKSB2YWxpZGF0ZUVmZmVjdEdyYXBoKG1vZHVsZSwgbGFuZ3VhZ2UsIGZ1bmN0aW9ucywgZmFpbCwgdHJ1ZSwgY2xhc3Nlcylcbn1cblxuLyoqXG4gKiBBc3NpZ25zIHBhcnNlci1hdXRob3JlZCBsb29wL2NvbnRyb2wgaWRlbnRpdGllcyBhbmQgdmFsaWRhdGVzIGNhbGxlci1vd25lZCBpZGVudGl0aWVzIHdpdGhvdXQgY3Jvc3NpbmcgYSBmdW5jdGlvbiBib3VuZGFyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gU2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtib29sZWFufSBub3JtYWxpemVPcGVyYXRpb25zIC0gV2hldGhlciBwYXJzZXItYXV0aG9yZWQgaWRlbnRpdGllcyBhcmUgYXNzaWduZWQuXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcmV0dXJucyB7TWFwPHN0cmluZywgb2JqZWN0Pn0gTG9vcCBvd25lciBieSBpZGVudGl0eS5cbiAqL1xuZnVuY3Rpb24gcHJlcGFyZUxvb3BJZGVudGl0aWVzKG1vZHVsZSwgbm9ybWFsaXplT3BlcmF0aW9ucywgZmFpbCkge1xuICBjb25zdCBvd25lcnMgPSBuZXcgTWFwKClcbiAgbGV0IG5leHRMb29wID0gMFxuXG4gIGNvbnN0IGNsYXNzT3duZXJzID0gKG1vZHVsZS5jbGFzc2VzID8/IFtdKS5mbGF0TWFwKChkZWNsYXJhdGlvbikgPT4gW2RlY2xhcmF0aW9uLmNvbnN0cnVjdG9yLCAuLi5kZWNsYXJhdGlvbi5tZXRob2RzXSlcblxuICBmb3IgKGNvbnN0IG93bmVyIG9mIFsuLi5jbGFzc093bmVycywgLi4ubW9kdWxlLmZ1bmN0aW9ucywgbW9kdWxlLmVudHJ5UG9pbnRdKSB2aXNpdChvd25lci5ib2R5LCBvd25lciwgW10pXG5cbiAgcmV0dXJuIG93bmVyc1xuXG4gIC8qKlxuICAgKiBWaXNpdHMgb25lIGJsb2NrIGluIGxleGljYWwgc2VtYW50aWMgb3JkZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBDYW5kaWRhdGUgYmxvY2suXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBvd25lciAtIEVuY2xvc2luZyBmdW5jdGlvbiBvciBlbnRyeSBwb2ludC5cbiAgICogQHBhcmFtIHsoaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Gb3JFYWNoU3RhdGVtZW50IHwgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Gb3JFYWNoTWFwU3RhdGVtZW50IHwgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5XaGlsZVN0YXRlbWVudClbXX0gYWN0aXZlIC0gQWN0aXZlIGxvb3BzLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGZ1bmN0aW9uIHZpc2l0KGJsb2NrLCBvd25lciwgYWN0aXZlKSB7XG4gICAgaWYgKCFibG9jayB8fCAhQXJyYXkuaXNBcnJheShibG9jay5zdGF0ZW1lbnRzKSkgcmV0dXJuXG4gICAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgYmxvY2suc3RhdGVtZW50cykge1xuICAgICAgaWYgKCFzdGF0ZW1lbnQgfHwgdHlwZW9mIHN0YXRlbWVudCAhPSBcIm9iamVjdFwiKSBjb250aW51ZVxuICAgICAgaWYgKFtcIkZvckVhY2hTdGF0ZW1lbnRcIiwgXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIsIFwiV2hpbGVTdGF0ZW1lbnRcIl0uaW5jbHVkZXMoc3RhdGVtZW50LmtpbmQpKSB7XG4gICAgICAgIGNvbnN0IGxvb3AgPSAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRm9yRWFjaFN0YXRlbWVudCB8IGltcG9ydChcIi4vdHlwZXMuanNcIikuRm9yRWFjaE1hcFN0YXRlbWVudCB8IGltcG9ydChcIi4vdHlwZXMuanNcIikuV2hpbGVTdGF0ZW1lbnR9ICovIChzdGF0ZW1lbnQpXG5cbiAgICAgICAgaWYgKG5vcm1hbGl6ZU9wZXJhdGlvbnMpIGxvb3AuaWQgPSBgbG9vcDoke25leHRMb29wfWBcbiAgICAgICAgbmV4dExvb3AgKz0gMVxuICAgICAgICBpZiAodHlwZW9mIGxvb3AuaWQgIT0gXCJzdHJpbmdcIiB8fCAhL15sb29wOlswLTldKyQvdS50ZXN0KGxvb3AuaWQpIHx8IG93bmVycy5oYXMobG9vcC5pZCkpIHtcbiAgICAgICAgICBmYWlsKFwiSU5WQUxJRF9MT09QX1RBUkdFVFwiLCBcIkR1cGxpY2F0ZSBvciBpbnZhbGlkIGxvb3AgaWRlbnRpdHkuXCIsIGxvb3AubG9jYXRpb24pXG4gICAgICAgIH1cbiAgICAgICAgb3duZXJzLnNldChsb29wLmlkLCBvd25lcilcbiAgICAgICAgdmlzaXQobG9vcC5ib2R5LCBvd25lciwgWy4uLmFjdGl2ZSwgbG9vcF0pXG4gICAgICB9IGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiQnJlYWtTdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIkNvbnRpbnVlU3RhdGVtZW50XCIpIHtcbiAgICAgICAgaWYgKG5vcm1hbGl6ZU9wZXJhdGlvbnMgJiYgYWN0aXZlLmxlbmd0aCA+IDApIHN0YXRlbWVudC50YXJnZXRMb29wSWQgPSAvKiogQHR5cGUge3N0cmluZ30gKi8gKGFjdGl2ZS5hdCgtMSk/LmlkKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgdmlzaXQoc3RhdGVtZW50LmNvbnNlcXVlbnQsIG93bmVyLCBhY3RpdmUpXG4gICAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSB2aXNpdChzdGF0ZW1lbnQuYWx0ZXJuYXRlLCBvd25lciwgYWN0aXZlKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlRyeVN0YXRlbWVudFwiKSB7XG4gICAgICAgIHZpc2l0KHN0YXRlbWVudC5ib2R5LCBvd25lciwgYWN0aXZlKVxuICAgICAgICB2aXNpdChzdGF0ZW1lbnQuY2F0Y2hCb2R5LCBvd25lciwgYWN0aXZlKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIERlcml2ZXMgdmFsaWRhdG9yLW9ubHkgdW5jaGVja2VkLWVycm9yIGVmZmVjdHMgZm9yIGEgdmFsaWRhdGVkIG1vZHVsZSdzIGxvY2FsIGZ1bmN0aW9ucy5cbiAqIFRoZXNlIGVmZmVjdHMgbmV2ZXIgZW50ZXIgc2VtYW50aWMgZnVuY3Rpb24gZGVjbGFyYXRpb25zIG9yIHB1YmxpYyBzaWduYXR1cmVzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBWYWxpZGF0ZWQgc2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHt7ZnVuY3Rpb25zPzogTWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uPiwgY2FsbEVmZmVjdHM/OiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj59fSBbdmlzaWJsZV0gLSBJbXBvcnRlZCBmdW5jdGlvbnMgYW5kIGFscmVhZHktcmVzb2x2ZWQgZWZmZWN0cyBieSBsb2NhbCBiaW5kaW5nLlxuICogQHJldHVybnMge01hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn0gTG9jYWwgZnVuY3Rpb24gZWZmZWN0cyBieSBzb3VyY2UtdmlzaWJsZSBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbW9kdWxlVW5jaGVja2VkRXJyb3JFZmZlY3RzKG1vZHVsZSwgdmlzaWJsZSA9IHt9KSB7XG4gIGNvbnN0IGZ1bmN0aW9ucyA9IG5ldyBNYXAodmlzaWJsZS5mdW5jdGlvbnMgPz8gW10pXG5cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSBmdW5jdGlvbnMuc2V0KGRlY2xhcmF0aW9uLm5hbWUsIGRlY2xhcmF0aW9uKVxuICBjb25zdCBsb2NhbEZ1bmN0aW9uTmFtZXMgPSBuZXcgU2V0KG1vZHVsZS5mdW5jdGlvbnMubWFwKCh7bmFtZX0pID0+IG5hbWUpKVxuICBjb25zdCBlZmZlY3RzID0gaW5mZXJDYWxsRWZmZWN0cyhmdW5jdGlvbnMsIHZpc2libGUuY2FsbEVmZmVjdHMsIGxvY2FsRnVuY3Rpb25OYW1lcylcblxuICByZXR1cm4gbmV3IE1hcChtb2R1bGUuZnVuY3Rpb25zLm1hcCgoZGVjbGFyYXRpb24pID0+IFtkZWNsYXJhdGlvbi5uYW1lLCBuZXcgU2V0KGVmZmVjdHMuZ2V0KGRlY2xhcmF0aW9uLm5hbWUpID8/IFtdKV0pKVxufVxuXG4vKipcbiAqIEFzc2lnbnMgYW5kIHZhbGlkYXRlcyB0aGUgY2xvc2VkIG5vbWluYWwgaWRlbnRpdGllcyBvd25lZCBieSByZWZlcmVuY2UgY2xhc3Nlcy5cbiAqIEBwYXJhbSB7dW5rbm93bn0gZGVjbGFyYXRpb25zIC0gQ2FuZGlkYXRlIGRlY2xhcmF0aW9ucy5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gbm9ybWFsaXplT3BlcmF0aW9ucyAtIFdoZXRoZXIgcGFyc2VyLWF1dGhvcmVkIGlkZW50aXRpZXMgYXJlIGFzc2lnbmVkLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24+fSBbdmlzaWJsZUNsYXNzZXNdIC0gSW1wb3J0ZWQgY2xhc3NlcyBieSBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHtDbGFzc1JlZ2lzdHJ5fSBDbGFzc2VzIGJ5IHN0YWJsZSBpZGVudGl0eS5cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJDbGFzc0RlY2xhcmF0aW9ucyhkZWNsYXJhdGlvbnMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIHZpc2libGVDbGFzc2VzID0gbmV3IE1hcCgpKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShkZWNsYXJhdGlvbnMpKSB7XG4gICAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiUmVmZXJlbmNlIGNsYXNzIGRlY2xhcmF0aW9ucyBtdXN0IGJlIGFuIG9yZGVyZWQgYXJyYXkuXCIsIC8qKiBAdHlwZSB7bmV2ZXJ9ICovICh1bmRlZmluZWQpKVxuICB9XG4gIC8qKiBAdHlwZSB7Q2xhc3NSZWdpc3RyeX0gKi9cbiAgY29uc3QgY2xhc3NlcyA9IG5ldyBNYXAodmlzaWJsZUNsYXNzZXMpXG4gIGNvbnN0IG5hbWVzID0gbmV3IFNldChbLi4udmlzaWJsZUNsYXNzZXMudmFsdWVzKCldLm1hcCgoe25hbWV9KSA9PiBuYW1lKSlcblxuICBmb3IgKGxldCBjbGFzc0luZGV4ID0gMDsgY2xhc3NJbmRleCA8IGRlY2xhcmF0aW9ucy5sZW5ndGg7IGNsYXNzSW5kZXggKz0gMSkge1xuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb259ICovIChkZWNsYXJhdGlvbnNbY2xhc3NJbmRleF0pXG5cbiAgICBpZiAoIWRlY2xhcmF0aW9uIHx8IGRlY2xhcmF0aW9uLmtpbmQgIT0gXCJDbGFzc0RlY2xhcmF0aW9uXCIgfHwgIUFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb24uZmllbGRzKSB8fFxuICAgICAgIUFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb24ubWV0aG9kcykgfHwgIWRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yIHx8IGRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yLmtpbmQgIT0gXCJDb25zdHJ1Y3RvckRlY2xhcmF0aW9uXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiRFVQTElDQVRFX0NMQVNTXCIsIFwiTWFsZm9ybWVkIG9yIGludmFsaWQgcmVmZXJlbmNlIGNsYXNzIGRlY2xhcmF0aW9uLlwiLCBkZWNsYXJhdGlvbj8ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChkZWNsYXJhdGlvbi5maWVsZHMubGVuZ3RoID09IDApIHtcbiAgICAgIGZhaWwoXCJJTkNPTVBMRVRFX0lOSVRJQUxJWkFUSU9OXCIsIFwiUmVmZXJlbmNlIGNsYXNzZXMgbXVzdCBkZWNsYXJlIHByaXZhdGUgaW5zdGFuY2Ugc3RhdGUuXCIsIGRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAobm9ybWFsaXplT3BlcmF0aW9ucykgZGVjbGFyYXRpb24uaWQgPSBgY2xhc3M6JHtjbGFzc0luZGV4fWBcbiAgICBpZiAodHlwZW9mIGRlY2xhcmF0aW9uLmlkICE9IFwic3RyaW5nXCIgfHwgIS9eKD86W2Etel1bYS16MC05Ll8tXSojKT9jbGFzczpbMC05XSskL3UudGVzdChkZWNsYXJhdGlvbi5pZCkgfHxcbiAgICAgIGNsYXNzZXMuaGFzKGRlY2xhcmF0aW9uLmlkKSB8fCB0eXBlb2YgZGVjbGFyYXRpb24ubmFtZSAhPSBcInN0cmluZ1wiIHx8IGRlY2xhcmF0aW9uLm5hbWUubGVuZ3RoID09IDAgfHwgbmFtZXMuaGFzKGRlY2xhcmF0aW9uLm5hbWUpKSB7XG4gICAgICBmYWlsKFwiRFVQTElDQVRFX0NMQVNTXCIsIGBEdXBsaWNhdGUgb3IgaW52YWxpZCByZWZlcmVuY2UgY2xhc3MgJyR7U3RyaW5nKGRlY2xhcmF0aW9uLm5hbWUpfScuYCwgcm9sZUxvY2F0aW9uKGRlY2xhcmF0aW9uLCBcIm5hbWVcIikpXG4gICAgfVxuICAgIG5hbWVzLmFkZChkZWNsYXJhdGlvbi5uYW1lKVxuICAgIGNsYXNzZXMuc2V0KGRlY2xhcmF0aW9uLmlkLCBkZWNsYXJhdGlvbilcblxuICAgIGNvbnN0IGZpZWxkTmFtZXMgPSBuZXcgU2V0KClcblxuICAgIGZvciAobGV0IGZpZWxkSW5kZXggPSAwOyBmaWVsZEluZGV4IDwgZGVjbGFyYXRpb24uZmllbGRzLmxlbmd0aDsgZmllbGRJbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBmaWVsZCA9IGRlY2xhcmF0aW9uLmZpZWxkc1tmaWVsZEluZGV4XVxuICAgICAgY29uc3QgZXhwZWN0ZWRJZCA9IGAke2RlY2xhcmF0aW9uLmlkfTpmaWVsZDoke2ZpZWxkSW5kZXh9YFxuXG4gICAgICBpZiAoIWZpZWxkIHx8IGZpZWxkLmtpbmQgIT0gXCJQcml2YXRlRmllbGRcIikge1xuICAgICAgICBmYWlsKFwiRFVQTElDQVRFX1BSSVZBVEVfRklFTERcIiwgXCJNYWxmb3JtZWQgb3IgaW52YWxpZCBwcml2YXRlIGZpZWxkLlwiLCBmaWVsZD8ubG9jYXRpb24gPz8gZGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBpZiAobm9ybWFsaXplT3BlcmF0aW9ucykgZmllbGQuaWQgPSBleHBlY3RlZElkXG4gICAgICBpZiAoZmllbGQuaWQgIT0gZXhwZWN0ZWRJZCB8fCB0eXBlb2YgZmllbGQubmFtZSAhPSBcInN0cmluZ1wiIHx8IGZpZWxkLm5hbWUubGVuZ3RoID09IDAgfHwgZmllbGROYW1lcy5oYXMoZmllbGQubmFtZSkpIHtcbiAgICAgICAgZmFpbChcIkRVUExJQ0FURV9QUklWQVRFX0ZJRUxEXCIsIGBEdXBsaWNhdGUgb3IgaW52YWxpZCBwcml2YXRlIGZpZWxkICcke1N0cmluZyhmaWVsZC5uYW1lKX0nLmAsIHJvbGVMb2NhdGlvbihmaWVsZCwgXCJuYW1lXCIpKVxuICAgICAgfVxuICAgICAgZmllbGROYW1lcy5hZGQoZmllbGQubmFtZSlcbiAgICB9XG4gICAgY29uc3QgaW52YWxpZE93bmVkRmllbGQgPSBkZWNsYXJhdGlvbi5maWVsZHMuZmluZCgoe3R5cGV9KSA9PiBjb250YWluc093bmVkVHlwZSh0eXBlKSAmJiB0eXBlLmtpbmQgIT0gXCJPd25lZFJlc291cmNlVHlwZVwiKVxuXG4gICAgaWYgKGludmFsaWRPd25lZEZpZWxkKSB7XG4gICAgICBmYWlsKFwiUkVTT1VSQ0VfQUxJQVNcIiwgYENsYXNzICcke2RlY2xhcmF0aW9uLm5hbWV9JyBtYXkgY29udGFpbiBvd25lcnNoaXAgb25seSBpbiBvbmUgZGlyZWN0IHJlc291cmNlIGZpZWxkLmAsIGludmFsaWRPd25lZEZpZWxkLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBvd25lZEZpZWxkcyA9IGRlY2xhcmF0aW9uLmZpZWxkcy5maWx0ZXIoKHt0eXBlfSkgPT4gdHlwZT8ua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIpXG5cbiAgICBpZiAob3duZWRGaWVsZHMubGVuZ3RoID4gMSkge1xuICAgICAgZmFpbChcIlJFU09VUkNFX0FMSUFTXCIsIGBDbGFzcyAnJHtkZWNsYXJhdGlvbi5uYW1lfScgbWF5IG93biBleGFjdGx5IG9uZSBkaXJlY3QgcmVzb3VyY2UgZmllbGQuYCwgZGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChvd25lZEZpZWxkcy5sZW5ndGggPT0gMSkge1xuICAgICAgY29uc3QgZmllbGQgPSAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuUHJpdmF0ZUZpZWxkICYge3R5cGU6IGltcG9ydChcIi4vdHlwZXMuanNcIikuT3duZWRSZXNvdXJjZVR5cGV9fSAqLyAob3duZWRGaWVsZHNbMF0pXG4gICAgICBjb25zdCBleHBlY3RlZCA9IHtmaWVsZElkOiAvKiogQHR5cGUge3N0cmluZ30gKi8gKGZpZWxkLmlkKSwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwib3duZWRSZXNvdXJjZVwiKSxcbiAgICAgICAgcmVzb3VyY2VJZDogZmllbGQudHlwZS5yZXNvdXJjZUlkfVxuXG4gICAgICBpZiAobm9ybWFsaXplT3BlcmF0aW9ucykgZGVjbGFyYXRpb24ub3duZXJzaGlwID0gZXhwZWN0ZWRcbiAgICAgIGVsc2UgaWYgKEpTT04uc3RyaW5naWZ5KGRlY2xhcmF0aW9uLm93bmVyc2hpcCkgIT0gSlNPTi5zdHJpbmdpZnkoZXhwZWN0ZWQpKSB7XG4gICAgICAgIGZhaWwoXCJSRVNPVVJDRV9UWVBFX01JU01BVENIXCIsIGBDbGFzcyAnJHtkZWNsYXJhdGlvbi5uYW1lfScgaGFzIG1hbGZvcm1lZCByZXNvdXJjZSBvd25lcnNoaXAgbWV0YWRhdGEuYCwgZGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChkZWNsYXJhdGlvbi5vd25lcnNoaXA/LmtpbmQgPT0gXCJvd25lZFJlc291cmNlXCIpIHtcbiAgICAgIGZhaWwoXCJSRVNPVVJDRV9UWVBFX01JU01BVENIXCIsIGBDbGFzcyAnJHtkZWNsYXJhdGlvbi5uYW1lfScgZG9lcyBub3QgY29udGFpbiBpdHMgZGVjbGFyZWQgcmVzb3VyY2UgZmllbGQuYCwgZGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgfVxuXG4gICAgY29uc3QgY29uc3RydWN0b3JJZCA9IGAke2RlY2xhcmF0aW9uLmlkfTpjb25zdHJ1Y3RvcmBcblxuICAgIGlmIChub3JtYWxpemVPcGVyYXRpb25zKSBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5pZCA9IGNvbnN0cnVjdG9ySWRcbiAgICBpZiAoZGVjbGFyYXRpb24uY29uc3RydWN0b3IuaWQgIT0gY29uc3RydWN0b3JJZCB8fCAhQXJyYXkuaXNBcnJheShkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzKSB8fFxuICAgICAgIWRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yLmJvZHkgfHwgZGVjbGFyYXRpb24uY29uc3RydWN0b3IuYm9keS5raW5kICE9IFwiQmxvY2tcIikge1xuICAgICAgZmFpbChcIkRVUExJQ0FURV9DT05TVFJVQ1RPUlwiLCBcIk1hbGZvcm1lZCBvciBpbnZhbGlkIGNvbnN0cnVjdG9yIGRlY2xhcmF0aW9uLlwiLCBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5sb2NhdGlvbilcbiAgICB9XG5cbiAgICBjb25zdCBtZXRob2ROYW1lcyA9IG5ldyBTZXQoKVxuXG4gICAgZm9yIChsZXQgbWV0aG9kSW5kZXggPSAwOyBtZXRob2RJbmRleCA8IGRlY2xhcmF0aW9uLm1ldGhvZHMubGVuZ3RoOyBtZXRob2RJbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBtZXRob2QgPSBkZWNsYXJhdGlvbi5tZXRob2RzW21ldGhvZEluZGV4XVxuICAgICAgY29uc3QgZXhwZWN0ZWRJZCA9IGAke2RlY2xhcmF0aW9uLmlkfTptZXRob2Q6JHttZXRob2RJbmRleH1gXG5cbiAgICAgIGlmICghbWV0aG9kIHx8IG1ldGhvZC5raW5kICE9IFwiTWV0aG9kRGVjbGFyYXRpb25cIikge1xuICAgICAgICBmYWlsKFwiRFVQTElDQVRFX01FVEhPRFwiLCBcIk1hbGZvcm1lZCBvciBpbnZhbGlkIG1ldGhvZCBkZWNsYXJhdGlvbi5cIiwgbWV0aG9kPy5sb2NhdGlvbiA/PyBkZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGlmIChub3JtYWxpemVPcGVyYXRpb25zKSBtZXRob2QuaWQgPSBleHBlY3RlZElkXG4gICAgICBpZiAobWV0aG9kLmlkICE9IGV4cGVjdGVkSWQgfHwgdHlwZW9mIG1ldGhvZC5uYW1lICE9IFwic3RyaW5nXCIgfHwgbWV0aG9kLm5hbWUubGVuZ3RoID09IDAgfHwgbWV0aG9kTmFtZXMuaGFzKG1ldGhvZC5uYW1lKSB8fFxuICAgICAgICAhQXJyYXkuaXNBcnJheShtZXRob2QucGFyYW1ldGVycykgfHwgIW1ldGhvZC5ib2R5IHx8IG1ldGhvZC5ib2R5LmtpbmQgIT0gXCJCbG9ja1wiKSB7XG4gICAgICAgIGZhaWwoXCJEVVBMSUNBVEVfTUVUSE9EXCIsIGBEdXBsaWNhdGUgb3IgaW52YWxpZCBtZXRob2QgJyR7U3RyaW5nKG1ldGhvZC5uYW1lKX0nLmAsIHJvbGVMb2NhdGlvbihtZXRob2QsIFwibmFtZVwiKSlcbiAgICAgIH1cbiAgICAgIG1ldGhvZE5hbWVzLmFkZChtZXRob2QubmFtZSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY2xhc3Nlc1xufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBleGFjdCBjb25zdHJ1Y3Rpb24sIHByaXZhdGUgc3RhdGUsIGFuZCBtZXRob2QgYm9kaWVzIGZvciBvbmUgY2xhc3MuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbn0gZGVjbGFyYXRpb24gLSBDbGFzcyBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uPn0gZnVuY3Rpb25zIC0gRnVuY3Rpb24gc2lnbmF0dXJlcy5cbiAqIEBwYXJhbSB7UmVjb3JkUmVnaXN0cnl9IHJlY29yZHMgLSBSZWNvcmQgYW5kIHJlZmVyZW5jZS1jbGFzcyByZWdpc3RyaWVzLlxuICogQHBhcmFtIHtFcnJvclJlZ2lzdHJ5fSBlcnJvcnMgLSBFcnJvciBkZWNsYXJhdGlvbnMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn0gY2FsbEVmZmVjdHMgLSBGdW5jdGlvbiBjYWxsIGVmZmVjdHMuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSByZXNlcnZlZFZhbHVlTmFtZXMgLSBNb2R1bGUtcmVzZXJ2ZWQgbmFtZXMuXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5vcm1hbGl6ZU9wZXJhdGlvbnMgLSBXaGV0aGVyIHBhcnNlci1hdXRob3JlZCByZXNvbHV0aW9ucyBhcmUgYXNzaWduZWQuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIG9iamVjdD59IGxvb3BPd25lcnMgLSBMb29wIG93bmVyc2hpcCByZWdpc3RyeS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUNsYXNzRGVjbGFyYXRpb24oZGVjbGFyYXRpb24sIGZ1bmN0aW9ucywgcmVjb3JkcywgZXJyb3JzLCBjYWxsRWZmZWN0cywgcmVzZXJ2ZWRWYWx1ZU5hbWVzLCBmYWlsLFxuICBub3JtYWxpemVPcGVyYXRpb25zLCBsb29wT3duZXJzKSB7XG4gIGZvciAoY29uc3QgZmllbGQgb2YgZGVjbGFyYXRpb24uZmllbGRzKSB7XG4gICAgdmFsaWRhdGVWYWx1ZVR5cGVSZWZlcmVuY2UoZmllbGQudHlwZSwgZmllbGQubG9jYXRpb24sIGZhaWwsIHVuZGVmaW5lZCwgcmVjb3JkcylcbiAgfVxuXG4gIGNvbnN0IGNvbnN0cnVjdG9yID0gZGVjbGFyYXRpb24uY29uc3RydWN0b3JcbiAgY29uc3QgYWNxdWlzaXRpb25TdGF0ZW1lbnQgPSBjb25zdHJ1Y3Rvci5ib2R5LnN0YXRlbWVudHNbMF1cbiAgY29uc3QgYWNxdWlzaXRpb25FeHByZXNzaW9uID0gYWNxdWlzaXRpb25TdGF0ZW1lbnQ/LmtpbmQgPT0gXCJQcml2YXRlRmllbGRXcml0ZVN0YXRlbWVudFwiXG4gICAgPyBhY3F1aXNpdGlvblN0YXRlbWVudC5leHByZXNzaW9uIDogdW5kZWZpbmVkXG4gIGNvbnN0IG93bmVkQWNxdWlzaXRpb24gPSBkZWNsYXJhdGlvbi5vd25lcnNoaXA/LmtpbmQgPT0gXCJvd25lZFJlc291cmNlXCIgJiYgZGVjbGFyYXRpb24uZmllbGRzLmxlbmd0aCA9PSAxICYmXG4gICAgY29uc3RydWN0b3IuYm9keS5zdGF0ZW1lbnRzLmxlbmd0aCA9PSAxICYmIGFjcXVpc2l0aW9uU3RhdGVtZW50Py5raW5kID09IFwiUHJpdmF0ZUZpZWxkV3JpdGVTdGF0ZW1lbnRcIiAmJlxuICAgIGFjcXVpc2l0aW9uU3RhdGVtZW50LmZpZWxkID09IGRlY2xhcmF0aW9uLm93bmVyc2hpcC5maWVsZElkICYmIGFjcXVpc2l0aW9uU3RhdGVtZW50LnJlY2VpdmVyLmtpbmQgPT0gXCJSZWNlaXZlckV4cHJlc3Npb25cIiAmJlxuICAgIGFjcXVpc2l0aW9uU3RhdGVtZW50LnJlY2VpdmVyLmNsYXNzSWQgPT0gZGVjbGFyYXRpb24uaWQgJiYgYWNxdWlzaXRpb25FeHByZXNzaW9uPy5raW5kID09IFwiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIiAmJlxuICAgIGFjcXVpc2l0aW9uRXhwcmVzc2lvbi5yZXNvbHV0aW9uLnJlc291cmNlRmxvdy5raW5kID09IFwiYWNxdWlyZVwiICYmXG4gICAgYWNxdWlzaXRpb25FeHByZXNzaW9uLnJlc29sdXRpb24ucmVzb3VyY2VGbG93LnJlc291cmNlSWQgPT0gZGVjbGFyYXRpb24ub3duZXJzaGlwLnJlc291cmNlSWRcblxuICBpZiAoc3ludGFjdGljQmxvY2tFZmZlY3RzKGNvbnN0cnVjdG9yLmJvZHksIGNhbGxFZmZlY3RzKS5zaXplID4gMCAmJiAhb3duZWRBY3F1aXNpdGlvbikge1xuICAgIGZhaWwoXCJVTlNVUFBPUlRFRF9TVEFURU1FTlRcIiwgXCJSZWZlcmVuY2UgY29uc3RydWN0b3JzIGNhbm5vdCBleHBvc2UgdW5jaGVja2VkLWVycm9yIGVmZmVjdHMgaW4gVGFzayAwMzMuXCIsIGNvbnN0cnVjdG9yLmxvY2F0aW9uKVxuICB9XG5cbiAgaWYgKCFvd25lZEFjcXVpc2l0aW9uICYmXG4gICAgKGNvbnN0cnVjdG9yLnBhcmFtZXRlcnMubGVuZ3RoICE9IGRlY2xhcmF0aW9uLmZpZWxkcy5sZW5ndGggfHwgY29uc3RydWN0b3IuYm9keS5zdGF0ZW1lbnRzLmxlbmd0aCAhPSBkZWNsYXJhdGlvbi5maWVsZHMubGVuZ3RoKSkge1xuICAgIGZhaWwoXCJJTkNPTVBMRVRFX0lOSVRJQUxJWkFUSU9OXCIsIGBDb25zdHJ1Y3RvciBmb3IgJyR7ZGVjbGFyYXRpb24ubmFtZX0nIG11c3QgaW5pdGlhbGl6ZSBldmVyeSBwcml2YXRlIGZpZWxkIGV4YWN0bHkgb25jZSBpbiBkZWNsYXJhdGlvbiBvcmRlci5gLFxuICAgICAgY29uc3RydWN0b3IubG9jYXRpb24pXG4gIH1cbiAgY29uc3QgY29uc3RydWN0b3JTY29wZSA9IGNyZWF0ZVNjb3BlKHVuZGVmaW5lZCwgY29uc3RydWN0b3IuYm9keS5zdGF0ZW1lbnRzLCByZXNlcnZlZFZhbHVlTmFtZXMsIG5ldyBTZXQoKSwgZGVjbGFyYXRpb24pXG5cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGNvbnN0cnVjdG9yLnBhcmFtZXRlcnMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgcGFyYW1ldGVyID0gY29uc3RydWN0b3IucGFyYW1ldGVyc1tpbmRleF1cbiAgICBjb25zdCBmaWVsZCA9IGRlY2xhcmF0aW9uLmZpZWxkc1tpbmRleF1cbiAgICBjb25zdCB0eXBlID0gdmFsaWRhdGVWYWx1ZVR5cGVSZWZlcmVuY2UocGFyYW1ldGVyLnR5cGUsIHBhcmFtZXRlci5sb2NhdGlvbiwgZmFpbCwgdW5kZWZpbmVkLCByZWNvcmRzKVxuXG4gICAgaWYgKCFvd25lZEFjcXVpc2l0aW9uICYmICFzYW1lVHlwZSh0eXBlLCBmaWVsZC50eXBlKSkge1xuICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYENvbnN0cnVjdG9yIHBhcmFtZXRlciAnJHtwYXJhbWV0ZXIubmFtZX0nIG11c3QgZXhhY3RseSBtYXRjaCBwcml2YXRlIGZpZWxkICcke2ZpZWxkLm5hbWV9Jy5gLCBwYXJhbWV0ZXIubG9jYXRpb24pXG4gICAgfVxuICAgIGRlY2xhcmVCaW5kaW5nKHBhcmFtZXRlci5uYW1lLCB7a25vd25WYWx1ZTogdW5kZWZpbmVkLCBtdXRhYmxlOiBmYWxzZSwgdHlwZX0sIHJvbGVMb2NhdGlvbihwYXJhbWV0ZXIsIFwibmFtZVwiKSwgY29uc3RydWN0b3JTY29wZSwgZmFpbClcbiAgICBpZiAob3duZWRBY3F1aXNpdGlvbikgY29udGludWVcbiAgICBjb25zdCBzdGF0ZW1lbnQgPSBjb25zdHJ1Y3Rvci5ib2R5LnN0YXRlbWVudHNbaW5kZXhdXG4gICAgY29uc3QgaW5pdGlhbGl6ZXIgPSBzdGF0ZW1lbnQ/LmtpbmQgPT0gXCJQcml2YXRlRmllbGRXcml0ZVN0YXRlbWVudFwiXG4gICAgICA/IHN0YXRlbWVudC5leHByZXNzaW9uLmtpbmQgPT0gXCJPd25lZE1vdmVFeHByZXNzaW9uXCIgPyBzdGF0ZW1lbnQuZXhwcmVzc2lvbi5leHByZXNzaW9uIDogc3RhdGVtZW50LmV4cHJlc3Npb25cbiAgICAgIDogdW5kZWZpbmVkXG5cbiAgICBpZiAoIXN0YXRlbWVudCB8fCBzdGF0ZW1lbnQua2luZCAhPSBcIlByaXZhdGVGaWVsZFdyaXRlU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmZpZWxkICE9IGZpZWxkLmlkIHx8XG4gICAgICBzdGF0ZW1lbnQucmVjZWl2ZXI/LmtpbmQgIT0gXCJSZWNlaXZlckV4cHJlc3Npb25cIiB8fCBzdGF0ZW1lbnQucmVjZWl2ZXIuY2xhc3NJZCAhPSBkZWNsYXJhdGlvbi5pZCB8fFxuICAgICAgaW5pdGlhbGl6ZXI/LmtpbmQgIT0gXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiIHx8IGluaXRpYWxpemVyLm5hbWUgIT0gcGFyYW1ldGVyLm5hbWUpIHtcbiAgICAgIGZhaWwoXCJJTkNPTVBMRVRFX0lOSVRJQUxJWkFUSU9OXCIsIGBDb25zdHJ1Y3RvciBmb3IgJyR7ZGVjbGFyYXRpb24ubmFtZX0nIG11c3QgaW5pdGlhbGl6ZSAnJHtmaWVsZC5uYW1lfScgZnJvbSBpdHMgY29ycmVzcG9uZGluZyBwYXJhbWV0ZXIuYCxcbiAgICAgICAgc3RhdGVtZW50Py5sb2NhdGlvbiA/PyBjb25zdHJ1Y3Rvci5sb2NhdGlvbilcbiAgICB9XG4gIH1cbiAgdmFsaWRhdGVCbG9jayhjb25zdHJ1Y3Rvci5ib2R5LCBjb25zdHJ1Y3RvclNjb3BlLCB7a2luZDogXCJUeXBlUmVmZXJlbmNlXCIsIG5hbWU6IFwidm9pZFwifSwgZnVuY3Rpb25zLCByZWNvcmRzLFxuICAgIGVycm9ycywgY2FsbEVmZmVjdHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIHtvd25lcjogY29uc3RydWN0b3IsIG93bmVyczogbG9vcE93bmVyc30pXG5cbiAgZm9yIChjb25zdCBtZXRob2Qgb2YgZGVjbGFyYXRpb24ubWV0aG9kcykge1xuICAgIGNvbnN0IHVuc3VwcG9ydGVkTWV0aG9kRWZmZWN0cyA9IFsuLi5zeW50YWN0aWNCbG9ja0VmZmVjdHMobWV0aG9kLmJvZHksIGNhbGxFZmZlY3RzKV1cbiAgICAgIC5maWx0ZXIoKGlkKSA9PiAhL14oPzptb2R1bGU6WzAtOV0rXFwvKT9jYXBhYmlsaXR5OlswLTldK1xcL2ZhaWx1cmU6WzAtOV0rJC91LnRlc3QoaWQpKVxuXG4gICAgaWYgKGRlY2xhcmF0aW9uLm93bmVyc2hpcD8ua2luZCAhPSBcIm93bmVkUmVzb3VyY2VcIiAmJiB1bnN1cHBvcnRlZE1ldGhvZEVmZmVjdHMubGVuZ3RoID4gMCkge1xuICAgICAgZmFpbChcIlVOU1VQUE9SVEVEX1NUQVRFTUVOVFwiLCBgUmVmZXJlbmNlIG1ldGhvZCAnJHttZXRob2QubmFtZX0nIGNhbm5vdCBleHBvc2UgdW5jaGVja2VkLWVycm9yIGVmZmVjdHMgaW4gVGFzayAwMzMuYCwgbWV0aG9kLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBzY29wZSA9IGNyZWF0ZVNjb3BlKHVuZGVmaW5lZCwgbWV0aG9kLmJvZHkuc3RhdGVtZW50cywgcmVzZXJ2ZWRWYWx1ZU5hbWVzLCBuZXcgU2V0KCksIGRlY2xhcmF0aW9uKVxuXG4gICAgZm9yIChjb25zdCBwYXJhbWV0ZXIgb2YgbWV0aG9kLnBhcmFtZXRlcnMpIHtcbiAgICAgIGNvbnN0IHR5cGUgPSB2YWxpZGF0ZVZhbHVlVHlwZVJlZmVyZW5jZShwYXJhbWV0ZXIudHlwZSwgcGFyYW1ldGVyLmxvY2F0aW9uLCBmYWlsLCB1bmRlZmluZWQsIHJlY29yZHMpXG5cbiAgICAgIGRlY2xhcmVCaW5kaW5nKHBhcmFtZXRlci5uYW1lLCB7a25vd25WYWx1ZTogdW5kZWZpbmVkLCBtdXRhYmxlOiBmYWxzZSwgdHlwZX0sIHJvbGVMb2NhdGlvbihwYXJhbWV0ZXIsIFwibmFtZVwiKSwgc2NvcGUsIGZhaWwpXG4gICAgfVxuICAgIGNvbnN0IHJldHVyblR5cGUgPSB2YWxpZGF0ZVJldHVyblR5cGVSZWZlcmVuY2UobWV0aG9kLnJldHVyblR5cGUsIG1ldGhvZC5sb2NhdGlvbiwgZmFpbCwgcmVjb3JkcylcbiAgICBjb25zdCBmbG93ID0gdmFsaWRhdGVCbG9jayhtZXRob2QuYm9keSwgc2NvcGUsIHJldHVyblR5cGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZXJyb3JzLCBjYWxsRWZmZWN0cywgZmFpbCxcbiAgICAgIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIHtvd25lcjogbWV0aG9kLCBvd25lcnM6IGxvb3BPd25lcnN9KVxuXG4gICAgaWYgKGRlY2xhcmF0aW9uLm93bmVyc2hpcD8ua2luZCA9PSBcIm93bmVkUmVzb3VyY2VcIikgb3duZWRNZXRob2RSZXNvdXJjZUZsb3coZGVjbGFyYXRpb24sIG1ldGhvZCwgZmFpbClcblxuICAgIGlmICghaXNWb2lkVHlwZShyZXR1cm5UeXBlKSAmJiBmbG93Lm5vcm1hbCkge1xuICAgICAgZmFpbChcIk1JU1NJTkdfUkVUVVJOXCIsIGBNZXRob2QgJyR7bWV0aG9kLm5hbWV9JyBkb2VzIG5vdCByZXR1cm4gb24gZXZlcnkgcmVhY2hhYmxlIHBhdGguYCwgbWV0aG9kLmxvY2F0aW9uKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBub21pbmFsIHVuY2hlY2tlZC1lcnJvciBkZWNsYXJhdGlvbnMuXG4gKiBAcGFyYW0ge3Vua25vd259IGRlY2xhcmF0aW9ucyAtIENhbmRpZGF0ZSBkZWNsYXJhdGlvbnMuXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5vcm1hbGl6ZU9wZXJhdGlvbnMgLSBXaGV0aGVyIHBhcnNlci1hdXRob3JlZCBpZGVudGl0aWVzIGFyZSBhc3NpZ25lZC5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uPn0gW3Zpc2libGVFcnJvcnNdIC0gSW1wb3J0ZWQgZXJyb3IgZGVjbGFyYXRpb25zIGJ5IGlkZW50aXR5LlxuICogQHJldHVybnMge0Vycm9yUmVnaXN0cnl9IFZhbGlkYXRlZCBkZWNsYXJhdGlvbnMgYnkgaWRlbnRpdHkuXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlRXJyb3JEZWNsYXJhdGlvbnMoZGVjbGFyYXRpb25zLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCB2aXNpYmxlRXJyb3JzID0gbmV3IE1hcCgpKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShkZWNsYXJhdGlvbnMpKSByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJFcnJvciBkZWNsYXJhdGlvbnMgbXVzdCBiZSBhbiBvcmRlcmVkIGFycmF5LlwiLCAvKiogQHR5cGUge25ldmVyfSAqLyAodW5kZWZpbmVkKSlcbiAgLyoqIEB0eXBlIHtFcnJvclJlZ2lzdHJ5fSAqL1xuICBjb25zdCBlcnJvcnMgPSBuZXcgTWFwKHZpc2libGVFcnJvcnMpXG4gIGNvbnN0IG5hbWVzID0gbmV3IFNldCgpXG5cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGRlY2xhcmF0aW9ucy5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGRlY2xhcmF0aW9uc1tpbmRleF1cblxuICAgIGlmICghZGVjbGFyYXRpb24gfHwgZGVjbGFyYXRpb24ua2luZCAhPSBcIkVycm9yRGVjbGFyYXRpb25cIikge1xuICAgICAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiTWFsZm9ybWVkIGVycm9yIGRlY2xhcmF0aW9uLlwiLCBkZWNsYXJhdGlvbj8ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChub3JtYWxpemVPcGVyYXRpb25zKSBkZWNsYXJhdGlvbi5pZCA9IGBlcnJvcjoke2luZGV4fWBcbiAgICBpZiAodHlwZW9mIGRlY2xhcmF0aW9uLmlkICE9IFwic3RyaW5nXCIgfHwgIS9eKD86W2Etel1bYS16MC05Ll8tXSojKT9lcnJvcjpbMC05XSskL3UudGVzdChkZWNsYXJhdGlvbi5pZCkgfHwgZXJyb3JzLmhhcyhkZWNsYXJhdGlvbi5pZCkpIHtcbiAgICAgIGZhaWwoXCJEVVBMSUNBVEVfRVJST1JcIiwgXCJEdXBsaWNhdGUgb3IgaW52YWxpZCBlcnJvciBkZWNsYXJhdGlvbiBpZGVudGl0eS5cIiwgZGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZGVjbGFyYXRpb24ubmFtZSAhPSBcInN0cmluZ1wiIHx8IG5hbWVzLmhhcyhkZWNsYXJhdGlvbi5uYW1lKSkge1xuICAgICAgZmFpbChcIkRVUExJQ0FURV9FUlJPUlwiLCBgRHVwbGljYXRlIG9yIGludmFsaWQgZXJyb3IgJyR7U3RyaW5nKGRlY2xhcmF0aW9uLm5hbWUpfScuYCwgcm9sZUxvY2F0aW9uKGRlY2xhcmF0aW9uLCBcIm5hbWVcIikpXG4gICAgfVxuICAgIG5hbWVzLmFkZChkZWNsYXJhdGlvbi5uYW1lKVxuICAgIGVycm9ycy5zZXQoZGVjbGFyYXRpb24uaWQsIGRlY2xhcmF0aW9uKVxuICB9XG5cbiAgcmV0dXJuIGVycm9yc1xufVxuXG4vKipcbiAqIEFzc2lnbnMgYW5kIHZhbGlkYXRlcyBvbmUgZGVjbGFyYXRpb24ncyBpbnZhcmlhbnQgdW5ib3VuZGVkIHR5cGUgcGFyYW1ldGVycy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbn0gZGVjbGFyYXRpb24gLSBPd25pbmcgZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5vcm1hbGl6ZU9wZXJhdGlvbnMgLSBXaGV0aGVyIHBhcnNlci1hdXRob3JlZCBpZGVudGl0aWVzIGFyZSBhc3NpZ25lZC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVR5cGVQYXJhbWV0ZXJzKGRlY2xhcmF0aW9uLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zKSB7XG4gIGlmIChkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycyA9PT0gdW5kZWZpbmVkKSByZXR1cm5cbiAgaWYgKCFBcnJheS5pc0FycmF5KGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzKSkge1xuICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiVHlwZSBwYXJhbWV0ZXJzIG11c3QgYmUgYSBkZW5zZSBvcmRlcmVkIGFycmF5LlwiLCBkZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgfVxuICBjb25zdCBuYW1lcyA9IG5ldyBTZXQoKVxuXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycy5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBjb25zdCBwYXJhbWV0ZXIgPSBkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVyc1tpbmRleF1cbiAgICBjb25zdCBrZXlzID0gcGFyYW1ldGVyICYmIHR5cGVvZiBwYXJhbWV0ZXIgPT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheShwYXJhbWV0ZXIpXG4gICAgICA/IE9iamVjdC5rZXlzKHBhcmFtZXRlcikuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpIDogXCJcIlxuXG4gICAgaWYgKCFPYmplY3QuaGFzT3duKGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzLCBpbmRleCkgfHwgIXBhcmFtZXRlciB8fCBwYXJhbWV0ZXIua2luZCAhPSBcIlR5cGVQYXJhbWV0ZXJcIiB8fFxuICAgICAga2V5cyAhPSBcImlkLGtpbmQsbG9jYXRpb24sbmFtZVwiIHx8IHR5cGVvZiBwYXJhbWV0ZXIubmFtZSAhPSBcInN0cmluZ1wiIHx8IHBhcmFtZXRlci5uYW1lLmxlbmd0aCA9PSAwKSB7XG4gICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIk1hbGZvcm1lZCB0eXBlIHBhcmFtZXRlciBkZWNsYXJhdGlvbi5cIiwgcGFyYW1ldGVyPy5sb2NhdGlvbiA/PyBkZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKG5hbWVzLmhhcyhwYXJhbWV0ZXIubmFtZSkpIHtcbiAgICAgIGZhaWwoXCJEVVBMSUNBVEVfVFlQRV9QQVJBTUVURVJcIiwgYER1cGxpY2F0ZSB0eXBlIHBhcmFtZXRlciAnJHtwYXJhbWV0ZXIubmFtZX0nLmAsIHJvbGVMb2NhdGlvbihwYXJhbWV0ZXIsIFwibmFtZVwiKSlcbiAgICB9XG4gICAgbmFtZXMuYWRkKHBhcmFtZXRlci5uYW1lKVxuICAgIGNvbnN0IGV4cGVjdGVkSWQgPSBgJHtkZWNsYXJhdGlvbi5pZH06dHlwZToke2luZGV4fWBcblxuICAgIGlmIChub3JtYWxpemVPcGVyYXRpb25zKSBwYXJhbWV0ZXIuaWQgPSBleHBlY3RlZElkXG4gICAgaWYgKHBhcmFtZXRlci5pZCAhPSBleHBlY3RlZElkKSB7XG4gICAgICBmYWlsKFwiRFVQTElDQVRFX1RZUEVfUEFSQU1FVEVSXCIsIFwiRHVwbGljYXRlIG9yIGludmFsaWQgdHlwZSBwYXJhbWV0ZXIgaWRlbnRpdHkuXCIsIHBhcmFtZXRlci5sb2NhdGlvbilcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBjbG9zZWQgaWRlbnRpdHkgc2NvcGUgb3duZWQgYnkgb25lIHZhbGlkYXRlZCBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbn0gZGVjbGFyYXRpb24gLSBEZWNsYXJhdGlvbi5cbiAqIEByZXR1cm5zIHtTZXQ8c3RyaW5nPn0gVHlwZS1wYXJhbWV0ZXIgaWRlbnRpdGllcy5cbiAqL1xuZnVuY3Rpb24gZGVjbGFyYXRpb25UeXBlUGFyYW1ldGVySWRzKGRlY2xhcmF0aW9uKSB7XG4gIHJldHVybiBuZXcgU2V0KChkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycyA/PyBbXSkubWFwKCh7aWR9KSA9PiAvKiogQHR5cGUge3N0cmluZ30gKi8gKGlkKSkpXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIG5vbWluYWwgZGVjbGFyYXRpb25zIGFuZCByZXR1cm5zIHRoZWlyIHN0YWJsZSBpZGVudGl0eSByZWdpc3RyeS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gZGVjbGFyYXRpb25zIC0gQ2FuZGlkYXRlIG9yZGVyZWQgZGVjbGFyYXRpb25zLlxuICogQHBhcmFtIHtTZW1hbnRpY0ZhaWx9IGZhaWwgLSBEaWFnbm9zdGljIGNhbGxiYWNrLlxuICogQHBhcmFtIHtib29sZWFufSBub3JtYWxpemVPcGVyYXRpb25zIC0gV2hldGhlciBwYXJzZXItYXV0aG9yZWQgaWRlbnRpdGllcyBhcmUgYXNzaWduZWQuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4vdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24+fSBbdmlzaWJsZVJlY29yZHNdIC0gSW1wb3J0ZWQgcmVjb3JkIGRlY2xhcmF0aW9ucyBieSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7Q2xhc3NSZWdpc3RyeX0gW2NsYXNzZXNdIC0gTW9kdWxlIHJlZmVyZW5jZSBjbGFzc2VzIGJ5IGlkZW50aXR5LlxuICogQHJldHVybnMge1JlY29yZFJlZ2lzdHJ5fSBWYWxpZGF0ZWQgZGVjbGFyYXRpb25zIGJ5IGlkZW50aXR5LlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVJlY29yZERlY2xhcmF0aW9ucyhkZWNsYXJhdGlvbnMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIHZpc2libGVSZWNvcmRzID0gbmV3IE1hcCgpLCBjbGFzc2VzID0gbmV3IE1hcCgpKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShkZWNsYXJhdGlvbnMpKSByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJSZWNvcmQgZGVjbGFyYXRpb25zIG11c3QgYmUgYW4gb3JkZXJlZCBhcnJheS5cIiwgLyoqIEB0eXBlIHtuZXZlcn0gKi8gKHVuZGVmaW5lZCkpXG4gIC8qKiBAdHlwZSB7UmVjb3JkUmVnaXN0cnl9ICovXG4gIGNvbnN0IHJlY29yZHMgPSBuZXcgTWFwKHZpc2libGVSZWNvcmRzKVxuXG4gIHJlZmVyZW5jZUNsYXNzZXNCeVJlY29yZFJlZ2lzdHJ5LnNldChyZWNvcmRzLCBjbGFzc2VzKVxuICBjb25zdCBuYW1lcyA9IG5ldyBTZXQoKVxuXG4gIGZvciAobGV0IHJlY29yZEluZGV4ID0gMDsgcmVjb3JkSW5kZXggPCBkZWNsYXJhdGlvbnMubGVuZ3RoOyByZWNvcmRJbmRleCArPSAxKSB7XG4gICAgY29uc3QgZGVjbGFyYXRpb24gPSBkZWNsYXJhdGlvbnNbcmVjb3JkSW5kZXhdXG5cbiAgICBpZiAoIWRlY2xhcmF0aW9uIHx8IGRlY2xhcmF0aW9uLmtpbmQgIT0gXCJSZWNvcmREZWNsYXJhdGlvblwiIHx8ICFBcnJheS5pc0FycmF5KGRlY2xhcmF0aW9uLmZpZWxkcykpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIk1hbGZvcm1lZCByZWNvcmQgZGVjbGFyYXRpb24uXCIsIGRlY2xhcmF0aW9uPy5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKG5vcm1hbGl6ZU9wZXJhdGlvbnMpIGRlY2xhcmF0aW9uLmlkID0gYHJlY29yZDoke3JlY29yZEluZGV4fWBcbiAgICBpZiAodHlwZW9mIGRlY2xhcmF0aW9uLmlkICE9IFwic3RyaW5nXCIgfHwgIS9eKD86W2Etel1bYS16MC05Ll8tXSojKT9yZWNvcmQ6WzAtOV0rJC91LnRlc3QoZGVjbGFyYXRpb24uaWQpIHx8IHJlY29yZHMuaGFzKGRlY2xhcmF0aW9uLmlkKSkge1xuICAgICAgZmFpbChcIkRVUExJQ0FURV9SRUNPUkRcIiwgXCJEdXBsaWNhdGUgb3IgaW52YWxpZCByZWNvcmQgZGVjbGFyYXRpb24gaWRlbnRpdHkuXCIsIGRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAobmFtZXMuaGFzKGRlY2xhcmF0aW9uLm5hbWUpKSB7XG4gICAgICBmYWlsKFwiRFVQTElDQVRFX1JFQ09SRFwiLCBgRHVwbGljYXRlIHJlY29yZCAnJHtkZWNsYXJhdGlvbi5uYW1lfScuYCwgcm9sZUxvY2F0aW9uKGRlY2xhcmF0aW9uLCBcIm5hbWVcIikpXG4gICAgfVxuICAgIG5hbWVzLmFkZChkZWNsYXJhdGlvbi5uYW1lKVxuICAgIHZhbGlkYXRlVHlwZVBhcmFtZXRlcnMoZGVjbGFyYXRpb24sIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMpXG4gICAgcmVjb3Jkcy5zZXQoZGVjbGFyYXRpb24uaWQsIGRlY2xhcmF0aW9uKVxuICB9XG5cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBkZWNsYXJhdGlvbnMpIHtcbiAgICBjb25zdCBmaWVsZE5hbWVzID0gbmV3IFNldCgpXG4gICAgY29uc3QgdHlwZVBhcmFtZXRlcnMgPSBkZWNsYXJhdGlvblR5cGVQYXJhbWV0ZXJJZHMoZGVjbGFyYXRpb24pXG5cbiAgICBmb3IgKGxldCBmaWVsZEluZGV4ID0gMDsgZmllbGRJbmRleCA8IGRlY2xhcmF0aW9uLmZpZWxkcy5sZW5ndGg7IGZpZWxkSW5kZXggKz0gMSkge1xuICAgICAgY29uc3QgZmllbGQgPSBkZWNsYXJhdGlvbi5maWVsZHNbZmllbGRJbmRleF1cblxuICAgICAgaWYgKCFmaWVsZCB8fCBmaWVsZC5raW5kICE9IFwiUmVjb3JkRmllbGRcIikgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJNYWxmb3JtZWQgcmVjb3JkIGZpZWxkLlwiLCBmaWVsZD8ubG9jYXRpb24gPz8gZGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgICBpZiAobm9ybWFsaXplT3BlcmF0aW9ucykgZmllbGQuaWQgPSBgJHtkZWNsYXJhdGlvbi5pZH06ZmllbGQ6JHtmaWVsZEluZGV4fWBcbiAgICAgIGlmICh0eXBlb2YgZmllbGQuaWQgIT0gXCJzdHJpbmdcIiB8fCBmaWVsZC5pZCAhPSBgJHtkZWNsYXJhdGlvbi5pZH06ZmllbGQ6JHtmaWVsZEluZGV4fWApIHtcbiAgICAgICAgZmFpbChcIkRVUExJQ0FURV9GSUVMRFwiLCBcIkR1cGxpY2F0ZSBvciBpbnZhbGlkIHJlY29yZCBmaWVsZCBpZGVudGl0eS5cIiwgZmllbGQubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBpZiAoZmllbGROYW1lcy5oYXMoZmllbGQubmFtZSkpIGZhaWwoXCJEVVBMSUNBVEVfRklFTERcIiwgYER1cGxpY2F0ZSBmaWVsZCAnJHtmaWVsZC5uYW1lfScuYCwgcm9sZUxvY2F0aW9uKGZpZWxkLCBcIm5hbWVcIikpXG4gICAgICBmaWVsZE5hbWVzLmFkZChmaWVsZC5uYW1lKVxuICAgICAgaWYgKGNvbnRhaW5zT3duZWRUeXBlKGZpZWxkLnR5cGUpKSB7XG4gICAgICAgIGZhaWwoXCJSRVNPVVJDRV9BTElBU1wiLCBcIk93bmVkIHJlc291cmNlcyBjYW5ub3QgYmUgc3RvcmVkIGluIGltbXV0YWJsZSByZWNvcmRzLlwiLCBmaWVsZC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIHZhbGlkYXRlVmFsdWVUeXBlUmVmZXJlbmNlKGZpZWxkLnR5cGUsIGZpZWxkLmxvY2F0aW9uLCBmYWlsLCB1bmRlZmluZWQsIHJlY29yZHMsIHR5cGVQYXJhbWV0ZXJzKVxuICAgIH1cbiAgfVxuICB2YWxpZGF0ZURpcmVjdFJlY29yZFJlY3Vyc2lvbihkZWNsYXJhdGlvbnMsIHJlY29yZHMsIGZhaWwpXG5cbiAgcmV0dXJuIHJlY29yZHNcbn1cblxuLyoqXG4gKiBSZWplY3RzIGN5Y2xlcyBjb21wb3NlZCBzb2xlbHkgb2YgdW5tZWRpYXRlZCByZWNvcmQgZmllbGRzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uW119IGRlY2xhcmF0aW9ucyAtIFZhbGlkIGRlY2xhcmF0aW9ucy5cbiAqIEBwYXJhbSB7UmVjb3JkUmVnaXN0cnl9IHJlY29yZHMgLSBEZWNsYXJhdGlvbnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVEaXJlY3RSZWNvcmRSZWN1cnNpb24oZGVjbGFyYXRpb25zLCByZWNvcmRzLCBmYWlsKSB7XG4gIGNvbnN0IGNvbXBsZXRlID0gbmV3IFNldCgpXG5cbiAgLyoqXG4gICAqIFZpc2l0cyBvbmUgZGVjbGFyYXRpb24gYWxvbmcgYW4gdW5tZWRpYXRlZCByZWNvcmQgcGF0aC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIEN1cnJlbnQgZGVjbGFyYXRpb24uXG4gICAqIEBwYXJhbSB7U2V0PHN0cmluZz59IGFjdGl2ZSAtIERlY2xhcmF0aW9uIGlkZW50aXRpZXMgYWN0aXZlIG9uIHRoaXMgcGF0aC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBmdW5jdGlvbiB2aXNpdChkZWNsYXJhdGlvbiwgYWN0aXZlKSB7XG4gICAgaWYgKGNvbXBsZXRlLmhhcygvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSkpIHJldHVyblxuICAgIGNvbnN0IG5leHQgPSBuZXcgU2V0KGFjdGl2ZSlcblxuICAgIG5leHQuYWRkKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpKVxuICAgIGZvciAoY29uc3QgZmllbGQgb2YgZGVjbGFyYXRpb24uZmllbGRzKSB7XG4gICAgICBpZiAoZmllbGQudHlwZS5raW5kICE9IFwiUmVjb3JkVHlwZVwiKSBjb250aW51ZVxuICAgICAgaWYgKG5leHQuaGFzKGZpZWxkLnR5cGUuZGVjbGFyYXRpb25JZCkpIHtcbiAgICAgICAgZmFpbChcIklMTEVHQUxfUkVDT1JEX1JFQ1VSU0lPTlwiLCBgRGlyZWN0IHZhbHVlLXJlY3Vyc2l2ZSBmaWVsZCAnJHtmaWVsZC5uYW1lfScuYCwgdHlwZUxvY2F0aW9uKGZpZWxkLnR5cGUsIGZpZWxkLmxvY2F0aW9uKSlcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlZmVyZW5jZWQgPSByZWNvcmRzLmdldChmaWVsZC50eXBlLmRlY2xhcmF0aW9uSWQpXG5cbiAgICAgIGlmIChyZWZlcmVuY2VkKSB2aXNpdChyZWZlcmVuY2VkLCBuZXh0KVxuICAgIH1cbiAgICBjb21wbGV0ZS5hZGQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCkpXG4gIH1cblxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIGRlY2xhcmF0aW9ucykgdmlzaXQoZGVjbGFyYXRpb24sIG5ldyBTZXQoKSlcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgb25lIG5vbi12b2lkIGZ1bmN0aW9uIGFuZCBpdHMgY29tcGxldGUgY29udHJvbCBmbG93LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb259IGRlY2xhcmF0aW9uIC0gRnVuY3Rpb24gZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4vdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbj59IGZ1bmN0aW9ucyAtIEZ1bmN0aW9uIHNpZ25hdHVyZXMuXG4gKiBAcGFyYW0ge1JlY29yZFJlZ2lzdHJ5fSByZWNvcmRzIC0gUmVjb3JkIGRlY2xhcmF0aW9ucyBieSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7RXJyb3JSZWdpc3RyeX0gZXJyb3JzIC0gRXJyb3IgZGVjbGFyYXRpb25zIGJ5IGlkZW50aXR5LlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj59IGNhbGxFZmZlY3RzIC0gSW50ZXJuYWxseSBpbmZlcnJlZCB1bmNoZWNrZWQtZXJyb3IgZWZmZWN0cy5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IHJlc2VydmVkVmFsdWVOYW1lcyAtIE1vZHVsZSBmdW5jdGlvbnMgYW5kIG5vbWluYWwgY29uc3RydWN0b3JzIHVuYXZhaWxhYmxlIHRvIGxleGljYWwgYmluZGluZ3MuXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5vcm1hbGl6ZU9wZXJhdGlvbnMgLSBXaGV0aGVyIHRvIHJlcGxhY2UgdHJhbnNpZW50IGZyb250ZW5kIG9wZXJhdGlvbiBpbnRlbnQuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIG9iamVjdD59IGxvb3BPd25lcnMgLSBMb29wIG93bmVyIGJ5IG1vZHVsZS1sb2NhbCBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUZ1bmN0aW9uKGRlY2xhcmF0aW9uLCBmdW5jdGlvbnMsIHJlY29yZHMsIGVycm9ycywgY2FsbEVmZmVjdHMsIHJlc2VydmVkVmFsdWVOYW1lcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgbG9vcE93bmVycykge1xuICBjb25zdCB0eXBlUGFyYW1ldGVycyA9IGRlY2xhcmF0aW9uVHlwZVBhcmFtZXRlcklkcyhkZWNsYXJhdGlvbilcbiAgY29uc3Qgc2NvcGUgPSBjcmVhdGVTY29wZSh1bmRlZmluZWQsIGRlY2xhcmF0aW9uLmJvZHkuc3RhdGVtZW50cywgcmVzZXJ2ZWRWYWx1ZU5hbWVzLCB0eXBlUGFyYW1ldGVycylcblxuICBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzKSB7XG4gICAgY29uc3QgdHlwZSA9IHZhbGlkYXRlVmFsdWVUeXBlUmVmZXJlbmNlKHBhcmFtZXRlci50eXBlLCBwYXJhbWV0ZXIubG9jYXRpb24sIGZhaWwsIHVuZGVmaW5lZCwgcmVjb3JkcywgdHlwZVBhcmFtZXRlcnMpXG5cbiAgICBkZWNsYXJlQmluZGluZyhwYXJhbWV0ZXIubmFtZSwge2tub3duVmFsdWU6IHVuZGVmaW5lZCwgbXV0YWJsZTogZmFsc2UsIHR5cGV9LCByb2xlTG9jYXRpb24ocGFyYW1ldGVyLCBcIm5hbWVcIiksIHNjb3BlLCBmYWlsKVxuICB9XG5cbiAgY29uc3QgcmV0dXJuVHlwZSA9IHZhbGlkYXRlUmV0dXJuVHlwZVJlZmVyZW5jZShkZWNsYXJhdGlvbi5yZXR1cm5UeXBlLCBkZWNsYXJhdGlvbi5sb2NhdGlvbiwgZmFpbCwgcmVjb3JkcywgdHlwZVBhcmFtZXRlcnMpXG4gIGNvbnN0IHJldHVybnMgPSB2YWxpZGF0ZUJsb2NrKGRlY2xhcmF0aW9uLmJvZHksIHNjb3BlLCByZXR1cm5UeXBlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGVycm9ycywgY2FsbEVmZmVjdHMsIGZhaWwsXG4gICAgbm9ybWFsaXplT3BlcmF0aW9ucywge293bmVyOiBkZWNsYXJhdGlvbiwgb3duZXJzOiBsb29wT3duZXJzfSlcblxuICBpZiAoIWlzVm9pZFR5cGUocmV0dXJuVHlwZSkgJiYgcmV0dXJucy5ub3JtYWwpIHtcbiAgICBmYWlsKFwiTUlTU0lOR19SRVRVUk5cIiwgYEZ1bmN0aW9uICcke2RlY2xhcmF0aW9uLm5hbWV9JyBkb2VzIG5vdCByZXR1cm4gb24gZXZlcnkgcmVhY2hhYmxlIHBhdGguYCwgZGVjbGFyYXRpb24ubG9jYXRpb24pXG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgb25lIG9yZGVyZWQgYmxvY2sgYW5kIHJlcG9ydHMgd2hldGhlciBldmVyeSBwYXRoIHJldHVybnMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQmxvY2t9IGJsb2NrIC0gU2VtYW50aWMgYmxvY2suXG4gKiBAcGFyYW0ge1Njb3BlfSBzY29wZSAtIFNjb3BlIGJlbG9uZ2luZyB0byB0aGlzIGJsb2NrLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlIHwgdW5kZWZpbmVkfSByZXR1cm5UeXBlIC0gRnVuY3Rpb24gcmV0dXJuIHR5cGUsIGFic2VudCBmb3IgZW50cnkgcG9pbnRzLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb24+fSBmdW5jdGlvbnMgLSBGdW5jdGlvbiBzaWduYXR1cmVzLlxuICogQHBhcmFtIHtSZWNvcmRSZWdpc3RyeX0gcmVjb3JkcyAtIFJlY29yZCBkZWNsYXJhdGlvbnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge0Vycm9yUmVnaXN0cnl9IGVycm9ycyAtIEVycm9yIGRlY2xhcmF0aW9ucyBieSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgU2V0PHN0cmluZz4+fSBjYWxsRWZmZWN0cyAtIEludGVybmFsbHkgaW5mZXJyZWQgdW5jaGVja2VkLWVycm9yIGVmZmVjdHMuXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5vcm1hbGl6ZU9wZXJhdGlvbnMgLSBXaGV0aGVyIHRvIHJlcGxhY2UgdHJhbnNpZW50IGZyb250ZW5kIG9wZXJhdGlvbiBpbnRlbnQuXG4gKiBAcGFyYW0ge0xvb3BGbG93Q29udGV4dH0gbG9vcENvbnRleHQgLSBBY3RpdmUgbG9vcCBhbmQgb3duZXIgaWRlbnRpdGllcy5cbiAqIEByZXR1cm5zIHt7bm9ybWFsOiBib29sZWFuLCByYWlzZXM6IFNldDxzdHJpbmc+fX0gUmVhY2hhYmxlIG5vcm1hbCBjb250aW51YXRpb24gYW5kIGVzY2FwaW5nIGVycm9yIGlkZW50aXRpZXMuXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQmxvY2soYmxvY2ssIHNjb3BlLCByZXR1cm5UeXBlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGVycm9ycywgY2FsbEVmZmVjdHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIGxvb3BDb250ZXh0KSB7XG4gIGxldCBub3JtYWwgPSB0cnVlXG4gIGNvbnN0IHJhaXNlcyA9IG5ldyBTZXQoKVxuXG4gIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJsb2NrLnN0YXRlbWVudHMpIHtcbiAgICBpZiAoIW5vcm1hbCkgZmFpbChcIlVOUkVBQ0hBQkxFX1NUQVRFTUVOVFwiLCBcIlN0YXRlbWVudCBpcyB1bnJlYWNoYWJsZS5cIiwgc3RhdGVtZW50LmxvY2F0aW9uKVxuXG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiKSB7XG4gICAgICBjb25zdCBkZWNsYXJlZFR5cGUgPSB2YWxpZGF0ZVZhbHVlVHlwZVJlZmVyZW5jZShzdGF0ZW1lbnQudHlwZSwgc3RhdGVtZW50LmxvY2F0aW9uLCBmYWlsLCB1bmRlZmluZWQsIHJlY29yZHMsIHNjb3BlLnR5cGVQYXJhbWV0ZXJzKVxuICAgICAgc3RhdGVtZW50LmluaXRpYWxpemVyID0gbm9ybWFsaXplT3duZWRNb3ZlKHN0YXRlbWVudC5pbml0aWFsaXplciwgZGVjbGFyZWRUeXBlLCBub3JtYWxpemVPcGVyYXRpb25zLCBmYWlsKVxuICAgICAgY29uc3QgaW5pdGlhbGl6ZXJUeXBlID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKFxuICAgICAgICBzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIsIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYW4gaW5pdGlhbGl6ZXJcIiwgZGVjbGFyZWRUeXBlXG4gICAgICApXG5cbiAgICAgIHNjb3BlLnBlbmRpbmcuZGVsZXRlKHN0YXRlbWVudC5uYW1lKVxuICAgICAgaWYgKCFzYW1lVHlwZShpbml0aWFsaXplclR5cGUsIGRlY2xhcmVkVHlwZSkpIHtcbiAgICAgICAgaWYgKGluaXRpYWxpemVyVHlwZS5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIgJiYgZGVjbGFyZWRUeXBlLmtpbmQgIT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgICAgICAgIGZhaWwoXCJGQUlMVVJFX0FCU0VOQ0VfQ09ORkxBVElPTlwiLCBcIk9wdGlvbmFsIGFic2VuY2UgY2Fubm90IGJlIGNvZXJjZWQgaW50byBhIHZhbHVlIG9yIHR5cGVkIGZhaWx1cmUuXCIsIHN0YXRlbWVudC5pbml0aWFsaXplci5sb2NhdGlvbilcbiAgICAgICAgfVxuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgSW5pdGlhbGl6ZXIgdHlwZSAke3R5cGVEZXNjcmlwdGlvbihpbml0aWFsaXplclR5cGUpfTsgZXhwZWN0ZWQgJHt0eXBlRGVzY3JpcHRpb24oZGVjbGFyZWRUeXBlKX0uYCwgc3RhdGVtZW50LmluaXRpYWxpemVyLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgZGVjbGFyZUJpbmRpbmcoc3RhdGVtZW50Lm5hbWUsIHtcbiAgICAgICAga25vd25WYWx1ZToga25vd25WYWx1ZUZvckV4cHJlc3Npb24oc3RhdGVtZW50LmluaXRpYWxpemVyLCBzY29wZSksXG4gICAgICAgIG11dGFibGU6IHN0YXRlbWVudC5tdXRhYmxlLFxuICAgICAgICB0eXBlOiBkZWNsYXJlZFR5cGVcbiAgICAgIH0sIHJvbGVMb2NhdGlvbihzdGF0ZW1lbnQsIFwibmFtZVwiKSwgc2NvcGUsIGZhaWwpXG4gICAgICBhZGRFeHByZXNzaW9uRWZmZWN0cyhyYWlzZXMsIHN0YXRlbWVudC5pbml0aWFsaXplciwgY2FsbEVmZmVjdHMpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJBc3NpZ25tZW50U3RhdGVtZW50XCIpIHtcbiAgICAgIGNvbnN0IGJpbmRpbmcgPSByZXNvbHZlQmluZGluZyhzdGF0ZW1lbnQudGFyZ2V0Lm5hbWUsIHN0YXRlbWVudC50YXJnZXQubG9jYXRpb24sIHNjb3BlLCBmYWlsKVxuXG4gICAgICBpZiAoYmluZGluZy50eXBlLmtpbmQgPT0gXCJFcnJvclR5cGVcIikge1xuICAgICAgICBmYWlsKFwiSU1NVVRBQkxFX0FTU0lHTk1FTlRcIiwgYENhbm5vdCBhc3NpZ24gdG8gaW1tdXRhYmxlIGNhdGNoIGJpbmRpbmcgJyR7c3RhdGVtZW50LnRhcmdldC5uYW1lfScuYCwgc3RhdGVtZW50LnRhcmdldC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGlmIChiaW5kaW5nLnR5cGUua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIgfHwgYmluZGluZy50eXBlLmtpbmQgPT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIikge1xuICAgICAgICBmYWlsKFwiUkVTT1VSQ0VfQUxJQVNcIiwgXCJPd25lZCByZXNvdXJjZXMgY2Fubm90IGJlIHJlYXNzaWduZWQgb3IgYWxpYXNlZC5cIiwgc3RhdGVtZW50LmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY29uc3QgZXhwcmVzc2lvblR5cGUgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoXG4gICAgICAgIHN0YXRlbWVudC5leHByZXNzaW9uLCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCBcImFuIGFzc2lnbm1lbnRcIiwgYmluZGluZy50eXBlXG4gICAgICApXG5cbiAgICAgIGlmICghYmluZGluZy5tdXRhYmxlKSB7XG4gICAgICAgIGZhaWwoXCJJTU1VVEFCTEVfQVNTSUdOTUVOVFwiLCBgQ2Fubm90IGFzc2lnbiB0byBpbW11dGFibGUgYmluZGluZyAnJHtzdGF0ZW1lbnQudGFyZ2V0Lm5hbWV9Jy5gLCBzdGF0ZW1lbnQudGFyZ2V0LmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKCFzYW1lVHlwZShleHByZXNzaW9uVHlwZSwgYmluZGluZy50eXBlKSkge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgQXNzaWdubWVudCB0eXBlICR7dHlwZURlc2NyaXB0aW9uKGV4cHJlc3Npb25UeXBlKX07IGV4cGVjdGVkICR7dHlwZURlc2NyaXB0aW9uKGJpbmRpbmcudHlwZSl9LmAsIHN0YXRlbWVudC5leHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgYmluZGluZy5rbm93blZhbHVlID0ga25vd25WYWx1ZUZvckV4cHJlc3Npb24oc3RhdGVtZW50LmV4cHJlc3Npb24sIHNjb3BlKVxuICAgICAgc2NvcGUucHJlc2VuY2VQcm9vZnMuZGVsZXRlKGJpbmRpbmcpXG4gICAgICBhZGRFeHByZXNzaW9uRWZmZWN0cyhyYWlzZXMsIHN0YXRlbWVudC5leHByZXNzaW9uLCBjYWxsRWZmZWN0cylcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlByaXZhdGVGaWVsZFdyaXRlU3RhdGVtZW50XCIpIHtcbiAgICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gc2NvcGUuY3VycmVudENsYXNzXG5cbiAgICAgIGlmICghZGVjbGFyYXRpb24gfHwgIXN0YXRlbWVudC5yZWNlaXZlciB8fCBzdGF0ZW1lbnQucmVjZWl2ZXIua2luZCAhPSBcIlJlY2VpdmVyRXhwcmVzc2lvblwiIHx8XG4gICAgICAgIHN0YXRlbWVudC5yZWNlaXZlci5jbGFzc0lkICE9IGRlY2xhcmF0aW9uLmlkKSB7XG4gICAgICAgIGZhaWwoXCJJTExFR0FMX1BSSVZBVEVfQUNDRVNTXCIsIFwiUHJpdmF0ZSBmaWVsZCByZWNlaXZlciBtdXN0IGJlIHRoZSBkZWNsYXJpbmcgY2xhc3MgcmVjZWl2ZXIuXCIsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpZWxkID0gZGVjbGFyYXRpb24uZmllbGRzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLmlkID09IHN0YXRlbWVudC5maWVsZClcblxuICAgICAgaWYgKCFmaWVsZCkgZmFpbChcIklMTEVHQUxfUFJJVkFURV9BQ0NFU1NcIiwgXCJQcml2YXRlIGZpZWxkIGlkZW50aXR5IGlzIG5vdCBvd25lZCBieSB0aGUgZGVjbGFyaW5nIGNsYXNzLlwiLCBzdGF0ZW1lbnQubG9jYXRpb24pXG4gICAgICBzdGF0ZW1lbnQuZXhwcmVzc2lvbiA9IG5vcm1hbGl6ZU93bmVkTW92ZShzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgZmllbGQudHlwZSwgbm9ybWFsaXplT3BlcmF0aW9ucywgZmFpbClcbiAgICAgIGNvbnN0IGV4cHJlc3Npb25UeXBlID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKFxuICAgICAgICBzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgXCJhIHByaXZhdGUgZmllbGQgYXNzaWdubWVudFwiLCBmaWVsZC50eXBlXG4gICAgICApXG5cbiAgICAgIGlmICghc2FtZVR5cGUoZXhwcmVzc2lvblR5cGUsIGZpZWxkLnR5cGUpKSB7XG4gICAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBQcml2YXRlIGZpZWxkIGFzc2lnbm1lbnQgdHlwZSAke3R5cGVEZXNjcmlwdGlvbihleHByZXNzaW9uVHlwZSl9OyBleHBlY3RlZCAke3R5cGVEZXNjcmlwdGlvbihmaWVsZC50eXBlKX0uYCxcbiAgICAgICAgICBzdGF0ZW1lbnQuZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGFkZEV4cHJlc3Npb25FZmZlY3RzKHJhaXNlcywgc3RhdGVtZW50LmV4cHJlc3Npb24sIGNhbGxFZmZlY3RzKVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgICAgY29uc3QgcHJpbnRlZFR5cGUgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoc3RhdGVtZW50LmV4cHJlc3Npb24sIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYSBwcmludCB2YWx1ZVwiKVxuXG4gICAgICBpZiAocHJpbnRlZFR5cGUua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIgfHwgcHJpbnRlZFR5cGUua2luZCA9PSBcIk93bmVkUmVmZXJlbmNlVHlwZVwiKSB7XG4gICAgICAgIGZhaWwoXCJCT1JST1dfRVNDQVBFXCIsIFwiT3duZWQgdmFsdWVzIGNhbm5vdCBlc2NhcGUgdGhyb3VnaCBwcmludGluZyBvciBzZXJpYWxpemF0aW9uLlwiLCBzdGF0ZW1lbnQuZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGlmIChwcmludGVkVHlwZS5raW5kICE9IFwiVHlwZVJlZmVyZW5jZVwiKSB7XG4gICAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiQ29sbGVjdGlvbnMgYW5kIHJlY29yZHMgY2Fubm90IGJlIHByaW50ZWQgZGlyZWN0bHkuXCIsIHN0YXRlbWVudC5leHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgYWRkRXhwcmVzc2lvbkVmZmVjdHMocmFpc2VzLCBzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgY2FsbEVmZmVjdHMpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJFeHByZXNzaW9uU3RhdGVtZW50XCIpIHtcbiAgICAgIGlmICghc3RhdGVtZW50LmV4cHJlc3Npb24gfHwgIVtcIkNhbGxFeHByZXNzaW9uXCIsIFwiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIiwgXCJNZXRob2RDYWxsRXhwcmVzc2lvblwiXS5pbmNsdWRlcyhzdGF0ZW1lbnQuZXhwcmVzc2lvbi5raW5kKSkge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIkV4cHJlc3Npb24gc3RhdGVtZW50IG11c3QgY29udGFpbiBhIGRpcmVjdCBvciByZWNlaXZlciBjYWxsLlwiLCBzdGF0ZW1lbnQubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBjb25zdCBleHByZXNzaW9uVHlwZSA9IGluZmVyRXhwcmVzc2lvblR5cGUoc3RhdGVtZW50LmV4cHJlc3Npb24sIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMpXG5cbiAgICAgIGlmIChleHByZXNzaW9uVHlwZSAhPSBcInZvaWRcIikge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIkV4cHJlc3Npb24gc3RhdGVtZW50cyBtYXkgY29udGFpbiBvbmx5IHZvaWQgY2FsbHMuXCIsIHN0YXRlbWVudC5leHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgYWRkRXhwcmVzc2lvbkVmZmVjdHMocmFpc2VzLCBzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgY2FsbEVmZmVjdHMpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJCcmVha1N0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiQ29udGludWVTdGF0ZW1lbnRcIikge1xuICAgICAgY29uc3QgY29udHJvbCA9IHN0YXRlbWVudC5raW5kID09IFwiQnJlYWtTdGF0ZW1lbnRcIiA/IFwiYnJlYWtcIiA6IFwiY29udGludWVcIlxuXG4gICAgICBpZiAoIWxvb3BDb250ZXh0Lm5lYXJlc3QpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzdGF0ZW1lbnQudGFyZ2V0TG9vcElkID09IFwic3RyaW5nXCIgJiYgbG9vcENvbnRleHQub3duZXJzLmhhcyhzdGF0ZW1lbnQudGFyZ2V0TG9vcElkKSAmJlxuICAgICAgICAgIGxvb3BDb250ZXh0Lm93bmVycy5nZXQoc3RhdGVtZW50LnRhcmdldExvb3BJZCkgIT09IGxvb3BDb250ZXh0Lm93bmVyKSB7XG4gICAgICAgICAgZmFpbChcIkNST1NTX0ZVTkNUSU9OX0xPT1BfVEFSR0VUXCIsIGAke2NvbnRyb2xbMF0udG9VcHBlckNhc2UoKX0ke2NvbnRyb2wuc2xpY2UoMSl9IHRhcmdldCBjcm9zc2VzIGEgZnVuY3Rpb24gYm91bmRhcnkuYCwgc3RhdGVtZW50LmxvY2F0aW9uKVxuICAgICAgICB9XG4gICAgICAgIGZhaWwoYElMTEVHQUxfJHtjb250cm9sLnRvVXBwZXJDYXNlKCl9X0NPTlRFWFRgLCBgJHtjb250cm9sWzBdLnRvVXBwZXJDYXNlKCl9JHtjb250cm9sLnNsaWNlKDEpfSBzdGF0ZW1lbnQgb3V0c2lkZSBhIGxvb3AuYCwgc3RhdGVtZW50LmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBzdGF0ZW1lbnQudGFyZ2V0TG9vcElkICE9IFwic3RyaW5nXCIgfHwgIWxvb3BDb250ZXh0Lm93bmVycy5oYXMoc3RhdGVtZW50LnRhcmdldExvb3BJZCkpIHtcbiAgICAgICAgZmFpbChcIklOVkFMSURfTE9PUF9UQVJHRVRcIiwgYCR7Y29udHJvbFswXS50b1VwcGVyQ2FzZSgpfSR7Y29udHJvbC5zbGljZSgxKX0gaGFzIGFuIGludmFsaWQgbG9vcCB0YXJnZXQgaWRlbnRpdHkuYCwgc3RhdGVtZW50LmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKGxvb3BDb250ZXh0Lm93bmVycy5nZXQoc3RhdGVtZW50LnRhcmdldExvb3BJZCkgIT09IGxvb3BDb250ZXh0Lm93bmVyKSB7XG4gICAgICAgIGZhaWwoXCJDUk9TU19GVU5DVElPTl9MT09QX1RBUkdFVFwiLCBgJHtjb250cm9sWzBdLnRvVXBwZXJDYXNlKCl9JHtjb250cm9sLnNsaWNlKDEpfSB0YXJnZXQgY3Jvc3NlcyBhIGZ1bmN0aW9uIGJvdW5kYXJ5LmAsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGlmIChzdGF0ZW1lbnQudGFyZ2V0TG9vcElkICE9IGxvb3BDb250ZXh0Lm5lYXJlc3QuaWQpIHtcbiAgICAgICAgZmFpbChcIklOVkFMSURfTE9PUF9UQVJHRVRcIiwgYCR7Y29udHJvbFswXS50b1VwcGVyQ2FzZSgpfSR7Y29udHJvbC5zbGljZSgxKX0gbXVzdCB0YXJnZXQgdGhlIG5lYXJlc3QgZW5jbG9zaW5nIGxvb3AuYCwgc3RhdGVtZW50LmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgbm9ybWFsID0gZmFsc2VcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlJldHVyblN0YXRlbWVudFwiKSB7XG4gICAgICBpZiAoIXJldHVyblR5cGUpIGZhaWwoXCJJTExFR0FMX1JFVFVSTl9DT05URVhUXCIsIFwiUmV0dXJuIHN0YXRlbWVudCBvdXRzaWRlIGEgZnVuY3Rpb24uXCIsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICAgIGlmIChpc1ZvaWRUeXBlKHJldHVyblR5cGUpKSB7XG4gICAgICAgIGlmIChzdGF0ZW1lbnQuZXhwcmVzc2lvbikge1xuICAgICAgICAgIGZhaWwoXCJWT0lEX1JFVFVSTl9WQUxVRVwiLCBcIlZvaWQgZnVuY3Rpb24gY2Fubm90IHJldHVybiBhIHZhbHVlLlwiLCBzdGF0ZW1lbnQuZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCFzdGF0ZW1lbnQuZXhwcmVzc2lvbikge1xuICAgICAgICAgIGZhaWwoXCJNSVNTSU5HX1JFVFVSTl9WQUxVRVwiLCBgRnVuY3Rpb24gcmV0dXJuIHJlcXVpcmVzIGEgJHt0eXBlRGVzY3JpcHRpb24ocmV0dXJuVHlwZSl9IHZhbHVlLmAsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZW1lbnQuZXhwcmVzc2lvbiA9IG5vcm1hbGl6ZU93bmVkTW92ZShzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgcmV0dXJuVHlwZSwgbm9ybWFsaXplT3BlcmF0aW9ucywgZmFpbClcbiAgICAgICAgY29uc3QgYWN0dWFsVHlwZSA9IGluZmVyVmFsdWVFeHByZXNzaW9uVHlwZShcbiAgICAgICAgICBzdGF0ZW1lbnQuZXhwcmVzc2lvbixcbiAgICAgICAgICBzY29wZSxcbiAgICAgICAgICBmdW5jdGlvbnMsXG4gICAgICAgICAgcmVjb3JkcyxcbiAgICAgICAgICBmYWlsLFxuICAgICAgICAgIG5vcm1hbGl6ZU9wZXJhdGlvbnMsXG4gICAgICAgICAgXCJhIHJldHVybmVkIHZhbHVlXCIsXG4gICAgICAgICAgcmV0dXJuVHlwZVxuICAgICAgICApXG5cbiAgICAgICAgaWYgKCFzYW1lVHlwZShhY3R1YWxUeXBlLCByZXR1cm5UeXBlKSkge1xuICAgICAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBSZXR1cm4gdHlwZSAke3R5cGVEZXNjcmlwdGlvbihhY3R1YWxUeXBlKX07IGV4cGVjdGVkICR7dHlwZURlc2NyaXB0aW9uKHJldHVyblR5cGUpfS5gLCBzdGF0ZW1lbnQuZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHN0YXRlbWVudC5leHByZXNzaW9uKSBhZGRFeHByZXNzaW9uRWZmZWN0cyhyYWlzZXMsIHN0YXRlbWVudC5leHByZXNzaW9uLCBjYWxsRWZmZWN0cylcbiAgICAgIG5vcm1hbCA9IGZhbHNlXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJJZlN0YXRlbWVudFwiKSB7XG4gICAgICBjb25zdCBjb25kaXRpb25UeXBlID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKHN0YXRlbWVudC5jb25kaXRpb24sIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYSBjb25kaXRpb25cIilcblxuICAgICAgaWYgKCFpc1NjYWxhclR5cGUoY29uZGl0aW9uVHlwZSwgXCJib29sZWFuXCIpKSB7XG4gICAgICAgIGZhaWwoXCJOT05fQk9PTEVBTl9DT05ESVRJT05cIiwgYElmIGNvbmRpdGlvbiB0eXBlICR7dHlwZURlc2NyaXB0aW9uKGNvbmRpdGlvblR5cGUpfTsgZXhwZWN0ZWQgYm9vbGVhbi5gLCBzdGF0ZW1lbnQuY29uZGl0aW9uLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY29uc3QgdmlzaWJsZUJpbmRpbmdzID0gYmluZGluZ3NWaXNpYmxlRnJvbShzY29wZSlcbiAgICAgIGNvbnN0IGluaXRpYWxLbm93blZhbHVlcyA9IHZpc2libGVCaW5kaW5ncy5tYXAoKGJpbmRpbmcpID0+IGJpbmRpbmcua25vd25WYWx1ZSlcbiAgICAgIGNvbnN0IGNvbnNlcXVlbnRTY29wZSA9IGNyZWF0ZVNjb3BlKHNjb3BlLCBzdGF0ZW1lbnQuY29uc2VxdWVudC5zdGF0ZW1lbnRzKVxuICAgICAgY29uc3QgYWx0ZXJuYXRlU2NvcGUgPSBjcmVhdGVTY29wZShzY29wZSwgc3RhdGVtZW50LmFsdGVybmF0ZT8uc3RhdGVtZW50cyA/PyBbXSlcbiAgICAgIGFwcGx5UHJlc2VuY2VOYXJyb3dpbmcoc3RhdGVtZW50LmNvbmRpdGlvbiwgc2NvcGUsIGNvbnNlcXVlbnRTY29wZSwgdHJ1ZSlcbiAgICAgIGFwcGx5UHJlc2VuY2VOYXJyb3dpbmcoc3RhdGVtZW50LmNvbmRpdGlvbiwgc2NvcGUsIGFsdGVybmF0ZVNjb3BlLCBmYWxzZSlcbiAgICAgIGNvbnN0IGNvbnNlcXVlbnRSZXR1cm5zID0gdmFsaWRhdGVCbG9jayhzdGF0ZW1lbnQuY29uc2VxdWVudCwgY29uc2VxdWVudFNjb3BlLCByZXR1cm5UeXBlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGVycm9ycywgY2FsbEVmZmVjdHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIGxvb3BDb250ZXh0KVxuICAgICAgY29uc3QgY29uc2VxdWVudEtub3duVmFsdWVzID0gdmlzaWJsZUJpbmRpbmdzLm1hcCgoYmluZGluZykgPT4gYmluZGluZy5rbm93blZhbHVlKVxuXG4gICAgICB2aXNpYmxlQmluZGluZ3MuZm9yRWFjaCgoYmluZGluZywgaW5kZXgpID0+IHtcbiAgICAgICAgYmluZGluZy5rbm93blZhbHVlID0gaW5pdGlhbEtub3duVmFsdWVzW2luZGV4XVxuICAgICAgfSlcbiAgICAgIGxldCBhbHRlcm5hdGVSZXR1cm5zID0ge25vcm1hbDogdHJ1ZSwgcmFpc2VzOiBuZXcgU2V0KCl9XG5cbiAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSB7XG4gICAgICAgIGFsdGVybmF0ZVJldHVybnMgPSB2YWxpZGF0ZUJsb2NrKHN0YXRlbWVudC5hbHRlcm5hdGUsIGFsdGVybmF0ZVNjb3BlLCByZXR1cm5UeXBlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGVycm9ycywgY2FsbEVmZmVjdHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIGxvb3BDb250ZXh0KVxuICAgICAgfVxuICAgICAgY29uc3QgYWx0ZXJuYXRlS25vd25WYWx1ZXMgPSB2aXNpYmxlQmluZGluZ3MubWFwKChiaW5kaW5nKSA9PiBiaW5kaW5nLmtub3duVmFsdWUpXG5cbiAgICAgIHZpc2libGVCaW5kaW5ncy5mb3JFYWNoKChiaW5kaW5nLCBpbmRleCkgPT4ge1xuICAgICAgICBpZiAoIWNvbnNlcXVlbnRSZXR1cm5zLm5vcm1hbCAmJiBhbHRlcm5hdGVSZXR1cm5zLm5vcm1hbCkgYmluZGluZy5rbm93blZhbHVlID0gYWx0ZXJuYXRlS25vd25WYWx1ZXNbaW5kZXhdXG4gICAgICAgIGVsc2UgaWYgKGNvbnNlcXVlbnRSZXR1cm5zLm5vcm1hbCAmJiAhYWx0ZXJuYXRlUmV0dXJucy5ub3JtYWwpIGJpbmRpbmcua25vd25WYWx1ZSA9IGNvbnNlcXVlbnRLbm93blZhbHVlc1tpbmRleF1cbiAgICAgICAgZWxzZSBpZiAoY29uc2VxdWVudFJldHVybnMubm9ybWFsICYmIGFsdGVybmF0ZVJldHVybnMubm9ybWFsICYmIGNvbnNlcXVlbnRLbm93blZhbHVlc1tpbmRleF0gPT09IGFsdGVybmF0ZUtub3duVmFsdWVzW2luZGV4XSkge1xuICAgICAgICAgIGJpbmRpbmcua25vd25WYWx1ZSA9IGNvbnNlcXVlbnRLbm93blZhbHVlc1tpbmRleF1cbiAgICAgICAgfSBlbHNlIGJpbmRpbmcua25vd25WYWx1ZSA9IHVuZGVmaW5lZFxuICAgICAgfSlcbiAgICAgIGNvbnN0IGNvbnRpbnVpbmdQcm9vZnMgPSAhY29uc2VxdWVudFJldHVybnMubm9ybWFsICYmIGFsdGVybmF0ZVJldHVybnMubm9ybWFsXG4gICAgICAgID8gYWx0ZXJuYXRlU2NvcGUucHJlc2VuY2VQcm9vZnNcbiAgICAgICAgOiBjb25zZXF1ZW50UmV0dXJucy5ub3JtYWwgJiYgIWFsdGVybmF0ZVJldHVybnMubm9ybWFsXG4gICAgICAgICAgPyBjb25zZXF1ZW50U2NvcGUucHJlc2VuY2VQcm9vZnNcbiAgICAgICAgICA6IGNvbnNlcXVlbnRSZXR1cm5zLm5vcm1hbCAmJiBhbHRlcm5hdGVSZXR1cm5zLm5vcm1hbFxuICAgICAgICAgICAgPyBuZXcgU2V0KFsuLi5jb25zZXF1ZW50U2NvcGUucHJlc2VuY2VQcm9vZnNdLmZpbHRlcigoYmluZGluZykgPT4gYWx0ZXJuYXRlU2NvcGUucHJlc2VuY2VQcm9vZnMuaGFzKGJpbmRpbmcpKSlcbiAgICAgICAgICAgIDogbmV3IFNldCgpXG4gICAgICBjb25zdCB2aXNpYmxlU2V0ID0gbmV3IFNldCh2aXNpYmxlQmluZGluZ3MpXG5cbiAgICAgIHNjb3BlLnByZXNlbmNlUHJvb2ZzLmNsZWFyKClcbiAgICAgIGZvciAoY29uc3QgYmluZGluZyBvZiBjb250aW51aW5nUHJvb2ZzKSB7XG4gICAgICAgIGlmICh2aXNpYmxlU2V0LmhhcyhiaW5kaW5nKSkgc2NvcGUucHJlc2VuY2VQcm9vZnMuYWRkKGJpbmRpbmcpXG4gICAgICB9XG4gICAgICBhZGRFeHByZXNzaW9uRWZmZWN0cyhyYWlzZXMsIHN0YXRlbWVudC5jb25kaXRpb24sIGNhbGxFZmZlY3RzKVxuICAgICAgYWRkQWxsKHJhaXNlcywgY29uc2VxdWVudFJldHVybnMucmFpc2VzKVxuICAgICAgYWRkQWxsKHJhaXNlcywgYWx0ZXJuYXRlUmV0dXJucy5yYWlzZXMpXG4gICAgICBub3JtYWwgPSBjb25zZXF1ZW50UmV0dXJucy5ub3JtYWwgfHwgYWx0ZXJuYXRlUmV0dXJucy5ub3JtYWxcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIldoaWxlU3RhdGVtZW50XCIpIHtcbiAgICAgIGNvbnN0IGFzc2lnbmVkT3V0ZXJCaW5kaW5ncyA9IG91dGVyTXV0YWJsZUJpbmRpbmdzQXNzaWduZWRCeShzdGF0ZW1lbnQuYm9keSwgc2NvcGUpXG5cbiAgICAgIGZvciAoY29uc3QgYmluZGluZyBvZiBhc3NpZ25lZE91dGVyQmluZGluZ3MpIHtcbiAgICAgICAgYmluZGluZy5rbm93blZhbHVlID0gdW5kZWZpbmVkXG4gICAgICAgIHNjb3BlLnByZXNlbmNlUHJvb2ZzLmRlbGV0ZShiaW5kaW5nKVxuICAgICAgfVxuICAgICAgY29uc3QgY29uZGl0aW9uVHlwZSA9IGluZmVyVmFsdWVFeHByZXNzaW9uVHlwZShcbiAgICAgICAgc3RhdGVtZW50LmNvbmRpdGlvbiwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgXCJhIGNvbmRpdGlvbi1jb250cm9sbGVkIGxvb3AgY29uZGl0aW9uXCJcbiAgICAgIClcblxuICAgICAgaWYgKCFpc1NjYWxhclR5cGUoY29uZGl0aW9uVHlwZSwgXCJib29sZWFuXCIpKSB7XG4gICAgICAgIGZhaWwoXCJOT05fQk9PTEVBTl9DT05ESVRJT05cIiwgYFdoaWxlIGNvbmRpdGlvbiB0eXBlICR7dHlwZURlc2NyaXB0aW9uKGNvbmRpdGlvblR5cGUpfTsgZXhwZWN0ZWQgYm9vbGVhbi5gLCBzdGF0ZW1lbnQuY29uZGl0aW9uLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY29uc3QgbG9vcFNjb3BlID0gY3JlYXRlU2NvcGUoc2NvcGUsIHN0YXRlbWVudC5ib2R5LnN0YXRlbWVudHMpXG5cbiAgICAgIGFwcGx5UHJlc2VuY2VOYXJyb3dpbmcoc3RhdGVtZW50LmNvbmRpdGlvbiwgc2NvcGUsIGxvb3BTY29wZSwgdHJ1ZSlcbiAgICAgIGNvbnN0IGJvZHlGbG93ID0gdmFsaWRhdGVCbG9jayhzdGF0ZW1lbnQuYm9keSwgbG9vcFNjb3BlLCByZXR1cm5UeXBlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGVycm9ycywgY2FsbEVmZmVjdHMsIGZhaWwsXG4gICAgICAgIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIHtuZWFyZXN0OiBzdGF0ZW1lbnQsIG93bmVyOiBsb29wQ29udGV4dC5vd25lciwgb3duZXJzOiBsb29wQ29udGV4dC5vd25lcnN9KVxuXG4gICAgICBhZGRFeHByZXNzaW9uRWZmZWN0cyhyYWlzZXMsIHN0YXRlbWVudC5jb25kaXRpb24sIGNhbGxFZmZlY3RzKVxuICAgICAgYWRkQWxsKHJhaXNlcywgYm9keUZsb3cucmFpc2VzKVxuICAgICAgZm9yIChjb25zdCBiaW5kaW5nIG9mIGFzc2lnbmVkT3V0ZXJCaW5kaW5ncykge1xuICAgICAgICBiaW5kaW5nLmtub3duVmFsdWUgPSB1bmRlZmluZWRcbiAgICAgICAgc2NvcGUucHJlc2VuY2VQcm9vZnMuZGVsZXRlKGJpbmRpbmcpXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoU3RhdGVtZW50XCIpIHtcbiAgICAgIGNvbnN0IGxpc3RUeXBlID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKHN0YXRlbWVudC5saXN0LCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCBcImFuIGl0ZXJhdGlvbiBjb2xsZWN0aW9uXCIpXG5cbiAgICAgIGlmIChsaXN0VHlwZS5raW5kICE9IFwiTGlzdFR5cGVcIikge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgSXRlcmF0aW9uIGNvbGxlY3Rpb24gdHlwZSAke3R5cGVEZXNjcmlwdGlvbihsaXN0VHlwZSl9OyBleHBlY3RlZCBsaXN0LmAsIHN0YXRlbWVudC5saXN0LmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKCFzdGF0ZW1lbnQudmFsdWVCaW5kaW5nIHx8IHN0YXRlbWVudC52YWx1ZUJpbmRpbmcua2luZCAhPSBcIlZhbHVlQmluZGluZ1wiKSB7XG4gICAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiSXRlcmF0aW9uIHJlcXVpcmVzIG9uZSB0eXBlZCB2YWx1ZSBiaW5kaW5nLlwiLCBzdGF0ZW1lbnQubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBpZiAoc3RhdGVtZW50LnZhbHVlQmluZGluZy5tdXRhYmxlICE9PSBmYWxzZSkge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIkl0ZXJhdGlvbiBiaW5kaW5nIG11c3QgYmUgaW1tdXRhYmxlLlwiLCBzdGF0ZW1lbnQudmFsdWVCaW5kaW5nLmxvY2F0aW9uID8/IHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJpbmRpbmdUeXBlID0gdmFsaWRhdGVWYWx1ZVR5cGVSZWZlcmVuY2Uoc3RhdGVtZW50LnZhbHVlQmluZGluZy50eXBlLCBzdGF0ZW1lbnQudmFsdWVCaW5kaW5nLmxvY2F0aW9uLCBmYWlsLCB1bmRlZmluZWQsIHJlY29yZHMsIHNjb3BlLnR5cGVQYXJhbWV0ZXJzKVxuXG4gICAgICBpZiAoIXNhbWVUeXBlKGJpbmRpbmdUeXBlLCBsaXN0VHlwZS5lbGVtZW50VHlwZSkpIHtcbiAgICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYEl0ZXJhdGlvbiBiaW5kaW5nIHR5cGUgJHt0eXBlRGVzY3JpcHRpb24oYmluZGluZ1R5cGUpfTsgZXhwZWN0ZWQgJHt0eXBlRGVzY3JpcHRpb24obGlzdFR5cGUuZWxlbWVudFR5cGUpfS5gLFxuICAgICAgICAgIHR5cGVMb2NhdGlvbihzdGF0ZW1lbnQudmFsdWVCaW5kaW5nLnR5cGUsIHN0YXRlbWVudC52YWx1ZUJpbmRpbmcubG9jYXRpb24pKVxuICAgICAgfVxuICAgICAgY29uc3QgYXNzaWduZWRPdXRlckJpbmRpbmdzID0gb3V0ZXJNdXRhYmxlQmluZGluZ3NBc3NpZ25lZEJ5KHN0YXRlbWVudC5ib2R5LCBzY29wZSlcblxuICAgICAgZm9yIChjb25zdCBiaW5kaW5nIG9mIGFzc2lnbmVkT3V0ZXJCaW5kaW5ncykge1xuICAgICAgICBiaW5kaW5nLmtub3duVmFsdWUgPSB1bmRlZmluZWRcbiAgICAgICAgc2NvcGUucHJlc2VuY2VQcm9vZnMuZGVsZXRlKGJpbmRpbmcpXG4gICAgICB9XG4gICAgICBjb25zdCBsb29wU2NvcGUgPSBjcmVhdGVTY29wZShzY29wZSwgc3RhdGVtZW50LmJvZHkuc3RhdGVtZW50cylcblxuICAgICAgZGVjbGFyZUJpbmRpbmcoc3RhdGVtZW50LnZhbHVlQmluZGluZy5uYW1lLCB7XG4gICAgICAgIGtub3duVmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgbXV0YWJsZTogZmFsc2UsXG4gICAgICAgIHR5cGU6IGJpbmRpbmdUeXBlXG4gICAgICB9LCByb2xlTG9jYXRpb24oc3RhdGVtZW50LnZhbHVlQmluZGluZywgXCJuYW1lXCIpLCBsb29wU2NvcGUsIGZhaWwpXG4gICAgICBjb25zdCBib2R5RmxvdyA9IHZhbGlkYXRlQmxvY2soc3RhdGVtZW50LmJvZHksIGxvb3BTY29wZSwgcmV0dXJuVHlwZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBlcnJvcnMsIGNhbGxFZmZlY3RzLCBmYWlsLFxuICAgICAgICBub3JtYWxpemVPcGVyYXRpb25zLCB7bmVhcmVzdDogc3RhdGVtZW50LCBvd25lcjogbG9vcENvbnRleHQub3duZXIsIG93bmVyczogbG9vcENvbnRleHQub3duZXJzfSlcbiAgICAgIGFkZEV4cHJlc3Npb25FZmZlY3RzKHJhaXNlcywgc3RhdGVtZW50Lmxpc3QsIGNhbGxFZmZlY3RzKVxuICAgICAgYWRkQWxsKHJhaXNlcywgYm9keUZsb3cucmFpc2VzKVxuICAgICAgZm9yIChjb25zdCBiaW5kaW5nIG9mIGFzc2lnbmVkT3V0ZXJCaW5kaW5ncykge1xuICAgICAgICBiaW5kaW5nLmtub3duVmFsdWUgPSB1bmRlZmluZWRcbiAgICAgICAgc2NvcGUucHJlc2VuY2VQcm9vZnMuZGVsZXRlKGJpbmRpbmcpXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIpIHtcbiAgICAgIGNvbnN0IG1hcFR5cGUgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoc3RhdGVtZW50Lm1hcCwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucyxcbiAgICAgICAgXCJhIG1hcCBpdGVyYXRpb24gY29sbGVjdGlvblwiKVxuXG4gICAgICBpZiAobWFwVHlwZS5raW5kICE9IFwiT3JkZXJlZE1hcFR5cGVcIikge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgTWFwIGl0ZXJhdGlvbiBjb2xsZWN0aW9uIHR5cGUgJHt0eXBlRGVzY3JpcHRpb24obWFwVHlwZSl9OyBleHBlY3RlZCBvcmRlcmVkIG1hcC5gLCBzdGF0ZW1lbnQubWFwLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKCFzdGF0ZW1lbnQua2V5QmluZGluZyB8fCBzdGF0ZW1lbnQua2V5QmluZGluZy5raW5kICE9IFwiVmFsdWVCaW5kaW5nXCIgfHxcbiAgICAgICAgIXN0YXRlbWVudC52YWx1ZUJpbmRpbmcgfHwgc3RhdGVtZW50LnZhbHVlQmluZGluZy5raW5kICE9IFwiVmFsdWVCaW5kaW5nXCIpIHtcbiAgICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJNYXAgaXRlcmF0aW9uIHJlcXVpcmVzIGV4YWN0IGtleSBhbmQgdmFsdWUgYmluZGluZ3MuXCIsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGlmIChzdGF0ZW1lbnQua2V5QmluZGluZy5tdXRhYmxlICE9PSBmYWxzZSB8fCBzdGF0ZW1lbnQudmFsdWVCaW5kaW5nLm11dGFibGUgIT09IGZhbHNlKSB7XG4gICAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiTWFwIGl0ZXJhdGlvbiBiaW5kaW5ncyBtdXN0IGJlIGltbXV0YWJsZS5cIixcbiAgICAgICAgICBzdGF0ZW1lbnQua2V5QmluZGluZy5tdXRhYmxlICE9PSBmYWxzZSA/IHN0YXRlbWVudC5rZXlCaW5kaW5nLmxvY2F0aW9uIDogc3RhdGVtZW50LnZhbHVlQmluZGluZy5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGNvbnN0IGtleVR5cGUgPSB2YWxpZGF0ZVZhbHVlVHlwZVJlZmVyZW5jZShzdGF0ZW1lbnQua2V5QmluZGluZy50eXBlLCBzdGF0ZW1lbnQua2V5QmluZGluZy5sb2NhdGlvbiwgZmFpbCxcbiAgICAgICAgdW5kZWZpbmVkLCByZWNvcmRzLCBzY29wZS50eXBlUGFyYW1ldGVycylcbiAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IHZhbGlkYXRlVmFsdWVUeXBlUmVmZXJlbmNlKHN0YXRlbWVudC52YWx1ZUJpbmRpbmcudHlwZSwgc3RhdGVtZW50LnZhbHVlQmluZGluZy5sb2NhdGlvbiwgZmFpbCxcbiAgICAgICAgdW5kZWZpbmVkLCByZWNvcmRzLCBzY29wZS50eXBlUGFyYW1ldGVycylcblxuICAgICAgaWYgKCFzYW1lVHlwZShrZXlUeXBlLCBtYXBUeXBlLmtleVR5cGUpKSB7XG4gICAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBNYXAgaXRlcmF0aW9uIGtleSBiaW5kaW5nIHR5cGUgJHt0eXBlRGVzY3JpcHRpb24oa2V5VHlwZSl9OyBleHBlY3RlZCAke3R5cGVEZXNjcmlwdGlvbihtYXBUeXBlLmtleVR5cGUpfS5gLFxuICAgICAgICAgIHR5cGVMb2NhdGlvbihzdGF0ZW1lbnQua2V5QmluZGluZy50eXBlLCBzdGF0ZW1lbnQua2V5QmluZGluZy5sb2NhdGlvbikpXG4gICAgICB9XG4gICAgICBpZiAoIXNhbWVUeXBlKHZhbHVlVHlwZSwgbWFwVHlwZS52YWx1ZVR5cGUpKSB7XG4gICAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBNYXAgaXRlcmF0aW9uIHZhbHVlIGJpbmRpbmcgdHlwZSAke3R5cGVEZXNjcmlwdGlvbih2YWx1ZVR5cGUpfTsgZXhwZWN0ZWQgJHt0eXBlRGVzY3JpcHRpb24obWFwVHlwZS52YWx1ZVR5cGUpfS5gLFxuICAgICAgICAgIHR5cGVMb2NhdGlvbihzdGF0ZW1lbnQudmFsdWVCaW5kaW5nLnR5cGUsIHN0YXRlbWVudC52YWx1ZUJpbmRpbmcubG9jYXRpb24pKVxuICAgICAgfVxuICAgICAgY29uc3QgYXNzaWduZWRPdXRlckJpbmRpbmdzID0gb3V0ZXJNdXRhYmxlQmluZGluZ3NBc3NpZ25lZEJ5KHN0YXRlbWVudC5ib2R5LCBzY29wZSlcblxuICAgICAgZm9yIChjb25zdCBiaW5kaW5nIG9mIGFzc2lnbmVkT3V0ZXJCaW5kaW5ncykge1xuICAgICAgICBiaW5kaW5nLmtub3duVmFsdWUgPSB1bmRlZmluZWRcbiAgICAgICAgc2NvcGUucHJlc2VuY2VQcm9vZnMuZGVsZXRlKGJpbmRpbmcpXG4gICAgICB9XG4gICAgICBjb25zdCBsb29wU2NvcGUgPSBjcmVhdGVTY29wZShzY29wZSwgc3RhdGVtZW50LmJvZHkuc3RhdGVtZW50cylcblxuICAgICAgZGVjbGFyZUJpbmRpbmcoc3RhdGVtZW50LmtleUJpbmRpbmcubmFtZSwge2tub3duVmFsdWU6IHVuZGVmaW5lZCwgbXV0YWJsZTogZmFsc2UsIHR5cGU6IGtleVR5cGV9LFxuICAgICAgICByb2xlTG9jYXRpb24oc3RhdGVtZW50LmtleUJpbmRpbmcsIFwibmFtZVwiKSwgbG9vcFNjb3BlLCBmYWlsKVxuICAgICAgZGVjbGFyZUJpbmRpbmcoc3RhdGVtZW50LnZhbHVlQmluZGluZy5uYW1lLCB7a25vd25WYWx1ZTogdW5kZWZpbmVkLCBtdXRhYmxlOiBmYWxzZSwgdHlwZTogdmFsdWVUeXBlfSxcbiAgICAgICAgcm9sZUxvY2F0aW9uKHN0YXRlbWVudC52YWx1ZUJpbmRpbmcsIFwibmFtZVwiKSwgbG9vcFNjb3BlLCBmYWlsKVxuICAgICAgY29uc3QgYm9keUZsb3cgPSB2YWxpZGF0ZUJsb2NrKHN0YXRlbWVudC5ib2R5LCBsb29wU2NvcGUsIHJldHVyblR5cGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZXJyb3JzLCBjYWxsRWZmZWN0cyxcbiAgICAgICAgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywge25lYXJlc3Q6IHN0YXRlbWVudCwgb3duZXI6IGxvb3BDb250ZXh0Lm93bmVyLCBvd25lcnM6IGxvb3BDb250ZXh0Lm93bmVyc30pXG5cbiAgICAgIGFkZEV4cHJlc3Npb25FZmZlY3RzKHJhaXNlcywgc3RhdGVtZW50Lm1hcCwgY2FsbEVmZmVjdHMpXG4gICAgICBhZGRBbGwocmFpc2VzLCBib2R5Rmxvdy5yYWlzZXMpXG4gICAgICBmb3IgKGNvbnN0IGJpbmRpbmcgb2YgYXNzaWduZWRPdXRlckJpbmRpbmdzKSB7XG4gICAgICAgIGJpbmRpbmcua25vd25WYWx1ZSA9IHVuZGVmaW5lZFxuICAgICAgICBzY29wZS5wcmVzZW5jZVByb29mcy5kZWxldGUoYmluZGluZylcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlJhaXNlU3RhdGVtZW50XCIpIHtcbiAgICAgIGlmICghc3RhdGVtZW50LmVycm9yIHx8IHN0YXRlbWVudC5lcnJvci5raW5kICE9IFwiRXJyb3JDb25zdHJ1Y3Rpb25cIikge1xuICAgICAgICBmYWlsKFwiTk9OX0VSUk9SX1JBSVNFXCIsIFwiUmFpc2UgcmVxdWlyZXMgb25lIGNvbnN0cnVjdGVkIHNlbWFudGljIGVycm9yLlwiLCBzdGF0ZW1lbnQubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBjb25zdCByYWlzZWRUeXBlID0gdmFsaWRhdGVFcnJvclR5cGUoc3RhdGVtZW50LmVycm9yLmVycm9yLCBzdGF0ZW1lbnQuZXJyb3IubG9jYXRpb24sIGVycm9ycywgZmFpbClcbiAgICAgIGNvbnN0IG1lc3NhZ2VUeXBlID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKFxuICAgICAgICBzdGF0ZW1lbnQuZXJyb3IubWVzc2FnZSwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgXCJhbiBlcnJvciBtZXNzYWdlXCIsIHNjYWxhclR5cGUoXCJzdHJpbmdcIilcbiAgICAgIClcblxuICAgICAgaWYgKCFpc1NjYWxhclR5cGUobWVzc2FnZVR5cGUsIFwic3RyaW5nXCIpKSB7XG4gICAgICAgIGZhaWwoXCJOT05fRVJST1JfUkFJU0VcIiwgYEVycm9yIG1lc3NhZ2UgdHlwZSAke3R5cGVEZXNjcmlwdGlvbihtZXNzYWdlVHlwZSl9OyBleHBlY3RlZCBzdHJpbmcuYCwgc3RhdGVtZW50LmVycm9yLm1lc3NhZ2UubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBhZGRFeHByZXNzaW9uRWZmZWN0cyhyYWlzZXMsIHN0YXRlbWVudC5lcnJvci5tZXNzYWdlLCBjYWxsRWZmZWN0cylcbiAgICAgIHJhaXNlcy5hZGQocmFpc2VkVHlwZS5kZWNsYXJhdGlvbklkKVxuICAgICAgbm9ybWFsID0gZmFsc2VcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlRyeVN0YXRlbWVudFwiKSB7XG4gICAgICBjb25zdCBjYXVnaHRUeXBlID0gdmFsaWRhdGVFcnJvclR5cGUoc3RhdGVtZW50LmNhdGNoVHlwZSwgc3RhdGVtZW50LmxvY2F0aW9uLCBlcnJvcnMsIGZhaWwpXG5cbiAgICAgIGlmICghc3RhdGVtZW50LmNhdGNoQmluZGluZyB8fCBzdGF0ZW1lbnQuY2F0Y2hCaW5kaW5nLmtpbmQgIT0gXCJDYXRjaEJpbmRpbmdcIiB8fCBzdGF0ZW1lbnQuY2F0Y2hCaW5kaW5nLm11dGFibGUgIT09IGZhbHNlKSB7XG4gICAgICAgIGZhaWwoXCJJTlZBTElEX0VSUk9SX0hBTkRMRVJcIiwgXCJDYXRjaCByZXF1aXJlcyBvbmUgaW1tdXRhYmxlIHR5cGVkIGJpbmRpbmcuXCIsIHN0YXRlbWVudC5jYXRjaEJpbmRpbmc/LmxvY2F0aW9uID8/IHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJpbmRpbmdUeXBlID0gdmFsaWRhdGVFcnJvclR5cGUoc3RhdGVtZW50LmNhdGNoQmluZGluZy50eXBlLCBzdGF0ZW1lbnQuY2F0Y2hCaW5kaW5nLmxvY2F0aW9uLCBlcnJvcnMsIGZhaWwpXG5cbiAgICAgIGlmIChiaW5kaW5nVHlwZS5kZWNsYXJhdGlvbklkICE9IGNhdWdodFR5cGUuZGVjbGFyYXRpb25JZCkge1xuICAgICAgICBmYWlsKFwiSU5WQUxJRF9FUlJPUl9IQU5ETEVSXCIsIFwiQ2F0Y2ggYmluZGluZyB0eXBlIG11c3QgZXhhY3RseSBtYXRjaCBpdHMgaGFuZGxlciB0eXBlLlwiLCBzdGF0ZW1lbnQuY2F0Y2hCaW5kaW5nLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY29uc3QgYm9keUFzc2lnbmVkT3V0ZXJCaW5kaW5ncyA9IG91dGVyTXV0YWJsZUJpbmRpbmdzQXNzaWduZWRCeShzdGF0ZW1lbnQuYm9keSwgc2NvcGUpXG4gICAgICBjb25zdCBhc3NpZ25lZE91dGVyQmluZGluZ3MgPSBuZXcgU2V0KGJvZHlBc3NpZ25lZE91dGVyQmluZGluZ3MpXG5cbiAgICAgIG91dGVyTXV0YWJsZUJpbmRpbmdzQXNzaWduZWRCeShzdGF0ZW1lbnQuY2F0Y2hCb2R5LCBzY29wZSwgYXNzaWduZWRPdXRlckJpbmRpbmdzKVxuICAgICAgY29uc3QgYm9keVNjb3BlID0gY3JlYXRlU2NvcGUoc2NvcGUsIHN0YXRlbWVudC5ib2R5LnN0YXRlbWVudHMpXG4gICAgICBjb25zdCBib2R5RmxvdyA9IHZhbGlkYXRlQmxvY2soc3RhdGVtZW50LmJvZHksIGJvZHlTY29wZSwgcmV0dXJuVHlwZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBlcnJvcnMsIGNhbGxFZmZlY3RzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCBsb29wQ29udGV4dClcbiAgICAgIGNvbnN0IGNhdGNoU2NvcGUgPSBjcmVhdGVTY29wZShzY29wZSwgc3RhdGVtZW50LmNhdGNoQm9keS5zdGF0ZW1lbnRzKVxuXG4gICAgICBmb3IgKGNvbnN0IGJpbmRpbmcgb2YgYm9keUFzc2lnbmVkT3V0ZXJCaW5kaW5ncykge1xuICAgICAgICBiaW5kaW5nLmtub3duVmFsdWUgPSB1bmRlZmluZWRcbiAgICAgICAgY2F0Y2hTY29wZS5wcmVzZW5jZVByb29mcy5kZWxldGUoYmluZGluZylcbiAgICAgIH1cblxuICAgICAgZGVjbGFyZUJpbmRpbmcoc3RhdGVtZW50LmNhdGNoQmluZGluZy5uYW1lLCB7XG4gICAgICAgIGtub3duVmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgbXV0YWJsZTogZmFsc2UsXG4gICAgICAgIHR5cGU6IGJpbmRpbmdUeXBlXG4gICAgICB9LCByb2xlTG9jYXRpb24oc3RhdGVtZW50LmNhdGNoQmluZGluZywgXCJuYW1lXCIpLCBjYXRjaFNjb3BlLCBmYWlsKVxuICAgICAgY29uc3QgY2F0Y2hGbG93ID0gdmFsaWRhdGVCbG9jayhzdGF0ZW1lbnQuY2F0Y2hCb2R5LCBjYXRjaFNjb3BlLCByZXR1cm5UeXBlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGVycm9ycywgY2FsbEVmZmVjdHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIGxvb3BDb250ZXh0KVxuXG4gICAgICBpZiAoIWJvZHlGbG93LnJhaXNlcy5oYXMoY2F1Z2h0VHlwZS5kZWNsYXJhdGlvbklkKSkge1xuICAgICAgICBmYWlsKFwiVU5SRUFDSEFCTEVfSEFORExFUlwiLCBgSGFuZGxlciBmb3IgJyR7ZXJyb3JzLmdldChjYXVnaHRUeXBlLmRlY2xhcmF0aW9uSWQpPy5uYW1lfScgY2Fubm90IGJlIHJlYWNoZWQuYCwgdHlwZUxvY2F0aW9uKHN0YXRlbWVudC5jYXRjaFR5cGUsIHN0YXRlbWVudC5sb2NhdGlvbikpXG4gICAgICB9XG4gICAgICBib2R5Rmxvdy5yYWlzZXMuZGVsZXRlKGNhdWdodFR5cGUuZGVjbGFyYXRpb25JZClcbiAgICAgIGFkZEFsbChyYWlzZXMsIGJvZHlGbG93LnJhaXNlcylcbiAgICAgIGFkZEFsbChyYWlzZXMsIGNhdGNoRmxvdy5yYWlzZXMpXG4gICAgICBub3JtYWwgPSBib2R5Rmxvdy5ub3JtYWwgfHwgY2F0Y2hGbG93Lm5vcm1hbFxuICAgICAgZm9yIChjb25zdCBiaW5kaW5nIG9mIGFzc2lnbmVkT3V0ZXJCaW5kaW5ncykge1xuICAgICAgICBiaW5kaW5nLmtub3duVmFsdWUgPSB1bmRlZmluZWRcbiAgICAgICAgc2NvcGUucHJlc2VuY2VQcm9vZnMuZGVsZXRlKGJpbmRpbmcpXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGNvbnN0IHVuZXhwZWN0ZWQgPSAvKiogQHR5cGUge3traW5kOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufX0gKi8gKHN0YXRlbWVudClcblxuICAgIGZhaWwoXCJVTlNVUFBPUlRFRF9TVEFURU1FTlRcIiwgdW5leHBlY3RlZC5raW5kLCB1bmV4cGVjdGVkLmxvY2F0aW9uKVxuICB9XG5cbiAgcmV0dXJuIHtub3JtYWwsIHJhaXNlc31cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgb25lIGV4YWN0IG5vbWluYWwgZXJyb3IgdHlwZS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdHlwZSAtIENhbmRpZGF0ZSB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIE93bmluZyBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7RXJyb3JSZWdpc3RyeX0gZXJyb3JzIC0gVmlzaWJsZSBlcnJvciBkZWNsYXJhdGlvbnMuXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FcnJvclR5cGV9IFZhbGlkYXRlZCB0eXBlLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUVycm9yVHlwZSh0eXBlLCBsb2NhdGlvbiwgZXJyb3JzLCBmYWlsKSB7XG4gIGlmICghdHlwZSB8fCB0eXBlb2YgdHlwZSAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkodHlwZSkpIHtcbiAgICByZXR1cm4gZmFpbChcIlVOS05PV05fRVJST1JcIiwgXCJIYW5kbGVyIG9yIHJhaXNlIGlzIG1pc3NpbmcgYW4gZXhhY3QgZXJyb3IgdHlwZS5cIiwgbG9jYXRpb24pXG4gIH1cbiAgY29uc3QgY2FuZGlkYXRlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkVycm9yVHlwZX0gKi8gKHR5cGUpXG5cbiAgaWYgKGNhbmRpZGF0ZS5raW5kICE9IFwiRXJyb3JUeXBlXCIgfHxcbiAgICBPYmplY3Qua2V5cyhjYW5kaWRhdGUpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKSAhPSBcImRlY2xhcmF0aW9uSWQsa2luZFwiIHx8XG4gICAgdHlwZW9mIGNhbmRpZGF0ZS5kZWNsYXJhdGlvbklkICE9IFwic3RyaW5nXCIgfHwgIWVycm9ycy5oYXMoY2FuZGlkYXRlLmRlY2xhcmF0aW9uSWQpKSB7XG4gICAgZmFpbChcIlVOS05PV05fRVJST1JcIiwgYFVua25vd24gZXJyb3IgZGVjbGFyYXRpb24gJyR7U3RyaW5nKGNhbmRpZGF0ZS5kZWNsYXJhdGlvbklkKX0nLmAsIHR5cGVMb2NhdGlvbihjYW5kaWRhdGUsIGxvY2F0aW9uKSlcbiAgfVxuXG4gIHJldHVybiBjYW5kaWRhdGVcbn1cblxuLyoqXG4gKiBBZGRzIGV2ZXJ5IHNvdXJjZSB2YWx1ZSB0byBvbmUgc2V0LlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gdGFyZ2V0IC0gRGVzdGluYXRpb24gaWRlbnRpdGllcy5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IHNvdXJjZSAtIFNvdXJjZSBpZGVudGl0aWVzLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIGFkZEFsbCh0YXJnZXQsIHNvdXJjZSkge1xuICBmb3IgKGNvbnN0IHZhbHVlIG9mIHNvdXJjZSkgdGFyZ2V0LmFkZCh2YWx1ZSlcbn1cblxuLyoqXG4gKiBBZGRzIHVuY2hlY2tlZCBlcnJvcnMgcmFpc2VkIHdoaWxlIGV2YWx1YXRpbmcgb25lIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSB0YXJnZXQgLSBEZXN0aW5hdGlvbiBpZGVudGl0aWVzLlxuICogQHBhcmFtIHt1bmtub3dufSBleHByZXNzaW9uIC0gQ2FuZGlkYXRlIHNlbWFudGljIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn0gY2FsbEVmZmVjdHMgLSBJbmZlcnJlZCBjYWxsIGVmZmVjdHMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn0gW21ldGhvZEVmZmVjdHNdIC0gSW5mZXJyZWQgZWZmZWN0cyBieSByZXNvbHZlZCBtZXRob2QgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gYWRkRXhwcmVzc2lvbkVmZmVjdHModGFyZ2V0LCBleHByZXNzaW9uLCBjYWxsRWZmZWN0cywgbWV0aG9kRWZmZWN0cyA9IG5ldyBNYXAoKSkge1xuICBjb25zdCBwZW5kaW5nID0gW2V4cHJlc3Npb25dXG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0KClcblxuICB3aGlsZSAocGVuZGluZy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgdmFsdWUgPSBwZW5kaW5nLnBvcCgpXG5cbiAgICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKHZhbHVlKSkgY29udGludWVcbiAgICBzZWVuLmFkZCh2YWx1ZSlcbiAgICBpZiAoUmVmbGVjdC5nZXQodmFsdWUsIFwia2luZFwiKSA9PSBcIkNhbGxFeHByZXNzaW9uXCIpIGFkZEFsbCh0YXJnZXQsIGNhbGxFZmZlY3RzLmdldChSZWZsZWN0LmdldCh2YWx1ZSwgXCJjYWxsZWVcIikpID8/IG5ldyBTZXQoKSlcbiAgICBpZiAoUmVmbGVjdC5nZXQodmFsdWUsIFwia2luZFwiKSA9PSBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCIgfHwgUmVmbGVjdC5nZXQodmFsdWUsIFwia2luZFwiKSA9PSBcIlJlZmVyZW5jZUNvbnN0cnVjdGlvblwiKSB7XG4gICAgICBjb25zdCBmYWlsdXJlcyA9IFJlZmxlY3QuZ2V0KHZhbHVlLCBcImZhaWx1cmVJZHNcIilcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGZhaWx1cmVzKSkgZm9yIChjb25zdCBmYWlsdXJlIG9mIGZhaWx1cmVzKSBpZiAodHlwZW9mIGZhaWx1cmUgPT0gXCJzdHJpbmdcIikgdGFyZ2V0LmFkZChmYWlsdXJlKVxuICAgICAgaWYgKFJlZmxlY3QuZ2V0KHZhbHVlLCBcImtpbmRcIikgPT0gXCJNZXRob2RDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgICAgIGFkZEFsbCh0YXJnZXQsIG1ldGhvZEVmZmVjdHMuZ2V0KFJlZmxlY3QuZ2V0KHZhbHVlLCBcIm1ldGhvZFwiKSkgPz8gbmV3IFNldCgpKVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoUmVmbGVjdC5nZXQodmFsdWUsIFwia2luZFwiKSA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IHJlc29sdXRpb24gPSBSZWZsZWN0LmdldCh2YWx1ZSwgXCJyZXNvbHV0aW9uXCIpXG4gICAgICBjb25zdCBmYWlsdXJlcyA9IHJlc29sdXRpb24gJiYgdHlwZW9mIHJlc29sdXRpb24gPT0gXCJvYmplY3RcIiA/IFJlZmxlY3QuZ2V0KHJlc29sdXRpb24sIFwiZmFpbHVyZUlkc1wiKSA6IHVuZGVmaW5lZFxuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShmYWlsdXJlcykpIGZvciAoY29uc3QgZmFpbHVyZSBvZiBmYWlsdXJlcykgaWYgKHR5cGVvZiBmYWlsdXJlID09IFwic3RyaW5nXCIpIHRhcmdldC5hZGQoZmFpbHVyZSlcbiAgICB9XG4gICAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG4gICAgICBpZiAoW1wibG9jYXRpb25cIiwgXCJzb3VyY2VQcm92ZW5hbmNlXCIsIFwicmVzb2x1dGlvblwiXS5pbmNsdWRlcyhrZXkpKSBjb250aW51ZVxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGQpKSBwZW5kaW5nLnB1c2goLi4uY2hpbGQpXG4gICAgICBlbHNlIGlmIChjaGlsZCAmJiB0eXBlb2YgY2hpbGQgPT0gXCJvYmplY3RcIikgcGVuZGluZy5wdXNoKGNoaWxkKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIERlcml2ZXMgdW5jaGVja2VkLWVycm9yIHByb3BhZ2F0aW9uIG92ZXIgdGhlIHJlc29sdmVkIGZpbml0ZSBmdW5jdGlvbiBncmFwaC5cbiAqIFRoaXMgaXMgdmFsaWRhdG9yIHN0YXRlLCBuZXZlciBhIGNoZWNrZWQgZWZmZWN0IGluIHRoZSBwdWJsaWMgZnVuY3Rpb24gc2lnbmF0dXJlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb24+fSBmdW5jdGlvbnMgLSBSZXNvbHZlZCBmdW5jdGlvbnMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn0gW3NlZWRFZmZlY3RzXSAtIERlcGVuZGVuY3kgZWZmZWN0cyBrZXllZCBieSBsb2NhbCBpbXBvcnQgbmFtZS5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IFtsb2NhbEZ1bmN0aW9uTmFtZXNdIC0gRnVuY3Rpb25zIHdob3NlIGJvZGllcyBiZWxvbmcgdG8gdGhlIGN1cnJlbnQgbW9kdWxlLlxuICogQHJldHVybnMge01hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn0gRXNjYXBpbmcgZXJyb3IgaWRlbnRpdGllcyBieSBzb3VyY2UtdmlzaWJsZSBmdW5jdGlvbiBuYW1lLlxuICovXG5mdW5jdGlvbiBpbmZlckNhbGxFZmZlY3RzKGZ1bmN0aW9ucywgc2VlZEVmZmVjdHMgPSBuZXcgTWFwKCksIGxvY2FsRnVuY3Rpb25OYW1lcyA9IG5ldyBTZXQoZnVuY3Rpb25zLmtleXMoKSkpIHtcbiAgY29uc3QgZWZmZWN0cyA9IG5ldyBNYXAoWy4uLmZ1bmN0aW9ucy5rZXlzKCldLm1hcCgobmFtZSkgPT4gW25hbWUsIG5ldyBTZXQoc2VlZEVmZmVjdHMuZ2V0KG5hbWUpID8/IFtdKV0pKVxuICBsZXQgY2hhbmdlZCA9IHRydWVcblxuICB3aGlsZSAoY2hhbmdlZCkge1xuICAgIGNoYW5nZWQgPSBmYWxzZVxuICAgIGZvciAoY29uc3QgbmFtZSBvZiBsb2NhbEZ1bmN0aW9uTmFtZXMpIHtcbiAgICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gZnVuY3Rpb25zLmdldChuYW1lKVxuXG4gICAgICBpZiAoIWRlY2xhcmF0aW9uKSBjb250aW51ZVxuICAgICAgY29uc3QgbmV4dCA9IHN5bnRhY3RpY0Jsb2NrRWZmZWN0cyhkZWNsYXJhdGlvbi5ib2R5LCBlZmZlY3RzKVxuICAgICAgY29uc3QgY3VycmVudCA9IC8qKiBAdHlwZSB7U2V0PHN0cmluZz59ICovIChlZmZlY3RzLmdldChuYW1lKSlcblxuICAgICAgZm9yIChjb25zdCBlcnJvciBvZiBuZXh0KSB7XG4gICAgICAgIGlmICghY3VycmVudC5oYXMoZXJyb3IpKSB7XG4gICAgICAgICAgY3VycmVudC5hZGQoZXJyb3IpXG4gICAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlZmZlY3RzXG59XG5cbi8qKlxuICogQ29tcHV0ZXMgZXNjYXBpbmcgaWRlbnRpdGllcyBmcm9tIG9uZSBibG9jayBmb3IgdGhlIGNhbGwtZWZmZWN0IGZpeGVkIHBvaW50LlxuICogQHBhcmFtIHt1bmtub3dufSBibG9jayAtIENhbmRpZGF0ZSBibG9jay5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgU2V0PHN0cmluZz4+fSBjYWxsRWZmZWN0cyAtIEN1cnJlbnQgZml4ZWQtcG9pbnQgc3RhdGUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn0gW21ldGhvZEVmZmVjdHNdIC0gQ3VycmVudCBtZXRob2QgZml4ZWQtcG9pbnQgc3RhdGUuXG4gKiBAcmV0dXJucyB7U2V0PHN0cmluZz59IEVzY2FwaW5nIGlkZW50aXRpZXMuXG4gKi9cbmZ1bmN0aW9uIHN5bnRhY3RpY0Jsb2NrRWZmZWN0cyhibG9jaywgY2FsbEVmZmVjdHMsIG1ldGhvZEVmZmVjdHMgPSBuZXcgTWFwKCkpIHtcbiAgY29uc3QgcmVzdWx0ID0gbmV3IFNldCgpXG4gIGNvbnN0IHN0YXRlbWVudHMgPSBSZWZsZWN0LmdldCgvKiogQHR5cGUge29iamVjdH0gKi8gKGJsb2NrID8/IHt9KSwgXCJzdGF0ZW1lbnRzXCIpXG5cbiAgaWYgKCFBcnJheS5pc0FycmF5KHN0YXRlbWVudHMpKSByZXR1cm4gcmVzdWx0XG4gIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIHN0YXRlbWVudHMpIHtcbiAgICBpZiAoIXN0YXRlbWVudCB8fCB0eXBlb2Ygc3RhdGVtZW50ICE9IFwib2JqZWN0XCIpIGNvbnRpbnVlXG4gICAgY29uc3Qga2luZCA9IFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJraW5kXCIpXG5cbiAgICBpZiAoa2luZCA9PSBcIlJhaXNlU3RhdGVtZW50XCIpIHtcbiAgICAgIGNvbnN0IGNvbnN0cnVjdGlvbiA9IFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJlcnJvclwiKVxuICAgICAgY29uc3QgdHlwZSA9IGNvbnN0cnVjdGlvbiAmJiB0eXBlb2YgY29uc3RydWN0aW9uID09IFwib2JqZWN0XCIgPyBSZWZsZWN0LmdldChjb25zdHJ1Y3Rpb24sIFwiZXJyb3JcIikgOiB1bmRlZmluZWRcbiAgICAgIGNvbnN0IGRlY2xhcmF0aW9uSWQgPSB0eXBlICYmIHR5cGVvZiB0eXBlID09IFwib2JqZWN0XCIgPyBSZWZsZWN0LmdldCh0eXBlLCBcImRlY2xhcmF0aW9uSWRcIikgOiB1bmRlZmluZWRcblxuICAgICAgaWYgKHR5cGVvZiBkZWNsYXJhdGlvbklkID09IFwic3RyaW5nXCIpIHJlc3VsdC5hZGQoZGVjbGFyYXRpb25JZClcbiAgICAgIGlmIChjb25zdHJ1Y3Rpb24gJiYgdHlwZW9mIGNvbnN0cnVjdGlvbiA9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIGFkZEV4cHJlc3Npb25FZmZlY3RzKHJlc3VsdCwgUmVmbGVjdC5nZXQoY29uc3RydWN0aW9uLCBcIm1lc3NhZ2VcIiksIGNhbGxFZmZlY3RzLCBtZXRob2RFZmZlY3RzKVxuICAgICAgfVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgaWYgKGtpbmQgPT0gXCJUcnlTdGF0ZW1lbnRcIikge1xuICAgICAgY29uc3QgYm9keUVmZmVjdHMgPSBzeW50YWN0aWNCbG9ja0VmZmVjdHMoUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImJvZHlcIiksIGNhbGxFZmZlY3RzLCBtZXRob2RFZmZlY3RzKVxuICAgICAgY29uc3QgY2F0Y2hUeXBlID0gUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImNhdGNoVHlwZVwiKVxuICAgICAgY29uc3QgY2F1Z2h0SWQgPSBjYXRjaFR5cGUgJiYgdHlwZW9mIGNhdGNoVHlwZSA9PSBcIm9iamVjdFwiID8gUmVmbGVjdC5nZXQoY2F0Y2hUeXBlLCBcImRlY2xhcmF0aW9uSWRcIikgOiB1bmRlZmluZWRcblxuICAgICAgaWYgKHR5cGVvZiBjYXVnaHRJZCA9PSBcInN0cmluZ1wiICYmIGJvZHlFZmZlY3RzLmRlbGV0ZShjYXVnaHRJZCkpIHtcbiAgICAgICAgYWRkQWxsKGJvZHlFZmZlY3RzLCBzeW50YWN0aWNCbG9ja0VmZmVjdHMoUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImNhdGNoQm9keVwiKSwgY2FsbEVmZmVjdHMsIG1ldGhvZEVmZmVjdHMpKVxuICAgICAgfVxuICAgICAgYWRkQWxsKHJlc3VsdCwgYm9keUVmZmVjdHMpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoa2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgIGFkZEV4cHJlc3Npb25FZmZlY3RzKHJlc3VsdCwgUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImNvbmRpdGlvblwiKSwgY2FsbEVmZmVjdHMsIG1ldGhvZEVmZmVjdHMpXG4gICAgICBhZGRBbGwocmVzdWx0LCBzeW50YWN0aWNCbG9ja0VmZmVjdHMoUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImNvbnNlcXVlbnRcIiksIGNhbGxFZmZlY3RzLCBtZXRob2RFZmZlY3RzKSlcbiAgICAgIGFkZEFsbChyZXN1bHQsIHN5bnRhY3RpY0Jsb2NrRWZmZWN0cyhSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiYWx0ZXJuYXRlXCIpLCBjYWxsRWZmZWN0cywgbWV0aG9kRWZmZWN0cykpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoa2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIiB8fCBraW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiKSB7XG4gICAgICBhZGRFeHByZXNzaW9uRWZmZWN0cyhyZXN1bHQsIFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwga2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIiA/IFwibGlzdFwiIDogXCJtYXBcIiksIGNhbGxFZmZlY3RzLFxuICAgICAgICBtZXRob2RFZmZlY3RzKVxuICAgICAgYWRkQWxsKHJlc3VsdCwgc3ludGFjdGljQmxvY2tFZmZlY3RzKFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJib2R5XCIpLCBjYWxsRWZmZWN0cywgbWV0aG9kRWZmZWN0cykpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoa2luZCA9PSBcIldoaWxlU3RhdGVtZW50XCIpIHtcbiAgICAgIGFkZEV4cHJlc3Npb25FZmZlY3RzKHJlc3VsdCwgUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImNvbmRpdGlvblwiKSwgY2FsbEVmZmVjdHMsIG1ldGhvZEVmZmVjdHMpXG4gICAgICBhZGRBbGwocmVzdWx0LCBzeW50YWN0aWNCbG9ja0VmZmVjdHMoUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImJvZHlcIiksIGNhbGxFZmZlY3RzLCBtZXRob2RFZmZlY3RzKSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IG9mIFtcImV4cHJlc3Npb25cIiwgXCJpbml0aWFsaXplclwiXSkge1xuICAgICAgYWRkRXhwcmVzc2lvbkVmZmVjdHMocmVzdWx0LCBSZWZsZWN0LmdldChzdGF0ZW1lbnQsIGtleSksIGNhbGxFZmZlY3RzLCBtZXRob2RFZmZlY3RzKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHRcbn1cblxuLyoqXG4gKiBEZXJpdmVzIHRoZSBlc2NhcGluZyB1c2VyLWRlZmluZWQgZXJyb3Igc2V0cyBmb3IgbG9jYWwgZnVuY3Rpb25zIGFuZCByZXNvbHZlZCBjbGFzcyBtZXRob2RzLlxuICogVGhlIGZpeGVkIHBvaW50IGlzIGNvbXB1dGVkIG92ZXIgZXZlcnkgdW5jaGVja2VkIGVycm9yOyBjYXBhYmlsaXR5IGZhaWx1cmVzIGFyZSBwcm9qZWN0ZWQgb3V0XG4gKiBiZWNhdXNlIGNhbGwgc2l0ZXMgYWxyZWFkeSBjYXJyeSB0aGVpciBjYXBhYmlsaXR5LWZhaWx1cmUgYm91bmRhcnkgdGhyb3VnaCByZXNvbHV0aW9uIG1ldGFkYXRhLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBSZXNvbHZlZCBtb2R1bGUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn0gW3NlZWRFZmZlY3RzXSAtIERlcGVuZGVuY3kgZWZmZWN0cyBrZXllZCBieSBsb2NhbCBpbXBvcnQgbmFtZS5cbiAqIEByZXR1cm5zIHt7ZnVuY3Rpb25zOiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj4sIG1ldGhvZHM6IE1hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn19IEVzY2FwaW5nIHVzZXItZGVmaW5lZCBlcnJvciBpZGVudGl0aWVzIGJ5IGZ1bmN0aW9uIG5hbWUgYW5kIG1ldGhvZCBpZGVudGl0eS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluZmVyRXNjYXBpbmdFcnJvckVmZmVjdHMobW9kdWxlLCBzZWVkRWZmZWN0cyA9IG5ldyBNYXAoKSkge1xuICBjb25zdCBmdW5jdGlvbnMgPSBuZXcgTWFwKG1vZHVsZS5mdW5jdGlvbnMubWFwKChkZWNsYXJhdGlvbikgPT4gW2RlY2xhcmF0aW9uLm5hbWUsIGRlY2xhcmF0aW9uXSkpXG4gIGNvbnN0IGZ1bmN0aW9uRWZmZWN0cyA9IG5ldyBNYXAoWy4uLmZ1bmN0aW9ucy5rZXlzKCldLm1hcCgobmFtZSkgPT4gW25hbWUsIG5ldyBTZXQoc2VlZEVmZmVjdHMuZ2V0KG5hbWUpID8/IFtdKV0pKVxuICBjb25zdCBjbGFzc2VzID0gbW9kdWxlLmNsYXNzZXMgPz8gW11cbiAgY29uc3QgbWV0aG9kRWZmZWN0cyA9IG5ldyBNYXAoKVxuICBjb25zdCBjYXBhYmlsaXR5RmFpbHVyZUlkcyA9IG5ldyBTZXQoKG1vZHVsZS5jYXBhYmlsaXRpZXMgPz8gW10pLmZsYXRNYXAoKHtmYWlsdXJlc30pID0+IGZhaWx1cmVzKS5tYXAoKHtpZH0pID0+IGlkKSlcblxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIGNsYXNzZXMpIGZvciAoY29uc3QgbWV0aG9kIG9mIGRlY2xhcmF0aW9uLm1ldGhvZHMpIG1ldGhvZEVmZmVjdHMuc2V0KG1ldGhvZC5pZCwgbmV3IFNldCgpKVxuICBsZXQgY2hhbmdlZCA9IHRydWVcblxuICB3aGlsZSAoY2hhbmdlZCkge1xuICAgIGNoYW5nZWQgPSBmYWxzZVxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykge1xuICAgICAgY29uc3QgY3VycmVudCA9IC8qKiBAdHlwZSB7U2V0PHN0cmluZz59ICovIChmdW5jdGlvbkVmZmVjdHMuZ2V0KGRlY2xhcmF0aW9uLm5hbWUpKVxuICAgICAgZm9yIChjb25zdCBlcnJvciBvZiBzeW50YWN0aWNCbG9ja0VmZmVjdHMoZGVjbGFyYXRpb24uYm9keSwgZnVuY3Rpb25FZmZlY3RzLCBtZXRob2RFZmZlY3RzKSkge1xuICAgICAgICBpZiAoIWN1cnJlbnQuaGFzKGVycm9yKSkgeyBjdXJyZW50LmFkZChlcnJvcik7IGNoYW5nZWQgPSB0cnVlIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBjbGFzc2VzKSB7XG4gICAgICBmb3IgKGNvbnN0IG1ldGhvZCBvZiBkZWNsYXJhdGlvbi5tZXRob2RzKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSAvKiogQHR5cGUge1NldDxzdHJpbmc+fSAqLyAobWV0aG9kRWZmZWN0cy5nZXQobWV0aG9kLmlkKSlcbiAgICAgICAgZm9yIChjb25zdCBlcnJvciBvZiBzeW50YWN0aWNCbG9ja0VmZmVjdHMobWV0aG9kLmJvZHksIGZ1bmN0aW9uRWZmZWN0cywgbWV0aG9kRWZmZWN0cykpIHtcbiAgICAgICAgICBpZiAoIWN1cnJlbnQuaGFzKGVycm9yKSkgeyBjdXJyZW50LmFkZChlcnJvcik7IGNoYW5nZWQgPSB0cnVlIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgZWZmZWN0cyBvZiBbZnVuY3Rpb25FZmZlY3RzLCBtZXRob2RFZmZlY3RzXSkge1xuICAgIGZvciAoY29uc3QgZXJyb3JzIG9mIGVmZmVjdHMudmFsdWVzKCkpIHtcbiAgICAgIGZvciAoY29uc3QgZXJyb3Igb2YgWy4uLmVycm9yc10pIGlmIChjYXBhYmlsaXR5RmFpbHVyZUlkcy5oYXMoZXJyb3IpKSBlcnJvcnMuZGVsZXRlKGVycm9yKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7ZnVuY3Rpb25zOiBmdW5jdGlvbkVmZmVjdHMsIG1ldGhvZHM6IG1ldGhvZEVmZmVjdHN9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGxleGljYWwgc2NvcGUgd2l0aCBkZWNsYXJhdGlvbnMgbWFya2VkIHBlbmRpbmcgdW50aWwgdmlzaXRlZC5cbiAqIEBwYXJhbSB7U2NvcGUgfCB1bmRlZmluZWR9IHBhcmVudCAtIEVuY2xvc2luZyBzY29wZS5cbiAqIEBwYXJhbSB7e2tpbmQ6IHN0cmluZywgbmFtZT86IHN0cmluZ31bXX0gc3RhdGVtZW50cyAtIFNjb3BlIHN0YXRlbWVudHMuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSBbcmVzZXJ2ZWROYW1lc10gLSBOYW1lcyB1bmF2YWlsYWJsZSB0byByb290IGJpbmRpbmdzLlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gW3R5cGVQYXJhbWV0ZXJzXSAtIERlY2xhcmF0aW9uLXNjb3BlZCB0eXBlIHBhcmFtZXRlcnMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbn0gW2N1cnJlbnRDbGFzc10gLSBEZWNsYXJpbmcgY2xhc3MgZm9yIHJlY2VpdmVyLXByaXZhdGUgYWNjZXNzLlxuICogQHJldHVybnMge1Njb3BlfSBTY29wZS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlU2NvcGUocGFyZW50LCBzdGF0ZW1lbnRzLCByZXNlcnZlZE5hbWVzID0gbmV3IFNldCgpLCB0eXBlUGFyYW1ldGVycyA9IHBhcmVudD8udHlwZVBhcmFtZXRlcnMgPz8gbmV3IFNldCgpLFxuICBjdXJyZW50Q2xhc3MgPSBwYXJlbnQ/LmN1cnJlbnRDbGFzcykge1xuICBjb25zdCBwZW5kaW5nID0gbmV3IFNldChzdGF0ZW1lbnRzLmZpbHRlcigoc3RhdGVtZW50KSA9PiBzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIilcbiAgICAubWFwKChzdGF0ZW1lbnQpID0+IC8qKiBAdHlwZSB7e25hbWU6IHN0cmluZ319ICovIChzdGF0ZW1lbnQpLm5hbWUpKVxuXG4gIHJldHVybiB7XG4gICAgYmluZGluZ3M6IG5ldyBNYXAoKSxcbiAgICBjdXJyZW50Q2xhc3MsXG4gICAgcGFyZW50LFxuICAgIHBlbmRpbmcsXG4gICAgcHJlc2VuY2VQcm9vZnM6IG5ldyBTZXQocGFyZW50Py5wcmVzZW5jZVByb29mcyA/PyBbXSksXG4gICAgdHlwZVBhcmFtZXRlcnMsXG4gICAgdXNlZE5hbWVzOiBwYXJlbnQ/LnVzZWROYW1lcyA/PyBuZXcgU2V0KHJlc2VydmVkTmFtZXMpXG4gIH1cbn1cblxuLyoqXG4gKiBBcHBsaWVzIGEgc2ltcGxlLWlkZW50aWZpZXIgcHJlc2VuY2UgcHJvb2YgdG8gZXhhY3RseSB0aGUgYnJhbmNoIHdoZXJlIHRoZSB0ZXN0IGlzIHRydWUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gY29uZGl0aW9uIC0gVmFsaWRhdGVkIGJyYW5jaCBjb25kaXRpb24uXG4gKiBAcGFyYW0ge1Njb3BlfSBzb3VyY2VTY29wZSAtIFNjb3BlIGNvbnRhaW5pbmcgdGhlIHRlc3RlZCBiaW5kaW5nLlxuICogQHBhcmFtIHtTY29wZX0gYnJhbmNoU2NvcGUgLSBCcmFuY2gtbG9jYWwgcHJvb2Ygc2NvcGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGJyYW5jaFdoZW5UcnVlIC0gV2hldGhlciB0aGlzIGlzIHRoZSBjb25kaXRpb24ncyB0cnVlIGJyYW5jaC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBhcHBseVByZXNlbmNlTmFycm93aW5nKGNvbmRpdGlvbiwgc291cmNlU2NvcGUsIGJyYW5jaFNjb3BlLCBicmFuY2hXaGVuVHJ1ZSkge1xuICBsZXQgdGVzdCA9IGNvbmRpdGlvblxuICBsZXQgcHJlc2VudFdoZW5UcnVlID0gdHJ1ZVxuXG4gIGlmIChjb25kaXRpb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiICYmIGNvbmRpdGlvbi5vcGVyYXRpb24gPT0gXCJCb29sZWFuTm90XCIgJiZcbiAgICBjb25kaXRpb24ub3BlcmFuZC5raW5kID09IFwiT3B0aW9uYWxJc1ByZXNlbnRcIikge1xuICAgIHRlc3QgPSBjb25kaXRpb24ub3BlcmFuZFxuICAgIHByZXNlbnRXaGVuVHJ1ZSA9IGZhbHNlXG4gIH1cbiAgaWYgKHRlc3Qua2luZCAhPSBcIk9wdGlvbmFsSXNQcmVzZW50XCIpIHJldHVyblxuICBjb25zdCBiaW5kaW5nID0gZmluZEJpbmRpbmcodGVzdC5vcGVyYW5kLm5hbWUsIHNvdXJjZVNjb3BlKVxuXG4gIGlmICghYmluZGluZykgcmV0dXJuXG4gIGlmIChicmFuY2hXaGVuVHJ1ZSA9PSBwcmVzZW50V2hlblRydWUpIGJyYW5jaFNjb3BlLnByZXNlbmNlUHJvb2ZzLmFkZChiaW5kaW5nKVxuICBlbHNlIGJyYW5jaFNjb3BlLnByZXNlbmNlUHJvb2ZzLmRlbGV0ZShiaW5kaW5nKVxufVxuXG4vKipcbiAqIEFkZHMgb25lIGJpbmRpbmcgd2hpbGUgcmVqZWN0aW5nIGR1cGxpY2F0ZXMgYW5kIHNoYWRvd2luZy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gQmluZGluZyBuYW1lLlxuICogQHBhcmFtIHtCaW5kaW5nfSBiaW5kaW5nIC0gQmluZGluZyBtZXRhZGF0YS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbG9jYXRpb24gLSBEZWNsYXJhdGlvbiBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7U2NvcGV9IHNjb3BlIC0gQ3VycmVudCBzY29wZS5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBkZWNsYXJlQmluZGluZyhuYW1lLCBiaW5kaW5nLCBsb2NhdGlvbiwgc2NvcGUsIGZhaWwpIHtcbiAgaWYgKHNjb3BlLnVzZWROYW1lcy5oYXMobmFtZSkpIGZhaWwoXCJEVVBMSUNBVEVfQklORElOR1wiLCBgRHVwbGljYXRlIG9yIHNoYWRvd2VkIGJpbmRpbmcgJyR7bmFtZX0nLmAsIGxvY2F0aW9uKVxuXG4gIHNjb3BlLmJpbmRpbmdzLnNldChuYW1lLCBiaW5kaW5nKVxuICBzY29wZS51c2VkTmFtZXMuYWRkKG5hbWUpXG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25lIGlkZW50aWZpZXIgYW5kIGRpc3Rpbmd1aXNoZXMgdXNlLWJlZm9yZS1kZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gQmluZGluZyBuYW1lLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIFJlZmVyZW5jZSBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7U2NvcGV9IHNjb3BlIC0gQ3VycmVudCBzY29wZS5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEByZXR1cm5zIHtCaW5kaW5nfSBCaW5kaW5nLlxuICovXG5mdW5jdGlvbiByZXNvbHZlQmluZGluZyhuYW1lLCBsb2NhdGlvbiwgc2NvcGUsIGZhaWwpIHtcbiAgZm9yIChsZXQgY3VycmVudCA9IC8qKiBAdHlwZSB7U2NvcGUgfCB1bmRlZmluZWR9ICovIChzY29wZSk7IGN1cnJlbnQ7IGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudCkge1xuICAgIGNvbnN0IGJpbmRpbmcgPSBjdXJyZW50LmJpbmRpbmdzLmdldChuYW1lKVxuXG4gICAgaWYgKGJpbmRpbmcpIHJldHVybiBiaW5kaW5nXG4gICAgaWYgKGN1cnJlbnQucGVuZGluZy5oYXMobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVVNFX0JFRk9SRV9ERUNMQVJBVElPTlwiLCBgQmluZGluZyAnJHtuYW1lfScgaXMgdXNlZCBiZWZvcmUgaXRzIGRlY2xhcmF0aW9uLmAsIGxvY2F0aW9uKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWlsKFwiVU5SRVNPTFZFRF9CSU5ESU5HXCIsIGBVbmtub3duIGJpbmRpbmcgJyR7bmFtZX0nLmAsIGxvY2F0aW9uKVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBvbmUgc2VtYW50aWMgdmFsdWUgdHlwZSByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge3Vua25vd259IHR5cGUgLSBDYW5kaWRhdGUgc2VtYW50aWMgdHlwZSByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gT3duaW5nIHNvdXJjZSBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEBwYXJhbSB7U2V0PG9iamVjdD59IFtzZWVuXSAtIEFjdGl2ZSByZWN1cnNpdmUgdHlwZSBwYXRoLlxuICogQHBhcmFtIHtSZWNvcmRSZWdpc3RyeX0gW3JlY29yZHNdIC0gUmVjb3JkIGRlY2xhcmF0aW9ucyBieSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IFt0eXBlUGFyYW1ldGVyc10gLSBUeXBlLXZhcmlhYmxlIGlkZW50aXRpZXMgaW4gZGVjbGFyYXRpb24gc2NvcGUuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gVmFsaWRhdGVkIHZhbHVlIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlVmFsdWVUeXBlUmVmZXJlbmNlKHR5cGUsIGxvY2F0aW9uLCBmYWlsLCBzZWVuLCByZWNvcmRzID0gbmV3IE1hcCgpLCB0eXBlUGFyYW1ldGVycyA9IG5ldyBTZXQoKSkge1xuICBjb25zdCBjYW5kaWRhdGUgPSB2YWxpZGF0ZVR5cGVSZWZlcmVuY2UodHlwZSwgbG9jYXRpb24sIGZhaWwsIHNlZW4sIHJlY29yZHMsIHR5cGVQYXJhbWV0ZXJzKVxuXG4gIGlmIChpc1ZvaWRUeXBlKGNhbmRpZGF0ZSkpIHJldHVybiBmYWlsKFwiVk9JRF9BU19WQUxVRVwiLCBcIlZvaWQgaXMgdmFsaWQgb25seSBhcyBhIGZ1bmN0aW9uIHJldHVybiB0eXBlLlwiLCB0eXBlTG9jYXRpb24odHlwZSwgbG9jYXRpb24pKVxuXG4gIHJldHVybiBjYW5kaWRhdGVcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgb25lIGZ1bmN0aW9uIHJldHVybiB0eXBlIHJlZmVyZW5jZS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdHlwZSAtIENhbmRpZGF0ZSBzZW1hbnRpYyByZXR1cm4gdHlwZSByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gT3duaW5nIHNvdXJjZSBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEBwYXJhbSB7UmVjb3JkUmVnaXN0cnl9IFtyZWNvcmRzXSAtIFJlY29yZCBkZWNsYXJhdGlvbnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSBbdHlwZVBhcmFtZXRlcnNdIC0gVHlwZS12YXJpYWJsZSBpZGVudGl0aWVzIGluIGRlY2xhcmF0aW9uIHNjb3BlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9IFZhbGlkYXRlZCByZXR1cm4gdHlwZS5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVSZXR1cm5UeXBlUmVmZXJlbmNlKHR5cGUsIGxvY2F0aW9uLCBmYWlsLCByZWNvcmRzID0gbmV3IE1hcCgpLCB0eXBlUGFyYW1ldGVycyA9IG5ldyBTZXQoKSkge1xuICByZXR1cm4gdmFsaWRhdGVUeXBlUmVmZXJlbmNlKHR5cGUsIGxvY2F0aW9uLCBmYWlsLCBuZXcgU2V0KCksIHJlY29yZHMsIHR5cGVQYXJhbWV0ZXJzKVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBvbmUgcmVjdXJzaXZlIHNlbWFudGljIHR5cGUtcmVmZXJlbmNlIHNoYXBlLlxuICogQHBhcmFtIHt1bmtub3dufSB0eXBlIC0gQ2FuZGlkYXRlIHNlbWFudGljIHR5cGUgcmVmZXJlbmNlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIE93bmluZyBzb3VyY2UgbG9jYXRpb24uXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcGFyYW0ge1NldDxvYmplY3Q+fSBbc2Vlbl0gLSBBY3RpdmUgcmVjdXJzaXZlIHR5cGUgcGF0aC5cbiAqIEBwYXJhbSB7UmVjb3JkUmVnaXN0cnl9IFtyZWNvcmRzXSAtIFJlY29yZCBkZWNsYXJhdGlvbnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSBbdHlwZVBhcmFtZXRlcnNdIC0gVHlwZS12YXJpYWJsZSBpZGVudGl0aWVzIGluIGRlY2xhcmF0aW9uIHNjb3BlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9IFZhbGlkYXRlZCB0eXBlLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVR5cGVSZWZlcmVuY2UodHlwZSwgbG9jYXRpb24sIGZhaWwsIHNlZW4gPSBuZXcgU2V0KCksIHJlY29yZHMgPSBuZXcgTWFwKCksIHR5cGVQYXJhbWV0ZXJzID0gbmV3IFNldCgpKSB7XG4gIGlmICghdHlwZSB8fCB0eXBlb2YgdHlwZSAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkodHlwZSkpIHtcbiAgICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJVbnN1cHBvcnRlZCBzZW1hbnRpYyB0eXBlLlwiLCBsb2NhdGlvbilcbiAgfVxuXG4gIGNvbnN0IGNhbmRpZGF0ZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZX0gKi8gKHR5cGUpXG5cbiAgaWYgKFtcIkxpc3RUeXBlXCIsIFwiTWFwVHlwZVwiLCBcIk9wdGlvbmFsVHlwZVwiLCBcIk9yZGVyZWRNYXBUeXBlXCIsIFwiUmVjb3JkVHlwZVwiXS5pbmNsdWRlcyhjYW5kaWRhdGUua2luZCkgJiZcbiAgICBjb250YWluc093bmVkVHlwZShjYW5kaWRhdGUpKSB7XG4gICAgZmFpbChcIlJFU09VUkNFX0FMSUFTXCIsIFwiT3duZWQgcmVzb3VyY2VzIGFuZCByZWZlcmVuY2VzIGNhbm5vdCBiZSBuZXN0ZWQgaW4gdmFsdWUgb3IgZ2VuZXJpYyB0eXBlcy5cIiwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24pKVxuICB9XG5cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiKSB7XG4gICAgaWYgKCFpc1NjYWxhclR5cGVOYW1lKGNhbmRpZGF0ZS5uYW1lKSAmJiBjYW5kaWRhdGUubmFtZSAhPSBcInZvaWRcIikge1xuICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJVbnN1cHBvcnRlZCBzY2FsYXIgb3Igdm9pZCByZXR1cm4gdHlwZS5cIiwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24pKVxuICAgIH1cblxuICAgIHJldHVybiBjYW5kaWRhdGVcbiAgfVxuICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJUeXBlVmFyaWFibGVSZWZlcmVuY2VcIikge1xuICAgIGlmIChPYmplY3Qua2V5cyhjYW5kaWRhdGUpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKSAhPSBcImtpbmQsbG9jYXRpb24scGFyYW1ldGVySWRcIiB8fFxuICAgICAgdHlwZW9mIGNhbmRpZGF0ZS5wYXJhbWV0ZXJJZCAhPSBcInN0cmluZ1wiIHx8ICF0eXBlUGFyYW1ldGVycy5oYXMoY2FuZGlkYXRlLnBhcmFtZXRlcklkKSkge1xuICAgICAgZmFpbChcIkZSRUVfVFlQRV9WQVJJQUJMRVwiLCBgRnJlZSBvciB1bmtub3duIHR5cGUgdmFyaWFibGUgJyR7U3RyaW5nKGNhbmRpZGF0ZS5wYXJhbWV0ZXJJZCl9Jy5gLCB0eXBlTG9jYXRpb24oY2FuZGlkYXRlLCBsb2NhdGlvbikpXG4gICAgfVxuXG4gICAgcmV0dXJuIGNhbmRpZGF0ZVxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIlJlY29yZFR5cGVcIikge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhjYW5kaWRhdGUpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKVxuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gcmVjb3Jkcy5nZXQoY2FuZGlkYXRlLmRlY2xhcmF0aW9uSWQpXG5cbiAgICBpZiAoIShbXCJhcmd1bWVudHMsZGVjbGFyYXRpb25JZCxraW5kXCIsIFwiZGVjbGFyYXRpb25JZCxraW5kXCJdLmluY2x1ZGVzKGtleXMpKSB8fFxuICAgICAgdHlwZW9mIGNhbmRpZGF0ZS5kZWNsYXJhdGlvbklkICE9IFwic3RyaW5nXCIgfHwgIWRlY2xhcmF0aW9uKSB7XG4gICAgICBmYWlsKFwiVU5LTk9XTl9SRUNPUkRcIiwgYFVua25vd24gcmVjb3JkIGRlY2xhcmF0aW9uICcke1N0cmluZyhjYW5kaWRhdGUuZGVjbGFyYXRpb25JZCl9Jy5gLCB0eXBlTG9jYXRpb24oY2FuZGlkYXRlLCBsb2NhdGlvbikpXG4gICAgfVxuICAgIGNvbnN0IGV4cGVjdGVkQXJpdHkgPSBkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycz8ubGVuZ3RoID8/IDBcblxuICAgIGlmIChleHBlY3RlZEFyaXR5ID4gMCAmJiBjYW5kaWRhdGUuYXJndW1lbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGZhaWwoXCJSQVdfR0VORVJJQ19BUFBMSUNBVElPTlwiLCBgR2VuZXJpYyByZWNvcmQgJyR7ZGVjbGFyYXRpb24ubmFtZX0nIHJlcXVpcmVzICR7ZXhwZWN0ZWRBcml0eX0gdHlwZSBhcmd1bWVudHMuYCwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24pKVxuICAgIH1cbiAgICBpZiAoZXhwZWN0ZWRBcml0eSA9PSAwICYmIGNhbmRpZGF0ZS5hcmd1bWVudHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZmFpbChcIkdFTkVSSUNfQVJJVFlfTUlTTUFUQ0hcIiwgYE5vbi1nZW5lcmljIHJlY29yZCAnJHtkZWNsYXJhdGlvbi5uYW1lfScgZG9lcyBub3QgYWNjZXB0IHR5cGUgYXJndW1lbnRzLmAsIHR5cGVMb2NhdGlvbihjYW5kaWRhdGUsIGxvY2F0aW9uKSlcbiAgICB9XG4gICAgY29uc3QgY2FuZGlkYXRlQXJndW1lbnRzID0gY2FuZGlkYXRlLmFyZ3VtZW50c1xuXG4gICAgaWYgKGNhbmRpZGF0ZUFyZ3VtZW50cyAhPT0gdW5kZWZpbmVkICYmICghQXJyYXkuaXNBcnJheShjYW5kaWRhdGVBcmd1bWVudHMpIHx8XG4gICAgICBjYW5kaWRhdGVBcmd1bWVudHMuc29tZSgoX2FyZ3VtZW50LCBpbmRleCkgPT4gIU9iamVjdC5oYXNPd24oY2FuZGlkYXRlQXJndW1lbnRzLCBpbmRleCkpKSkge1xuICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJHZW5lcmljIHJlY29yZCBhcmd1bWVudHMgbXVzdCBiZSBhIGRlbnNlIG9yZGVyZWQgYXJyYXkuXCIsIHR5cGVMb2NhdGlvbihjYW5kaWRhdGUsIGxvY2F0aW9uKSlcbiAgICB9XG4gICAgY29uc3QgYXJndW1lbnRzXyA9IGNhbmRpZGF0ZS5hcmd1bWVudHMgPz8gW11cblxuICAgIGlmIChhcmd1bWVudHNfLmxlbmd0aCAhPSBleHBlY3RlZEFyaXR5KSB7XG4gICAgICBmYWlsKFwiR0VORVJJQ19BUklUWV9NSVNNQVRDSFwiLCBgUmVjb3JkICcke2RlY2xhcmF0aW9uLm5hbWV9JyBoYXMgJHthcmd1bWVudHNfLmxlbmd0aH0gdHlwZSBhcmd1bWVudHM7IGV4cGVjdGVkICR7ZXhwZWN0ZWRBcml0eX0uYCwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24pKVxuICAgIH1cbiAgICBpZiAoc2Vlbi5oYXMoY2FuZGlkYXRlKSkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiUmVjdXJzaXZlIGdlbmVyaWMgYXBwbGljYXRpb25zIGNhbm5vdCBjb250YWluIGN5Y2xlcy5cIiwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24pKVxuICAgIH1cbiAgICBzZWVuLmFkZChjYW5kaWRhdGUpXG4gICAgZm9yIChjb25zdCBhcmd1bWVudCBvZiBhcmd1bWVudHNfKSB7XG4gICAgICB2YWxpZGF0ZVZhbHVlVHlwZVJlZmVyZW5jZShhcmd1bWVudCwgdHlwZUxvY2F0aW9uKGFyZ3VtZW50LCBsb2NhdGlvbiksIGZhaWwsIHNlZW4sIHJlY29yZHMsIHR5cGVQYXJhbWV0ZXJzKVxuICAgIH1cbiAgICBzZWVuLmRlbGV0ZShjYW5kaWRhdGUpXG5cbiAgICByZXR1cm4gY2FuZGlkYXRlXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiUmVmZXJlbmNlVHlwZVwiKSB7XG4gICAgY29uc3QgY2xhc3NlcyA9IHJlZmVyZW5jZUNsYXNzZXNGb3IocmVjb3JkcylcblxuICAgIGlmIChPYmplY3Qua2V5cyhjYW5kaWRhdGUpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKSAhPSBcImRlY2xhcmF0aW9uSWQsa2luZFwiIHx8XG4gICAgICB0eXBlb2YgY2FuZGlkYXRlLmRlY2xhcmF0aW9uSWQgIT0gXCJzdHJpbmdcIiB8fCAhY2xhc3Nlcy5oYXMoY2FuZGlkYXRlLmRlY2xhcmF0aW9uSWQpKSB7XG4gICAgICBmYWlsKFwiVU5LTk9XTl9DTEFTU1wiLCBgVW5rbm93biByZWZlcmVuY2UgY2xhc3MgZGVjbGFyYXRpb24gJyR7U3RyaW5nKGNhbmRpZGF0ZS5kZWNsYXJhdGlvbklkKX0nLmAsIHR5cGVMb2NhdGlvbihjYW5kaWRhdGUsIGxvY2F0aW9uKSlcbiAgICB9XG5cbiAgICByZXR1cm4gY2FuZGlkYXRlXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiT3duZWRSZXNvdXJjZVR5cGVcIikge1xuICAgIGlmIChPYmplY3Qua2V5cyhjYW5kaWRhdGUpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKSAhPSBcImtpbmQscmVzb3VyY2VJZFwiIHx8XG4gICAgICB0eXBlb2YgY2FuZGlkYXRlLnJlc291cmNlSWQgIT0gXCJzdHJpbmdcIiB8fCAhcmVzb3VyY2VJZHNCeVJlY29yZFJlZ2lzdHJ5LmdldChyZWNvcmRzKT8uaGFzKGNhbmRpZGF0ZS5yZXNvdXJjZUlkKSkge1xuICAgICAgZmFpbChcIlJFU09VUkNFX1RZUEVfTUlTTUFUQ0hcIiwgYFVua25vd24gb3duZWQgcmVzb3VyY2UgJyR7U3RyaW5nKGNhbmRpZGF0ZS5yZXNvdXJjZUlkKX0nLmAsIHR5cGVMb2NhdGlvbihjYW5kaWRhdGUsIGxvY2F0aW9uKSlcbiAgICB9XG4gICAgcmV0dXJuIGNhbmRpZGF0ZVxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIk93bmVkUmVmZXJlbmNlVHlwZVwiKSB7XG4gICAgY29uc3QgY2xhc3NlcyA9IHJlZmVyZW5jZUNsYXNzZXNGb3IocmVjb3JkcylcblxuICAgIGlmIChPYmplY3Qua2V5cyhjYW5kaWRhdGUpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKSAhPSBcImRlY2xhcmF0aW9uSWQsa2luZFwiIHx8XG4gICAgICB0eXBlb2YgY2FuZGlkYXRlLmRlY2xhcmF0aW9uSWQgIT0gXCJzdHJpbmdcIiB8fCBjbGFzc2VzLmdldChjYW5kaWRhdGUuZGVjbGFyYXRpb25JZCk/Lm93bmVyc2hpcD8ua2luZCAhPSBcIm93bmVkUmVzb3VyY2VcIikge1xuICAgICAgZmFpbChcIlJFU09VUkNFX1RZUEVfTUlTTUFUQ0hcIiwgYFVua25vd24gb3duZWQgcmVmZXJlbmNlICcke1N0cmluZyhjYW5kaWRhdGUuZGVjbGFyYXRpb25JZCl9Jy5gLCB0eXBlTG9jYXRpb24oY2FuZGlkYXRlLCBsb2NhdGlvbikpXG4gICAgfVxuICAgIHJldHVybiBjYW5kaWRhdGVcbiAgfVxuICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJMaXN0VHlwZVwiKSB7XG4gICAgaWYgKHNlZW4uaGFzKGNhbmRpZGF0ZSkpIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIlJlY3Vyc2l2ZSBjb2xsZWN0aW9uIHR5cGVzIGNhbm5vdCBjb250YWluIGN5Y2xlcy5cIiwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24pKVxuICAgIHNlZW4uYWRkKGNhbmRpZGF0ZSlcbiAgICBjb25zdCBlbGVtZW50VHlwZSA9IHZhbGlkYXRlVmFsdWVUeXBlUmVmZXJlbmNlKGNhbmRpZGF0ZS5lbGVtZW50VHlwZSwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24sIFwiZWxlbWVudFR5cGVcIiksIGZhaWwsIHNlZW4sIHJlY29yZHMsIHR5cGVQYXJhbWV0ZXJzKVxuXG4gICAgc2Vlbi5kZWxldGUoY2FuZGlkYXRlKVxuXG4gICAgaWYgKGNhbmRpZGF0ZS5lbGVtZW50VHlwZSAhPT0gZWxlbWVudFR5cGUpIGNhbmRpZGF0ZS5lbGVtZW50VHlwZSA9IGVsZW1lbnRUeXBlXG5cbiAgICByZXR1cm4gY2FuZGlkYXRlXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiTWFwVHlwZVwiIHx8IGNhbmRpZGF0ZS5raW5kID09IFwiT3JkZXJlZE1hcFR5cGVcIikge1xuICAgIGNvbnN0IGV4cGVjdGVkRmllbGRzID0gY2FuZGlkYXRlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiID8gXCJrZXlUeXBlLGtpbmQsb3JkZXIsdmFsdWVUeXBlXCIgOiBcImtleVR5cGUsa2luZCx2YWx1ZVR5cGVcIlxuXG4gICAgaWYgKE9iamVjdC5rZXlzKGNhbmRpZGF0ZSkuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpICE9IGV4cGVjdGVkRmllbGRzKSB7XG4gICAgICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYE1hbGZvcm1lZCAke2NhbmRpZGF0ZS5raW5kID09IFwiT3JkZXJlZE1hcFR5cGVcIiA/IFwib3JkZXJlZCBtYXBcIiA6IFwibWFwXCJ9IHR5cGUuYCxcbiAgICAgICAgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24pKVxuICAgIH1cbiAgICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiICYmIGNhbmRpZGF0ZS5vcmRlciAhPSBcImluc2VydGlvblwiKSB7XG4gICAgICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJPcmRlcmVkIG1hcCB0eXBlIHJlcXVpcmVzIGluc2VydGlvbiBvcmRlci5cIiwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24pKVxuICAgIH1cbiAgICBpZiAoc2Vlbi5oYXMoY2FuZGlkYXRlKSkgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiUmVjdXJzaXZlIGNvbGxlY3Rpb24gdHlwZXMgY2Fubm90IGNvbnRhaW4gY3ljbGVzLlwiLCB0eXBlTG9jYXRpb24oY2FuZGlkYXRlLCBsb2NhdGlvbikpXG4gICAgc2Vlbi5hZGQoY2FuZGlkYXRlKVxuICAgIGNvbnN0IGtleVR5cGUgPSB2YWxpZGF0ZVZhbHVlVHlwZVJlZmVyZW5jZShjYW5kaWRhdGUua2V5VHlwZSwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24sIFwia2V5VHlwZVwiKSwgZmFpbCwgc2VlbiwgcmVjb3JkcywgdHlwZVBhcmFtZXRlcnMpXG5cbiAgICBpZiAoIWlzU2NhbGFyVHlwZShrZXlUeXBlLCBcInN0cmluZ1wiKSkge1xuICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYE1hcCBrZXkgdHlwZSAke3R5cGVEZXNjcmlwdGlvbihrZXlUeXBlKX07IGV4cGVjdGVkIHN0cmluZy5gLCB0eXBlTG9jYXRpb24oY2FuZGlkYXRlLmtleVR5cGUsIGxvY2F0aW9uKSlcbiAgICB9XG4gICAgY29uc3QgdmFsdWVUeXBlID0gdmFsaWRhdGVWYWx1ZVR5cGVSZWZlcmVuY2UoY2FuZGlkYXRlLnZhbHVlVHlwZSwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24sIFwidmFsdWVUeXBlXCIpLCBmYWlsLCBzZWVuLCByZWNvcmRzLCB0eXBlUGFyYW1ldGVycylcblxuICAgIHNlZW4uZGVsZXRlKGNhbmRpZGF0ZSlcblxuICAgIGlmIChjYW5kaWRhdGUua2V5VHlwZSAhPT0ga2V5VHlwZSkgY2FuZGlkYXRlLmtleVR5cGUgPSAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKGtleVR5cGUpXG4gICAgaWYgKGNhbmRpZGF0ZS52YWx1ZVR5cGUgIT09IHZhbHVlVHlwZSkgY2FuZGlkYXRlLnZhbHVlVHlwZSA9IHZhbHVlVHlwZVxuXG4gICAgcmV0dXJuIGNhbmRpZGF0ZVxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgaWYgKE9iamVjdC5rZXlzKGNhbmRpZGF0ZSkuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpICE9IFwia2luZCx2YWx1ZVR5cGVcIikge1xuICAgICAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiTWFsZm9ybWVkIG9wdGlvbmFsIHR5cGUuXCIsIHR5cGVMb2NhdGlvbihjYW5kaWRhdGUsIGxvY2F0aW9uKSlcbiAgICB9XG4gICAgaWYgKHNlZW4uaGFzKGNhbmRpZGF0ZSkpIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIlJlY3Vyc2l2ZSBvcHRpb25hbCB0eXBlcyBjYW5ub3QgY29udGFpbiBjeWNsZXMuXCIsIHR5cGVMb2NhdGlvbihjYW5kaWRhdGUsIGxvY2F0aW9uKSlcbiAgICBzZWVuLmFkZChjYW5kaWRhdGUpXG4gICAgY29uc3QgdmFsdWVUeXBlID0gdmFsaWRhdGVWYWx1ZVR5cGVSZWZlcmVuY2UoY2FuZGlkYXRlLnZhbHVlVHlwZSwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24sIFwidmFsdWVUeXBlXCIpLCBmYWlsLCBzZWVuLCByZWNvcmRzLCB0eXBlUGFyYW1ldGVycylcblxuICAgIHNlZW4uZGVsZXRlKGNhbmRpZGF0ZSlcbiAgICBpZiAodmFsdWVUeXBlLmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgICAgZmFpbChcIklOVkFMSURfT1BUSU9OQUxfQ09OU1RJVFVFTlRcIiwgXCJPcHRpb25hbCB2YWx1ZXMgY2Fubm90IGRpcmVjdGx5IGNvbnRhaW4gYW5vdGhlciBvcHRpb25hbC5cIiwgdHlwZUxvY2F0aW9uKGNhbmRpZGF0ZSwgbG9jYXRpb24sIFwidmFsdWVUeXBlXCIpKVxuICAgIH1cbiAgICBpZiAoY2FuZGlkYXRlLnZhbHVlVHlwZSAhPT0gdmFsdWVUeXBlKSBjYW5kaWRhdGUudmFsdWVUeXBlID0gdmFsdWVUeXBlXG5cbiAgICByZXR1cm4gY2FuZGlkYXRlXG4gIH1cblxuICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJVbnN1cHBvcnRlZCBzZW1hbnRpYyB0eXBlLlwiLCB0eXBlTG9jYXRpb24oY2FuZGlkYXRlLCBsb2NhdGlvbikpXG59XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSByZWZlcmVuY2UtY2xhc3MgcmVnaXN0cnkgYXR0YWNoZWQgdG8gdGhlIHJlY29yZCB2YWxpZGF0aW9uIGNvbnRleHQuXG4gKiBAcGFyYW0ge1JlY29yZFJlZ2lzdHJ5fSByZWNvcmRzIC0gUmVjb3JkIHZhbGlkYXRpb24gcmVnaXN0cnkuXG4gKiBAcmV0dXJucyB7Q2xhc3NSZWdpc3RyeX0gUmVmZXJlbmNlIGNsYXNzZXMuXG4gKi9cbmZ1bmN0aW9uIHJlZmVyZW5jZUNsYXNzZXNGb3IocmVjb3Jkcykge1xuICByZXR1cm4gcmVmZXJlbmNlQ2xhc3Nlc0J5UmVjb3JkUmVnaXN0cnkuZ2V0KHJlY29yZHMpID8/IG5ldyBNYXAoKVxufVxuXG4vKipcbiAqIEluZmVycyBhIHZhbHVlIGV4cHJlc3Npb24gYW5kIHJlamVjdHMgdGhlIG5vbi12YWx1ZSByZXN1bHQgb2YgYSB2b2lkIGNhbGwuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gZXhwcmVzc2lvbiAtIFNlbWFudGljIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge1Njb3BlfSBzY29wZSAtIFZpc2libGUgbGV4aWNhbCBzY29wZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uPn0gZnVuY3Rpb25zIC0gTW9kdWxlIGZ1bmN0aW9uIHNpZ25hdHVyZXMuXG4gKiBAcGFyYW0ge1JlY29yZFJlZ2lzdHJ5fSByZWNvcmRzIC0gUmVjb3JkIGRlY2xhcmF0aW9ucyBieSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gbm9ybWFsaXplT3BlcmF0aW9ucyAtIFdoZXRoZXIgdG8gbm9ybWFsaXplIGZyb250ZW5kIGludGVudCBhbmQgY2FsbCByZXNvbHV0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbnRleHQgLSBWYWx1ZSBjb250ZXh0IGZvciBkaWFnbm9zdGljcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gW2V4cGVjdGVkVHlwZV0gLSBDb250ZXh0dWFsIGNvbGxlY3Rpb24gdHlwZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2luZmVyQ29sbGVjdGlvbkVsZW1lbnRzXSAtIFdoZXRoZXIgYSBnZW5lcmljLWNhbGwgZXZpZGVuY2UgcGFzcyBtYXkgaW5mZXIgbm9uZW1wdHkgY29sbGVjdGlvbiBsaXRlcmFscy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVmFsdWVUeXBlfSBFeHByZXNzaW9uIHZhbHVlIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGluZmVyVmFsdWVFeHByZXNzaW9uVHlwZShleHByZXNzaW9uLCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCBjb250ZXh0LCBleHBlY3RlZFR5cGUsXG4gIGluZmVyQ29sbGVjdGlvbkVsZW1lbnRzID0gZmFsc2UpIHtcbiAgY29uc3QgYWxsb3dPd25lZEJvcnJvdyA9IGNvbnRleHQgPT0gXCJhbiBlZmZlY3QgYXJndW1lbnRcIiB8fCBjb250ZXh0ID09IFwiYSBtZXRob2QgcmVjZWl2ZXJcIlxuICBjb25zdCB0eXBlID0gaW5mZXJFeHByZXNzaW9uVHlwZShleHByZXNzaW9uLCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCBleHBlY3RlZFR5cGUsXG4gICAgaW5mZXJDb2xsZWN0aW9uRWxlbWVudHMsIGFsbG93T3duZWRCb3Jyb3cpXG5cbiAgaWYgKHR5cGUgPT0gXCJ2b2lkXCIpIHJldHVybiBmYWlsKFwiVk9JRF9BU19WQUxVRVwiLCBgVm9pZCBjYWxsIGNhbm5vdCBiZSB1c2VkIGFzICR7Y29udGV4dH0uYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgaWYgKHR5cGUua2luZCA9PSBcIkVycm9yVHlwZVwiKSByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYEVycm9yIHZhbHVlIGNhbm5vdCBiZSB1c2VkIGFzICR7Y29udGV4dH0uYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcblxuICByZXR1cm4gdHlwZVxufVxuXG4vKipcbiAqIEluZmVycyBhbmQgdmFsaWRhdGVzIG9uZSBleHByZXNzaW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICogQHBhcmFtIHtTY29wZX0gc2NvcGUgLSBWaXNpYmxlIGxleGljYWwgc2NvcGUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4vdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbj59IGZ1bmN0aW9ucyAtIE1vZHVsZSBmdW5jdGlvbiBzaWduYXR1cmVzLlxuICogQHBhcmFtIHtSZWNvcmRSZWdpc3RyeX0gcmVjb3JkcyAtIFJlY29yZCBkZWNsYXJhdGlvbnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5vcm1hbGl6ZU9wZXJhdGlvbnMgLSBXaGV0aGVyIHRvIHJlcGxhY2UgdHJhbnNpZW50IGZyb250ZW5kIG9wZXJhdGlvbiBpbnRlbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IFtleHBlY3RlZFR5cGVdIC0gQ29udGV4dHVhbCBjb2xsZWN0aW9uIHR5cGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpbmZlckNvbGxlY3Rpb25FbGVtZW50c10gLSBXaGV0aGVyIGEgZ2VuZXJpYy1jYWxsIGV2aWRlbmNlIHBhc3MgbWF5IGluZmVyIG5vbmVtcHR5IGNvbGxlY3Rpb24gbGl0ZXJhbHMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFthbGxvd093bmVkQm9ycm93XSAtIFdoZXRoZXIgdGhpcyBleGFjdCBjYWxsIHBvc2l0aW9uIGFkbWl0cyBhbiBpbW1lZGlhdGUgYm9ycm93LlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNCaW5kaW5nVHlwZSB8IFwidm9pZFwifSBFeHByZXNzaW9uIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGluZmVyRXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbiwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgZXhwZWN0ZWRUeXBlLFxuICBpbmZlckNvbGxlY3Rpb25FbGVtZW50cyA9IGZhbHNlLCBhbGxvd093bmVkQm9ycm93ID0gZmFsc2UpIHtcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpIHJldHVybiByZXNvbHZlQmluZGluZyhleHByZXNzaW9uLm5hbWUsIGV4cHJlc3Npb24ubG9jYXRpb24sIHNjb3BlLCBmYWlsKS50eXBlXG5cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlJlY2VpdmVyRXhwcmVzc2lvblwiKSB7XG4gICAgaWYgKCFzY29wZS5jdXJyZW50Q2xhc3MgfHwgZXhwcmVzc2lvbi5jbGFzc0lkICE9IHNjb3BlLmN1cnJlbnRDbGFzcy5pZCkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJJTExFR0FMX1BSSVZBVEVfQUNDRVNTXCIsIFwiUmVjZWl2ZXIgZXhwcmVzc2lvbiBpcyB2YWxpZCBvbmx5IGluc2lkZSBpdHMgZGVjbGFyaW5nIGNsYXNzLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cblxuICAgIHJldHVybiB7ZGVjbGFyYXRpb25JZDogLyoqIEB0eXBlIHtzdHJpbmd9ICovIChzY29wZS5jdXJyZW50Q2xhc3MuaWQpLCBraW5kOiBcIlJlZmVyZW5jZVR5cGVcIn1cbiAgfVxuXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJQcml2YXRlRmllbGRSZWFkXCIpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IHNjb3BlLmN1cnJlbnRDbGFzc1xuXG4gICAgaWYgKCFkZWNsYXJhdGlvbiB8fCAhZXhwcmVzc2lvbi5yZWNlaXZlciB8fCBleHByZXNzaW9uLnJlY2VpdmVyLmtpbmQgIT0gXCJSZWNlaXZlckV4cHJlc3Npb25cIiB8fFxuICAgICAgZXhwcmVzc2lvbi5yZWNlaXZlci5jbGFzc0lkICE9IGRlY2xhcmF0aW9uLmlkKSB7XG4gICAgICByZXR1cm4gZmFpbChcIklMTEVHQUxfUFJJVkFURV9BQ0NFU1NcIiwgXCJQcml2YXRlIGZpZWxkIHJlY2VpdmVyIG11c3QgYmUgdGhlIGRlY2xhcmluZyBjbGFzcyByZWNlaXZlci5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgZmllbGQgPSBkZWNsYXJhdGlvbi5maWVsZHMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUuaWQgPT0gZXhwcmVzc2lvbi5maWVsZClcblxuICAgIGlmICghZmllbGQpIHJldHVybiBmYWlsKFwiSUxMRUdBTF9QUklWQVRFX0FDQ0VTU1wiLCBcIlByaXZhdGUgZmllbGQgaWRlbnRpdHkgaXMgbm90IG93bmVkIGJ5IHRoZSBkZWNsYXJpbmcgY2xhc3MuXCIsIGV4cHJlc3Npb24ubG9jYXRpb24pXG5cbiAgICByZXR1cm4gZmllbGQudHlwZVxuICB9XG5cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk93bmVkQm9ycm93RXhwcmVzc2lvblwiKSB7XG4gICAgaWYgKCFhbGxvd093bmVkQm9ycm93KSB7XG4gICAgICByZXR1cm4gZmFpbChcIkJPUlJPV19FU0NBUEVcIiwgXCJCT1JST1dfRVNDQVBFOiBPd25lZCBib3Jyb3dzIGFyZSB2YWxpZCBvbmx5IGFzIGltbWVkaWF0ZSBjYXBhYmlsaXR5IGFyZ3VtZW50cyBvciBtZXRob2QgcmVjZWl2ZXJzLlwiLFxuICAgICAgICBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoZXhwcmVzc2lvbi5tb2RlICE9IFwic2hhcmVkXCIgJiYgZXhwcmVzc2lvbi5tb2RlICE9IFwiZXhjbHVzaXZlXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiSU5WQUxJRF9SRVNPVVJDRV9CT1JST1dcIiwgXCJJTlZBTElEX1JFU09VUkNFX0JPUlJPVzogT3duZWQgYm9ycm93IG1vZGUgbXVzdCBiZSBzaGFyZWQgb3IgZXhjbHVzaXZlLlwiLFxuICAgICAgICBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBib3Jyb3dlZCA9IGluZmVyVmFsdWVFeHByZXNzaW9uVHlwZShleHByZXNzaW9uLmV4cHJlc3Npb24sIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYW4gb3duZWQgYm9ycm93XCIpXG5cbiAgICBpZiAoYm9ycm93ZWQua2luZCAhPSBcIk93bmVkUmVzb3VyY2VUeXBlXCIgJiYgYm9ycm93ZWQua2luZCAhPSBcIk93bmVkUmVmZXJlbmNlVHlwZVwiKSB7XG4gICAgICByZXR1cm4gZmFpbChcIklOVkFMSURfUkVTT1VSQ0VfQk9SUk9XXCIsIFwiQm9ycm93ZWQgZXhwcmVzc2lvbiBtdXN0IGJlIGFuIG93bmVkIHJlc291cmNlIG9yIG93bmVkIHJlZmVyZW5jZS5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKCFzYW1lVHlwZShib3Jyb3dlZCwgZXhwcmVzc2lvbi50eXBlKSkge1xuICAgICAgZmFpbChcIlJFU09VUkNFX1RZUEVfTUlTTUFUQ0hcIiwgXCJCb3Jyb3cgbWV0YWRhdGEgZG9lcyBub3QgbWF0Y2ggaXRzIHJlc291cmNlIHBsYWNlLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICByZXR1cm4gYm9ycm93ZWRcbiAgfVxuXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPd25lZE1vdmVFeHByZXNzaW9uXCIpIHtcbiAgICBjb25zdCBtb3ZlZCA9IGluZmVyVmFsdWVFeHByZXNzaW9uVHlwZShleHByZXNzaW9uLmV4cHJlc3Npb24sIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYW4gb3duZWQgbW92ZVwiKVxuXG4gICAgaWYgKG1vdmVkLmtpbmQgIT0gXCJPd25lZFJlc291cmNlVHlwZVwiICYmIG1vdmVkLmtpbmQgIT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIikge1xuICAgICAgcmV0dXJuIGZhaWwoXCJJTlZBTElEX1JFU09VUkNFX1RSQU5TRkVSXCIsIFwiTW92ZWQgZXhwcmVzc2lvbiBtdXN0IGJlIGFuIG93bmVkIHJlc291cmNlIG9yIG93bmVkIHJlZmVyZW5jZS5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKCFzYW1lVHlwZShtb3ZlZCwgZXhwcmVzc2lvbi50eXBlKSkge1xuICAgICAgZmFpbChcIlJFU09VUkNFX1RZUEVfTUlTTUFUQ0hcIiwgXCJNb3ZlIG1ldGFkYXRhIGRvZXMgbm90IG1hdGNoIGl0cyByZXNvdXJjZSBwbGFjZS5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgcmV0dXJuIG1vdmVkXG4gIH1cblxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiRXJyb3JNZXNzYWdlUmVhZFwiKSB7XG4gICAgaWYgKCFleHByZXNzaW9uLnJlY2VpdmVyIHx8IGV4cHJlc3Npb24ucmVjZWl2ZXIua2luZCAhPSBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiSU5WQUxJRF9NRU1CRVJfUkVDRUlWRVJcIiwgXCJFcnJvciBtZXNzYWdlIHJlY2VpdmVyIG11c3QgYmUgb25lIGNhdGNoIGJpbmRpbmcuXCIsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IHJlY2VpdmVyID0gcmVzb2x2ZUJpbmRpbmcoZXhwcmVzc2lvbi5yZWNlaXZlci5uYW1lLCBleHByZXNzaW9uLnJlY2VpdmVyLmxvY2F0aW9uLCBzY29wZSwgZmFpbClcblxuICAgIGlmIChyZWNlaXZlci50eXBlLmtpbmQgIT0gXCJFcnJvclR5cGVcIikge1xuICAgICAgcmV0dXJuIGZhaWwoXCJJTlZBTElEX01FTUJFUl9SRUNFSVZFUlwiLCBcIk1lc3NhZ2UgbWVtYmVyIHJlcXVpcmVzIGEgdHlwZWQgZXJyb3IgY2F0Y2ggYmluZGluZy5cIiwgZXhwcmVzc2lvbi5yZWNlaXZlci5sb2NhdGlvbilcbiAgICB9XG5cbiAgICByZXR1cm4gc2NhbGFyVHlwZShcInN0cmluZ1wiKVxuICB9XG5cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkludGVnZXJMaXRlcmFsXCIpIHtcbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGV4cHJlc3Npb24udmFsdWUpKSBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIk5vbi1zYWZlIGludGVnZXIgbGl0ZXJhbC5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICByZXR1cm4gc2NhbGFyVHlwZShcImludGVnZXJcIilcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQm9vbGVhbkxpdGVyYWxcIikge1xuICAgIGlmICh0eXBlb2YgUmVmbGVjdC5nZXQoZXhwcmVzc2lvbiwgXCJ2YWx1ZVwiKSAhPSBcImJvb2xlYW5cIikge1xuICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJJbnZhbGlkIGJvb2xlYW4gbGl0ZXJhbCB2YWx1ZS5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgcmV0dXJuIHNjYWxhclR5cGUoXCJib29sZWFuXCIpXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlN0cmluZ0xpdGVyYWxcIikge1xuICAgIGNvbnN0IHZhbHVlID0gUmVmbGVjdC5nZXQoZXhwcmVzc2lvbiwgXCJ2YWx1ZVwiKVxuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPSBcInN0cmluZ1wiIHx8ICFoYXNPbmx5VW5pY29kZVNjYWxhcnModmFsdWUpKSB7XG4gICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIkludmFsaWQgVW5pY29kZSBzdHJpbmcgbGl0ZXJhbC5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgcmV0dXJuIHNjYWxhclR5cGUoXCJzdHJpbmdcIilcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiT3B0aW9uYWxOb25lXCIpIHtcbiAgICBpZiAoIWV4cGVjdGVkVHlwZSB8fCBleHBlY3RlZFR5cGUua2luZCAhPSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgICByZXR1cm4gZmFpbChcIk1JU1NJTkdfVFlQRVwiLCBcIk9wdGlvbmFsIGFic2VuY2UgcmVxdWlyZXMgYW4gZXhwbGljaXQgb3B0aW9uYWwgdHlwZS5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG5cbiAgICByZXR1cm4gZXhwZWN0ZWRUeXBlXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsU29tZVwiKSB7XG4gICAgaWYgKCFleHBlY3RlZFR5cGUgfHwgZXhwZWN0ZWRUeXBlLmtpbmQgIT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgICAgY29uc3QgdmFsdWVUeXBlID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKFxuICAgICAgICBleHByZXNzaW9uLnZhbHVlLCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCBcImFuIG9wdGlvbmFsIHByZXNlbnQgdmFsdWVcIlxuICAgICAgKVxuXG4gICAgICBpZiAodmFsdWVUeXBlLmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgICAgICByZXR1cm4gZmFpbChcIklOVkFMSURfT1BUSU9OQUxfQ09OU1RJVFVFTlRcIiwgXCJPcHRpb25hbCB2YWx1ZXMgY2Fubm90IGRpcmVjdGx5IGNvbnRhaW4gYW5vdGhlciBvcHRpb25hbC5cIiwgZXhwcmVzc2lvbi52YWx1ZS5sb2NhdGlvbilcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtraW5kOiBcIk9wdGlvbmFsVHlwZVwiLCB2YWx1ZVR5cGV9XG4gICAgfVxuICAgIGNvbnN0IHZhbHVlVHlwZSA9IGluZmVyVmFsdWVFeHByZXNzaW9uVHlwZShcbiAgICAgIGV4cHJlc3Npb24udmFsdWUsIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYW4gb3B0aW9uYWwgcHJlc2VudCB2YWx1ZVwiLCBleHBlY3RlZFR5cGUudmFsdWVUeXBlXG4gICAgKVxuXG4gICAgaWYgKCFzYW1lVHlwZSh2YWx1ZVR5cGUsIGV4cGVjdGVkVHlwZS52YWx1ZVR5cGUpKSB7XG4gICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgT3B0aW9uYWwgcHJlc2VudCB0eXBlICR7dHlwZURlc2NyaXB0aW9uKHZhbHVlVHlwZSl9OyBleHBlY3RlZCAke3R5cGVEZXNjcmlwdGlvbihleHBlY3RlZFR5cGUudmFsdWVUeXBlKX0uYCwgZXhwcmVzc2lvbi52YWx1ZS5sb2NhdGlvbilcbiAgICB9XG5cbiAgICByZXR1cm4gZXhwZWN0ZWRUeXBlXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsSXNQcmVzZW50XCIpIHtcbiAgICBpZiAoIWV4cHJlc3Npb24ub3BlcmFuZCB8fCBleHByZXNzaW9uLm9wZXJhbmQua2luZCAhPSBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIk9wdGlvbmFsIHByZXNlbmNlIHRlc3QgcmVxdWlyZXMgb25lIHNpbXBsZSBpZGVudGlmaWVyLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBvcGVyYW5kVHlwZSA9IHJlc29sdmVCaW5kaW5nKGV4cHJlc3Npb24ub3BlcmFuZC5uYW1lLCBleHByZXNzaW9uLm9wZXJhbmQubG9jYXRpb24sIHNjb3BlLCBmYWlsKS50eXBlXG5cbiAgICBpZiAob3BlcmFuZFR5cGUua2luZCAhPSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYFByZXNlbmNlIHRlc3QgcmVjZWl2ZWQgJHt0eXBlRGVzY3JpcHRpb24ob3BlcmFuZFR5cGUpfTsgZXhwZWN0ZWQgb3B0aW9uYWwuYCwgZXhwcmVzc2lvbi5vcGVyYW5kLmxvY2F0aW9uKVxuICAgIH1cblxuICAgIHJldHVybiBzY2FsYXJUeXBlKFwiYm9vbGVhblwiKVxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbFVud3JhcFwiKSB7XG4gICAgaWYgKCFleHByZXNzaW9uLm9wZXJhbmQgfHwgZXhwcmVzc2lvbi5vcGVyYW5kLmtpbmQgIT0gXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSB7XG4gICAgICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJPcHRpb25hbCB1bndyYXAgcmVxdWlyZXMgb25lIHNpbXBsZSBpZGVudGlmaWVyLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBiaW5kaW5nID0gcmVzb2x2ZUJpbmRpbmcoZXhwcmVzc2lvbi5vcGVyYW5kLm5hbWUsIGV4cHJlc3Npb24ub3BlcmFuZC5sb2NhdGlvbiwgc2NvcGUsIGZhaWwpXG5cbiAgICBpZiAoYmluZGluZy50eXBlLmtpbmQgIT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgICAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBPcHRpb25hbCB1bndyYXAgcmVjZWl2ZWQgJHt0eXBlRGVzY3JpcHRpb24oYmluZGluZy50eXBlKX07IGV4cGVjdGVkIG9wdGlvbmFsLmAsIGV4cHJlc3Npb24ub3BlcmFuZC5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKCFzY29wZS5wcmVzZW5jZVByb29mcy5oYXMoYmluZGluZykpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVU5DSEVDS0VEX09QVElPTkFMX1VOV1JBUFwiLCBgT3B0aW9uYWwgYmluZGluZyAnJHtleHByZXNzaW9uLm9wZXJhbmQubmFtZX0nIGlzIG5vdCBwcm92ZW4gcHJlc2VudC5gLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cblxuICAgIHJldHVybiBiaW5kaW5nLnR5cGUudmFsdWVUeXBlXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkxpc3RMaXRlcmFsXCIpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZXhwcmVzc2lvbi5lbGVtZW50cykpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIkxpc3QgbGl0ZXJhbCBlbGVtZW50cyBtdXN0IGJlIGEgZGVuc2Ugc291cmNlLW9yZGVyZWQgYXJyYXkuXCIsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmICgoIWV4cGVjdGVkVHlwZSB8fCBleHBlY3RlZFR5cGUua2luZCAhPSBcIkxpc3RUeXBlXCIpICYmXG4gICAgICAoIWluZmVyQ29sbGVjdGlvbkVsZW1lbnRzIHx8IGV4cHJlc3Npb24uZWxlbWVudHMubGVuZ3RoID09IDApKSB7XG4gICAgICByZXR1cm4gZmFpbChcIk1JU1NJTkdfVFlQRVwiLCBcIkxpc3QgbGl0ZXJhbCByZXF1aXJlcyBhbiBleHBsaWNpdCByZWN1cnNpdmUgbGlzdCB0eXBlLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGUgfCB1bmRlZmluZWR9ICovXG4gICAgbGV0IGluZmVycmVkRWxlbWVudFR5cGVcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgZXhwcmVzc2lvbi5lbGVtZW50cy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGlmICghT2JqZWN0Lmhhc093bihleHByZXNzaW9uLmVsZW1lbnRzLCBpbmRleCkpIHtcbiAgICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJTcGFyc2UgbGlzdCBsaXRlcmFscyBhcmUgb3V0c2lkZSB0aGUgaW1wbGVtZW50ZWQgc3Vic2V0LlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY29uc3QgZWxlbWVudCA9IGV4cHJlc3Npb24uZWxlbWVudHNbaW5kZXhdXG4gICAgICBjb25zdCBhY3R1YWwgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoXG4gICAgICAgIGVsZW1lbnQsIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYSBsaXN0IGVsZW1lbnRcIixcbiAgICAgICAgZXhwZWN0ZWRUeXBlPy5raW5kID09IFwiTGlzdFR5cGVcIiA/IGV4cGVjdGVkVHlwZS5lbGVtZW50VHlwZSA6IGluZmVycmVkRWxlbWVudFR5cGUsIGluZmVyQ29sbGVjdGlvbkVsZW1lbnRzXG4gICAgICApXG5cbiAgICAgIGluZmVycmVkRWxlbWVudFR5cGUgPz89IGFjdHVhbFxuICAgICAgY29uc3QgcmVxdWlyZWRFbGVtZW50VHlwZSA9IGV4cGVjdGVkVHlwZT8ua2luZCA9PSBcIkxpc3RUeXBlXCIgPyBleHBlY3RlZFR5cGUuZWxlbWVudFR5cGUgOiBpbmZlcnJlZEVsZW1lbnRUeXBlXG5cbiAgICAgIGlmICghc2FtZVR5cGUoYWN0dWFsLCByZXF1aXJlZEVsZW1lbnRUeXBlKSkge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgTGlzdCBlbGVtZW50IHR5cGUgJHt0eXBlRGVzY3JpcHRpb24oYWN0dWFsKX07IGV4cGVjdGVkICR7dHlwZURlc2NyaXB0aW9uKHJlcXVpcmVkRWxlbWVudFR5cGUpfS5gLCBlbGVtZW50LmxvY2F0aW9uKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJMaXN0VHlwZVwiXG4gICAgICA/IGV4cGVjdGVkVHlwZVxuICAgICAgOiB7ZWxlbWVudFR5cGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gKi8gKGluZmVycmVkRWxlbWVudFR5cGUpLCBraW5kOiBcIkxpc3RUeXBlXCJ9XG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExpdGVyYWxcIikge1xuICAgIGlmIChleHBlY3RlZFR5cGUgJiYgZXhwZWN0ZWRUeXBlLmtpbmQgIT0gXCJNYXBUeXBlXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgTWFwIGxpdGVyYWwgY29udGV4dCAke3R5cGVEZXNjcmlwdGlvbihleHBlY3RlZFR5cGUpfTsgZXhwZWN0ZWQgbWFwLmAsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmICghZXhwZWN0ZWRUeXBlICYmICFpbmZlckNvbGxlY3Rpb25FbGVtZW50cykge1xuICAgICAgcmV0dXJuIGZhaWwoXCJNSVNTSU5HX1RZUEVcIiwgXCJNYXAgbGl0ZXJhbCByZXF1aXJlcyBhbiBleHBsaWNpdCByZWN1cnNpdmUgbWFwIHR5cGUuXCIsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJNYXBUeXBlXCIgJiYgIWlzU2NhbGFyVHlwZShleHBlY3RlZFR5cGUua2V5VHlwZSwgXCJzdHJpbmdcIikpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIk1hcCBrZXkgdHlwZSBtdXN0IGJlIHN0cmluZy5cIiwgdHlwZUxvY2F0aW9uKGV4cGVjdGVkVHlwZS5rZXlUeXBlLCBleHByZXNzaW9uLmxvY2F0aW9uKSlcbiAgICB9XG4gICAgY29uc3QgZW50cmllcyA9IHZhbGlkYXRlTWFwTGl0ZXJhbEVudHJpZXMoZXhwcmVzc2lvbiwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucyxcbiAgICAgIGluZmVyQ29sbGVjdGlvbkVsZW1lbnRzKVxuXG4gICAgaWYgKCFleHBlY3RlZFR5cGUgJiYgZW50cmllcy5sZW5ndGggPT0gMCkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJNSVNTSU5HX1RZUEVcIiwgXCJFbXB0eSBtYXAgbGl0ZXJhbCByZXF1aXJlcyBhbiBleHBsaWNpdCByZWN1cnNpdmUgbWFwIHR5cGUuXCIsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZSB8IHVuZGVmaW5lZH0gKi9cbiAgICBsZXQgaW5mZXJyZWRWYWx1ZVR5cGVcblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgY29uc3QgYWN0dWFsID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKFxuICAgICAgICBlbnRyeS52YWx1ZSwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgXCJhIG1hcCB2YWx1ZVwiLFxuICAgICAgICBleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJNYXBUeXBlXCIgPyBleHBlY3RlZFR5cGUudmFsdWVUeXBlIDogaW5mZXJyZWRWYWx1ZVR5cGUsIGluZmVyQ29sbGVjdGlvbkVsZW1lbnRzXG4gICAgICApXG4gICAgICBpbmZlcnJlZFZhbHVlVHlwZSA/Pz0gYWN0dWFsXG4gICAgICBjb25zdCByZXF1aXJlZFZhbHVlVHlwZSA9IGV4cGVjdGVkVHlwZT8ua2luZCA9PSBcIk1hcFR5cGVcIiA/IGV4cGVjdGVkVHlwZS52YWx1ZVR5cGUgOiBpbmZlcnJlZFZhbHVlVHlwZVxuXG4gICAgICBpZiAoIXNhbWVUeXBlKGFjdHVhbCwgcmVxdWlyZWRWYWx1ZVR5cGUpKSB7XG4gICAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBNYXAgdmFsdWUgdHlwZSAke3R5cGVEZXNjcmlwdGlvbihhY3R1YWwpfTsgZXhwZWN0ZWQgJHt0eXBlRGVzY3JpcHRpb24ocmVxdWlyZWRWYWx1ZVR5cGUpfS5gLCBlbnRyeS52YWx1ZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZXhwZWN0ZWRUeXBlPy5raW5kID09IFwiTWFwVHlwZVwiID8gZXhwZWN0ZWRUeXBlIDoge1xuICAgICAga2V5VHlwZTogc2NhbGFyVHlwZShcInN0cmluZ1wiKSxcbiAgICAgIGtpbmQ6IFwiTWFwVHlwZVwiLFxuICAgICAgdmFsdWVUeXBlOiAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9ICovIChpbmZlcnJlZFZhbHVlVHlwZSlcbiAgICB9XG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk9yZGVyZWRNYXBMaXRlcmFsXCIpIHtcbiAgICBpZiAoZXhwZWN0ZWRUeXBlICYmIGV4cGVjdGVkVHlwZS5raW5kICE9IFwiT3JkZXJlZE1hcFR5cGVcIikge1xuICAgICAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBPcmRlcmVkLW1hcCBsaXRlcmFsIGNvbnRleHQgJHt0eXBlRGVzY3JpcHRpb24oZXhwZWN0ZWRUeXBlKX07IGV4cGVjdGVkIG9yZGVyZWQgbWFwLmAsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmICghZXhwZWN0ZWRUeXBlICYmICFpbmZlckNvbGxlY3Rpb25FbGVtZW50cykge1xuICAgICAgcmV0dXJuIGZhaWwoXCJNSVNTSU5HX1RZUEVcIiwgXCJPcmRlcmVkLW1hcCBsaXRlcmFsIHJlcXVpcmVzIGFuIGV4cGxpY2l0IHJlY3Vyc2l2ZSBvcmRlcmVkLW1hcCB0eXBlLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoZXhwZWN0ZWRUeXBlPy5raW5kID09IFwiT3JkZXJlZE1hcFR5cGVcIiAmJiAhaXNTY2FsYXJUeXBlKGV4cGVjdGVkVHlwZS5rZXlUeXBlLCBcInN0cmluZ1wiKSkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiT3JkZXJlZC1tYXAga2V5IHR5cGUgbXVzdCBiZSBzdHJpbmcuXCIsIHR5cGVMb2NhdGlvbihleHBlY3RlZFR5cGUua2V5VHlwZSwgZXhwcmVzc2lvbi5sb2NhdGlvbikpXG4gICAgfVxuICAgIGNvbnN0IGVudHJpZXMgPSB2YWxpZGF0ZU1hcExpdGVyYWxFbnRyaWVzKGV4cHJlc3Npb24sIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsXG4gICAgICBpbmZlckNvbGxlY3Rpb25FbGVtZW50cylcblxuICAgIGlmICghZXhwZWN0ZWRUeXBlICYmIGVudHJpZXMubGVuZ3RoID09IDApIHtcbiAgICAgIHJldHVybiBmYWlsKFwiTUlTU0lOR19UWVBFXCIsIFwiRW1wdHkgb3JkZXJlZC1tYXAgbGl0ZXJhbCByZXF1aXJlcyBhbiBleHBsaWNpdCByZWN1cnNpdmUgb3JkZXJlZC1tYXAgdHlwZS5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVmFsdWVUeXBlIHwgdW5kZWZpbmVkfSAqL1xuICAgIGxldCBpbmZlcnJlZFZhbHVlVHlwZVxuXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICBjb25zdCBhY3R1YWwgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoXG4gICAgICAgIGVudHJ5LnZhbHVlLCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCBcImFuIG9yZGVyZWQtbWFwIHZhbHVlXCIsXG4gICAgICAgIGV4cGVjdGVkVHlwZT8ua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCIgPyBleHBlY3RlZFR5cGUudmFsdWVUeXBlIDogaW5mZXJyZWRWYWx1ZVR5cGUsIGluZmVyQ29sbGVjdGlvbkVsZW1lbnRzXG4gICAgICApXG4gICAgICBpbmZlcnJlZFZhbHVlVHlwZSA/Pz0gYWN0dWFsXG4gICAgICBjb25zdCByZXF1aXJlZFZhbHVlVHlwZSA9IGV4cGVjdGVkVHlwZT8ua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCIgPyBleHBlY3RlZFR5cGUudmFsdWVUeXBlIDogaW5mZXJyZWRWYWx1ZVR5cGVcblxuICAgICAgaWYgKCFzYW1lVHlwZShhY3R1YWwsIHJlcXVpcmVkVmFsdWVUeXBlKSkge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgT3JkZXJlZC1tYXAgdmFsdWUgdHlwZSAke3R5cGVEZXNjcmlwdGlvbihhY3R1YWwpfTsgZXhwZWN0ZWQgJHt0eXBlRGVzY3JpcHRpb24ocmVxdWlyZWRWYWx1ZVR5cGUpfS5gLFxuICAgICAgICAgIGVudHJ5LnZhbHVlLmxvY2F0aW9uKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiID8gZXhwZWN0ZWRUeXBlIDoge1xuICAgICAga2V5VHlwZTogc2NhbGFyVHlwZShcInN0cmluZ1wiKSxcbiAgICAgIGtpbmQ6IFwiT3JkZXJlZE1hcFR5cGVcIixcbiAgICAgIG9yZGVyOiBcImluc2VydGlvblwiLFxuICAgICAgdmFsdWVUeXBlOiAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9ICovIChpbmZlcnJlZFZhbHVlVHlwZSlcbiAgICB9XG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkxpc3RJbmRleEV4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IGNvbGxlY3Rpb25UeXBlID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKGV4cHJlc3Npb24uY29sbGVjdGlvbiwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgXCJhIGxpc3QgcmVjZWl2ZXJcIilcbiAgICBjb25zdCBpbmRleFR5cGUgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbi5pbmRleCwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgXCJhIGxpc3QgaW5kZXhcIiwgc2NhbGFyVHlwZShcImludGVnZXJcIikpXG5cbiAgICBpZiAoY29sbGVjdGlvblR5cGUua2luZCAhPSBcIkxpc3RUeXBlXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgTGlzdCBpbmRleCByZWNlaXZlciB0eXBlICR7dHlwZURlc2NyaXB0aW9uKGNvbGxlY3Rpb25UeXBlKX07IGV4cGVjdGVkIGxpc3QuYCwgZXhwcmVzc2lvbi5jb2xsZWN0aW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoIWlzU2NhbGFyVHlwZShpbmRleFR5cGUsIFwiaW50ZWdlclwiKSkge1xuICAgICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYExpc3QgaW5kZXggdHlwZSAke3R5cGVEZXNjcmlwdGlvbihpbmRleFR5cGUpfTsgZXhwZWN0ZWQgaW50ZWdlci5gLCBleHByZXNzaW9uLmluZGV4LmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBrbm93bkNvbGxlY3Rpb24gPSBrbm93blZhbHVlRm9yRXhwcmVzc2lvbihleHByZXNzaW9uLmNvbGxlY3Rpb24sIHNjb3BlKVxuICAgIGNvbnN0IGtub3duSW5kZXggPSBrbm93blZhbHVlRm9yRXhwcmVzc2lvbihleHByZXNzaW9uLmluZGV4LCBzY29wZSlcblxuICAgIGlmIChrbm93bkNvbGxlY3Rpb24/LmtpbmQgPT0gXCJMaXN0TGl0ZXJhbFwiICYmIGtub3duSW5kZXg/LmtpbmQgPT0gXCJJbnRlZ2VyTGl0ZXJhbFwiICYmXG4gICAgICAoa25vd25JbmRleC52YWx1ZSA8IDAgfHwga25vd25JbmRleC52YWx1ZSA+PSBrbm93bkNvbGxlY3Rpb24uZWxlbWVudHMubGVuZ3RoKSkge1xuICAgICAgZmFpbChcIklOREVYX09VVF9PRl9CT1VORFNcIiwgYExpc3QgaW5kZXggJHtrbm93bkluZGV4LnZhbHVlfSBpcyBvdXRzaWRlIGEgbGl0ZXJhbCBsaXN0IG9mIHNpemUgJHtrbm93bkNvbGxlY3Rpb24uZWxlbWVudHMubGVuZ3RofS5gLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBwcm92ZW4gPSBwcm92ZW5MaXN0RWxlbWVudChleHByZXNzaW9uLmNvbGxlY3Rpb24sIGV4cHJlc3Npb24uaW5kZXgsIHNjb3BlKVxuXG4gICAgdmFsaWRhdGVBY2Nlc3NUb3RhbGl0eShleHByZXNzaW9uLCBwcm92ZW4gIT09IHVuZGVmaW5lZCwgbm9ybWFsaXplT3BlcmF0aW9ucywgZmFpbClcblxuICAgIHJldHVybiBjb2xsZWN0aW9uVHlwZS5lbGVtZW50VHlwZVxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJNYXBMb29rdXBFeHByZXNzaW9uXCIpIHtcbiAgICBjb25zdCBjb2xsZWN0aW9uVHlwZSA9IGluZmVyVmFsdWVFeHByZXNzaW9uVHlwZShleHByZXNzaW9uLmNvbGxlY3Rpb24sIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYSBtYXAgcmVjZWl2ZXJcIilcbiAgICBjb25zdCBrZXlUeXBlID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKGV4cHJlc3Npb24ua2V5LCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCBcImEgbWFwIGtleVwiLCBzY2FsYXJUeXBlKFwic3RyaW5nXCIpKVxuXG4gICAgaWYgKGNvbGxlY3Rpb25UeXBlLmtpbmQgIT0gXCJNYXBUeXBlXCIgJiYgY29sbGVjdGlvblR5cGUua2luZCAhPSBcIk9yZGVyZWRNYXBUeXBlXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgTWFwIGxvb2t1cCByZWNlaXZlciB0eXBlICR7dHlwZURlc2NyaXB0aW9uKGNvbGxlY3Rpb25UeXBlKX07IGV4cGVjdGVkIG1hcC5gLCBleHByZXNzaW9uLmNvbGxlY3Rpb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmICghaXNTY2FsYXJUeXBlKGtleVR5cGUsIFwic3RyaW5nXCIpKSB7XG4gICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgTWFwIGxvb2t1cCBrZXkgdHlwZSAke3R5cGVEZXNjcmlwdGlvbihrZXlUeXBlKX07IGV4cGVjdGVkIHN0cmluZy5gLCBleHByZXNzaW9uLmtleS5sb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3Qga25vd25Db2xsZWN0aW9uID0ga25vd25WYWx1ZUZvckV4cHJlc3Npb24oZXhwcmVzc2lvbi5jb2xsZWN0aW9uLCBzY29wZSlcbiAgICBjb25zdCBrbm93bktleSA9IGtub3duVmFsdWVGb3JFeHByZXNzaW9uKGV4cHJlc3Npb24ua2V5LCBzY29wZSlcblxuICAgIGlmICgoa25vd25Db2xsZWN0aW9uPy5raW5kID09IFwiTWFwTGl0ZXJhbFwiIHx8IGtub3duQ29sbGVjdGlvbj8ua2luZCA9PSBcIk9yZGVyZWRNYXBMaXRlcmFsXCIpICYmXG4gICAgICBrbm93bktleT8ua2luZCA9PSBcIlN0cmluZ0xpdGVyYWxcIiAmJlxuICAgICAgIWtub3duQ29sbGVjdGlvbi5lbnRyaWVzLnNvbWUoKGVudHJ5KSA9PiBlbnRyeS5rZXkudmFsdWUgPT0ga25vd25LZXkudmFsdWUpKSB7XG4gICAgICBmYWlsKFwiTUlTU0lOR19NQVBfS0VZXCIsIGBNYXAga2V5ICcke2tub3duS2V5LnZhbHVlfScgaXMgYWJzZW50IGZyb20gdGhlIGxpdGVyYWwgaW5pdGlhbGl6ZXIuYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgcHJvdmVuID0gcHJvdmVuTWFwVmFsdWUoZXhwcmVzc2lvbi5jb2xsZWN0aW9uLCBleHByZXNzaW9uLmtleSwgc2NvcGUpXG5cbiAgICB2YWxpZGF0ZUFjY2Vzc1RvdGFsaXR5KGV4cHJlc3Npb24sIHByb3ZlbiAhPT0gdW5kZWZpbmVkLCBub3JtYWxpemVPcGVyYXRpb25zLCBmYWlsKVxuXG4gICAgcmV0dXJuIGNvbGxlY3Rpb25UeXBlLnZhbHVlVHlwZVxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJDb2xsZWN0aW9uU2l6ZUV4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IGNvbGxlY3Rpb25UeXBlID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKGV4cHJlc3Npb24uY29sbGVjdGlvbiwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgXCJhIGNvbGxlY3Rpb24tc2l6ZSByZWNlaXZlclwiKVxuXG4gICAgaWYgKGNvbGxlY3Rpb25UeXBlLmtpbmQgIT0gXCJMaXN0VHlwZVwiICYmIGNvbGxlY3Rpb25UeXBlLmtpbmQgIT0gXCJNYXBUeXBlXCIgJiYgY29sbGVjdGlvblR5cGUua2luZCAhPSBcIk9yZGVyZWRNYXBUeXBlXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgQ29sbGVjdGlvbiBzaXplIHJlY2VpdmVyIHR5cGUgJHt0eXBlRGVzY3JpcHRpb24oY29sbGVjdGlvblR5cGUpfTsgZXhwZWN0ZWQgbGlzdCBvciBtYXAuYCwgZXhwcmVzc2lvbi5jb2xsZWN0aW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBjb2xsZWN0aW9uS2luZCA9IGNvbGxlY3Rpb25UeXBlLmtpbmQgPT0gXCJMaXN0VHlwZVwiID8gXCJsaXN0XCIgOiBcIm1hcFwiXG5cbiAgICBpZiAobm9ybWFsaXplT3BlcmF0aW9ucykge1xuICAgICAgaWYgKGV4cHJlc3Npb24uY29sbGVjdGlvbktpbmQgIT09IHVuZGVmaW5lZCAmJiBleHByZXNzaW9uLmNvbGxlY3Rpb25LaW5kICE9IGNvbGxlY3Rpb25LaW5kKSB7XG4gICAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiQ29sbGVjdGlvbiBzaXplIG9wZXJhdGlvbiBkb2VzIG5vdCBtYXRjaCBpdHMgcmVjZWl2ZXIgdHlwZS5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGV4cHJlc3Npb24uY29sbGVjdGlvbktpbmQgPSBjb2xsZWN0aW9uS2luZFxuICAgIH1cbiAgICBlbHNlIGlmIChleHByZXNzaW9uLmNvbGxlY3Rpb25LaW5kICE9IGNvbGxlY3Rpb25LaW5kKSB7XG4gICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIkNvbGxlY3Rpb24gc2l6ZSBraW5kIGRvZXMgbm90IG1hdGNoIGl0cyByZWNlaXZlciB0eXBlLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cblxuICAgIHJldHVybiBzY2FsYXJUeXBlKFwiaW50ZWdlclwiKVxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJFZmZlY3RDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGV4cHJlc3Npb24uYXJndW1lbnRzKSB8fCBleHByZXNzaW9uLmFyZ3VtZW50cy5sZW5ndGggIT0gZXhwcmVzc2lvbi5yZXNvbHV0aW9uLnBhcmFtZXRlclR5cGVzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiRWZmZWN0IGNhbGwgYXJndW1lbnQgY291bnQgZG9lcyBub3QgbWF0Y2ggaXRzIGF1dGhvcml6ZWQgb3BlcmF0aW9uLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCByZXNvdXJjZUZsb3cgPSBleHByZXNzaW9uLnJlc29sdXRpb24ucmVzb3VyY2VGbG93XG5cbiAgICBpZiAocmVzb3VyY2VGbG93LmtpbmQgPT0gXCJib3Jyb3dcIiB8fCByZXNvdXJjZUZsb3cua2luZCA9PSBcImNsb3NlXCIpIHtcbiAgICAgIGNvbnN0IGJvcnJvdyA9IGV4cHJlc3Npb24uYXJndW1lbnRzW3Jlc291cmNlRmxvdy5wYXJhbWV0ZXJJbmRleF1cbiAgICAgIGNvbnN0IGV4cGVjdGVkTW9kZSA9IHJlc291cmNlRmxvdy5raW5kID09IFwiY2xvc2VcIiA/IFwiZXhjbHVzaXZlXCIgOiBcInNoYXJlZFwiXG5cbiAgICAgIGlmIChib3Jyb3c/LmtpbmQgIT0gXCJPd25lZEJvcnJvd0V4cHJlc3Npb25cIiB8fCBib3Jyb3cubW9kZSAhPSBleHBlY3RlZE1vZGUpIHtcbiAgICAgICAgZmFpbChcIklOVkFMSURfUkVTT1VSQ0VfQk9SUk9XXCIsIGBJTlZBTElEX1JFU09VUkNFX0JPUlJPVzogJHtyZXNvdXJjZUZsb3cua2luZH0gcmVxdWlyZXMgYW4gaW1tZWRpYXRlICR7ZXhwZWN0ZWRNb2RlfSBib3Jyb3cuYCxcbiAgICAgICAgICBib3Jyb3c/LmxvY2F0aW9uID8/IGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgICB9XG4gICAgfVxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBleHByZXNzaW9uLmFyZ3VtZW50cy5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gaWRlbnRpdHlBc1ZhbHVlVHlwZShleHByZXNzaW9uLnJlc29sdXRpb24ucGFyYW1ldGVyVHlwZXNbaW5kZXhdLCBleHByZXNzaW9uLmFyZ3VtZW50c1tpbmRleF0ubG9jYXRpb24sIGZhaWwpXG4gICAgICBjb25zdCBhY3R1YWwgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbi5hcmd1bWVudHNbaW5kZXhdLCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLFxuICAgICAgICBcImFuIGVmZmVjdCBhcmd1bWVudFwiLCBleHBlY3RlZClcblxuICAgICAgaWYgKCFzYW1lVHlwZShhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgICAgICBmYWlsKFwiUkVTT1VSQ0VfVFlQRV9NSVNNQVRDSFwiLCBgRWZmZWN0IGFyZ3VtZW50IHR5cGUgJHt0eXBlRGVzY3JpcHRpb24oYWN0dWFsKX07IGV4cGVjdGVkICR7dHlwZURlc2NyaXB0aW9uKGV4cGVjdGVkKX0uYCxcbiAgICAgICAgICBleHByZXNzaW9uLmFyZ3VtZW50c1tpbmRleF0ubG9jYXRpb24pXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChleHByZXNzaW9uLnJlc29sdXRpb24ucmV0dXJuVHlwZSA9PSBcInZvaWRcIikgcmV0dXJuIFwidm9pZFwiXG4gICAgcmV0dXJuIGlkZW50aXR5QXNWYWx1ZVR5cGUoZXhwcmVzc2lvbi5yZXNvbHV0aW9uLnJldHVyblR5cGUsIGV4cHJlc3Npb24ubG9jYXRpb24sIGZhaWwpXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlJlZmVyZW5jZUNvbnN0cnVjdGlvblwiKSB7XG4gICAgY29uc3QgcmVmZXJlbmNlVHlwZSA9IHZhbGlkYXRlVmFsdWVUeXBlUmVmZXJlbmNlKGV4cHJlc3Npb24ucmVmZXJlbmNlLCBleHByZXNzaW9uLmxvY2F0aW9uLCBmYWlsLCB1bmRlZmluZWQsIHJlY29yZHMsXG4gICAgICBzY29wZS50eXBlUGFyYW1ldGVycylcblxuICAgIGlmIChyZWZlcmVuY2VUeXBlLmtpbmQgIT0gXCJSZWZlcmVuY2VUeXBlXCIgJiYgcmVmZXJlbmNlVHlwZS5raW5kICE9IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIlJlZmVyZW5jZSBjb25zdHJ1Y3Rpb24gcmVxdWlyZXMgYSBub21pbmFsIHJlZmVyZW5jZSBjbGFzcyB0eXBlLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IHJlZmVyZW5jZUNsYXNzZXNGb3IocmVjb3JkcykuZ2V0KHJlZmVyZW5jZVR5cGUuZGVjbGFyYXRpb25JZClcblxuICAgIGlmICghZGVjbGFyYXRpb24pIHJldHVybiBmYWlsKFwiVU5LTk9XTl9DTEFTU1wiLCBgVW5rbm93biByZWZlcmVuY2UgY2xhc3MgJyR7cmVmZXJlbmNlVHlwZS5kZWNsYXJhdGlvbklkfScuYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICBpZiAoIWlzRGVuc2VBcnJheShleHByZXNzaW9uLmFyZ3VtZW50cykpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIkNvbnN0cnVjdG9yIGFyZ3VtZW50cyBtdXN0IGJlIGEgZGVuc2Ugb3JkZXJlZCBhcnJheS5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKGV4cHJlc3Npb24uYXJndW1lbnRzLmxlbmd0aCAhPSBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJDT05TVFJVQ1RPUl9BUklUWV9NSVNNQVRDSFwiLFxuICAgICAgICBgQ29uc3RydWN0b3IgZm9yICcke2RlY2xhcmF0aW9uLm5hbWV9JyBoYXMgJHtleHByZXNzaW9uLmFyZ3VtZW50cy5sZW5ndGh9IGFyZ3VtZW50czsgZXhwZWN0ZWQgJHtkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzLmxlbmd0aH0uYCxcbiAgICAgICAgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgcGFyYW1ldGVyVHlwZXMgPSBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PlxuICAgICAgdmFsaWRhdGVWYWx1ZVR5cGVSZWZlcmVuY2UocGFyYW1ldGVyLnR5cGUsIHBhcmFtZXRlci5sb2NhdGlvbiwgZmFpbCwgdW5kZWZpbmVkLCByZWNvcmRzKSlcblxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBleHByZXNzaW9uLmFyZ3VtZW50cy5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgIGV4cHJlc3Npb24uYXJndW1lbnRzW2luZGV4XSA9IG5vcm1hbGl6ZU93bmVkTW92ZShleHByZXNzaW9uLmFyZ3VtZW50c1tpbmRleF0sIHBhcmFtZXRlclR5cGVzW2luZGV4XSwgbm9ybWFsaXplT3BlcmF0aW9ucywgZmFpbClcbiAgICAgIGNvbnN0IGFjdHVhbCA9IGluZmVyVmFsdWVFeHByZXNzaW9uVHlwZShleHByZXNzaW9uLmFyZ3VtZW50c1tpbmRleF0sIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsXG4gICAgICAgIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYSBjb25zdHJ1Y3RvciBhcmd1bWVudFwiLCBwYXJhbWV0ZXJUeXBlc1tpbmRleF0pXG5cbiAgICAgIGlmICghc2FtZVR5cGUoYWN0dWFsLCBwYXJhbWV0ZXJUeXBlc1tpbmRleF0pKSB7XG4gICAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBDb25zdHJ1Y3RvciBhcmd1bWVudCB0eXBlICR7dHlwZURlc2NyaXB0aW9uKGFjdHVhbCl9OyBleHBlY3RlZCAke3R5cGVEZXNjcmlwdGlvbihwYXJhbWV0ZXJUeXBlc1tpbmRleF0pfS5gLFxuICAgICAgICAgIGV4cHJlc3Npb24uYXJndW1lbnRzW2luZGV4XS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgcmVzb2x1dGlvbiA9IHtcbiAgICAgIGRlY2xhcmF0aW9uSWQ6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uY29uc3RydWN0b3IuaWQpLFxuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmVzb2x2ZWRDb25zdHJ1Y3RvclNpZ25hdHVyZVwiKSxcbiAgICAgIHBhcmFtZXRlclR5cGVzOiBwYXJhbWV0ZXJUeXBlcy5tYXAoKHR5cGUpID0+IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVJZGVudGl0eX0gKi8gKHR5cGVJZGVudGl0eSh0eXBlKSkpXG4gICAgfVxuXG4gICAgaWYgKG5vcm1hbGl6ZU9wZXJhdGlvbnMpIGV4cHJlc3Npb24ucmVzb2x1dGlvbiA9IHJlc29sdXRpb25cbiAgICBlbHNlIHZhbGlkYXRlUmVmZXJlbmNlUmVzb2x1dGlvbihleHByZXNzaW9uLnJlc29sdXRpb24sIHJlc29sdXRpb24sIGV4cHJlc3Npb24ubG9jYXRpb24sIGZhaWwsIFwiY29uc3RydWN0b3JcIilcblxuICAgIHJldHVybiByZWZlcmVuY2VUeXBlXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCIpIHtcbiAgICBjb25zdCByZWNlaXZlclR5cGUgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbi5yZWNlaXZlciwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCxcbiAgICAgIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYSBtZXRob2QgcmVjZWl2ZXJcIilcblxuICAgIGlmIChyZWNlaXZlclR5cGUua2luZCAhPSBcIlJlZmVyZW5jZVR5cGVcIiAmJiByZWNlaXZlclR5cGUua2luZCAhPSBcIk93bmVkUmVmZXJlbmNlVHlwZVwiKSB7XG4gICAgICByZXR1cm4gZmFpbChcIklOVkFMSURfTUVUSE9EX1JFQ0VJVkVSXCIsIFwiTWV0aG9kIGNhbGwgcmVjZWl2ZXIgbXVzdCBoYXZlIGEgcmVmZXJlbmNlIGNsYXNzIHR5cGUuXCIsIGV4cHJlc3Npb24ucmVjZWl2ZXIubG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gcmVmZXJlbmNlQ2xhc3Nlc0ZvcihyZWNvcmRzKS5nZXQocmVjZWl2ZXJUeXBlLmRlY2xhcmF0aW9uSWQpXG5cbiAgICBpZiAoIWRlY2xhcmF0aW9uKSByZXR1cm4gZmFpbChcIlVOS05PV05fQ0xBU1NcIiwgYFVua25vd24gcmVmZXJlbmNlIGNsYXNzICcke3JlY2VpdmVyVHlwZS5kZWNsYXJhdGlvbklkfScuYCwgZXhwcmVzc2lvbi5yZWNlaXZlci5sb2NhdGlvbilcbiAgICBjb25zdCBtZXRob2QgPSBkZWNsYXJhdGlvbi5tZXRob2RzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLmlkID09IGV4cHJlc3Npb24ubWV0aG9kKSA/P1xuICAgICAgKG5vcm1hbGl6ZU9wZXJhdGlvbnMgPyBkZWNsYXJhdGlvbi5tZXRob2RzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLm5hbWUgPT0gZXhwcmVzc2lvbi5tZXRob2QpIDogdW5kZWZpbmVkKVxuXG4gICAgaWYgKCFtZXRob2QpIHJldHVybiBmYWlsKFwiVU5LTk9XTl9NRVRIT0RcIiwgYENsYXNzICcke2RlY2xhcmF0aW9uLm5hbWV9JyBoYXMgbm8gbWV0aG9kICcke2V4cHJlc3Npb24ubWV0aG9kfScuYCxcbiAgICAgIHJvbGVMb2NhdGlvbihleHByZXNzaW9uLCBcIm1lbWJlclwiKSlcbiAgICBpZiAobm9ybWFsaXplT3BlcmF0aW9ucykgZXhwcmVzc2lvbi5tZXRob2QgPSAvKiogQHR5cGUge3N0cmluZ30gKi8gKG1ldGhvZC5pZClcbiAgICBpZiAoIWlzRGVuc2VBcnJheShleHByZXNzaW9uLmFyZ3VtZW50cykpIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIk1ldGhvZCBhcmd1bWVudHMgbXVzdCBiZSBhIGRlbnNlIG9yZGVyZWQgYXJyYXkuXCIsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgaWYgKGV4cHJlc3Npb24uYXJndW1lbnRzLmxlbmd0aCAhPSBtZXRob2QucGFyYW1ldGVycy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiTUVUSE9EX0FSSVRZX01JU01BVENIXCIsXG4gICAgICAgIGBNZXRob2QgJyR7bWV0aG9kLm5hbWV9JyBoYXMgJHtleHByZXNzaW9uLmFyZ3VtZW50cy5sZW5ndGh9IGFyZ3VtZW50czsgZXhwZWN0ZWQgJHttZXRob2QucGFyYW1ldGVycy5sZW5ndGh9LmAsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IHBhcmFtZXRlclR5cGVzID0gbWV0aG9kLnBhcmFtZXRlcnMubWFwKChwYXJhbWV0ZXIpID0+XG4gICAgICB2YWxpZGF0ZVZhbHVlVHlwZVJlZmVyZW5jZShwYXJhbWV0ZXIudHlwZSwgcGFyYW1ldGVyLmxvY2F0aW9uLCBmYWlsLCB1bmRlZmluZWQsIHJlY29yZHMpKVxuXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGV4cHJlc3Npb24uYXJndW1lbnRzLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgICAgZXhwcmVzc2lvbi5hcmd1bWVudHNbaW5kZXhdID0gbm9ybWFsaXplT3duZWRNb3ZlKGV4cHJlc3Npb24uYXJndW1lbnRzW2luZGV4XSwgcGFyYW1ldGVyVHlwZXNbaW5kZXhdLCBub3JtYWxpemVPcGVyYXRpb25zLCBmYWlsKVxuICAgICAgY29uc3QgYWN0dWFsID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKGV4cHJlc3Npb24uYXJndW1lbnRzW2luZGV4XSwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCxcbiAgICAgICAgbm9ybWFsaXplT3BlcmF0aW9ucywgXCJhIG1ldGhvZCBhcmd1bWVudFwiLCBwYXJhbWV0ZXJUeXBlc1tpbmRleF0pXG5cbiAgICAgIGlmICghc2FtZVR5cGUoYWN0dWFsLCBwYXJhbWV0ZXJUeXBlc1tpbmRleF0pKSB7XG4gICAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBNZXRob2QgYXJndW1lbnQgdHlwZSAke3R5cGVEZXNjcmlwdGlvbihhY3R1YWwpfTsgZXhwZWN0ZWQgJHt0eXBlRGVzY3JpcHRpb24ocGFyYW1ldGVyVHlwZXNbaW5kZXhdKX0uYCxcbiAgICAgICAgICBleHByZXNzaW9uLmFyZ3VtZW50c1tpbmRleF0ubG9jYXRpb24pXG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHJldHVyblR5cGUgPSB2YWxpZGF0ZVJldHVyblR5cGVSZWZlcmVuY2UobWV0aG9kLnJldHVyblR5cGUsIG1ldGhvZC5sb2NhdGlvbiwgZmFpbCwgcmVjb3JkcylcbiAgICBjb25zdCByZXNvdXJjZUZsb3cgPSBkZWNsYXJhdGlvbi5vd25lcnNoaXA/LmtpbmQgPT0gXCJvd25lZFJlc291cmNlXCJcbiAgICAgID8gb3duZWRNZXRob2RSZXNvdXJjZUZsb3coZGVjbGFyYXRpb24sIG1ldGhvZCwgZmFpbCkgOiB1bmRlZmluZWRcbiAgICBjb25zdCByZXNvbHV0aW9uID0ge1xuICAgICAgZGVjbGFyYXRpb25JZDogLyoqIEB0eXBlIHtzdHJpbmd9ICovIChtZXRob2QuaWQpLFxuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmVzb2x2ZWRNZXRob2RTaWduYXR1cmVcIiksXG4gICAgICBwYXJhbWV0ZXJUeXBlczogcGFyYW1ldGVyVHlwZXMubWFwKCh0eXBlKSA9PiAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlSWRlbnRpdHl9ICovICh0eXBlSWRlbnRpdHkodHlwZSkpKSxcbiAgICAgIHJldHVyblR5cGU6IHR5cGVJZGVudGl0eShyZXR1cm5UeXBlKSxcbiAgICAgIC4uLihyZXNvdXJjZUZsb3cgPyB7cmVzb3VyY2VGbG93fSA6IHt9KVxuICAgIH1cblxuICAgIGlmIChleHByZXNzaW9uLnJlY2VpdmVyLmtpbmQgPT0gXCJPd25lZEJvcnJvd0V4cHJlc3Npb25cIiAmJiByZXNvdXJjZUZsb3cpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkTW9kZSA9IHJlc291cmNlRmxvdy5raW5kID09IFwidGVybWluYWxcIiA/IFwiZXhjbHVzaXZlXCIgOiBcInNoYXJlZFwiXG5cbiAgICAgIGlmIChleHByZXNzaW9uLnJlY2VpdmVyLm1vZGUgIT0gZXhwZWN0ZWRNb2RlKSB7XG4gICAgICAgIGZhaWwoXCJJTlZBTElEX1JFU09VUkNFX0JPUlJPV1wiLCBgSU5WQUxJRF9SRVNPVVJDRV9CT1JST1c6IE93bmVkIG1ldGhvZCByZXF1aXJlcyBhbiBpbW1lZGlhdGUgJHtleHBlY3RlZE1vZGV9IHJlY2VpdmVyIGJvcnJvdy5gLFxuICAgICAgICAgIGV4cHJlc3Npb24ucmVjZWl2ZXIubG9jYXRpb24pXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHJlY2VpdmVyVHlwZS5raW5kID09IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIgJiYgZXhwcmVzc2lvbi5yZWNlaXZlci5raW5kICE9IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIpIHtcbiAgICAgIGlmICghbm9ybWFsaXplT3BlcmF0aW9ucykgZmFpbChcIklOVkFMSURfUkVTT1VSQ0VfQk9SUk9XXCIsIFwiT3duZWQgbWV0aG9kIHJlY2VpdmVyIHJlcXVpcmVzIGFuIGltbWVkaWF0ZSBib3Jyb3cuXCIsIGV4cHJlc3Npb24ucmVjZWl2ZXIubG9jYXRpb24pXG4gICAgICBpZiAoZXhwcmVzc2lvbi5yZWNlaXZlci5raW5kICE9IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIikge1xuICAgICAgICBmYWlsKFwiQk9SUk9XX0VTQ0FQRVwiLCBcIk93bmVkIG1ldGhvZCByZWNlaXZlciBib3Jyb3cgbXVzdCBuYW1lIG9uZSBpbW1lZGlhdGUgYmluZGluZy5cIiwgZXhwcmVzc2lvbi5yZWNlaXZlci5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGV4cHJlc3Npb24ucmVjZWl2ZXIgPSB7XG4gICAgICAgIGV4cHJlc3Npb246IGV4cHJlc3Npb24ucmVjZWl2ZXIsXG4gICAgICAgIGtpbmQ6IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIsXG4gICAgICAgIGxvY2F0aW9uOiBleHByZXNzaW9uLnJlY2VpdmVyLmxvY2F0aW9uLFxuICAgICAgICBtb2RlOiByZXNvdXJjZUZsb3c/LmtpbmQgPT0gXCJ0ZXJtaW5hbFwiID8gXCJleGNsdXNpdmVcIiA6IFwic2hhcmVkXCIsXG4gICAgICAgIHNvdXJjZVByb3ZlbmFuY2U6IGV4cHJlc3Npb24ucmVjZWl2ZXIuc291cmNlUHJvdmVuYW5jZSxcbiAgICAgICAgdHlwZTogcmVjZWl2ZXJUeXBlXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG5vcm1hbGl6ZU9wZXJhdGlvbnMpIGV4cHJlc3Npb24ucmVzb2x1dGlvbiA9IHJlc29sdXRpb25cbiAgICBlbHNlIHZhbGlkYXRlUmVmZXJlbmNlUmVzb2x1dGlvbihleHByZXNzaW9uLnJlc29sdXRpb24sIHJlc29sdXRpb24sIGV4cHJlc3Npb24ubG9jYXRpb24sIGZhaWwsIFwibWV0aG9kXCIpXG5cbiAgICByZXR1cm4gaXNWb2lkVHlwZShyZXR1cm5UeXBlKSA/IFwidm9pZFwiIDogcmV0dXJuVHlwZVxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJSZWNvcmRDb25zdHJ1Y3Rpb25cIikge1xuICAgIGNvbnN0IHJlY29yZFR5cGUgPSB2YWxpZGF0ZVZhbHVlVHlwZVJlZmVyZW5jZShleHByZXNzaW9uLnJlY29yZCwgZXhwcmVzc2lvbi5sb2NhdGlvbiwgZmFpbCwgdW5kZWZpbmVkLCByZWNvcmRzLCBzY29wZS50eXBlUGFyYW1ldGVycylcblxuICAgIGlmIChyZWNvcmRUeXBlLmtpbmQgIT0gXCJSZWNvcmRUeXBlXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIlJlY29yZCBjb25zdHJ1Y3Rpb24gcmVxdWlyZXMgYSBub21pbmFsIHJlY29yZCB0eXBlLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IHJlY29yZHMuZ2V0KHJlY29yZFR5cGUuZGVjbGFyYXRpb25JZClcblxuICAgIGlmICghZGVjbGFyYXRpb24pIHJldHVybiBmYWlsKFwiVU5LTk9XTl9SRUNPUkRcIiwgYFVua25vd24gcmVjb3JkIGRlY2xhcmF0aW9uICcke3JlY29yZFR5cGUuZGVjbGFyYXRpb25JZH0nLmAsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGV4cHJlc3Npb24uYXJndW1lbnRzKSB8fCBleHByZXNzaW9uLmFyZ3VtZW50cy5zb21lKChfYXJndW1lbnQsIGluZGV4KSA9PiAhT2JqZWN0Lmhhc093bihleHByZXNzaW9uLmFyZ3VtZW50cywgaW5kZXgpKSkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiUmVjb3JkIGNvbnN0cnVjdGlvbiBhcmd1bWVudHMgbXVzdCBiZSBhIGRlbnNlIG9yZGVyZWQgYXJyYXkuXCIsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChleHByZXNzaW9uLmFyZ3VtZW50cy5sZW5ndGggIT0gZGVjbGFyYXRpb24uZmllbGRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhaWwoXG4gICAgICAgIFwiUkVDT1JEX0FSSVRZX01JU01BVENIXCIsXG4gICAgICAgIGBSZWNvcmQgJyR7ZGVjbGFyYXRpb24ubmFtZX0nIGNvbnN0cnVjdGlvbiBoYXMgJHtleHByZXNzaW9uLmFyZ3VtZW50cy5sZW5ndGh9IGFyZ3VtZW50czsgZXhwZWN0ZWQgJHtkZWNsYXJhdGlvbi5maWVsZHMubGVuZ3RofS5gLFxuICAgICAgICBleHByZXNzaW9uLmxvY2F0aW9uXG4gICAgICApXG4gICAgfVxuICAgIGNvbnN0IHN1YnN0aXR1dGlvbnMgPSByZWNvcmRUeXBlU3Vic3RpdHV0aW9ucyhyZWNvcmRUeXBlLCBkZWNsYXJhdGlvbilcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgZXhwcmVzc2lvbi5hcmd1bWVudHMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBhcmd1bWVudCA9IGV4cHJlc3Npb24uYXJndW1lbnRzW2luZGV4XVxuICAgICAgY29uc3QgZmllbGQgPSBkZWNsYXJhdGlvbi5maWVsZHNbaW5kZXhdXG4gICAgICBjb25zdCBmaWVsZFR5cGUgPSBzdWJzdGl0dXRlVmFsdWVUeXBlKGZpZWxkLnR5cGUsIHN1YnN0aXR1dGlvbnMpXG4gICAgICBjb25zdCBhY3R1YWwgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoXG4gICAgICAgIGFyZ3VtZW50LCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCBgcmVjb3JkIGZpZWxkICcke2ZpZWxkLm5hbWV9J2AsIGZpZWxkVHlwZVxuICAgICAgKVxuXG4gICAgICBpZiAoIXNhbWVUeXBlKGFjdHVhbCwgZmllbGRUeXBlKSkge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgUmVjb3JkIGZpZWxkICcke2ZpZWxkLm5hbWV9JyBhcmd1bWVudCB0eXBlICR7dHlwZURlc2NyaXB0aW9uKGFjdHVhbCl9OyBleHBlY3RlZCAke3R5cGVEZXNjcmlwdGlvbihmaWVsZFR5cGUpfS5gLCBhcmd1bWVudC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVjb3JkVHlwZVxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJNZW1iZXJSZWFkXCIpIHtcbiAgICBjb25zdCByZWNlaXZlclR5cGUgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbi5yZWNlaXZlciwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgXCJhIG1lbWJlciByZWNlaXZlclwiKVxuXG4gICAgaWYgKHJlY2VpdmVyVHlwZS5raW5kICE9IFwiUmVjb3JkVHlwZVwiKSB7XG4gICAgICByZXR1cm4gZmFpbChcIklOVkFMSURfTUVNQkVSX1JFQ0VJVkVSXCIsIGBNZW1iZXIgcmVjZWl2ZXIgdHlwZSAke3R5cGVEZXNjcmlwdGlvbihyZWNlaXZlclR5cGUpfTsgZXhwZWN0ZWQgcmVjb3JkLmAsIGV4cHJlc3Npb24ucmVjZWl2ZXIubG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gcmVjb3Jkcy5nZXQocmVjZWl2ZXJUeXBlLmRlY2xhcmF0aW9uSWQpXG5cbiAgICBpZiAoIWRlY2xhcmF0aW9uKSByZXR1cm4gZmFpbChcIlVOS05PV05fUkVDT1JEXCIsIGBVbmtub3duIHJlY29yZCBkZWNsYXJhdGlvbiAnJHtyZWNlaXZlclR5cGUuZGVjbGFyYXRpb25JZH0nLmAsIGV4cHJlc3Npb24ucmVjZWl2ZXIubG9jYXRpb24pXG4gICAgY29uc3QgZmllbGQgPSBkZWNsYXJhdGlvbi5maWVsZHMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUuaWQgPT0gZXhwcmVzc2lvbi5maWVsZCkgPz9cbiAgICAgIChub3JtYWxpemVPcGVyYXRpb25zID8gZGVjbGFyYXRpb24uZmllbGRzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLm5hbWUgPT0gZXhwcmVzc2lvbi5maWVsZCkgOiB1bmRlZmluZWQpXG5cbiAgICBpZiAoIWZpZWxkKSBmYWlsKFwiVU5LTk9XTl9GSUVMRFwiLCBgUmVjb3JkICcke2RlY2xhcmF0aW9uLm5hbWV9JyBoYXMgbm8gZmllbGQgJyR7ZXhwcmVzc2lvbi5maWVsZH0nLmAsIHJvbGVMb2NhdGlvbihleHByZXNzaW9uLCBcIm1lbWJlclwiKSlcbiAgICBpZiAobm9ybWFsaXplT3BlcmF0aW9ucykgZXhwcmVzc2lvbi5maWVsZCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZmllbGQuaWQpXG5cbiAgICByZXR1cm4gc3Vic3RpdHV0ZVZhbHVlVHlwZShmaWVsZC50eXBlLCByZWNvcmRUeXBlU3Vic3RpdHV0aW9ucyhyZWNlaXZlclR5cGUsIGRlY2xhcmF0aW9uKSlcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IGZ1bmN0aW9uRGVjbGFyYXRpb24gPSBmdW5jdGlvbnMuZ2V0KGV4cHJlc3Npb24uY2FsbGVlKVxuXG4gICAgaWYgKCFmdW5jdGlvbkRlY2xhcmF0aW9uKSB7XG4gICAgICByZXR1cm4gZmFpbChcIlVOUkVTT0xWRURfQklORElOR1wiLCBgVW5rbm93biBmdW5jdGlvbiAnJHtleHByZXNzaW9uLmNhbGxlZX0nLmAsIHJvbGVMb2NhdGlvbihleHByZXNzaW9uLCBcImNhbGxlZVwiKSlcbiAgICB9XG4gICAgaWYgKGV4cHJlc3Npb24uYXJndW1lbnRzLmxlbmd0aCAhPSBmdW5jdGlvbkRlY2xhcmF0aW9uLnBhcmFtZXRlcnMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYENhbGwgYXJndW1lbnQgY291bnQgZm9yICcke2V4cHJlc3Npb24uY2FsbGVlfScuYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgZGVjbGFyYXRpb25UeXBlUGFyYW1ldGVycyA9IGRlY2xhcmF0aW9uVHlwZVBhcmFtZXRlcklkcyhmdW5jdGlvbkRlY2xhcmF0aW9uKVxuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZT59ICovXG4gICAgY29uc3Qgc3Vic3RpdHV0aW9ucyA9IG5ldyBNYXAoKVxuICAgIGNvbnN0IHBhcmFtZXRlclR5cGVzID0gZnVuY3Rpb25EZWNsYXJhdGlvbi5wYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PiB2YWxpZGF0ZVZhbHVlVHlwZVJlZmVyZW5jZShcbiAgICAgIHBhcmFtZXRlci50eXBlLCBwYXJhbWV0ZXIubG9jYXRpb24sIGZhaWwsIHVuZGVmaW5lZCwgcmVjb3JkcywgZGVjbGFyYXRpb25UeXBlUGFyYW1ldGVyc1xuICAgICkpXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGV4cHJlc3Npb24uYXJndW1lbnRzLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgICAgZXhwcmVzc2lvbi5hcmd1bWVudHNbaW5kZXhdID0gbm9ybWFsaXplT3duZWRNb3ZlKGV4cHJlc3Npb24uYXJndW1lbnRzW2luZGV4XSwgcGFyYW1ldGVyVHlwZXNbaW5kZXhdLCBub3JtYWxpemVPcGVyYXRpb25zLCBmYWlsKVxuICAgIH1cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgZXhwcmVzc2lvbi5hcmd1bWVudHMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCBhcmd1bWVudCA9IGV4cHJlc3Npb24uYXJndW1lbnRzW2luZGV4XVxuICAgICAgY29uc3QgZXhwZWN0ZWRUeXBlID0gcGFyYW1ldGVyVHlwZXNbaW5kZXhdXG4gICAgICBjb25zdCBnYXRoZXJzR2VuZXJpY0V2aWRlbmNlID0gdHlwZUNvbnRhaW5zQW55VmFyaWFibGUoZXhwZWN0ZWRUeXBlKVxuXG4gICAgICBpZiAoZ2F0aGVyc0dlbmVyaWNFdmlkZW5jZSkge1xuICAgICAgICBpbmZlckdlbmVyaWNBcmd1bWVudEV2aWRlbmNlKGV4cGVjdGVkVHlwZSwgYXJndW1lbnQsIHN1YnN0aXR1dGlvbnMsIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsXG4gICAgICAgICAgbm9ybWFsaXplT3BlcmF0aW9ucylcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFjdHVhbFR5cGUgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoXG4gICAgICAgIGFyZ3VtZW50LCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLCBcImEgY2FsbCBhcmd1bWVudFwiLCBleHBlY3RlZFR5cGVcbiAgICAgIClcblxuICAgICAgaWYgKChmdW5jdGlvbkRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzPy5sZW5ndGggPz8gMCkgPiAwKSB7XG4gICAgICAgIGluZmVyVHlwZUFyZ3VtZW50cyhleHBlY3RlZFR5cGUsIGFjdHVhbFR5cGUsIHN1YnN0aXR1dGlvbnMsIGFyZ3VtZW50LmxvY2F0aW9uLCBmYWlsKVxuICAgICAgfSBlbHNlIGlmICghc2FtZVR5cGUoYWN0dWFsVHlwZSwgZXhwZWN0ZWRUeXBlKSkge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgQ2FsbCBhcmd1bWVudCB0eXBlICR7dHlwZURlc2NyaXB0aW9uKGFjdHVhbFR5cGUpfTsgZXhwZWN0ZWQgJHt0eXBlRGVzY3JpcHRpb24oZXhwZWN0ZWRUeXBlKX0uYCwgYXJndW1lbnQubG9jYXRpb24pXG4gICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIGZ1bmN0aW9uRGVjbGFyYXRpb24udHlwZVBhcmFtZXRlcnMgPz8gW10pIHtcbiAgICAgIGlmICghc3Vic3RpdHV0aW9ucy5oYXMoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChwYXJhbWV0ZXIuaWQpKSkge1xuICAgICAgICBjb25zdCBldmlkZW5jZUZyZWVJbmRleCA9IHBhcmFtZXRlclR5cGVzLmZpbmRJbmRleCgodHlwZSkgPT5cbiAgICAgICAgICB0eXBlQ29udGFpbnNWYXJpYWJsZSh0eXBlLCAvKiogQHR5cGUge3N0cmluZ30gKi8gKHBhcmFtZXRlci5pZCkpKVxuXG4gICAgICAgIGlmIChldmlkZW5jZUZyZWVJbmRleCA+PSAwKSB7XG4gICAgICAgICAgZmFpbChcIkdFTkVSSUNfSU5GRVJFTkNFX0ZBSUxVUkVcIiwgXCJDYW5ub3QgaW5mZXIgYSB0eXBlIHBhcmFtZXRlciBmcm9tIGFuIGV2aWRlbmNlLWZyZWUgY2FsbCBhcmd1bWVudC5cIixcbiAgICAgICAgICAgIGV4cHJlc3Npb24uYXJndW1lbnRzW2V2aWRlbmNlRnJlZUluZGV4XS5sb2NhdGlvbilcbiAgICAgICAgfVxuICAgICAgICBmYWlsKFwiR0VORVJJQ19JTkZFUkVOQ0VfRkFJTFVSRVwiLCBgQ2Fubm90IGluZmVyIHR5cGUgcGFyYW1ldGVyICcke3BhcmFtZXRlci5uYW1lfScgZnJvbSBjYWxsIGFyZ3VtZW50cy5gLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoWy4uLnN1YnN0aXR1dGlvbnMudmFsdWVzKCldLnNvbWUoKHR5cGUpID0+IGNvbnRhaW5zT3duZWRUeXBlKHR5cGUpKSkge1xuICAgICAgZmFpbChcIlJFU09VUkNFX0FMSUFTXCIsIFwiT3duZWQgcmVzb3VyY2VzIGFuZCByZWZlcmVuY2VzIGNhbm5vdCBiZSBpbmZlcnJlZCBhcyBnZW5lcmljIGFyZ3VtZW50cy5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGZ1bmN0aW9uRGVjbGFyYXRpb24ucGFyYW1ldGVycy5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gc3Vic3RpdHV0ZVZhbHVlVHlwZShmdW5jdGlvbkRlY2xhcmF0aW9uLnBhcmFtZXRlcnNbaW5kZXhdLnR5cGUsIHN1YnN0aXR1dGlvbnMpXG4gICAgICBjb25zdCBhY3R1YWwgPSBpbmZlclZhbHVlRXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbi5hcmd1bWVudHNbaW5kZXhdLCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLFxuICAgICAgICBub3JtYWxpemVPcGVyYXRpb25zLCBcImEgY2FsbCBhcmd1bWVudFwiLCBleHBlY3RlZClcblxuICAgICAgaWYgKCFzYW1lVHlwZShhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgQ2FsbCBhcmd1bWVudCB0eXBlICR7dHlwZURlc2NyaXB0aW9uKGFjdHVhbCl9OyBleHBlY3RlZCAke3R5cGVEZXNjcmlwdGlvbihleHBlY3RlZCl9LmAsIGV4cHJlc3Npb24uYXJndW1lbnRzW2luZGV4XS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgcmVzb2x1dGlvbiA9IHNpZ25hdHVyZUZvcihmdW5jdGlvbkRlY2xhcmF0aW9uLCByZWNvcmRzLCBmYWlsLCBzdWJzdGl0dXRpb25zKVxuXG4gICAgaWYgKG5vcm1hbGl6ZU9wZXJhdGlvbnMpIGV4cHJlc3Npb24ucmVzb2x1dGlvbiA9IHJlc29sdXRpb25cbiAgICBlbHNlIHZhbGlkYXRlUmVzb2x1dGlvbihleHByZXNzaW9uLnJlc29sdXRpb24sIHJlc29sdXRpb24sIGV4cHJlc3Npb24ubG9jYXRpb24sIGZhaWwpXG4gICAgY29uc3QgcmV0dXJuVHlwZSA9IHN1YnN0aXR1dGVSZXR1cm5UeXBlKHZhbGlkYXRlUmV0dXJuVHlwZVJlZmVyZW5jZShmdW5jdGlvbkRlY2xhcmF0aW9uLnJldHVyblR5cGUsXG4gICAgICBmdW5jdGlvbkRlY2xhcmF0aW9uLmxvY2F0aW9uLCBmYWlsLCByZWNvcmRzLCBkZWNsYXJhdGlvblR5cGVQYXJhbWV0ZXJzKSwgc3Vic3RpdHV0aW9ucylcblxuICAgIHJldHVybiBpc1ZvaWRUeXBlKHJldHVyblR5cGUpID8gXCJ2b2lkXCIgOiByZXR1cm5UeXBlXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgY29uc3Qgb3BlcmFuZCA9IGluZmVyVmFsdWVFeHByZXNzaW9uVHlwZShleHByZXNzaW9uLm9wZXJhbmQsIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYSB1bmFyeSBvcGVyYW5kXCIpXG4gICAgY29uc3Qgb3BlcmFuZFR5cGUgPSBzY2FsYXJOYW1lRm9yT3BlcmF0aW9uKG9wZXJhbmQsIGV4cHJlc3Npb24ub3BlcmFuZC5sb2NhdGlvbiwgZmFpbClcbiAgICBjb25zdCBvcGVyYXRpb24gPSBub3JtYWxpemVPcGVyYXRpb25zXG4gICAgICA/IG5vcm1hbGl6ZVVuYXJ5T3BlcmF0aW9uKGFkYXB0ZWRPcGVyYXRpb25Gb3IoZXhwcmVzc2lvbiksIG9wZXJhbmRUeXBlLCBleHByZXNzaW9uLm9wZXJhbmQubG9jYXRpb24sIGZhaWwpXG4gICAgICA6IGV4cHJlc3Npb24ub3BlcmF0aW9uXG5cbiAgICBpZiAobm9ybWFsaXplT3BlcmF0aW9ucykgc2V0Tm9ybWFsaXplZE9wZXJhdGlvbihleHByZXNzaW9uLCBvcGVyYXRpb24sIHVuYXJ5T3BlcmF0aW9uU2lnbmF0dXJlc1tvcGVyYXRpb25dLnJlc3VsdClcblxuICAgIGNvbnN0IHNpZ25hdHVyZSA9IHVuYXJ5T3BlcmF0aW9uU2lnbmF0dXJlc1tvcGVyYXRpb25dXG5cbiAgICBpZiAoIXNpZ25hdHVyZSkgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBVbmtub3duIHVuYXJ5IG9wZXJhdGlvbiAke1N0cmluZyhvcGVyYXRpb24pfS5gLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIGlmIChvcGVyYW5kVHlwZSAhPSBzaWduYXR1cmUub3BlcmFuZCkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJJTlZBTElEX09QRVJBTkRfVFlQRVwiLCBgJHtvcGVyYXRpb259IHJlcXVpcmVzICR7c2lnbmF0dXJlLm9wZXJhbmR9OyByZWNlaXZlZCAke29wZXJhbmRUeXBlfS5gLCBleHByZXNzaW9uLm9wZXJhbmQubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChleHByZXNzaW9uLnR5cGUgIT0gc2lnbmF0dXJlLnJlc3VsdCkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGAke29wZXJhdGlvbn0gcmVzdWx0IHR5cGUgJHtTdHJpbmcoZXhwcmVzc2lvbi50eXBlKX07IGV4cGVjdGVkICR7c2lnbmF0dXJlLnJlc3VsdH0uYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgcmV0dXJuIHNjYWxhclR5cGUoc2lnbmF0dXJlLnJlc3VsdClcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQmluYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgY29uc3QgbGVmdCA9IGluZmVyVmFsdWVFeHByZXNzaW9uVHlwZShleHByZXNzaW9uLmxlZnQsIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYSBiaW5hcnkgb3BlcmFuZFwiKVxuICAgIGNvbnN0IHJpZ2h0ID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKGV4cHJlc3Npb24ucmlnaHQsIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYSBiaW5hcnkgb3BlcmFuZFwiKVxuICAgIGNvbnN0IGxlZnRUeXBlID0gc2NhbGFyTmFtZUZvck9wZXJhdGlvbihsZWZ0LCBleHByZXNzaW9uLmxlZnQubG9jYXRpb24sIGZhaWwpXG4gICAgY29uc3QgcmlnaHRUeXBlID0gc2NhbGFyTmFtZUZvck9wZXJhdGlvbihyaWdodCwgZXhwcmVzc2lvbi5yaWdodC5sb2NhdGlvbiwgZmFpbClcbiAgICBjb25zdCBvcGVyYXRpb24gPSBub3JtYWxpemVPcGVyYXRpb25zXG4gICAgICA/IG5vcm1hbGl6ZUJpbmFyeU9wZXJhdGlvbihhZGFwdGVkT3BlcmF0aW9uRm9yKGV4cHJlc3Npb24pLCBsZWZ0VHlwZSwgcmlnaHRUeXBlLCBleHByZXNzaW9uLmxlZnQubG9jYXRpb24sIGV4cHJlc3Npb24ucmlnaHQubG9jYXRpb24sIGV4cHJlc3Npb24ubG9jYXRpb24sIGZhaWwpXG4gICAgICA6IGV4cHJlc3Npb24ub3BlcmF0aW9uXG5cbiAgICBpZiAobm9ybWFsaXplT3BlcmF0aW9ucykgc2V0Tm9ybWFsaXplZE9wZXJhdGlvbihleHByZXNzaW9uLCBvcGVyYXRpb24sIGJpbmFyeU9wZXJhdGlvblNpZ25hdHVyZXNbb3BlcmF0aW9uXS5yZXN1bHQpXG5cbiAgICBjb25zdCBzaWduYXR1cmUgPSBiaW5hcnlPcGVyYXRpb25TaWduYXR1cmVzW29wZXJhdGlvbl1cblxuICAgIGlmICghc2lnbmF0dXJlKSByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYFVua25vd24gYmluYXJ5IG9wZXJhdGlvbiAke1N0cmluZyhvcGVyYXRpb24pfS5gLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIGlmIChsZWZ0VHlwZSAhPSBzaWduYXR1cmUubGVmdCkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJJTlZBTElEX09QRVJBTkRfVFlQRVwiLCBgJHtvcGVyYXRpb259IHJlcXVpcmVzICR7c2lnbmF0dXJlLmxlZnR9IGxlZnQgb3BlcmFuZDsgcmVjZWl2ZWQgJHtsZWZ0VHlwZX0uYCwgZXhwcmVzc2lvbi5sZWZ0LmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAocmlnaHRUeXBlICE9IHNpZ25hdHVyZS5yaWdodCkge1xuICAgICAgcmV0dXJuIGZhaWwoXCJJTlZBTElEX09QRVJBTkRfVFlQRVwiLCBgJHtvcGVyYXRpb259IHJlcXVpcmVzICR7c2lnbmF0dXJlLnJpZ2h0fSByaWdodCBvcGVyYW5kOyByZWNlaXZlZCAke3JpZ2h0VHlwZX0uYCwgZXhwcmVzc2lvbi5yaWdodC5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKGV4cHJlc3Npb24udHlwZSAhPSBzaWduYXR1cmUucmVzdWx0KSB7XG4gICAgICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYCR7b3BlcmF0aW9ufSByZXN1bHQgdHlwZSAke1N0cmluZyhleHByZXNzaW9uLnR5cGUpfTsgZXhwZWN0ZWQgJHtzaWduYXR1cmUucmVzdWx0fS5gLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICByZXR1cm4gc2NhbGFyVHlwZShzaWduYXR1cmUucmVzdWx0KVxuICB9XG5cbiAgY29uc3QgdW5leHBlY3RlZCA9IC8qKiBAdHlwZSB7e2tpbmQ6IHN0cmluZywgbG9jYXRpb246IGltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259fSAqLyAoZXhwcmVzc2lvbilcblxuICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgdW5leHBlY3RlZC5raW5kLCB1bmV4cGVjdGVkLmxvY2F0aW9uKVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBtYXAgbGF5b3V0IGFuZCBmaXhlZCBzdHJpbmcga2V5cyBpbmRlcGVuZGVudGx5IG9mIGNvbnRleHR1YWwgdmFsdWUgaW5mZXJlbmNlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLk1hcExpdGVyYWwgfCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLk9yZGVyZWRNYXBMaXRlcmFsfSBleHByZXNzaW9uIC0gQ2FuZGlkYXRlIG1hcCBsaXRlcmFsLlxuICogQHBhcmFtIHtTY29wZX0gc2NvcGUgLSBWaXNpYmxlIGxleGljYWwgc2NvcGUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4vdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbj59IGZ1bmN0aW9ucyAtIE1vZHVsZSBmdW5jdGlvbiBzaWduYXR1cmVzLlxuICogQHBhcmFtIHtSZWNvcmRSZWdpc3RyeX0gcmVjb3JkcyAtIFJlY29yZCBkZWNsYXJhdGlvbnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5vcm1hbGl6ZU9wZXJhdGlvbnMgLSBXaGV0aGVyIHRvIG5vcm1hbGl6ZSBmcm9udGVuZCBpbnRlbnQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGluZmVyQ29sbGVjdGlvbkVsZW1lbnRzIC0gV2hldGhlciBuZXN0ZWQgY29sbGVjdGlvbiBldmlkZW5jZSBtYXkgYmUgaW5mZXJyZWQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5NYXBFbnRyeVtdfSBWYWxpZGF0ZWQgZGVuc2UgZW50cmllcy5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVNYXBMaXRlcmFsRW50cmllcyhleHByZXNzaW9uLCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLCBub3JtYWxpemVPcGVyYXRpb25zLFxuICBpbmZlckNvbGxlY3Rpb25FbGVtZW50cykge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoZXhwcmVzc2lvbi5lbnRyaWVzKSkge1xuICAgIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIk1hcCBsaXRlcmFsIGVudHJpZXMgbXVzdCBiZSBhIGRlbnNlIHNvdXJjZS1vcmRlcmVkIGFycmF5LlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICB9XG4gIGlmICghaXNEZW5zZUFycmF5KGV4cHJlc3Npb24uZW50cmllcykpIHtcbiAgICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgXCJTcGFyc2UgbWFwIGxpdGVyYWxzIGFyZSBvdXRzaWRlIHRoZSBpbXBsZW1lbnRlZCBzdWJzZXQuXCIsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gIH1cbiAgY29uc3Qga2V5cyA9IG5ldyBTZXQoKVxuXG4gIGZvciAoY29uc3QgZW50cnkgb2YgZXhwcmVzc2lvbi5lbnRyaWVzKSB7XG4gICAgaWYgKCFlbnRyeSB8fCBlbnRyeS5raW5kICE9IFwiTWFwRW50cnlcIiB8fCAhZW50cnkua2V5IHx8IGVudHJ5LmtleS5raW5kICE9IFwiU3RyaW5nTGl0ZXJhbFwiKSB7XG4gICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIk1hcCBlbnRyaWVzIHJlcXVpcmUgbGl0ZXJhbCBzdHJpbmcga2V5cy5cIiwgZW50cnk/LmxvY2F0aW9uID8/IGV4cHJlc3Npb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGluZmVyVmFsdWVFeHByZXNzaW9uVHlwZShlbnRyeS5rZXksIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYSBtYXAga2V5XCIsXG4gICAgICBzY2FsYXJUeXBlKFwic3RyaW5nXCIpLCBpbmZlckNvbGxlY3Rpb25FbGVtZW50cylcbiAgICBpZiAoaXNOdW1lcmljU3RyaW5nKGVudHJ5LmtleS52YWx1ZSkpIHtcbiAgICAgIGZhaWwoXCJJTlZBTElEX01BUF9LRVlcIiwgXCJNYXAgaW5pdGlhbGl6ZXIga2V5cyBtdXN0IGJlIG5vbm51bWVyaWMgc3RyaW5ncy5cIiwgZW50cnkua2V5LmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoa2V5cy5oYXMoZW50cnkua2V5LnZhbHVlKSkge1xuICAgICAgZmFpbChcIkRVUExJQ0FURV9NQVBfS0VZXCIsIGBEdXBsaWNhdGUgJHtleHByZXNzaW9uLmtpbmQgPT0gXCJPcmRlcmVkTWFwTGl0ZXJhbFwiID8gXCJvcmRlcmVkLW1hcFwiIDogXCJtYXBcIn0ga2V5ICcke2VudHJ5LmtleS52YWx1ZX0nLmAsXG4gICAgICAgIGVudHJ5LmtleS5sb2NhdGlvbilcbiAgICB9XG4gICAga2V5cy5hZGQoZW50cnkua2V5LnZhbHVlKVxuICB9XG5cbiAgcmV0dXJuIGV4cHJlc3Npb24uZW50cmllc1xufVxuXG4vKipcbiAqIENvbGxlY3RzIGFyZ3VtZW50LW9ubHkgZ2VuZXJpYyBldmlkZW5jZSB3aGlsZSBkZWZlcnJpbmcgcmVjdXJzaXZlbHkgY29udGV4dHVhbCBsaXRlcmFscy5cbiAqIFRoZSBjb21wbGV0ZSBhcmd1bWVudCBpcyB2YWxpZGF0ZWQgYWdhaW5zdCBpdHMgY2xvc2VkIHN1YnN0aXR1dGVkIHR5cGUgYWZ0ZXIgaW5mZXJlbmNlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVmFsdWVUeXBlfSBmb3JtYWwgLSBPcGVuIGRlY2xhcmF0aW9uIHBhcmFtZXRlciB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBDYWxsIGFyZ3VtZW50IG9yIG5lc3RlZCBjb2xsZWN0aW9uIHZhbHVlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVmFsdWVUeXBlPn0gc3Vic3RpdHV0aW9ucyAtIEluZmVyZW5jZSBzdGF0ZS5cbiAqIEBwYXJhbSB7U2NvcGV9IHNjb3BlIC0gVmlzaWJsZSBsZXhpY2FsIHNjb3BlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb24+fSBmdW5jdGlvbnMgLSBNb2R1bGUgZnVuY3Rpb24gc2lnbmF0dXJlcy5cbiAqIEBwYXJhbSB7UmVjb3JkUmVnaXN0cnl9IHJlY29yZHMgLSBSZWNvcmQgZGVjbGFyYXRpb25zIGJ5IGlkZW50aXR5LlxuICogQHBhcmFtIHtTZW1hbnRpY0ZhaWx9IGZhaWwgLSBEaWFnbm9zdGljIGNhbGxiYWNrLlxuICogQHBhcmFtIHtib29sZWFufSBub3JtYWxpemVPcGVyYXRpb25zIC0gV2hldGhlciB0byBub3JtYWxpemUgZnJvbnRlbmQgaW50ZW50LlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIGluZmVyR2VuZXJpY0FyZ3VtZW50RXZpZGVuY2UoZm9ybWFsLCBleHByZXNzaW9uLCBzdWJzdGl0dXRpb25zLCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLFxuICBub3JtYWxpemVPcGVyYXRpb25zKSB7XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbE5vbmVcIikgcmV0dXJuXG4gIGlmIChmb3JtYWwua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiICYmIGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsU29tZVwiKSB7XG4gICAgaW5mZXJHZW5lcmljQXJndW1lbnRFdmlkZW5jZShmb3JtYWwudmFsdWVUeXBlLCBleHByZXNzaW9uLnZhbHVlLCBzdWJzdGl0dXRpb25zLCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLFxuICAgICAgbm9ybWFsaXplT3BlcmF0aW9ucylcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZm9ybWFsLmtpbmQgPT0gXCJMaXN0VHlwZVwiICYmIGV4cHJlc3Npb24ua2luZCA9PSBcIkxpc3RMaXRlcmFsXCIpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZXhwcmVzc2lvbi5lbGVtZW50cykpIHtcbiAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiTGlzdCBsaXRlcmFsIGVsZW1lbnRzIG11c3QgYmUgYSBkZW5zZSBzb3VyY2Utb3JkZXJlZCBhcnJheS5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKCFpc0RlbnNlQXJyYXkoZXhwcmVzc2lvbi5lbGVtZW50cykpIHtcbiAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiU3BhcnNlIGxpc3QgbGl0ZXJhbHMgYXJlIG91dHNpZGUgdGhlIGltcGxlbWVudGVkIHN1YnNldC5cIiwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIGV4cHJlc3Npb24uZWxlbWVudHMpIHtcbiAgICAgIGluZmVyR2VuZXJpY0FyZ3VtZW50RXZpZGVuY2UoZm9ybWFsLmVsZW1lbnRUeXBlLCBlbGVtZW50LCBzdWJzdGl0dXRpb25zLCBzY29wZSwgZnVuY3Rpb25zLCByZWNvcmRzLCBmYWlsLFxuICAgICAgICBub3JtYWxpemVPcGVyYXRpb25zKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBpZiAoKGZvcm1hbC5raW5kID09IFwiTWFwVHlwZVwiICYmIGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExpdGVyYWxcIikgfHxcbiAgICAoZm9ybWFsLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiICYmIGV4cHJlc3Npb24ua2luZCA9PSBcIk9yZGVyZWRNYXBMaXRlcmFsXCIpKSB7XG4gICAgY29uc3QgZW50cmllcyA9IHZhbGlkYXRlTWFwTGl0ZXJhbEVudHJpZXMoZXhwcmVzc2lvbiwgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCwgbm9ybWFsaXplT3BlcmF0aW9ucywgdHJ1ZSlcblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgaW5mZXJHZW5lcmljQXJndW1lbnRFdmlkZW5jZShmb3JtYWwudmFsdWVUeXBlLCBlbnRyeS52YWx1ZSwgc3Vic3RpdHV0aW9ucywgc2NvcGUsIGZ1bmN0aW9ucywgcmVjb3JkcywgZmFpbCxcbiAgICAgICAgbm9ybWFsaXplT3BlcmF0aW9ucylcbiAgICB9XG4gICAgcmV0dXJuXG4gIH1cbiAgY29uc3QgYWN0dWFsID0gaW5mZXJWYWx1ZUV4cHJlc3Npb25UeXBlKFxuICAgIGV4cHJlc3Npb24sIHNjb3BlLCBmdW5jdGlvbnMsIHJlY29yZHMsIGZhaWwsIG5vcm1hbGl6ZU9wZXJhdGlvbnMsIFwiYSBjYWxsIGFyZ3VtZW50XCIsIHVuZGVmaW5lZCwgdHJ1ZVxuICApXG5cbiAgaW5mZXJUeXBlQXJndW1lbnRzKGZvcm1hbCwgYWN0dWFsLCBzdWJzdGl0dXRpb25zLCBleHByZXNzaW9uLmxvY2F0aW9uLCBmYWlsKVxufVxuXG4vKipcbiAqIFVuaWZpZXMgb25lIGRlY2xhcmF0aW9uLW93bmVkIGZvcm1hbCB0eXBlIHdpdGggb25lIGFyZ3VtZW50IHR5cGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IGZvcm1hbCAtIEdlbmVyaWMgc2lnbmF0dXJlIHR5cGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IGFjdHVhbCAtIEluZmVycmVkIGFyZ3VtZW50IHR5cGUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGU+fSBzdWJzdGl0dXRpb25zIC0gSW5mZXJlbmNlIHN0YXRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIEFyZ3VtZW50IGxvY2F0aW9uLlxuICogQHBhcmFtIHtTZW1hbnRpY0ZhaWx9IGZhaWwgLSBEaWFnbm9zdGljIGNhbGxiYWNrLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIGluZmVyVHlwZUFyZ3VtZW50cyhmb3JtYWwsIGFjdHVhbCwgc3Vic3RpdHV0aW9ucywgbG9jYXRpb24sIGZhaWwpIHtcbiAgaWYgKGZvcm1hbC5raW5kID09IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHtcbiAgICBjb25zdCBwcmlvciA9IHN1YnN0aXR1dGlvbnMuZ2V0KGZvcm1hbC5wYXJhbWV0ZXJJZClcblxuICAgIGlmIChwcmlvcikge1xuICAgICAgaWYgKCFzYW1lVHlwZShwcmlvciwgYWN0dWFsKSkge1xuICAgICAgICBmYWlsKFwiR0VORVJJQ19JTkZFUkVOQ0VfQ09ORkxJQ1RcIiwgYENvbmZsaWN0aW5nIGluZmVyZW5jZSBmb3IgdHlwZSBwYXJhbWV0ZXIgJyR7Zm9ybWFsLnBhcmFtZXRlcklkfScuYCwgbG9jYXRpb24pXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKCEoYWN0dWFsLmtpbmQgPT0gXCJUeXBlVmFyaWFibGVSZWZlcmVuY2VcIiAmJiBhY3R1YWwucGFyYW1ldGVySWQgPT0gZm9ybWFsLnBhcmFtZXRlcklkKSAmJlxuICAgICAgdHlwZUNvbnRhaW5zVmFyaWFibGUoYWN0dWFsLCBmb3JtYWwucGFyYW1ldGVySWQpKSB7XG4gICAgICBmYWlsKFwiR0VORVJJQ19JTkZFUkVOQ0VfUkVDVVJTSU9OXCIsIGBSZWN1cnNpdmUgaW5mZXJlbmNlIGZvciB0eXBlIHBhcmFtZXRlciAnJHtmb3JtYWwucGFyYW1ldGVySWR9Jy5gLCBsb2NhdGlvbilcbiAgICB9XG4gICAgc3Vic3RpdHV0aW9ucy5zZXQoZm9ybWFsLnBhcmFtZXRlcklkLCBhY3R1YWwpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGZvcm1hbC5raW5kICE9IGFjdHVhbC5raW5kKSB7XG4gICAgZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYENhbGwgYXJndW1lbnQgdHlwZSAke3R5cGVEZXNjcmlwdGlvbihhY3R1YWwpfTsgZXhwZWN0ZWQgJHt0eXBlRGVzY3JpcHRpb24oZm9ybWFsKX0uYCwgbG9jYXRpb24pXG4gIH1cbiAgaWYgKGZvcm1hbC5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiKSB7XG4gICAgaWYgKCFzYW1lVHlwZShmb3JtYWwsIGFjdHVhbCkpIHtcbiAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBDYWxsIGFyZ3VtZW50IHR5cGUgJHt0eXBlRGVzY3JpcHRpb24oYWN0dWFsKX07IGV4cGVjdGVkICR7dHlwZURlc2NyaXB0aW9uKGZvcm1hbCl9LmAsIGxvY2F0aW9uKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZm9ybWFsLmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIgJiYgYWN0dWFsLmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIpIHtcbiAgICBpZiAoZm9ybWFsLmRlY2xhcmF0aW9uSWQgIT0gYWN0dWFsLmRlY2xhcmF0aW9uSWQpIHtcbiAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBDYWxsIGFyZ3VtZW50IHR5cGUgJHt0eXBlRGVzY3JpcHRpb24oYWN0dWFsKX07IGV4cGVjdGVkICR7dHlwZURlc2NyaXB0aW9uKGZvcm1hbCl9LmAsIGxvY2F0aW9uKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZm9ybWFsLmtpbmQgPT0gXCJSZWNvcmRUeXBlXCIgJiYgYWN0dWFsLmtpbmQgPT0gXCJSZWNvcmRUeXBlXCIpIHtcbiAgICBpZiAoZm9ybWFsLmRlY2xhcmF0aW9uSWQgIT0gYWN0dWFsLmRlY2xhcmF0aW9uSWQgfHwgKGZvcm1hbC5hcmd1bWVudHM/Lmxlbmd0aCA/PyAwKSAhPSAoYWN0dWFsLmFyZ3VtZW50cz8ubGVuZ3RoID8/IDApKSB7XG4gICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgQ2FsbCBhcmd1bWVudCB0eXBlICR7dHlwZURlc2NyaXB0aW9uKGFjdHVhbCl9OyBleHBlY3RlZCAke3R5cGVEZXNjcmlwdGlvbihmb3JtYWwpfS5gLCBsb2NhdGlvbilcbiAgICB9XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IChmb3JtYWwuYXJndW1lbnRzPy5sZW5ndGggPz8gMCk7IGluZGV4ICs9IDEpIHtcbiAgICAgIGluZmVyVHlwZUFyZ3VtZW50cygvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9ICovIChmb3JtYWwuYXJndW1lbnRzPy5baW5kZXhdKSxcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVmFsdWVUeXBlfSAqLyAoYWN0dWFsLmFyZ3VtZW50cz8uW2luZGV4XSksIHN1YnN0aXR1dGlvbnMsIGxvY2F0aW9uLCBmYWlsKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZm9ybWFsLmtpbmQgPT0gXCJMaXN0VHlwZVwiICYmIGFjdHVhbC5raW5kID09IFwiTGlzdFR5cGVcIikge1xuICAgIGluZmVyVHlwZUFyZ3VtZW50cyhmb3JtYWwuZWxlbWVudFR5cGUsIGFjdHVhbC5lbGVtZW50VHlwZSwgc3Vic3RpdHV0aW9ucywgbG9jYXRpb24sIGZhaWwpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGZvcm1hbC5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIgJiYgYWN0dWFsLmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgIGluZmVyVHlwZUFyZ3VtZW50cyhmb3JtYWwudmFsdWVUeXBlLCBhY3R1YWwudmFsdWVUeXBlLCBzdWJzdGl0dXRpb25zLCBsb2NhdGlvbiwgZmFpbClcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoKGZvcm1hbC5raW5kID09IFwiTWFwVHlwZVwiICYmIGFjdHVhbC5raW5kID09IFwiTWFwVHlwZVwiKSB8fFxuICAgIChmb3JtYWwua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCIgJiYgYWN0dWFsLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSkge1xuICAgIGluZmVyVHlwZUFyZ3VtZW50cyhmb3JtYWwua2V5VHlwZSwgYWN0dWFsLmtleVR5cGUsIHN1YnN0aXR1dGlvbnMsIGxvY2F0aW9uLCBmYWlsKVxuICAgIGluZmVyVHlwZUFyZ3VtZW50cyhmb3JtYWwudmFsdWVUeXBlLCBhY3R1YWwudmFsdWVUeXBlLCBzdWJzdGl0dXRpb25zLCBsb2NhdGlvbiwgZmFpbClcbiAgfVxufVxuXG4vKipcbiAqIENoZWNrcyB0aGUgb2NjdXJzIGNvbnN0cmFpbnQgZm9yIGZpcnN0LW9yZGVyIGluZmVyZW5jZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gdHlwZSAtIENhbmRpZGF0ZSBpbmZlcnJlZCB0eXBlLlxuICogQHBhcmFtIHtzdHJpbmd9IHBhcmFtZXRlcklkIC0gUGFyYW1ldGVyIGJlaW5nIGluZmVycmVkLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHR5cGUgcmVjdXJzaXZlbHkgY29udGFpbnMgdGhlIHBhcmFtZXRlci5cbiAqL1xuZnVuY3Rpb24gdHlwZUNvbnRhaW5zVmFyaWFibGUodHlwZSwgcGFyYW1ldGVySWQpIHtcbiAgaWYgKHR5cGUua2luZCA9PSBcIlR5cGVWYXJpYWJsZVJlZmVyZW5jZVwiKSByZXR1cm4gdHlwZS5wYXJhbWV0ZXJJZCA9PSBwYXJhbWV0ZXJJZFxuICBpZiAodHlwZS5raW5kID09IFwiUmVjb3JkVHlwZVwiKSByZXR1cm4gdHlwZS5hcmd1bWVudHM/LnNvbWUoKGFyZ3VtZW50KSA9PiB0eXBlQ29udGFpbnNWYXJpYWJsZShhcmd1bWVudCwgcGFyYW1ldGVySWQpKSA/PyBmYWxzZVxuICBpZiAodHlwZS5raW5kID09IFwiTGlzdFR5cGVcIikgcmV0dXJuIHR5cGVDb250YWluc1ZhcmlhYmxlKHR5cGUuZWxlbWVudFR5cGUsIHBhcmFtZXRlcklkKVxuICBpZiAodHlwZS5raW5kID09IFwiTWFwVHlwZVwiIHx8IHR5cGUua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCIpIHtcbiAgICByZXR1cm4gdHlwZUNvbnRhaW5zVmFyaWFibGUodHlwZS5rZXlUeXBlLCBwYXJhbWV0ZXJJZCkgfHwgdHlwZUNvbnRhaW5zVmFyaWFibGUodHlwZS52YWx1ZVR5cGUsIHBhcmFtZXRlcklkKVxuICB9XG4gIGlmICh0eXBlLmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIikgcmV0dXJuIHR5cGVDb250YWluc1ZhcmlhYmxlKHR5cGUudmFsdWVUeXBlLCBwYXJhbWV0ZXJJZClcblxuICByZXR1cm4gZmFsc2Vcbn1cblxuLyoqXG4gKiBBcHBsaWVzIHN1YnN0aXR1dGlvbnMgdG8gYSB2YWx1ZSBvciB2b2lkIHJldHVybiB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSB0eXBlIC0gT3BlbiByZXR1cm4gdHlwZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZT59IHN1YnN0aXR1dGlvbnMgLSBDbG9zZWQgc3Vic3RpdHV0aW9ucy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSBTdWJzdGl0dXRlZCByZXR1cm4gdHlwZS5cbiAqL1xuZnVuY3Rpb24gc3Vic3RpdHV0ZVJldHVyblR5cGUodHlwZSwgc3Vic3RpdHV0aW9ucykge1xuICByZXR1cm4gaXNWb2lkVHlwZSh0eXBlKSA/IHR5cGUgOiBzdWJzdGl0dXRlVmFsdWVUeXBlKHR5cGUsIHN1YnN0aXR1dGlvbnMpXG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBleGFjdCBzZW1hbnRpYyBzaWduYXR1cmUgYm91bmQgdG8gb25lIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb259IGRlY2xhcmF0aW9uIC0gUmVzb2x2ZWQgZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0ge1JlY29yZFJlZ2lzdHJ5fSByZWNvcmRzIC0gUmVjb3JkIGRlY2xhcmF0aW9ucyBieSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZT59IFtzdWJzdGl0dXRpb25zXSAtIEluZmVycmVkIGdlbmVyaWMgc3Vic3RpdHV0aW9ucy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlJlc29sdmVkRnVuY3Rpb25TaWduYXR1cmV9IERldGFjaGVkIHNpZ25hdHVyZSBiaW5kaW5nLlxuICovXG5mdW5jdGlvbiBzaWduYXR1cmVGb3IoZGVjbGFyYXRpb24sIHJlY29yZHMsIGZhaWwsIHN1YnN0aXR1dGlvbnMgPSBuZXcgTWFwKCkpIHtcbiAgY29uc3QgdHlwZVBhcmFtZXRlcnMgPSBkZWNsYXJhdGlvblR5cGVQYXJhbWV0ZXJJZHMoZGVjbGFyYXRpb24pXG4gIGNvbnN0IGRlY2xhcmVkUGFyYW1ldGVycyA9IGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzID8/IFtdXG4gIGNvbnN0IHBhcmFtZXRlclR5cGVzID0gZGVjbGFyYXRpb24ucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT5cbiAgICBzdWJzdGl0dXRlVmFsdWVUeXBlKHZhbGlkYXRlVmFsdWVUeXBlUmVmZXJlbmNlKHBhcmFtZXRlci50eXBlLCBwYXJhbWV0ZXIubG9jYXRpb24sIGZhaWwsIHVuZGVmaW5lZCwgcmVjb3JkcywgdHlwZVBhcmFtZXRlcnMpLCBzdWJzdGl0dXRpb25zKSlcbiAgY29uc3QgcmV0dXJuVHlwZSA9IHN1YnN0aXR1dGVSZXR1cm5UeXBlKFxuICAgIHZhbGlkYXRlUmV0dXJuVHlwZVJlZmVyZW5jZShkZWNsYXJhdGlvbi5yZXR1cm5UeXBlLCBkZWNsYXJhdGlvbi5sb2NhdGlvbiwgZmFpbCwgcmVjb3JkcywgdHlwZVBhcmFtZXRlcnMpLCBzdWJzdGl0dXRpb25zKVxuXG4gIHJldHVybiB7XG4gICAgZGVjbGFyYXRpb25JZDogLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksXG4gICAga2luZDogXCJSZXNvbHZlZEZ1bmN0aW9uU2lnbmF0dXJlXCIsXG4gICAgcGFyYW1ldGVyVHlwZXM6IHBhcmFtZXRlclR5cGVzLm1hcCgodHlwZSkgPT4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZUlkZW50aXR5fSAqLyAodHlwZUlkZW50aXR5KHR5cGUpKSksXG4gICAgcmV0dXJuVHlwZTogdHlwZUlkZW50aXR5KHJldHVyblR5cGUpLFxuICAgIC4uLihkZWNsYXJlZFBhcmFtZXRlcnMubGVuZ3RoID4gMCA/IHtcbiAgICAgIHR5cGVBcmd1bWVudHM6IGRlY2xhcmVkUGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT5cbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZUlkZW50aXR5fSAqLyAodHlwZUlkZW50aXR5KC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gKi8gKFxuICAgICAgICAgIHN1YnN0aXR1dGlvbnMuZ2V0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAocGFyYW1ldGVyLmlkKSlcbiAgICAgICAgKSkpKVxuICAgIH0gOiB7fSlcbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBhbiBleHRlcm5hbGx5IHN1cHBsaWVkIGNhbGwgYmluZGluZyBhZ2FpbnN0IHRoZSBkZWNsYXJhdGlvbiBjb2xsZWN0ZWQgZm9yIHRoaXMgbW9kdWxlLlxuICogQHBhcmFtIHt1bmtub3dufSBhY3R1YWwgLSBDYW5kaWRhdGUgY2FsbCByZXNvbHV0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlJlc29sdmVkRnVuY3Rpb25TaWduYXR1cmV9IGV4cGVjdGVkIC0gRXhhY3QgZGVjbGFyYXRpb24gc2lnbmF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIENhbGwgbG9jYXRpb24uXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVSZXNvbHV0aW9uKGFjdHVhbCwgZXhwZWN0ZWQsIGxvY2F0aW9uLCBmYWlsKSB7XG4gIGNvbnN0IGV4cGVjdGVkS2V5cyA9IGV4cGVjdGVkLnR5cGVBcmd1bWVudHMgPyBcImRlY2xhcmF0aW9uSWQsa2luZCxwYXJhbWV0ZXJUeXBlcyxyZXR1cm5UeXBlLHR5cGVBcmd1bWVudHNcIiA6XG4gICAgXCJkZWNsYXJhdGlvbklkLGtpbmQscGFyYW1ldGVyVHlwZXMscmV0dXJuVHlwZVwiXG5cbiAgaWYgKCFhY3R1YWwgfHwgdHlwZW9mIGFjdHVhbCAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoYWN0dWFsKSB8fFxuICAgIE9iamVjdC5rZXlzKGFjdHVhbCkuc29ydCgpLmpvaW4oXCIsXCIpICE9IGV4cGVjdGVkS2V5cykge1xuICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiQ2FsbCBpcyBtaXNzaW5nIGFuIGV4YWN0IHJlc29sdmVkIGZ1bmN0aW9uIHNpZ25hdHVyZS5cIiwgbG9jYXRpb24pXG4gIH1cbiAgY29uc3QgY2FuZGlkYXRlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlJlc29sdmVkRnVuY3Rpb25TaWduYXR1cmV9ICovIChhY3R1YWwpXG5cbiAgaWYgKGNhbmRpZGF0ZS5raW5kICE9IFwiUmVzb2x2ZWRGdW5jdGlvblNpZ25hdHVyZVwiIHx8IHR5cGVvZiBjYW5kaWRhdGUuZGVjbGFyYXRpb25JZCAhPSBcInN0cmluZ1wiIHx8XG4gICAgIUFycmF5LmlzQXJyYXkoY2FuZGlkYXRlLnBhcmFtZXRlclR5cGVzKSB8fCAhdmFsaWRUeXBlSWRlbnRpdHkoY2FuZGlkYXRlLnJldHVyblR5cGUsIHRydWUpIHx8XG4gICAgY2FuZGlkYXRlLmRlY2xhcmF0aW9uSWQgIT0gZXhwZWN0ZWQuZGVjbGFyYXRpb25JZCB8fFxuICAgICFzYW1lVHlwZUlkZW50aXR5KGNhbmRpZGF0ZS5yZXR1cm5UeXBlLCBleHBlY3RlZC5yZXR1cm5UeXBlKSB8fCBjYW5kaWRhdGUucGFyYW1ldGVyVHlwZXMubGVuZ3RoICE9IGV4cGVjdGVkLnBhcmFtZXRlclR5cGVzLmxlbmd0aCkge1xuICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiQ2FsbCByZXNvbHV0aW9uIGRvZXMgbm90IG1hdGNoIGl0cyBkZWNsYXJhdGlvbiBzaWduYXR1cmUuXCIsIGxvY2F0aW9uKVxuICB9XG4gIGlmIChleHBlY3RlZC50eXBlQXJndW1lbnRzKSB7XG4gICAgY29uc3QgY2FuZGlkYXRlVHlwZUFyZ3VtZW50cyA9IGNhbmRpZGF0ZS50eXBlQXJndW1lbnRzXG5cbiAgICBpZiAoIWlzRGVuc2VBcnJheShjYW5kaWRhdGVUeXBlQXJndW1lbnRzKSB8fCBjYW5kaWRhdGVUeXBlQXJndW1lbnRzLmxlbmd0aCAhPSBleHBlY3RlZC50eXBlQXJndW1lbnRzLmxlbmd0aCB8fFxuICAgICAgY2FuZGlkYXRlVHlwZUFyZ3VtZW50cy5zb21lKCh0eXBlLCBpbmRleCkgPT5cbiAgICAgICAgIXZhbGlkVHlwZUlkZW50aXR5KHR5cGUsIGZhbHNlKSB8fCAhc2FtZVR5cGVJZGVudGl0eSh0eXBlLCBleHBlY3RlZC50eXBlQXJndW1lbnRzPy5baW5kZXhdKSkpIHtcbiAgICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiQ2FsbCByZXNvbHV0aW9uIGRvZXMgbm90IG1hdGNoIGl0cyBpbmZlcnJlZCB0eXBlIGFyZ3VtZW50cy5cIiwgbG9jYXRpb24pXG4gICAgfVxuICB9XG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBjYW5kaWRhdGUucGFyYW1ldGVyVHlwZXMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgY29uc3QgdHlwZSA9IGNhbmRpZGF0ZS5wYXJhbWV0ZXJUeXBlc1tpbmRleF1cblxuICAgIGlmICghT2JqZWN0Lmhhc093bihjYW5kaWRhdGUucGFyYW1ldGVyVHlwZXMsIGluZGV4KSB8fCAhdmFsaWRUeXBlSWRlbnRpdHkodHlwZSwgZmFsc2UpIHx8XG4gICAgICAhc2FtZVR5cGVJZGVudGl0eSh0eXBlLCBleHBlY3RlZC5wYXJhbWV0ZXJUeXBlc1tpbmRleF0pKSB7XG4gICAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIkNhbGwgcmVzb2x1dGlvbiBkb2VzIG5vdCBtYXRjaCBpdHMgZGVjbGFyYXRpb24gc2lnbmF0dXJlLlwiLCBsb2NhdGlvbilcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgZXhhY3QgY2FsbGVyLW93bmVkIGNvbnN0cnVjdG9yIG9yIG1ldGhvZCByZXNvbHV0aW9uIG1ldGFkYXRhLlxuICogQHBhcmFtIHt1bmtub3dufSBhY3R1YWwgLSBDYW5kaWRhdGUgcmVzb2x1dGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5SZXNvbHZlZENvbnN0cnVjdG9yU2lnbmF0dXJlIHwgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5SZXNvbHZlZE1ldGhvZFNpZ25hdHVyZX0gZXhwZWN0ZWQgLSBFeGFjdCByZXNvbHV0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIEV4cHJlc3Npb24gbG9jYXRpb24uXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcGFyYW0ge1wiY29uc3RydWN0b3JcIiB8IFwibWV0aG9kXCJ9IHJvbGUgLSBSZXNvbHV0aW9uIHJvbGUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVSZWZlcmVuY2VSZXNvbHV0aW9uKGFjdHVhbCwgZXhwZWN0ZWQsIGxvY2F0aW9uLCBmYWlsLCByb2xlKSB7XG4gIGNvbnN0IGV4cGVjdGVkTWV0aG9kID0gcm9sZSA9PSBcIm1ldGhvZFwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlJlc29sdmVkTWV0aG9kU2lnbmF0dXJlfSAqLyAoZXhwZWN0ZWQpIDogdW5kZWZpbmVkXG4gIGNvbnN0IGV4cGVjdGVkS2V5cyA9IHJvbGUgPT0gXCJjb25zdHJ1Y3RvclwiID8gXCJkZWNsYXJhdGlvbklkLGtpbmQscGFyYW1ldGVyVHlwZXNcIiA6XG4gICAgZXhwZWN0ZWRNZXRob2Q/LnJlc291cmNlRmxvdyA/IFwiZGVjbGFyYXRpb25JZCxraW5kLHBhcmFtZXRlclR5cGVzLHJlc291cmNlRmxvdyxyZXR1cm5UeXBlXCIgOlxuICAgICAgXCJkZWNsYXJhdGlvbklkLGtpbmQscGFyYW1ldGVyVHlwZXMscmV0dXJuVHlwZVwiXG5cbiAgaWYgKCFhY3R1YWwgfHwgdHlwZW9mIGFjdHVhbCAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoYWN0dWFsKSB8fCBPYmplY3Qua2V5cyhhY3R1YWwpLnNvcnQoKS5qb2luKFwiLFwiKSAhPSBleHBlY3RlZEtleXMpIHtcbiAgICBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBgUmVmZXJlbmNlICR7cm9sZX0gY2FsbCBpcyBtaXNzaW5nIGFuIGV4YWN0IHJlc29sdmVkICR7cm9sZX0gc2lnbmF0dXJlLmAsIGxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IGNhbmRpZGF0ZSA9IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59ICovIChhY3R1YWwpXG5cbiAgaWYgKGNhbmRpZGF0ZS5raW5kICE9IGV4cGVjdGVkLmtpbmQgfHwgY2FuZGlkYXRlLmRlY2xhcmF0aW9uSWQgIT0gZXhwZWN0ZWQuZGVjbGFyYXRpb25JZCB8fFxuICAgICFpc0RlbnNlQXJyYXkoY2FuZGlkYXRlLnBhcmFtZXRlclR5cGVzKSB8fCBjYW5kaWRhdGUucGFyYW1ldGVyVHlwZXMubGVuZ3RoICE9IGV4cGVjdGVkLnBhcmFtZXRlclR5cGVzLmxlbmd0aCB8fFxuICAgIGNhbmRpZGF0ZS5wYXJhbWV0ZXJUeXBlcy5zb21lKCh0eXBlLCBpbmRleCkgPT4gIXZhbGlkVHlwZUlkZW50aXR5KHR5cGUsIGZhbHNlKSB8fFxuICAgICAgIXNhbWVUeXBlSWRlbnRpdHkodHlwZSwgZXhwZWN0ZWQucGFyYW1ldGVyVHlwZXNbaW5kZXhdKSkgfHxcbiAgICByb2xlID09IFwibWV0aG9kXCIgJiYgKCF2YWxpZFR5cGVJZGVudGl0eShjYW5kaWRhdGUucmV0dXJuVHlwZSwgdHJ1ZSkgfHxcbiAgICAgICFzYW1lVHlwZUlkZW50aXR5KGNhbmRpZGF0ZS5yZXR1cm5UeXBlLCAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuUmVzb2x2ZWRNZXRob2RTaWduYXR1cmV9ICovIChleHBlY3RlZCkucmV0dXJuVHlwZSkgfHxcbiAgICAgIEpTT04uc3RyaW5naWZ5KGNhbmRpZGF0ZS5yZXNvdXJjZUZsb3cpICE9IEpTT04uc3RyaW5naWZ5KGV4cGVjdGVkTWV0aG9kPy5yZXNvdXJjZUZsb3cpKSkge1xuICAgIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBSZXNvbHZlZCAke3JvbGV9IHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaCBpdHMgZGVjbGFyYXRpb24uYCwgbG9jYXRpb24pXG4gIH1cbn1cblxuLyoqXG4gKiBNYWtlcyBhIHNvdXJjZSBpZGVudGlmaWVyJ3Mgb3duZXJzaGlwIHRyYW5zZmVyIGV4cGxpY2l0IGluIG5vcm1hbGl6ZWQgSVIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gZXhwcmVzc2lvbiAtIENhbmRpZGF0ZSB0cmFuc2ZlciBleHByZXNzaW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSBleHBlY3RlZCAtIERlc3RpbmF0aW9uIHR5cGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5vcm1hbGl6ZSAtIFdoZXRoZXIgcGFyc2VyIGludGVudCBtYXkgYmUgbm9ybWFsaXplZC5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gTG9jYXRlZCBmYWlsdXJlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gRXhwbGljaXQgZXhwcmVzc2lvbi5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplT3duZWRNb3ZlKGV4cHJlc3Npb24sIGV4cGVjdGVkLCBub3JtYWxpemUsIGZhaWwpIHtcbiAgaWYgKGV4cGVjdGVkLmtpbmQgIT0gXCJPd25lZFJlc291cmNlVHlwZVwiICYmIGV4cGVjdGVkLmtpbmQgIT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIikgcmV0dXJuIGV4cHJlc3Npb25cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk93bmVkTW92ZUV4cHJlc3Npb25cIikgcmV0dXJuIGV4cHJlc3Npb25cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlByaXZhdGVGaWVsZFJlYWRcIikge1xuICAgIHJldHVybiBmYWlsKFwiSU5WQUxJRF9SRVNPVVJDRV9UUkFOU0ZFUlwiLCBcIlByaXZhdGUgcmVzb3VyY2UgZmllbGRzIGNhbm5vdCBiZSBtb3ZlZCBvciBleHBvc2VkOyB0cmFuc2ZlciB0aGUgb3duaW5nIHJlZmVyZW5jZS5cIixcbiAgICAgIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCAhPSBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpIHJldHVybiBleHByZXNzaW9uXG4gIGlmICghbm9ybWFsaXplKSByZXR1cm4gZmFpbChcIlJFU09VUkNFX01PVkVfUkVRVUlSRURcIiwgXCJPd25lZCB0cmFuc2ZlciByZXF1aXJlcyBhbiBleHBsaWNpdCBtb3ZlIGV4cHJlc3Npb24uXCIsIGV4cHJlc3Npb24ubG9jYXRpb24pXG5cbiAgcmV0dXJuIHtcbiAgICBleHByZXNzaW9uLFxuICAgIGtpbmQ6IFwiT3duZWRNb3ZlRXhwcmVzc2lvblwiLFxuICAgIGxvY2F0aW9uOiBleHByZXNzaW9uLmxvY2F0aW9uLFxuICAgIHNvdXJjZVByb3ZlbmFuY2U6IGV4cHJlc3Npb24uc291cmNlUHJvdmVuYW5jZSxcbiAgICB0eXBlOiBleHBlY3RlZFxuICB9XG59XG5cbi8qKlxuICogQ2xhc3NpZmllcyB0aGUgZGVsaWJlcmF0ZWx5IGJvdW5kZWQgVGFzayAwMzQgcmVjZWl2ZXIgdHJhbnNpdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIE93bmVkIGNsYXNzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLk1ldGhvZERlY2xhcmF0aW9ufSBtZXRob2QgLSBDYW5kaWRhdGUgbWV0aG9kLlxuICogQHBhcmFtIHtTZW1hbnRpY0ZhaWx9IGZhaWwgLSBMb2NhdGVkIGZhaWx1cmUuXG4gKiBAcmV0dXJucyB7e2tpbmQ6IFwicHJlc2VydmVcIiB8IFwidGVybWluYWxcIiwgdGVybWluYWxGYWlsdXJlSWQ/OiBzdHJpbmd9fSBSZWNlaXZlciB0cmFuc2l0aW9uLlxuICovXG5mdW5jdGlvbiBvd25lZE1ldGhvZFJlc291cmNlRmxvdyhkZWNsYXJhdGlvbiwgbWV0aG9kLCBmYWlsKSB7XG4gIGNvbnN0IGVmZmVjdFN0YXRlbWVudHMgPSBtZXRob2QuYm9keS5zdGF0ZW1lbnRzLmZsYXRNYXAoKHN0YXRlbWVudCkgPT4ge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBzdGF0ZW1lbnQua2luZCA9PSBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIlJldHVyblN0YXRlbWVudFwiID8gc3RhdGVtZW50LmV4cHJlc3Npb24gOlxuICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIgPyBzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIgOiB1bmRlZmluZWRcblxuICAgIHJldHVybiBleHByZXNzaW9uPy5raW5kID09IFwiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIiA/IFtleHByZXNzaW9uXSA6IFtdXG4gIH0pXG4gIGNvbnN0IGFsbEVmZmVjdHMgPSBtZXRob2RFZmZlY3RFeHByZXNzaW9ucyhtZXRob2QuYm9keSlcblxuICBpZiAoYWxsRWZmZWN0cy5sZW5ndGggPT0gMCkgcmV0dXJuIHtraW5kOiBcInByZXNlcnZlXCJ9XG4gIGlmIChtZXRob2QuYm9keS5zdGF0ZW1lbnRzLmxlbmd0aCAhPSAxIHx8IGVmZmVjdFN0YXRlbWVudHMubGVuZ3RoICE9IDEgfHwgYWxsRWZmZWN0cy5sZW5ndGggIT0gMSB8fFxuICAgIGFsbEVmZmVjdHNbMF0gIT09IGVmZmVjdFN0YXRlbWVudHNbMF0pIHtcbiAgICByZXR1cm4gZmFpbChcIlVOU1VQUE9SVEVEX1NUQVRFTUVOVFwiLFxuICAgICAgYE93bmVkIG1ldGhvZCAnJHttZXRob2QubmFtZX0nIG11c3QgY29udGFpbiBvbmUgZGlyZWN0IHJlc291cmNlIG9wZXJhdGlvbiBvciBvbmx5IHB1cmUgc3RhdGVtZW50cy5gLCBtZXRob2QubG9jYXRpb24pXG4gIH1cbiAgY29uc3Qgb3BlcmF0aW9uID0gZWZmZWN0U3RhdGVtZW50c1swXVxuICBjb25zdCBmbG93ID0gb3BlcmF0aW9uLnJlc29sdXRpb24ucmVzb3VyY2VGbG93XG5cbiAgaWYgKGZsb3cua2luZCA9PSBcIm5vbmVcIiB8fCBmbG93LmtpbmQgPT0gXCJhY3F1aXJlXCIpIHJldHVybiB7a2luZDogXCJwcmVzZXJ2ZVwifVxuICBjb25zdCBhcmd1bWVudCA9IG9wZXJhdGlvbi5hcmd1bWVudHNbZmxvdy5wYXJhbWV0ZXJJbmRleF1cblxuICBjb25zdCBvd25lZCA9IGRlY2xhcmF0aW9uLm93bmVyc2hpcD8ua2luZCA9PSBcIm93bmVkUmVzb3VyY2VcIiA/IGRlY2xhcmF0aW9uLm93bmVyc2hpcCA6IHVuZGVmaW5lZFxuICBjb25zdCBib3Jyb3dlZFBhcmFtZXRlck5hbWUgPSBhcmd1bWVudD8ua2luZCA9PSBcIk93bmVkQm9ycm93RXhwcmVzc2lvblwiICYmIGFyZ3VtZW50LmV4cHJlc3Npb24ua2luZCA9PSBcIklkZW50aWZpZXJFeHByZXNzaW9uXCJcbiAgICA/IGFyZ3VtZW50LmV4cHJlc3Npb24ubmFtZSA6IHVuZGVmaW5lZFxuICBjb25zdCBib3Jyb3dlZFBhcmFtZXRlciA9IGJvcnJvd2VkUGFyYW1ldGVyTmFtZSAhPT0gdW5kZWZpbmVkICYmXG4gICAgbWV0aG9kLnBhcmFtZXRlcnMuc29tZSgocGFyYW1ldGVyKSA9PiBwYXJhbWV0ZXIubmFtZSA9PSBib3Jyb3dlZFBhcmFtZXRlck5hbWUgJiYgY29udGFpbnNPd25lZFR5cGUocGFyYW1ldGVyLnR5cGUpKVxuXG4gIGlmIChib3Jyb3dlZFBhcmFtZXRlcikgcmV0dXJuIHtraW5kOiBcInByZXNlcnZlXCJ9XG5cbiAgaWYgKCFhcmd1bWVudCB8fCBhcmd1bWVudC5raW5kICE9IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIgfHwgYXJndW1lbnQuZXhwcmVzc2lvbi5raW5kICE9IFwiUHJpdmF0ZUZpZWxkUmVhZFwiIHx8XG4gICAgYXJndW1lbnQuZXhwcmVzc2lvbi5maWVsZCAhPSBvd25lZD8uZmllbGRJZCkge1xuICAgIHJldHVybiBmYWlsKFwiSU5WQUxJRF9SRVNPVVJDRV9CT1JST1dcIiwgYE93bmVkIG1ldGhvZCAnJHttZXRob2QubmFtZX0nIG11c3Qgb3BlcmF0ZSBvbiBpdHMgcHJpdmF0ZSByZXNvdXJjZSBmaWVsZC5gLCBvcGVyYXRpb24ubG9jYXRpb24pXG4gIH1cbiAgcmV0dXJuIHtraW5kOiBmbG93LmtpbmQgPT0gXCJjbG9zZVwiID8gXCJ0ZXJtaW5hbFwiIDogXCJwcmVzZXJ2ZVwiLCB0ZXJtaW5hbEZhaWx1cmVJZDogZmxvdy50ZXJtaW5hbEZhaWx1cmVJZH1cbn1cblxuLyoqXG4gKiBDb2xsZWN0cyBldmVyeSBob3N0LWVmZmVjdCBzaXRlIG5lc3RlZCBpbiBvbmUgb3duZWQgbWV0aG9kIGJvZHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQmxvY2t9IGJsb2NrIC0gTWV0aG9kIGJvZHkuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FeHByZXNzaW9uW119IEVmZmVjdGZ1bCBleHByZXNzaW9ucy5cbiAqL1xuZnVuY3Rpb24gbWV0aG9kRWZmZWN0RXhwcmVzc2lvbnMoYmxvY2spIHtcbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkV4cHJlc3Npb25bXX0gKi9cbiAgY29uc3QgZWZmZWN0cyA9IFtdXG4gIGNvbnN0IHBlbmRpbmcgPSBbLyoqIEB0eXBlIHt1bmtub3dufSAqLyAoYmxvY2spXVxuICBjb25zdCBzZWVuID0gbmV3IFNldCgpXG5cbiAgd2hpbGUgKHBlbmRpbmcubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IHZhbHVlID0gcGVuZGluZy5wb3AoKVxuXG4gICAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT0gXCJvYmplY3RcIiB8fCBzZWVuLmhhcyh2YWx1ZSkpIGNvbnRpbnVlXG4gICAgc2Vlbi5hZGQodmFsdWUpXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSAmJiAoUmVmbGVjdC5nZXQodmFsdWUsIFwia2luZFwiKSA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIgfHxcbiAgICAgIHR5cGVvZiBSZWZsZWN0LmdldCh2YWx1ZSwgXCJlZmZlY3RTaXRlSWRcIikgPT0gXCJzdHJpbmdcIikpIHtcbiAgICAgIGVmZmVjdHMucHVzaCgvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKHZhbHVlKSlcbiAgICB9XG4gICAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG4gICAgICBpZiAoW1wibG9jYXRpb25cIiwgXCJyZXNvbHV0aW9uXCIsIFwic291cmNlUHJvdmVuYW5jZVwiXS5pbmNsdWRlcyhrZXkpKSBjb250aW51ZVxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGQpKSBwZW5kaW5nLnB1c2goLi4uY2hpbGQpXG4gICAgICBlbHNlIGlmIChjaGlsZCAmJiB0eXBlb2YgY2hpbGQgPT0gXCJvYmplY3RcIikgcGVuZGluZy5wdXNoKGNoaWxkKVxuICAgIH1cbiAgfVxuICByZXR1cm4gZWZmZWN0c1xufVxuXG4vKipcbiAqIFJlaHlkcmF0ZXMgYSBjbG9zZWQgY2FwYWJpbGl0eSB0eXBlIGlkZW50aXR5IGZvciBvcmRpbmFyeSBleHByZXNzaW9uIGNoZWNrcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvblJldHVyblR5cGVJZGVudGl0eX0gaWRlbnRpdHkgLSBDbG9zZWQgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gRGlhZ25vc3RpYyBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gTG9jYXRlZCBmYWlsdXJlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IFZhbHVlIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGlkZW50aXR5QXNWYWx1ZVR5cGUoaWRlbnRpdHksIGxvY2F0aW9uLCBmYWlsKSB7XG4gIGlmICh0eXBlb2YgaWRlbnRpdHkgPT0gXCJzdHJpbmdcIikge1xuICAgIGlmICghaXNTY2FsYXJUeXBlTmFtZShpZGVudGl0eSkpIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIlZvaWQgb3IgaW52YWxpZCBpZGVudGl0eSB1c2VkIGFzIGFuIGVmZmVjdCB2YWx1ZSB0eXBlLlwiLCBsb2NhdGlvbilcbiAgICByZXR1cm4gc2NhbGFyVHlwZShpZGVudGl0eSlcbiAgfVxuICBpZiAoIWlkZW50aXR5IHx8IHR5cGVvZiBpZGVudGl0eSAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoaWRlbnRpdHkpKSB7XG4gICAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIFwiTWFsZm9ybWVkIGVmZmVjdCB0eXBlIGlkZW50aXR5LlwiLCBsb2NhdGlvbilcbiAgfVxuICBjb25zdCBjYW5kaWRhdGUgPSAvKiogQHR5cGUge0V4Y2x1ZGU8aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVJZGVudGl0eSwgc3RyaW5nPn0gKi8gKGlkZW50aXR5KVxuXG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIpIHJldHVybiB7a2luZDogXCJPd25lZFJlc291cmNlVHlwZVwiLCByZXNvdXJjZUlkOiBjYW5kaWRhdGUucmVzb3VyY2VJZH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIpIHJldHVybiB7ZGVjbGFyYXRpb25JZDogY2FuZGlkYXRlLmRlY2xhcmF0aW9uSWQsIGtpbmQ6IFwiT3duZWRSZWZlcmVuY2VUeXBlXCJ9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSByZXR1cm4ge2tpbmQ6IFwiT3B0aW9uYWxUeXBlXCIsIHZhbHVlVHlwZTogaWRlbnRpdHlBc1ZhbHVlVHlwZShjYW5kaWRhdGUudmFsdWVUeXBlLCBsb2NhdGlvbiwgZmFpbCl9XG4gIHJldHVybiBmYWlsKFwiVFlQRV9NSVNNQVRDSFwiLCBcIlVuc3VwcG9ydGVkIGVmZmVjdCB0eXBlIGlkZW50aXR5LlwiLCBsb2NhdGlvbilcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHNlbWFudGljIHR5cGUgdG8gaXRzIGRldGFjaGVkIGNhbGwtcmVzb2x1dGlvbiBpZGVudGl0eS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZX0gdHlwZSAtIFZhbGlkYXRlZCBzZW1hbnRpYyB0eXBlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRnVuY3Rpb25SZXR1cm5UeXBlSWRlbnRpdHl9IERldGFjaGVkIGlkZW50aXR5LlxuICovXG5mdW5jdGlvbiB0eXBlSWRlbnRpdHkodHlwZSkge1xuICBpZiAodHlwZS5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiKSByZXR1cm4gdHlwZS5uYW1lXG4gIGlmICh0eXBlLmtpbmQgPT0gXCJUeXBlVmFyaWFibGVSZWZlcmVuY2VcIikgcmV0dXJuIHtraW5kOiBcIlR5cGVWYXJpYWJsZVJlZmVyZW5jZVwiLCBwYXJhbWV0ZXJJZDogdHlwZS5wYXJhbWV0ZXJJZH1cbiAgaWYgKHR5cGUua2luZCA9PSBcIlJlY29yZFR5cGVcIikgcmV0dXJuIHtcbiAgICBkZWNsYXJhdGlvbklkOiB0eXBlLmRlY2xhcmF0aW9uSWQsXG4gICAga2luZDogXCJSZWNvcmRUeXBlXCIsXG4gICAgLi4uKHR5cGUuYXJndW1lbnRzID8ge2FyZ3VtZW50czogdHlwZS5hcmd1bWVudHMubWFwKChhcmd1bWVudCkgPT5cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVJZGVudGl0eX0gKi8gKHR5cGVJZGVudGl0eShhcmd1bWVudCkpKX0gOiB7fSlcbiAgfVxuICBpZiAodHlwZS5raW5kID09IFwiUmVmZXJlbmNlVHlwZVwiKSByZXR1cm4ge2RlY2xhcmF0aW9uSWQ6IHR5cGUuZGVjbGFyYXRpb25JZCwga2luZDogXCJSZWZlcmVuY2VUeXBlXCJ9XG4gIGlmICh0eXBlLmtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiKSByZXR1cm4ge2tpbmQ6IFwiT3duZWRSZXNvdXJjZVR5cGVcIiwgcmVzb3VyY2VJZDogdHlwZS5yZXNvdXJjZUlkfVxuICBpZiAodHlwZS5raW5kID09IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIpIHJldHVybiB7ZGVjbGFyYXRpb25JZDogdHlwZS5kZWNsYXJhdGlvbklkLCBraW5kOiBcIk93bmVkUmVmZXJlbmNlVHlwZVwifVxuICBpZiAodHlwZS5raW5kID09IFwiTGlzdFR5cGVcIikgcmV0dXJuIHtlbGVtZW50VHlwZTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZUlkZW50aXR5fSAqLyAodHlwZUlkZW50aXR5KHR5cGUuZWxlbWVudFR5cGUpKSwga2luZDogXCJMaXN0VHlwZVwifVxuICBpZiAodHlwZS5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHJldHVybiB7a2luZDogXCJPcHRpb25hbFR5cGVcIiwgdmFsdWVUeXBlOiAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlSWRlbnRpdHl9ICovICh0eXBlSWRlbnRpdHkodHlwZS52YWx1ZVR5cGUpKX1cbiAgaWYgKHR5cGUua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCIpIHJldHVybiB7XG4gICAga2V5VHlwZTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZUlkZW50aXR5fSAqLyAodHlwZUlkZW50aXR5KHR5cGUua2V5VHlwZSkpLFxuICAgIGtpbmQ6IFwiT3JkZXJlZE1hcFR5cGVcIixcbiAgICBvcmRlcjogXCJpbnNlcnRpb25cIixcbiAgICB2YWx1ZVR5cGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVJZGVudGl0eX0gKi8gKHR5cGVJZGVudGl0eSh0eXBlLnZhbHVlVHlwZSkpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGtleVR5cGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVJZGVudGl0eX0gKi8gKHR5cGVJZGVudGl0eSh0eXBlLmtleVR5cGUpKSxcbiAgICBraW5kOiBcIk1hcFR5cGVcIixcbiAgICB2YWx1ZVR5cGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVJZGVudGl0eX0gKi8gKHR5cGVJZGVudGl0eSh0eXBlLnZhbHVlVHlwZSkpXG4gIH1cbn1cblxuLyoqXG4gKiBDaGVja3Mgb25lIGV4dGVybmFsbHkgc3VwcGxpZWQgcmVjdXJzaXZlIHR5cGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3Vua25vd259IHR5cGUgLSBDYW5kaWRhdGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGFsbG93Vm9pZCAtIFdoZXRoZXIgdm9pZCBpcyBwZXJtaXR0ZWQuXG4gKiBAcGFyYW0ge1NldDxvYmplY3Q+fSBbc2Vlbl0gLSBBY3RpdmUgcmVjdXJzaW9uIHBhdGguXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgaWRlbnRpdHkgaXMgY2xvc2VkIGFuZCBhY3ljbGljLlxuICovXG5mdW5jdGlvbiB2YWxpZFR5cGVJZGVudGl0eSh0eXBlLCBhbGxvd1ZvaWQsIHNlZW4gPSBuZXcgU2V0KCkpIHtcbiAgaWYgKHR5cGVvZiB0eXBlID09IFwic3RyaW5nXCIpIHJldHVybiBpc1NjYWxhclR5cGVOYW1lKHR5cGUpIHx8IGFsbG93Vm9pZCAmJiB0eXBlID09IFwidm9pZFwiXG4gIGlmICghdHlwZSB8fCB0eXBlb2YgdHlwZSAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkodHlwZSkgfHwgc2Vlbi5oYXModHlwZSkpIHJldHVybiBmYWxzZVxuXG4gIHNlZW4uYWRkKHR5cGUpXG4gIGNvbnN0IGNhbmRpZGF0ZSA9IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59ICovICh0eXBlKVxuICBsZXQgdmFsaWQgPSBmYWxzZVxuXG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIkxpc3RUeXBlXCIgJiYgT2JqZWN0LmtleXMoY2FuZGlkYXRlKS5zb3J0KCkuam9pbihcIixcIikgPT0gXCJlbGVtZW50VHlwZSxraW5kXCIpIHtcbiAgICB2YWxpZCA9IHZhbGlkVHlwZUlkZW50aXR5KGNhbmRpZGF0ZS5lbGVtZW50VHlwZSwgZmFsc2UsIHNlZW4pXG4gIH0gZWxzZSBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJNYXBUeXBlXCIgJiYgT2JqZWN0LmtleXMoY2FuZGlkYXRlKS5zb3J0KCkuam9pbihcIixcIikgPT0gXCJrZXlUeXBlLGtpbmQsdmFsdWVUeXBlXCIpIHtcbiAgICB2YWxpZCA9IGNhbmRpZGF0ZS5rZXlUeXBlID09IFwic3RyaW5nXCIgJiYgdmFsaWRUeXBlSWRlbnRpdHkoY2FuZGlkYXRlLnZhbHVlVHlwZSwgZmFsc2UsIHNlZW4pXG4gIH0gZWxzZSBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiICYmXG4gICAgT2JqZWN0LmtleXMoY2FuZGlkYXRlKS5zb3J0KCkuam9pbihcIixcIikgPT0gXCJrZXlUeXBlLGtpbmQsb3JkZXIsdmFsdWVUeXBlXCIpIHtcbiAgICB2YWxpZCA9IGNhbmRpZGF0ZS5rZXlUeXBlID09IFwic3RyaW5nXCIgJiYgY2FuZGlkYXRlLm9yZGVyID09IFwiaW5zZXJ0aW9uXCIgJiZcbiAgICAgIHZhbGlkVHlwZUlkZW50aXR5KGNhbmRpZGF0ZS52YWx1ZVR5cGUsIGZhbHNlLCBzZWVuKVxuICB9IGVsc2UgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIgJiYgT2JqZWN0LmtleXMoY2FuZGlkYXRlKS5zb3J0KCkuam9pbihcIixcIikgPT0gXCJraW5kLHZhbHVlVHlwZVwiKSB7XG4gICAgdmFsaWQgPSB2YWxpZFR5cGVJZGVudGl0eShjYW5kaWRhdGUudmFsdWVUeXBlLCBmYWxzZSwgc2VlbikgJiZcbiAgICAgICEoY2FuZGlkYXRlLnZhbHVlVHlwZSAmJiB0eXBlb2YgY2FuZGlkYXRlLnZhbHVlVHlwZSA9PSBcIm9iamVjdFwiICYmIFJlZmxlY3QuZ2V0KGNhbmRpZGF0ZS52YWx1ZVR5cGUsIFwia2luZFwiKSA9PSBcIk9wdGlvbmFsVHlwZVwiKVxuICB9IGVsc2UgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIgJiYgT2JqZWN0LmtleXMoY2FuZGlkYXRlKS5zb3J0KCkuam9pbihcIixcIikgPT0gXCJraW5kLHBhcmFtZXRlcklkXCIpIHtcbiAgICB2YWxpZCA9IHR5cGVvZiBjYW5kaWRhdGUucGFyYW1ldGVySWQgPT0gXCJzdHJpbmdcIiAmJiAvXig/OlthLXpdW2EtejAtOS5fLV0qIyk/KD86cmVjb3JkfGZ1bmN0aW9uKTpbMC05XSs6dHlwZTpbMC05XSskL3UudGVzdChjYW5kaWRhdGUucGFyYW1ldGVySWQpXG4gIH0gZWxzZSBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJSZWNvcmRUeXBlXCIgJiZcbiAgICBbXCJhcmd1bWVudHMsZGVjbGFyYXRpb25JZCxraW5kXCIsIFwiZGVjbGFyYXRpb25JZCxraW5kXCJdLmluY2x1ZGVzKE9iamVjdC5rZXlzKGNhbmRpZGF0ZSkuc29ydCgpLmpvaW4oXCIsXCIpKSkge1xuICAgIGNvbnN0IGNhbmRpZGF0ZUFyZ3VtZW50cyA9IGNhbmRpZGF0ZS5hcmd1bWVudHNcblxuICAgIHZhbGlkID0gdHlwZW9mIGNhbmRpZGF0ZS5kZWNsYXJhdGlvbklkID09IFwic3RyaW5nXCIgJiYgL14oPzpbYS16XVthLXowLTkuXy1dKiMpP3JlY29yZDpbMC05XSskL3UudGVzdChjYW5kaWRhdGUuZGVjbGFyYXRpb25JZCkgJiZcbiAgICAgIChjYW5kaWRhdGVBcmd1bWVudHMgPT09IHVuZGVmaW5lZCB8fCBpc0RlbnNlQXJyYXkoY2FuZGlkYXRlQXJndW1lbnRzKSAmJlxuICAgICAgICBjYW5kaWRhdGVBcmd1bWVudHMuZXZlcnkoKGFyZ3VtZW50KSA9PiB2YWxpZFR5cGVJZGVudGl0eShhcmd1bWVudCwgZmFsc2UsIHNlZW4pKSlcbiAgfSBlbHNlIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIlJlZmVyZW5jZVR5cGVcIiAmJiBPYmplY3Qua2V5cyhjYW5kaWRhdGUpLnNvcnQoKS5qb2luKFwiLFwiKSA9PSBcImRlY2xhcmF0aW9uSWQsa2luZFwiKSB7XG4gICAgdmFsaWQgPSB0eXBlb2YgY2FuZGlkYXRlLmRlY2xhcmF0aW9uSWQgPT0gXCJzdHJpbmdcIiAmJlxuICAgICAgL14oPzpbYS16XVthLXowLTkuXy1dKiMpP2NsYXNzOlswLTldKyQvdS50ZXN0KGNhbmRpZGF0ZS5kZWNsYXJhdGlvbklkKVxuICB9IGVsc2UgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiT3duZWRSZXNvdXJjZVR5cGVcIiAmJiBPYmplY3Qua2V5cyhjYW5kaWRhdGUpLnNvcnQoKS5qb2luKFwiLFwiKSA9PSBcImtpbmQscmVzb3VyY2VJZFwiKSB7XG4gICAgdmFsaWQgPSB0eXBlb2YgY2FuZGlkYXRlLnJlc291cmNlSWQgPT0gXCJzdHJpbmdcIiAmJiAvXig/Om1vZHVsZTpbMC05XStcXC8pP2NhcGFiaWxpdHk6WzAtOV0rXFwvcmVzb3VyY2U6WzAtOV0rJC91XG4gICAgICAudGVzdChjYW5kaWRhdGUucmVzb3VyY2VJZClcbiAgfSBlbHNlIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIk93bmVkUmVmZXJlbmNlVHlwZVwiICYmIE9iamVjdC5rZXlzKGNhbmRpZGF0ZSkuc29ydCgpLmpvaW4oXCIsXCIpID09IFwiZGVjbGFyYXRpb25JZCxraW5kXCIpIHtcbiAgICB2YWxpZCA9IHR5cGVvZiBjYW5kaWRhdGUuZGVjbGFyYXRpb25JZCA9PSBcInN0cmluZ1wiICYmIC9eKD86W2Etel1bYS16MC05Ll8tXSojKT9jbGFzczpbMC05XSskL3UudGVzdChjYW5kaWRhdGUuZGVjbGFyYXRpb25JZClcbiAgfVxuICBzZWVuLmRlbGV0ZSh0eXBlKVxuXG4gIHJldHVybiB2YWxpZFxufVxuXG4vKipcbiAqIENoZWNrcyBhcnJheSBpZGVudGl0eSB3aXRob3V0IHJlbHlpbmcgb24gaXRlcmF0aW9uIG1ldGhvZHMgdGhhdCBza2lwIHNwYXJzZSBzbG90cy5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgYXJyYXkuXG4gKiBAcmV0dXJucyB7dmFsdWUgaXMgdW5rbm93bltdfSBXaGV0aGVyIGV2ZXJ5IGluZGV4ZWQgc2xvdCBpcyBwcmVzZW50LlxuICovXG5mdW5jdGlvbiBpc0RlbnNlQXJyYXkodmFsdWUpIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIGZhbHNlXG5cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHZhbHVlLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIGlmICghT2JqZWN0Lmhhc093bih2YWx1ZSwgaW5kZXgpKSByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiB0cnVlXG59XG5cbi8qKlxuICogQ29tcGFyZXMgdHdvIGNsb3NlZCB0eXBlIGlkZW50aXRpZXMgc3RydWN0dXJhbGx5LlxuICogQHBhcmFtIHt1bmtub3dufSBsZWZ0IC0gRmlyc3QgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3Vua25vd259IHJpZ2h0IC0gU2Vjb25kIGlkZW50aXR5LlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIGlkZW50aXRpZXMgYXJlIGVxdWFsLlxuICovXG5mdW5jdGlvbiBzYW1lVHlwZUlkZW50aXR5KGxlZnQsIHJpZ2h0KSB7XG4gIGlmICh0eXBlb2YgbGVmdCA9PSBcInN0cmluZ1wiIHx8IHR5cGVvZiByaWdodCA9PSBcInN0cmluZ1wiKSByZXR1cm4gbGVmdCA9PT0gcmlnaHRcbiAgaWYgKCFsZWZ0IHx8ICFyaWdodCB8fCB0eXBlb2YgbGVmdCAhPSBcIm9iamVjdFwiIHx8IHR5cGVvZiByaWdodCAhPSBcIm9iamVjdFwiKSByZXR1cm4gZmFsc2VcbiAgY29uc3QgbGVmdFR5cGUgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAobGVmdClcbiAgY29uc3QgcmlnaHRUeXBlID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gKi8gKHJpZ2h0KVxuXG4gIGlmIChsZWZ0VHlwZS5raW5kICE9IHJpZ2h0VHlwZS5raW5kKSByZXR1cm4gZmFsc2VcbiAgaWYgKGxlZnRUeXBlLmtpbmQgPT0gXCJMaXN0VHlwZVwiKSByZXR1cm4gc2FtZVR5cGVJZGVudGl0eShsZWZ0VHlwZS5lbGVtZW50VHlwZSwgcmlnaHRUeXBlLmVsZW1lbnRUeXBlKVxuICBpZiAobGVmdFR5cGUua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSByZXR1cm4gc2FtZVR5cGVJZGVudGl0eShsZWZ0VHlwZS52YWx1ZVR5cGUsIHJpZ2h0VHlwZS52YWx1ZVR5cGUpXG4gIGlmIChsZWZ0VHlwZS5raW5kID09IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHJldHVybiBsZWZ0VHlwZS5wYXJhbWV0ZXJJZCA9PSByaWdodFR5cGUucGFyYW1ldGVySWRcbiAgaWYgKGxlZnRUeXBlLmtpbmQgPT0gXCJSZWNvcmRUeXBlXCIpIHtcbiAgICBjb25zdCBsZWZ0QXJndW1lbnRzID0gQXJyYXkuaXNBcnJheShsZWZ0VHlwZS5hcmd1bWVudHMpID8gbGVmdFR5cGUuYXJndW1lbnRzIDogW11cbiAgICBjb25zdCByaWdodEFyZ3VtZW50cyA9IEFycmF5LmlzQXJyYXkocmlnaHRUeXBlLmFyZ3VtZW50cykgPyByaWdodFR5cGUuYXJndW1lbnRzIDogW11cblxuICAgIHJldHVybiBsZWZ0VHlwZS5kZWNsYXJhdGlvbklkID09IHJpZ2h0VHlwZS5kZWNsYXJhdGlvbklkICYmIGxlZnRBcmd1bWVudHMubGVuZ3RoID09IHJpZ2h0QXJndW1lbnRzLmxlbmd0aCAmJlxuICAgICAgbGVmdEFyZ3VtZW50cy5ldmVyeSgoYXJndW1lbnQsIGluZGV4KSA9PiBzYW1lVHlwZUlkZW50aXR5KGFyZ3VtZW50LCByaWdodEFyZ3VtZW50c1tpbmRleF0pKVxuICB9XG4gIGlmIChsZWZ0VHlwZS5raW5kID09IFwiUmVmZXJlbmNlVHlwZVwiKSByZXR1cm4gbGVmdFR5cGUuZGVjbGFyYXRpb25JZCA9PSByaWdodFR5cGUuZGVjbGFyYXRpb25JZFxuICBpZiAobGVmdFR5cGUua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIpIHJldHVybiBsZWZ0VHlwZS5yZXNvdXJjZUlkID09IHJpZ2h0VHlwZS5yZXNvdXJjZUlkXG4gIGlmIChsZWZ0VHlwZS5raW5kID09IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIpIHJldHVybiBsZWZ0VHlwZS5kZWNsYXJhdGlvbklkID09IHJpZ2h0VHlwZS5kZWNsYXJhdGlvbklkXG4gIGlmIChsZWZ0VHlwZS5raW5kID09IFwiTWFwVHlwZVwiIHx8IGxlZnRUeXBlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSB7XG4gICAgcmV0dXJuIHNhbWVUeXBlSWRlbnRpdHkobGVmdFR5cGUua2V5VHlwZSwgcmlnaHRUeXBlLmtleVR5cGUpICYmIHNhbWVUeXBlSWRlbnRpdHkobGVmdFR5cGUudmFsdWVUeXBlLCByaWdodFR5cGUudmFsdWVUeXBlKVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG5cbi8qKlxuICogQ29tcGFyZXMgdHdvIHZhbGlkYXRlZCBzZW1hbnRpYyB0eXBlcyBzdHJ1Y3R1cmFsbHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9IGxlZnQgLSBGaXJzdCB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSByaWdodCAtIFNlY29uZCB0eXBlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHR5cGVzIGFyZSBlcXVhbC5cbiAqL1xuZnVuY3Rpb24gc2FtZVR5cGUobGVmdCwgcmlnaHQpIHtcbiAgcmV0dXJuIHNhbWVUeXBlSWRlbnRpdHkodHlwZUlkZW50aXR5KGxlZnQpLCB0eXBlSWRlbnRpdHkocmlnaHQpKVxufVxuXG4vKipcbiAqIEZvcm1hdHMgb25lIHZhbGlkYXRlZCBzZW1hbnRpYyB0eXBlIGZvciBkaWFnbm9zdGljcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZSB8IGltcG9ydChcIi4vdHlwZXMuanNcIikuRXJyb3JUeXBlfSB0eXBlIC0gU2VtYW50aWMgdHlwZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFN0YWJsZSByZWN1cnNpdmUgc3BlbGxpbmcuXG4gKi9cbmZ1bmN0aW9uIHR5cGVEZXNjcmlwdGlvbih0eXBlKSB7XG4gIGlmICh0eXBlLmtpbmQgPT0gXCJUeXBlUmVmZXJlbmNlXCIpIHJldHVybiB0eXBlLm5hbWVcbiAgaWYgKHR5cGUua2luZCA9PSBcIlR5cGVWYXJpYWJsZVJlZmVyZW5jZVwiKSByZXR1cm4gYHR5cGUtdmFyaWFibGU8JHt0eXBlLnBhcmFtZXRlcklkfT5gXG4gIGlmICh0eXBlLmtpbmQgPT0gXCJSZWNvcmRUeXBlXCIpIHJldHVybiBgcmVjb3JkPCR7dHlwZS5kZWNsYXJhdGlvbklkfSR7dHlwZS5hcmd1bWVudHM/Lmxlbmd0aFxuICAgID8gYCwgJHt0eXBlLmFyZ3VtZW50cy5tYXAodHlwZURlc2NyaXB0aW9uKS5qb2luKFwiLCBcIil9YCA6IFwiXCJ9PmBcbiAgaWYgKHR5cGUua2luZCA9PSBcIlJlZmVyZW5jZVR5cGVcIikgcmV0dXJuIGByZWZlcmVuY2U8JHt0eXBlLmRlY2xhcmF0aW9uSWR9PmBcbiAgaWYgKHR5cGUua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIpIHJldHVybiBgb3duZWQtcmVzb3VyY2U8JHt0eXBlLnJlc291cmNlSWR9PmBcbiAgaWYgKHR5cGUua2luZCA9PSBcIk93bmVkUmVmZXJlbmNlVHlwZVwiKSByZXR1cm4gYG93bmVkLXJlZmVyZW5jZTwke3R5cGUuZGVjbGFyYXRpb25JZH0+YFxuICBpZiAodHlwZS5raW5kID09IFwiRXJyb3JUeXBlXCIpIHJldHVybiBgZXJyb3I8JHt0eXBlLmRlY2xhcmF0aW9uSWR9PmBcbiAgaWYgKHR5cGUua2luZCA9PSBcIkxpc3RUeXBlXCIpIHJldHVybiBgbGlzdDwke3R5cGVEZXNjcmlwdGlvbih0eXBlLmVsZW1lbnRUeXBlKX0+YFxuICBpZiAodHlwZS5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHJldHVybiBgb3B0aW9uYWw8JHt0eXBlRGVzY3JpcHRpb24odHlwZS52YWx1ZVR5cGUpfT5gXG4gIGlmICh0eXBlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSByZXR1cm4gYG9yZGVyZWQtbWFwPHN0cmluZywgJHt0eXBlRGVzY3JpcHRpb24odHlwZS52YWx1ZVR5cGUpfSwgaW5zZXJ0aW9uPmBcblxuICByZXR1cm4gYG1hcDxzdHJpbmcsICR7dHlwZURlc2NyaXB0aW9uKHR5cGUudmFsdWVUeXBlKX0+YFxufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdHlwZSBncmFwaCBjb250YWlucyBsaW5lYXIgb3duZXJzaGlwLlxuICogQHBhcmFtIHt1bmtub3dufSB0eXBlIC0gQ2FuZGlkYXRlIHNlbWFudGljIHR5cGUuXG4gKiBAcGFyYW0ge1NldDxvYmplY3Q+fSBbc2Vlbl0gLSBWaXNpdGVkIHR5cGUgY29udGFpbmVycy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIG93bmVyc2hpcCBvY2N1cnMgYXQgYW55IGRlcHRoLlxuICovXG5mdW5jdGlvbiBjb250YWluc093bmVkVHlwZSh0eXBlLCBzZWVuID0gbmV3IFNldCgpKSB7XG4gIGlmICghdHlwZSB8fCB0eXBlb2YgdHlwZSAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkodHlwZSkgfHwgc2Vlbi5oYXModHlwZSkpIHJldHVybiBmYWxzZVxuICBzZWVuLmFkZCh0eXBlKVxuICBjb25zdCBraW5kID0gUmVmbGVjdC5nZXQodHlwZSwgXCJraW5kXCIpXG5cbiAgaWYgKGtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiIHx8IGtpbmQgPT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIikgcmV0dXJuIHRydWVcbiAgaWYgKGtpbmQgPT0gXCJMaXN0VHlwZVwiKSByZXR1cm4gY29udGFpbnNPd25lZFR5cGUoUmVmbGVjdC5nZXQodHlwZSwgXCJlbGVtZW50VHlwZVwiKSwgc2VlbilcbiAgaWYgKGtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIikgcmV0dXJuIGNvbnRhaW5zT3duZWRUeXBlKFJlZmxlY3QuZ2V0KHR5cGUsIFwidmFsdWVUeXBlXCIpLCBzZWVuKVxuICBpZiAoa2luZCA9PSBcIk1hcFR5cGVcIiB8fCBraW5kID09IFwiT3JkZXJlZE1hcFR5cGVcIikge1xuICAgIHJldHVybiBjb250YWluc093bmVkVHlwZShSZWZsZWN0LmdldCh0eXBlLCBcImtleVR5cGVcIiksIHNlZW4pIHx8IGNvbnRhaW5zT3duZWRUeXBlKFJlZmxlY3QuZ2V0KHR5cGUsIFwidmFsdWVUeXBlXCIpLCBzZWVuKVxuICB9XG4gIGlmIChraW5kID09IFwiUmVjb3JkVHlwZVwiKSB7XG4gICAgY29uc3QgYXJndW1lbnRzXyA9IFJlZmxlY3QuZ2V0KHR5cGUsIFwiYXJndW1lbnRzXCIpXG5cbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShhcmd1bWVudHNfKSAmJiBhcmd1bWVudHNfLnNvbWUoKGFyZ3VtZW50KSA9PiBjb250YWluc093bmVkVHlwZShhcmd1bWVudCwgc2VlbikpXG4gIH1cbiAgcmV0dXJuIGZhbHNlXG59XG5cbi8qKlxuICogQ2hlY2tzIG9uZSBzY2FsYXIgc2VtYW50aWMgdHlwZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZX0gdHlwZSAtIFNlbWFudGljIHR5cGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZX0gW25hbWVdIC0gT3B0aW9uYWwgcmVxdWlyZWQgc2NhbGFyLlxuICogQHJldHVybnMge3R5cGUgaXMgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSBXaGV0aGVyIGl0IGlzIHRoZSByZXF1ZXN0ZWQgc2NhbGFyLlxuICovXG5mdW5jdGlvbiBpc1NjYWxhclR5cGUodHlwZSwgbmFtZSkge1xuICByZXR1cm4gdHlwZS5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiICYmIGlzU2NhbGFyVHlwZU5hbWUodHlwZS5uYW1lKSAmJiAobmFtZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGUubmFtZSA9PSBuYW1lKVxufVxuXG4vKipcbiAqIENoZWNrcyB0aGUgc29sZSBub24tdmFsdWUgcmV0dXJuIHR5cGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9IHR5cGUgLSBTZW1hbnRpYyB0eXBlLlxuICogQHJldHVybnMge3R5cGUgaXMgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5GdW5jdGlvblJldHVyblR5cGVSZWZlcmVuY2V9IFdoZXRoZXIgaXQgaXMgdm9pZC5cbiAqL1xuZnVuY3Rpb24gaXNWb2lkVHlwZSh0eXBlKSB7XG4gIHJldHVybiB0eXBlLmtpbmQgPT0gXCJUeXBlUmVmZXJlbmNlXCIgJiYgdHlwZS5uYW1lID09IFwidm9pZFwiXG59XG5cbi8qKlxuICogUmVxdWlyZXMgYSBzY2FsYXIgdHlwZSBmb3IgdGhlIHByZS1jb2xsZWN0aW9uIG9wZXJhdG9yIGNvbnRyYWN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVmFsdWVUeXBlfSB0eXBlIC0gT3BlcmFuZCB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIE9wZXJhbmQgbG9jYXRpb24uXG4gKiBAcGFyYW0ge1NlbWFudGljRmFpbH0gZmFpbCAtIERpYWdub3N0aWMgY2FsbGJhY2suXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVOYW1lfSBTY2FsYXIgbmFtZS5cbiAqL1xuZnVuY3Rpb24gc2NhbGFyTmFtZUZvck9wZXJhdGlvbih0eXBlLCBsb2NhdGlvbiwgZmFpbCkge1xuICBpZiAoIWlzU2NhbGFyVHlwZSh0eXBlKSkge1xuICAgIHJldHVybiBmYWlsKFwiSU5WQUxJRF9PUEVSQU5EX1RZUEVcIiwgYFNjYWxhciBvcGVyYXRpb24gcmVjZWl2ZWQgJHt0eXBlRGVzY3JpcHRpb24odHlwZSl9LmAsIGxvY2F0aW9uKVxuICB9XG5cbiAgcmV0dXJuIHR5cGUubmFtZVxufVxuXG4vKipcbiAqIEVuZm9yY2VzIHRoYXQgYSB0b3RhbCBjb2xsZWN0aW9uIGFjY2VzcyBpcyBwcm92ZW4gb3IgdXNlcyBhIHNvdXJjZSBvcGVyYXRpb24gdGhhdCBmYWlscyBvbiBhYnNlbmNlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkxpc3RJbmRleEV4cHJlc3Npb24gfCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLk1hcExvb2t1cEV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBBY2Nlc3MuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHByb3ZlbiAtIFdoZXRoZXIgc3RhdGljIGxpdGVyYWwgcHJvcGFnYXRpb24gcHJvdmVzIHByZXNlbmNlLlxuICogQHBhcmFtIHtib29sZWFufSBub3JtYWxpemVPcGVyYXRpb25zIC0gV2hldGhlciB0aGlzIGlzIGZyb250ZW5kIGFkbWlzc2lvbi5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUFjY2Vzc1RvdGFsaXR5KGV4cHJlc3Npb24sIHByb3Zlbiwgbm9ybWFsaXplT3BlcmF0aW9ucywgZmFpbCkge1xuICBpZiAocHJvdmVuKSB7XG4gICAgaWYgKG5vcm1hbGl6ZU9wZXJhdGlvbnMpIGV4cHJlc3Npb24udG90YWxpdHkgPSBcInByb3ZlblwiXG4gICAgZWxzZSBpZiAoZXhwcmVzc2lvbi50b3RhbGl0eSAhPSBcInByb3ZlblwiICYmIGV4cHJlc3Npb24udG90YWxpdHkgIT0gXCJmYWlsLW9uLWFic2VuY2VcIikge1xuICAgICAgZmFpbChcIlVOQ0hFQ0tFRF9DT0xMRUNUSU9OX0FDQ0VTU1wiLCBcIkNvbGxlY3Rpb24gYWNjZXNzIGxhY2tzIGEgdG90YWxpdHkgZ3VhcmFudGVlLlwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cblxuICAgIHJldHVyblxuICB9XG4gIGlmIChleHByZXNzaW9uLnRvdGFsaXR5ICE9IFwiZmFpbC1vbi1hYnNlbmNlXCIpIHtcbiAgICBmYWlsKFwiVU5DSEVDS0VEX0NPTExFQ1RJT05fQUNDRVNTXCIsIFwiQ29sbGVjdGlvbiBhY2Nlc3MgaXMgbm90IHN0YXRpY2FsbHkgcHJvdmVuIGFuZCBkb2VzIG5vdCBmYWlsIG9uIGFic2VuY2UuXCIsIGV4cHJlc3Npb24ubG9jYXRpb24pXG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhIGJpbmRpbmcgd2l0aG91dCBwcm9kdWNpbmcgYSBkaWFnbm9zdGljLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBCaW5kaW5nIG5hbWUuXG4gKiBAcGFyYW0ge1Njb3BlfSBzY29wZSAtIFZpc2libGUgc2NvcGUuXG4gKiBAcmV0dXJucyB7QmluZGluZyB8IHVuZGVmaW5lZH0gQmluZGluZyB3aGVuIHZpc2libGUuXG4gKi9cbmZ1bmN0aW9uIGZpbmRCaW5kaW5nKG5hbWUsIHNjb3BlKSB7XG4gIGZvciAobGV0IGN1cnJlbnQgPSAvKiogQHR5cGUge1Njb3BlIHwgdW5kZWZpbmVkfSAqLyAoc2NvcGUpOyBjdXJyZW50OyBjdXJyZW50ID0gY3VycmVudC5wYXJlbnQpIHtcbiAgICBjb25zdCBiaW5kaW5nID0gY3VycmVudC5iaW5kaW5ncy5nZXQobmFtZSlcblxuICAgIGlmIChiaW5kaW5nKSByZXR1cm4gYmluZGluZ1xuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGV4aXN0aW5nIGJpbmRpbmdzIHdob3NlIGtub3duIHZhbHVlcyBtdXN0IGJlIG1lcmdlZCBhY3Jvc3MgYSBjb25kaXRpb25hbC5cbiAqIEBwYXJhbSB7U2NvcGV9IHNjb3BlIC0gVmlzaWJsZSBzY29wZS5cbiAqIEByZXR1cm5zIHtCaW5kaW5nW119IE5lYXJlc3QtdG8tZmFydGhlc3QgYmluZGluZ3MuXG4gKi9cbmZ1bmN0aW9uIGJpbmRpbmdzVmlzaWJsZUZyb20oc2NvcGUpIHtcbiAgY29uc3QgYmluZGluZ3MgPSBbXVxuXG4gIGZvciAobGV0IGN1cnJlbnQgPSAvKiogQHR5cGUge1Njb3BlIHwgdW5kZWZpbmVkfSAqLyAoc2NvcGUpOyBjdXJyZW50OyBjdXJyZW50ID0gY3VycmVudC5wYXJlbnQpIHtcbiAgICBiaW5kaW5ncy5wdXNoKC4uLmN1cnJlbnQuYmluZGluZ3MudmFsdWVzKCkpXG4gIH1cblxuICByZXR1cm4gYmluZGluZ3Ncbn1cblxuLyoqXG4gKiBGaW5kcyB2aXNpYmxlIG11dGFibGUgYmluZGluZ3MgdGhhdCBhIGxvb3AgYm9keSBtYXkgYXNzaWduIG9uIGFueSBuZXN0ZWQgcGF0aC5cbiAqIFRoZSBzZXQgaXMgY29tcHV0ZWQgYWZ0ZXIgdmFsaWRhdGluZyB0aGUgbGlzdCBleHByZXNzaW9uIGJlY2F1c2UgY29sbGVjdGlvbiBldmFsdWF0aW9uIHByZWNlZGVzIGJvZHkgZWZmZWN0cy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBDYW5kaWRhdGUgbG9vcCBib2R5LlxuICogQHBhcmFtIHtTY29wZX0gb3V0ZXJTY29wZSAtIFNjb3BlIHZpc2libGUgYmVmb3JlIGVudGVyaW5nIHRoZSBsb29wLlxuICogQHBhcmFtIHtTZXQ8QmluZGluZz59IFthc3NpZ25lZF0gLSBBY2N1bXVsYXRlZCBiaW5kaW5nIGlkZW50aXRpZXMuXG4gKiBAcmV0dXJucyB7U2V0PEJpbmRpbmc+fSBFeGFjdGx5IHRoZSB2aXNpYmxlIG11dGFibGUgYmluZGluZ3MgdGFyZ2V0ZWQgYnkgbmVzdGVkIGFzc2lnbm1lbnRzLlxuICovXG5mdW5jdGlvbiBvdXRlck11dGFibGVCaW5kaW5nc0Fzc2lnbmVkQnkoYmxvY2ssIG91dGVyU2NvcGUsIGFzc2lnbmVkID0gbmV3IFNldCgpKSB7XG4gIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJsb2NrLnN0YXRlbWVudHMpIHtcbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJBc3NpZ25tZW50U3RhdGVtZW50XCIpIHtcbiAgICAgIGNvbnN0IGJpbmRpbmcgPSBmaW5kQmluZGluZyhzdGF0ZW1lbnQudGFyZ2V0Lm5hbWUsIG91dGVyU2NvcGUpXG5cbiAgICAgIGlmIChiaW5kaW5nPy5tdXRhYmxlKSBhc3NpZ25lZC5hZGQoYmluZGluZylcbiAgICB9IGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgb3V0ZXJNdXRhYmxlQmluZGluZ3NBc3NpZ25lZEJ5KHN0YXRlbWVudC5jb25zZXF1ZW50LCBvdXRlclNjb3BlLCBhc3NpZ25lZClcbiAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSBvdXRlck11dGFibGVCaW5kaW5nc0Fzc2lnbmVkQnkoc3RhdGVtZW50LmFsdGVybmF0ZSwgb3V0ZXJTY29wZSwgYXNzaWduZWQpXG4gICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hNYXBTdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIldoaWxlU3RhdGVtZW50XCIpIHtcbiAgICAgIG91dGVyTXV0YWJsZUJpbmRpbmdzQXNzaWduZWRCeShzdGF0ZW1lbnQuYm9keSwgb3V0ZXJTY29wZSwgYXNzaWduZWQpXG4gICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlRyeVN0YXRlbWVudFwiKSB7XG4gICAgICBvdXRlck11dGFibGVCaW5kaW5nc0Fzc2lnbmVkQnkoc3RhdGVtZW50LmJvZHksIG91dGVyU2NvcGUsIGFzc2lnbmVkKVxuICAgICAgb3V0ZXJNdXRhYmxlQmluZGluZ3NBc3NpZ25lZEJ5KHN0YXRlbWVudC5jYXRjaEJvZHksIG91dGVyU2NvcGUsIGFzc2lnbmVkKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBhc3NpZ25lZFxufVxuXG4vKipcbiAqIFByb3BhZ2F0ZXMgb25seSBpbW11dGFibGUgdmFsdWVzIHdob3NlIGV4YWN0IGNvbGxlY3Rpb24gY29udGVudHMgcmVtYWluIGtub3duLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBFeHByZXNzaW9uLlxuICogQHBhcmFtIHtTY29wZX0gc2NvcGUgLSBWaXNpYmxlIHNjb3BlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXhwcmVzc2lvbiB8IHVuZGVmaW5lZH0gS25vd24gdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGtub3duVmFsdWVGb3JFeHByZXNzaW9uKGV4cHJlc3Npb24sIHNjb3BlKSB7XG4gIGlmIChbXCJJbnRlZ2VyTGl0ZXJhbFwiLCBcIkJvb2xlYW5MaXRlcmFsXCIsIFwiU3RyaW5nTGl0ZXJhbFwiLCBcIkxpc3RMaXRlcmFsXCIsIFwiTWFwTGl0ZXJhbFwiLCBcIk9yZGVyZWRNYXBMaXRlcmFsXCJdLmluY2x1ZGVzKGV4cHJlc3Npb24ua2luZCkpIHJldHVybiBleHByZXNzaW9uXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSByZXR1cm4gZmluZEJpbmRpbmcoZXhwcmVzc2lvbi5uYW1lLCBzY29wZSk/Lmtub3duVmFsdWVcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkxpc3RJbmRleEV4cHJlc3Npb25cIikgcmV0dXJuIHByb3Zlbkxpc3RFbGVtZW50KGV4cHJlc3Npb24uY29sbGVjdGlvbiwgZXhwcmVzc2lvbi5pbmRleCwgc2NvcGUpXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJNYXBMb29rdXBFeHByZXNzaW9uXCIpIHJldHVybiBwcm92ZW5NYXBWYWx1ZShleHByZXNzaW9uLmNvbGxlY3Rpb24sIGV4cHJlc3Npb24ua2V5LCBzY29wZSlcblxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogRmluZHMgdGhlIHN0YXRpY2FsbHkgc2VsZWN0ZWQgbGlzdCBlbGVtZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGNvbGxlY3Rpb24gLSBMaXN0IHJlY2VpdmVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGluZGV4IC0gSW5kZXggZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSB7U2NvcGV9IHNjb3BlIC0gVmlzaWJsZSBzY29wZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkV4cHJlc3Npb24gfCB1bmRlZmluZWR9IFByb3ZlbiBlbGVtZW50LlxuICovXG5mdW5jdGlvbiBwcm92ZW5MaXN0RWxlbWVudChjb2xsZWN0aW9uLCBpbmRleCwgc2NvcGUpIHtcbiAgY29uc3Qga25vd25Db2xsZWN0aW9uID0ga25vd25WYWx1ZUZvckV4cHJlc3Npb24oY29sbGVjdGlvbiwgc2NvcGUpXG4gIGNvbnN0IGtub3duSW5kZXggPSBrbm93blZhbHVlRm9yRXhwcmVzc2lvbihpbmRleCwgc2NvcGUpXG5cbiAgaWYgKGtub3duQ29sbGVjdGlvbj8ua2luZCAhPSBcIkxpc3RMaXRlcmFsXCIgfHwga25vd25JbmRleD8ua2luZCAhPSBcIkludGVnZXJMaXRlcmFsXCIgfHxcbiAgICBrbm93bkluZGV4LnZhbHVlIDwgMCB8fCBrbm93bkluZGV4LnZhbHVlID49IGtub3duQ29sbGVjdGlvbi5lbGVtZW50cy5sZW5ndGgpIHJldHVybiB1bmRlZmluZWRcblxuICByZXR1cm4ga25vd25Db2xsZWN0aW9uLmVsZW1lbnRzW2tub3duSW5kZXgudmFsdWVdXG59XG5cbi8qKlxuICogRmluZHMgdGhlIHN0YXRpY2FsbHkgc2VsZWN0ZWQgbWFwIHZhbHVlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGNvbGxlY3Rpb24gLSBNYXAgcmVjZWl2ZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXhwcmVzc2lvbn0ga2V5IC0gS2V5IGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge1Njb3BlfSBzY29wZSAtIFZpc2libGUgc2NvcGUuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FeHByZXNzaW9uIHwgdW5kZWZpbmVkfSBQcm92ZW4gdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIHByb3Zlbk1hcFZhbHVlKGNvbGxlY3Rpb24sIGtleSwgc2NvcGUpIHtcbiAgY29uc3Qga25vd25Db2xsZWN0aW9uID0ga25vd25WYWx1ZUZvckV4cHJlc3Npb24oY29sbGVjdGlvbiwgc2NvcGUpXG4gIGNvbnN0IGtub3duS2V5ID0ga25vd25WYWx1ZUZvckV4cHJlc3Npb24oa2V5LCBzY29wZSlcblxuICBpZiAoa25vd25Db2xsZWN0aW9uPy5raW5kICE9IFwiTWFwTGl0ZXJhbFwiICYmIGtub3duQ29sbGVjdGlvbj8ua2luZCAhPSBcIk9yZGVyZWRNYXBMaXRlcmFsXCIgfHxcbiAgICBrbm93bktleT8ua2luZCAhPSBcIlN0cmluZ0xpdGVyYWxcIikgcmV0dXJuIHVuZGVmaW5lZFxuXG4gIHJldHVybiBrbm93bkNvbGxlY3Rpb24uZW50cmllcy5maW5kKChlbnRyeSkgPT4gZW50cnkua2V5LnZhbHVlID09IGtub3duS2V5LnZhbHVlKT8udmFsdWVcbn1cblxuLyoqXG4gKiBJZGVudGlmaWVzIG51bWVyaWMgc3RyaW5ncyBpbmRlcGVuZGVudGx5IGZyb20gYW55IHRhcmdldCdzIGtleSBjb2VyY2lvbnMuXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBMaXRlcmFsIGtleS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIGl0IGlzIG51bWVyaWMuXG4gKi9cbmZ1bmN0aW9uIGlzTnVtZXJpY1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gL15bKy1dPyg/OlxcZCsoPzpcXC5cXGQqKT98XFwuXFxkKykoPzplWystXT9cXGQrKT8kL2l1LnRlc3QodmFsdWUudHJpbSgpKVxufVxuXG4vKipcbiAqIFNlbGVjdHMgYW4gZXhhY3Qgc2VtYW50aWMgdG9rZW4gbG9jYXRpb24gd2hlbiBwYXJzZXIgcHJvdmVuYW5jZSBpcyBhdmFpbGFibGUuXG4gKiBAcGFyYW0ge3tsb2NhdGlvbjogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiwgc291cmNlUHJvdmVuYW5jZT86IGltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNOb2RlU291cmNlUHJvdmVuYW5jZX19IG5vZGUgLSBMb2NhdGVkIHNlbWFudGljIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gcm9sZSAtIFRva2VuIHJvbGUuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gRXhhY3Qgb3Igb3duaW5nIGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiByb2xlTG9jYXRpb24obm9kZSwgcm9sZSkge1xuICByZXR1cm4gbm9kZS5zb3VyY2VQcm92ZW5hbmNlPy5yYW5nZXNbcm9sZV0gPz8gcGFyc2VyUmFuZ2VGb3Iobm9kZSwgcm9sZSkgPz8gbm9kZS5sb2NhdGlvblxufVxuXG4vKipcbiAqIFNlbGVjdHMgdGhlIGV4YWN0IHR5cGUgdG9rZW4gb3IgdGhlIG93bmluZyBkZWNsYXJhdGlvbiBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdHlwZSAtIENhbmRpZGF0ZSB0eXBlIHJlZmVyZW5jZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gb3duZXJMb2NhdGlvbiAtIE93bmluZyBkZWNsYXJhdGlvbiBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbcm9sZV0gLSBSZWN1cnNpdmUgdHlwZSByb2xlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IEV4YWN0IHR5cGUgbG9jYXRpb24gd2hlbiBrbm93bi5cbiAqL1xuZnVuY3Rpb24gdHlwZUxvY2F0aW9uKHR5cGUsIG93bmVyTG9jYXRpb24sIHJvbGUgPSBcInR5cGVcIikge1xuICBpZiAoIXR5cGUgfHwgdHlwZW9mIHR5cGUgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHR5cGUpKSByZXR1cm4gb3duZXJMb2NhdGlvblxuICBjb25zdCBjYW5kaWRhdGUgPSAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9ICovICh0eXBlKVxuXG4gIHJldHVybiBjYW5kaWRhdGUuc291cmNlUHJvdmVuYW5jZT8ucmFuZ2VzW3JvbGVdID8/IHBhcnNlclJhbmdlRm9yKGNhbmRpZGF0ZSwgcm9sZSkgPz9cbiAgICBjYW5kaWRhdGUuc291cmNlUHJvdmVuYW5jZT8ucmFuZ2VzLnR5cGUgPz8gcGFyc2VyUmFuZ2VGb3IoY2FuZGlkYXRlLCBcInR5cGVcIikgPz8gb3duZXJMb2NhdGlvblxufVxuXG4vKiogQHR5cGUge1JlYWRvbmx5PFJlY29yZDxpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVW5hcnlPcGVyYXRpb24sIHtvcGVyYW5kOiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWUsIHJlc3VsdDogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVOYW1lfT4+fSAqL1xuY29uc3QgdW5hcnlPcGVyYXRpb25TaWduYXR1cmVzID0gT2JqZWN0LmZyZWV6ZSh7XG4gIEJvb2xlYW5Ob3Q6IE9iamVjdC5mcmVlemUoe29wZXJhbmQ6IFwiYm9vbGVhblwiLCByZXN1bHQ6IFwiYm9vbGVhblwifSksXG4gIEludGVnZXJOZWdhdGU6IE9iamVjdC5mcmVlemUoe29wZXJhbmQ6IFwiaW50ZWdlclwiLCByZXN1bHQ6IFwiaW50ZWdlclwifSlcbn0pXG5cbi8qKiBAdHlwZSB7UmVhZG9ubHk8UmVjb3JkPGltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNCaW5hcnlPcGVyYXRpb24sIHtsZWZ0OiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWUsIHJpZ2h0OiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWUsIHJlc3VsdDogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVOYW1lfT4+fSAqL1xuY29uc3QgYmluYXJ5T3BlcmF0aW9uU2lnbmF0dXJlcyA9IE9iamVjdC5mcmVlemUoe1xuICBCb29sZWFuQW5kOiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcImJvb2xlYW5cIiwgcmVzdWx0OiBcImJvb2xlYW5cIiwgcmlnaHQ6IFwiYm9vbGVhblwifSksXG4gIEJvb2xlYW5FcXVhbDogT2JqZWN0LmZyZWV6ZSh7bGVmdDogXCJib29sZWFuXCIsIHJlc3VsdDogXCJib29sZWFuXCIsIHJpZ2h0OiBcImJvb2xlYW5cIn0pLFxuICBCb29sZWFuTm90RXF1YWw6IE9iamVjdC5mcmVlemUoe2xlZnQ6IFwiYm9vbGVhblwiLCByZXN1bHQ6IFwiYm9vbGVhblwiLCByaWdodDogXCJib29sZWFuXCJ9KSxcbiAgQm9vbGVhbk9yOiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcImJvb2xlYW5cIiwgcmVzdWx0OiBcImJvb2xlYW5cIiwgcmlnaHQ6IFwiYm9vbGVhblwifSksXG4gIEludGVnZXJBZGQ6IE9iamVjdC5mcmVlemUoe2xlZnQ6IFwiaW50ZWdlclwiLCByZXN1bHQ6IFwiaW50ZWdlclwiLCByaWdodDogXCJpbnRlZ2VyXCJ9KSxcbiAgSW50ZWdlckVxdWFsOiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcImludGVnZXJcIiwgcmVzdWx0OiBcImJvb2xlYW5cIiwgcmlnaHQ6IFwiaW50ZWdlclwifSksXG4gIEludGVnZXJHcmVhdGVyVGhhbjogT2JqZWN0LmZyZWV6ZSh7bGVmdDogXCJpbnRlZ2VyXCIsIHJlc3VsdDogXCJib29sZWFuXCIsIHJpZ2h0OiBcImludGVnZXJcIn0pLFxuICBJbnRlZ2VyR3JlYXRlclRoYW5PckVxdWFsOiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcImludGVnZXJcIiwgcmVzdWx0OiBcImJvb2xlYW5cIiwgcmlnaHQ6IFwiaW50ZWdlclwifSksXG4gIEludGVnZXJMZXNzVGhhbjogT2JqZWN0LmZyZWV6ZSh7bGVmdDogXCJpbnRlZ2VyXCIsIHJlc3VsdDogXCJib29sZWFuXCIsIHJpZ2h0OiBcImludGVnZXJcIn0pLFxuICBJbnRlZ2VyTGVzc1RoYW5PckVxdWFsOiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcImludGVnZXJcIiwgcmVzdWx0OiBcImJvb2xlYW5cIiwgcmlnaHQ6IFwiaW50ZWdlclwifSksXG4gIEludGVnZXJNdWx0aXBseTogT2JqZWN0LmZyZWV6ZSh7bGVmdDogXCJpbnRlZ2VyXCIsIHJlc3VsdDogXCJpbnRlZ2VyXCIsIHJpZ2h0OiBcImludGVnZXJcIn0pLFxuICBJbnRlZ2VyTm90RXF1YWw6IE9iamVjdC5mcmVlemUoe2xlZnQ6IFwiaW50ZWdlclwiLCByZXN1bHQ6IFwiYm9vbGVhblwiLCByaWdodDogXCJpbnRlZ2VyXCJ9KSxcbiAgSW50ZWdlclN1YnRyYWN0OiBPYmplY3QuZnJlZXplKHtsZWZ0OiBcImludGVnZXJcIiwgcmVzdWx0OiBcImludGVnZXJcIiwgcmlnaHQ6IFwiaW50ZWdlclwifSksXG4gIFN0cmluZ0NvbmNhdDogT2JqZWN0LmZyZWV6ZSh7bGVmdDogXCJzdHJpbmdcIiwgcmVzdWx0OiBcInN0cmluZ1wiLCByaWdodDogXCJzdHJpbmdcIn0pLFxuICBTdHJpbmdFcXVhbDogT2JqZWN0LmZyZWV6ZSh7bGVmdDogXCJzdHJpbmdcIiwgcmVzdWx0OiBcImJvb2xlYW5cIiwgcmlnaHQ6IFwic3RyaW5nXCJ9KSxcbiAgU3RyaW5nTm90RXF1YWw6IE9iamVjdC5mcmVlemUoe2xlZnQ6IFwic3RyaW5nXCIsIHJlc3VsdDogXCJib29sZWFuXCIsIHJpZ2h0OiBcInN0cmluZ1wifSlcbn0pXG5cbi8qKlxuICogU2VsZWN0cyBvbmUgdHlwZWQgdW5hcnkgbWVhbmluZyBmcm9tIHBhcnNlci1ub3JtYWxpemVkIHNvdXJjZSBpbnRlbnQuXG4gKiBAcGFyYW0ge3Vua25vd259IHNvdXJjZU9wZXJhdGlvbiAtIFRyYW5zaWVudCBmcm9udGVuZCBvcGVyYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZX0gb3BlcmFuZFR5cGUgLSBSZXNvbHZlZCBvcGVyYW5kIHR5cGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gT3BlcmFuZCBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVW5hcnlPcGVyYXRpb259IFNlbWFudGljIG9wZXJhdGlvbi5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplVW5hcnlPcGVyYXRpb24oc291cmNlT3BlcmF0aW9uLCBvcGVyYW5kVHlwZSwgbG9jYXRpb24sIGZhaWwpIHtcbiAgaWYgKHNvdXJjZU9wZXJhdGlvbiA9PSBcIk5lZ2F0ZVwiKSB7XG4gICAgaWYgKG9wZXJhbmRUeXBlICE9IFwiaW50ZWdlclwiKSBmYWlsKFwiSU5WQUxJRF9PUEVSQU5EX1RZUEVcIiwgYEludGVnZXIgbmVnYXRpb24gcmVxdWlyZXMgaW50ZWdlcjsgcmVjZWl2ZWQgJHtvcGVyYW5kVHlwZX0uYCwgbG9jYXRpb24pXG4gICAgcmV0dXJuIFwiSW50ZWdlck5lZ2F0ZVwiXG4gIH1cbiAgaWYgKHNvdXJjZU9wZXJhdGlvbiA9PSBcIk5vdFwiKSB7XG4gICAgaWYgKG9wZXJhbmRUeXBlICE9IFwiYm9vbGVhblwiKSBmYWlsKFwiSU5WQUxJRF9PUEVSQU5EX1RZUEVcIiwgYEJvb2xlYW4gbm90IHJlcXVpcmVzIGJvb2xlYW47IHJlY2VpdmVkICR7b3BlcmFuZFR5cGV9LmAsIGxvY2F0aW9uKVxuICAgIHJldHVybiBcIkJvb2xlYW5Ob3RcIlxuICB9XG5cbiAgcmV0dXJuIGZhaWwoXCJUWVBFX01JU01BVENIXCIsIGBVbmtub3duIHVuYXJ5IHNvdXJjZSBvcGVyYXRpb24gJHtTdHJpbmcoc291cmNlT3BlcmF0aW9uKX0uYCwgbG9jYXRpb24pXG59XG5cbi8qKlxuICogU2VsZWN0cyBvbmUgdHlwZWQgYmluYXJ5IG1lYW5pbmcgZnJvbSBwYXJzZXItbm9ybWFsaXplZCBzb3VyY2UgaW50ZW50LlxuICogQHBhcmFtIHt1bmtub3dufSBzb3VyY2VPcGVyYXRpb24gLSBUcmFuc2llbnQgZnJvbnRlbmQgb3BlcmF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWV9IGxlZnRUeXBlIC0gUmVzb2x2ZWQgbGVmdCB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWV9IHJpZ2h0VHlwZSAtIFJlc29sdmVkIHJpZ2h0IHR5cGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxlZnRMb2NhdGlvbiAtIExlZnQgb3BlcmFuZCBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gcmlnaHRMb2NhdGlvbiAtIFJpZ2h0IG9wZXJhbmQgbG9jYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGV4cHJlc3Npb25Mb2NhdGlvbiAtIFdob2xlIG9wZXJhdGlvbiBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7U2VtYW50aWNGYWlsfSBmYWlsIC0gRGlhZ25vc3RpYyBjYWxsYmFjay5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljQmluYXJ5T3BlcmF0aW9ufSBTZW1hbnRpYyBvcGVyYXRpb24uXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUJpbmFyeU9wZXJhdGlvbihzb3VyY2VPcGVyYXRpb24sIGxlZnRUeXBlLCByaWdodFR5cGUsIGxlZnRMb2NhdGlvbiwgcmlnaHRMb2NhdGlvbiwgZXhwcmVzc2lvbkxvY2F0aW9uLCBmYWlsKSB7XG4gIGlmIChzb3VyY2VPcGVyYXRpb24gPT0gXCJQaHBBZGRcIikge1xuICAgIGlmIChsZWZ0VHlwZSA9PSBcInN0cmluZ1wiICYmIHJpZ2h0VHlwZSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gZmFpbChcIlVOU1VQUE9SVEVEX1NZTlRBWFwiLCBcIlBIUCBiaW5hcnkgKyBkb2VzIG5vdCBjb25jYXRlbmF0ZSBzdHJpbmdzOyB1c2UgLiBpbnN0ZWFkLlwiLCBleHByZXNzaW9uTG9jYXRpb24pXG4gICAgfVxuXG4gICAgc291cmNlT3BlcmF0aW9uID0gXCJBZGRcIlxuICB9XG5cbiAgaWYgKHNvdXJjZU9wZXJhdGlvbiA9PSBcIlN0cmluZ0NvbmNhdFwiKSB7XG4gICAgaWYgKGxlZnRUeXBlICE9IFwic3RyaW5nXCIpIGZhaWwoXCJJTlZBTElEX09QRVJBTkRfVFlQRVwiLCBgU3RyaW5nIGNvbmNhdGVuYXRpb24gcmVxdWlyZXMgc3RyaW5nOyByZWNlaXZlZCAke2xlZnRUeXBlfS5gLCBsZWZ0TG9jYXRpb24pXG4gICAgaWYgKHJpZ2h0VHlwZSAhPSBcInN0cmluZ1wiKSBmYWlsKFwiSU5WQUxJRF9PUEVSQU5EX1RZUEVcIiwgYFN0cmluZyBjb25jYXRlbmF0aW9uIHJlcXVpcmVzIHN0cmluZzsgcmVjZWl2ZWQgJHtyaWdodFR5cGV9LmAsIHJpZ2h0TG9jYXRpb24pXG4gICAgcmV0dXJuIFwiU3RyaW5nQ29uY2F0XCJcbiAgfVxuXG4gIGlmIChzb3VyY2VPcGVyYXRpb24gPT0gXCJBZGRcIikge1xuICAgIGlmIChsZWZ0VHlwZSA9PSBcImludGVnZXJcIiAmJiByaWdodFR5cGUgPT0gXCJpbnRlZ2VyXCIpIHJldHVybiBcIkludGVnZXJBZGRcIlxuICAgIGlmIChsZWZ0VHlwZSA9PSBcInN0cmluZ1wiICYmIHJpZ2h0VHlwZSA9PSBcInN0cmluZ1wiKSByZXR1cm4gXCJTdHJpbmdDb25jYXRcIlxuXG4gICAgY29uc3QgbG9jYXRpb24gPSBsZWZ0VHlwZSA9PSBcImludGVnZXJcIiB8fCBsZWZ0VHlwZSA9PSBcInN0cmluZ1wiID8gcmlnaHRMb2NhdGlvbiA6IGxlZnRMb2NhdGlvblxuXG4gICAgcmV0dXJuIGZhaWwoXCJJTlZBTElEX09QRVJBTkRfVFlQRVwiLCBgQWRkaXRpb24gcmVxdWlyZXMgdHdvIGludGVnZXJzIG9yIHR3byBzdHJpbmdzOyByZWNlaXZlZCAke2xlZnRUeXBlfSBhbmQgJHtyaWdodFR5cGV9LmAsIGxvY2F0aW9uKVxuICB9XG5cbiAgY29uc3QgZml4ZWRPcGVyYXRpb25zID0gLyoqIEB0eXBlIHtjb25zdH0gKi8gKHtcbiAgICBBbmQ6IFtcImJvb2xlYW5cIiwgXCJCb29sZWFuQW5kXCJdLFxuICAgIEdyZWF0ZXJUaGFuOiBbXCJpbnRlZ2VyXCIsIFwiSW50ZWdlckdyZWF0ZXJUaGFuXCJdLFxuICAgIEdyZWF0ZXJUaGFuT3JFcXVhbDogW1wiaW50ZWdlclwiLCBcIkludGVnZXJHcmVhdGVyVGhhbk9yRXF1YWxcIl0sXG4gICAgTGVzc1RoYW46IFtcImludGVnZXJcIiwgXCJJbnRlZ2VyTGVzc1RoYW5cIl0sXG4gICAgTGVzc1RoYW5PckVxdWFsOiBbXCJpbnRlZ2VyXCIsIFwiSW50ZWdlckxlc3NUaGFuT3JFcXVhbFwiXSxcbiAgICBNdWx0aXBseTogW1wiaW50ZWdlclwiLCBcIkludGVnZXJNdWx0aXBseVwiXSxcbiAgICBPcjogW1wiYm9vbGVhblwiLCBcIkJvb2xlYW5PclwiXSxcbiAgICBTdWJ0cmFjdDogW1wiaW50ZWdlclwiLCBcIkludGVnZXJTdWJ0cmFjdFwiXVxuICB9KVxuICBjb25zdCBmaXhlZCA9IFJlZmxlY3QuZ2V0KGZpeGVkT3BlcmF0aW9ucywgU3RyaW5nKHNvdXJjZU9wZXJhdGlvbikpXG5cbiAgaWYgKGZpeGVkKSB7XG4gICAgY29uc3QgW3JlcXVpcmVkVHlwZSwgb3BlcmF0aW9uXSA9IGZpeGVkXG5cbiAgICBpZiAobGVmdFR5cGUgIT0gcmVxdWlyZWRUeXBlKSBmYWlsKFwiSU5WQUxJRF9PUEVSQU5EX1RZUEVcIiwgYCR7U3RyaW5nKHNvdXJjZU9wZXJhdGlvbil9IHJlcXVpcmVzICR7cmVxdWlyZWRUeXBlfTsgcmVjZWl2ZWQgJHtsZWZ0VHlwZX0uYCwgbGVmdExvY2F0aW9uKVxuICAgIGlmIChyaWdodFR5cGUgIT0gcmVxdWlyZWRUeXBlKSBmYWlsKFwiSU5WQUxJRF9PUEVSQU5EX1RZUEVcIiwgYCR7U3RyaW5nKHNvdXJjZU9wZXJhdGlvbil9IHJlcXVpcmVzICR7cmVxdWlyZWRUeXBlfTsgcmVjZWl2ZWQgJHtyaWdodFR5cGV9LmAsIHJpZ2h0TG9jYXRpb24pXG5cbiAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljQmluYXJ5T3BlcmF0aW9ufSAqLyAob3BlcmF0aW9uKVxuICB9XG5cbiAgaWYgKHNvdXJjZU9wZXJhdGlvbiA9PSBcIkphdmFFcXVhbFwiIHx8IHNvdXJjZU9wZXJhdGlvbiA9PSBcIkphdmFOb3RFcXVhbFwiKSB7XG4gICAgaWYgKGxlZnRUeXBlID09IFwic3RyaW5nXCIgfHwgcmlnaHRUeXBlID09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiVU5TVVBQT1JURURfU1lOVEFYXCIsIFwiSmF2YSByZWZlcmVuY2UgZXF1YWxpdHkgaXMgb3V0c2lkZSB0aGUgaW1wbGVtZW50ZWQgc2VtYW50aWMgc3Vic2V0LlwiLCBleHByZXNzaW9uTG9jYXRpb24pXG4gICAgfVxuXG4gICAgc291cmNlT3BlcmF0aW9uID0gc291cmNlT3BlcmF0aW9uID09IFwiSmF2YUVxdWFsXCIgPyBcIkVxdWFsXCIgOiBcIk5vdEVxdWFsXCJcbiAgfVxuXG4gIGlmIChzb3VyY2VPcGVyYXRpb24gPT0gXCJTdHJpbmdFcXVhbFwiIHx8IHNvdXJjZU9wZXJhdGlvbiA9PSBcIlN0cmluZ05vdEVxdWFsXCIpIHtcbiAgICBpZiAobGVmdFR5cGUgIT0gXCJzdHJpbmdcIikgZmFpbChcIklOVkFMSURfT1BFUkFORF9UWVBFXCIsIGBTdHJpbmcgZXF1YWxpdHkgcmVxdWlyZXMgc3RyaW5nOyByZWNlaXZlZCAke2xlZnRUeXBlfS5gLCBsZWZ0TG9jYXRpb24pXG4gICAgaWYgKHJpZ2h0VHlwZSAhPSBcInN0cmluZ1wiKSBmYWlsKFwiSU5WQUxJRF9PUEVSQU5EX1RZUEVcIiwgYFN0cmluZyBlcXVhbGl0eSByZXF1aXJlcyBzdHJpbmc7IHJlY2VpdmVkICR7cmlnaHRUeXBlfS5gLCByaWdodExvY2F0aW9uKVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7XCJTdHJpbmdFcXVhbFwiIHwgXCJTdHJpbmdOb3RFcXVhbFwifSAqLyAoc291cmNlT3BlcmF0aW9uKVxuICB9XG5cbiAgaWYgKHNvdXJjZU9wZXJhdGlvbiA9PSBcIkVxdWFsXCIgfHwgc291cmNlT3BlcmF0aW9uID09IFwiTm90RXF1YWxcIikge1xuICAgIGlmIChsZWZ0VHlwZSAhPSByaWdodFR5cGUpIHtcbiAgICAgIHJldHVybiBmYWlsKFwiTUlTTUFUQ0hFRF9FUVVBTElUWV9UWVBFU1wiLCBgRXF1YWxpdHkgcmVxdWlyZXMgbWF0Y2hpbmcgc2NhbGFyIHR5cGVzOyByZWNlaXZlZCAke2xlZnRUeXBlfSBhbmQgJHtyaWdodFR5cGV9LmAsIHJpZ2h0TG9jYXRpb24pXG4gICAgfVxuXG4gICAgY29uc3QgcHJlZml4ID0gbGVmdFR5cGUgPT0gXCJpbnRlZ2VyXCIgPyBcIkludGVnZXJcIiA6IGxlZnRUeXBlID09IFwiYm9vbGVhblwiID8gXCJCb29sZWFuXCIgOiBcIlN0cmluZ1wiXG5cbiAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljQmluYXJ5T3BlcmF0aW9ufSAqLyAoYCR7cHJlZml4fSR7c291cmNlT3BlcmF0aW9ufWApXG4gIH1cblxuICByZXR1cm4gZmFpbChcIlRZUEVfTUlTTUFUQ0hcIiwgYFVua25vd24gYmluYXJ5IHNvdXJjZSBvcGVyYXRpb24gJHtTdHJpbmcoc291cmNlT3BlcmF0aW9uKX0uYCwgbGVmdExvY2F0aW9uKVxufVxuXG4vKipcbiAqIFJlcGxhY2VzIHRyYW5zaWVudCBmcm9udGVuZCBpbnRlbnQgd2l0aCB0aGUgcHVibGljIHR5cGVkIG9wZXJhdGlvbiBmaWVsZHMuXG4gKiBAcGFyYW0ge29iamVjdH0gZXhwcmVzc2lvbiAtIE11dGFibGUgYWRhcHRlZCBleHByZXNzaW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVW5hcnlPcGVyYXRpb24gfCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljQmluYXJ5T3BlcmF0aW9ufSBvcGVyYXRpb24gLSBUeXBlZCBvcGVyYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZX0gdHlwZSAtIEV4cGxpY2l0IHJlc3VsdCB0eXBlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHNldE5vcm1hbGl6ZWRPcGVyYXRpb24oZXhwcmVzc2lvbiwgb3BlcmF0aW9uLCB0eXBlKSB7XG4gIFJlZmxlY3Quc2V0KGV4cHJlc3Npb24sIFwib3BlcmF0aW9uXCIsIG9wZXJhdGlvbilcbiAgUmVmbGVjdC5zZXQoZXhwcmVzc2lvbiwgXCJ0eXBlXCIsIHR5cGUpXG59XG4iXX0=
|