semantifold 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -15
- package/build/index.d.ts +48 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +57 -8
- package/build/src/artifact-path.d.ts +23 -1
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +45 -3
- package/build/src/artifacts.d.ts.map +1 -1
- package/build/src/artifacts.js +66 -1
- package/build/src/backends/c-validation.d.ts.map +1 -1
- package/build/src/backends/c-validation.js +7 -3
- package/build/src/backends/cpp-validation.d.ts.map +1 -1
- package/build/src/backends/cpp-validation.js +7 -3
- package/build/src/backends/csharp.js +7 -1
- package/build/src/backends/dart-runtime.d.ts +2 -0
- package/build/src/backends/dart-runtime.d.ts.map +1 -0
- package/build/src/backends/dart-runtime.js +41 -0
- package/build/src/backends/dart.d.ts +20 -0
- package/build/src/backends/dart.d.ts.map +1 -0
- package/build/src/backends/dart.js +321 -0
- package/build/src/backends/effects.d.ts +60 -0
- package/build/src/backends/effects.d.ts.map +1 -0
- package/build/src/backends/effects.js +746 -0
- package/build/src/backends/go.js +18 -4
- package/build/src/backends/identifiers.d.ts +36 -4
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +154 -10
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -4
- package/build/src/backends/ios.d.ts +68 -0
- package/build/src/backends/ios.d.ts.map +1 -0
- package/build/src/backends/ios.js +1503 -0
- package/build/src/backends/java.d.ts.map +1 -1
- package/build/src/backends/java.js +429 -36
- package/build/src/backends/javascript.d.ts +6 -0
- package/build/src/backends/javascript.d.ts.map +1 -1
- package/build/src/backends/javascript.js +380 -24
- package/build/src/backends/kotlin-runtime.d.ts +3 -0
- package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
- package/build/src/backends/kotlin-runtime.js +29 -0
- package/build/src/backends/kotlin.d.ts +23 -0
- package/build/src/backends/kotlin.d.ts.map +1 -0
- package/build/src/backends/kotlin.js +136 -0
- package/build/src/backends/native-validation.d.ts +2 -2
- package/build/src/backends/native-validation.d.ts.map +1 -1
- package/build/src/backends/native-validation.js +2 -2
- package/build/src/backends/ordered-expressions.d.ts.map +1 -1
- package/build/src/backends/ordered-expressions.js +39 -7
- package/build/src/backends/php-stdlib-support.d.ts +19 -0
- package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
- package/build/src/backends/php-stdlib-support.js +227 -0
- package/build/src/backends/php.d.ts.map +1 -1
- package/build/src/backends/php.js +448 -33
- package/build/src/backends/program.d.ts +81 -0
- package/build/src/backends/program.d.ts.map +1 -0
- package/build/src/backends/program.js +1308 -0
- package/build/src/backends/python.js +7 -1
- package/build/src/backends/ruby.d.ts.map +1 -1
- package/build/src/backends/ruby.js +310 -24
- package/build/src/backends/rust-runtime.d.ts +7 -0
- package/build/src/backends/rust-runtime.d.ts.map +1 -0
- package/build/src/backends/rust-runtime.js +32 -0
- package/build/src/backends/rust-validation.d.ts +9 -0
- package/build/src/backends/rust-validation.d.ts.map +1 -0
- package/build/src/backends/rust-validation.js +78 -0
- package/build/src/backends/rust.d.ts +24 -0
- package/build/src/backends/rust.d.ts.map +1 -0
- package/build/src/backends/rust.js +344 -0
- package/build/src/backends/scalars.d.ts +14 -6
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +167 -17
- package/build/src/backends/shared.d.ts +23 -4
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +2158 -62
- package/build/src/backends/stdlib-support.d.ts +14 -0
- package/build/src/backends/stdlib-support.d.ts.map +1 -0
- package/build/src/backends/stdlib-support.js +237 -0
- package/build/src/backends/swift-runtime.d.ts +3 -0
- package/build/src/backends/swift-runtime.d.ts.map +1 -0
- package/build/src/backends/swift-runtime.js +14 -0
- package/build/src/backends/swift.d.ts +8 -0
- package/build/src/backends/swift.d.ts.map +1 -0
- package/build/src/backends/swift.js +127 -0
- package/build/src/backends/typescript.d.ts.map +1 -1
- package/build/src/backends/typescript.js +344 -24
- package/build/src/backends/wasm.d.ts +43 -0
- package/build/src/backends/wasm.d.ts.map +1 -0
- package/build/src/backends/wasm.js +2164 -0
- package/build/src/backends/writer.d.ts +235 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +468 -3
- package/build/src/diagnostic.d.ts +4 -3
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +5 -3
- package/build/src/frontends/c.d.ts.map +1 -1
- package/build/src/frontends/c.js +5 -3
- package/build/src/frontends/cpp.d.ts.map +1 -1
- package/build/src/frontends/cpp.js +5 -3
- package/build/src/frontends/csharp.d.ts.map +1 -1
- package/build/src/frontends/csharp.js +7 -3
- package/build/src/frontends/dart.d.ts +10 -0
- package/build/src/frontends/dart.d.ts.map +1 -0
- package/build/src/frontends/dart.js +913 -0
- package/build/src/frontends/index.d.ts +3 -1
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +15 -5
- package/build/src/frontends/java.d.ts +110 -1
- package/build/src/frontends/java.d.ts.map +1 -1
- package/build/src/frontends/java.js +1725 -70
- package/build/src/frontends/javascript-typescript.d.ts +69 -1
- package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
- package/build/src/frontends/javascript-typescript.js +1825 -93
- package/build/src/frontends/kotlin.d.ts +10 -0
- package/build/src/frontends/kotlin.d.ts.map +1 -0
- package/build/src/frontends/kotlin.js +685 -0
- package/build/src/frontends/php.d.ts +118 -1
- package/build/src/frontends/php.d.ts.map +1 -1
- package/build/src/frontends/php.js +1583 -76
- package/build/src/frontends/program.d.ts +74 -0
- package/build/src/frontends/program.d.ts.map +1 -0
- package/build/src/frontends/program.js +989 -0
- package/build/src/frontends/ruby.d.ts +68 -1
- package/build/src/frontends/ruby.d.ts.map +1 -1
- package/build/src/frontends/ruby.js +1446 -101
- package/build/src/frontends/rust-parser.d.ts +11 -0
- package/build/src/frontends/rust-parser.d.ts.map +1 -0
- package/build/src/frontends/rust-parser.js +15 -0
- package/build/src/frontends/rust.d.ts +14 -0
- package/build/src/frontends/rust.d.ts.map +1 -0
- package/build/src/frontends/rust.js +715 -0
- package/build/src/frontends/scalars.d.ts +10 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +28 -2
- package/build/src/frontends/swift.d.ts +10 -0
- package/build/src/frontends/swift.d.ts.map +1 -0
- package/build/src/frontends/swift.js +860 -0
- package/build/src/frontends/types.d.ts +186 -0
- package/build/src/frontends/types.d.ts.map +1 -0
- package/build/src/frontends/types.js +634 -0
- package/build/src/language-registry.d.ts +46 -4
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +167 -13
- package/build/src/mapping.d.ts +2 -2
- package/build/src/mapping.d.ts.map +1 -1
- package/build/src/mapping.js +31 -10
- package/build/src/semantic/capabilities.d.ts +66 -0
- package/build/src/semantic/capabilities.d.ts.map +1 -0
- package/build/src/semantic/capabilities.js +649 -0
- package/build/src/semantic/effects.d.ts +26 -0
- package/build/src/semantic/effects.d.ts.map +1 -0
- package/build/src/semantic/effects.js +764 -0
- package/build/src/semantic/generics.d.ts +23 -0
- package/build/src/semantic/generics.d.ts.map +1 -0
- package/build/src/semantic/generics.js +61 -0
- package/build/src/semantic/lifetime.d.ts +37 -0
- package/build/src/semantic/lifetime.d.ts.map +1 -0
- package/build/src/semantic/lifetime.js +527 -0
- package/build/src/semantic/provenance.d.ts +9 -2
- package/build/src/semantic/provenance.d.ts.map +1 -1
- package/build/src/semantic/provenance.js +462 -20
- package/build/src/semantic/scalars.d.ts +11 -0
- package/build/src/semantic/scalars.d.ts.map +1 -1
- package/build/src/semantic/scalars.js +16 -1
- package/build/src/semantic/stdlib.d.ts +254 -0
- package/build/src/semantic/stdlib.d.ts.map +1 -0
- package/build/src/semantic/stdlib.js +880 -0
- package/build/src/semantic/types.d.ts +2952 -202
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +688 -15
- package/build/src/semantic/validate.d.ts +85 -5
- package/build/src/semantic/validate.d.ts.map +1 -1
- package/build/src/semantic/validate.js +2576 -98
- package/build/src/stdlib-facades.d.ts +304 -0
- package/build/src/stdlib-facades.d.ts.map +1 -0
- package/build/src/stdlib-facades.js +1167 -0
- package/build/src/stdlib-negotiation.d.ts +69 -0
- package/build/src/stdlib-negotiation.d.ts.map +1 -0
- package/build/src/stdlib-negotiation.js +403 -0
- package/build/src/stdlib-providers.d.ts +72 -0
- package/build/src/stdlib-providers.d.ts.map +1 -0
- package/build/src/stdlib-providers.js +339 -0
- package/build/src/toolchains.d.ts +55 -1
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +15 -4
- package/docs/architecture.md +45 -13
- package/docs/dart.md +60 -0
- package/docs/goals.md +3 -3
- package/docs/ios.md +121 -0
- package/docs/kotlin.md +42 -0
- package/docs/language-support.md +231 -26
- package/docs/multi-file-modules.md +52 -0
- package/docs/parser-qualification.md +121 -8
- package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
- package/docs/rust.md +88 -0
- package/docs/source-maps.md +15 -7
- package/docs/standard-library-portability.md +39 -8
- package/docs/swift.md +44 -0
- package/docs/testing.md +366 -4
- package/docs/webassembly.md +52 -0
- package/index.js +63 -8
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
- package/package.json +5 -2
- package/src/artifact-path.js +47 -2
- package/src/artifacts.js +67 -0
- package/src/backends/c-validation.js +6 -1
- package/src/backends/cpp-validation.js +6 -1
- package/src/backends/csharp.js +3 -0
- package/src/backends/dart-runtime.js +41 -0
- package/src/backends/dart.js +326 -0
- package/src/backends/effects.js +705 -0
- package/src/backends/go.js +14 -2
- package/src/backends/identifiers.js +160 -9
- package/src/backends/index.js +27 -2
- package/src/backends/ios.js +1612 -0
- package/src/backends/java.js +454 -36
- package/src/backends/javascript.js +389 -23
- package/src/backends/kotlin-runtime.js +29 -0
- package/src/backends/kotlin.js +141 -0
- package/src/backends/native-validation.js +1 -1
- package/src/backends/ordered-expressions.js +40 -6
- package/src/backends/php-stdlib-support.js +239 -0
- package/src/backends/php.js +469 -32
- package/src/backends/program.js +1407 -0
- package/src/backends/python.js +3 -0
- package/src/backends/ruby.js +326 -23
- package/src/backends/rust-runtime.js +34 -0
- package/src/backends/rust-validation.js +75 -0
- package/src/backends/rust.js +335 -0
- package/src/backends/scalars.js +141 -16
- package/src/backends/shared.js +2304 -124
- package/src/backends/stdlib-support.js +234 -0
- package/src/backends/swift-runtime.js +14 -0
- package/src/backends/swift.js +132 -0
- package/src/backends/typescript.js +349 -23
- package/src/backends/wasm.js +2208 -0
- package/src/backends/writer.js +520 -2
- package/src/diagnostic.js +4 -2
- package/src/frontends/c.js +4 -2
- package/src/frontends/cpp.js +4 -2
- package/src/frontends/csharp.js +4 -2
- package/src/frontends/dart.js +963 -0
- package/src/frontends/index.js +14 -4
- package/src/frontends/java.js +1977 -69
- package/src/frontends/javascript-typescript.js +2046 -102
- package/src/frontends/kotlin.js +713 -0
- package/src/frontends/php.js +1725 -79
- package/src/frontends/program.js +1062 -0
- package/src/frontends/ruby.js +1624 -98
- package/src/frontends/rust-parser.js +18 -0
- package/src/frontends/rust.js +714 -0
- package/src/frontends/scalars.js +31 -1
- package/src/frontends/swift.js +893 -0
- package/src/frontends/types.js +750 -0
- package/src/language-registry.js +172 -12
- package/src/mapping.js +33 -9
- package/src/semantic/capabilities.js +671 -0
- package/src/semantic/effects.js +737 -0
- package/src/semantic/generics.js +58 -0
- package/src/semantic/lifetime.js +517 -0
- package/src/semantic/provenance.js +412 -19
- package/src/semantic/scalars.js +17 -0
- package/src/semantic/stdlib.js +921 -0
- package/src/semantic/types.js +765 -14
- package/src/semantic/validate.js +2934 -209
- package/src/stdlib-facades.js +1211 -0
- package/src/stdlib-negotiation.js +446 -0
- package/src/stdlib-providers.js +377 -0
- package/src/toolchains.js +16 -3
|
@@ -0,0 +1,715 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { rustRuntime } from "../backends/rust-runtime.js";
|
|
3
|
+
import { maximumRustSourceLength } from "../backends/rust-validation.js";
|
|
4
|
+
import { isRustIdentifier } from "../backends/identifiers.js";
|
|
5
|
+
import { missingType, SemantifoldDiagnostic, unsupportedSyntax } from "../diagnostic.js";
|
|
6
|
+
import { createCoordinateIndex, indexedPointAt } from "../semantic/location.js";
|
|
7
|
+
import { withAdaptedOperation } from "../semantic/operators.js";
|
|
8
|
+
import { withParserRanges } from "../semantic/provenance.js";
|
|
9
|
+
import { hasOnlyUnicodeScalars } from "../semantic/scalars.js";
|
|
10
|
+
import { validateParsedModule } from "../semantic/validate.js";
|
|
11
|
+
import { sourceScalarType } from "./scalars.js";
|
|
12
|
+
import { parseRustCst } from "./rust-parser.js";
|
|
13
|
+
/** @typedef {import("./rust-parser.js").CstNode} CstNode */
|
|
14
|
+
/** @typedef {import("../semantic/types.js").Expression} Expression */
|
|
15
|
+
/** @typedef {import("../semantic/types.js").Statement} Statement */
|
|
16
|
+
/** @typedef {import("../semantic/types.js").SemanticTypeName} Scalar */
|
|
17
|
+
const binaryOperations = new Map([
|
|
18
|
+
["+", "Add"], ["-", "Subtract"], ["*", "Multiply"], ["==", "Equal"], ["!=", "NotEqual"],
|
|
19
|
+
["<", "LessThan"], ["<=", "LessThanOrEqual"], [">", "GreaterThan"], [">=", "GreaterThanOrEqual"],
|
|
20
|
+
["&&", "And"], ["||", "Or"]
|
|
21
|
+
]);
|
|
22
|
+
const arithmeticHelpers = new Map([
|
|
23
|
+
["semantifold_integer_add", "PhpAdd"], ["semantifold_integer_subtract", "Subtract"],
|
|
24
|
+
["semantifold_integer_multiply", "Multiply"]
|
|
25
|
+
]);
|
|
26
|
+
/** Consumes complete Rust CST shapes and retains source-only scaffold constraints. */
|
|
27
|
+
class RustReader {
|
|
28
|
+
/**
|
|
29
|
+
* Owns source text and parser-origin metadata, never native parser handles.
|
|
30
|
+
* @param {string} filename - Original filename.
|
|
31
|
+
* @param {string} source - Exact source.
|
|
32
|
+
*/
|
|
33
|
+
constructor(filename, source) {
|
|
34
|
+
this.filename = filename;
|
|
35
|
+
this.source = source;
|
|
36
|
+
this.coordinates = createCoordinateIndex(source);
|
|
37
|
+
/** @type {Set<string>} */
|
|
38
|
+
this.helpers = new Set();
|
|
39
|
+
/** @type {Map<Expression, CstNode>} */
|
|
40
|
+
this.clones = new Map();
|
|
41
|
+
/** @type {Map<Expression, {borrowed: boolean, node: CstNode}>} */
|
|
42
|
+
this.additions = new Map();
|
|
43
|
+
/** @type {Map<Statement, {type: string, node: CstNode}>} */
|
|
44
|
+
this.prints = new Map();
|
|
45
|
+
/** @type {Map<string, Scalar>} */
|
|
46
|
+
this.functions = new Map();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Locates an original parser node in UTF-16 coordinates.
|
|
50
|
+
* @param {CstNode} node - Original node.
|
|
51
|
+
* @returns {import("../semantic/types.js").SourceLocation} Exact location.
|
|
52
|
+
*/
|
|
53
|
+
location(node) {
|
|
54
|
+
return { filename: this.filename, start: indexedPointAt(this.coordinates, node.startIndex), end: indexedPointAt(this.coordinates, node.endIndex) };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Reads the spelling of an already recognized parser node.
|
|
58
|
+
* @param {CstNode} node - Recognized node.
|
|
59
|
+
* @returns {string} Original spelling.
|
|
60
|
+
*/
|
|
61
|
+
text(node) {
|
|
62
|
+
return this.source.slice(node.startIndex, node.endIndex);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Rejects one located source-profile violation.
|
|
66
|
+
* @param {CstNode} node - Violating node.
|
|
67
|
+
* @param {string} [detail] - Profile detail.
|
|
68
|
+
* @returns {never} Always throws.
|
|
69
|
+
*/
|
|
70
|
+
fail(node, detail = node.type) {
|
|
71
|
+
unsupportedSyntax("rust", detail, this.location(node));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Accounts for recovery, every extra, and doc comments before interpreting meaning.
|
|
75
|
+
* @param {CstNode} node - Current node.
|
|
76
|
+
* @param {number} [depth] - Bounded traversal depth.
|
|
77
|
+
* @returns {void}
|
|
78
|
+
*/
|
|
79
|
+
validateTree(node, depth = 0) {
|
|
80
|
+
if (depth > 512)
|
|
81
|
+
this.fail(node, "Rust CST exceeds the 512-level traversal limit");
|
|
82
|
+
for (const { node: child } of node.children)
|
|
83
|
+
this.validateTree(child, depth + 1);
|
|
84
|
+
if (node.error || node.missing || node.hasError) {
|
|
85
|
+
throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "rust", location: this.location(node), message: `Rust parser recovery at '${node.type}'.` });
|
|
86
|
+
}
|
|
87
|
+
if (node.extra && !["line_comment", "block_comment"].includes(node.type))
|
|
88
|
+
this.fail(node, "unexpected extra parser child");
|
|
89
|
+
if (["line_comment", "block_comment"].includes(node.type) && /^(?:\/\/[!/]|\/\*[*!])/u.test(this.text(node))) {
|
|
90
|
+
this.fail(node, "doc-comment attribute");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Omits only inert comments already checked during exhaustive traversal.
|
|
95
|
+
* @param {CstNode} node - Parent.
|
|
96
|
+
* @returns {CstNode[]} Ordered structural children.
|
|
97
|
+
*/
|
|
98
|
+
parts(node) {
|
|
99
|
+
return node.children.map(({ node: child }) => child).filter(child => !["line_comment", "block_comment"].includes(child.type));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Requires an exact sole parser field.
|
|
103
|
+
* @param {CstNode} node - Field owner.
|
|
104
|
+
* @param {string} name - Field name.
|
|
105
|
+
* @returns {CstNode} Sole field value.
|
|
106
|
+
*/
|
|
107
|
+
field(node, name) {
|
|
108
|
+
const edges = node.children.filter(({ field }) => field == name);
|
|
109
|
+
if (edges.length != 1)
|
|
110
|
+
this.fail(node, `expected one '${name}' field`);
|
|
111
|
+
return edges[0].node;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Requires all ordered children, including anonymous punctuation.
|
|
115
|
+
* @param {CstNode} node - Shape owner.
|
|
116
|
+
* @param {(CstNode | string)[]} expected - Exact child sequence.
|
|
117
|
+
* @returns {void}
|
|
118
|
+
*/
|
|
119
|
+
shape(node, expected) {
|
|
120
|
+
const parts = this.parts(node);
|
|
121
|
+
if (parts.length != expected.length || parts.some((child, index) => typeof expected[index] == "string" ? child.type != expected[index] || !child.named && this.text(child) != expected[index] : child !== expected[index]))
|
|
122
|
+
this.fail(node, `${node.type} child shape`);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Protects Rust keywords and the private support namespace.
|
|
126
|
+
* @param {CstNode} node - Identifier token.
|
|
127
|
+
* @returns {string} Validated name.
|
|
128
|
+
*/
|
|
129
|
+
identifier(node) {
|
|
130
|
+
const name = this.text(node);
|
|
131
|
+
if (node.type != "identifier" || !isRustIdentifier(name))
|
|
132
|
+
this.fail(node, "reserved or unsupported identifier");
|
|
133
|
+
return name;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Accepts only explicitly spelled i64, bool and owned String.
|
|
137
|
+
* @param {CstNode} node - Type token.
|
|
138
|
+
* @returns {import("../semantic/types.js").TypeReference} Semantic scalar type.
|
|
139
|
+
*/
|
|
140
|
+
type(node) {
|
|
141
|
+
if (node.children.length || !["primitive_type", "type_identifier"].includes(node.type))
|
|
142
|
+
this.fail(node, "scalar type shape");
|
|
143
|
+
const spelling = this.text(node);
|
|
144
|
+
const type = sourceScalarType("rust", spelling, this.location(node));
|
|
145
|
+
if (!type)
|
|
146
|
+
return missingType("rust", "scalar", this.location(node));
|
|
147
|
+
if ((spelling == "String") != (node.type == "type_identifier"))
|
|
148
|
+
this.fail(node, "scalar type spelling");
|
|
149
|
+
return type;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Converts exact call syntax without interpreting macro token trees as calls.
|
|
153
|
+
* @param {CstNode} node - Call expression.
|
|
154
|
+
* @returns {{name: CstNode, arguments: CstNode[]}} Parsed direct argument sequence.
|
|
155
|
+
*/
|
|
156
|
+
call(node) {
|
|
157
|
+
if (node.type != "call_expression")
|
|
158
|
+
this.fail(node, "direct call required");
|
|
159
|
+
const name = this.field(node, "function");
|
|
160
|
+
const list = this.field(node, "arguments");
|
|
161
|
+
this.shape(node, [name, list]);
|
|
162
|
+
if (list.type != "arguments")
|
|
163
|
+
this.fail(list, "call arguments");
|
|
164
|
+
const args = this.parts(list).slice(1, -1).filter((_part, index) => index % 2 == 0);
|
|
165
|
+
this.shape(list, ["(", ...args.flatMap((arg, index) => index == 0 ? [arg] : [",", arg]), ")"]);
|
|
166
|
+
return { arguments: args, name };
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Decodes parser-owned ordinary string content and exact scalar escapes.
|
|
170
|
+
* @param {CstNode} node - String literal.
|
|
171
|
+
* @returns {string} Unicode scalar value.
|
|
172
|
+
*/
|
|
173
|
+
string(node) {
|
|
174
|
+
if (node.type != "string_literal")
|
|
175
|
+
this.fail(node, "ordinary String literal required");
|
|
176
|
+
const parts = this.parts(node);
|
|
177
|
+
this.shape(node, ['"', ...parts.slice(1, -1), '"']);
|
|
178
|
+
let value = "";
|
|
179
|
+
for (const part of parts.slice(1, -1)) {
|
|
180
|
+
const spelling = this.text(part);
|
|
181
|
+
if (part.type == "string_content") {
|
|
182
|
+
if (/[\r\n]/u.test(spelling))
|
|
183
|
+
this.fail(part, "raw string line terminator");
|
|
184
|
+
value += spelling;
|
|
185
|
+
}
|
|
186
|
+
else if (part.type == "escape_sequence") {
|
|
187
|
+
const escape = spelling.slice(1);
|
|
188
|
+
const simple = new Map([["0", "\0"], ["n", "\n"], ["r", "\r"], ["t", "\t"], ["\\", "\\"], ['"', '"'], ["'", "'"]]);
|
|
189
|
+
if (spelling[0] != "\\")
|
|
190
|
+
this.fail(part, "escape prefix");
|
|
191
|
+
if (simple.has(escape))
|
|
192
|
+
value += simple.get(escape);
|
|
193
|
+
else if (/^x[0-9a-fA-F]{2}$/u.test(escape)) {
|
|
194
|
+
const scalar = Number.parseInt(escape.slice(1), 16);
|
|
195
|
+
if (scalar > 127)
|
|
196
|
+
this.fail(part, "non-ASCII byte escape");
|
|
197
|
+
value += String.fromCodePoint(scalar);
|
|
198
|
+
}
|
|
199
|
+
else if (/^u\{[0-9a-fA-F]{1,6}\}$/u.test(escape)) {
|
|
200
|
+
const scalar = Number.parseInt(escape.slice(2, -1), 16);
|
|
201
|
+
if (scalar > 0x10FFFF || scalar >= 0xD800 && scalar <= 0xDFFF)
|
|
202
|
+
this.fail(part, "non-scalar Unicode escape");
|
|
203
|
+
value += String.fromCodePoint(scalar);
|
|
204
|
+
}
|
|
205
|
+
else
|
|
206
|
+
this.fail(part, "unsupported string escape");
|
|
207
|
+
}
|
|
208
|
+
else
|
|
209
|
+
this.fail(part, "string child");
|
|
210
|
+
}
|
|
211
|
+
return value;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Converts exact scalar expressions while retaining source clone/borrow constraints.
|
|
215
|
+
* @param {CstNode} node - Expression node.
|
|
216
|
+
* @returns {Expression} Pending typed semantic expression.
|
|
217
|
+
*/
|
|
218
|
+
expression(node) {
|
|
219
|
+
const location = this.location(node);
|
|
220
|
+
if (node.type == "parenthesized_expression") {
|
|
221
|
+
const parts = this.parts(node);
|
|
222
|
+
this.shape(node, ["(", parts[1], ")"]);
|
|
223
|
+
return this.expression(parts[1]);
|
|
224
|
+
}
|
|
225
|
+
if (node.type == "identifier")
|
|
226
|
+
return withParserRanges({ kind: "IdentifierExpression", location, name: this.identifier(node) }, { name: location });
|
|
227
|
+
if (node.type == "integer_literal") {
|
|
228
|
+
const spelling = this.text(node);
|
|
229
|
+
const value = Number(spelling.slice(0, -3));
|
|
230
|
+
if (!/^(?:0|[1-9][0-9]*)i64$/u.test(spelling) || !Number.isSafeInteger(value))
|
|
231
|
+
this.fail(node, "non-safe or noncanonical i64 literal");
|
|
232
|
+
return withParserRanges({ kind: "IntegerLiteral", location, value }, { literal: location });
|
|
233
|
+
}
|
|
234
|
+
if (node.type == "boolean_literal") {
|
|
235
|
+
const spelling = this.text(node);
|
|
236
|
+
if (spelling != "true" && spelling != "false")
|
|
237
|
+
this.fail(node, "Boolean literal spelling");
|
|
238
|
+
this.shape(node, [spelling]);
|
|
239
|
+
return withParserRanges({ kind: "BooleanLiteral", location, value: spelling == "true" }, { literal: location });
|
|
240
|
+
}
|
|
241
|
+
if (node.type == "unary_expression") {
|
|
242
|
+
const parts = this.parts(node);
|
|
243
|
+
this.shape(node, [parts[0], parts[1]]);
|
|
244
|
+
if (!["-", "!"].includes(parts[0].type))
|
|
245
|
+
this.fail(parts[0], "unary operator");
|
|
246
|
+
return this.unary(node, parts[0].type == "-" ? "Negate" : "Not", this.expression(parts[1]), parts[0]);
|
|
247
|
+
}
|
|
248
|
+
if (node.type == "binary_expression") {
|
|
249
|
+
const left = this.field(node, "left");
|
|
250
|
+
const right = this.field(node, "right");
|
|
251
|
+
const operator = this.field(node, "operator");
|
|
252
|
+
const intent = binaryOperations.get(operator.type);
|
|
253
|
+
this.shape(node, [left, operator, right]);
|
|
254
|
+
if (!intent)
|
|
255
|
+
this.fail(operator, "unsupported binary operator");
|
|
256
|
+
const borrowed = operator.type == "+" && right.type == "reference_expression";
|
|
257
|
+
const value = borrowed ? this.field(right, "value") : right;
|
|
258
|
+
if (borrowed)
|
|
259
|
+
this.shape(right, ["&", value]);
|
|
260
|
+
const expression = this.binary(node, intent, this.expression(left), this.expression(value), operator);
|
|
261
|
+
if (operator.type == "+")
|
|
262
|
+
this.additions.set(expression, { borrowed, node: right });
|
|
263
|
+
return expression;
|
|
264
|
+
}
|
|
265
|
+
if (node.type == "call_expression") {
|
|
266
|
+
const call = this.call(node);
|
|
267
|
+
const name = this.text(call.name);
|
|
268
|
+
if (call.name.type == "scoped_identifier") {
|
|
269
|
+
const owner = this.field(call.name, "path");
|
|
270
|
+
const method = this.field(call.name, "name");
|
|
271
|
+
this.shape(call.name, [owner, "::", method]);
|
|
272
|
+
if (owner.type != "identifier" || this.text(owner) != "String" || method.type != "identifier" || this.text(method) != "from" || call.arguments.length != 1) {
|
|
273
|
+
this.fail(call.name, "exact String::from construction required");
|
|
274
|
+
}
|
|
275
|
+
return withParserRanges({ kind: "StringLiteral", location, value: this.string(call.arguments[0]) }, { literal: this.location(call.arguments[0]) });
|
|
276
|
+
}
|
|
277
|
+
if (call.name.type == "field_expression") {
|
|
278
|
+
const receiver = this.field(call.name, "value");
|
|
279
|
+
const method = this.field(call.name, "field");
|
|
280
|
+
this.shape(call.name, [receiver, ".", method]);
|
|
281
|
+
if (method.type != "field_identifier" || this.text(method) != "clone" || call.arguments.length)
|
|
282
|
+
this.fail(call.name, "exact owned String clone required");
|
|
283
|
+
const expression = this.expression(receiver);
|
|
284
|
+
this.clones.set(expression, call.name);
|
|
285
|
+
return expression;
|
|
286
|
+
}
|
|
287
|
+
if (call.name.type != "identifier")
|
|
288
|
+
this.fail(call.name, "direct function call required");
|
|
289
|
+
if (this.helpers.has(name) && name == "semantifold_integer_negate") {
|
|
290
|
+
if (call.arguments.length != 1)
|
|
291
|
+
this.fail(node, "negation helper arity");
|
|
292
|
+
return this.unary(node, "Negate", this.expression(call.arguments[0]), call.name);
|
|
293
|
+
}
|
|
294
|
+
const intent = this.helpers.has(name) ? arithmeticHelpers.get(name) : undefined;
|
|
295
|
+
if (intent) {
|
|
296
|
+
if (call.arguments.length != 2)
|
|
297
|
+
this.fail(node, "arithmetic helper arity");
|
|
298
|
+
return this.binary(node, intent, this.expression(call.arguments[0]), this.expression(call.arguments[1]), call.name);
|
|
299
|
+
}
|
|
300
|
+
const callee = this.identifier(call.name);
|
|
301
|
+
if (call.arguments.length != 2)
|
|
302
|
+
this.fail(node, "semantic call arity");
|
|
303
|
+
return withParserRanges({ kind: "CallExpression", location, callee, arguments: call.arguments.map(argument => this.expression(argument)) }, { callee: this.location(call.name) });
|
|
304
|
+
}
|
|
305
|
+
return this.fail(node);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Retains parser operator intent until shared scalar resolution.
|
|
309
|
+
* @param {CstNode} node - Owning node.
|
|
310
|
+
* @param {string} intent - Parser operation.
|
|
311
|
+
* @param {Expression} left - Left operand.
|
|
312
|
+
* @param {Expression} right - Right operand.
|
|
313
|
+
* @param {CstNode} operator - Exact operator token.
|
|
314
|
+
* @returns {Expression} Pending binary expression.
|
|
315
|
+
*/
|
|
316
|
+
binary(node, intent, left, right, operator) {
|
|
317
|
+
return /** @type {Expression} */ (withAdaptedOperation(withParserRanges({ kind: "BinaryExpression", location: this.location(node), left, right }, { operator: this.location(operator) }), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (intent)));
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Retains unary parser intent and its original token range.
|
|
321
|
+
* @param {CstNode} node - Owning node.
|
|
322
|
+
* @param {"Negate" | "Not"} intent - Unary intent.
|
|
323
|
+
* @param {Expression} operand - Operand.
|
|
324
|
+
* @param {CstNode} operator - Exact token.
|
|
325
|
+
* @returns {Expression} Pending unary expression.
|
|
326
|
+
*/
|
|
327
|
+
unary(node, intent, operand, operator) {
|
|
328
|
+
return /** @type {Expression} */ (withAdaptedOperation(withParserRanges({ kind: "UnaryExpression", location: this.location(node), operand }, { operator: this.location(operator) }), intent));
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Converts one explicitly typed initialized binding or executable statement.
|
|
332
|
+
* @param {CstNode} node - Statement.
|
|
333
|
+
* @returns {Statement} Semantic statement.
|
|
334
|
+
*/
|
|
335
|
+
statement(node) {
|
|
336
|
+
const location = this.location(node);
|
|
337
|
+
const parts = this.parts(node);
|
|
338
|
+
if (node.type == "let_declaration") {
|
|
339
|
+
const typeNode = node.children.find(({ field }) => field == "type")?.node;
|
|
340
|
+
if (!typeNode)
|
|
341
|
+
return missingType("rust", "local", location);
|
|
342
|
+
const name = this.field(node, "pattern");
|
|
343
|
+
const value = this.field(node, "value");
|
|
344
|
+
const mutable = parts[1].type == "mutable_specifier";
|
|
345
|
+
this.shape(node, ["let", ...(mutable ? [parts[1]] : []), name, ":", typeNode, "=", value, ";"]);
|
|
346
|
+
if (mutable && this.text(parts[1]) != "mut")
|
|
347
|
+
this.fail(parts[1], "mutability token");
|
|
348
|
+
return withParserRanges({ kind: "LocalDeclaration", location, name: this.identifier(name), type: this.type(typeNode), mutable,
|
|
349
|
+
initializer: this.expression(value) }, { name: this.location(name), operator: this.location(parts[parts.length - 3]) });
|
|
350
|
+
}
|
|
351
|
+
if (node.type != "expression_statement")
|
|
352
|
+
this.fail(node, "explicit statement required; tail expressions are unsupported");
|
|
353
|
+
const expression = parts[0];
|
|
354
|
+
if (expression.type == "if_expression") {
|
|
355
|
+
this.shape(node, [expression]);
|
|
356
|
+
return this.conditional(expression);
|
|
357
|
+
}
|
|
358
|
+
this.shape(node, [expression, ";"]);
|
|
359
|
+
if (expression.type == "return_expression") {
|
|
360
|
+
const returned = this.parts(expression);
|
|
361
|
+
this.shape(expression, ["return", returned[1]]);
|
|
362
|
+
return { kind: "ReturnStatement", location, expression: this.expression(returned[1]) };
|
|
363
|
+
}
|
|
364
|
+
if (expression.type == "assignment_expression") {
|
|
365
|
+
const left = this.field(expression, "left");
|
|
366
|
+
const right = this.field(expression, "right");
|
|
367
|
+
this.shape(expression, [left, "=", right]);
|
|
368
|
+
const target = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: this.location(left), name: this.identifier(left) }, { name: this.location(left) });
|
|
369
|
+
return withParserRanges({ kind: "AssignmentStatement", location, target, expression: this.expression(right) }, { operator: this.location(this.parts(expression)[1]) });
|
|
370
|
+
}
|
|
371
|
+
const call = this.call(expression);
|
|
372
|
+
const name = this.text(call.name);
|
|
373
|
+
if (call.name.type != "identifier" || !this.helpers.has(name) || !/^semantifold_print_(?:integer|boolean|string)$/u.test(name) || call.arguments.length != 1)
|
|
374
|
+
this.fail(node, "exact print helper call required");
|
|
375
|
+
const statement = { kind: /** @type {const} */ ("PrintStatement"), location, expression: this.expression(call.arguments[0]) };
|
|
376
|
+
this.prints.set(statement, { node: call.name, type: name.slice("semantifold_print_".length) });
|
|
377
|
+
return statement;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Converts exact braced conditionals and else-if nesting.
|
|
381
|
+
* @param {CstNode} node - If expression used as a statement.
|
|
382
|
+
* @returns {import("../semantic/types.js").IfStatement} Conditional statement.
|
|
383
|
+
*/
|
|
384
|
+
conditional(node) {
|
|
385
|
+
const condition = this.field(node, "condition");
|
|
386
|
+
const consequence = this.field(node, "consequence");
|
|
387
|
+
const alternative = node.children.find(({ field }) => field == "alternative")?.node;
|
|
388
|
+
this.shape(node, ["if", condition, consequence, ...(alternative ? [alternative] : [])]);
|
|
389
|
+
const statement = { kind: /** @type {const} */ ("IfStatement"), location: this.location(node), condition: this.expression(condition), consequent: this.block(consequence) };
|
|
390
|
+
if (!alternative)
|
|
391
|
+
return statement;
|
|
392
|
+
const branch = this.parts(alternative)[1];
|
|
393
|
+
this.shape(alternative, ["else", branch]);
|
|
394
|
+
return { ...statement, alternate: branch.type == "if_expression" ? { kind: "Block", location: this.location(branch), statements: [this.conditional(branch)] } : this.block(branch) };
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Converts one complete lexical block.
|
|
398
|
+
* @param {CstNode} node - Braced block.
|
|
399
|
+
* @returns {import("../semantic/types.js").Block} Semantic block.
|
|
400
|
+
*/
|
|
401
|
+
block(node) {
|
|
402
|
+
if (node.type != "block")
|
|
403
|
+
this.fail(node, "braced block required");
|
|
404
|
+
const parts = this.parts(node);
|
|
405
|
+
this.shape(node, ["{", ...parts.slice(1, -1), "}"]);
|
|
406
|
+
return { kind: "Block", location: this.location(node), statements: parts.slice(1, -1).map(child => this.statement(child)) };
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Converts a crate-root function with exactly two required by-value parameters.
|
|
410
|
+
* @param {CstNode} node - Function item.
|
|
411
|
+
* @returns {import("../semantic/types.js").FunctionDeclaration} Semantic declaration.
|
|
412
|
+
*/
|
|
413
|
+
function(node) {
|
|
414
|
+
const name = this.field(node, "name");
|
|
415
|
+
const parameters = this.field(node, "parameters");
|
|
416
|
+
const returnType = node.children.find(({ field }) => field == "return_type")?.node;
|
|
417
|
+
const body = this.field(node, "body");
|
|
418
|
+
if (!returnType)
|
|
419
|
+
return missingType("rust", "function return", this.location(node));
|
|
420
|
+
this.shape(node, ["fn", name, parameters, "->", returnType, body]);
|
|
421
|
+
this.shape(parameters, ["(", "parameter", ",", "parameter", ")"]);
|
|
422
|
+
const converted = [this.parts(parameters)[1], this.parts(parameters)[3]].map(parameter => {
|
|
423
|
+
const pattern = this.field(parameter, "pattern");
|
|
424
|
+
const type = this.field(parameter, "type");
|
|
425
|
+
this.shape(parameter, [pattern, ":", type]);
|
|
426
|
+
return withParserRanges({ kind: /** @type {const} */ ("Parameter"), location: this.location(parameter), name: this.identifier(pattern), type: this.type(type) }, { name: this.location(pattern) });
|
|
427
|
+
});
|
|
428
|
+
return withParserRanges({ kind: "FunctionDeclaration", location: this.location(node), name: this.identifier(name), parameters: converted,
|
|
429
|
+
returnType: this.type(returnType), body: this.block(body) }, { name: this.location(name) });
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Compares all fields, children and leaf spellings against qualified support syntax.
|
|
433
|
+
* @param {CstNode} actual - Original node.
|
|
434
|
+
* @param {CstNode} expected - Qualified node.
|
|
435
|
+
* @param {RustReader} canonical - Qualified spelling reader.
|
|
436
|
+
* @returns {void}
|
|
437
|
+
*/
|
|
438
|
+
compareTree(actual, expected, canonical) {
|
|
439
|
+
if (actual.type != expected.type || actual.named != expected.named || actual.extra != expected.extra)
|
|
440
|
+
this.fail(actual, "modified Rust support node");
|
|
441
|
+
const left = this.parts(actual);
|
|
442
|
+
const right = canonical.parts(expected);
|
|
443
|
+
if (left.length != right.length)
|
|
444
|
+
this.fail(actual, "modified Rust support children");
|
|
445
|
+
if (!left.length && this.text(actual) != canonical.text(expected))
|
|
446
|
+
this.fail(actual, "modified Rust support token");
|
|
447
|
+
left.forEach((child, index) => {
|
|
448
|
+
if (actual.children.find(edge => edge.node === child)?.field != expected.children.find(edge => edge.node === right[index])?.field)
|
|
449
|
+
this.fail(child, "modified Rust support field");
|
|
450
|
+
this.compareTree(child, right[index], canonical);
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Resolves only already validated scalar expressions for scaffold checking.
|
|
455
|
+
* @param {Expression} expression - Resolved semantic expression.
|
|
456
|
+
* @param {Map<string, Scalar>} bindings - Lexical types.
|
|
457
|
+
* @returns {Scalar} Semantic result type.
|
|
458
|
+
*/
|
|
459
|
+
expressionType(expression, bindings) {
|
|
460
|
+
if (expression.kind == "StringLiteral")
|
|
461
|
+
return "string";
|
|
462
|
+
if (expression.kind == "IntegerLiteral")
|
|
463
|
+
return "integer";
|
|
464
|
+
if (expression.kind == "BooleanLiteral")
|
|
465
|
+
return "boolean";
|
|
466
|
+
if (expression.kind == "BinaryExpression" || expression.kind == "UnaryExpression")
|
|
467
|
+
return expression.type;
|
|
468
|
+
if (expression.kind != "CallExpression" && expression.kind != "IdentifierExpression") {
|
|
469
|
+
throw new Error("Validated Rust source exposed a collection expression.");
|
|
470
|
+
}
|
|
471
|
+
const type = expression.kind == "CallExpression" ? this.functions.get(expression.callee) : bindings.get(expression.name);
|
|
472
|
+
if (!type)
|
|
473
|
+
throw new Error("Validated Rust expression lost its scalar binding.");
|
|
474
|
+
return type;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Checks clone, borrow and print constraints after shared operation resolution.
|
|
478
|
+
* @param {import("../semantic/types.js").Block} block - Resolved block.
|
|
479
|
+
* @param {Map<string, Scalar>} inherited - Enclosing types.
|
|
480
|
+
* @returns {void}
|
|
481
|
+
*/
|
|
482
|
+
validateScalars(block, inherited) {
|
|
483
|
+
const bindings = new Map(inherited);
|
|
484
|
+
/**
|
|
485
|
+
* Checks each original clone and borrowed concatenation after scalar resolution.
|
|
486
|
+
* @param {Expression} expression - Current expression.
|
|
487
|
+
* @returns {void}
|
|
488
|
+
*/
|
|
489
|
+
const visit = expression => {
|
|
490
|
+
const clone = this.clones.get(expression);
|
|
491
|
+
const addition = this.additions.get(expression);
|
|
492
|
+
if (clone && this.expressionType(expression, bindings) != "string")
|
|
493
|
+
this.fail(clone, "clone requires owned String");
|
|
494
|
+
if (addition && (this.expressionType(expression, bindings) == "string") != addition.borrowed)
|
|
495
|
+
this.fail(addition.node, "string concatenation requires exactly a borrowed String RHS");
|
|
496
|
+
if (expression.kind == "CallExpression")
|
|
497
|
+
expression.arguments.forEach(visit);
|
|
498
|
+
else if (expression.kind == "UnaryExpression")
|
|
499
|
+
visit(expression.operand);
|
|
500
|
+
else if (expression.kind == "BinaryExpression") {
|
|
501
|
+
visit(expression.left);
|
|
502
|
+
visit(expression.right);
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
for (const statement of block.statements) {
|
|
506
|
+
const expression = statement.kind == "IfStatement" ? statement.condition :
|
|
507
|
+
statement.kind == "LocalDeclaration" ? statement.initializer :
|
|
508
|
+
statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ? statement.expression :
|
|
509
|
+
statement.kind == "ReturnStatement" ? statement.expression : undefined;
|
|
510
|
+
if (!expression)
|
|
511
|
+
throw new Error("Validated Rust source contained a bare return.");
|
|
512
|
+
visit(expression);
|
|
513
|
+
if (statement.kind == "LocalDeclaration")
|
|
514
|
+
bindings.set(statement.name,
|
|
515
|
+
/** @type {import("../semantic/types.js").TypeReference} */ (statement.type).name);
|
|
516
|
+
if (statement.kind == "PrintStatement") {
|
|
517
|
+
const print = this.prints.get(statement);
|
|
518
|
+
if (!print)
|
|
519
|
+
throw new Error("Rust print lost its original helper identity.");
|
|
520
|
+
if (this.expressionType(expression, bindings) != print.type)
|
|
521
|
+
this.fail(print.node, "print helper scalar mismatch");
|
|
522
|
+
}
|
|
523
|
+
if (statement.kind == "IfStatement") {
|
|
524
|
+
this.validateScalars(statement.consequent, bindings);
|
|
525
|
+
if (statement.alternate)
|
|
526
|
+
this.validateScalars(statement.alternate, bindings);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Validates genuine source moves in evaluation order, retaining implicit comparison borrows.
|
|
532
|
+
* @param {Expression} expression - Original expression occurrence.
|
|
533
|
+
* @param {Map<string, Scalar>} bindings - Validated lexical types.
|
|
534
|
+
* @param {Set<string>} moved - Definitely or possibly consumed String bindings.
|
|
535
|
+
* @param {Set<string>} borrowed - Borrows held by enclosing operand evaluation.
|
|
536
|
+
* @param {"move" | "borrow"} [usage] - How this expression's result is consumed.
|
|
537
|
+
* @param {boolean} [applyClone] - Whether to apply this occurrence's checked clone wrapper.
|
|
538
|
+
* @returns {Set<string>} Place borrows held until the containing operation completes.
|
|
539
|
+
*/
|
|
540
|
+
ownershipExpression(expression, bindings, moved, borrowed, usage = "move", applyClone = true) {
|
|
541
|
+
if (applyClone && this.clones.has(expression)) {
|
|
542
|
+
this.ownershipExpression(expression, bindings, moved, borrowed, "borrow", false);
|
|
543
|
+
return new Set();
|
|
544
|
+
}
|
|
545
|
+
if (expression.kind == "IdentifierExpression" && this.expressionType(expression, bindings) == "string") {
|
|
546
|
+
const name = expression.name;
|
|
547
|
+
if (moved.has(name))
|
|
548
|
+
unsupportedSyntax("rust", `use of moved String '${name}'`, expression.location);
|
|
549
|
+
if (usage == "borrow")
|
|
550
|
+
return new Set([name]);
|
|
551
|
+
if (borrowed.has(name))
|
|
552
|
+
unsupportedSyntax("rust", `cannot move borrowed String '${name}' during operand evaluation`, expression.location);
|
|
553
|
+
moved.add(name);
|
|
554
|
+
}
|
|
555
|
+
else if (expression.kind == "CallExpression") {
|
|
556
|
+
for (const argument of expression.arguments)
|
|
557
|
+
this.ownershipExpression(argument, bindings, moved, borrowed);
|
|
558
|
+
}
|
|
559
|
+
else if (expression.kind == "UnaryExpression")
|
|
560
|
+
this.ownershipExpression(expression.operand, bindings, moved, borrowed);
|
|
561
|
+
else if (expression.kind == "BinaryExpression") {
|
|
562
|
+
if (expression.operation == "StringEqual" || expression.operation == "StringNotEqual") {
|
|
563
|
+
const held = this.ownershipExpression(expression.left, bindings, moved, borrowed, "borrow");
|
|
564
|
+
this.ownershipExpression(expression.right, bindings, moved, new Set([...borrowed, ...held]), "borrow");
|
|
565
|
+
}
|
|
566
|
+
else {
|
|
567
|
+
this.ownershipExpression(expression.left, bindings, moved, borrowed);
|
|
568
|
+
if (expression.operation == "BooleanAnd" || expression.operation == "BooleanOr") {
|
|
569
|
+
const conditional = new Set(moved);
|
|
570
|
+
this.ownershipExpression(expression.right, bindings, conditional, borrowed);
|
|
571
|
+
for (const name of conditional)
|
|
572
|
+
moved.add(name);
|
|
573
|
+
}
|
|
574
|
+
else
|
|
575
|
+
this.ownershipExpression(expression.right, bindings, moved, borrowed, expression.operation == "StringConcat" ? "borrow" : "move");
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
return new Set();
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Merges source availability only from paths that continue, restoring explicit assignments.
|
|
582
|
+
* @param {import("../semantic/types.js").Block} block - Original lexical block.
|
|
583
|
+
* @param {Map<string, Scalar>} inherited - Visible scalar bindings.
|
|
584
|
+
* @param {Set<string>} inheritedMoved - Incoming consumed bindings.
|
|
585
|
+
* @returns {{moved: Set<string>, returns: boolean}} Outgoing source availability and control flow.
|
|
586
|
+
*/
|
|
587
|
+
validateOwnership(block, inherited, inheritedMoved) {
|
|
588
|
+
const bindings = new Map(inherited);
|
|
589
|
+
const moved = new Set(inheritedMoved);
|
|
590
|
+
for (const statement of block.statements) {
|
|
591
|
+
const expression = statement.kind == "IfStatement" ? statement.condition :
|
|
592
|
+
statement.kind == "LocalDeclaration" ? statement.initializer :
|
|
593
|
+
statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ? statement.expression :
|
|
594
|
+
statement.kind == "ReturnStatement" ? statement.expression : undefined;
|
|
595
|
+
if (!expression)
|
|
596
|
+
throw new Error("Validated Rust source contained a bare return.");
|
|
597
|
+
this.ownershipExpression(expression, bindings, moved, new Set());
|
|
598
|
+
if (statement.kind == "ReturnStatement")
|
|
599
|
+
return { moved, returns: true };
|
|
600
|
+
if (statement.kind == "LocalDeclaration")
|
|
601
|
+
bindings.set(statement.name,
|
|
602
|
+
/** @type {import("../semantic/types.js").TypeReference} */ (statement.type).name);
|
|
603
|
+
else if (statement.kind == "AssignmentStatement")
|
|
604
|
+
moved.delete(statement.target.name);
|
|
605
|
+
else if (statement.kind == "IfStatement") {
|
|
606
|
+
const consequent = this.validateOwnership(statement.consequent, bindings, moved);
|
|
607
|
+
const alternate = statement.alternate ? this.validateOwnership(statement.alternate, bindings, moved) : { moved: new Set(moved), returns: false };
|
|
608
|
+
if (consequent.returns && alternate.returns)
|
|
609
|
+
return { moved, returns: true };
|
|
610
|
+
moved.clear();
|
|
611
|
+
for (const path of [consequent, alternate]) {
|
|
612
|
+
if (!path.returns)
|
|
613
|
+
for (const name of path.moved)
|
|
614
|
+
if (bindings.has(name))
|
|
615
|
+
moved.add(name);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
return { moved, returns: false };
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Validates the complete crate and collapses only exact declared support.
|
|
623
|
+
* @param {CstNode} root - Complete root.
|
|
624
|
+
* @returns {import("../semantic/types.js").SemanticModule} Resolved semantics.
|
|
625
|
+
*/
|
|
626
|
+
module(root) {
|
|
627
|
+
this.validateTree(root);
|
|
628
|
+
if (root.type != "source_file")
|
|
629
|
+
this.fail(root, "crate root required");
|
|
630
|
+
const canonical = new RustReader(this.filename, rustRuntime);
|
|
631
|
+
const support = canonical.parts(parseRustCst(rustRuntime).root);
|
|
632
|
+
const helpers = new Map(support.filter(node => node.type == "function_item").map(node => [canonical.text(canonical.field(node, "name")), node]));
|
|
633
|
+
/** @type {CstNode[]} */
|
|
634
|
+
const definitions = [];
|
|
635
|
+
let lint = false;
|
|
636
|
+
/** @type {CstNode | undefined} */
|
|
637
|
+
let main;
|
|
638
|
+
for (const node of this.parts(root)) {
|
|
639
|
+
if (node.type == "inner_attribute_item") {
|
|
640
|
+
if (lint || definitions.length || main || this.helpers.size)
|
|
641
|
+
this.fail(node, "misplaced Rust lint support");
|
|
642
|
+
this.compareTree(node, support[0], canonical);
|
|
643
|
+
lint = true;
|
|
644
|
+
continue;
|
|
645
|
+
}
|
|
646
|
+
if (node.type != "function_item")
|
|
647
|
+
this.fail(node, "crate-root free functions only");
|
|
648
|
+
const name = this.text(this.field(node, "name"));
|
|
649
|
+
const helper = helpers.get(name);
|
|
650
|
+
if (helper) {
|
|
651
|
+
if (this.helpers.has(name))
|
|
652
|
+
this.fail(node, "duplicate Rust helper");
|
|
653
|
+
this.compareTree(node, helper, canonical);
|
|
654
|
+
this.helpers.add(name);
|
|
655
|
+
}
|
|
656
|
+
else if (name == "main") {
|
|
657
|
+
if (main)
|
|
658
|
+
this.fail(node, "duplicate main");
|
|
659
|
+
main = node;
|
|
660
|
+
}
|
|
661
|
+
else
|
|
662
|
+
definitions.push(node);
|
|
663
|
+
}
|
|
664
|
+
if (!main)
|
|
665
|
+
this.fail(root, "canonical fn main() required");
|
|
666
|
+
if (!definitions.length)
|
|
667
|
+
this.fail(root, "semantic function required");
|
|
668
|
+
const name = this.field(main, "name");
|
|
669
|
+
const parameters = this.field(main, "parameters");
|
|
670
|
+
const body = this.field(main, "body");
|
|
671
|
+
this.shape(main, ["fn", name, parameters, body]);
|
|
672
|
+
this.shape(parameters, ["(", ")"]);
|
|
673
|
+
const module = validateParsedModule({ kind: "Module", location: this.location(root), functions: definitions.map(node => this.function(node)),
|
|
674
|
+
entryPoint: { kind: "EntryPoint", location: this.location(main), body: this.block(body) } }, "rust");
|
|
675
|
+
this.functions = new Map(module.functions.map(declaration => [
|
|
676
|
+
declaration.name,
|
|
677
|
+
/** @type {Scalar} */ ( /** @type {import("../semantic/types.js").TypeReference} */(declaration.returnType).name)
|
|
678
|
+
]));
|
|
679
|
+
for (const declaration of module.functions) {
|
|
680
|
+
const bindings = new Map(declaration.parameters.map(parameter => [parameter.name,
|
|
681
|
+
/** @type {import("../semantic/types.js").TypeReference} */ (parameter.type).name]));
|
|
682
|
+
this.validateScalars(declaration.body, bindings);
|
|
683
|
+
this.validateOwnership(declaration.body, bindings, new Set());
|
|
684
|
+
}
|
|
685
|
+
this.validateScalars(module.entryPoint.body, new Map());
|
|
686
|
+
this.validateOwnership(module.entryPoint.body, new Map(), new Set());
|
|
687
|
+
return module;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Parses only the qualified frozen CST and rejects unsupported input before adaptation.
|
|
692
|
+
* @param {{filename: string, source: string}} input - Exact source request.
|
|
693
|
+
* @returns {import("../semantic/types.js").SemanticModule} Rust semantic module.
|
|
694
|
+
*/
|
|
695
|
+
export function parseRust({ filename, source }) {
|
|
696
|
+
const coordinates = createCoordinateIndex(source);
|
|
697
|
+
const location = { filename, start: indexedPointAt(coordinates, 0), end: indexedPointAt(coordinates, source.length) };
|
|
698
|
+
if (!hasOnlyUnicodeScalars(source)) {
|
|
699
|
+
const offset = source.search(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u);
|
|
700
|
+
throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "rust", message: "Rust source contains a lone UTF-16 surrogate.",
|
|
701
|
+
location: { filename, start: indexedPointAt(coordinates, offset), end: indexedPointAt(coordinates, offset + 1) } });
|
|
702
|
+
}
|
|
703
|
+
if (source.length > maximumRustSourceLength)
|
|
704
|
+
return unsupportedSyntax("rust", "source exceeds the frozen Rust parser's 32767 UTF-16 input limit", location);
|
|
705
|
+
let snapshot;
|
|
706
|
+
try {
|
|
707
|
+
snapshot = parseRustCst(source);
|
|
708
|
+
}
|
|
709
|
+
catch (error) {
|
|
710
|
+
throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "rust", location,
|
|
711
|
+
cause: error instanceof Error ? error : undefined, message: "The qualified Rust parser could not produce a complete CST." });
|
|
712
|
+
}
|
|
713
|
+
return new RustReader(filename, source).module(snapshot.root);
|
|
714
|
+
}
|
|
715
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9mcm9udGVuZHMvcnVzdC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLDZCQUE2QixDQUFBO0FBQ3ZELE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLGdDQUFnQyxDQUFBO0FBQ3RFLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDRCQUE0QixDQUFBO0FBQzNELE9BQU8sRUFBQyxXQUFXLEVBQUUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUN0RixPQUFPLEVBQUMscUJBQXFCLEVBQUUsY0FBYyxFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDN0UsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDN0QsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sMkJBQTJCLENBQUE7QUFDMUQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sd0JBQXdCLENBQUE7QUFDNUQsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDNUQsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sY0FBYyxDQUFBO0FBQzdDLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUU3Qyw0REFBNEQ7QUFDNUQsc0VBQXNFO0FBQ3RFLG9FQUFvRTtBQUNwRSx3RUFBd0U7QUFFeEUsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUMvQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxVQUFVLENBQUM7SUFDdkYsQ0FBQyxHQUFH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QyxFQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRO1lBQzlFLEtBQUssRUFBRSxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsNkRBQTZELEVBQUMsQ0FBQyxDQUFBO0lBQy9ILENBQUM7SUFDRCxPQUFPLElBQUksVUFBVSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO0FBQy9ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtydXN0UnVudGltZX0gZnJvbSBcIi4uL2JhY2tlbmRzL3J1c3QtcnVudGltZS5qc1wiXG5pbXBvcnQge21heGltdW1SdXN0U291cmNlTGVuZ3RofSBmcm9tIFwiLi4vYmFja2VuZHMvcnVzdC12YWxpZGF0aW9uLmpzXCJcbmltcG9ydCB7aXNSdXN0SWRlbnRpZmllcn0gZnJvbSBcIi4uL2JhY2tlbmRzL2lkZW50aWZpZXJzLmpzXCJcbmltcG9ydCB7bWlzc2luZ1R5cGUsIFNlbWFudGlmb2xkRGlhZ25vc3RpYywgdW5zdXBwb3J0ZWRTeW50YXh9IGZyb20gXCIuLi9kaWFnbm9zdGljLmpzXCJcbmltcG9ydCB7Y3JlYXRlQ29vcmRpbmF0ZUluZGV4LCBpbmRleGVkUG9pbnRBdH0gZnJvbSBcIi4uL3NlbWFudGljL2xvY2F0aW9uLmpzXCJcbmltcG9ydCB7d2l0aEFkYXB0ZWRPcGVyYXRpb259IGZyb20gXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIlxuaW1wb3J0IHt3aXRoUGFyc2VyUmFuZ2VzfSBmcm9tIFwiLi4vc2VtYW50aWMvcHJvdmVuYW5jZS5qc1wiXG5pbXBvcnQge2hhc09ubHlVbmljb2RlU2NhbGFyc30gZnJvbSBcIi4uL3NlbWFudGljL3NjYWxhcnMuanNcIlxuaW1wb3J0IHt2YWxpZGF0ZVBhcnNlZE1vZHVsZX0gZnJvbSBcIi4uL3NlbWFudGljL3ZhbGlkYXRlLmpzXCJcbmltcG9ydCB7c291cmNlU2NhbGFyVHlwZX0gZnJvbSBcIi4vc2NhbGFycy5qc1wiXG5pbXBvcnQge3BhcnNlUnVzdENzdH0gZnJvbSBcIi4vcnVzdC1wYXJzZXIuanNcIlxuXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4vcnVzdC1wYXJzZXIuanNcIikuQ3N0Tm9kZX0gQ3N0Tm9kZSAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBFeHByZXNzaW9uICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gU3RhdGVtZW50ICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWV9IFNjYWxhciAqL1xuXG5jb25zdCBiaW5hcnlPcGVyYXRpb25zID0gbmV3IE1hcChbXG4gIFtcIitcIiwgXCJBZGRcIl0sIFtcIi1cIiwgXCJTdWJ0cmFjdFwiXSwgW1wiKlwiLCBcIk11bHRpcGx5XCJdLCBbXCI9PVwiLCBcIkVxdWFsXCJdLCBbXCIhPVwiLCBcIk5vdEVxdWFsXCJdLFxuICBbXCI8XCIsIFwiTGVzc1RoYW5cIl0sIFtcIjw9XCIsIFwiTGVzc1RoYW5PckVxdWFsXCJdLCBbXCI+XCIsIFwiR3JlYXRlclRoYW5cIl0sIFtcIj49XCIsIFwiR3JlYXRlclRoYW5PckVxdWFsXCJdLFxuICBbXCImJlwiLCBcIkFuZFwiXSwgW1wifHxcIiwgXCJPclwiXVxuXSlcbmNvbnN0IGFyaXRobWV0aWNIZWxwZXJzID0gbmV3IE1hcChbXG4gIFtcInNlbWFudGlmb2xkX2ludGVnZXJfYWRkXCIsIFwiUGhwQWRkXCJdLCBbXCJzZW1hbnRpZm9sZF9pbnRlZ2VyX3N1YnRyYWN0XCIsIFwiU3VidHJhY3RcIl0sXG4gIFtcInNlbWFudGlmb2xkX2ludGVnZXJfbXVsdGlwbHlcIiwgXCJNdWx0aXBseVwiXVxuXSlcblxuLyoqIENvbnN1bWVzIGNvbXBsZXRlIFJ1c3QgQ1NUIHNoYXBlcyBhbmQgcmV0YWlucyBzb3VyY2Utb25seSBzY2FmZm9sZCBjb25zdHJhaW50cy4gKi9cbmNsYXNzIFJ1c3RSZWFkZXIge1xuICAvKipcbiAgICogT3ducyBzb3VyY2UgdGV4dCBhbmQgcGFyc2VyLW9yaWdpbiBtZXRhZGF0YSwgbmV2ZXIgbmF0aXZlIHBhcnNlciBoYW5kbGVzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBPcmlnaW5hbCBmaWxlbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIEV4YWN0IHNvdXJjZS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgICB0aGlzLmZpbGVuYW1lID0gZmlsZW5hbWVcbiAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZVxuICAgIHRoaXMuY29vcmRpbmF0ZXMgPSBjcmVhdGVDb29yZGluYXRlSW5kZXgoc291cmNlKVxuICAgIC8qKiBAdHlwZSB7U2V0PHN0cmluZz59ICovXG4gICAgdGhpcy5oZWxwZXJzID0gbmV3IFNldCgpXG4gICAgLyoqIEB0eXBlIHtNYXA8RXhwcmVzc2lvbiwgQ3N0Tm9kZT59ICovXG4gICAgdGhpcy5jbG9uZXMgPSBuZXcgTWFwKClcbiAgICAvKiogQHR5cGUge01hcDxFeHByZXNzaW9uLCB7Ym9ycm93ZWQ6IGJvb2xlYW4sIG5vZGU6IENzdE5vZGV9Pn0gKi9cbiAgICB0aGlzLmFkZGl0aW9ucyA9IG5ldyBNYXAoKVxuICAgIC8qKiBAdHlwZSB7TWFwPFN0YXRlbWVudCwge3R5cGU6IHN0cmluZywgbm9kZTogQ3N0Tm9kZX0+fSAqL1xuICAgIHRoaXMucHJpbnRzID0gbmV3IE1hcCgpXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBTY2FsYXI+fSAqL1xuICAgIHRoaXMuZnVuY3Rpb25zID0gbmV3IE1hcCgpXG4gIH1cblxuICAvKipcbiAgICogTG9jYXRlcyBhbiBvcmlnaW5hbCBwYXJzZXIgbm9kZSBpbiBVVEYtMTYgY29vcmRpbmF0ZXMuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIE9yaWdpbmFsIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gRXhhY3QgbG9jYXRpb24uXG4gICAqL1xuICBsb2NhdGlvbihub2RlKSB7XG4gICAgcmV0dXJuIHtmaWxlbmFtZTogdGhpcy5maWxlbmFtZSwgc3RhcnQ6IGluZGV4ZWRQb2ludEF0KHRoaXMuY29vcmRpbmF0ZXMsIG5vZGUuc3RhcnRJbmRleCksIGVuZDogaW5kZXhlZFBvaW50QXQodGhpcy5jb29yZGluYXRlcywgbm9kZS5lbmRJbmRleCl9XG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgdGhlIHNwZWxsaW5nIG9mIGFuIGFscmVhZHkgcmVjb2duaXplZCBwYXJzZXIgbm9kZS5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gUmVjb2duaXplZCBub2RlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBPcmlnaW5hbCBzcGVsbGluZy5cbiAgICovXG4gIHRleHQobm9kZSkge1xuICAgIHJldHVybiB0aGlzLnNvdXJjZS5zbGljZShub2RlLnN0YXJ0SW5kZXgsIG5vZGUuZW5kSW5kZXgpXG4gIH1cblxuICAvKipcbiAgICogUmVqZWN0cyBvbmUgbG9jYXRlZCBzb3VyY2UtcHJvZmlsZSB2aW9sYXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFZpb2xhdGluZyBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2RldGFpbF0gLSBQcm9maWxlIGRldGFpbC5cbiAgICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICAgKi9cbiAgZmFpbChub2RlLCBkZXRhaWwgPSBub2RlLnR5cGUpIHtcbiAgICB1bnN1cHBvcnRlZFN5bnRheChcInJ1c3RcIiwgZGV0YWlsLCB0aGlzLmxvY2F0aW9uKG5vZGUpKVxuICB9XG5cbiAgLyoqXG4gICAqIEFjY291bnRzIGZvciByZWNvdmVyeSwgZXZlcnkgZXh0cmEsIGFuZCBkb2MgY29tbWVudHMgYmVmb3JlIGludGVycHJldGluZyBtZWFuaW5nLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDdXJyZW50IG5vZGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbZGVwdGhdIC0gQm91bmRlZCB0cmF2ZXJzYWwgZGVwdGguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgdmFsaWRhdGVUcmVlKG5vZGUsIGRlcHRoID0gMCkge1xuICAgIGlmIChkZXB0aCA+IDUxMikgdGhpcy5mYWlsKG5vZGUsIFwiUnVzdCBDU1QgZXhjZWVkcyB0aGUgNTEyLWxldmVsIHRyYXZlcnNhbCBsaW1pdFwiKVxuICAgIGZvciAoY29uc3Qge25vZGU6IGNoaWxkfSBvZiBub2RlLmNoaWxkcmVuKSB0aGlzLnZhbGlkYXRlVHJlZShjaGlsZCwgZGVwdGggKyAxKVxuICAgIGlmIChub2RlLmVycm9yIHx8IG5vZGUubWlzc2luZyB8fCBub2RlLmhhc0Vycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlBBUlNFX0VSUk9SXCIsIGxhbmd1YWdlOiBcInJ1c3RcIiwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksIG1lc3NhZ2U6IGBSdXN0IHBhcnNlciByZWNvdmVyeSBhdCAnJHtub2RlLnR5cGV9Jy5gfSlcbiAgICB9XG4gICAgaWYgKG5vZGUuZXh0cmEgJiYgIVtcImxpbmVfY29tbWVudFwiLCBcImJsb2NrX2NvbW1lbnRcIl0uaW5jbHVkZXMobm9kZS50eXBlKSkgdGhpcy5mYWlsKG5vZGUsIFwidW5leHBlY3RlZCBleHRyYSBwYXJzZXIgY2hpbGRcIilcbiAgICBpZiAoW1wibGluZV9jb21tZW50XCIsIFwiYmxvY2tfY29tbWVudFwiXS5pbmNsdWRlcyhub2RlLnR5cGUpICYmIC9eKD86XFwvXFwvWyEvXXxcXC9cXCpbKiFdKS91LnRlc3QodGhpcy50ZXh0KG5vZGUpKSkge1xuICAgICAgdGhpcy5mYWlsKG5vZGUsIFwiZG9jLWNvbW1lbnQgYXR0cmlidXRlXCIpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE9taXRzIG9ubHkgaW5lcnQgY29tbWVudHMgYWxyZWFkeSBjaGVja2VkIGR1cmluZyBleGhhdXN0aXZlIHRyYXZlcnNhbC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gUGFyZW50LlxuICAgKiBAcmV0dXJucyB7Q3N0Tm9kZVtdfSBPcmRlcmVkIHN0cnVjdHVyYWwgY2hpbGRyZW4uXG4gICAqL1xuICBwYXJ0cyhub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUuY2hpbGRyZW4ubWFwKCh7bm9kZTogY2hpbGR9KSA9PiBjaGlsZCkuZmlsdGVyKGNoaWxkID0+ICFbXCJsaW5lX2NvbW1lbnRcIiwgXCJibG9ja19jb21tZW50XCJdLmluY2x1ZGVzKGNoaWxkLnR5cGUpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcXVpcmVzIGFuIGV4YWN0IHNvbGUgcGFyc2VyIGZpZWxkLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBGaWVsZCBvd25lci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBGaWVsZCBuYW1lLlxuICAgKiBAcmV0dXJucyB7Q3N0Tm9kZX0gU29sZSBmaWVsZCB2YWx1ZS5cbiAgICovXG4gIGZpZWxkKG5vZGUsIG5hbWUpIHtcbiAgICBjb25zdCBlZGdlcyA9IG5vZGUuY2hpbGRyZW4uZmlsdGVyKCh7ZmllbGR9KSA9PiBmaWVsZCA9PSBuYW1lKVxuXG4gICAgaWYgKGVkZ2VzLmxlbmd0aCAhPSAxKSB0aGlzLmZhaWwobm9kZSwgYGV4cGVjdGVkIG9uZSAnJHtuYW1lfScgZmllbGRgKVxuICAgIHJldHVybiBlZGdlc1swXS5ub2RlXG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZXMgYWxsIG9yZGVyZWQgY2hpbGRyZW4sIGluY2x1ZGluZyBhbm9ueW1vdXMgcHVuY3R1YXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFNoYXBlIG93bmVyLlxuICAgKiBAcGFyYW0geyhDc3ROb2RlIHwgc3RyaW5nKVtdfSBleHBlY3RlZCAtIEV4YWN0IGNoaWxkIHNlcXVlbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHNoYXBlKG5vZGUsIGV4cGVjdGVkKSB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICBpZiAocGFydHMubGVuZ3RoICE9IGV4cGVjdGVkLmxlbmd0aCB8fCBwYXJ0cy5zb21lKChjaGlsZCwgaW5kZXgpID0+XG4gICAgICB0eXBlb2YgZXhwZWN0ZWRbaW5kZXhdID09IFwic3RyaW5nXCIgPyBjaGlsZC50eXBlICE9IGV4cGVjdGVkW2luZGV4XSB8fCAhY2hpbGQubmFtZWQgJiYgdGhpcy50ZXh0KGNoaWxkKSAhPSBleHBlY3RlZFtpbmRleF0gOiBjaGlsZCAhPT0gZXhwZWN0ZWRbaW5kZXhdKSkgdGhpcy5mYWlsKG5vZGUsIGAke25vZGUudHlwZX0gY2hpbGQgc2hhcGVgKVxuICB9XG5cbiAgLyoqXG4gICAqIFByb3RlY3RzIFJ1c3Qga2V5d29yZHMgYW5kIHRoZSBwcml2YXRlIHN1cHBvcnQgbmFtZXNwYWNlLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBJZGVudGlmaWVyIHRva2VuLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBWYWxpZGF0ZWQgbmFtZS5cbiAgICovXG4gIGlkZW50aWZpZXIobm9kZSkge1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHQobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgIWlzUnVzdElkZW50aWZpZXIobmFtZSkpIHRoaXMuZmFpbChub2RlLCBcInJlc2VydmVkIG9yIHVuc3VwcG9ydGVkIGlkZW50aWZpZXJcIilcbiAgICByZXR1cm4gbmFtZVxuICB9XG5cbiAgLyoqXG4gICAqIEFjY2VwdHMgb25seSBleHBsaWNpdGx5IHNwZWxsZWQgaTY0LCBib29sIGFuZCBvd25lZCBTdHJpbmcuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFR5cGUgdG9rZW4uXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSBTZW1hbnRpYyBzY2FsYXIgdHlwZS5cbiAgICovXG4gIHR5cGUobm9kZSkge1xuICAgIGlmIChub2RlLmNoaWxkcmVuLmxlbmd0aCB8fCAhW1wicHJpbWl0aXZlX3R5cGVcIiwgXCJ0eXBlX2lkZW50aWZpZXJcIl0uaW5jbHVkZXMobm9kZS50eXBlKSkgdGhpcy5mYWlsKG5vZGUsIFwic2NhbGFyIHR5cGUgc2hhcGVcIilcbiAgICBjb25zdCBzcGVsbGluZyA9IHRoaXMudGV4dChub2RlKVxuICAgIGNvbnN0IHR5cGUgPSBzb3VyY2VTY2FsYXJUeXBlKFwicnVzdFwiLCBzcGVsbGluZywgdGhpcy5sb2NhdGlvbihub2RlKSlcblxuICAgIGlmICghdHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicnVzdFwiLCBcInNjYWxhclwiLCB0aGlzLmxvY2F0aW9uKG5vZGUpKVxuICAgIGlmICgoc3BlbGxpbmcgPT0gXCJTdHJpbmdcIikgIT0gKG5vZGUudHlwZSA9PSBcInR5cGVfaWRlbnRpZmllclwiKSkgdGhpcy5mYWlsKG5vZGUsIFwic2NhbGFyIHR5cGUgc3BlbGxpbmdcIilcbiAgICByZXR1cm4gdHlwZVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGV4YWN0IGNhbGwgc3ludGF4IHdpdGhvdXQgaW50ZXJwcmV0aW5nIG1hY3JvIHRva2VuIHRyZWVzIGFzIGNhbGxzLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDYWxsIGV4cHJlc3Npb24uXG4gICAqIEByZXR1cm5zIHt7bmFtZTogQ3N0Tm9kZSwgYXJndW1lbnRzOiBDc3ROb2RlW119fSBQYXJzZWQgZGlyZWN0IGFyZ3VtZW50IHNlcXVlbmNlLlxuICAgKi9cbiAgY2FsbChub2RlKSB7XG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImNhbGxfZXhwcmVzc2lvblwiKSB0aGlzLmZhaWwobm9kZSwgXCJkaXJlY3QgY2FsbCByZXF1aXJlZFwiKVxuICAgIGNvbnN0IG5hbWUgPSB0aGlzLmZpZWxkKG5vZGUsIFwiZnVuY3Rpb25cIilcbiAgICBjb25zdCBsaXN0ID0gdGhpcy5maWVsZChub2RlLCBcImFyZ3VtZW50c1wiKVxuXG4gICAgdGhpcy5zaGFwZShub2RlLCBbbmFtZSwgbGlzdF0pXG4gICAgaWYgKGxpc3QudHlwZSAhPSBcImFyZ3VtZW50c1wiKSB0aGlzLmZhaWwobGlzdCwgXCJjYWxsIGFyZ3VtZW50c1wiKVxuICAgIGNvbnN0IGFyZ3MgPSB0aGlzLnBhcnRzKGxpc3QpLnNsaWNlKDEsIC0xKS5maWx0ZXIoKF9wYXJ0LCBpbmRleCkgPT4gaW5kZXggJSAyID09IDApXG5cbiAgICB0aGlzLnNoYXBlKGxpc3QsIFtcIihcIiwgLi4uYXJncy5mbGF0TWFwKChhcmcsIGluZGV4KSA9PiBpbmRleCA9PSAwID8gW2FyZ10gOiBbXCIsXCIsIGFyZ10pLCBcIilcIl0pXG4gICAgcmV0dXJuIHthcmd1bWVudHM6IGFyZ3MsIG5hbWV9XG4gIH1cblxuICAvKipcbiAgICogRGVjb2RlcyBwYXJzZXItb3duZWQgb3JkaW5hcnkgc3RyaW5nIGNvbnRlbnQgYW5kIGV4YWN0IHNjYWxhciBlc2NhcGVzLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBTdHJpbmcgbGl0ZXJhbC5cbiAgICogQHJldHVybnMge3N0cmluZ30gVW5pY29kZSBzY2FsYXIgdmFsdWUuXG4gICAqL1xuICBzdHJpbmcobm9kZSkge1xuICAgIGlmIChub2RlLnR5cGUgIT0gXCJzdHJpbmdfbGl0ZXJhbFwiKSB0aGlzLmZhaWwobm9kZSwgXCJvcmRpbmFyeSBTdHJpbmcgbGl0ZXJhbCByZXF1aXJlZFwiKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgdGhpcy5zaGFwZShub2RlLCBbJ1wiJywgLi4ucGFydHMuc2xpY2UoMSwgLTEpLCAnXCInXSlcbiAgICBsZXQgdmFsdWUgPSBcIlwiXG5cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMuc2xpY2UoMSwgLTEpKSB7XG4gICAgICBjb25zdCBzcGVsbGluZyA9IHRoaXMudGV4dChwYXJ0KVxuXG4gICAgICBpZiAocGFydC50eXBlID09IFwic3RyaW5nX2NvbnRlbnRcIikge1xuICAgICAgICBpZiAoL1tcXHJcXG5dL3UudGVzdChzcGVsbGluZykpIHRoaXMuZmFpbChwYXJ0LCBcInJhdyBzdHJpbmcgbGluZSB0ZXJtaW5hdG9yXCIpXG4gICAgICAgIHZhbHVlICs9IHNwZWxsaW5nXG4gICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PSBcImVzY2FwZV9zZXF1ZW5jZVwiKSB7XG4gICAgICAgIGNvbnN0IGVzY2FwZSA9IHNwZWxsaW5nLnNsaWNlKDEpXG4gICAgICAgIGNvbnN0IHNpbXBsZSA9IG5ldyBNYXAoW1tcIjBcIiwgXCJcXDBcIl0sIFtcIm5cIiwgXCJcXG5cIl0sIFtcInJcIiwgXCJcXHJcIl0sIFtcInRcIiwgXCJcXHRcIl0sIFtcIlxcXFxcIiwgXCJcXFxcXCJdLCBbJ1wiJywgJ1wiJ10sIFtcIidcIiwgXCInXCJdXSlcblxuICAgICAgICBpZiAoc3BlbGxpbmdbMF0gIT0gXCJcXFxcXCIpIHRoaXMuZmFpbChwYXJ0LCBcImVzY2FwZSBwcmVmaXhcIilcbiAgICAgICAgaWYgKHNpbXBsZS5oYXMoZXNjYXBlKSkgdmFsdWUgKz0gc2ltcGxlLmdldChlc2NhcGUpXG4gICAgICAgIGVsc2UgaWYgKC9eeFswLTlhLWZBLUZdezJ9JC91LnRlc3QoZXNjYXBlKSkge1xuICAgICAgICAgIGNvbnN0IHNjYWxhciA9IE51bWJlci5wYXJzZUludChlc2NhcGUuc2xpY2UoMSksIDE2KVxuXG4gICAgICAgICAgaWYgKHNjYWxhciA+IDEyNykgdGhpcy5mYWlsKHBhcnQsIFwibm9uLUFTQ0lJIGJ5dGUgZXNjYXBlXCIpXG4gICAgICAgICAgdmFsdWUgKz0gU3RyaW5nLmZyb21Db2RlUG9pbnQoc2NhbGFyKVxuICAgICAgICB9IGVsc2UgaWYgKC9edVxce1swLTlhLWZBLUZdezEsNn1cXH0kL3UudGVzdChlc2NhcGUpKSB7XG4gICAgICAgICAgY29uc3Qgc2NhbGFyID0gTnVtYmVyLnBhcnNlSW50KGVzY2FwZS5zbGljZSgyLCAtMSksIDE2KVxuXG4gICAgICAgICAgaWYgKHNjYWxhciA+IDB4MTBGRkZGIHx8IHNjYWxhciA+PSAweEQ4MDAgJiYgc2NhbGFyIDw9IDB4REZGRikgdGhpcy5mYWlsKHBhcnQsIFwibm9uLXNjYWxhciBVbmljb2RlIGVzY2FwZVwiKVxuICAgICAgICAgIHZhbHVlICs9IFN0cmluZy5mcm9tQ29kZVBvaW50KHNjYWxhcilcbiAgICAgICAgfSBlbHNlIHRoaXMuZmFpbChwYXJ0LCBcInVuc3VwcG9ydGVkIHN0cmluZyBlc2NhcGVcIilcbiAgICAgIH0gZWxzZSB0aGlzLmZhaWwocGFydCwgXCJzdHJpbmcgY2hpbGRcIilcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgZXhhY3Qgc2NhbGFyIGV4cHJlc3Npb25zIHdoaWxlIHJldGFpbmluZyBzb3VyY2UgY2xvbmUvYm9ycm93IGNvbnN0cmFpbnRzLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBFeHByZXNzaW9uIG5vZGUuXG4gICAqIEByZXR1cm5zIHtFeHByZXNzaW9ufSBQZW5kaW5nIHR5cGVkIHNlbWFudGljIGV4cHJlc3Npb24uXG4gICAqL1xuICBleHByZXNzaW9uKG5vZGUpIHtcbiAgICBjb25zdCBsb2NhdGlvbiA9IHRoaXMubG9jYXRpb24obm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJwYXJlbnRoZXNpemVkX2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiKFwiLCBwYXJ0c1sxXSwgXCIpXCJdKVxuICAgICAgcmV0dXJuIHRoaXMuZXhwcmVzc2lvbihwYXJ0c1sxXSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImlkZW50aWZpZXJcIikgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiwgbG9jYXRpb24sIG5hbWU6IHRoaXMuaWRlbnRpZmllcihub2RlKX0sIHtuYW1lOiBsb2NhdGlvbn0pXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImludGVnZXJfbGl0ZXJhbFwiKSB7XG4gICAgICBjb25zdCBzcGVsbGluZyA9IHRoaXMudGV4dChub2RlKVxuICAgICAgY29uc3QgdmFsdWUgPSBOdW1iZXIoc3BlbGxpbmcuc2xpY2UoMCwgLTMpKVxuXG4gICAgICBpZiAoIS9eKD86MHxbMS05XVswLTldKilpNjQkL3UudGVzdChzcGVsbGluZykgfHwgIU51bWJlci5pc1NhZmVJbnRlZ2VyKHZhbHVlKSkgdGhpcy5mYWlsKG5vZGUsIFwibm9uLXNhZmUgb3Igbm9uY2Fub25pY2FsIGk2NCBsaXRlcmFsXCIpXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJJbnRlZ2VyTGl0ZXJhbFwiLCBsb2NhdGlvbiwgdmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiYm9vbGVhbl9saXRlcmFsXCIpIHtcbiAgICAgIGNvbnN0IHNwZWxsaW5nID0gdGhpcy50ZXh0KG5vZGUpXG5cbiAgICAgIGlmIChzcGVsbGluZyAhPSBcInRydWVcIiAmJiBzcGVsbGluZyAhPSBcImZhbHNlXCIpIHRoaXMuZmFpbChub2RlLCBcIkJvb2xlYW4gbGl0ZXJhbCBzcGVsbGluZ1wiKVxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbc3BlbGxpbmddKVxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiQm9vbGVhbkxpdGVyYWxcIiwgbG9jYXRpb24sIHZhbHVlOiBzcGVsbGluZyA9PSBcInRydWVcIn0sIHtsaXRlcmFsOiBsb2NhdGlvbn0pXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJ1bmFyeV9leHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtwYXJ0c1swXSwgcGFydHNbMV1dKVxuICAgICAgaWYgKCFbXCItXCIsIFwiIVwiXS5pbmNsdWRlcyhwYXJ0c1swXS50eXBlKSkgdGhpcy5mYWlsKHBhcnRzWzBdLCBcInVuYXJ5IG9wZXJhdG9yXCIpXG4gICAgICByZXR1cm4gdGhpcy51bmFyeShub2RlLCBwYXJ0c1swXS50eXBlID09IFwiLVwiID8gXCJOZWdhdGVcIiA6IFwiTm90XCIsIHRoaXMuZXhwcmVzc2lvbihwYXJ0c1sxXSksIHBhcnRzWzBdKVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiYmluYXJ5X2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgbGVmdCA9IHRoaXMuZmllbGQobm9kZSwgXCJsZWZ0XCIpXG4gICAgICBjb25zdCByaWdodCA9IHRoaXMuZmllbGQobm9kZSwgXCJyaWdodFwiKVxuICAgICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLmZpZWxkKG5vZGUsIFwib3BlcmF0b3JcIilcbiAgICAgIGNvbnN0IGludGVudCA9IGJpbmFyeU9wZXJhdGlvbnMuZ2V0KG9wZXJhdG9yLnR5cGUpXG5cbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW2xlZnQsIG9wZXJhdG9yLCByaWdodF0pXG4gICAgICBpZiAoIWludGVudCkgdGhpcy5mYWlsKG9wZXJhdG9yLCBcInVuc3VwcG9ydGVkIGJpbmFyeSBvcGVyYXRvclwiKVxuICAgICAgY29uc3QgYm9ycm93ZWQgPSBvcGVyYXRvci50eXBlID09IFwiK1wiICYmIHJpZ2h0LnR5cGUgPT0gXCJyZWZlcmVuY2VfZXhwcmVzc2lvblwiXG4gICAgICBjb25zdCB2YWx1ZSA9IGJvcnJvd2VkID8gdGhpcy5maWVsZChyaWdodCwgXCJ2YWx1ZVwiKSA6IHJpZ2h0XG5cbiAgICAgIGlmIChib3Jyb3dlZCkgdGhpcy5zaGFwZShyaWdodCwgW1wiJlwiLCB2YWx1ZV0pXG4gICAgICBjb25zdCBleHByZXNzaW9uID0gdGhpcy5iaW5hcnkobm9kZSwgaW50ZW50LCB0aGlzLmV4cHJlc3Npb24obGVmdCksIHRoaXMuZXhwcmVzc2lvbih2YWx1ZSksIG9wZXJhdG9yKVxuXG4gICAgICBpZiAob3BlcmF0b3IudHlwZSA9PSBcIitcIikgdGhpcy5hZGRpdGlvbnMuc2V0KGV4cHJlc3Npb24sIHtib3Jyb3dlZCwgbm9kZTogcmlnaHR9KVxuICAgICAgcmV0dXJuIGV4cHJlc3Npb25cbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImNhbGxfZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBjYWxsID0gdGhpcy5jYWxsKG5vZGUpXG4gICAgICBjb25zdCBuYW1lID0gdGhpcy50ZXh0KGNhbGwubmFtZSlcblxuICAgICAgaWYgKGNhbGwubmFtZS50eXBlID09IFwic2NvcGVkX2lkZW50aWZpZXJcIikge1xuICAgICAgICBjb25zdCBvd25lciA9IHRoaXMuZmllbGQoY2FsbC5uYW1lLCBcInBhdGhcIilcbiAgICAgICAgY29uc3QgbWV0aG9kID0gdGhpcy5maWVsZChjYWxsLm5hbWUsIFwibmFtZVwiKVxuXG4gICAgICAgIHRoaXMuc2hhcGUoY2FsbC5uYW1lLCBbb3duZXIsIFwiOjpcIiwgbWV0aG9kXSlcbiAgICAgICAgaWYgKG93bmVyLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgdGhpcy50ZXh0KG93bmVyKSAhPSBcIlN0cmluZ1wiIHx8IG1ldGhvZC50eXBlICE9IFwiaWRlbnRpZmllclwiIHx8IHRoaXMudGV4dChtZXRob2QpICE9IFwiZnJvbVwiIHx8IGNhbGwuYXJndW1lbnRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgdGhpcy5mYWlsKGNhbGwubmFtZSwgXCJleGFjdCBTdHJpbmc6OmZyb20gY29uc3RydWN0aW9uIHJlcXVpcmVkXCIpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiU3RyaW5nTGl0ZXJhbFwiLCBsb2NhdGlvbiwgdmFsdWU6IHRoaXMuc3RyaW5nKGNhbGwuYXJndW1lbnRzWzBdKX0sIHtsaXRlcmFsOiB0aGlzLmxvY2F0aW9uKGNhbGwuYXJndW1lbnRzWzBdKX0pXG4gICAgICB9XG4gICAgICBpZiAoY2FsbC5uYW1lLnR5cGUgPT0gXCJmaWVsZF9leHByZXNzaW9uXCIpIHtcbiAgICAgICAgY29uc3QgcmVjZWl2ZXIgPSB0aGlzLmZpZWxkKGNhbGwubmFtZSwgXCJ2YWx1ZVwiKVxuICAgICAgICBjb25zdCBtZXRob2QgPSB0aGlzLmZpZWxkKGNhbGwubmFtZSwgXCJmaWVsZFwiKVxuXG4gICAgICAgIHRoaXMuc2hhcGUoY2FsbC5uYW1lLCBbcmVjZWl2ZXIsIFwiLlwiLCBtZXRob2RdKVxuICAgICAgICBpZiAobWV0aG9kLnR5cGUgIT0gXCJmaWVsZF9pZGVudGlmaWVyXCIgfHwgdGhpcy50ZXh0KG1ldGhvZCkgIT0gXCJjbG9uZVwiIHx8IGNhbGwuYXJndW1lbnRzLmxlbmd0aCkgdGhpcy5mYWlsKGNhbGwubmFtZSwgXCJleGFjdCBvd25lZCBTdHJpbmcgY2xvbmUgcmVxdWlyZWRcIilcbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IHRoaXMuZXhwcmVzc2lvbihyZWNlaXZlcilcblxuICAgICAgICB0aGlzLmNsb25lcy5zZXQoZXhwcmVzc2lvbiwgY2FsbC5uYW1lKVxuICAgICAgICByZXR1cm4gZXhwcmVzc2lvblxuICAgICAgfVxuICAgICAgaWYgKGNhbGwubmFtZS50eXBlICE9IFwiaWRlbnRpZmllclwiKSB0aGlzLmZhaWwoY2FsbC5uYW1lLCBcImRpcmVjdCBmdW5jdGlvbiBjYWxsIHJlcXVpcmVkXCIpXG4gICAgICBpZiAodGhpcy5oZWxwZXJzLmhhcyhuYW1lKSAmJiBuYW1lID09IFwic2VtYW50aWZvbGRfaW50ZWdlcl9uZWdhdGVcIikge1xuICAgICAgICBpZiAoY2FsbC5hcmd1bWVudHMubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChub2RlLCBcIm5lZ2F0aW9uIGhlbHBlciBhcml0eVwiKVxuICAgICAgICByZXR1cm4gdGhpcy51bmFyeShub2RlLCBcIk5lZ2F0ZVwiLCB0aGlzLmV4cHJlc3Npb24oY2FsbC5hcmd1bWVudHNbMF0pLCBjYWxsLm5hbWUpXG4gICAgICB9XG4gICAgICBjb25zdCBpbnRlbnQgPSB0aGlzLmhlbHBlcnMuaGFzKG5hbWUpID8gYXJpdGhtZXRpY0hlbHBlcnMuZ2V0KG5hbWUpIDogdW5kZWZpbmVkXG5cbiAgICAgIGlmIChpbnRlbnQpIHtcbiAgICAgICAgaWYgKGNhbGwuYXJndW1lbnRzLmxlbmd0aCAhPSAyKSB0aGlzLmZhaWwobm9kZSwgXCJhcml0aG1ldGljIGhlbHBlciBhcml0eVwiKVxuICAgICAgICByZXR1cm4gdGhpcy5iaW5hcnkobm9kZSwgaW50ZW50LCB0aGlzLmV4cHJlc3Npb24oY2FsbC5hcmd1bWVudHNbMF0pLCB0aGlzLmV4cHJlc3Npb24oY2FsbC5hcmd1bWVudHNbMV0pLCBjYWxsLm5hbWUpXG4gICAgICB9XG4gICAgICBjb25zdCBjYWxsZWUgPSB0aGlzLmlkZW50aWZpZXIoY2FsbC5uYW1lKVxuXG4gICAgICBpZiAoY2FsbC5hcmd1bWVudHMubGVuZ3RoICE9IDIpIHRoaXMuZmFpbChub2RlLCBcInNlbWFudGljIGNhbGwgYXJpdHlcIilcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiBcIkNhbGxFeHByZXNzaW9uXCIsIGxvY2F0aW9uLCBjYWxsZWUsIGFyZ3VtZW50czogY2FsbC5hcmd1bWVudHMubWFwKGFyZ3VtZW50ID0+IHRoaXMuZXhwcmVzc2lvbihhcmd1bWVudCkpfSwge2NhbGxlZTogdGhpcy5sb2NhdGlvbihjYWxsLm5hbWUpfSlcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZmFpbChub2RlKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldGFpbnMgcGFyc2VyIG9wZXJhdG9yIGludGVudCB1bnRpbCBzaGFyZWQgc2NhbGFyIHJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIE93bmluZyBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaW50ZW50IC0gUGFyc2VyIG9wZXJhdGlvbi5cbiAgICogQHBhcmFtIHtFeHByZXNzaW9ufSBsZWZ0IC0gTGVmdCBvcGVyYW5kLlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IHJpZ2h0IC0gUmlnaHQgb3BlcmFuZC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBvcGVyYXRvciAtIEV4YWN0IG9wZXJhdG9yIHRva2VuLlxuICAgKiBAcmV0dXJucyB7RXhwcmVzc2lvbn0gUGVuZGluZyBiaW5hcnkgZXhwcmVzc2lvbi5cbiAgICovXG4gIGJpbmFyeShub2RlLCBpbnRlbnQsIGxlZnQsIHJpZ2h0LCBvcGVyYXRvcikge1xuICAgIHJldHVybiAvKiogQHR5cGUge0V4cHJlc3Npb259ICovICh3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiBcIkJpbmFyeUV4cHJlc3Npb25cIiwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksIGxlZnQsIHJpZ2h0fSxcbiAgICAgIHtvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihvcGVyYXRvcil9KSwgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIikuQWRhcHRlZE9wZXJhdGlvbn0gKi8gKGludGVudCkpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldGFpbnMgdW5hcnkgcGFyc2VyIGludGVudCBhbmQgaXRzIG9yaWdpbmFsIHRva2VuIHJhbmdlLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBPd25pbmcgbm9kZS5cbiAgICogQHBhcmFtIHtcIk5lZ2F0ZVwiIHwgXCJOb3RcIn0gaW50ZW50IC0gVW5hcnkgaW50ZW50LlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IG9wZXJhbmQgLSBPcGVyYW5kLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG9wZXJhdG9yIC0gRXhhY3QgdG9rZW4uXG4gICAqIEByZXR1cm5zIHtFeHByZXNzaW9ufSBQZW5kaW5nIHVuYXJ5IGV4cHJlc3Npb24uXG4gICAqL1xuICB1bmFyeShub2RlLCBpbnRlbnQsIG9wZXJhbmQsIG9wZXJhdG9yKSB7XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7RXhwcmVzc2lvbn0gKi8gKHdpdGhBZGFwdGVkT3BlcmF0aW9uKHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiVW5hcnlFeHByZXNzaW9uXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBvcGVyYW5kfSxcbiAgICAgIHtvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihvcGVyYXRvcil9KSwgaW50ZW50KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgZXhwbGljaXRseSB0eXBlZCBpbml0aWFsaXplZCBiaW5kaW5nIG9yIGV4ZWN1dGFibGUgc3RhdGVtZW50LlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBTdGF0ZW1lbnQuXG4gICAqIEByZXR1cm5zIHtTdGF0ZW1lbnR9IFNlbWFudGljIHN0YXRlbWVudC5cbiAgICovXG4gIHN0YXRlbWVudChub2RlKSB7XG4gICAgY29uc3QgbG9jYXRpb24gPSB0aGlzLmxvY2F0aW9uKG5vZGUpXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICBpZiAobm9kZS50eXBlID09IFwibGV0X2RlY2xhcmF0aW9uXCIpIHtcbiAgICAgIGNvbnN0IHR5cGVOb2RlID0gbm9kZS5jaGlsZHJlbi5maW5kKCh7ZmllbGR9KSA9PiBmaWVsZCA9PSBcInR5cGVcIik/Lm5vZGVcblxuICAgICAgaWYgKCF0eXBlTm9kZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicnVzdFwiLCBcImxvY2FsXCIsIGxvY2F0aW9uKVxuICAgICAgY29uc3QgbmFtZSA9IHRoaXMuZmllbGQobm9kZSwgXCJwYXR0ZXJuXCIpXG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZmllbGQobm9kZSwgXCJ2YWx1ZVwiKVxuICAgICAgY29uc3QgbXV0YWJsZSA9IHBhcnRzWzFdLnR5cGUgPT0gXCJtdXRhYmxlX3NwZWNpZmllclwiXG5cbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW1wibGV0XCIsIC4uLihtdXRhYmxlID8gW3BhcnRzWzFdXSA6IFtdKSwgbmFtZSwgXCI6XCIsIHR5cGVOb2RlLCBcIj1cIiwgdmFsdWUsIFwiO1wiXSlcbiAgICAgIGlmIChtdXRhYmxlICYmIHRoaXMudGV4dChwYXJ0c1sxXSkgIT0gXCJtdXRcIikgdGhpcy5mYWlsKHBhcnRzWzFdLCBcIm11dGFiaWxpdHkgdG9rZW5cIilcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiBcIkxvY2FsRGVjbGFyYXRpb25cIiwgbG9jYXRpb24sIG5hbWU6IHRoaXMuaWRlbnRpZmllcihuYW1lKSwgdHlwZTogdGhpcy50eXBlKHR5cGVOb2RlKSwgbXV0YWJsZSxcbiAgICAgICAgaW5pdGlhbGl6ZXI6IHRoaXMuZXhwcmVzc2lvbih2YWx1ZSl9LCB7bmFtZTogdGhpcy5sb2NhdGlvbihuYW1lKSwgb3BlcmF0b3I6IHRoaXMubG9jYXRpb24ocGFydHNbcGFydHMubGVuZ3RoIC0gM10pfSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImV4cHJlc3Npb25fc3RhdGVtZW50XCIpIHRoaXMuZmFpbChub2RlLCBcImV4cGxpY2l0IHN0YXRlbWVudCByZXF1aXJlZDsgdGFpbCBleHByZXNzaW9ucyBhcmUgdW5zdXBwb3J0ZWRcIilcbiAgICBjb25zdCBleHByZXNzaW9uID0gcGFydHNbMF1cblxuICAgIGlmIChleHByZXNzaW9uLnR5cGUgPT0gXCJpZl9leHByZXNzaW9uXCIpIHtcbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW2V4cHJlc3Npb25dKVxuICAgICAgcmV0dXJuIHRoaXMuY29uZGl0aW9uYWwoZXhwcmVzc2lvbilcbiAgICB9XG4gICAgdGhpcy5zaGFwZShub2RlLCBbZXhwcmVzc2lvbiwgXCI7XCJdKVxuICAgIGlmIChleHByZXNzaW9uLnR5cGUgPT0gXCJyZXR1cm5fZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCByZXR1cm5lZCA9IHRoaXMucGFydHMoZXhwcmVzc2lvbilcblxuICAgICAgdGhpcy5zaGFwZShleHByZXNzaW9uLCBbXCJyZXR1cm5cIiwgcmV0dXJuZWRbMV1dKVxuICAgICAgcmV0dXJuIHtraW5kOiBcIlJldHVyblN0YXRlbWVudFwiLCBsb2NhdGlvbiwgZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9uKHJldHVybmVkWzFdKX1cbiAgICB9XG4gICAgaWYgKGV4cHJlc3Npb24udHlwZSA9PSBcImFzc2lnbm1lbnRfZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBsZWZ0ID0gdGhpcy5maWVsZChleHByZXNzaW9uLCBcImxlZnRcIilcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5maWVsZChleHByZXNzaW9uLCBcInJpZ2h0XCIpXG5cbiAgICAgIHRoaXMuc2hhcGUoZXhwcmVzc2lvbiwgW2xlZnQsIFwiPVwiLCByaWdodF0pXG4gICAgICBjb25zdCB0YXJnZXQgPSB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obGVmdCksIG5hbWU6IHRoaXMuaWRlbnRpZmllcihsZWZ0KX0sIHtuYW1lOiB0aGlzLmxvY2F0aW9uKGxlZnQpfSlcblxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiQXNzaWdubWVudFN0YXRlbWVudFwiLCBsb2NhdGlvbiwgdGFyZ2V0LCBleHByZXNzaW9uOiB0aGlzLmV4cHJlc3Npb24ocmlnaHQpfSwge29wZXJhdG9yOiB0aGlzLmxvY2F0aW9uKHRoaXMucGFydHMoZXhwcmVzc2lvbilbMV0pfSlcbiAgICB9XG4gICAgY29uc3QgY2FsbCA9IHRoaXMuY2FsbChleHByZXNzaW9uKVxuICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHQoY2FsbC5uYW1lKVxuXG4gICAgaWYgKGNhbGwubmFtZS50eXBlICE9IFwiaWRlbnRpZmllclwiIHx8ICF0aGlzLmhlbHBlcnMuaGFzKG5hbWUpIHx8ICEvXnNlbWFudGlmb2xkX3ByaW50Xyg/OmludGVnZXJ8Ym9vbGVhbnxzdHJpbmcpJC91LnRlc3QobmFtZSkgfHwgY2FsbC5hcmd1bWVudHMubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChub2RlLCBcImV4YWN0IHByaW50IGhlbHBlciBjYWxsIHJlcXVpcmVkXCIpXG4gICAgY29uc3Qgc3RhdGVtZW50ID0ge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlByaW50U3RhdGVtZW50XCIpLCBsb2NhdGlvbiwgZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9uKGNhbGwuYXJndW1lbnRzWzBdKX1cblxuICAgIHRoaXMucHJpbnRzLnNldChzdGF0ZW1lbnQsIHtub2RlOiBjYWxsLm5hbWUsIHR5cGU6IG5hbWUuc2xpY2UoXCJzZW1hbnRpZm9sZF9wcmludF9cIi5sZW5ndGgpfSlcbiAgICByZXR1cm4gc3RhdGVtZW50XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgZXhhY3QgYnJhY2VkIGNvbmRpdGlvbmFscyBhbmQgZWxzZS1pZiBuZXN0aW5nLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBJZiBleHByZXNzaW9uIHVzZWQgYXMgYSBzdGF0ZW1lbnQuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5JZlN0YXRlbWVudH0gQ29uZGl0aW9uYWwgc3RhdGVtZW50LlxuICAgKi9cbiAgY29uZGl0aW9uYWwobm9kZSkge1xuICAgIGNvbnN0IGNvbmRpdGlvbiA9IHRoaXMuZmllbGQobm9kZSwgXCJjb25kaXRpb25cIilcbiAgICBjb25zdCBjb25zZXF1ZW5jZSA9IHRoaXMuZmllbGQobm9kZSwgXCJjb25zZXF1ZW5jZVwiKVxuICAgIGNvbnN0IGFsdGVybmF0aXZlID0gbm9kZS5jaGlsZHJlbi5maW5kKCh7ZmllbGR9KSA9PiBmaWVsZCA9PSBcImFsdGVybmF0aXZlXCIpPy5ub2RlXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFtcImlmXCIsIGNvbmRpdGlvbiwgY29uc2VxdWVuY2UsIC4uLihhbHRlcm5hdGl2ZSA/IFthbHRlcm5hdGl2ZV0gOiBbXSldKVxuICAgIGNvbnN0IHN0YXRlbWVudCA9IHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZlN0YXRlbWVudFwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksIGNvbmRpdGlvbjogdGhpcy5leHByZXNzaW9uKGNvbmRpdGlvbiksIGNvbnNlcXVlbnQ6IHRoaXMuYmxvY2soY29uc2VxdWVuY2UpfVxuXG4gICAgaWYgKCFhbHRlcm5hdGl2ZSkgcmV0dXJuIHN0YXRlbWVudFxuICAgIGNvbnN0IGJyYW5jaCA9IHRoaXMucGFydHMoYWx0ZXJuYXRpdmUpWzFdXG5cbiAgICB0aGlzLnNoYXBlKGFsdGVybmF0aXZlLCBbXCJlbHNlXCIsIGJyYW5jaF0pXG4gICAgcmV0dXJuIHsuLi5zdGF0ZW1lbnQsIGFsdGVybmF0ZTogYnJhbmNoLnR5cGUgPT0gXCJpZl9leHByZXNzaW9uXCIgPyB7a2luZDogXCJCbG9ja1wiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihicmFuY2gpLCBzdGF0ZW1lbnRzOiBbdGhpcy5jb25kaXRpb25hbChicmFuY2gpXX0gOiB0aGlzLmJsb2NrKGJyYW5jaCl9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGNvbXBsZXRlIGxleGljYWwgYmxvY2suXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIEJyYWNlZCBibG9jay5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBTZW1hbnRpYyBibG9jay5cbiAgICovXG4gIGJsb2NrKG5vZGUpIHtcbiAgICBpZiAobm9kZS50eXBlICE9IFwiYmxvY2tcIikgdGhpcy5mYWlsKG5vZGUsIFwiYnJhY2VkIGJsb2NrIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFtcIntcIiwgLi4ucGFydHMuc2xpY2UoMSwgLTEpLCBcIn1cIl0pXG4gICAgcmV0dXJuIHtraW5kOiBcIkJsb2NrXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBzdGF0ZW1lbnRzOiBwYXJ0cy5zbGljZSgxLCAtMSkubWFwKGNoaWxkID0+IHRoaXMuc3RhdGVtZW50KGNoaWxkKSl9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBjcmF0ZS1yb290IGZ1bmN0aW9uIHdpdGggZXhhY3RseSB0d28gcmVxdWlyZWQgYnktdmFsdWUgcGFyYW1ldGVycy5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gRnVuY3Rpb24gaXRlbS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb259IFNlbWFudGljIGRlY2xhcmF0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24obm9kZSkge1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLmZpZWxkKG5vZGUsIFwibmFtZVwiKVxuICAgIGNvbnN0IHBhcmFtZXRlcnMgPSB0aGlzLmZpZWxkKG5vZGUsIFwicGFyYW1ldGVyc1wiKVxuICAgIGNvbnN0IHJldHVyblR5cGUgPSBub2RlLmNoaWxkcmVuLmZpbmQoKHtmaWVsZH0pID0+IGZpZWxkID09IFwicmV0dXJuX3R5cGVcIik/Lm5vZGVcbiAgICBjb25zdCBib2R5ID0gdGhpcy5maWVsZChub2RlLCBcImJvZHlcIilcblxuICAgIGlmICghcmV0dXJuVHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicnVzdFwiLCBcImZ1bmN0aW9uIHJldHVyblwiLCB0aGlzLmxvY2F0aW9uKG5vZGUpKVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiZm5cIiwgbmFtZSwgcGFyYW1ldGVycywgXCItPlwiLCByZXR1cm5UeXBlLCBib2R5XSlcbiAgICB0aGlzLnNoYXBlKHBhcmFtZXRlcnMsIFtcIihcIiwgXCJwYXJhbWV0ZXJcIiwgXCIsXCIsIFwicGFyYW1ldGVyXCIsIFwiKVwiXSlcbiAgICBjb25zdCBjb252ZXJ0ZWQgPSBbdGhpcy5wYXJ0cyhwYXJhbWV0ZXJzKVsxXSwgdGhpcy5wYXJ0cyhwYXJhbWV0ZXJzKVszXV0ubWFwKHBhcmFtZXRlciA9PiB7XG4gICAgICBjb25zdCBwYXR0ZXJuID0gdGhpcy5maWVsZChwYXJhbWV0ZXIsIFwicGF0dGVyblwiKVxuICAgICAgY29uc3QgdHlwZSA9IHRoaXMuZmllbGQocGFyYW1ldGVyLCBcInR5cGVcIilcblxuICAgICAgdGhpcy5zaGFwZShwYXJhbWV0ZXIsIFtwYXR0ZXJuLCBcIjpcIiwgdHlwZV0pXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUGFyYW1ldGVyXCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihwYXJhbWV0ZXIpLCBuYW1lOiB0aGlzLmlkZW50aWZpZXIocGF0dGVybiksIHR5cGU6IHRoaXMudHlwZSh0eXBlKX0sIHtuYW1lOiB0aGlzLmxvY2F0aW9uKHBhdHRlcm4pfSlcbiAgICB9KVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgbmFtZTogdGhpcy5pZGVudGlmaWVyKG5hbWUpLCBwYXJhbWV0ZXJzOiBjb252ZXJ0ZWQsXG4gICAgICByZXR1cm5UeXBlOiB0aGlzLnR5cGUocmV0dXJuVHlwZSksIGJvZHk6IHRoaXMuYmxvY2soYm9keSl9LCB7bmFtZTogdGhpcy5sb2NhdGlvbihuYW1lKX0pXG4gIH1cblxuICAvKipcbiAgICogQ29tcGFyZXMgYWxsIGZpZWxkcywgY2hpbGRyZW4gYW5kIGxlYWYgc3BlbGxpbmdzIGFnYWluc3QgcXVhbGlmaWVkIHN1cHBvcnQgc3ludGF4LlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IGFjdHVhbCAtIE9yaWdpbmFsIG5vZGUuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gZXhwZWN0ZWQgLSBRdWFsaWZpZWQgbm9kZS5cbiAgICogQHBhcmFtIHtSdXN0UmVhZGVyfSBjYW5vbmljYWwgLSBRdWFsaWZpZWQgc3BlbGxpbmcgcmVhZGVyLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGNvbXBhcmVUcmVlKGFjdHVhbCwgZXhwZWN0ZWQsIGNhbm9uaWNhbCkge1xuICAgIGlmIChhY3R1YWwudHlwZSAhPSBleHBlY3RlZC50eXBlIHx8IGFjdHVhbC5uYW1lZCAhPSBleHBlY3RlZC5uYW1lZCB8fCBhY3R1YWwuZXh0cmEgIT0gZXhwZWN0ZWQuZXh0cmEpIHRoaXMuZmFpbChhY3R1YWwsIFwibW9kaWZpZWQgUnVzdCBzdXBwb3J0IG5vZGVcIilcbiAgICBjb25zdCBsZWZ0ID0gdGhpcy5wYXJ0cyhhY3R1YWwpXG4gICAgY29uc3QgcmlnaHQgPSBjYW5vbmljYWwucGFydHMoZXhwZWN0ZWQpXG5cbiAgICBpZiAobGVmdC5sZW5ndGggIT0gcmlnaHQubGVuZ3RoKSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFJ1c3Qgc3VwcG9ydCBjaGlsZHJlblwiKVxuICAgIGlmICghbGVmdC5sZW5ndGggJiYgdGhpcy50ZXh0KGFjdHVhbCkgIT0gY2Fub25pY2FsLnRleHQoZXhwZWN0ZWQpKSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFJ1c3Qgc3VwcG9ydCB0b2tlblwiKVxuICAgIGxlZnQuZm9yRWFjaCgoY2hpbGQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoYWN0dWFsLmNoaWxkcmVuLmZpbmQoZWRnZSA9PiBlZGdlLm5vZGUgPT09IGNoaWxkKT8uZmllbGQgIT0gZXhwZWN0ZWQuY2hpbGRyZW4uZmluZChlZGdlID0+IGVkZ2Uubm9kZSA9PT0gcmlnaHRbaW5kZXhdKT8uZmllbGQpIHRoaXMuZmFpbChjaGlsZCwgXCJtb2RpZmllZCBSdXN0IHN1cHBvcnQgZmllbGRcIilcbiAgICAgIHRoaXMuY29tcGFyZVRyZWUoY2hpbGQsIHJpZ2h0W2luZGV4XSwgY2Fub25pY2FsKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgb25seSBhbHJlYWR5IHZhbGlkYXRlZCBzY2FsYXIgZXhwcmVzc2lvbnMgZm9yIHNjYWZmb2xkIGNoZWNraW5nLlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IGV4cHJlc3Npb24gLSBSZXNvbHZlZCBzZW1hbnRpYyBleHByZXNzaW9uLlxuICAgKiBAcGFyYW0ge01hcDxzdHJpbmcsIFNjYWxhcj59IGJpbmRpbmdzIC0gTGV4aWNhbCB0eXBlcy5cbiAgICogQHJldHVybnMge1NjYWxhcn0gU2VtYW50aWMgcmVzdWx0IHR5cGUuXG4gICAqL1xuICBleHByZXNzaW9uVHlwZShleHByZXNzaW9uLCBiaW5kaW5ncykge1xuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJTdHJpbmdMaXRlcmFsXCIpIHJldHVybiBcInN0cmluZ1wiXG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkludGVnZXJMaXRlcmFsXCIpIHJldHVybiBcImludGVnZXJcIlxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCb29sZWFuTGl0ZXJhbFwiKSByZXR1cm4gXCJib29sZWFuXCJcbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQmluYXJ5RXhwcmVzc2lvblwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSByZXR1cm4gZXhwcmVzc2lvbi50eXBlXG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCAhPSBcIkNhbGxFeHByZXNzaW9uXCIgJiYgZXhwcmVzc2lvbi5raW5kICE9IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVmFsaWRhdGVkIFJ1c3Qgc291cmNlIGV4cG9zZWQgYSBjb2xsZWN0aW9uIGV4cHJlc3Npb24uXCIpXG4gICAgfVxuICAgIGNvbnN0IHR5cGUgPSBleHByZXNzaW9uLmtpbmQgPT0gXCJDYWxsRXhwcmVzc2lvblwiID8gdGhpcy5mdW5jdGlvbnMuZ2V0KGV4cHJlc3Npb24uY2FsbGVlKSA6IGJpbmRpbmdzLmdldChleHByZXNzaW9uLm5hbWUpXG5cbiAgICBpZiAoIXR5cGUpIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBSdXN0IGV4cHJlc3Npb24gbG9zdCBpdHMgc2NhbGFyIGJpbmRpbmcuXCIpXG4gICAgcmV0dXJuIHR5cGVcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgY2xvbmUsIGJvcnJvdyBhbmQgcHJpbnQgY29uc3RyYWludHMgYWZ0ZXIgc2hhcmVkIG9wZXJhdGlvbiByZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBibG9jayAtIFJlc29sdmVkIGJsb2NrLlxuICAgKiBAcGFyYW0ge01hcDxzdHJpbmcsIFNjYWxhcj59IGluaGVyaXRlZCAtIEVuY2xvc2luZyB0eXBlcy5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICB2YWxpZGF0ZVNjYWxhcnMoYmxvY2ssIGluaGVyaXRlZCkge1xuICAgIGNvbnN0IGJpbmRpbmdzID0gbmV3IE1hcChpbmhlcml0ZWQpXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGVhY2ggb3JpZ2luYWwgY2xvbmUgYW5kIGJvcnJvd2VkIGNvbmNhdGVuYXRpb24gYWZ0ZXIgc2NhbGFyIHJlc29sdXRpb24uXG4gICAgICogQHBhcmFtIHtFeHByZXNzaW9ufSBleHByZXNzaW9uIC0gQ3VycmVudCBleHByZXNzaW9uLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIGNvbnN0IHZpc2l0ID0gZXhwcmVzc2lvbiA9PiB7XG4gICAgICBjb25zdCBjbG9uZSA9IHRoaXMuY2xvbmVzLmdldChleHByZXNzaW9uKVxuICAgICAgY29uc3QgYWRkaXRpb24gPSB0aGlzLmFkZGl0aW9ucy5nZXQoZXhwcmVzc2lvbilcblxuICAgICAgaWYgKGNsb25lICYmIHRoaXMuZXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbiwgYmluZGluZ3MpICE9IFwic3RyaW5nXCIpIHRoaXMuZmFpbChjbG9uZSwgXCJjbG9uZSByZXF1aXJlcyBvd25lZCBTdHJpbmdcIilcbiAgICAgIGlmIChhZGRpdGlvbiAmJiAodGhpcy5leHByZXNzaW9uVHlwZShleHByZXNzaW9uLCBiaW5kaW5ncykgPT0gXCJzdHJpbmdcIikgIT0gYWRkaXRpb24uYm9ycm93ZWQpIHRoaXMuZmFpbChhZGRpdGlvbi5ub2RlLCBcInN0cmluZyBjb25jYXRlbmF0aW9uIHJlcXVpcmVzIGV4YWN0bHkgYSBib3Jyb3dlZCBTdHJpbmcgUkhTXCIpXG4gICAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikgZXhwcmVzc2lvbi5hcmd1bWVudHMuZm9yRWFjaCh2aXNpdClcbiAgICAgIGVsc2UgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB2aXNpdChleHByZXNzaW9uLm9wZXJhbmQpXG4gICAgICBlbHNlIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIpIHsgdmlzaXQoZXhwcmVzc2lvbi5sZWZ0KTsgdmlzaXQoZXhwcmVzc2lvbi5yaWdodCkgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJsb2NrLnN0YXRlbWVudHMpIHtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuY29uZGl0aW9uIDpcbiAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIgPyBzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIgOlxuICAgICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5leHByZXNzaW9uIDpcbiAgICAgICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuZXhwcmVzc2lvbiA6IHVuZGVmaW5lZFxuXG4gICAgICBpZiAoIWV4cHJlc3Npb24pIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBSdXN0IHNvdXJjZSBjb250YWluZWQgYSBiYXJlIHJldHVybi5cIilcbiAgICAgIHZpc2l0KGV4cHJlc3Npb24pXG4gICAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIpIGJpbmRpbmdzLnNldChzdGF0ZW1lbnQubmFtZSxcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSAqLyAoc3RhdGVtZW50LnR5cGUpLm5hbWUpXG4gICAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJQcmludFN0YXRlbWVudFwiKSB7XG4gICAgICAgIGNvbnN0IHByaW50ID0gdGhpcy5wcmludHMuZ2V0KHN0YXRlbWVudClcblxuICAgICAgICBpZiAoIXByaW50KSB0aHJvdyBuZXcgRXJyb3IoXCJSdXN0IHByaW50IGxvc3QgaXRzIG9yaWdpbmFsIGhlbHBlciBpZGVudGl0eS5cIilcbiAgICAgICAgaWYgKHRoaXMuZXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbiwgYmluZGluZ3MpICE9IHByaW50LnR5cGUpIHRoaXMuZmFpbChwcmludC5ub2RlLCBcInByaW50IGhlbHBlciBzY2FsYXIgbWlzbWF0Y2hcIilcbiAgICAgIH1cbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVNjYWxhcnMoc3RhdGVtZW50LmNvbnNlcXVlbnQsIGJpbmRpbmdzKVxuICAgICAgICBpZiAoc3RhdGVtZW50LmFsdGVybmF0ZSkgdGhpcy52YWxpZGF0ZVNjYWxhcnMoc3RhdGVtZW50LmFsdGVybmF0ZSwgYmluZGluZ3MpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBnZW51aW5lIHNvdXJjZSBtb3ZlcyBpbiBldmFsdWF0aW9uIG9yZGVyLCByZXRhaW5pbmcgaW1wbGljaXQgY29tcGFyaXNvbiBib3Jyb3dzLlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IGV4cHJlc3Npb24gLSBPcmlnaW5hbCBleHByZXNzaW9uIG9jY3VycmVuY2UuXG4gICAqIEBwYXJhbSB7TWFwPHN0cmluZywgU2NhbGFyPn0gYmluZGluZ3MgLSBWYWxpZGF0ZWQgbGV4aWNhbCB0eXBlcy5cbiAgICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gbW92ZWQgLSBEZWZpbml0ZWx5IG9yIHBvc3NpYmx5IGNvbnN1bWVkIFN0cmluZyBiaW5kaW5ncy5cbiAgICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gYm9ycm93ZWQgLSBCb3Jyb3dzIGhlbGQgYnkgZW5jbG9zaW5nIG9wZXJhbmQgZXZhbHVhdGlvbi5cbiAgICogQHBhcmFtIHtcIm1vdmVcIiB8IFwiYm9ycm93XCJ9IFt1c2FnZV0gLSBIb3cgdGhpcyBleHByZXNzaW9uJ3MgcmVzdWx0IGlzIGNvbnN1bWVkLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthcHBseUNsb25lXSAtIFdoZXRoZXIgdG8gYXBwbHkgdGhpcyBvY2N1cnJlbmNlJ3MgY2hlY2tlZCBjbG9uZSB3cmFwcGVyLlxuICAgKiBAcmV0dXJucyB7U2V0PHN0cmluZz59IFBsYWNlIGJvcnJvd3MgaGVsZCB1bnRpbCB0aGUgY29udGFpbmluZyBvcGVyYXRpb24gY29tcGxldGVzLlxuICAgKi9cbiAgb3duZXJzaGlwRXhwcmVzc2lvbihleHByZXNzaW9uLCBiaW5kaW5ncywgbW92ZWQsIGJvcnJvd2VkLCB1c2FnZSA9IFwibW92ZVwiLCBhcHBseUNsb25lID0gdHJ1ZSkge1xuICAgIGlmIChhcHBseUNsb25lICYmIHRoaXMuY2xvbmVzLmhhcyhleHByZXNzaW9uKSkge1xuICAgICAgdGhpcy5vd25lcnNoaXBFeHByZXNzaW9uKGV4cHJlc3Npb24sIGJpbmRpbmdzLCBtb3ZlZCwgYm9ycm93ZWQsIFwiYm9ycm93XCIsIGZhbHNlKVxuICAgICAgcmV0dXJuIG5ldyBTZXQoKVxuICAgIH1cbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiAmJiB0aGlzLmV4cHJlc3Npb25UeXBlKGV4cHJlc3Npb24sIGJpbmRpbmdzKSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICBjb25zdCBuYW1lID0gZXhwcmVzc2lvbi5uYW1lXG5cbiAgICAgIGlmIChtb3ZlZC5oYXMobmFtZSkpIHVuc3VwcG9ydGVkU3ludGF4KFwicnVzdFwiLCBgdXNlIG9mIG1vdmVkIFN0cmluZyAnJHtuYW1lfSdgLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgaWYgKHVzYWdlID09IFwiYm9ycm93XCIpIHJldHVybiBuZXcgU2V0KFtuYW1lXSlcbiAgICAgIGlmIChib3Jyb3dlZC5oYXMobmFtZSkpIHVuc3VwcG9ydGVkU3ludGF4KFwicnVzdFwiLCBgY2Fubm90IG1vdmUgYm9ycm93ZWQgU3RyaW5nICcke25hbWV9JyBkdXJpbmcgb3BlcmFuZCBldmFsdWF0aW9uYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgIG1vdmVkLmFkZChuYW1lKVxuICAgIH0gZWxzZSBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgICAgZm9yIChjb25zdCBhcmd1bWVudCBvZiBleHByZXNzaW9uLmFyZ3VtZW50cykgdGhpcy5vd25lcnNoaXBFeHByZXNzaW9uKGFyZ3VtZW50LCBiaW5kaW5ncywgbW92ZWQsIGJvcnJvd2VkKVxuICAgIH0gZWxzZSBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiVW5hcnlFeHByZXNzaW9uXCIpIHRoaXMub3duZXJzaGlwRXhwcmVzc2lvbihleHByZXNzaW9uLm9wZXJhbmQsIGJpbmRpbmdzLCBtb3ZlZCwgYm9ycm93ZWQpXG4gICAgZWxzZSBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQmluYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgICBpZiAoZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJTdHJpbmdFcXVhbFwiIHx8IGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiU3RyaW5nTm90RXF1YWxcIikge1xuICAgICAgICBjb25zdCBoZWxkID0gdGhpcy5vd25lcnNoaXBFeHByZXNzaW9uKGV4cHJlc3Npb24ubGVmdCwgYmluZGluZ3MsIG1vdmVkLCBib3Jyb3dlZCwgXCJib3Jyb3dcIilcblxuICAgICAgICB0aGlzLm93bmVyc2hpcEV4cHJlc3Npb24oZXhwcmVzc2lvbi5yaWdodCwgYmluZGluZ3MsIG1vdmVkLCBuZXcgU2V0KFsuLi5ib3Jyb3dlZCwgLi4uaGVsZF0pLCBcImJvcnJvd1wiKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vd25lcnNoaXBFeHByZXNzaW9uKGV4cHJlc3Npb24ubGVmdCwgYmluZGluZ3MsIG1vdmVkLCBib3Jyb3dlZClcbiAgICAgICAgaWYgKGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiQm9vbGVhbkFuZFwiIHx8IGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiQm9vbGVhbk9yXCIpIHtcbiAgICAgICAgICBjb25zdCBjb25kaXRpb25hbCA9IG5ldyBTZXQobW92ZWQpXG5cbiAgICAgICAgICB0aGlzLm93bmVyc2hpcEV4cHJlc3Npb24oZXhwcmVzc2lvbi5yaWdodCwgYmluZGluZ3MsIGNvbmRpdGlvbmFsLCBib3Jyb3dlZClcbiAgICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgY29uZGl0aW9uYWwpIG1vdmVkLmFkZChuYW1lKVxuICAgICAgICB9IGVsc2UgdGhpcy5vd25lcnNoaXBFeHByZXNzaW9uKGV4cHJlc3Npb24ucmlnaHQsIGJpbmRpbmdzLCBtb3ZlZCwgYm9ycm93ZWQsIGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiU3RyaW5nQ29uY2F0XCIgPyBcImJvcnJvd1wiIDogXCJtb3ZlXCIpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgU2V0KClcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZXMgc291cmNlIGF2YWlsYWJpbGl0eSBvbmx5IGZyb20gcGF0aHMgdGhhdCBjb250aW51ZSwgcmVzdG9yaW5nIGV4cGxpY2l0IGFzc2lnbm1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBibG9jayAtIE9yaWdpbmFsIGxleGljYWwgYmxvY2suXG4gICAqIEBwYXJhbSB7TWFwPHN0cmluZywgU2NhbGFyPn0gaW5oZXJpdGVkIC0gVmlzaWJsZSBzY2FsYXIgYmluZGluZ3MuXG4gICAqIEBwYXJhbSB7U2V0PHN0cmluZz59IGluaGVyaXRlZE1vdmVkIC0gSW5jb21pbmcgY29uc3VtZWQgYmluZGluZ3MuXG4gICAqIEByZXR1cm5zIHt7bW92ZWQ6IFNldDxzdHJpbmc+LCByZXR1cm5zOiBib29sZWFufX0gT3V0Z29pbmcgc291cmNlIGF2YWlsYWJpbGl0eSBhbmQgY29udHJvbCBmbG93LlxuICAgKi9cbiAgdmFsaWRhdGVPd25lcnNoaXAoYmxvY2ssIGluaGVyaXRlZCwgaW5oZXJpdGVkTW92ZWQpIHtcbiAgICBjb25zdCBiaW5kaW5ncyA9IG5ldyBNYXAoaW5oZXJpdGVkKVxuICAgIGNvbnN0IG1vdmVkID0gbmV3IFNldChpbmhlcml0ZWRNb3ZlZClcblxuICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJsb2NrLnN0YXRlbWVudHMpIHtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuY29uZGl0aW9uIDpcbiAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIgPyBzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIgOlxuICAgICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5leHByZXNzaW9uIDpcbiAgICAgICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuZXhwcmVzc2lvbiA6IHVuZGVmaW5lZFxuXG4gICAgICBpZiAoIWV4cHJlc3Npb24pIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBSdXN0IHNvdXJjZSBjb250YWluZWQgYSBiYXJlIHJldHVybi5cIilcbiAgICAgIHRoaXMub3duZXJzaGlwRXhwcmVzc2lvbihleHByZXNzaW9uLCBiaW5kaW5ncywgbW92ZWQsIG5ldyBTZXQoKSlcbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlJldHVyblN0YXRlbWVudFwiKSByZXR1cm4ge21vdmVkLCByZXR1cm5zOiB0cnVlfVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiKSBiaW5kaW5ncy5zZXQoc3RhdGVtZW50Lm5hbWUsXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKHN0YXRlbWVudC50eXBlKS5uYW1lKVxuICAgICAgZWxzZSBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJBc3NpZ25tZW50U3RhdGVtZW50XCIpIG1vdmVkLmRlbGV0ZShzdGF0ZW1lbnQudGFyZ2V0Lm5hbWUpXG4gICAgICBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgY29uc3QgY29uc2VxdWVudCA9IHRoaXMudmFsaWRhdGVPd25lcnNoaXAoc3RhdGVtZW50LmNvbnNlcXVlbnQsIGJpbmRpbmdzLCBtb3ZlZClcbiAgICAgICAgY29uc3QgYWx0ZXJuYXRlID0gc3RhdGVtZW50LmFsdGVybmF0ZSA/IHRoaXMudmFsaWRhdGVPd25lcnNoaXAoc3RhdGVtZW50LmFsdGVybmF0ZSwgYmluZGluZ3MsIG1vdmVkKSA6IHttb3ZlZDogbmV3IFNldChtb3ZlZCksIHJldHVybnM6IGZhbHNlfVxuXG4gICAgICAgIGlmIChjb25zZXF1ZW50LnJldHVybnMgJiYgYWx0ZXJuYXRlLnJldHVybnMpIHJldHVybiB7bW92ZWQsIHJldHVybnM6IHRydWV9XG4gICAgICAgIG1vdmVkLmNsZWFyKClcbiAgICAgICAgZm9yIChjb25zdCBwYXRoIG9mIFtjb25zZXF1ZW50LCBhbHRlcm5hdGVdKSB7XG4gICAgICAgICAgaWYgKCFwYXRoLnJldHVybnMpIGZvciAoY29uc3QgbmFtZSBvZiBwYXRoLm1vdmVkKSBpZiAoYmluZGluZ3MuaGFzKG5hbWUpKSBtb3ZlZC5hZGQobmFtZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge21vdmVkLCByZXR1cm5zOiBmYWxzZX1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgdGhlIGNvbXBsZXRlIGNyYXRlIGFuZCBjb2xsYXBzZXMgb25seSBleGFjdCBkZWNsYXJlZCBzdXBwb3J0LlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IHJvb3QgLSBDb21wbGV0ZSByb290LlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IFJlc29sdmVkIHNlbWFudGljcy5cbiAgICovXG4gIG1vZHVsZShyb290KSB7XG4gICAgdGhpcy52YWxpZGF0ZVRyZWUocm9vdClcbiAgICBpZiAocm9vdC50eXBlICE9IFwic291cmNlX2ZpbGVcIikgdGhpcy5mYWlsKHJvb3QsIFwiY3JhdGUgcm9vdCByZXF1aXJlZFwiKVxuICAgIGNvbnN0IGNhbm9uaWNhbCA9IG5ldyBSdXN0UmVhZGVyKHRoaXMuZmlsZW5hbWUsIHJ1c3RSdW50aW1lKVxuICAgIGNvbnN0IHN1cHBvcnQgPSBjYW5vbmljYWwucGFydHMocGFyc2VSdXN0Q3N0KHJ1c3RSdW50aW1lKS5yb290KVxuICAgIGNvbnN0IGhlbHBlcnMgPSBuZXcgTWFwKHN1cHBvcnQuZmlsdGVyKG5vZGUgPT4gbm9kZS50eXBlID09IFwiZnVuY3Rpb25faXRlbVwiKS5tYXAobm9kZSA9PiBbY2Fub25pY2FsLnRleHQoY2Fub25pY2FsLmZpZWxkKG5vZGUsIFwibmFtZVwiKSksIG5vZGVdKSlcbiAgICAvKiogQHR5cGUge0NzdE5vZGVbXX0gKi9cbiAgICBjb25zdCBkZWZpbml0aW9ucyA9IFtdXG4gICAgbGV0IGxpbnQgPSBmYWxzZVxuICAgIC8qKiBAdHlwZSB7Q3N0Tm9kZSB8IHVuZGVmaW5lZH0gKi9cbiAgICBsZXQgbWFpblxuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMucGFydHMocm9vdCkpIHtcbiAgICAgIGlmIChub2RlLnR5cGUgPT0gXCJpbm5lcl9hdHRyaWJ1dGVfaXRlbVwiKSB7XG4gICAgICAgIGlmIChsaW50IHx8IGRlZmluaXRpb25zLmxlbmd0aCB8fCBtYWluIHx8IHRoaXMuaGVscGVycy5zaXplKSB0aGlzLmZhaWwobm9kZSwgXCJtaXNwbGFjZWQgUnVzdCBsaW50IHN1cHBvcnRcIilcbiAgICAgICAgdGhpcy5jb21wYXJlVHJlZShub2RlLCBzdXBwb3J0WzBdLCBjYW5vbmljYWwpXG4gICAgICAgIGxpbnQgPSB0cnVlXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBpZiAobm9kZS50eXBlICE9IFwiZnVuY3Rpb25faXRlbVwiKSB0aGlzLmZhaWwobm9kZSwgXCJjcmF0ZS1yb290IGZyZWUgZnVuY3Rpb25zIG9ubHlcIilcbiAgICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHQodGhpcy5maWVsZChub2RlLCBcIm5hbWVcIikpXG4gICAgICBjb25zdCBoZWxwZXIgPSBoZWxwZXJzLmdldChuYW1lKVxuXG4gICAgICBpZiAoaGVscGVyKSB7XG4gICAgICAgIGlmICh0aGlzLmhlbHBlcnMuaGFzKG5hbWUpKSB0aGlzLmZhaWwobm9kZSwgXCJkdXBsaWNhdGUgUnVzdCBoZWxwZXJcIilcbiAgICAgICAgdGhpcy5jb21wYXJlVHJlZShub2RlLCBoZWxwZXIsIGNhbm9uaWNhbClcbiAgICAgICAgdGhpcy5oZWxwZXJzLmFkZChuYW1lKVxuICAgICAgfSBlbHNlIGlmIChuYW1lID09IFwibWFpblwiKSB7XG4gICAgICAgIGlmIChtYWluKSB0aGlzLmZhaWwobm9kZSwgXCJkdXBsaWNhdGUgbWFpblwiKVxuICAgICAgICBtYWluID0gbm9kZVxuICAgICAgfSBlbHNlIGRlZmluaXRpb25zLnB1c2gobm9kZSlcbiAgICB9XG4gICAgaWYgKCFtYWluKSB0aGlzLmZhaWwocm9vdCwgXCJjYW5vbmljYWwgZm4gbWFpbigpIHJlcXVpcmVkXCIpXG4gICAgaWYgKCFkZWZpbml0aW9ucy5sZW5ndGgpIHRoaXMuZmFpbChyb290LCBcInNlbWFudGljIGZ1bmN0aW9uIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgbmFtZSA9IHRoaXMuZmllbGQobWFpbiwgXCJuYW1lXCIpXG4gICAgY29uc3QgcGFyYW1ldGVycyA9IHRoaXMuZmllbGQobWFpbiwgXCJwYXJhbWV0ZXJzXCIpXG4gICAgY29uc3QgYm9keSA9IHRoaXMuZmllbGQobWFpbiwgXCJib2R5XCIpXG5cbiAgICB0aGlzLnNoYXBlKG1haW4sIFtcImZuXCIsIG5hbWUsIHBhcmFtZXRlcnMsIGJvZHldKVxuICAgIHRoaXMuc2hhcGUocGFyYW1ldGVycywgW1wiKFwiLCBcIilcIl0pXG4gICAgY29uc3QgbW9kdWxlID0gdmFsaWRhdGVQYXJzZWRNb2R1bGUoe2tpbmQ6IFwiTW9kdWxlXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKHJvb3QpLCBmdW5jdGlvbnM6IGRlZmluaXRpb25zLm1hcChub2RlID0+IHRoaXMuZnVuY3Rpb24obm9kZSkpLFxuICAgICAgZW50cnlQb2ludDoge2tpbmQ6IFwiRW50cnlQb2ludFwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihtYWluKSwgYm9keTogdGhpcy5ibG9jayhib2R5KX19LCBcInJ1c3RcIilcblxuICAgIHRoaXMuZnVuY3Rpb25zID0gbmV3IE1hcChtb2R1bGUuZnVuY3Rpb25zLm1hcChkZWNsYXJhdGlvbiA9PiBbXG4gICAgICBkZWNsYXJhdGlvbi5uYW1lLFxuICAgICAgLyoqIEB0eXBlIHtTY2FsYXJ9ICovICgvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVSZWZlcmVuY2V9ICovIChkZWNsYXJhdGlvbi5yZXR1cm5UeXBlKS5uYW1lKVxuICAgIF0pKVxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykge1xuICAgICAgY29uc3QgYmluZGluZ3MgPSBuZXcgTWFwKGRlY2xhcmF0aW9uLnBhcmFtZXRlcnMubWFwKHBhcmFtZXRlciA9PiBbcGFyYW1ldGVyLm5hbWUsXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKHBhcmFtZXRlci50eXBlKS5uYW1lXSkpXG5cbiAgICAgIHRoaXMudmFsaWRhdGVTY2FsYXJzKGRlY2xhcmF0aW9uLmJvZHksIGJpbmRpbmdzKVxuICAgICAgdGhpcy52YWxpZGF0ZU93bmVyc2hpcChkZWNsYXJhdGlvbi5ib2R5LCBiaW5kaW5ncywgbmV3IFNldCgpKVxuICAgIH1cbiAgICB0aGlzLnZhbGlkYXRlU2NhbGFycyhtb2R1bGUuZW50cnlQb2ludC5ib2R5LCBuZXcgTWFwKCkpXG4gICAgdGhpcy52YWxpZGF0ZU93bmVyc2hpcChtb2R1bGUuZW50cnlQb2ludC5ib2R5LCBuZXcgTWFwKCksIG5ldyBTZXQoKSlcbiAgICByZXR1cm4gbW9kdWxlXG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZXMgb25seSB0aGUgcXVhbGlmaWVkIGZyb3plbiBDU1QgYW5kIHJlamVjdHMgdW5zdXBwb3J0ZWQgaW5wdXQgYmVmb3JlIGFkYXB0YXRpb24uXG4gKiBAcGFyYW0ge3tmaWxlbmFtZTogc3RyaW5nLCBzb3VyY2U6IHN0cmluZ319IGlucHV0IC0gRXhhY3Qgc291cmNlIHJlcXVlc3QuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IFJ1c3Qgc2VtYW50aWMgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VSdXN0KHtmaWxlbmFtZSwgc291cmNlfSkge1xuICBjb25zdCBjb29yZGluYXRlcyA9IGNyZWF0ZUNvb3JkaW5hdGVJbmRleChzb3VyY2UpXG4gIGNvbnN0IGxvY2F0aW9uID0ge2ZpbGVuYW1lLCBzdGFydDogaW5kZXhlZFBvaW50QXQoY29vcmRpbmF0ZXMsIDApLCBlbmQ6IGluZGV4ZWRQb2ludEF0KGNvb3JkaW5hdGVzLCBzb3VyY2UubGVuZ3RoKX1cblxuICBpZiAoIWhhc09ubHlVbmljb2RlU2NhbGFycyhzb3VyY2UpKSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gc291cmNlLnNlYXJjaCgvW1xcdUQ4MDAtXFx1REJGRl0oPyFbXFx1REMwMC1cXHVERkZGXSl8KD88IVtcXHVEODAwLVxcdURCRkZdKVtcXHVEQzAwLVxcdURGRkZdL3UpXG5cbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlBBUlNFX0VSUk9SXCIsIGxhbmd1YWdlOiBcInJ1c3RcIiwgbWVzc2FnZTogXCJSdXN0IHNvdXJjZSBjb250YWlucyBhIGxvbmUgVVRGLTE2IHN1cnJvZ2F0ZS5cIixcbiAgICAgIGxvY2F0aW9uOiB7ZmlsZW5hbWUsIHN0YXJ0OiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgb2Zmc2V0KSwgZW5kOiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgb2Zmc2V0ICsgMSl9fSlcbiAgfVxuICBpZiAoc291cmNlLmxlbmd0aCA+IG1heGltdW1SdXN0U291cmNlTGVuZ3RoKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJydXN0XCIsIFwic291cmNlIGV4Y2VlZHMgdGhlIGZyb3plbiBSdXN0IHBhcnNlcidzIDMyNzY3IFVURi0xNiBpbnB1dCBsaW1pdFwiLCBsb2NhdGlvbilcbiAgbGV0IHNuYXBzaG90XG5cbiAgdHJ5IHtcbiAgICBzbmFwc2hvdCA9IHBhcnNlUnVzdENzdChzb3VyY2UpXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7Y29kZTogXCJQQVJTRV9FUlJPUlwiLCBsYW5ndWFnZTogXCJydXN0XCIsIGxvY2F0aW9uLFxuICAgICAgY2F1c2U6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IHVuZGVmaW5lZCwgbWVzc2FnZTogXCJUaGUgcXVhbGlmaWVkIFJ1c3QgcGFyc2VyIGNvdWxkIG5vdCBwcm9kdWNlIGEgY29tcGxldGUgQ1NULlwifSlcbiAgfVxuICByZXR1cm4gbmV3IFJ1c3RSZWFkZXIoZmlsZW5hbWUsIHNvdXJjZSkubW9kdWxlKHNuYXBzaG90LnJvb3QpXG59XG4iXX0=
|