semantifold 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -15
- package/build/index.d.ts +52 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +60 -8
- package/build/src/artifact-path.d.ts +23 -1
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +45 -3
- package/build/src/artifacts.d.ts.map +1 -1
- package/build/src/artifacts.js +66 -1
- package/build/src/backends/android.d.ts +49 -0
- package/build/src/backends/android.d.ts.map +1 -0
- package/build/src/backends/android.js +1274 -0
- package/build/src/backends/c-validation.d.ts.map +1 -1
- package/build/src/backends/c-validation.js +7 -3
- package/build/src/backends/cpp-validation.d.ts.map +1 -1
- package/build/src/backends/cpp-validation.js +7 -3
- package/build/src/backends/csharp.js +7 -1
- package/build/src/backends/dart-runtime.d.ts +2 -0
- package/build/src/backends/dart-runtime.d.ts.map +1 -0
- package/build/src/backends/dart-runtime.js +41 -0
- package/build/src/backends/dart.d.ts +20 -0
- package/build/src/backends/dart.d.ts.map +1 -0
- package/build/src/backends/dart.js +321 -0
- package/build/src/backends/effects.d.ts +60 -0
- package/build/src/backends/effects.d.ts.map +1 -0
- package/build/src/backends/effects.js +746 -0
- package/build/src/backends/go.js +18 -4
- package/build/src/backends/identifiers.d.ts +36 -4
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +160 -10
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -4
- package/build/src/backends/ios.d.ts +68 -0
- package/build/src/backends/ios.d.ts.map +1 -0
- package/build/src/backends/ios.js +1503 -0
- package/build/src/backends/java.d.ts.map +1 -1
- package/build/src/backends/java.js +429 -36
- package/build/src/backends/javascript.d.ts +6 -0
- package/build/src/backends/javascript.d.ts.map +1 -1
- package/build/src/backends/javascript.js +380 -24
- package/build/src/backends/kotlin-runtime.d.ts +3 -0
- package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
- package/build/src/backends/kotlin-runtime.js +29 -0
- package/build/src/backends/kotlin.d.ts +33 -0
- package/build/src/backends/kotlin.d.ts.map +1 -0
- package/build/src/backends/kotlin.js +138 -0
- package/build/src/backends/native-validation.d.ts +2 -2
- package/build/src/backends/native-validation.d.ts.map +1 -1
- package/build/src/backends/native-validation.js +2 -2
- package/build/src/backends/ordered-expressions.d.ts.map +1 -1
- package/build/src/backends/ordered-expressions.js +39 -7
- package/build/src/backends/php-stdlib-support.d.ts +19 -0
- package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
- package/build/src/backends/php-stdlib-support.js +227 -0
- package/build/src/backends/php.d.ts.map +1 -1
- package/build/src/backends/php.js +448 -33
- package/build/src/backends/program.d.ts +83 -0
- package/build/src/backends/program.d.ts.map +1 -0
- package/build/src/backends/program.js +1309 -0
- package/build/src/backends/python.js +7 -1
- package/build/src/backends/ruby.d.ts.map +1 -1
- package/build/src/backends/ruby.js +310 -24
- package/build/src/backends/rust-runtime.d.ts +7 -0
- package/build/src/backends/rust-runtime.d.ts.map +1 -0
- package/build/src/backends/rust-runtime.js +32 -0
- package/build/src/backends/rust-validation.d.ts +9 -0
- package/build/src/backends/rust-validation.d.ts.map +1 -0
- package/build/src/backends/rust-validation.js +78 -0
- package/build/src/backends/rust.d.ts +24 -0
- package/build/src/backends/rust.d.ts.map +1 -0
- package/build/src/backends/rust.js +344 -0
- package/build/src/backends/scalars.d.ts +14 -6
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +167 -17
- package/build/src/backends/shared.d.ts +23 -4
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +2174 -62
- package/build/src/backends/stdlib-support.d.ts +14 -0
- package/build/src/backends/stdlib-support.d.ts.map +1 -0
- package/build/src/backends/stdlib-support.js +237 -0
- package/build/src/backends/swift-runtime.d.ts +3 -0
- package/build/src/backends/swift-runtime.d.ts.map +1 -0
- package/build/src/backends/swift-runtime.js +14 -0
- package/build/src/backends/swift.d.ts +8 -0
- package/build/src/backends/swift.d.ts.map +1 -0
- package/build/src/backends/swift.js +127 -0
- package/build/src/backends/typescript.d.ts.map +1 -1
- package/build/src/backends/typescript.js +344 -24
- package/build/src/backends/wasm.d.ts +43 -0
- package/build/src/backends/wasm.d.ts.map +1 -0
- package/build/src/backends/wasm.js +2164 -0
- package/build/src/backends/writer.d.ts +255 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +491 -3
- package/build/src/diagnostic.d.ts +4 -3
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +5 -3
- package/build/src/frontends/c.d.ts.map +1 -1
- package/build/src/frontends/c.js +5 -3
- package/build/src/frontends/cpp.d.ts.map +1 -1
- package/build/src/frontends/cpp.js +5 -3
- package/build/src/frontends/csharp.d.ts.map +1 -1
- package/build/src/frontends/csharp.js +7 -3
- package/build/src/frontends/dart.d.ts +10 -0
- package/build/src/frontends/dart.d.ts.map +1 -0
- package/build/src/frontends/dart.js +913 -0
- package/build/src/frontends/index.d.ts +3 -1
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +15 -5
- package/build/src/frontends/java.d.ts +110 -1
- package/build/src/frontends/java.d.ts.map +1 -1
- package/build/src/frontends/java.js +1725 -70
- package/build/src/frontends/javascript-typescript.d.ts +69 -1
- package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
- package/build/src/frontends/javascript-typescript.js +1825 -93
- package/build/src/frontends/kotlin.d.ts +10 -0
- package/build/src/frontends/kotlin.d.ts.map +1 -0
- package/build/src/frontends/kotlin.js +685 -0
- package/build/src/frontends/php.d.ts +118 -1
- package/build/src/frontends/php.d.ts.map +1 -1
- package/build/src/frontends/php.js +1583 -76
- package/build/src/frontends/program.d.ts +74 -0
- package/build/src/frontends/program.d.ts.map +1 -0
- package/build/src/frontends/program.js +989 -0
- package/build/src/frontends/ruby.d.ts +68 -1
- package/build/src/frontends/ruby.d.ts.map +1 -1
- package/build/src/frontends/ruby.js +1446 -101
- package/build/src/frontends/rust-parser.d.ts +11 -0
- package/build/src/frontends/rust-parser.d.ts.map +1 -0
- package/build/src/frontends/rust-parser.js +15 -0
- package/build/src/frontends/rust.d.ts +14 -0
- package/build/src/frontends/rust.d.ts.map +1 -0
- package/build/src/frontends/rust.js +715 -0
- package/build/src/frontends/scalars.d.ts +10 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +28 -2
- package/build/src/frontends/swift.d.ts +10 -0
- package/build/src/frontends/swift.d.ts.map +1 -0
- package/build/src/frontends/swift.js +860 -0
- package/build/src/frontends/types.d.ts +186 -0
- package/build/src/frontends/types.d.ts.map +1 -0
- package/build/src/frontends/types.js +634 -0
- package/build/src/language-registry.d.ts +46 -4
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +177 -13
- package/build/src/mapping.d.ts +2 -2
- package/build/src/mapping.d.ts.map +1 -1
- package/build/src/mapping.js +31 -10
- package/build/src/semantic/capabilities.d.ts +66 -0
- package/build/src/semantic/capabilities.d.ts.map +1 -0
- package/build/src/semantic/capabilities.js +649 -0
- package/build/src/semantic/effects.d.ts +26 -0
- package/build/src/semantic/effects.d.ts.map +1 -0
- package/build/src/semantic/effects.js +764 -0
- package/build/src/semantic/generics.d.ts +23 -0
- package/build/src/semantic/generics.d.ts.map +1 -0
- package/build/src/semantic/generics.js +61 -0
- package/build/src/semantic/lifetime.d.ts +37 -0
- package/build/src/semantic/lifetime.d.ts.map +1 -0
- package/build/src/semantic/lifetime.js +527 -0
- package/build/src/semantic/provenance.d.ts +9 -2
- package/build/src/semantic/provenance.d.ts.map +1 -1
- package/build/src/semantic/provenance.js +462 -20
- package/build/src/semantic/scalars.d.ts +11 -0
- package/build/src/semantic/scalars.d.ts.map +1 -1
- package/build/src/semantic/scalars.js +16 -1
- package/build/src/semantic/stdlib.d.ts +254 -0
- package/build/src/semantic/stdlib.d.ts.map +1 -0
- package/build/src/semantic/stdlib.js +880 -0
- package/build/src/semantic/types.d.ts +3108 -178
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +730 -15
- package/build/src/semantic/validate.d.ts +85 -5
- package/build/src/semantic/validate.d.ts.map +1 -1
- package/build/src/semantic/validate.js +2576 -98
- package/build/src/stdlib-facades.d.ts +304 -0
- package/build/src/stdlib-facades.d.ts.map +1 -0
- package/build/src/stdlib-facades.js +1167 -0
- package/build/src/stdlib-negotiation.d.ts +69 -0
- package/build/src/stdlib-negotiation.d.ts.map +1 -0
- package/build/src/stdlib-negotiation.js +403 -0
- package/build/src/stdlib-providers.d.ts +72 -0
- package/build/src/stdlib-providers.d.ts.map +1 -0
- package/build/src/stdlib-providers.js +339 -0
- package/build/src/toolchains.d.ts +55 -1
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +15 -4
- package/docs/android.md +79 -0
- package/docs/architecture.md +47 -13
- package/docs/dart.md +60 -0
- package/docs/goals.md +3 -3
- package/docs/ios.md +121 -0
- package/docs/kotlin.md +42 -0
- package/docs/language-support.md +238 -26
- package/docs/multi-file-modules.md +52 -0
- package/docs/parser-qualification.md +121 -8
- package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
- package/docs/rust.md +88 -0
- package/docs/source-maps.md +17 -7
- package/docs/specification.md +5 -0
- package/docs/standard-library-portability.md +39 -8
- package/docs/swift.md +44 -0
- package/docs/testing.md +381 -4
- package/docs/webassembly.md +52 -0
- package/index.js +66 -8
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
- package/package.json +5 -2
- package/src/artifact-path.js +47 -2
- package/src/artifacts.js +67 -0
- package/src/backends/android.js +1370 -0
- package/src/backends/c-validation.js +6 -1
- package/src/backends/cpp-validation.js +6 -1
- package/src/backends/csharp.js +3 -0
- package/src/backends/dart-runtime.js +41 -0
- package/src/backends/dart.js +326 -0
- package/src/backends/effects.js +705 -0
- package/src/backends/go.js +14 -2
- package/src/backends/identifiers.js +166 -9
- package/src/backends/index.js +27 -2
- package/src/backends/ios.js +1612 -0
- package/src/backends/java.js +454 -36
- package/src/backends/javascript.js +389 -23
- package/src/backends/kotlin-runtime.js +29 -0
- package/src/backends/kotlin.js +144 -0
- package/src/backends/native-validation.js +1 -1
- package/src/backends/ordered-expressions.js +40 -6
- package/src/backends/php-stdlib-support.js +239 -0
- package/src/backends/php.js +469 -32
- package/src/backends/program.js +1408 -0
- package/src/backends/python.js +3 -0
- package/src/backends/ruby.js +326 -23
- package/src/backends/rust-runtime.js +34 -0
- package/src/backends/rust-validation.js +75 -0
- package/src/backends/rust.js +335 -0
- package/src/backends/scalars.js +141 -16
- package/src/backends/shared.js +2314 -115
- package/src/backends/stdlib-support.js +234 -0
- package/src/backends/swift-runtime.js +14 -0
- package/src/backends/swift.js +132 -0
- package/src/backends/typescript.js +349 -23
- package/src/backends/wasm.js +2208 -0
- package/src/backends/writer.js +545 -2
- package/src/diagnostic.js +4 -2
- package/src/frontends/c.js +4 -2
- package/src/frontends/cpp.js +4 -2
- package/src/frontends/csharp.js +4 -2
- package/src/frontends/dart.js +963 -0
- package/src/frontends/index.js +14 -4
- package/src/frontends/java.js +1977 -69
- package/src/frontends/javascript-typescript.js +2046 -102
- package/src/frontends/kotlin.js +713 -0
- package/src/frontends/php.js +1725 -79
- package/src/frontends/program.js +1062 -0
- package/src/frontends/ruby.js +1624 -98
- package/src/frontends/rust-parser.js +18 -0
- package/src/frontends/rust.js +714 -0
- package/src/frontends/scalars.js +31 -1
- package/src/frontends/swift.js +893 -0
- package/src/frontends/types.js +750 -0
- package/src/language-registry.js +182 -12
- package/src/mapping.js +33 -9
- package/src/semantic/capabilities.js +671 -0
- package/src/semantic/effects.js +737 -0
- package/src/semantic/generics.js +58 -0
- package/src/semantic/lifetime.js +517 -0
- package/src/semantic/provenance.js +412 -19
- package/src/semantic/scalars.js +17 -0
- package/src/semantic/stdlib.js +921 -0
- package/src/semantic/types.js +810 -14
- package/src/semantic/validate.js +2934 -209
- package/src/stdlib-facades.js +1211 -0
- package/src/stdlib-negotiation.js +446 -0
- package/src/stdlib-providers.js +377 -0
- package/src/toolchains.js +16 -3
|
@@ -0,0 +1,860 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import Parser from "tree-sitter";
|
|
3
|
+
import SwiftLanguage from "tree-sitter-swift/bindings/node/index.js";
|
|
4
|
+
import { isSwiftIdentifier } from "../backends/identifiers.js";
|
|
5
|
+
import { swiftRuntime } from "../backends/swift-runtime.js";
|
|
6
|
+
import { missingType, SemantifoldDiagnostic, unsupportedSyntax } from "../diagnostic.js";
|
|
7
|
+
import { locationFromOffsets, moduleLocation, utf8ByteOffsetToUtf16Offset } from "../semantic/location.js";
|
|
8
|
+
import { withAdaptedOperation } from "../semantic/operators.js";
|
|
9
|
+
import { withParserRanges } from "../semantic/provenance.js";
|
|
10
|
+
import { hasOnlyUnicodeScalars } from "../semantic/scalars.js";
|
|
11
|
+
import { validateParsedModule } from "../semantic/validate.js";
|
|
12
|
+
import { sourceScalarType } from "./scalars.js";
|
|
13
|
+
const parser = new Parser();
|
|
14
|
+
parser.setLanguage(/** @type {import("tree-sitter").Language} */ ( /** @type {unknown} */(SwiftLanguage)));
|
|
15
|
+
const binaryOperations = new Map([
|
|
16
|
+
["+", "Add"], ["-", "Subtract"], ["*", "Multiply"], ["==", "Equal"], ["!=", "NotEqual"],
|
|
17
|
+
["<", "LessThan"], ["<=", "LessThanOrEqual"], [">", "GreaterThan"], [">=", "GreaterThanOrEqual"],
|
|
18
|
+
["&&", "And"], ["||", "Or"]
|
|
19
|
+
]);
|
|
20
|
+
const binaryNodeOperators = new Map([
|
|
21
|
+
["additive_expression", new Set(["+", "-"])],
|
|
22
|
+
["multiplicative_expression", new Set(["*"])],
|
|
23
|
+
["equality_expression", new Set(["=="])],
|
|
24
|
+
["comparison_expression", new Set(["<", ">"])],
|
|
25
|
+
["conjunction_expression", new Set(["&&"])],
|
|
26
|
+
["disjunction_expression", new Set(["||"])],
|
|
27
|
+
["infix_expression", new Set(["!=", "<=", ">="])]
|
|
28
|
+
]);
|
|
29
|
+
/** @type {Map<string, import("../semantic/operators.js").AdaptedOperation>} */
|
|
30
|
+
const helperOperations = new Map([
|
|
31
|
+
["semantifold_string_equal", "StringEqual"], ["semantifold_string_not_equal", "StringNotEqual"]
|
|
32
|
+
]);
|
|
33
|
+
/**
|
|
34
|
+
* Verifies a Tree-sitter binding index through the shared byte converter.
|
|
35
|
+
* @param {string} source - Complete source.
|
|
36
|
+
* @param {number} index - Binding-reported UTF-16 index.
|
|
37
|
+
* @returns {number} Verified UTF-16 offset.
|
|
38
|
+
*/
|
|
39
|
+
function bindingIndexToUtf16Offset(source, index) {
|
|
40
|
+
if (!Number.isInteger(index) || index < 0 || index > source.length ||
|
|
41
|
+
index > 0 && index < source.length && /[\uD800-\uDBFF]/u.test(source[index - 1]) && /[\uDC00-\uDFFF]/u.test(source[index])) {
|
|
42
|
+
throw new RangeError("Invalid Tree-sitter source index: " + index);
|
|
43
|
+
}
|
|
44
|
+
return utf8ByteOffsetToUtf16Offset(source, new TextEncoder().encode(source.slice(0, index)).length);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Finds an unpaired UTF-16 surrogate.
|
|
48
|
+
* @param {string} source - Complete source.
|
|
49
|
+
* @returns {number} Invalid offset or -1.
|
|
50
|
+
*/
|
|
51
|
+
function firstLoneSurrogateOffset(source) {
|
|
52
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
53
|
+
const unit = source.charCodeAt(index);
|
|
54
|
+
if (unit >= 0xD800 && unit <= 0xDBFF) {
|
|
55
|
+
const next = source.charCodeAt(index + 1);
|
|
56
|
+
if (next >= 0xDC00 && next <= 0xDFFF)
|
|
57
|
+
index += 1;
|
|
58
|
+
else
|
|
59
|
+
return index;
|
|
60
|
+
}
|
|
61
|
+
else if (unit >= 0xDC00 && unit <= 0xDFFF)
|
|
62
|
+
return index;
|
|
63
|
+
}
|
|
64
|
+
return -1;
|
|
65
|
+
}
|
|
66
|
+
/** Consumes exact qualified Swift CST shapes without retaining parser handles. */
|
|
67
|
+
class SwiftReader {
|
|
68
|
+
/**
|
|
69
|
+
* Creates a reader over one parser-owned Swift source.
|
|
70
|
+
* @param {string} filename - Original filename.
|
|
71
|
+
* @param {string} source - Complete source.
|
|
72
|
+
*/
|
|
73
|
+
constructor(filename, source) {
|
|
74
|
+
this.filename = filename;
|
|
75
|
+
this.source = source;
|
|
76
|
+
/** @type {Set<string>} */
|
|
77
|
+
this.helpers = new Set();
|
|
78
|
+
this.mutableMarker = false;
|
|
79
|
+
/** @type {WeakMap<object, import("tree-sitter").SyntaxNode>} */
|
|
80
|
+
this.nativeEqualityOperators = new WeakMap();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Converts one parser range to Semantifold UTF-16 coordinates.
|
|
84
|
+
* @param {import("tree-sitter").SyntaxNode} node - Parser node.
|
|
85
|
+
* @returns {import("../semantic/types.js").SourceLocation} Exact location.
|
|
86
|
+
*/
|
|
87
|
+
location(node) {
|
|
88
|
+
return locationFromOffsets(this.filename, this.source, bindingIndexToUtf16Offset(this.source, node.startIndex), bindingIndexToUtf16Offset(this.source, node.endIndex));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Rejects one located source-profile violation.
|
|
92
|
+
* @param {import("tree-sitter").SyntaxNode} node - Violating node.
|
|
93
|
+
* @param {string} [detail] - Profile detail.
|
|
94
|
+
* @returns {never} Always throws.
|
|
95
|
+
*/
|
|
96
|
+
fail(node, detail = node.type) {
|
|
97
|
+
unsupportedSyntax("swift", detail, this.location(node));
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Traverses every named, anonymous, extra, directive, and recovery node.
|
|
101
|
+
* @param {import("tree-sitter").SyntaxNode} root - Complete parser root.
|
|
102
|
+
* @returns {void}
|
|
103
|
+
*/
|
|
104
|
+
validateTree(root) {
|
|
105
|
+
const pending = [{ depth: 0, node: root, visited: false }];
|
|
106
|
+
while (pending.length) {
|
|
107
|
+
const current = pending.pop();
|
|
108
|
+
if (!current)
|
|
109
|
+
throw new Error("Swift traversal lost a pending parser node.");
|
|
110
|
+
const { depth, node, visited } = current;
|
|
111
|
+
if (depth > 512)
|
|
112
|
+
this.fail(node, "CST exceeds the 512-level traversal limit");
|
|
113
|
+
if (!visited) {
|
|
114
|
+
pending.push({ depth, node, visited: true });
|
|
115
|
+
for (let index = node.childCount - 1; index >= 0; index -= 1) {
|
|
116
|
+
const child = node.child(index);
|
|
117
|
+
if (!child)
|
|
118
|
+
throw new Error(`Tree-sitter omitted child ${index} of ${node.type}.`);
|
|
119
|
+
pending.push({ depth: depth + 1, node: child, visited: false });
|
|
120
|
+
}
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (node.hasError || node.isError || node.isMissing) {
|
|
124
|
+
throw new SemantifoldDiagnostic({
|
|
125
|
+
code: "PARSE_ERROR",
|
|
126
|
+
language: "swift",
|
|
127
|
+
location: this.location(node),
|
|
128
|
+
message: `Tree-sitter exposed recovery at '${node.type}'.`
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
if (["attribute", "directive", "shebang_line"].includes(node.type))
|
|
132
|
+
this.fail(node, node.type);
|
|
133
|
+
if (node.type == "comment" && /swift-tools-version/u.test(node.text)) {
|
|
134
|
+
this.fail(node, "directive-bearing comment");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Omits only inert comments already accounted for by exhaustive traversal.
|
|
140
|
+
* @param {import("tree-sitter").SyntaxNode} node - Parent node.
|
|
141
|
+
* @returns {import("tree-sitter").SyntaxNode[]} Structural children.
|
|
142
|
+
*/
|
|
143
|
+
parts(node) {
|
|
144
|
+
return node.children.filter((child) => child.type != "comment");
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Requires one exact parser field edge.
|
|
148
|
+
* @param {import("tree-sitter").SyntaxNode} node - Field owner.
|
|
149
|
+
* @param {string} name - Field name.
|
|
150
|
+
* @returns {import("tree-sitter").SyntaxNode} Sole field node.
|
|
151
|
+
*/
|
|
152
|
+
field(node, name) {
|
|
153
|
+
const matches = [];
|
|
154
|
+
for (let index = 0; index < node.childCount; index += 1) {
|
|
155
|
+
const child = node.child(index);
|
|
156
|
+
if (!child)
|
|
157
|
+
throw new Error(`Tree-sitter omitted child ${index} of ${node.type}.`);
|
|
158
|
+
if (node.fieldNameForChild(index) == name)
|
|
159
|
+
matches.push(child);
|
|
160
|
+
}
|
|
161
|
+
if (matches.length != 1)
|
|
162
|
+
this.fail(node, `expected one '${name}' field`);
|
|
163
|
+
return matches[0];
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Requires all ordered children, including anonymous punctuation.
|
|
167
|
+
* @param {import("tree-sitter").SyntaxNode} node - Shape owner.
|
|
168
|
+
* @param {(import("tree-sitter").SyntaxNode | string)[]} expected - Exact child sequence.
|
|
169
|
+
* @returns {void}
|
|
170
|
+
*/
|
|
171
|
+
shape(node, expected) {
|
|
172
|
+
const actual = this.parts(node);
|
|
173
|
+
if (actual.length != expected.length)
|
|
174
|
+
this.fail(actual[Math.min(actual.length, expected.length)] ?? node, `${node.type} child shape`);
|
|
175
|
+
for (let index = 0; index < expected.length; index += 1) {
|
|
176
|
+
const wanted = expected[index];
|
|
177
|
+
const child = actual[index];
|
|
178
|
+
const matches = typeof wanted == "string" ? child.text == wanted : child.id == wanted.id;
|
|
179
|
+
if (!matches)
|
|
180
|
+
this.fail(child, `${node.type} child shape`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Validates one Swift identifier in the portable source profile.
|
|
185
|
+
* @param {import("tree-sitter").SyntaxNode} node - Identifier token.
|
|
186
|
+
* @param {boolean} [allowPrint] - Whether the fixed print scaffold is expected.
|
|
187
|
+
* @returns {string} Accepted spelling.
|
|
188
|
+
*/
|
|
189
|
+
identifier(node, allowPrint = false) {
|
|
190
|
+
const name = node.text;
|
|
191
|
+
if (node.type != "simple_identifier" || !(allowPrint && name == "print") &&
|
|
192
|
+
(!isSwiftIdentifier(name) || name.normalize("NFC") != name))
|
|
193
|
+
this.fail(node, "reserved or unsupported identifier");
|
|
194
|
+
return name;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Converts exactly Int64, Bool, or String.
|
|
198
|
+
* @param {import("tree-sitter").SyntaxNode} node - Type node.
|
|
199
|
+
* @returns {import("../semantic/types.js").TypeReference} Semantic scalar.
|
|
200
|
+
*/
|
|
201
|
+
type(node) {
|
|
202
|
+
const parts = this.parts(node);
|
|
203
|
+
if (node.type != "user_type" || parts.length != 1 || parts[0].type != "type_identifier")
|
|
204
|
+
this.fail(node, "scalar type shape");
|
|
205
|
+
this.shape(node, [parts[0]]);
|
|
206
|
+
const type = sourceScalarType("swift", parts[0].text, this.location(parts[0]));
|
|
207
|
+
if (!type)
|
|
208
|
+
this.fail(parts[0], `unsupported scalar type '${parts[0].text}'`);
|
|
209
|
+
return type;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Converts one exact ordinary Swift string literal.
|
|
213
|
+
* @param {import("tree-sitter").SyntaxNode} node - String node.
|
|
214
|
+
* @returns {string} Unicode scalar value.
|
|
215
|
+
*/
|
|
216
|
+
string(node) {
|
|
217
|
+
const parts = this.parts(node);
|
|
218
|
+
if (node.type != "line_string_literal" || parts.length < 2 || parts[0].text != '"' || parts.at(-1)?.text != '"') {
|
|
219
|
+
return this.fail(node, "ordinary noninterpolated string literal required");
|
|
220
|
+
}
|
|
221
|
+
this.shape(node, ['"', ...parts.slice(1, -1), '"']);
|
|
222
|
+
let value = "";
|
|
223
|
+
const simpleEscapes = new Map([
|
|
224
|
+
["\\0", "\0"], ["\\n", "\n"], ["\\r", "\r"], ["\\t", "\t"], ["\\\\", "\\"], ['\\"', '"'], ["\\'", "'"]
|
|
225
|
+
]);
|
|
226
|
+
for (const part of parts.slice(1, -1)) {
|
|
227
|
+
if (part.type == "line_str_text") {
|
|
228
|
+
if (/[\r\n]/u.test(part.text))
|
|
229
|
+
this.fail(part, "string line terminator");
|
|
230
|
+
value += part.text;
|
|
231
|
+
}
|
|
232
|
+
else if (part.type == "str_escaped_char") {
|
|
233
|
+
const escape = part.text;
|
|
234
|
+
if (simpleEscapes.has(escape))
|
|
235
|
+
value += simpleEscapes.get(escape);
|
|
236
|
+
else {
|
|
237
|
+
const match = /^\\u\{([0-9A-Fa-f]{1,8})\}$/u.exec(escape);
|
|
238
|
+
if (!match)
|
|
239
|
+
this.fail(part, "unsupported string escape");
|
|
240
|
+
const scalar = Number.parseInt(match[1], 16);
|
|
241
|
+
if (scalar > 0x10FFFF || scalar >= 0xD800 && scalar <= 0xDFFF)
|
|
242
|
+
this.fail(part, "non-scalar Unicode escape");
|
|
243
|
+
value += String.fromCodePoint(scalar);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else
|
|
247
|
+
this.fail(part, part.type == "interpolated_expression" ? "interpolated string" : "string child");
|
|
248
|
+
}
|
|
249
|
+
if (!hasOnlyUnicodeScalars(value))
|
|
250
|
+
this.fail(node, "invalid Unicode string literal");
|
|
251
|
+
return value;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Reads exact unlabeled call arguments.
|
|
255
|
+
* @param {import("tree-sitter").SyntaxNode} suffix - Call suffix.
|
|
256
|
+
* @returns {import("tree-sitter").SyntaxNode[]} Argument value nodes.
|
|
257
|
+
*/
|
|
258
|
+
arguments(suffix) {
|
|
259
|
+
const suffixParts = this.parts(suffix);
|
|
260
|
+
if (suffix.type != "call_suffix" || suffixParts.length != 1 || suffixParts[0].type != "value_arguments") {
|
|
261
|
+
return this.fail(suffix, "call suffix shape");
|
|
262
|
+
}
|
|
263
|
+
this.shape(suffix, [suffixParts[0]]);
|
|
264
|
+
const list = suffixParts[0];
|
|
265
|
+
const parts = this.parts(list);
|
|
266
|
+
if (parts.length < 2 || parts[0].text != "(" || parts.at(-1)?.text != ")")
|
|
267
|
+
this.fail(list, "call argument list shape");
|
|
268
|
+
const arguments_ = parts.slice(1, -1).filter((_part, index) => index % 2 == 0);
|
|
269
|
+
const expected = ["(", ...arguments_.flatMap((argument, index) => index == 0 ? [argument] : [",", argument]), ")"];
|
|
270
|
+
this.shape(list, expected);
|
|
271
|
+
return arguments_.map((argument) => {
|
|
272
|
+
const value = this.field(argument, "value");
|
|
273
|
+
if (argument.type != "value_argument")
|
|
274
|
+
this.fail(argument, "unlabeled argument required");
|
|
275
|
+
this.shape(argument, [value]);
|
|
276
|
+
return value;
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Converts a direct semantic call, including qualified negated-call and trailing-call binary shapes.
|
|
281
|
+
* @param {import("tree-sitter").SyntaxNode} node - Call node.
|
|
282
|
+
* @returns {import("../semantic/types.js").Expression} Semantic expression.
|
|
283
|
+
*/
|
|
284
|
+
call(node) {
|
|
285
|
+
const location = this.location(node);
|
|
286
|
+
const parts = this.parts(node);
|
|
287
|
+
if (node.type != "call_expression" || parts.length != 2)
|
|
288
|
+
this.fail(node, "direct call shape");
|
|
289
|
+
const target = parts[0];
|
|
290
|
+
const suffix = parts[1];
|
|
291
|
+
if (binaryNodeOperators.has(target.type)) {
|
|
292
|
+
const right = this.field(target, "rhs");
|
|
293
|
+
const callLocation = locationFromOffsets(this.filename, this.source, bindingIndexToUtf16Offset(this.source, right.startIndex), bindingIndexToUtf16Offset(this.source, suffix.endIndex));
|
|
294
|
+
if (right.type != "simple_identifier")
|
|
295
|
+
this.fail(node, "trailing direct call shape");
|
|
296
|
+
this.shape(node, [target, suffix]);
|
|
297
|
+
return this.binary(target, undefined, location, this.callParts(right, suffix, callLocation));
|
|
298
|
+
}
|
|
299
|
+
return this.callParts(target, suffix, location);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Converts one direct call from its parser target and suffix.
|
|
303
|
+
* @param {import("tree-sitter").SyntaxNode} target - Direct call target.
|
|
304
|
+
* @param {import("tree-sitter").SyntaxNode} suffix - Argument suffix.
|
|
305
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Complete call location.
|
|
306
|
+
* @returns {import("../semantic/types.js").Expression} Semantic call or prefixed call.
|
|
307
|
+
*/
|
|
308
|
+
callParts(target, suffix, location) {
|
|
309
|
+
const argumentNodes = this.arguments(suffix);
|
|
310
|
+
let nameNode = target;
|
|
311
|
+
/** @type {import("tree-sitter").SyntaxNode | undefined} */
|
|
312
|
+
let unaryOperator;
|
|
313
|
+
if (["!", "-"].includes(nameNode.text)) {
|
|
314
|
+
if (argumentNodes.length != 1)
|
|
315
|
+
this.fail(target, "parenthesized unary expression shape");
|
|
316
|
+
const expression = this.expression(argumentNodes[0]);
|
|
317
|
+
return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withAdaptedOperation(withParserRanges({
|
|
318
|
+
kind: "UnaryExpression", location, operand: expression
|
|
319
|
+
}, { operator: this.location(nameNode) }), nameNode.text == "-" ? "Negate" : "Not")));
|
|
320
|
+
}
|
|
321
|
+
if (nameNode.type == "prefix_expression") {
|
|
322
|
+
const operation = this.field(nameNode, "operation");
|
|
323
|
+
const target = this.field(nameNode, "target");
|
|
324
|
+
this.shape(nameNode, [operation, target]);
|
|
325
|
+
if (!["!", "-"].includes(operation.text) || target.type != "simple_identifier")
|
|
326
|
+
this.fail(nameNode, "prefixed direct call shape");
|
|
327
|
+
unaryOperator = operation;
|
|
328
|
+
nameNode = target;
|
|
329
|
+
}
|
|
330
|
+
const name = nameNode.text;
|
|
331
|
+
const helperOperation = this.helpers.has(name) ? helperOperations.get(name) : undefined;
|
|
332
|
+
if (helperOperation) {
|
|
333
|
+
if (unaryOperator || argumentNodes.length != 2)
|
|
334
|
+
this.fail(target, "Swift scalar equality helper shape");
|
|
335
|
+
return /** @type {import("../semantic/types.js").Expression} */ (withAdaptedOperation(withParserRanges({
|
|
336
|
+
kind: "BinaryExpression", left: this.expression(argumentNodes[0]), location, right: this.expression(argumentNodes[1])
|
|
337
|
+
}, { operator: this.location(nameNode) }), helperOperation));
|
|
338
|
+
}
|
|
339
|
+
const semanticName = this.identifier(nameNode);
|
|
340
|
+
if (argumentNodes.length != 2)
|
|
341
|
+
this.fail(suffix, "semantic call argument count");
|
|
342
|
+
const call = withParserRanges({
|
|
343
|
+
arguments: argumentNodes.map((argument) => this.expression(argument)),
|
|
344
|
+
callee: semanticName,
|
|
345
|
+
kind: /** @type {const} */ ("CallExpression"),
|
|
346
|
+
location
|
|
347
|
+
}, { callee: this.location(nameNode) });
|
|
348
|
+
if (!unaryOperator)
|
|
349
|
+
return call;
|
|
350
|
+
return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withAdaptedOperation(withParserRanges({
|
|
351
|
+
kind: "UnaryExpression", location, operand: call
|
|
352
|
+
}, { operator: this.location(unaryOperator) }), unaryOperator.text == "-" ? "Negate" : "Not")));
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Converts one supported scalar expression.
|
|
356
|
+
* @param {import("tree-sitter").SyntaxNode} node - Expression node.
|
|
357
|
+
* @returns {import("../semantic/types.js").Expression} Semantic expression.
|
|
358
|
+
*/
|
|
359
|
+
expression(node) {
|
|
360
|
+
const location = this.location(node);
|
|
361
|
+
if (node.type == "simple_identifier") {
|
|
362
|
+
return withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location, name: this.identifier(node) }, { name: location });
|
|
363
|
+
}
|
|
364
|
+
if (node.type == "integer_literal") {
|
|
365
|
+
if (!/^(?:0|[1-9][0-9]*)$/u.test(node.text))
|
|
366
|
+
this.fail(node, "noncanonical integer literal");
|
|
367
|
+
const value = Number(BigInt(node.text));
|
|
368
|
+
if (!Number.isSafeInteger(value))
|
|
369
|
+
this.fail(node, "non-safe integer literal");
|
|
370
|
+
return withParserRanges({ kind: /** @type {const} */ ("IntegerLiteral"), location, value }, { literal: location });
|
|
371
|
+
}
|
|
372
|
+
if (node.type == "boolean_literal") {
|
|
373
|
+
const parts = this.parts(node);
|
|
374
|
+
if (parts.length != 1 || !["true", "false"].includes(parts[0].text))
|
|
375
|
+
this.fail(node, "Boolean literal shape");
|
|
376
|
+
this.shape(node, [parts[0].text]);
|
|
377
|
+
return withParserRanges({ kind: /** @type {const} */ ("BooleanLiteral"), location, value: parts[0].text == "true" }, { literal: location });
|
|
378
|
+
}
|
|
379
|
+
if (node.type == "line_string_literal") {
|
|
380
|
+
return withParserRanges({ kind: /** @type {const} */ ("StringLiteral"), location, value: this.string(node) }, { literal: location });
|
|
381
|
+
}
|
|
382
|
+
if (node.type == "tuple_expression") {
|
|
383
|
+
const value = this.field(node, "value");
|
|
384
|
+
this.shape(node, ["(", value, ")"]);
|
|
385
|
+
return this.expression(value);
|
|
386
|
+
}
|
|
387
|
+
if (node.type == "prefix_expression") {
|
|
388
|
+
const operation = this.field(node, "operation");
|
|
389
|
+
const target = this.field(node, "target");
|
|
390
|
+
this.shape(node, [operation, target]);
|
|
391
|
+
if (!["-", "!"].includes(operation.text))
|
|
392
|
+
this.fail(operation, "unary operator");
|
|
393
|
+
return this.prefixed(operation, target);
|
|
394
|
+
}
|
|
395
|
+
const acceptedOperators = binaryNodeOperators.get(node.type);
|
|
396
|
+
if (acceptedOperators) {
|
|
397
|
+
return this.binary(node);
|
|
398
|
+
}
|
|
399
|
+
if (node.type == "call_expression")
|
|
400
|
+
return this.call(node);
|
|
401
|
+
return this.fail(node);
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Converts the grammar's broad prefix target with Swift's tighter prefix precedence.
|
|
405
|
+
* @param {import("tree-sitter").SyntaxNode} operator - Prefix operator.
|
|
406
|
+
* @param {import("tree-sitter").SyntaxNode} target - Grammar target.
|
|
407
|
+
* @returns {import("../semantic/types.js").Expression} Semantic expression.
|
|
408
|
+
*/
|
|
409
|
+
prefixed(operator, target) {
|
|
410
|
+
const location = locationFromOffsets(this.filename, this.source, bindingIndexToUtf16Offset(this.source, operator.startIndex), bindingIndexToUtf16Offset(this.source, target.endIndex));
|
|
411
|
+
if (binaryNodeOperators.has(target.type)) {
|
|
412
|
+
const left = this.field(target, "lhs");
|
|
413
|
+
return this.binary(target, this.prefixed(operator, left), location);
|
|
414
|
+
}
|
|
415
|
+
return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withAdaptedOperation(withParserRanges({
|
|
416
|
+
kind: "UnaryExpression", location, operand: this.expression(target)
|
|
417
|
+
}, { operator: this.location(operator) }), operator.text == "-" ? "Negate" : "Not")));
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Converts one qualified binary node, optionally replacing its left edge for prefix precedence.
|
|
421
|
+
* @param {import("tree-sitter").SyntaxNode} node - Binary node.
|
|
422
|
+
* @param {import("../semantic/types.js").Expression} [leftExpression] - Adapted left operand.
|
|
423
|
+
* @param {import("../semantic/types.js").SourceLocation} [location] - Adapted expression range.
|
|
424
|
+
* @param {import("../semantic/types.js").Expression} [rightExpression] - Adapted trailing-call right operand.
|
|
425
|
+
* @returns {import("../semantic/types.js").Expression} Semantic expression.
|
|
426
|
+
*/
|
|
427
|
+
binary(node, leftExpression, location = this.location(node), rightExpression) {
|
|
428
|
+
const acceptedOperators = binaryNodeOperators.get(node.type);
|
|
429
|
+
const left = this.field(node, "lhs");
|
|
430
|
+
const operator = this.field(node, "op");
|
|
431
|
+
const right = this.field(node, "rhs");
|
|
432
|
+
const operation = binaryOperations.get(operator.text);
|
|
433
|
+
this.shape(node, [left, operator, right]);
|
|
434
|
+
if (!acceptedOperators?.has(operator.text) || !operation)
|
|
435
|
+
this.fail(operator, "unsupported binary operator");
|
|
436
|
+
const expression = /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withAdaptedOperation(withParserRanges({
|
|
437
|
+
kind: "BinaryExpression", left: leftExpression ?? this.expression(left), location, right: rightExpression ?? this.expression(right)
|
|
438
|
+
}, { operator: this.location(operator) }), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (operation))));
|
|
439
|
+
if (["==", "!="].includes(operator.text))
|
|
440
|
+
this.nativeEqualityOperators.set(expression, operator);
|
|
441
|
+
return expression;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Converts one explicitly typed initialized local.
|
|
445
|
+
* @param {import("tree-sitter").SyntaxNode} node - Property declaration.
|
|
446
|
+
* @returns {import("../semantic/types.js").LocalDeclaration} Semantic local.
|
|
447
|
+
*/
|
|
448
|
+
local(node) {
|
|
449
|
+
const location = this.location(node);
|
|
450
|
+
const parts = this.parts(node);
|
|
451
|
+
const binding = parts.find((child) => child.type == "value_binding_pattern");
|
|
452
|
+
const pattern = node.childForFieldName("name");
|
|
453
|
+
const annotation = parts.find((child) => child.type == "type_annotation");
|
|
454
|
+
const value = node.childForFieldName("value");
|
|
455
|
+
if (!annotation)
|
|
456
|
+
return missingType("swift", "Local", location);
|
|
457
|
+
if (!binding || !pattern || !value || pattern.type != "pattern")
|
|
458
|
+
this.fail(node, "local declaration shape");
|
|
459
|
+
const bindingParts = this.parts(binding);
|
|
460
|
+
const nameNode = pattern.childForFieldName("bound_identifier");
|
|
461
|
+
const annotationParts = this.parts(annotation);
|
|
462
|
+
if (bindingParts.length != 1 || !["let", "var"].includes(bindingParts[0].text) || !nameNode || annotationParts.length != 2) {
|
|
463
|
+
this.fail(node, "local declaration shape");
|
|
464
|
+
}
|
|
465
|
+
this.shape(binding, [bindingParts[0].text]);
|
|
466
|
+
this.shape(pattern, [nameNode]);
|
|
467
|
+
this.shape(annotation, [":", annotationParts[1]]);
|
|
468
|
+
this.shape(node, [binding, pattern, annotation, "=", value]);
|
|
469
|
+
const name = this.identifier(nameNode);
|
|
470
|
+
return withParserRanges({
|
|
471
|
+
initializer: this.expression(value),
|
|
472
|
+
kind: /** @type {const} */ ("LocalDeclaration"),
|
|
473
|
+
location,
|
|
474
|
+
mutable: bindingParts[0].text == "var",
|
|
475
|
+
name,
|
|
476
|
+
type: this.type(annotationParts[1])
|
|
477
|
+
}, { name: this.location(nameNode), operator: this.location(parts[3]) });
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Converts one plain identifier assignment.
|
|
481
|
+
* @param {import("tree-sitter").SyntaxNode} node - Assignment node.
|
|
482
|
+
* @returns {import("../semantic/types.js").AssignmentStatement} Semantic assignment.
|
|
483
|
+
*/
|
|
484
|
+
assignment(node) {
|
|
485
|
+
const target = this.field(node, "target");
|
|
486
|
+
const operator = this.field(node, "operator");
|
|
487
|
+
const value = this.field(node, "result");
|
|
488
|
+
const targetParts = this.parts(target);
|
|
489
|
+
if (target.type != "directly_assignable_expression" || targetParts.length != 1 || operator.text != "=") {
|
|
490
|
+
this.fail(node, "assignment shape");
|
|
491
|
+
}
|
|
492
|
+
this.shape(target, [targetParts[0]]);
|
|
493
|
+
this.shape(node, [target, operator, value]);
|
|
494
|
+
const name = this.identifier(targetParts[0]);
|
|
495
|
+
const targetLocation = this.location(targetParts[0]);
|
|
496
|
+
return withParserRanges({
|
|
497
|
+
expression: this.expression(value),
|
|
498
|
+
kind: /** @type {const} */ ("AssignmentStatement"),
|
|
499
|
+
location: this.location(node),
|
|
500
|
+
target: withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: targetLocation, name }, { name: targetLocation })
|
|
501
|
+
}, { operator: this.location(operator) });
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Converts one exact print call.
|
|
505
|
+
* @param {import("tree-sitter").SyntaxNode} node - Call statement.
|
|
506
|
+
* @returns {import("../semantic/types.js").PrintStatement} Semantic print.
|
|
507
|
+
*/
|
|
508
|
+
print(node) {
|
|
509
|
+
const parts = this.parts(node);
|
|
510
|
+
if (node.type != "call_expression" || parts.length != 2 || parts[0].type != "simple_identifier" ||
|
|
511
|
+
this.identifier(parts[0], true) != "print")
|
|
512
|
+
this.fail(node, "exact print call required");
|
|
513
|
+
const arguments_ = this.arguments(parts[1]);
|
|
514
|
+
if (arguments_.length != 1)
|
|
515
|
+
this.fail(parts[1], "print argument count");
|
|
516
|
+
return { expression: this.expression(arguments_[0]), kind: /** @type {const} */ ("PrintStatement"), location: this.location(node) };
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Converts one supported statement.
|
|
520
|
+
* @param {import("tree-sitter").SyntaxNode} node - Statement node.
|
|
521
|
+
* @returns {import("../semantic/types.js").Statement} Semantic statement.
|
|
522
|
+
*/
|
|
523
|
+
statement(node) {
|
|
524
|
+
if (node.type == "property_declaration")
|
|
525
|
+
return this.local(node);
|
|
526
|
+
if (node.type == "assignment")
|
|
527
|
+
return this.assignment(node);
|
|
528
|
+
if (node.type == "if_statement")
|
|
529
|
+
return this.conditional(node);
|
|
530
|
+
if (node.type == "call_expression")
|
|
531
|
+
return this.print(node);
|
|
532
|
+
if (node.type == "control_transfer_statement") {
|
|
533
|
+
const result = node.childForFieldName("result");
|
|
534
|
+
if (!result)
|
|
535
|
+
this.fail(node, "return without expression");
|
|
536
|
+
this.shape(node, ["return", result]);
|
|
537
|
+
return { expression: this.expression(result), kind: /** @type {const} */ ("ReturnStatement"), location: this.location(node) };
|
|
538
|
+
}
|
|
539
|
+
return this.fail(node);
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Converts one parser statements node.
|
|
543
|
+
* @param {import("tree-sitter").SyntaxNode | undefined} node - Optional statements node.
|
|
544
|
+
* @returns {import("../semantic/types.js").Statement[]} Ordered statements.
|
|
545
|
+
*/
|
|
546
|
+
statements(node) {
|
|
547
|
+
if (!node)
|
|
548
|
+
return [];
|
|
549
|
+
if (node.type != "statements")
|
|
550
|
+
this.fail(node, "statement list shape");
|
|
551
|
+
return this.statementList(this.parts(node));
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Converts a statement sequence while collapsing an adjacent generated marker.
|
|
555
|
+
* @param {import("tree-sitter").SyntaxNode[]} nodes - Ordered statement nodes.
|
|
556
|
+
* @returns {import("../semantic/types.js").Statement[]} Semantic statements.
|
|
557
|
+
*/
|
|
558
|
+
statementList(nodes) {
|
|
559
|
+
/** @type {import("../semantic/types.js").Statement[]} */
|
|
560
|
+
const statements = [];
|
|
561
|
+
for (const statement of nodes) {
|
|
562
|
+
const parts = this.parts(statement);
|
|
563
|
+
const marker = statement.type == "call_expression" && parts[0]?.text == "semantifold_keep_mutable";
|
|
564
|
+
if (marker) {
|
|
565
|
+
const previous = statements.at(-1);
|
|
566
|
+
if (!previous || previous.kind != "LocalDeclaration" || !previous.mutable)
|
|
567
|
+
this.fail(statement, "Swift mutable-local warning marker");
|
|
568
|
+
this.mutableMarkerCall(statement, previous);
|
|
569
|
+
}
|
|
570
|
+
else
|
|
571
|
+
statements.push(this.statement(statement));
|
|
572
|
+
}
|
|
573
|
+
return statements;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Collapses the generated inout call only beside its declared mutable local.
|
|
577
|
+
* @param {import("tree-sitter").SyntaxNode} node - Generated marker call.
|
|
578
|
+
* @param {import("../semantic/types.js").LocalDeclaration} local - Preceding local.
|
|
579
|
+
* @returns {void}
|
|
580
|
+
*/
|
|
581
|
+
mutableMarkerCall(node, local) {
|
|
582
|
+
const parts = this.parts(node);
|
|
583
|
+
const arguments_ = parts.length == 2 ? this.arguments(parts[1]) : [];
|
|
584
|
+
const argument = arguments_[0];
|
|
585
|
+
const target = argument?.type == "prefix_expression" ? this.field(argument, "target") : undefined;
|
|
586
|
+
if (!this.mutableMarker || parts[0]?.type != "simple_identifier" || parts[0].text != "semantifold_keep_mutable" ||
|
|
587
|
+
arguments_.length != 1 || !target || target.type != "simple_identifier" || target.text != local.name) {
|
|
588
|
+
this.fail(node, "Swift mutable-local warning marker");
|
|
589
|
+
}
|
|
590
|
+
this.shape(node, [parts[0], parts[1]]);
|
|
591
|
+
this.shape(argument, ["&", target]);
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Converts one exact braced conditional, including direct else-if.
|
|
595
|
+
* @param {import("tree-sitter").SyntaxNode} node - If node.
|
|
596
|
+
* @returns {import("../semantic/types.js").IfStatement} Semantic conditional.
|
|
597
|
+
*/
|
|
598
|
+
conditional(node) {
|
|
599
|
+
const parts = this.parts(node);
|
|
600
|
+
const condition = this.field(node, "condition");
|
|
601
|
+
let index = 3;
|
|
602
|
+
const consequentStatements = parts[index]?.type == "statements" ? parts[index++] : undefined;
|
|
603
|
+
if (node.type != "if_statement" || parts[0]?.text != "if" || parts[1]?.id != condition.id || parts[2]?.text != "{" ||
|
|
604
|
+
parts[index]?.text != "}")
|
|
605
|
+
this.fail(node, "if statement shape");
|
|
606
|
+
index += 1;
|
|
607
|
+
const statement = {
|
|
608
|
+
condition: this.expression(condition),
|
|
609
|
+
consequent: { kind: /** @type {const} */ ("Block"), location: this.location(consequentStatements ?? node),
|
|
610
|
+
statements: this.statements(consequentStatements) },
|
|
611
|
+
kind: /** @type {const} */ ("IfStatement"),
|
|
612
|
+
location: this.location(node)
|
|
613
|
+
};
|
|
614
|
+
if (index == parts.length) {
|
|
615
|
+
this.shape(node, ["if", condition, "{", ...(consequentStatements ? [consequentStatements] : []), "}"]);
|
|
616
|
+
return statement;
|
|
617
|
+
}
|
|
618
|
+
if (parts[index]?.text != "else")
|
|
619
|
+
this.fail(parts[index] ?? node, "if alternate shape");
|
|
620
|
+
index += 1;
|
|
621
|
+
const branch = parts[index];
|
|
622
|
+
if (branch?.type == "if_statement" && index + 1 == parts.length) {
|
|
623
|
+
this.shape(node, ["if", condition, "{", ...(consequentStatements ? [consequentStatements] : []), "}", "else", branch]);
|
|
624
|
+
return { ...statement, alternate: { kind: /** @type {const} */ ("Block"), location: this.location(branch), statements: [this.conditional(branch)] } };
|
|
625
|
+
}
|
|
626
|
+
if (branch?.text != "{")
|
|
627
|
+
this.fail(branch ?? node, "if alternate block shape");
|
|
628
|
+
index += 1;
|
|
629
|
+
const alternateStatements = parts[index]?.type == "statements" ? parts[index++] : undefined;
|
|
630
|
+
if (parts[index]?.text != "}" || index + 1 != parts.length)
|
|
631
|
+
this.fail(parts[index] ?? node, "if alternate block shape");
|
|
632
|
+
this.shape(node, ["if", condition, "{", ...(consequentStatements ? [consequentStatements] : []), "}", "else", "{",
|
|
633
|
+
...(alternateStatements ? [alternateStatements] : []), "}"]);
|
|
634
|
+
return { ...statement, alternate: { kind: /** @type {const} */ ("Block"), location: this.location(alternateStatements ?? node),
|
|
635
|
+
statements: this.statements(alternateStatements) } };
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Converts one function body.
|
|
639
|
+
* @param {import("tree-sitter").SyntaxNode} node - Function body.
|
|
640
|
+
* @returns {import("../semantic/types.js").Block} Semantic block.
|
|
641
|
+
*/
|
|
642
|
+
block(node) {
|
|
643
|
+
const parts = this.parts(node);
|
|
644
|
+
const statements = parts[1]?.type == "statements" ? parts[1] : undefined;
|
|
645
|
+
if (node.type != "function_body")
|
|
646
|
+
this.fail(node, "function body shape");
|
|
647
|
+
this.shape(node, ["{", ...(statements ? [statements] : []), "}"]);
|
|
648
|
+
return { kind: /** @type {const} */ ("Block"), location: this.location(node), statements: this.statements(statements) };
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Converts one exact underscore-labeled parameter.
|
|
652
|
+
* @param {import("tree-sitter").SyntaxNode} node - Parameter node.
|
|
653
|
+
* @returns {import("../semantic/types.js").Parameter} Semantic parameter.
|
|
654
|
+
*/
|
|
655
|
+
parameter(node) {
|
|
656
|
+
const parts = this.parts(node);
|
|
657
|
+
if (node.type != "parameter" || parts.length != 4 || parts[0].text != "_" || parts[0].type != "simple_identifier" ||
|
|
658
|
+
parts[1].type != "simple_identifier" || parts[2].text != ":")
|
|
659
|
+
this.fail(node, "parameter shape");
|
|
660
|
+
this.shape(node, [parts[0], parts[1], ":", parts[3]]);
|
|
661
|
+
const name = this.identifier(parts[1]);
|
|
662
|
+
return withParserRanges({ kind: /** @type {const} */ ("Parameter"), location: this.location(node), name, type: this.type(parts[3]) }, {
|
|
663
|
+
name: this.location(parts[1])
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Converts one synchronous top-level scalar function.
|
|
668
|
+
* @param {import("tree-sitter").SyntaxNode} node - Function node.
|
|
669
|
+
* @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
|
|
670
|
+
*/
|
|
671
|
+
function(node) {
|
|
672
|
+
const parts = this.parts(node);
|
|
673
|
+
const nameNode = node.childForFieldName("name");
|
|
674
|
+
const body = node.childForFieldName("body");
|
|
675
|
+
const parameters = parts.filter((part) => part.type == "parameter");
|
|
676
|
+
if (!nameNode || !body || node.type != "function_declaration")
|
|
677
|
+
this.fail(node, "function declaration shape");
|
|
678
|
+
if (parameters.length != 2)
|
|
679
|
+
this.fail(node, "function parameter count other than two");
|
|
680
|
+
if (!parts.some((part) => part.text == "->"))
|
|
681
|
+
return missingType("swift", "Function return", this.location(node));
|
|
682
|
+
if (parts.length != 10)
|
|
683
|
+
this.fail(parts.find((part) => !["func", "(", ",", ")", "->"].includes(part.text) &&
|
|
684
|
+
part.id != nameNode.id && part.id != body.id && !parameters.some((parameter) => parameter.id == part.id)) ?? node, "function declaration shape");
|
|
685
|
+
const returnType = parts[8];
|
|
686
|
+
this.shape(node, ["func", nameNode, "(", parameters[0], ",", parameters[1], ")", "->", returnType, body]);
|
|
687
|
+
const name = this.identifier(nameNode);
|
|
688
|
+
return withParserRanges({
|
|
689
|
+
body: this.block(body),
|
|
690
|
+
kind: /** @type {const} */ ("FunctionDeclaration"),
|
|
691
|
+
location: this.location(node),
|
|
692
|
+
name,
|
|
693
|
+
parameters: parameters.map((parameter) => this.parameter(parameter)),
|
|
694
|
+
returnType: this.type(returnType)
|
|
695
|
+
}, { name: this.location(nameNode) });
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Compares every child field and leaf token against target-only canonical support.
|
|
699
|
+
* @param {import("tree-sitter").SyntaxNode} actual - Source support node.
|
|
700
|
+
* @param {import("tree-sitter").SyntaxNode} expected - Canonical support node.
|
|
701
|
+
* @param {SwiftReader} canonical - Canonical source reader.
|
|
702
|
+
* @returns {void}
|
|
703
|
+
*/
|
|
704
|
+
compareTree(actual, expected, canonical) {
|
|
705
|
+
if (actual.type != expected.type || actual.isNamed != expected.isNamed || actual.isExtra != expected.isExtra ||
|
|
706
|
+
actual.childCount != expected.childCount)
|
|
707
|
+
this.fail(actual, "modified Swift support node");
|
|
708
|
+
if (!actual.childCount && actual.text != expected.text)
|
|
709
|
+
this.fail(actual, "modified Swift support token");
|
|
710
|
+
for (let index = 0; index < actual.childCount; index += 1) {
|
|
711
|
+
const left = actual.child(index);
|
|
712
|
+
const right = expected.child(index);
|
|
713
|
+
if (!left || !right || actual.fieldNameForChild(index) != expected.fieldNameForChild(index)) {
|
|
714
|
+
this.fail(left ?? actual, "modified Swift support field");
|
|
715
|
+
}
|
|
716
|
+
this.compareTree(left, right, canonical);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Rejects ordinary Swift equality after shared type resolution identifies Strings.
|
|
721
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Validated semantic module.
|
|
722
|
+
* @returns {void}
|
|
723
|
+
*/
|
|
724
|
+
rejectNativeStringEquality(module) {
|
|
725
|
+
const pending = [module.entryPoint.body, ...module.functions.map((declaration) => declaration.body)];
|
|
726
|
+
while (pending.length) {
|
|
727
|
+
const block = pending.pop();
|
|
728
|
+
if (!block)
|
|
729
|
+
throw new Error("Swift semantic traversal lost a pending block.");
|
|
730
|
+
for (const statement of block.statements) {
|
|
731
|
+
if (statement.kind == "IfStatement") {
|
|
732
|
+
pending.push(statement.consequent);
|
|
733
|
+
if (statement.alternate)
|
|
734
|
+
pending.push(statement.alternate);
|
|
735
|
+
this.rejectNativeStringEqualityExpression(statement.condition);
|
|
736
|
+
}
|
|
737
|
+
else if (statement.kind == "LocalDeclaration")
|
|
738
|
+
this.rejectNativeStringEqualityExpression(statement.initializer);
|
|
739
|
+
else if (statement.kind == "AssignmentStatement")
|
|
740
|
+
this.rejectNativeStringEqualityExpression(statement.expression);
|
|
741
|
+
else if (statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement") {
|
|
742
|
+
this.rejectNativeStringEqualityExpression(statement.expression);
|
|
743
|
+
}
|
|
744
|
+
else if (statement.kind == "ReturnStatement" && statement.expression) {
|
|
745
|
+
this.rejectNativeStringEqualityExpression(statement.expression);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Checks one validated expression without retaining parser state in public values.
|
|
752
|
+
* @param {import("../semantic/types.js").Expression} root - Validated expression.
|
|
753
|
+
* @returns {void}
|
|
754
|
+
*/
|
|
755
|
+
rejectNativeStringEqualityExpression(root) {
|
|
756
|
+
const pending = [root];
|
|
757
|
+
while (pending.length) {
|
|
758
|
+
const expression = pending.pop();
|
|
759
|
+
if (!expression)
|
|
760
|
+
throw new Error("Swift semantic traversal lost a pending expression.");
|
|
761
|
+
if (expression.kind == "BinaryExpression") {
|
|
762
|
+
const operator = this.nativeEqualityOperators.get(expression);
|
|
763
|
+
if (operator && ["StringEqual", "StringNotEqual"].includes(expression.operation)) {
|
|
764
|
+
this.fail(operator, "ordinary Swift String equality");
|
|
765
|
+
}
|
|
766
|
+
pending.push(expression.left, expression.right);
|
|
767
|
+
}
|
|
768
|
+
else if (expression.kind == "UnaryExpression")
|
|
769
|
+
pending.push(expression.operand);
|
|
770
|
+
else if (expression.kind == "CallExpression")
|
|
771
|
+
pending.push(...expression.arguments);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Converts the complete source file with declarations before top-level entry statements.
|
|
776
|
+
* @param {import("tree-sitter").SyntaxNode} root - Source root.
|
|
777
|
+
* @returns {import("../semantic/types.js").SemanticModule} Semantic module.
|
|
778
|
+
*/
|
|
779
|
+
module(root) {
|
|
780
|
+
this.validateTree(root);
|
|
781
|
+
if (root.type != "source_file")
|
|
782
|
+
this.fail(root, "source file root");
|
|
783
|
+
const parts = this.parts(root);
|
|
784
|
+
const canonical = new SwiftReader(this.filename, swiftRuntime);
|
|
785
|
+
const support = canonical.parts(parser.parse(swiftRuntime).rootNode);
|
|
786
|
+
let supportIndex = 0;
|
|
787
|
+
while (supportIndex < parts.length && supportIndex < support.length) {
|
|
788
|
+
const node = parts[supportIndex];
|
|
789
|
+
const name = node.type == "function_declaration" ? node.childForFieldName("name") : undefined;
|
|
790
|
+
const expectedName = support[supportIndex].childForFieldName("name");
|
|
791
|
+
if (!name || !expectedName || name.text != expectedName.text)
|
|
792
|
+
break;
|
|
793
|
+
this.compareTree(node, support[supportIndex], canonical);
|
|
794
|
+
if (helperOperations.has(name.text))
|
|
795
|
+
this.helpers.add(name.text);
|
|
796
|
+
else if (name.text == "semantifold_keep_mutable")
|
|
797
|
+
this.mutableMarker = true;
|
|
798
|
+
supportIndex += 1;
|
|
799
|
+
}
|
|
800
|
+
if (supportIndex > 0 && supportIndex != support.length)
|
|
801
|
+
this.fail(parts[supportIndex - 1], "complete Swift support required");
|
|
802
|
+
const semanticParts = parts.slice(supportIndex);
|
|
803
|
+
const firstEntry = semanticParts.findIndex((node) => node.type != "function_declaration");
|
|
804
|
+
const split = firstEntry < 0 ? semanticParts.length : firstEntry;
|
|
805
|
+
const declarations = semanticParts.slice(0, split);
|
|
806
|
+
const entries = semanticParts.slice(split);
|
|
807
|
+
if (!declarations.length)
|
|
808
|
+
this.fail(root, "top-level semantic function required");
|
|
809
|
+
const laterFunction = entries.find((node) => node.type == "function_declaration");
|
|
810
|
+
const unsupportedEntry = entries.find((node) => !["assignment", "call_expression", "control_transfer_statement", "if_statement",
|
|
811
|
+
"property_declaration", "function_declaration"].includes(node.type));
|
|
812
|
+
if (unsupportedEntry)
|
|
813
|
+
this.fail(unsupportedEntry);
|
|
814
|
+
if (laterFunction)
|
|
815
|
+
this.fail(laterFunction, "function declaration after entry statement");
|
|
816
|
+
if (!entries.length)
|
|
817
|
+
this.fail(root, "top-level entry/print shell required");
|
|
818
|
+
const module = {
|
|
819
|
+
entryPoint: { body: { kind: /** @type {const} */ ("Block"), location: this.location(root),
|
|
820
|
+
statements: this.statementList(entries) }, kind: /** @type {const} */ ("EntryPoint"), location: this.location(root) },
|
|
821
|
+
functions: declarations.map((declaration) => this.function(declaration)),
|
|
822
|
+
kind: /** @type {const} */ ("Module"),
|
|
823
|
+
location: this.location(root)
|
|
824
|
+
};
|
|
825
|
+
validateParsedModule(module, "swift");
|
|
826
|
+
this.rejectNativeStringEquality(module);
|
|
827
|
+
return module;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Parses the strict Task 022 Swift profile through the qualified grammar.
|
|
832
|
+
* @param {{filename: string, source: string}} input - Exact source request.
|
|
833
|
+
* @returns {import("../semantic/types.js").SemanticModule} Semantic module.
|
|
834
|
+
*/
|
|
835
|
+
export function parseSwift({ filename, source }) {
|
|
836
|
+
if (!hasOnlyUnicodeScalars(source)) {
|
|
837
|
+
const offset = firstLoneSurrogateOffset(source);
|
|
838
|
+
throw new SemantifoldDiagnostic({
|
|
839
|
+
code: "PARSE_ERROR",
|
|
840
|
+
language: "swift",
|
|
841
|
+
location: locationFromOffsets(filename, source, offset, offset + 1),
|
|
842
|
+
message: "Swift source contains an invalid lone UTF-16 surrogate."
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
let tree;
|
|
846
|
+
try {
|
|
847
|
+
tree = parser.parse(source);
|
|
848
|
+
}
|
|
849
|
+
catch (error) {
|
|
850
|
+
throw new SemantifoldDiagnostic({
|
|
851
|
+
cause: error instanceof Error ? error : undefined,
|
|
852
|
+
code: "PARSE_ERROR",
|
|
853
|
+
language: "swift",
|
|
854
|
+
location: moduleLocation(filename, source),
|
|
855
|
+
message: "The qualified Swift parser could not produce a complete CST."
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
return new SwiftReader(filename, source).module(tree.rootNode);
|
|
859
|
+
}
|
|
860
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3dpZnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZnJvbnRlbmRzL3N3aWZ0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUE7QUFDaEMsT0FBTyxhQUFhLE1BQU0sMENBQTBDLENBQUE7QUFDcEUsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sNEJBQTRCLENBQUE7QUFDNUQsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLDhCQUE4QixDQUFBO0FBQ3pELE9BQU8sRUFBQyxXQUFXLEVBQUUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUN0RixPQUFPLEVBQUMsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLDJCQUEyQixFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDeEcsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDN0QsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sMkJBQTJCLENBQUE7QUFDMUQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sd0JBQXdCLENBQUE7QUFDNUQsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDNUQsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sY0FBYyxDQUFBO0FBRTdDLE1BQU0sTUFBTSxHQUFHLElBQUksTUFBTSxFQUFFLENBQUE7QUFFM0IsTUFBTSxDQUFDLFdBQVcsQ0FBQyw2Q0FBNkMsQ0FBQyxFQUFDLHNCQUF1QixDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQTtBQUUxRyxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQy9CLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUMsSUFBSSxF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QyxNQUFNLENBQUMsQ0FBQTtRQUUvQyxNQUFNLElBQUkscUJBQXFCLENBQUM7WUFDOUIsSUFBSSxFQUFFLGFBQWE7WUFDbkIsUUFBUSxFQUFFLE9BQU87WUFDakIsUUFBUSxFQUFFLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFDbkUsT0FBTyxFQUFFLHlEQUF5RDtTQUNuRSxDQUFDLENBQUE7SUFDSixDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUE7SUFFUixJQUFJLENBQUM7UUFDSCxJQUFJLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUM3QixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sSUFBSSxxQkFBcUIsQ0FBQztZQUM5QixLQUFLLEVBQUUsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTO1lBQ2pELElBQUksRUFBRSxhQUFhO1lBQ25CLFFBQVEsRUFBRSxPQUFPO1lBQ2pCLFFBQVEsRUFBRSxjQUFjLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQztZQUMxQyxPQUFPLEVBQUUsOERBQThEO1NBQ3hFLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFDRCxPQUFPLElBQUksV0FBVyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0FBQ2hFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IFBhcnNlciBmcm9tIFwidHJlZS1zaXR0ZXJcIlxuaW1wb3J0IFN3aWZ0TGFuZ3VhZ2UgZnJvbSBcInRyZWUtc2l0dGVyLXN3aWZ0L2JpbmRpbmdzL25vZGUvaW5kZXguanNcIlxuaW1wb3J0IHtpc1N3aWZ0SWRlbnRpZmllcn0gZnJvbSBcIi4uL2JhY2tlbmRzL2lkZW50aWZpZXJzLmpzXCJcbmltcG9ydCB7c3dpZnRSdW50aW1lfSBmcm9tIFwiLi4vYmFja2VuZHMvc3dpZnQtcnVudGltZS5qc1wiXG5pbXBvcnQge21pc3NpbmdUeXBlLCBTZW1hbnRpZm9sZERpYWdub3N0aWMsIHVuc3VwcG9ydGVkU3ludGF4fSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge2xvY2F0aW9uRnJvbU9mZnNldHMsIG1vZHVsZUxvY2F0aW9uLCB1dGY4Qnl0ZU9mZnNldFRvVXRmMTZPZmZzZXR9IGZyb20gXCIuLi9zZW1hbnRpYy9sb2NhdGlvbi5qc1wiXG5pbXBvcnQge3dpdGhBZGFwdGVkT3BlcmF0aW9ufSBmcm9tIFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCJcbmltcG9ydCB7d2l0aFBhcnNlclJhbmdlc30gZnJvbSBcIi4uL3NlbWFudGljL3Byb3ZlbmFuY2UuanNcIlxuaW1wb3J0IHtoYXNPbmx5VW5pY29kZVNjYWxhcnN9IGZyb20gXCIuLi9zZW1hbnRpYy9zY2FsYXJzLmpzXCJcbmltcG9ydCB7dmFsaWRhdGVQYXJzZWRNb2R1bGV9IGZyb20gXCIuLi9zZW1hbnRpYy92YWxpZGF0ZS5qc1wiXG5pbXBvcnQge3NvdXJjZVNjYWxhclR5cGV9IGZyb20gXCIuL3NjYWxhcnMuanNcIlxuXG5jb25zdCBwYXJzZXIgPSBuZXcgUGFyc2VyKClcblxucGFyc2VyLnNldExhbmd1YWdlKC8qKiBAdHlwZSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuTGFuZ3VhZ2V9ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChTd2lmdExhbmd1YWdlKSkpXG5cbmNvbnN0IGJpbmFyeU9wZXJhdGlvbnMgPSBuZXcgTWFwKFtcbiAgW1wiK1wiLCBcIkFkZFwiXSwgW1wiLVwiLCBcIlN1YnRyYWN0XCJdLCBbXCIqXCIsIFwiTXVsdGlwbHlcIl0sIFtcIj09XCIsIFwiRXF1YWxcIl0sIFtcIiE9XCIsIFwiTm90RXF1YWxcIl0sXG4gIFtcIjxcIiwgXCJMZXNzVGhhblwiXSwgW1wiPD1cIiwgXCJMZXNzVGhhbk9yRXF1YWxcIl0sIFtcIj5cIiwgXCJHcmVhdGVyVGhhblwiXSwgW1wiPj1cIiwgXCJHcmVhdGVyVGhhbk9yRXF1YWxcIl0sXG4gIFtcIiYmXCIsIFwiQW5kXCJdLCBbXCJ8fFwiLCBcIk9yXCJdXG5dKVxuY29uc3QgYmluYXJ5Tm9kZU9wZXJhdG9ycyA9IG5ldyBNYXAoW1xuICBbXCJhZGRpdGl2ZV9leHByZXNzaW9uXCIsIG5ldyBTZXQoW1wiK1wiLCBcIi1cIl0pXSxcbiAgW1wibXVsdGlwbGljYXRpdmVfZXhwcmVzc2lvblwiLCBuZXcgU2V0KFtcIipcIl0pXSxcbiAgW1wiZXF1YWxpdHlfZXhwcmVzc2lvblwiLCBuZXcgU2V0KFtcIj09XCJdKV0sXG4gIFtcImNvbXBhcmlzb25fZXhwcmVzc2lvblwiLCBuZXcgU2V0KFtcIjxcIiwgXCI+XCJdKV0sXG4gIFtcImNvbmp1bmN0aW9uX2V4cHJlc3Npb25cIiwgbmV3IFNldChbXCImJlwiXSldLFxuICBbXCJkaXNqdW5jdGlvbl9leHByZXNzaW9uXCIsIG5ldyBTZXQoW1wifHxcIl0pXSxcbiAgW1wiaW5maXhfZXhwcmVzc2lvblwiLCBuZXcgU2V0KFtcIiE9XCIsIFwiPD1cIiwgXCI+PVwiXSldXG5dKVxuLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIikuQWRhcHRlZE9wZXJhdGlvbj59ICovXG5jb25zdCBoZWxwZXJPcGVyYXRpb25zID0gbmV3IE1hcChbXG4gIFtcInNlbWFudGlmb2xkX3N0cmluZ19lcXVhbFwiLCBcIlN0cmluZ0VxdWFsXCJdLCBbXCJzZW1hbnRpZm9sZF9zdHJpbmdfbm90X2VxdWFsXCIsIFwiU3RyaW5nTm90RXF1YWxcIl1cbl0pXG4vKipcbiAqIFZlcmlmaWVzIGEgVHJlZS1zaXR0ZXIgYmluZGluZyBpbmRleCB0aHJvdWdoIHRoZSBzaGFyZWQgYnl0ZSBjb252ZXJ0ZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gQmluZGluZy1yZXBvcnRlZCBVVEYtMTYgaW5kZXguXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWZXJpZmllZCBVVEYtMTYgb2Zmc2V0LlxuICovXG5mdW5jdGlvbiBiaW5kaW5nSW5kZXhUb1V0ZjE2T2Zmc2V0KHNvdXJjZSwgaW5kZXgpIHtcbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGluZGV4KSB8fCBpbmRleCA8IDAgfHwgaW5kZXggPiBzb3VyY2UubGVuZ3RoIHx8XG4gICAgaW5kZXggPiAwICYmIGluZGV4IDwgc291cmNlLmxlbmd0aCAmJiAvW1xcdUQ4MDAtXFx1REJGRl0vdS50ZXN0KHNvdXJjZVtpbmRleCAtIDFdKSAmJiAvW1xcdURDMDAtXFx1REZGRl0vdS50ZXN0KHNvdXJjZVtpbmRleF0pKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIFRyZWUtc2l0dGVyIHNvdXJjZSBpbmRleDogXCIgKyBpbmRleClcbiAgfVxuICByZXR1cm4gdXRmOEJ5dGVPZmZzZXRUb1V0ZjE2T2Zmc2V0KHNvdXJjZSwgbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNvdXJjZS5zbGljZSgwLCBpbmRleCkpLmxlbmd0aClcbn1cblxuLyoqXG4gKiBGaW5kcyBhbiB1bnBhaXJlZCBVVEYtMTYgc3Vycm9nYXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IEludmFsaWQgb2Zmc2V0IG9yIC0xLlxuICovXG5mdW5jdGlvbiBmaXJzdExvbmVTdXJyb2dhdGVPZmZzZXQoc291cmNlKSB7XG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBzb3VyY2UubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgdW5pdCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KVxuXG4gICAgaWYgKHVuaXQgPj0gMHhEODAwICYmIHVuaXQgPD0gMHhEQkZGKSB7XG4gICAgICBjb25zdCBuZXh0ID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXggKyAxKVxuXG4gICAgICBpZiAobmV4dCA+PSAweERDMDAgJiYgbmV4dCA8PSAweERGRkYpIGluZGV4ICs9IDFcbiAgICAgIGVsc2UgcmV0dXJuIGluZGV4XG4gICAgfSBlbHNlIGlmICh1bml0ID49IDB4REMwMCAmJiB1bml0IDw9IDB4REZGRikgcmV0dXJuIGluZGV4XG4gIH1cbiAgcmV0dXJuIC0xXG59XG5cbi8qKiBDb25zdW1lcyBleGFjdCBxdWFsaWZpZWQgU3dpZnQgQ1NUIHNoYXBlcyB3aXRob3V0IHJldGFpbmluZyBwYXJzZXIgaGFuZGxlcy4gKi9cbmNsYXNzIFN3aWZ0UmVhZGVyIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSByZWFkZXIgb3ZlciBvbmUgcGFyc2VyLW93bmVkIFN3aWZ0IHNvdXJjZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gT3JpZ2luYWwgZmlsZW5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihmaWxlbmFtZSwgc291cmNlKSB7XG4gICAgdGhpcy5maWxlbmFtZSA9IGZpbGVuYW1lXG4gICAgdGhpcy5zb3VyY2UgPSBzb3VyY2VcbiAgICAvKiogQHR5cGUge1NldDxzdHJpbmc+fSAqL1xuICAgIHRoaXMuaGVscGVycyA9IG5ldyBTZXQoKVxuICAgIHRoaXMubXV0YWJsZU1hcmtlciA9IGZhbHNlXG4gICAgLyoqIEB0eXBlIHtXZWFrTWFwPG9iamVjdCwgaW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZT59ICovXG4gICAgdGhpcy5uYXRpdmVFcXVhbGl0eU9wZXJhdG9ycyA9IG5ldyBXZWFrTWFwKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgcGFyc2VyIHJhbmdlIHRvIFNlbWFudGlmb2xkIFVURi0xNiBjb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gUGFyc2VyIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gRXhhY3QgbG9jYXRpb24uXG4gICAqL1xuICBsb2NhdGlvbihub2RlKSB7XG4gICAgcmV0dXJuIGxvY2F0aW9uRnJvbU9mZnNldHModGhpcy5maWxlbmFtZSwgdGhpcy5zb3VyY2UsIGJpbmRpbmdJbmRleFRvVXRmMTZPZmZzZXQodGhpcy5zb3VyY2UsIG5vZGUuc3RhcnRJbmRleCksXG4gICAgICBiaW5kaW5nSW5kZXhUb1V0ZjE2T2Zmc2V0KHRoaXMuc291cmNlLCBub2RlLmVuZEluZGV4KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWplY3RzIG9uZSBsb2NhdGVkIHNvdXJjZS1wcm9maWxlIHZpb2xhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gVmlvbGF0aW5nIG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGV0YWlsXSAtIFByb2ZpbGUgZGV0YWlsLlxuICAgKiBAcmV0dXJucyB7bmV2ZXJ9IEFsd2F5cyB0aHJvd3MuXG4gICAqL1xuICBmYWlsKG5vZGUsIGRldGFpbCA9IG5vZGUudHlwZSkge1xuICAgIHVuc3VwcG9ydGVkU3ludGF4KFwic3dpZnRcIiwgZGV0YWlsLCB0aGlzLmxvY2F0aW9uKG5vZGUpKVxuICB9XG5cbiAgLyoqXG4gICAqIFRyYXZlcnNlcyBldmVyeSBuYW1lZCwgYW5vbnltb3VzLCBleHRyYSwgZGlyZWN0aXZlLCBhbmQgcmVjb3Zlcnkgbm9kZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSByb290IC0gQ29tcGxldGUgcGFyc2VyIHJvb3QuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgdmFsaWRhdGVUcmVlKHJvb3QpIHtcbiAgICBjb25zdCBwZW5kaW5nID0gW3tkZXB0aDogMCwgbm9kZTogcm9vdCwgdmlzaXRlZDogZmFsc2V9XVxuXG4gICAgd2hpbGUgKHBlbmRpbmcubGVuZ3RoKSB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gcGVuZGluZy5wb3AoKVxuXG4gICAgICBpZiAoIWN1cnJlbnQpIHRocm93IG5ldyBFcnJvcihcIlN3aWZ0IHRyYXZlcnNhbCBsb3N0IGEgcGVuZGluZyBwYXJzZXIgbm9kZS5cIilcbiAgICAgIGNvbnN0IHtkZXB0aCwgbm9kZSwgdmlzaXRlZH0gPSBjdXJyZW50XG5cbiAgICAgIGlmIChkZXB0aCA+IDUxMikgdGhpcy5mYWlsKG5vZGUsIFwiQ1NUIGV4Y2VlZHMgdGhlIDUxMi1sZXZlbCB0cmF2ZXJzYWwgbGltaXRcIilcbiAgICAgIGlmICghdmlzaXRlZCkge1xuICAgICAgICBwZW5kaW5nLnB1c2goe2RlcHRoLCBub2RlLCB2aXNpdGVkOiB0cnVlfSlcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSBub2RlLmNoaWxkQ291bnQgLSAxOyBpbmRleCA+PSAwOyBpbmRleCAtPSAxKSB7XG4gICAgICAgICAgY29uc3QgY2hpbGQgPSBub2RlLmNoaWxkKGluZGV4KVxuXG4gICAgICAgICAgaWYgKCFjaGlsZCkgdGhyb3cgbmV3IEVycm9yKGBUcmVlLXNpdHRlciBvbWl0dGVkIGNoaWxkICR7aW5kZXh9IG9mICR7bm9kZS50eXBlfS5gKVxuICAgICAgICAgIHBlbmRpbmcucHVzaCh7ZGVwdGg6IGRlcHRoICsgMSwgbm9kZTogY2hpbGQsIHZpc2l0ZWQ6IGZhbHNlfSlcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgaWYgKG5vZGUuaGFzRXJyb3IgfHwgbm9kZS5pc0Vycm9yIHx8IG5vZGUuaXNNaXNzaW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgICAgICAgIGNvZGU6IFwiUEFSU0VfRVJST1JcIixcbiAgICAgICAgICBsYW5ndWFnZTogXCJzd2lmdFwiLFxuICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLFxuICAgICAgICAgIG1lc3NhZ2U6IGBUcmVlLXNpdHRlciBleHBvc2VkIHJlY292ZXJ5IGF0ICcke25vZGUudHlwZX0nLmBcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIGlmIChbXCJhdHRyaWJ1dGVcIiwgXCJkaXJlY3RpdmVcIiwgXCJzaGViYW5nX2xpbmVcIl0uaW5jbHVkZXMobm9kZS50eXBlKSkgdGhpcy5mYWlsKG5vZGUsIG5vZGUudHlwZSlcbiAgICAgIGlmIChub2RlLnR5cGUgPT0gXCJjb21tZW50XCIgJiYgL3N3aWZ0LXRvb2xzLXZlcnNpb24vdS50ZXN0KG5vZGUudGV4dCkpIHtcbiAgICAgICAgdGhpcy5mYWlsKG5vZGUsIFwiZGlyZWN0aXZlLWJlYXJpbmcgY29tbWVudFwiKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBPbWl0cyBvbmx5IGluZXJ0IGNvbW1lbnRzIGFscmVhZHkgYWNjb3VudGVkIGZvciBieSBleGhhdXN0aXZlIHRyYXZlcnNhbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gUGFyZW50IG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlW119IFN0cnVjdHVyYWwgY2hpbGRyZW4uXG4gICAqL1xuICBwYXJ0cyhub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUuY2hpbGRyZW4uZmlsdGVyKChjaGlsZCkgPT4gY2hpbGQudHlwZSAhPSBcImNvbW1lbnRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1aXJlcyBvbmUgZXhhY3QgcGFyc2VyIGZpZWxkIGVkZ2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIEZpZWxkIG93bmVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIEZpZWxkIG5hbWUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBTb2xlIGZpZWxkIG5vZGUuXG4gICAqL1xuICBmaWVsZChub2RlLCBuYW1lKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9IFtdXG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbm9kZS5jaGlsZENvdW50OyBpbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBjaGlsZCA9IG5vZGUuY2hpbGQoaW5kZXgpXG5cbiAgICAgIGlmICghY2hpbGQpIHRocm93IG5ldyBFcnJvcihgVHJlZS1zaXR0ZXIgb21pdHRlZCBjaGlsZCAke2luZGV4fSBvZiAke25vZGUudHlwZX0uYClcbiAgICAgIGlmIChub2RlLmZpZWxkTmFtZUZvckNoaWxkKGluZGV4KSA9PSBuYW1lKSBtYXRjaGVzLnB1c2goY2hpbGQpXG4gICAgfVxuICAgIGlmIChtYXRjaGVzLmxlbmd0aCAhPSAxKSB0aGlzLmZhaWwobm9kZSwgYGV4cGVjdGVkIG9uZSAnJHtuYW1lfScgZmllbGRgKVxuICAgIHJldHVybiBtYXRjaGVzWzBdXG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZXMgYWxsIG9yZGVyZWQgY2hpbGRyZW4sIGluY2x1ZGluZyBhbm9ueW1vdXMgcHVuY3R1YXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIFNoYXBlIG93bmVyLlxuICAgKiBAcGFyYW0geyhpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlIHwgc3RyaW5nKVtdfSBleHBlY3RlZCAtIEV4YWN0IGNoaWxkIHNlcXVlbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHNoYXBlKG5vZGUsIGV4cGVjdGVkKSB7XG4gICAgY29uc3QgYWN0dWFsID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgaWYgKGFjdHVhbC5sZW5ndGggIT0gZXhwZWN0ZWQubGVuZ3RoKSB0aGlzLmZhaWwoYWN0dWFsW01hdGgubWluKGFjdHVhbC5sZW5ndGgsIGV4cGVjdGVkLmxlbmd0aCldID8/IG5vZGUsIGAke25vZGUudHlwZX0gY2hpbGQgc2hhcGVgKVxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBleHBlY3RlZC5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgIGNvbnN0IHdhbnRlZCA9IGV4cGVjdGVkW2luZGV4XVxuICAgICAgY29uc3QgY2hpbGQgPSBhY3R1YWxbaW5kZXhdXG4gICAgICBjb25zdCBtYXRjaGVzID0gdHlwZW9mIHdhbnRlZCA9PSBcInN0cmluZ1wiID8gY2hpbGQudGV4dCA9PSB3YW50ZWQgOiBjaGlsZC5pZCA9PSB3YW50ZWQuaWRcblxuICAgICAgaWYgKCFtYXRjaGVzKSB0aGlzLmZhaWwoY2hpbGQsIGAke25vZGUudHlwZX0gY2hpbGQgc2hhcGVgKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgb25lIFN3aWZ0IGlkZW50aWZpZXIgaW4gdGhlIHBvcnRhYmxlIHNvdXJjZSBwcm9maWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBJZGVudGlmaWVyIHRva2VuLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthbGxvd1ByaW50XSAtIFdoZXRoZXIgdGhlIGZpeGVkIHByaW50IHNjYWZmb2xkIGlzIGV4cGVjdGVkLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBY2NlcHRlZCBzcGVsbGluZy5cbiAgICovXG4gIGlkZW50aWZpZXIobm9kZSwgYWxsb3dQcmludCA9IGZhbHNlKSB7XG4gICAgY29uc3QgbmFtZSA9IG5vZGUudGV4dFxuXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcInNpbXBsZV9pZGVudGlmaWVyXCIgfHwgIShhbGxvd1ByaW50ICYmIG5hbWUgPT0gXCJwcmludFwiKSAmJlxuICAgICAgKCFpc1N3aWZ0SWRlbnRpZmllcihuYW1lKSB8fCBuYW1lLm5vcm1hbGl6ZShcIk5GQ1wiKSAhPSBuYW1lKSkgdGhpcy5mYWlsKG5vZGUsIFwicmVzZXJ2ZWQgb3IgdW5zdXBwb3J0ZWQgaWRlbnRpZmllclwiKVxuICAgIHJldHVybiBuYW1lXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgZXhhY3RseSBJbnQ2NCwgQm9vbCwgb3IgU3RyaW5nLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBUeXBlIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSBTZW1hbnRpYyBzY2FsYXIuXG4gICAqL1xuICB0eXBlKG5vZGUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJ1c2VyX3R5cGVcIiB8fCBwYXJ0cy5sZW5ndGggIT0gMSB8fCBwYXJ0c1swXS50eXBlICE9IFwidHlwZV9pZGVudGlmaWVyXCIpIHRoaXMuZmFpbChub2RlLCBcInNjYWxhciB0eXBlIHNoYXBlXCIpXG4gICAgdGhpcy5zaGFwZShub2RlLCBbcGFydHNbMF1dKVxuICAgIGNvbnN0IHR5cGUgPSBzb3VyY2VTY2FsYXJUeXBlKFwic3dpZnRcIiwgcGFydHNbMF0udGV4dCwgdGhpcy5sb2NhdGlvbihwYXJ0c1swXSkpXG5cbiAgICBpZiAoIXR5cGUpIHRoaXMuZmFpbChwYXJ0c1swXSwgYHVuc3VwcG9ydGVkIHNjYWxhciB0eXBlICcke3BhcnRzWzBdLnRleHR9J2ApXG4gICAgcmV0dXJuIHR5cGVcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgZXhhY3Qgb3JkaW5hcnkgU3dpZnQgc3RyaW5nIGxpdGVyYWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIFN0cmluZyBub2RlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBVbmljb2RlIHNjYWxhciB2YWx1ZS5cbiAgICovXG4gIHN0cmluZyhub2RlKSB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICBpZiAobm9kZS50eXBlICE9IFwibGluZV9zdHJpbmdfbGl0ZXJhbFwiIHx8IHBhcnRzLmxlbmd0aCA8IDIgfHwgcGFydHNbMF0udGV4dCAhPSAnXCInIHx8IHBhcnRzLmF0KC0xKT8udGV4dCAhPSAnXCInKSB7XG4gICAgICByZXR1cm4gdGhpcy5mYWlsKG5vZGUsIFwib3JkaW5hcnkgbm9uaW50ZXJwb2xhdGVkIHN0cmluZyBsaXRlcmFsIHJlcXVpcmVkXCIpXG4gICAgfVxuICAgIHRoaXMuc2hhcGUobm9kZSwgWydcIicsIC4uLnBhcnRzLnNsaWNlKDEsIC0xKSwgJ1wiJ10pXG4gICAgbGV0IHZhbHVlID0gXCJcIlxuICAgIGNvbnN0IHNpbXBsZUVzY2FwZXMgPSBuZXcgTWFwKFtcbiAgICAgIFtcIlxcXFwwXCIsIFwiXFwwXCJdLCBbXCJcXFxcblwiLCBcIlxcblwiXSwgW1wiXFxcXHJcIiwgXCJcXHJcIl0sIFtcIlxcXFx0XCIsIFwiXFx0XCJdLCBbXCJcXFxcXFxcXFwiLCBcIlxcXFxcIl0sIFsnXFxcXFwiJywgJ1wiJ10sIFtcIlxcXFwnXCIsIFwiJ1wiXVxuICAgIF0pXG5cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMuc2xpY2UoMSwgLTEpKSB7XG4gICAgICBpZiAocGFydC50eXBlID09IFwibGluZV9zdHJfdGV4dFwiKSB7XG4gICAgICAgIGlmICgvW1xcclxcbl0vdS50ZXN0KHBhcnQudGV4dCkpIHRoaXMuZmFpbChwYXJ0LCBcInN0cmluZyBsaW5lIHRlcm1pbmF0b3JcIilcbiAgICAgICAgdmFsdWUgKz0gcGFydC50ZXh0XG4gICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PSBcInN0cl9lc2NhcGVkX2NoYXJcIikge1xuICAgICAgICBjb25zdCBlc2NhcGUgPSBwYXJ0LnRleHRcblxuICAgICAgICBpZiAoc2ltcGxlRXNjYXBlcy5oYXMoZXNjYXBlKSkgdmFsdWUgKz0gc2ltcGxlRXNjYXBlcy5nZXQoZXNjYXBlKVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjb25zdCBtYXRjaCA9IC9eXFxcXHVcXHsoWzAtOUEtRmEtZl17MSw4fSlcXH0kL3UuZXhlYyhlc2NhcGUpXG5cbiAgICAgICAgICBpZiAoIW1hdGNoKSB0aGlzLmZhaWwocGFydCwgXCJ1bnN1cHBvcnRlZCBzdHJpbmcgZXNjYXBlXCIpXG4gICAgICAgICAgY29uc3Qgc2NhbGFyID0gTnVtYmVyLnBhcnNlSW50KG1hdGNoWzFdLCAxNilcblxuICAgICAgICAgIGlmIChzY2FsYXIgPiAweDEwRkZGRiB8fCBzY2FsYXIgPj0gMHhEODAwICYmIHNjYWxhciA8PSAweERGRkYpIHRoaXMuZmFpbChwYXJ0LCBcIm5vbi1zY2FsYXIgVW5pY29kZSBlc2NhcGVcIilcbiAgICAgICAgICB2YWx1ZSArPSBTdHJpbmcuZnJvbUNvZGVQb2ludChzY2FsYXIpXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB0aGlzLmZhaWwocGFydCwgcGFydC50eXBlID09IFwiaW50ZXJwb2xhdGVkX2V4cHJlc3Npb25cIiA/IFwiaW50ZXJwb2xhdGVkIHN0cmluZ1wiIDogXCJzdHJpbmcgY2hpbGRcIilcbiAgICB9XG4gICAgaWYgKCFoYXNPbmx5VW5pY29kZVNjYWxhcnModmFsdWUpKSB0aGlzLmZhaWwobm9kZSwgXCJpbnZhbGlkIFVuaWNvZGUgc3RyaW5nIGxpdGVyYWxcIilcbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBleGFjdCB1bmxhYmVsZWQgY2FsbCBhcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gc3VmZml4IC0gQ2FsbCBzdWZmaXguXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlW119IEFyZ3VtZW50IHZhbHVlIG5vZGVzLlxuICAgKi9cbiAgYXJndW1lbnRzKHN1ZmZpeCkge1xuICAgIGNvbnN0IHN1ZmZpeFBhcnRzID0gdGhpcy5wYXJ0cyhzdWZmaXgpXG5cbiAgICBpZiAoc3VmZml4LnR5cGUgIT0gXCJjYWxsX3N1ZmZpeFwiIHx8IHN1ZmZpeFBhcnRzLmxlbmd0aCAhPSAxIHx8IHN1ZmZpeFBhcnRzWzBdLnR5cGUgIT0gXCJ2YWx1ZV9hcmd1bWVudHNcIikge1xuICAgICAgcmV0dXJuIHRoaXMuZmFpbChzdWZmaXgsIFwiY2FsbCBzdWZmaXggc2hhcGVcIilcbiAgICB9XG4gICAgdGhpcy5zaGFwZShzdWZmaXgsIFtzdWZmaXhQYXJ0c1swXV0pXG4gICAgY29uc3QgbGlzdCA9IHN1ZmZpeFBhcnRzWzBdXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKGxpc3QpXG5cbiAgICBpZiAocGFydHMubGVuZ3RoIDwgMiB8fCBwYXJ0c1swXS50ZXh0ICE9IFwiKFwiIHx8IHBhcnRzLmF0KC0xKT8udGV4dCAhPSBcIilcIikgdGhpcy5mYWlsKGxpc3QsIFwiY2FsbCBhcmd1bWVudCBsaXN0IHNoYXBlXCIpXG4gICAgY29uc3QgYXJndW1lbnRzXyA9IHBhcnRzLnNsaWNlKDEsIC0xKS5maWx0ZXIoKF9wYXJ0LCBpbmRleCkgPT4gaW5kZXggJSAyID09IDApXG4gICAgY29uc3QgZXhwZWN0ZWQgPSBbXCIoXCIsIC4uLmFyZ3VtZW50c18uZmxhdE1hcCgoYXJndW1lbnQsIGluZGV4KSA9PiBpbmRleCA9PSAwID8gW2FyZ3VtZW50XSA6IFtcIixcIiwgYXJndW1lbnRdKSwgXCIpXCJdXG5cbiAgICB0aGlzLnNoYXBlKGxpc3QsIGV4cGVjdGVkKVxuICAgIHJldHVybiBhcmd1bWVudHNfLm1hcCgoYXJndW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5maWVsZChhcmd1bWVudCwgXCJ2YWx1ZVwiKVxuXG4gICAgICBpZiAoYXJndW1lbnQudHlwZSAhPSBcInZhbHVlX2FyZ3VtZW50XCIpIHRoaXMuZmFpbChhcmd1bWVudCwgXCJ1bmxhYmVsZWQgYXJndW1lbnQgcmVxdWlyZWRcIilcbiAgICAgIHRoaXMuc2hhcGUoYXJndW1lbnQsIFt2YWx1ZV0pXG4gICAgICByZXR1cm4gdmFsdWVcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgZGlyZWN0IHNlbWFudGljIGNhbGwsIGluY2x1ZGluZyBxdWFsaWZpZWQgbmVnYXRlZC1jYWxsIGFuZCB0cmFpbGluZy1jYWxsIGJpbmFyeSBzaGFwZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIENhbGwgbm9kZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IFNlbWFudGljIGV4cHJlc3Npb24uXG4gICAqL1xuICBjYWxsKG5vZGUpIHtcbiAgICBjb25zdCBsb2NhdGlvbiA9IHRoaXMubG9jYXRpb24obm9kZSlcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJjYWxsX2V4cHJlc3Npb25cIiB8fCBwYXJ0cy5sZW5ndGggIT0gMikgdGhpcy5mYWlsKG5vZGUsIFwiZGlyZWN0IGNhbGwgc2hhcGVcIilcbiAgICBjb25zdCB0YXJnZXQgPSBwYXJ0c1swXVxuICAgIGNvbnN0IHN1ZmZpeCA9IHBhcnRzWzFdXG5cbiAgICBpZiAoYmluYXJ5Tm9kZU9wZXJhdG9ycy5oYXModGFyZ2V0LnR5cGUpKSB7XG4gICAgICBjb25zdCByaWdodCA9IHRoaXMuZmllbGQodGFyZ2V0LCBcInJoc1wiKVxuICAgICAgY29uc3QgY2FsbExvY2F0aW9uID0gbG9jYXRpb25Gcm9tT2Zmc2V0cyh0aGlzLmZpbGVuYW1lLCB0aGlzLnNvdXJjZSxcbiAgICAgICAgYmluZGluZ0luZGV4VG9VdGYxNk9mZnNldCh0aGlzLnNvdXJjZSwgcmlnaHQuc3RhcnRJbmRleCksIGJpbmRpbmdJbmRleFRvVXRmMTZPZmZzZXQodGhpcy5zb3VyY2UsIHN1ZmZpeC5lbmRJbmRleCkpXG5cbiAgICAgIGlmIChyaWdodC50eXBlICE9IFwic2ltcGxlX2lkZW50aWZpZXJcIikgdGhpcy5mYWlsKG5vZGUsIFwidHJhaWxpbmcgZGlyZWN0IGNhbGwgc2hhcGVcIilcbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW3RhcmdldCwgc3VmZml4XSlcblxuICAgICAgcmV0dXJuIHRoaXMuYmluYXJ5KHRhcmdldCwgdW5kZWZpbmVkLCBsb2NhdGlvbiwgdGhpcy5jYWxsUGFydHMocmlnaHQsIHN1ZmZpeCwgY2FsbExvY2F0aW9uKSlcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jYWxsUGFydHModGFyZ2V0LCBzdWZmaXgsIGxvY2F0aW9uKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBkaXJlY3QgY2FsbCBmcm9tIGl0cyBwYXJzZXIgdGFyZ2V0IGFuZCBzdWZmaXguXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gdGFyZ2V0IC0gRGlyZWN0IGNhbGwgdGFyZ2V0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IHN1ZmZpeCAtIEFyZ3VtZW50IHN1ZmZpeC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbG9jYXRpb24gLSBDb21wbGV0ZSBjYWxsIGxvY2F0aW9uLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gU2VtYW50aWMgY2FsbCBvciBwcmVmaXhlZCBjYWxsLlxuICAgKi9cbiAgY2FsbFBhcnRzKHRhcmdldCwgc3VmZml4LCBsb2NhdGlvbikge1xuICAgIGNvbnN0IGFyZ3VtZW50Tm9kZXMgPSB0aGlzLmFyZ3VtZW50cyhzdWZmaXgpXG4gICAgbGV0IG5hbWVOb2RlID0gdGFyZ2V0XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlIHwgdW5kZWZpbmVkfSAqL1xuICAgIGxldCB1bmFyeU9wZXJhdG9yXG5cbiAgICBpZiAoW1wiIVwiLCBcIi1cIl0uaW5jbHVkZXMobmFtZU5vZGUudGV4dCkpIHtcbiAgICAgIGlmIChhcmd1bWVudE5vZGVzLmxlbmd0aCAhPSAxKSB0aGlzLmZhaWwodGFyZ2V0LCBcInBhcmVudGhlc2l6ZWQgdW5hcnkgZXhwcmVzc2lvbiBzaGFwZVwiKVxuICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IHRoaXMuZXhwcmVzc2lvbihhcmd1bWVudE5vZGVzWzBdKVxuXG4gICAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAod2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICAgIGtpbmQ6IFwiVW5hcnlFeHByZXNzaW9uXCIsIGxvY2F0aW9uLCBvcGVyYW5kOiBleHByZXNzaW9uXG4gICAgICB9LCB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24obmFtZU5vZGUpfSksIG5hbWVOb2RlLnRleHQgPT0gXCItXCIgPyBcIk5lZ2F0ZVwiIDogXCJOb3RcIikpKVxuICAgIH1cbiAgICBpZiAobmFtZU5vZGUudHlwZSA9PSBcInByZWZpeF9leHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IG9wZXJhdGlvbiA9IHRoaXMuZmllbGQobmFtZU5vZGUsIFwib3BlcmF0aW9uXCIpXG4gICAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmZpZWxkKG5hbWVOb2RlLCBcInRhcmdldFwiKVxuXG4gICAgICB0aGlzLnNoYXBlKG5hbWVOb2RlLCBbb3BlcmF0aW9uLCB0YXJnZXRdKVxuICAgICAgaWYgKCFbXCIhXCIsIFwiLVwiXS5pbmNsdWRlcyhvcGVyYXRpb24udGV4dCkgfHwgdGFyZ2V0LnR5cGUgIT0gXCJzaW1wbGVfaWRlbnRpZmllclwiKSB0aGlzLmZhaWwobmFtZU5vZGUsIFwicHJlZml4ZWQgZGlyZWN0IGNhbGwgc2hhcGVcIilcbiAgICAgIHVuYXJ5T3BlcmF0b3IgPSBvcGVyYXRpb25cbiAgICAgIG5hbWVOb2RlID0gdGFyZ2V0XG4gICAgfVxuICAgIGNvbnN0IG5hbWUgPSBuYW1lTm9kZS50ZXh0XG5cbiAgICBjb25zdCBoZWxwZXJPcGVyYXRpb24gPSB0aGlzLmhlbHBlcnMuaGFzKG5hbWUpID8gaGVscGVyT3BlcmF0aW9ucy5nZXQobmFtZSkgOiB1bmRlZmluZWRcblxuICAgIGlmIChoZWxwZXJPcGVyYXRpb24pIHtcbiAgICAgIGlmICh1bmFyeU9wZXJhdG9yIHx8IGFyZ3VtZW50Tm9kZXMubGVuZ3RoICE9IDIpIHRoaXMuZmFpbCh0YXJnZXQsIFwiU3dpZnQgc2NhbGFyIGVxdWFsaXR5IGhlbHBlciBzaGFwZVwiKVxuICAgICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKHdpdGhBZGFwdGVkT3BlcmF0aW9uKHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICBraW5kOiBcIkJpbmFyeUV4cHJlc3Npb25cIiwgbGVmdDogdGhpcy5leHByZXNzaW9uKGFyZ3VtZW50Tm9kZXNbMF0pLCBsb2NhdGlvbiwgcmlnaHQ6IHRoaXMuZXhwcmVzc2lvbihhcmd1bWVudE5vZGVzWzFdKVxuICAgICAgfSwge29wZXJhdG9yOiB0aGlzLmxvY2F0aW9uKG5hbWVOb2RlKX0pLCBoZWxwZXJPcGVyYXRpb24pKVxuICAgIH1cbiAgICBjb25zdCBzZW1hbnRpY05hbWUgPSB0aGlzLmlkZW50aWZpZXIobmFtZU5vZGUpXG5cbiAgICBpZiAoYXJndW1lbnROb2Rlcy5sZW5ndGggIT0gMikgdGhpcy5mYWlsKHN1ZmZpeCwgXCJzZW1hbnRpYyBjYWxsIGFyZ3VtZW50IGNvdW50XCIpXG4gICAgY29uc3QgY2FsbCA9IHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgYXJndW1lbnRzOiBhcmd1bWVudE5vZGVzLm1hcCgoYXJndW1lbnQpID0+IHRoaXMuZXhwcmVzc2lvbihhcmd1bWVudCkpLFxuICAgICAgY2FsbGVlOiBzZW1hbnRpY05hbWUsXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJDYWxsRXhwcmVzc2lvblwiKSxcbiAgICAgIGxvY2F0aW9uXG4gICAgfSwge2NhbGxlZTogdGhpcy5sb2NhdGlvbihuYW1lTm9kZSl9KVxuXG4gICAgaWYgKCF1bmFyeU9wZXJhdG9yKSByZXR1cm4gY2FsbFxuICAgIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovICh3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IFwiVW5hcnlFeHByZXNzaW9uXCIsIGxvY2F0aW9uLCBvcGVyYW5kOiBjYWxsXG4gICAgfSwge29wZXJhdG9yOiB0aGlzLmxvY2F0aW9uKHVuYXJ5T3BlcmF0b3IpfSksIHVuYXJ5T3BlcmF0b3IudGV4dCA9PSBcIi1cIiA/IFwiTmVnYXRlXCIgOiBcIk5vdFwiKSkpXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIHN1cHBvcnRlZCBzY2FsYXIgZXhwcmVzc2lvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gRXhwcmVzc2lvbiBub2RlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAgICovXG4gIGV4cHJlc3Npb24obm9kZSkge1xuICAgIGNvbnN0IGxvY2F0aW9uID0gdGhpcy5sb2NhdGlvbihub2RlKVxuXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInNpbXBsZV9pZGVudGlmaWVyXCIpIHtcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb24sIG5hbWU6IHRoaXMuaWRlbnRpZmllcihub2RlKX0sIHtuYW1lOiBsb2NhdGlvbn0pXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJpbnRlZ2VyX2xpdGVyYWxcIikge1xuICAgICAgaWYgKCEvXig/OjB8WzEtOV1bMC05XSopJC91LnRlc3Qobm9kZS50ZXh0KSkgdGhpcy5mYWlsKG5vZGUsIFwibm9uY2Fub25pY2FsIGludGVnZXIgbGl0ZXJhbFwiKVxuICAgICAgY29uc3QgdmFsdWUgPSBOdW1iZXIoQmlnSW50KG5vZGUudGV4dCkpXG5cbiAgICAgIGlmICghTnVtYmVyLmlzU2FmZUludGVnZXIodmFsdWUpKSB0aGlzLmZhaWwobm9kZSwgXCJub24tc2FmZSBpbnRlZ2VyIGxpdGVyYWxcIilcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJbnRlZ2VyTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImJvb2xlYW5fbGl0ZXJhbFwiKSB7XG4gICAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgICAgaWYgKHBhcnRzLmxlbmd0aCAhPSAxIHx8ICFbXCJ0cnVlXCIsIFwiZmFsc2VcIl0uaW5jbHVkZXMocGFydHNbMF0udGV4dCkpIHRoaXMuZmFpbChub2RlLCBcIkJvb2xlYW4gbGl0ZXJhbCBzaGFwZVwiKVxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbcGFydHNbMF0udGV4dF0pXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQm9vbGVhbkxpdGVyYWxcIiksIGxvY2F0aW9uLCB2YWx1ZTogcGFydHNbMF0udGV4dCA9PSBcInRydWVcIn0sIHtsaXRlcmFsOiBsb2NhdGlvbn0pXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJsaW5lX3N0cmluZ19saXRlcmFsXCIpIHtcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJTdHJpbmdMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWU6IHRoaXMuc3RyaW5nKG5vZGUpfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInR1cGxlX2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmZpZWxkKG5vZGUsIFwidmFsdWVcIilcblxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbXCIoXCIsIHZhbHVlLCBcIilcIl0pXG4gICAgICByZXR1cm4gdGhpcy5leHByZXNzaW9uKHZhbHVlKVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwicHJlZml4X2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3Qgb3BlcmF0aW9uID0gdGhpcy5maWVsZChub2RlLCBcIm9wZXJhdGlvblwiKVxuICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5maWVsZChub2RlLCBcInRhcmdldFwiKVxuXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtvcGVyYXRpb24sIHRhcmdldF0pXG4gICAgICBpZiAoIVtcIi1cIiwgXCIhXCJdLmluY2x1ZGVzKG9wZXJhdGlvbi50ZXh0KSkgdGhpcy5mYWlsKG9wZXJhdGlvbiwgXCJ1bmFyeSBvcGVyYXRvclwiKVxuICAgICAgcmV0dXJuIHRoaXMucHJlZml4ZWQob3BlcmF0aW9uLCB0YXJnZXQpXG4gICAgfVxuICAgIGNvbnN0IGFjY2VwdGVkT3BlcmF0b3JzID0gYmluYXJ5Tm9kZU9wZXJhdG9ycy5nZXQobm9kZS50eXBlKVxuXG4gICAgaWYgKGFjY2VwdGVkT3BlcmF0b3JzKSB7XG4gICAgICByZXR1cm4gdGhpcy5iaW5hcnkobm9kZSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImNhbGxfZXhwcmVzc2lvblwiKSByZXR1cm4gdGhpcy5jYWxsKG5vZGUpXG4gICAgcmV0dXJuIHRoaXMuZmFpbChub2RlKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHRoZSBncmFtbWFyJ3MgYnJvYWQgcHJlZml4IHRhcmdldCB3aXRoIFN3aWZ0J3MgdGlnaHRlciBwcmVmaXggcHJlY2VkZW5jZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBvcGVyYXRvciAtIFByZWZpeCBvcGVyYXRvci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSB0YXJnZXQgLSBHcmFtbWFyIHRhcmdldC5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IFNlbWFudGljIGV4cHJlc3Npb24uXG4gICAqL1xuICBwcmVmaXhlZChvcGVyYXRvciwgdGFyZ2V0KSB7XG4gICAgY29uc3QgbG9jYXRpb24gPSBsb2NhdGlvbkZyb21PZmZzZXRzKHRoaXMuZmlsZW5hbWUsIHRoaXMuc291cmNlLFxuICAgICAgYmluZGluZ0luZGV4VG9VdGYxNk9mZnNldCh0aGlzLnNvdXJjZSwgb3BlcmF0b3Iuc3RhcnRJbmRleCksIGJpbmRpbmdJbmRleFRvVXRmMTZPZmZzZXQodGhpcy5zb3VyY2UsIHRhcmdldC5lbmRJbmRleCkpXG5cbiAgICBpZiAoYmluYXJ5Tm9kZU9wZXJhdG9ycy5oYXModGFyZ2V0LnR5cGUpKSB7XG4gICAgICBjb25zdCBsZWZ0ID0gdGhpcy5maWVsZCh0YXJnZXQsIFwibGhzXCIpXG5cbiAgICAgIHJldHVybiB0aGlzLmJpbmFyeSh0YXJnZXQsIHRoaXMucHJlZml4ZWQob3BlcmF0b3IsIGxlZnQpLCBsb2NhdGlvbilcbiAgICB9XG5cbiAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAod2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiBcIlVuYXJ5RXhwcmVzc2lvblwiLCBsb2NhdGlvbiwgb3BlcmFuZDogdGhpcy5leHByZXNzaW9uKHRhcmdldClcbiAgICB9LCB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24ob3BlcmF0b3IpfSksIG9wZXJhdG9yLnRleHQgPT0gXCItXCIgPyBcIk5lZ2F0ZVwiIDogXCJOb3RcIikpKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBxdWFsaWZpZWQgYmluYXJ5IG5vZGUsIG9wdGlvbmFsbHkgcmVwbGFjaW5nIGl0cyBsZWZ0IGVkZ2UgZm9yIHByZWZpeCBwcmVjZWRlbmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBCaW5hcnkgbm9kZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBbbGVmdEV4cHJlc3Npb25dIC0gQWRhcHRlZCBsZWZ0IG9wZXJhbmQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IFtsb2NhdGlvbl0gLSBBZGFwdGVkIGV4cHJlc3Npb24gcmFuZ2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gW3JpZ2h0RXhwcmVzc2lvbl0gLSBBZGFwdGVkIHRyYWlsaW5nLWNhbGwgcmlnaHQgb3BlcmFuZC5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IFNlbWFudGljIGV4cHJlc3Npb24uXG4gICAqL1xuICBiaW5hcnkobm9kZSwgbGVmdEV4cHJlc3Npb24sIGxvY2F0aW9uID0gdGhpcy5sb2NhdGlvbihub2RlKSwgcmlnaHRFeHByZXNzaW9uKSB7XG4gICAgY29uc3QgYWNjZXB0ZWRPcGVyYXRvcnMgPSBiaW5hcnlOb2RlT3BlcmF0b3JzLmdldChub2RlLnR5cGUpXG4gICAgY29uc3QgbGVmdCA9IHRoaXMuZmllbGQobm9kZSwgXCJsaHNcIilcbiAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMuZmllbGQobm9kZSwgXCJvcFwiKVxuICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5maWVsZChub2RlLCBcInJoc1wiKVxuICAgIGNvbnN0IG9wZXJhdGlvbiA9IGJpbmFyeU9wZXJhdGlvbnMuZ2V0KG9wZXJhdG9yLnRleHQpXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFtsZWZ0LCBvcGVyYXRvciwgcmlnaHRdKVxuICAgIGlmICghYWNjZXB0ZWRPcGVyYXRvcnM/LmhhcyhvcGVyYXRvci50ZXh0KSB8fCAhb3BlcmF0aW9uKSB0aGlzLmZhaWwob3BlcmF0b3IsIFwidW5zdXBwb3J0ZWQgYmluYXJ5IG9wZXJhdG9yXCIpXG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHdpdGhBZGFwdGVkT3BlcmF0aW9uKHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAga2luZDogXCJCaW5hcnlFeHByZXNzaW9uXCIsIGxlZnQ6IGxlZnRFeHByZXNzaW9uID8/IHRoaXMuZXhwcmVzc2lvbihsZWZ0KSwgbG9jYXRpb24sIHJpZ2h0OiByaWdodEV4cHJlc3Npb24gPz8gdGhpcy5leHByZXNzaW9uKHJpZ2h0KVxuICAgIH0sIHtvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihvcGVyYXRvcil9KSwgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIikuQWRhcHRlZE9wZXJhdGlvbn0gKi8gKG9wZXJhdGlvbikpKSlcblxuICAgIGlmIChbXCI9PVwiLCBcIiE9XCJdLmluY2x1ZGVzKG9wZXJhdG9yLnRleHQpKSB0aGlzLm5hdGl2ZUVxdWFsaXR5T3BlcmF0b3JzLnNldChleHByZXNzaW9uLCBvcGVyYXRvcilcbiAgICByZXR1cm4gZXhwcmVzc2lvblxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBleHBsaWNpdGx5IHR5cGVkIGluaXRpYWxpemVkIGxvY2FsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBQcm9wZXJ0eSBkZWNsYXJhdGlvbi5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkxvY2FsRGVjbGFyYXRpb259IFNlbWFudGljIGxvY2FsLlxuICAgKi9cbiAgbG9jYWwobm9kZSkge1xuICAgIGNvbnN0IGxvY2F0aW9uID0gdGhpcy5sb2NhdGlvbihub2RlKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuICAgIGNvbnN0IGJpbmRpbmcgPSBwYXJ0cy5maW5kKChjaGlsZCkgPT4gY2hpbGQudHlwZSA9PSBcInZhbHVlX2JpbmRpbmdfcGF0dGVyblwiKVxuICAgIGNvbnN0IHBhdHRlcm4gPSBub2RlLmNoaWxkRm9yRmllbGROYW1lKFwibmFtZVwiKVxuICAgIGNvbnN0IGFubm90YXRpb24gPSBwYXJ0cy5maW5kKChjaGlsZCkgPT4gY2hpbGQudHlwZSA9PSBcInR5cGVfYW5ub3RhdGlvblwiKVxuICAgIGNvbnN0IHZhbHVlID0gbm9kZS5jaGlsZEZvckZpZWxkTmFtZShcInZhbHVlXCIpXG5cbiAgICBpZiAoIWFubm90YXRpb24pIHJldHVybiBtaXNzaW5nVHlwZShcInN3aWZ0XCIsIFwiTG9jYWxcIiwgbG9jYXRpb24pXG4gICAgaWYgKCFiaW5kaW5nIHx8ICFwYXR0ZXJuIHx8ICF2YWx1ZSB8fCBwYXR0ZXJuLnR5cGUgIT0gXCJwYXR0ZXJuXCIpIHRoaXMuZmFpbChub2RlLCBcImxvY2FsIGRlY2xhcmF0aW9uIHNoYXBlXCIpXG4gICAgY29uc3QgYmluZGluZ1BhcnRzID0gdGhpcy5wYXJ0cyhiaW5kaW5nKVxuICAgIGNvbnN0IG5hbWVOb2RlID0gcGF0dGVybi5jaGlsZEZvckZpZWxkTmFtZShcImJvdW5kX2lkZW50aWZpZXJcIilcbiAgICBjb25zdCBhbm5vdGF0aW9uUGFydHMgPSB0aGlzLnBhcnRzKGFubm90YXRpb24pXG5cbiAgICBpZiAoYmluZGluZ1BhcnRzLmxlbmd0aCAhPSAxIHx8ICFbXCJsZXRcIiwgXCJ2YXJcIl0uaW5jbHVkZXMoYmluZGluZ1BhcnRzWzBdLnRleHQpIHx8ICFuYW1lTm9kZSB8fCBhbm5vdGF0aW9uUGFydHMubGVuZ3RoICE9IDIpIHtcbiAgICAgIHRoaXMuZmFpbChub2RlLCBcImxvY2FsIGRlY2xhcmF0aW9uIHNoYXBlXCIpXG4gICAgfVxuICAgIHRoaXMuc2hhcGUoYmluZGluZywgW2JpbmRpbmdQYXJ0c1swXS50ZXh0XSlcbiAgICB0aGlzLnNoYXBlKHBhdHRlcm4sIFtuYW1lTm9kZV0pXG4gICAgdGhpcy5zaGFwZShhbm5vdGF0aW9uLCBbXCI6XCIsIGFubm90YXRpb25QYXJ0c1sxXV0pXG4gICAgdGhpcy5zaGFwZShub2RlLCBbYmluZGluZywgcGF0dGVybiwgYW5ub3RhdGlvbiwgXCI9XCIsIHZhbHVlXSlcbiAgICBjb25zdCBuYW1lID0gdGhpcy5pZGVudGlmaWVyKG5hbWVOb2RlKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgaW5pdGlhbGl6ZXI6IHRoaXMuZXhwcmVzc2lvbih2YWx1ZSksXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJMb2NhbERlY2xhcmF0aW9uXCIpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICBtdXRhYmxlOiBiaW5kaW5nUGFydHNbMF0udGV4dCA9PSBcInZhclwiLFxuICAgICAgbmFtZSxcbiAgICAgIHR5cGU6IHRoaXMudHlwZShhbm5vdGF0aW9uUGFydHNbMV0pXG4gICAgfSwge25hbWU6IHRoaXMubG9jYXRpb24obmFtZU5vZGUpLCBvcGVyYXRvcjogdGhpcy5sb2NhdGlvbihwYXJ0c1szXSl9KVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBwbGFpbiBpZGVudGlmaWVyIGFzc2lnbm1lbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIEFzc2lnbm1lbnQgbm9kZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkFzc2lnbm1lbnRTdGF0ZW1lbnR9IFNlbWFudGljIGFzc2lnbm1lbnQuXG4gICAqL1xuICBhc3NpZ25tZW50KG5vZGUpIHtcbiAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmZpZWxkKG5vZGUsIFwidGFyZ2V0XCIpXG4gICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLmZpZWxkKG5vZGUsIFwib3BlcmF0b3JcIilcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZmllbGQobm9kZSwgXCJyZXN1bHRcIilcbiAgICBjb25zdCB0YXJnZXRQYXJ0cyA9IHRoaXMucGFydHModGFyZ2V0KVxuXG4gICAgaWYgKHRhcmdldC50eXBlICE9IFwiZGlyZWN0bHlfYXNzaWduYWJsZV9leHByZXNzaW9uXCIgfHwgdGFyZ2V0UGFydHMubGVuZ3RoICE9IDEgfHwgb3BlcmF0b3IudGV4dCAhPSBcIj1cIikge1xuICAgICAgdGhpcy5mYWlsKG5vZGUsIFwiYXNzaWdubWVudCBzaGFwZVwiKVxuICAgIH1cbiAgICB0aGlzLnNoYXBlKHRhcmdldCwgW3RhcmdldFBhcnRzWzBdXSlcbiAgICB0aGlzLnNoYXBlKG5vZGUsIFt0YXJnZXQsIG9wZXJhdG9yLCB2YWx1ZV0pXG4gICAgY29uc3QgbmFtZSA9IHRoaXMuaWRlbnRpZmllcih0YXJnZXRQYXJ0c1swXSlcbiAgICBjb25zdCB0YXJnZXRMb2NhdGlvbiA9IHRoaXMubG9jYXRpb24odGFyZ2V0UGFydHNbMF0pXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBleHByZXNzaW9uOiB0aGlzLmV4cHJlc3Npb24odmFsdWUpLFxuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQXNzaWdubWVudFN0YXRlbWVudFwiKSxcbiAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLFxuICAgICAgdGFyZ2V0OiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb246IHRhcmdldExvY2F0aW9uLCBuYW1lfSwge25hbWU6IHRhcmdldExvY2F0aW9ufSlcbiAgICB9LCB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24ob3BlcmF0b3IpfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgZXhhY3QgcHJpbnQgY2FsbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gQ2FsbCBzdGF0ZW1lbnQuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QcmludFN0YXRlbWVudH0gU2VtYW50aWMgcHJpbnQuXG4gICAqL1xuICBwcmludChub2RlKSB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICBpZiAobm9kZS50eXBlICE9IFwiY2FsbF9leHByZXNzaW9uXCIgfHwgcGFydHMubGVuZ3RoICE9IDIgfHwgcGFydHNbMF0udHlwZSAhPSBcInNpbXBsZV9pZGVudGlmaWVyXCIgfHxcbiAgICAgIHRoaXMuaWRlbnRpZmllcihwYXJ0c1swXSwgdHJ1ZSkgIT0gXCJwcmludFwiKSB0aGlzLmZhaWwobm9kZSwgXCJleGFjdCBwcmludCBjYWxsIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgYXJndW1lbnRzXyA9IHRoaXMuYXJndW1lbnRzKHBhcnRzWzFdKVxuXG4gICAgaWYgKGFyZ3VtZW50c18ubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChwYXJ0c1sxXSwgXCJwcmludCBhcmd1bWVudCBjb3VudFwiKVxuICAgIHJldHVybiB7ZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9uKGFyZ3VtZW50c19bMF0pLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJQcmludFN0YXRlbWVudFwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSl9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIHN1cHBvcnRlZCBzdGF0ZW1lbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIFN0YXRlbWVudCBub2RlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU3RhdGVtZW50fSBTZW1hbnRpYyBzdGF0ZW1lbnQuXG4gICAqL1xuICBzdGF0ZW1lbnQobm9kZSkge1xuICAgIGlmIChub2RlLnR5cGUgPT0gXCJwcm9wZXJ0eV9kZWNsYXJhdGlvblwiKSByZXR1cm4gdGhpcy5sb2NhbChub2RlKVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJhc3NpZ25tZW50XCIpIHJldHVybiB0aGlzLmFzc2lnbm1lbnQobm9kZSlcbiAgICBpZiAobm9kZS50eXBlID09IFwiaWZfc3RhdGVtZW50XCIpIHJldHVybiB0aGlzLmNvbmRpdGlvbmFsKG5vZGUpXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImNhbGxfZXhwcmVzc2lvblwiKSByZXR1cm4gdGhpcy5wcmludChub2RlKVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJjb250cm9sX3RyYW5zZmVyX3N0YXRlbWVudFwiKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBub2RlLmNoaWxkRm9yRmllbGROYW1lKFwicmVzdWx0XCIpXG5cbiAgICAgIGlmICghcmVzdWx0KSB0aGlzLmZhaWwobm9kZSwgXCJyZXR1cm4gd2l0aG91dCBleHByZXNzaW9uXCIpXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtcInJldHVyblwiLCByZXN1bHRdKVxuICAgICAgcmV0dXJuIHtleHByZXNzaW9uOiB0aGlzLmV4cHJlc3Npb24ocmVzdWx0KSwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmV0dXJuU3RhdGVtZW50XCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKX1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZmFpbChub2RlKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBwYXJzZXIgc3RhdGVtZW50cyBub2RlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGUgfCB1bmRlZmluZWR9IG5vZGUgLSBPcHRpb25hbCBzdGF0ZW1lbnRzIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TdGF0ZW1lbnRbXX0gT3JkZXJlZCBzdGF0ZW1lbnRzLlxuICAgKi9cbiAgc3RhdGVtZW50cyhub2RlKSB7XG4gICAgaWYgKCFub2RlKSByZXR1cm4gW11cbiAgICBpZiAobm9kZS50eXBlICE9IFwic3RhdGVtZW50c1wiKSB0aGlzLmZhaWwobm9kZSwgXCJzdGF0ZW1lbnQgbGlzdCBzaGFwZVwiKVxuICAgIHJldHVybiB0aGlzLnN0YXRlbWVudExpc3QodGhpcy5wYXJ0cyhub2RlKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIHN0YXRlbWVudCBzZXF1ZW5jZSB3aGlsZSBjb2xsYXBzaW5nIGFuIGFkamFjZW50IGdlbmVyYXRlZCBtYXJrZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZVtdfSBub2RlcyAtIE9yZGVyZWQgc3RhdGVtZW50IG5vZGVzLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU3RhdGVtZW50W119IFNlbWFudGljIHN0YXRlbWVudHMuXG4gICAqL1xuICBzdGF0ZW1lbnRMaXN0KG5vZGVzKSB7XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TdGF0ZW1lbnRbXX0gKi9cbiAgICBjb25zdCBzdGF0ZW1lbnRzID0gW11cblxuICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIG5vZGVzKSB7XG4gICAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMoc3RhdGVtZW50KVxuICAgICAgY29uc3QgbWFya2VyID0gc3RhdGVtZW50LnR5cGUgPT0gXCJjYWxsX2V4cHJlc3Npb25cIiAmJiBwYXJ0c1swXT8udGV4dCA9PSBcInNlbWFudGlmb2xkX2tlZXBfbXV0YWJsZVwiXG5cbiAgICAgIGlmIChtYXJrZXIpIHtcbiAgICAgICAgY29uc3QgcHJldmlvdXMgPSBzdGF0ZW1lbnRzLmF0KC0xKVxuXG4gICAgICAgIGlmICghcHJldmlvdXMgfHwgcHJldmlvdXMua2luZCAhPSBcIkxvY2FsRGVjbGFyYXRpb25cIiB8fCAhcHJldmlvdXMubXV0YWJsZSkgdGhpcy5mYWlsKHN0YXRlbWVudCwgXCJTd2lmdCBtdXRhYmxlLWxvY2FsIHdhcm5pbmcgbWFya2VyXCIpXG4gICAgICAgIHRoaXMubXV0YWJsZU1hcmtlckNhbGwoc3RhdGVtZW50LCBwcmV2aW91cylcbiAgICAgIH0gZWxzZSBzdGF0ZW1lbnRzLnB1c2godGhpcy5zdGF0ZW1lbnQoc3RhdGVtZW50KSlcbiAgICB9XG4gICAgcmV0dXJuIHN0YXRlbWVudHNcbiAgfVxuXG4gIC8qKlxuICAgKiBDb2xsYXBzZXMgdGhlIGdlbmVyYXRlZCBpbm91dCBjYWxsIG9ubHkgYmVzaWRlIGl0cyBkZWNsYXJlZCBtdXRhYmxlIGxvY2FsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBHZW5lcmF0ZWQgbWFya2VyIGNhbGwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuTG9jYWxEZWNsYXJhdGlvbn0gbG9jYWwgLSBQcmVjZWRpbmcgbG9jYWwuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgbXV0YWJsZU1hcmtlckNhbGwobm9kZSwgbG9jYWwpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcbiAgICBjb25zdCBhcmd1bWVudHNfID0gcGFydHMubGVuZ3RoID09IDIgPyB0aGlzLmFyZ3VtZW50cyhwYXJ0c1sxXSkgOiBbXVxuICAgIGNvbnN0IGFyZ3VtZW50ID0gYXJndW1lbnRzX1swXVxuICAgIGNvbnN0IHRhcmdldCA9IGFyZ3VtZW50Py50eXBlID09IFwicHJlZml4X2V4cHJlc3Npb25cIiA/IHRoaXMuZmllbGQoYXJndW1lbnQsIFwidGFyZ2V0XCIpIDogdW5kZWZpbmVkXG5cbiAgICBpZiAoIXRoaXMubXV0YWJsZU1hcmtlciB8fCBwYXJ0c1swXT8udHlwZSAhPSBcInNpbXBsZV9pZGVudGlmaWVyXCIgfHwgcGFydHNbMF0udGV4dCAhPSBcInNlbWFudGlmb2xkX2tlZXBfbXV0YWJsZVwiIHx8XG4gICAgICBhcmd1bWVudHNfLmxlbmd0aCAhPSAxIHx8ICF0YXJnZXQgfHwgdGFyZ2V0LnR5cGUgIT0gXCJzaW1wbGVfaWRlbnRpZmllclwiIHx8IHRhcmdldC50ZXh0ICE9IGxvY2FsLm5hbWUpIHtcbiAgICAgIHRoaXMuZmFpbChub2RlLCBcIlN3aWZ0IG11dGFibGUtbG9jYWwgd2FybmluZyBtYXJrZXJcIilcbiAgICB9XG4gICAgdGhpcy5zaGFwZShub2RlLCBbcGFydHNbMF0sIHBhcnRzWzFdXSlcbiAgICB0aGlzLnNoYXBlKGFyZ3VtZW50LCBbXCImXCIsIHRhcmdldF0pXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGV4YWN0IGJyYWNlZCBjb25kaXRpb25hbCwgaW5jbHVkaW5nIGRpcmVjdCBlbHNlLWlmLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBJZiBub2RlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWZTdGF0ZW1lbnR9IFNlbWFudGljIGNvbmRpdGlvbmFsLlxuICAgKi9cbiAgY29uZGl0aW9uYWwobm9kZSkge1xuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuICAgIGNvbnN0IGNvbmRpdGlvbiA9IHRoaXMuZmllbGQobm9kZSwgXCJjb25kaXRpb25cIilcbiAgICBsZXQgaW5kZXggPSAzXG4gICAgY29uc3QgY29uc2VxdWVudFN0YXRlbWVudHMgPSBwYXJ0c1tpbmRleF0/LnR5cGUgPT0gXCJzdGF0ZW1lbnRzXCIgPyBwYXJ0c1tpbmRleCsrXSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImlmX3N0YXRlbWVudFwiIHx8IHBhcnRzWzBdPy50ZXh0ICE9IFwiaWZcIiB8fCBwYXJ0c1sxXT8uaWQgIT0gY29uZGl0aW9uLmlkIHx8IHBhcnRzWzJdPy50ZXh0ICE9IFwie1wiIHx8XG4gICAgICBwYXJ0c1tpbmRleF0/LnRleHQgIT0gXCJ9XCIpIHRoaXMuZmFpbChub2RlLCBcImlmIHN0YXRlbWVudCBzaGFwZVwiKVxuICAgIGluZGV4ICs9IDFcbiAgICBjb25zdCBzdGF0ZW1lbnQgPSB7XG4gICAgICBjb25kaXRpb246IHRoaXMuZXhwcmVzc2lvbihjb25kaXRpb24pLFxuICAgICAgY29uc2VxdWVudDoge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJsb2NrXCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihjb25zZXF1ZW50U3RhdGVtZW50cyA/PyBub2RlKSxcbiAgICAgICAgc3RhdGVtZW50czogdGhpcy5zdGF0ZW1lbnRzKGNvbnNlcXVlbnRTdGF0ZW1lbnRzKX0sXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZlN0YXRlbWVudFwiKSxcbiAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpXG4gICAgfVxuXG4gICAgaWYgKGluZGV4ID09IHBhcnRzLmxlbmd0aCkge1xuICAgICAgdGhpcy5zaGFwZShub2RlLCBbXCJpZlwiLCBjb25kaXRpb24sIFwie1wiLCAuLi4oY29uc2VxdWVudFN0YXRlbWVudHMgPyBbY29uc2VxdWVudFN0YXRlbWVudHNdIDogW10pLCBcIn1cIl0pXG4gICAgICByZXR1cm4gc3RhdGVtZW50XG4gICAgfVxuICAgIGlmIChwYXJ0c1tpbmRleF0/LnRleHQgIT0gXCJlbHNlXCIpIHRoaXMuZmFpbChwYXJ0c1tpbmRleF0gPz8gbm9kZSwgXCJpZiBhbHRlcm5hdGUgc2hhcGVcIilcbiAgICBpbmRleCArPSAxXG4gICAgY29uc3QgYnJhbmNoID0gcGFydHNbaW5kZXhdXG5cbiAgICBpZiAoYnJhbmNoPy50eXBlID09IFwiaWZfc3RhdGVtZW50XCIgJiYgaW5kZXggKyAxID09IHBhcnRzLmxlbmd0aCkge1xuICAgICAgdGhpcy5zaGFwZShub2RlLCBbXCJpZlwiLCBjb25kaXRpb24sIFwie1wiLCAuLi4oY29uc2VxdWVudFN0YXRlbWVudHMgPyBbY29uc2VxdWVudFN0YXRlbWVudHNdIDogW10pLCBcIn1cIiwgXCJlbHNlXCIsIGJyYW5jaF0pXG4gICAgICByZXR1cm4gey4uLnN0YXRlbWVudCwgYWx0ZXJuYXRlOiB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQmxvY2tcIiksIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKGJyYW5jaCksIHN0YXRlbWVudHM6IFt0aGlzLmNvbmRpdGlvbmFsKGJyYW5jaCldfX1cbiAgICB9XG4gICAgaWYgKGJyYW5jaD8udGV4dCAhPSBcIntcIikgdGhpcy5mYWlsKGJyYW5jaCA/PyBub2RlLCBcImlmIGFsdGVybmF0ZSBibG9jayBzaGFwZVwiKVxuICAgIGluZGV4ICs9IDFcbiAgICBjb25zdCBhbHRlcm5hdGVTdGF0ZW1lbnRzID0gcGFydHNbaW5kZXhdPy50eXBlID09IFwic3RhdGVtZW50c1wiID8gcGFydHNbaW5kZXgrK10gOiB1bmRlZmluZWRcblxuICAgIGlmIChwYXJ0c1tpbmRleF0/LnRleHQgIT0gXCJ9XCIgfHwgaW5kZXggKyAxICE9IHBhcnRzLmxlbmd0aCkgdGhpcy5mYWlsKHBhcnRzW2luZGV4XSA/PyBub2RlLCBcImlmIGFsdGVybmF0ZSBibG9jayBzaGFwZVwiKVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiaWZcIiwgY29uZGl0aW9uLCBcIntcIiwgLi4uKGNvbnNlcXVlbnRTdGF0ZW1lbnRzID8gW2NvbnNlcXVlbnRTdGF0ZW1lbnRzXSA6IFtdKSwgXCJ9XCIsIFwiZWxzZVwiLCBcIntcIixcbiAgICAgIC4uLihhbHRlcm5hdGVTdGF0ZW1lbnRzID8gW2FsdGVybmF0ZVN0YXRlbWVudHNdIDogW10pLCBcIn1cIl0pXG4gICAgcmV0dXJuIHsuLi5zdGF0ZW1lbnQsIGFsdGVybmF0ZToge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJsb2NrXCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihhbHRlcm5hdGVTdGF0ZW1lbnRzID8/IG5vZGUpLFxuICAgICAgc3RhdGVtZW50czogdGhpcy5zdGF0ZW1lbnRzKGFsdGVybmF0ZVN0YXRlbWVudHMpfX1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgZnVuY3Rpb24gYm9keS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gRnVuY3Rpb24gYm9keS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBTZW1hbnRpYyBibG9jay5cbiAgICovXG4gIGJsb2NrKG5vZGUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcbiAgICBjb25zdCBzdGF0ZW1lbnRzID0gcGFydHNbMV0/LnR5cGUgPT0gXCJzdGF0ZW1lbnRzXCIgPyBwYXJ0c1sxXSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImZ1bmN0aW9uX2JvZHlcIikgdGhpcy5mYWlsKG5vZGUsIFwiZnVuY3Rpb24gYm9keSBzaGFwZVwiKVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW1wie1wiLCAuLi4oc3RhdGVtZW50cyA/IFtzdGF0ZW1lbnRzXSA6IFtdKSwgXCJ9XCJdKVxuICAgIHJldHVybiB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQmxvY2tcIiksIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBzdGF0ZW1lbnRzOiB0aGlzLnN0YXRlbWVudHMoc3RhdGVtZW50cyl9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGV4YWN0IHVuZGVyc2NvcmUtbGFiZWxlZCBwYXJhbWV0ZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIFBhcmFtZXRlciBub2RlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUGFyYW1ldGVyfSBTZW1hbnRpYyBwYXJhbWV0ZXIuXG4gICAqL1xuICBwYXJhbWV0ZXIobm9kZSkge1xuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgaWYgKG5vZGUudHlwZSAhPSBcInBhcmFtZXRlclwiIHx8IHBhcnRzLmxlbmd0aCAhPSA0IHx8IHBhcnRzWzBdLnRleHQgIT0gXCJfXCIgfHwgcGFydHNbMF0udHlwZSAhPSBcInNpbXBsZV9pZGVudGlmaWVyXCIgfHxcbiAgICAgIHBhcnRzWzFdLnR5cGUgIT0gXCJzaW1wbGVfaWRlbnRpZmllclwiIHx8IHBhcnRzWzJdLnRleHQgIT0gXCI6XCIpIHRoaXMuZmFpbChub2RlLCBcInBhcmFtZXRlciBzaGFwZVwiKVxuICAgIHRoaXMuc2hhcGUobm9kZSwgW3BhcnRzWzBdLCBwYXJ0c1sxXSwgXCI6XCIsIHBhcnRzWzNdXSlcbiAgICBjb25zdCBuYW1lID0gdGhpcy5pZGVudGlmaWVyKHBhcnRzWzFdKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlBhcmFtZXRlclwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24obm9kZSksIG5hbWUsIHR5cGU6IHRoaXMudHlwZShwYXJ0c1szXSl9LCB7XG4gICAgICBuYW1lOiB0aGlzLmxvY2F0aW9uKHBhcnRzWzFdKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIHN5bmNocm9ub3VzIHRvcC1sZXZlbCBzY2FsYXIgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIEZ1bmN0aW9uIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBTZW1hbnRpYyBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcbiAgICBjb25zdCBuYW1lTm9kZSA9IG5vZGUuY2hpbGRGb3JGaWVsZE5hbWUoXCJuYW1lXCIpXG4gICAgY29uc3QgYm9keSA9IG5vZGUuY2hpbGRGb3JGaWVsZE5hbWUoXCJib2R5XCIpXG4gICAgY29uc3QgcGFyYW1ldGVycyA9IHBhcnRzLmZpbHRlcigocGFydCkgPT4gcGFydC50eXBlID09IFwicGFyYW1ldGVyXCIpXG5cbiAgICBpZiAoIW5hbWVOb2RlIHx8ICFib2R5IHx8IG5vZGUudHlwZSAhPSBcImZ1bmN0aW9uX2RlY2xhcmF0aW9uXCIpIHRoaXMuZmFpbChub2RlLCBcImZ1bmN0aW9uIGRlY2xhcmF0aW9uIHNoYXBlXCIpXG4gICAgaWYgKHBhcmFtZXRlcnMubGVuZ3RoICE9IDIpIHRoaXMuZmFpbChub2RlLCBcImZ1bmN0aW9uIHBhcmFtZXRlciBjb3VudCBvdGhlciB0aGFuIHR3b1wiKVxuICAgIGlmICghcGFydHMuc29tZSgocGFydCkgPT4gcGFydC50ZXh0ID09IFwiLT5cIikpIHJldHVybiBtaXNzaW5nVHlwZShcInN3aWZ0XCIsIFwiRnVuY3Rpb24gcmV0dXJuXCIsIHRoaXMubG9jYXRpb24obm9kZSkpXG4gICAgaWYgKHBhcnRzLmxlbmd0aCAhPSAxMCkgdGhpcy5mYWlsKHBhcnRzLmZpbmQoKHBhcnQpID0+ICFbXCJmdW5jXCIsIFwiKFwiLCBcIixcIiwgXCIpXCIsIFwiLT5cIl0uaW5jbHVkZXMocGFydC50ZXh0KSAmJlxuICAgICAgcGFydC5pZCAhPSBuYW1lTm9kZS5pZCAmJiBwYXJ0LmlkICE9IGJvZHkuaWQgJiYgIXBhcmFtZXRlcnMuc29tZSgocGFyYW1ldGVyKSA9PiBwYXJhbWV0ZXIuaWQgPT0gcGFydC5pZCkpID8/IG5vZGUsIFwiZnVuY3Rpb24gZGVjbGFyYXRpb24gc2hhcGVcIilcbiAgICBjb25zdCByZXR1cm5UeXBlID0gcGFydHNbOF1cblxuICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiZnVuY1wiLCBuYW1lTm9kZSwgXCIoXCIsIHBhcmFtZXRlcnNbMF0sIFwiLFwiLCBwYXJhbWV0ZXJzWzFdLCBcIilcIiwgXCItPlwiLCByZXR1cm5UeXBlLCBib2R5XSlcbiAgICBjb25zdCBuYW1lID0gdGhpcy5pZGVudGlmaWVyKG5hbWVOb2RlKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgYm9keTogdGhpcy5ibG9jayhib2R5KSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIiksXG4gICAgICBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSxcbiAgICAgIG5hbWUsXG4gICAgICBwYXJhbWV0ZXJzOiBwYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PiB0aGlzLnBhcmFtZXRlcihwYXJhbWV0ZXIpKSxcbiAgICAgIHJldHVyblR5cGU6IHRoaXMudHlwZShyZXR1cm5UeXBlKVxuICAgIH0sIHtuYW1lOiB0aGlzLmxvY2F0aW9uKG5hbWVOb2RlKX0pXG4gIH1cblxuICAvKipcbiAgICogQ29tcGFyZXMgZXZlcnkgY2hpbGQgZmllbGQgYW5kIGxlYWYgdG9rZW4gYWdhaW5zdCB0YXJnZXQtb25seSBjYW5vbmljYWwgc3VwcG9ydC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBhY3R1YWwgLSBTb3VyY2Ugc3VwcG9ydCBub2RlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IGV4cGVjdGVkIC0gQ2Fub25pY2FsIHN1cHBvcnQgbm9kZS5cbiAgICogQHBhcmFtIHtTd2lmdFJlYWRlcn0gY2Fub25pY2FsIC0gQ2Fub25pY2FsIHNvdXJjZSByZWFkZXIuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgY29tcGFyZVRyZWUoYWN0dWFsLCBleHBlY3RlZCwgY2Fub25pY2FsKSB7XG4gICAgaWYgKGFjdHVhbC50eXBlICE9IGV4cGVjdGVkLnR5cGUgfHwgYWN0dWFsLmlzTmFtZWQgIT0gZXhwZWN0ZWQuaXNOYW1lZCB8fCBhY3R1YWwuaXNFeHRyYSAhPSBleHBlY3RlZC5pc0V4dHJhIHx8XG4gICAgICBhY3R1YWwuY2hpbGRDb3VudCAhPSBleHBlY3RlZC5jaGlsZENvdW50KSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFN3aWZ0IHN1cHBvcnQgbm9kZVwiKVxuICAgIGlmICghYWN0dWFsLmNoaWxkQ291bnQgJiYgYWN0dWFsLnRleHQgIT0gZXhwZWN0ZWQudGV4dCkgdGhpcy5mYWlsKGFjdHVhbCwgXCJtb2RpZmllZCBTd2lmdCBzdXBwb3J0IHRva2VuXCIpXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGFjdHVhbC5jaGlsZENvdW50OyBpbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBsZWZ0ID0gYWN0dWFsLmNoaWxkKGluZGV4KVxuICAgICAgY29uc3QgcmlnaHQgPSBleHBlY3RlZC5jaGlsZChpbmRleClcblxuICAgICAgaWYgKCFsZWZ0IHx8ICFyaWdodCB8fCBhY3R1YWwuZmllbGROYW1lRm9yQ2hpbGQoaW5kZXgpICE9IGV4cGVjdGVkLmZpZWxkTmFtZUZvckNoaWxkKGluZGV4KSkge1xuICAgICAgICB0aGlzLmZhaWwobGVmdCA/PyBhY3R1YWwsIFwibW9kaWZpZWQgU3dpZnQgc3VwcG9ydCBmaWVsZFwiKVxuICAgICAgfVxuICAgICAgdGhpcy5jb21wYXJlVHJlZShsZWZ0LCByaWdodCwgY2Fub25pY2FsKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWplY3RzIG9yZGluYXJ5IFN3aWZ0IGVxdWFsaXR5IGFmdGVyIHNoYXJlZCB0eXBlIHJlc29sdXRpb24gaWRlbnRpZmllcyBTdHJpbmdzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBWYWxpZGF0ZWQgc2VtYW50aWMgbW9kdWxlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHJlamVjdE5hdGl2ZVN0cmluZ0VxdWFsaXR5KG1vZHVsZSkge1xuICAgIGNvbnN0IHBlbmRpbmcgPSBbbW9kdWxlLmVudHJ5UG9pbnQuYm9keSwgLi4ubW9kdWxlLmZ1bmN0aW9ucy5tYXAoKGRlY2xhcmF0aW9uKSA9PiBkZWNsYXJhdGlvbi5ib2R5KV1cblxuICAgIHdoaWxlIChwZW5kaW5nLmxlbmd0aCkge1xuICAgICAgY29uc3QgYmxvY2sgPSBwZW5kaW5nLnBvcCgpXG5cbiAgICAgIGlmICghYmxvY2spIHRocm93IG5ldyBFcnJvcihcIlN3aWZ0IHNlbWFudGljIHRyYXZlcnNhbCBsb3N0IGEgcGVuZGluZyBibG9jay5cIilcbiAgICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJsb2NrLnN0YXRlbWVudHMpIHtcbiAgICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgICAgIHBlbmRpbmcucHVzaChzdGF0ZW1lbnQuY29uc2VxdWVudClcbiAgICAgICAgICBpZiAoc3RhdGVtZW50LmFsdGVybmF0ZSkgcGVuZGluZy5wdXNoKHN0YXRlbWVudC5hbHRlcm5hdGUpXG4gICAgICAgICAgdGhpcy5yZWplY3ROYXRpdmVTdHJpbmdFcXVhbGl0eUV4cHJlc3Npb24oc3RhdGVtZW50LmNvbmRpdGlvbilcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIikgdGhpcy5yZWplY3ROYXRpdmVTdHJpbmdFcXVhbGl0eUV4cHJlc3Npb24oc3RhdGVtZW50LmluaXRpYWxpemVyKVxuICAgICAgICBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIikgdGhpcy5yZWplY3ROYXRpdmVTdHJpbmdFcXVhbGl0eUV4cHJlc3Npb24oc3RhdGVtZW50LmV4cHJlc3Npb24pXG4gICAgICAgIGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgICAgICAgIHRoaXMucmVqZWN0TmF0aXZlU3RyaW5nRXF1YWxpdHlFeHByZXNzaW9uKHN0YXRlbWVudC5leHByZXNzaW9uKVxuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIgJiYgc3RhdGVtZW50LmV4cHJlc3Npb24pIHtcbiAgICAgICAgICB0aGlzLnJlamVjdE5hdGl2ZVN0cmluZ0VxdWFsaXR5RXhwcmVzc2lvbihzdGF0ZW1lbnQuZXhwcmVzc2lvbilcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3Mgb25lIHZhbGlkYXRlZCBleHByZXNzaW9uIHdpdGhvdXQgcmV0YWluaW5nIHBhcnNlciBzdGF0ZSBpbiBwdWJsaWMgdmFsdWVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IHJvb3QgLSBWYWxpZGF0ZWQgZXhwcmVzc2lvbi5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICByZWplY3ROYXRpdmVTdHJpbmdFcXVhbGl0eUV4cHJlc3Npb24ocm9vdCkge1xuICAgIGNvbnN0IHBlbmRpbmcgPSBbcm9vdF1cblxuICAgIHdoaWxlIChwZW5kaW5nLmxlbmd0aCkge1xuICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IHBlbmRpbmcucG9wKClcblxuICAgICAgaWYgKCFleHByZXNzaW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJTd2lmdCBzZW1hbnRpYyB0cmF2ZXJzYWwgbG9zdCBhIHBlbmRpbmcgZXhwcmVzc2lvbi5cIilcbiAgICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIpIHtcbiAgICAgICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLm5hdGl2ZUVxdWFsaXR5T3BlcmF0b3JzLmdldChleHByZXNzaW9uKVxuXG4gICAgICAgIGlmIChvcGVyYXRvciAmJiBbXCJTdHJpbmdFcXVhbFwiLCBcIlN0cmluZ05vdEVxdWFsXCJdLmluY2x1ZGVzKGV4cHJlc3Npb24ub3BlcmF0aW9uKSkge1xuICAgICAgICAgIHRoaXMuZmFpbChvcGVyYXRvciwgXCJvcmRpbmFyeSBTd2lmdCBTdHJpbmcgZXF1YWxpdHlcIilcbiAgICAgICAgfVxuICAgICAgICBwZW5kaW5nLnB1c2goZXhwcmVzc2lvbi5sZWZ0LCBleHByZXNzaW9uLnJpZ2h0KVxuICAgICAgfSBlbHNlIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJVbmFyeUV4cHJlc3Npb25cIikgcGVuZGluZy5wdXNoKGV4cHJlc3Npb24ub3BlcmFuZClcbiAgICAgIGVsc2UgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIpIHBlbmRpbmcucHVzaCguLi5leHByZXNzaW9uLmFyZ3VtZW50cylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgdGhlIGNvbXBsZXRlIHNvdXJjZSBmaWxlIHdpdGggZGVjbGFyYXRpb25zIGJlZm9yZSB0b3AtbGV2ZWwgZW50cnkgc3RhdGVtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSByb290IC0gU291cmNlIHJvb3QuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gU2VtYW50aWMgbW9kdWxlLlxuICAgKi9cbiAgbW9kdWxlKHJvb3QpIHtcbiAgICB0aGlzLnZhbGlkYXRlVHJlZShyb290KVxuICAgIGlmIChyb290LnR5cGUgIT0gXCJzb3VyY2VfZmlsZVwiKSB0aGlzLmZhaWwocm9vdCwgXCJzb3VyY2UgZmlsZSByb290XCIpXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKHJvb3QpXG4gICAgY29uc3QgY2Fub25pY2FsID0gbmV3IFN3aWZ0UmVhZGVyKHRoaXMuZmlsZW5hbWUsIHN3aWZ0UnVudGltZSlcbiAgICBjb25zdCBzdXBwb3J0ID0gY2Fub25pY2FsLnBhcnRzKHBhcnNlci5wYXJzZShzd2lmdFJ1bnRpbWUpLnJvb3ROb2RlKVxuICAgIGxldCBzdXBwb3J0SW5kZXggPSAwXG5cbiAgICB3aGlsZSAoc3VwcG9ydEluZGV4IDwgcGFydHMubGVuZ3RoICYmIHN1cHBvcnRJbmRleCA8IHN1cHBvcnQubGVuZ3RoKSB7XG4gICAgICBjb25zdCBub2RlID0gcGFydHNbc3VwcG9ydEluZGV4XVxuICAgICAgY29uc3QgbmFtZSA9IG5vZGUudHlwZSA9PSBcImZ1bmN0aW9uX2RlY2xhcmF0aW9uXCIgPyBub2RlLmNoaWxkRm9yRmllbGROYW1lKFwibmFtZVwiKSA6IHVuZGVmaW5lZFxuICAgICAgY29uc3QgZXhwZWN0ZWROYW1lID0gc3VwcG9ydFtzdXBwb3J0SW5kZXhdLmNoaWxkRm9yRmllbGROYW1lKFwibmFtZVwiKVxuXG4gICAgICBpZiAoIW5hbWUgfHwgIWV4cGVjdGVkTmFtZSB8fCBuYW1lLnRleHQgIT0gZXhwZWN0ZWROYW1lLnRleHQpIGJyZWFrXG4gICAgICB0aGlzLmNvbXBhcmVUcmVlKG5vZGUsIHN1cHBvcnRbc3VwcG9ydEluZGV4XSwgY2Fub25pY2FsKVxuICAgICAgaWYgKGhlbHBlck9wZXJhdGlvbnMuaGFzKG5hbWUudGV4dCkpIHRoaXMuaGVscGVycy5hZGQobmFtZS50ZXh0KVxuICAgICAgZWxzZSBpZiAobmFtZS50ZXh0ID09IFwic2VtYW50aWZvbGRfa2VlcF9tdXRhYmxlXCIpIHRoaXMubXV0YWJsZU1hcmtlciA9IHRydWVcbiAgICAgIHN1cHBvcnRJbmRleCArPSAxXG4gICAgfVxuICAgIGlmIChzdXBwb3J0SW5kZXggPiAwICYmIHN1cHBvcnRJbmRleCAhPSBzdXBwb3J0Lmxlbmd0aCkgdGhpcy5mYWlsKHBhcnRzW3N1cHBvcnRJbmRleCAtIDFdLCBcImNvbXBsZXRlIFN3aWZ0IHN1cHBvcnQgcmVxdWlyZWRcIilcbiAgICBjb25zdCBzZW1hbnRpY1BhcnRzID0gcGFydHMuc2xpY2Uoc3VwcG9ydEluZGV4KVxuICAgIGNvbnN0IGZpcnN0RW50cnkgPSBzZW1hbnRpY1BhcnRzLmZpbmRJbmRleCgobm9kZSkgPT4gbm9kZS50eXBlICE9IFwiZnVuY3Rpb25fZGVjbGFyYXRpb25cIilcbiAgICBjb25zdCBzcGxpdCA9IGZpcnN0RW50cnkgPCAwID8gc2VtYW50aWNQYXJ0cy5sZW5ndGggOiBmaXJzdEVudHJ5XG4gICAgY29uc3QgZGVjbGFyYXRpb25zID0gc2VtYW50aWNQYXJ0cy5zbGljZSgwLCBzcGxpdClcbiAgICBjb25zdCBlbnRyaWVzID0gc2VtYW50aWNQYXJ0cy5zbGljZShzcGxpdClcblxuICAgIGlmICghZGVjbGFyYXRpb25zLmxlbmd0aCkgdGhpcy5mYWlsKHJvb3QsIFwidG9wLWxldmVsIHNlbWFudGljIGZ1bmN0aW9uIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgbGF0ZXJGdW5jdGlvbiA9IGVudHJpZXMuZmluZCgobm9kZSkgPT4gbm9kZS50eXBlID09IFwiZnVuY3Rpb25fZGVjbGFyYXRpb25cIilcbiAgICBjb25zdCB1bnN1cHBvcnRlZEVudHJ5ID0gZW50cmllcy5maW5kKChub2RlKSA9PiAhW1wiYXNzaWdubWVudFwiLCBcImNhbGxfZXhwcmVzc2lvblwiLCBcImNvbnRyb2xfdHJhbnNmZXJfc3RhdGVtZW50XCIsIFwiaWZfc3RhdGVtZW50XCIsXG4gICAgICBcInByb3BlcnR5X2RlY2xhcmF0aW9uXCIsIFwiZnVuY3Rpb25fZGVjbGFyYXRpb25cIl0uaW5jbHVkZXMobm9kZS50eXBlKSlcblxuICAgIGlmICh1bnN1cHBvcnRlZEVudHJ5KSB0aGlzLmZhaWwodW5zdXBwb3J0ZWRFbnRyeSlcbiAgICBpZiAobGF0ZXJGdW5jdGlvbikgdGhpcy5mYWlsKGxhdGVyRnVuY3Rpb24sIFwiZnVuY3Rpb24gZGVjbGFyYXRpb24gYWZ0ZXIgZW50cnkgc3RhdGVtZW50XCIpXG4gICAgaWYgKCFlbnRyaWVzLmxlbmd0aCkgdGhpcy5mYWlsKHJvb3QsIFwidG9wLWxldmVsIGVudHJ5L3ByaW50IHNoZWxsIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgbW9kdWxlID0ge1xuICAgICAgZW50cnlQb2ludDoge2JvZHk6IHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCbG9ja1wiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24ocm9vdCksXG4gICAgICAgIHN0YXRlbWVudHM6IHRoaXMuc3RhdGVtZW50TGlzdChlbnRyaWVzKX0sIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkVudHJ5UG9pbnRcIiksIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKHJvb3QpfSxcbiAgICAgIGZ1bmN0aW9uczogZGVjbGFyYXRpb25zLm1hcCgoZGVjbGFyYXRpb24pID0+IHRoaXMuZnVuY3Rpb24oZGVjbGFyYXRpb24pKSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk1vZHVsZVwiKSxcbiAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKHJvb3QpXG4gICAgfVxuXG4gICAgdmFsaWRhdGVQYXJzZWRNb2R1bGUobW9kdWxlLCBcInN3aWZ0XCIpXG4gICAgdGhpcy5yZWplY3ROYXRpdmVTdHJpbmdFcXVhbGl0eShtb2R1bGUpXG4gICAgcmV0dXJuIG1vZHVsZVxuICB9XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSBzdHJpY3QgVGFzayAwMjIgU3dpZnQgcHJvZmlsZSB0aHJvdWdoIHRoZSBxdWFsaWZpZWQgZ3JhbW1hci5cbiAqIEBwYXJhbSB7e2ZpbGVuYW1lOiBzdHJpbmcsIHNvdXJjZTogc3RyaW5nfX0gaW5wdXQgLSBFeGFjdCBzb3VyY2UgcmVxdWVzdC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gU2VtYW50aWMgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTd2lmdCh7ZmlsZW5hbWUsIHNvdXJjZX0pIHtcbiAgaWYgKCFoYXNPbmx5VW5pY29kZVNjYWxhcnMoc291cmNlKSkge1xuICAgIGNvbnN0IG9mZnNldCA9IGZpcnN0TG9uZVN1cnJvZ2F0ZU9mZnNldChzb3VyY2UpXG5cbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgIGNvZGU6IFwiUEFSU0VfRVJST1JcIixcbiAgICAgIGxhbmd1YWdlOiBcInN3aWZ0XCIsXG4gICAgICBsb2NhdGlvbjogbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCBvZmZzZXQsIG9mZnNldCArIDEpLFxuICAgICAgbWVzc2FnZTogXCJTd2lmdCBzb3VyY2UgY29udGFpbnMgYW4gaW52YWxpZCBsb25lIFVURi0xNiBzdXJyb2dhdGUuXCJcbiAgICB9KVxuICB9XG4gIGxldCB0cmVlXG5cbiAgdHJ5IHtcbiAgICB0cmVlID0gcGFyc2VyLnBhcnNlKHNvdXJjZSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgIGNhdXNlOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiB1bmRlZmluZWQsXG4gICAgICBjb2RlOiBcIlBBUlNFX0VSUk9SXCIsXG4gICAgICBsYW5ndWFnZTogXCJzd2lmdFwiLFxuICAgICAgbG9jYXRpb246IG1vZHVsZUxvY2F0aW9uKGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgbWVzc2FnZTogXCJUaGUgcXVhbGlmaWVkIFN3aWZ0IHBhcnNlciBjb3VsZCBub3QgcHJvZHVjZSBhIGNvbXBsZXRlIENTVC5cIlxuICAgIH0pXG4gIH1cbiAgcmV0dXJuIG5ldyBTd2lmdFJlYWRlcihmaWxlbmFtZSwgc291cmNlKS5tb2R1bGUodHJlZS5yb290Tm9kZSlcbn1cbiJdfQ==
|