semantifold 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -15
- package/build/index.d.ts +48 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +57 -8
- package/build/src/artifact-path.d.ts +23 -1
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +45 -3
- package/build/src/artifacts.d.ts.map +1 -1
- package/build/src/artifacts.js +66 -1
- package/build/src/backends/c-validation.d.ts.map +1 -1
- package/build/src/backends/c-validation.js +7 -3
- package/build/src/backends/cpp-validation.d.ts.map +1 -1
- package/build/src/backends/cpp-validation.js +7 -3
- package/build/src/backends/csharp.js +7 -1
- package/build/src/backends/dart-runtime.d.ts +2 -0
- package/build/src/backends/dart-runtime.d.ts.map +1 -0
- package/build/src/backends/dart-runtime.js +41 -0
- package/build/src/backends/dart.d.ts +20 -0
- package/build/src/backends/dart.d.ts.map +1 -0
- package/build/src/backends/dart.js +321 -0
- package/build/src/backends/effects.d.ts +60 -0
- package/build/src/backends/effects.d.ts.map +1 -0
- package/build/src/backends/effects.js +746 -0
- package/build/src/backends/go.js +18 -4
- package/build/src/backends/identifiers.d.ts +36 -4
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +154 -10
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -4
- package/build/src/backends/ios.d.ts +68 -0
- package/build/src/backends/ios.d.ts.map +1 -0
- package/build/src/backends/ios.js +1503 -0
- package/build/src/backends/java.d.ts.map +1 -1
- package/build/src/backends/java.js +429 -36
- package/build/src/backends/javascript.d.ts +6 -0
- package/build/src/backends/javascript.d.ts.map +1 -1
- package/build/src/backends/javascript.js +380 -24
- package/build/src/backends/kotlin-runtime.d.ts +3 -0
- package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
- package/build/src/backends/kotlin-runtime.js +29 -0
- package/build/src/backends/kotlin.d.ts +23 -0
- package/build/src/backends/kotlin.d.ts.map +1 -0
- package/build/src/backends/kotlin.js +136 -0
- package/build/src/backends/native-validation.d.ts +2 -2
- package/build/src/backends/native-validation.d.ts.map +1 -1
- package/build/src/backends/native-validation.js +2 -2
- package/build/src/backends/ordered-expressions.d.ts.map +1 -1
- package/build/src/backends/ordered-expressions.js +39 -7
- package/build/src/backends/php-stdlib-support.d.ts +19 -0
- package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
- package/build/src/backends/php-stdlib-support.js +227 -0
- package/build/src/backends/php.d.ts.map +1 -1
- package/build/src/backends/php.js +448 -33
- package/build/src/backends/program.d.ts +81 -0
- package/build/src/backends/program.d.ts.map +1 -0
- package/build/src/backends/program.js +1308 -0
- package/build/src/backends/python.js +7 -1
- package/build/src/backends/ruby.d.ts.map +1 -1
- package/build/src/backends/ruby.js +310 -24
- package/build/src/backends/rust-runtime.d.ts +7 -0
- package/build/src/backends/rust-runtime.d.ts.map +1 -0
- package/build/src/backends/rust-runtime.js +32 -0
- package/build/src/backends/rust-validation.d.ts +9 -0
- package/build/src/backends/rust-validation.d.ts.map +1 -0
- package/build/src/backends/rust-validation.js +78 -0
- package/build/src/backends/rust.d.ts +24 -0
- package/build/src/backends/rust.d.ts.map +1 -0
- package/build/src/backends/rust.js +344 -0
- package/build/src/backends/scalars.d.ts +14 -6
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +167 -17
- package/build/src/backends/shared.d.ts +23 -4
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +2158 -62
- package/build/src/backends/stdlib-support.d.ts +14 -0
- package/build/src/backends/stdlib-support.d.ts.map +1 -0
- package/build/src/backends/stdlib-support.js +237 -0
- package/build/src/backends/swift-runtime.d.ts +3 -0
- package/build/src/backends/swift-runtime.d.ts.map +1 -0
- package/build/src/backends/swift-runtime.js +14 -0
- package/build/src/backends/swift.d.ts +8 -0
- package/build/src/backends/swift.d.ts.map +1 -0
- package/build/src/backends/swift.js +127 -0
- package/build/src/backends/typescript.d.ts.map +1 -1
- package/build/src/backends/typescript.js +344 -24
- package/build/src/backends/wasm.d.ts +43 -0
- package/build/src/backends/wasm.d.ts.map +1 -0
- package/build/src/backends/wasm.js +2164 -0
- package/build/src/backends/writer.d.ts +235 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +468 -3
- package/build/src/diagnostic.d.ts +4 -3
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +5 -3
- package/build/src/frontends/c.d.ts.map +1 -1
- package/build/src/frontends/c.js +5 -3
- package/build/src/frontends/cpp.d.ts.map +1 -1
- package/build/src/frontends/cpp.js +5 -3
- package/build/src/frontends/csharp.d.ts.map +1 -1
- package/build/src/frontends/csharp.js +7 -3
- package/build/src/frontends/dart.d.ts +10 -0
- package/build/src/frontends/dart.d.ts.map +1 -0
- package/build/src/frontends/dart.js +913 -0
- package/build/src/frontends/index.d.ts +3 -1
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +15 -5
- package/build/src/frontends/java.d.ts +110 -1
- package/build/src/frontends/java.d.ts.map +1 -1
- package/build/src/frontends/java.js +1725 -70
- package/build/src/frontends/javascript-typescript.d.ts +69 -1
- package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
- package/build/src/frontends/javascript-typescript.js +1825 -93
- package/build/src/frontends/kotlin.d.ts +10 -0
- package/build/src/frontends/kotlin.d.ts.map +1 -0
- package/build/src/frontends/kotlin.js +685 -0
- package/build/src/frontends/php.d.ts +118 -1
- package/build/src/frontends/php.d.ts.map +1 -1
- package/build/src/frontends/php.js +1583 -76
- package/build/src/frontends/program.d.ts +74 -0
- package/build/src/frontends/program.d.ts.map +1 -0
- package/build/src/frontends/program.js +989 -0
- package/build/src/frontends/ruby.d.ts +68 -1
- package/build/src/frontends/ruby.d.ts.map +1 -1
- package/build/src/frontends/ruby.js +1446 -101
- package/build/src/frontends/rust-parser.d.ts +11 -0
- package/build/src/frontends/rust-parser.d.ts.map +1 -0
- package/build/src/frontends/rust-parser.js +15 -0
- package/build/src/frontends/rust.d.ts +14 -0
- package/build/src/frontends/rust.d.ts.map +1 -0
- package/build/src/frontends/rust.js +715 -0
- package/build/src/frontends/scalars.d.ts +10 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +28 -2
- package/build/src/frontends/swift.d.ts +10 -0
- package/build/src/frontends/swift.d.ts.map +1 -0
- package/build/src/frontends/swift.js +860 -0
- package/build/src/frontends/types.d.ts +186 -0
- package/build/src/frontends/types.d.ts.map +1 -0
- package/build/src/frontends/types.js +634 -0
- package/build/src/language-registry.d.ts +46 -4
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +167 -13
- package/build/src/mapping.d.ts +2 -2
- package/build/src/mapping.d.ts.map +1 -1
- package/build/src/mapping.js +31 -10
- package/build/src/semantic/capabilities.d.ts +66 -0
- package/build/src/semantic/capabilities.d.ts.map +1 -0
- package/build/src/semantic/capabilities.js +649 -0
- package/build/src/semantic/effects.d.ts +26 -0
- package/build/src/semantic/effects.d.ts.map +1 -0
- package/build/src/semantic/effects.js +764 -0
- package/build/src/semantic/generics.d.ts +23 -0
- package/build/src/semantic/generics.d.ts.map +1 -0
- package/build/src/semantic/generics.js +61 -0
- package/build/src/semantic/lifetime.d.ts +37 -0
- package/build/src/semantic/lifetime.d.ts.map +1 -0
- package/build/src/semantic/lifetime.js +527 -0
- package/build/src/semantic/provenance.d.ts +9 -2
- package/build/src/semantic/provenance.d.ts.map +1 -1
- package/build/src/semantic/provenance.js +462 -20
- package/build/src/semantic/scalars.d.ts +11 -0
- package/build/src/semantic/scalars.d.ts.map +1 -1
- package/build/src/semantic/scalars.js +16 -1
- package/build/src/semantic/stdlib.d.ts +254 -0
- package/build/src/semantic/stdlib.d.ts.map +1 -0
- package/build/src/semantic/stdlib.js +880 -0
- package/build/src/semantic/types.d.ts +2952 -202
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +688 -15
- package/build/src/semantic/validate.d.ts +85 -5
- package/build/src/semantic/validate.d.ts.map +1 -1
- package/build/src/semantic/validate.js +2576 -98
- package/build/src/stdlib-facades.d.ts +304 -0
- package/build/src/stdlib-facades.d.ts.map +1 -0
- package/build/src/stdlib-facades.js +1167 -0
- package/build/src/stdlib-negotiation.d.ts +69 -0
- package/build/src/stdlib-negotiation.d.ts.map +1 -0
- package/build/src/stdlib-negotiation.js +403 -0
- package/build/src/stdlib-providers.d.ts +72 -0
- package/build/src/stdlib-providers.d.ts.map +1 -0
- package/build/src/stdlib-providers.js +339 -0
- package/build/src/toolchains.d.ts +55 -1
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +15 -4
- package/docs/architecture.md +45 -13
- package/docs/dart.md +60 -0
- package/docs/goals.md +3 -3
- package/docs/ios.md +121 -0
- package/docs/kotlin.md +42 -0
- package/docs/language-support.md +231 -26
- package/docs/multi-file-modules.md +52 -0
- package/docs/parser-qualification.md +121 -8
- package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
- package/docs/rust.md +88 -0
- package/docs/source-maps.md +15 -7
- package/docs/standard-library-portability.md +39 -8
- package/docs/swift.md +44 -0
- package/docs/testing.md +366 -4
- package/docs/webassembly.md +52 -0
- package/index.js +63 -8
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
- package/package.json +5 -2
- package/src/artifact-path.js +47 -2
- package/src/artifacts.js +67 -0
- package/src/backends/c-validation.js +6 -1
- package/src/backends/cpp-validation.js +6 -1
- package/src/backends/csharp.js +3 -0
- package/src/backends/dart-runtime.js +41 -0
- package/src/backends/dart.js +326 -0
- package/src/backends/effects.js +705 -0
- package/src/backends/go.js +14 -2
- package/src/backends/identifiers.js +160 -9
- package/src/backends/index.js +27 -2
- package/src/backends/ios.js +1612 -0
- package/src/backends/java.js +454 -36
- package/src/backends/javascript.js +389 -23
- package/src/backends/kotlin-runtime.js +29 -0
- package/src/backends/kotlin.js +141 -0
- package/src/backends/native-validation.js +1 -1
- package/src/backends/ordered-expressions.js +40 -6
- package/src/backends/php-stdlib-support.js +239 -0
- package/src/backends/php.js +469 -32
- package/src/backends/program.js +1407 -0
- package/src/backends/python.js +3 -0
- package/src/backends/ruby.js +326 -23
- package/src/backends/rust-runtime.js +34 -0
- package/src/backends/rust-validation.js +75 -0
- package/src/backends/rust.js +335 -0
- package/src/backends/scalars.js +141 -16
- package/src/backends/shared.js +2304 -124
- package/src/backends/stdlib-support.js +234 -0
- package/src/backends/swift-runtime.js +14 -0
- package/src/backends/swift.js +132 -0
- package/src/backends/typescript.js +349 -23
- package/src/backends/wasm.js +2208 -0
- package/src/backends/writer.js +520 -2
- package/src/diagnostic.js +4 -2
- package/src/frontends/c.js +4 -2
- package/src/frontends/cpp.js +4 -2
- package/src/frontends/csharp.js +4 -2
- package/src/frontends/dart.js +963 -0
- package/src/frontends/index.js +14 -4
- package/src/frontends/java.js +1977 -69
- package/src/frontends/javascript-typescript.js +2046 -102
- package/src/frontends/kotlin.js +713 -0
- package/src/frontends/php.js +1725 -79
- package/src/frontends/program.js +1062 -0
- package/src/frontends/ruby.js +1624 -98
- package/src/frontends/rust-parser.js +18 -0
- package/src/frontends/rust.js +714 -0
- package/src/frontends/scalars.js +31 -1
- package/src/frontends/swift.js +893 -0
- package/src/frontends/types.js +750 -0
- package/src/language-registry.js +172 -12
- package/src/mapping.js +33 -9
- package/src/semantic/capabilities.js +671 -0
- package/src/semantic/effects.js +737 -0
- package/src/semantic/generics.js +58 -0
- package/src/semantic/lifetime.js +517 -0
- package/src/semantic/provenance.js +412 -19
- package/src/semantic/scalars.js +17 -0
- package/src/semantic/stdlib.js +921 -0
- package/src/semantic/types.js +765 -14
- package/src/semantic/validate.js +2934 -209
- package/src/stdlib-facades.js +1211 -0
- package/src/stdlib-negotiation.js +446 -0
- package/src/stdlib-providers.js +377 -0
- package/src/toolchains.js +16 -3
|
@@ -0,0 +1,1308 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { isDenseArray } from "../array.js";
|
|
3
|
+
import { isSafeArtifactPath, isSafeSourcePath } from "../artifact-path.js";
|
|
4
|
+
import { createGeneratedArtifactSet } from "../artifacts.js";
|
|
5
|
+
import { SemantifoldDiagnostic, unsupportedCapability, unsupportedRole } from "../diagnostic.js";
|
|
6
|
+
import { parseProgramSource } from "../frontends/program.js";
|
|
7
|
+
import { languageRegistry } from "../language-registry.js";
|
|
8
|
+
import { finalizeMapping, toSourceMapV3 } from "../mapping.js";
|
|
9
|
+
import { createCoordinateIndex, indexedPointAt, moduleLocation } from "../semantic/location.js";
|
|
10
|
+
import { semanticEntries } from "../semantic/provenance.js";
|
|
11
|
+
import { listStdlibModules, parseStdlibVersionRange } from "../semantic/stdlib.js";
|
|
12
|
+
import { moduleUncheckedErrorEffects } from "../semantic/validate.js";
|
|
13
|
+
import { negotiateStdlibProviders } from "../stdlib-negotiation.js";
|
|
14
|
+
import { stdlibFacadeProgramDescriptor, stdlibFacadeRegistry } from "../stdlib-facades.js";
|
|
15
|
+
import { stdlibProviderRegistry } from "../stdlib-providers.js";
|
|
16
|
+
import { preflightEffectCapabilities } from "./effects.js";
|
|
17
|
+
import { validateTargetBindingIdentifier, validateTargetIdentifier, validateTargetTypeIdentifier } from "./identifiers.js";
|
|
18
|
+
import { generateStdlibProviderContent } from "./stdlib-support.js";
|
|
19
|
+
import { validateBackendModule } from "./shared.js";
|
|
20
|
+
import { programImportName, SourceWriter } from "./writer.js";
|
|
21
|
+
/** @type {Readonly<Set<import("../semantic/types.js").SemanticLanguage>>} */
|
|
22
|
+
const programTargets = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
23
|
+
/** @type {Readonly<Set<import("../semantic/types.js").BackendLanguage>>} */
|
|
24
|
+
const programApplicationTargets = new Set(["ios"]);
|
|
25
|
+
/**
|
|
26
|
+
* Validates and prepares a complete semantic program for a non-text backend without allocating a writer.
|
|
27
|
+
* @param {object} input - Backend preflight request.
|
|
28
|
+
* @param {import("../semantic/types.js").SemanticLanguage} input.backendLanguage - Existing semantic backend profile to enforce.
|
|
29
|
+
* @param {import("../semantic/types.js").BackendLanguage} input.diagnosticLanguage - Public target identity for capability failures.
|
|
30
|
+
* @param {import("../semantic/types.js").SemanticProgram} input.program - Complete candidate program.
|
|
31
|
+
* @param {Readonly<Set<import("../semantic/types.js").SemanticLanguage>>} [input.sourceLanguages] - Accepted source provenance languages.
|
|
32
|
+
* @returns {{modules: import("../semantic/types.js").SemanticModule[], program: import("../semantic/types.js").SemanticProgram, sources: {content: string, filename: string, language?: import("../semantic/types.js").SemanticLanguage}[]}} Prepared immutable-input views.
|
|
33
|
+
*/
|
|
34
|
+
export function preflightSemanticProgram({ backendLanguage, diagnosticLanguage, program: candidate, sourceLanguages }) {
|
|
35
|
+
try {
|
|
36
|
+
const program = validateProgram(candidate, backendLanguage, sourceLanguages);
|
|
37
|
+
const modules = prepareEmissionModules(program, backendLanguage);
|
|
38
|
+
validateProgramSourceOwnership(program, backendLanguage);
|
|
39
|
+
const sources = program.sources.map((source) => {
|
|
40
|
+
if (source.content === null)
|
|
41
|
+
invalidProgramGeneration(`Program source '${source.filename}' has no retained content.`);
|
|
42
|
+
return { content: source.content, filename: source.filename, ...(source.language ? { language: source.language } : {}) };
|
|
43
|
+
});
|
|
44
|
+
return { modules, program, sources };
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (error instanceof SemantifoldDiagnostic && error.code == "UNSUPPORTED_CAPABILITY" &&
|
|
48
|
+
error.language != diagnosticLanguage) {
|
|
49
|
+
throw new SemantifoldDiagnostic({
|
|
50
|
+
cause: error,
|
|
51
|
+
code: error.code,
|
|
52
|
+
language: diagnosticLanguage,
|
|
53
|
+
location: error.location,
|
|
54
|
+
message: error.detail
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Generates a complete deterministic mapped artifact set for one semantic program.
|
|
62
|
+
* @param {object} input - Program generation request.
|
|
63
|
+
* @param {import("../semantic/types.js").BackendLanguage} input.language - Registered program target.
|
|
64
|
+
* @param {import("../semantic/types.js").SemanticProgram} input.program - Complete semantic program.
|
|
65
|
+
* @param {"text" | "application"} [input.role] - Explicit artifact role; omitted preserves text generation.
|
|
66
|
+
* @param {import("../semantic/types.js").IosApplicationConfigurationInput} [input.configuration] - iOS application configuration.
|
|
67
|
+
* @param {import("../semantic/types.js").IosApplicationAssetInput[]} [input.assets] - Exact iOS caller assets.
|
|
68
|
+
* @returns {import("../semantic/types.js").GeneratedArtifactSet} Transactionally validated artifact set.
|
|
69
|
+
*/
|
|
70
|
+
export function generateProgramArtifacts(input) {
|
|
71
|
+
if (!isPlainObject(input) || typeof input.language != "string")
|
|
72
|
+
invalidProgramGeneration("Program generation requires a target language and program.");
|
|
73
|
+
const role = input.role ?? "text";
|
|
74
|
+
if (role != "text" && role != "application")
|
|
75
|
+
invalidProgramGeneration("Program artifact role must be 'text' or 'application'.");
|
|
76
|
+
languageRegistry.record(input.language);
|
|
77
|
+
if (role == "application") {
|
|
78
|
+
if (!programApplicationTargets.has(input.language))
|
|
79
|
+
unsupportedRole(input.language, "multi-file application backend");
|
|
80
|
+
const backend = languageRegistry.resolve(input.language, "applicationBackend");
|
|
81
|
+
return createGeneratedArtifactSet(backend(input));
|
|
82
|
+
}
|
|
83
|
+
if (!programTargets.has(/** @type {import("../semantic/types.js").SemanticLanguage} */ (input.language))) {
|
|
84
|
+
unsupportedRole(input.language, "multi-file text backend");
|
|
85
|
+
}
|
|
86
|
+
const language = /** @type {import("../semantic/types.js").SemanticLanguage} */ (input.language);
|
|
87
|
+
const program = validateProgram(input.program, language);
|
|
88
|
+
const linking = planStdlibLinking(program, language);
|
|
89
|
+
const emissionModules = prepareEmissionModules(program, language, linking);
|
|
90
|
+
validateProgramSourceOwnership(program, language);
|
|
91
|
+
const paths = planModulePaths(program, language, linking);
|
|
92
|
+
const sources = program.sources.map((source) => {
|
|
93
|
+
if (source.content === null)
|
|
94
|
+
invalidProgramGeneration(`Program source '${source.filename}' has no retained content.`);
|
|
95
|
+
return { content: source.content, filename: source.filename, ...(source.language ? { language: source.language } : {}) };
|
|
96
|
+
});
|
|
97
|
+
const backend = /** @type {typeof import("./javascript.js").generateJavaScript} */ (languageRegistry.resolve(language, "textBackend"));
|
|
98
|
+
const mediaType = languageRegistry.record(language).mediaType;
|
|
99
|
+
/** @type {import("../semantic/types.js").GeneratedSetArtifact[]} */
|
|
100
|
+
const artifacts = language == "javascript" || language == "typescript" ? [{
|
|
101
|
+
content: "{\n \"type\": \"module\"\n}\n",
|
|
102
|
+
contentKind: /** @type {const} */ ("text"),
|
|
103
|
+
mediaType: "application/json",
|
|
104
|
+
ownership: /** @type {const} */ ("generated"),
|
|
105
|
+
path: "package.json",
|
|
106
|
+
provenance: {
|
|
107
|
+
kind: /** @type {const} */ ("synthetic"),
|
|
108
|
+
reason: "Declares the generated JavaScript-family artifact set as canonical ESM.",
|
|
109
|
+
relatedOrigins: []
|
|
110
|
+
},
|
|
111
|
+
role: "manifest"
|
|
112
|
+
}] : [];
|
|
113
|
+
if (linking && language != "java") {
|
|
114
|
+
for (const provider of linking.negotiation.providers) {
|
|
115
|
+
const record = /** @type {import("../stdlib-providers.js").StdlibProviderRecord} */ (linking.records.get(provider.module));
|
|
116
|
+
artifacts.push({
|
|
117
|
+
content: generateStdlibProviderContent(/** @type {"php" | "ruby" | "javascript" | "typescript"} */ (language), [...provider.operations], provider.module),
|
|
118
|
+
contentKind: /** @type {const} */ ("text"),
|
|
119
|
+
mediaType: record.artifact.mediaType,
|
|
120
|
+
ownership: /** @type {const} */ ("generated"),
|
|
121
|
+
path: record.artifact.path,
|
|
122
|
+
provenance: {
|
|
123
|
+
kind: /** @type {const} */ ("synthetic"),
|
|
124
|
+
reason: `semantifold-stdlib-provider:${record.identity}`,
|
|
125
|
+
relatedOrigins: []
|
|
126
|
+
},
|
|
127
|
+
role: /** @type {const} */ ("support")
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
for (const emissionModule of emissionModules) {
|
|
132
|
+
const moduleId = /** @type {string} */ (Reflect.get(emissionModule, "id"));
|
|
133
|
+
const filename = /** @type {string} */ (paths.get(moduleId));
|
|
134
|
+
const writer = new SourceWriter({
|
|
135
|
+
filename,
|
|
136
|
+
language,
|
|
137
|
+
module: emissionModule,
|
|
138
|
+
program,
|
|
139
|
+
programPaths: paths,
|
|
140
|
+
sources,
|
|
141
|
+
...(linking && emissionModule.capabilities !== undefined ? {
|
|
142
|
+
stdlibProviderEntries: Object.fromEntries((linking.usedOperationsByModule.get(moduleId) ?? []).map(({ module, operation }) => [
|
|
143
|
+
qualifiedOperationKey(module, operation),
|
|
144
|
+
/** @type {string} */ (linking.records.get(module)?.nativeEntries[operation])
|
|
145
|
+
])),
|
|
146
|
+
stdlibProviderImports: language == "java" || language == "javascript" || language == "typescript" ?
|
|
147
|
+
linking.providerImportsByModule.get(moduleId) : undefined,
|
|
148
|
+
stdlibProviderPaths: linking.providerPathsByModule.get(moduleId),
|
|
149
|
+
...(language == "java" ? {
|
|
150
|
+
stdlibProviderOwnerModule: /** @type {string} */ (linking.ownerModuleId),
|
|
151
|
+
stdlibProviderShims: moduleId == linking.ownerModuleId ? linking.usedOperations.map(({ operation }) => operation) : undefined
|
|
152
|
+
} : {})
|
|
153
|
+
} : {})
|
|
154
|
+
});
|
|
155
|
+
backend(emissionModule, writer);
|
|
156
|
+
const mapping = finalizeMapping(writer.finish());
|
|
157
|
+
artifacts.push({
|
|
158
|
+
content: mapping.generated.content,
|
|
159
|
+
contentKind: /** @type {const} */ ("text"),
|
|
160
|
+
mediaType: /** @type {string} */ (mediaType),
|
|
161
|
+
ownership: /** @type {const} */ ("generated"),
|
|
162
|
+
path: filename,
|
|
163
|
+
provenance: {
|
|
164
|
+
kind: /** @type {const} */ ("text"),
|
|
165
|
+
mapping,
|
|
166
|
+
sourceMap: toSourceMapV3(mapping),
|
|
167
|
+
sourceMapFilename: `${filename}.map`
|
|
168
|
+
},
|
|
169
|
+
role: /** @type {import("../semantic/types.js").GeneratedArtifactRole} */ (moduleId == program.entryModule ? "entry" : Reflect.get(emissionModule, "stdlibFacade") ? "support" : "source")
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
return createGeneratedArtifactSet({
|
|
173
|
+
artifacts,
|
|
174
|
+
...(linking || program.stdlibFacades ? { metadata: stdlibLinkMetadata(linking, paths, program.stdlibFacades) } : {}),
|
|
175
|
+
target: language
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* @typedef StdlibProgramLinking
|
|
180
|
+
* @property {import("../stdlib-negotiation.js").StdlibNegotiationResult} negotiation - Negotiated provider closure.
|
|
181
|
+
* @property {Map<string, import("../stdlib-providers.js").StdlibProviderRecord>} records - Materialized provider records by canonical module.
|
|
182
|
+
* @property {QualifiedStdlibOperation[]} usedOperations - Program-wide used canonical operations in stable order.
|
|
183
|
+
* @property {Map<string, QualifiedStdlibOperation[]>} usedOperationsByModule - Used canonical operations by program module identity.
|
|
184
|
+
* @property {Map<string, string[]>} providerImportsByModule - Ordered provider import names by module identity.
|
|
185
|
+
* @property {Map<string, string[]>} providerPathsByModule - Provider artifact closure by program module identity.
|
|
186
|
+
* @property {string | null} ownerModuleId - Java target: first operation-using module identity hosting the shared support; null for artifact-materializing targets.
|
|
187
|
+
*/
|
|
188
|
+
/**
|
|
189
|
+
* @typedef QualifiedStdlibOperation
|
|
190
|
+
* @property {string} module - Canonical module identity.
|
|
191
|
+
* @property {string} operation - Canonical operation name.
|
|
192
|
+
*/
|
|
193
|
+
/**
|
|
194
|
+
* Plans the linked stdlib provider for one program, or reports that no operation is used.
|
|
195
|
+
* Java resolves the same negotiated provider record but hosts its support in the first
|
|
196
|
+
* operation-using module instead of a separate provider artifact.
|
|
197
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Validated semantic program.
|
|
198
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
199
|
+
* @returns {StdlibProgramLinking | null} Linking plan, or null when nothing is used.
|
|
200
|
+
*/
|
|
201
|
+
function planStdlibLinking(program, language) {
|
|
202
|
+
const { programWide, usedOperationsByModule } = collectUsedEffectOperations(program);
|
|
203
|
+
if (programWide.length == 0)
|
|
204
|
+
return null;
|
|
205
|
+
const contracts = program.stdlibContracts ?? [/** @type {{identity: string, contractVersion?: string}} */ (program.stdlibContract)];
|
|
206
|
+
const contractsByIdentity = new Map(contracts.map((contract) => [contract.identity, contract]));
|
|
207
|
+
const requirementsByModule = new Map();
|
|
208
|
+
for (const qualified of programWide) {
|
|
209
|
+
const requirement = requirementsByModule.get(qualified.module) ?? [];
|
|
210
|
+
requirement.push(qualified.operation);
|
|
211
|
+
requirementsByModule.set(qualified.module, requirement);
|
|
212
|
+
}
|
|
213
|
+
const negotiation = negotiateStdlibProviders({
|
|
214
|
+
requirements: [...requirementsByModule].map(([module, operations]) => {
|
|
215
|
+
const contract = contractsByIdentity.get(module);
|
|
216
|
+
if (!contract)
|
|
217
|
+
throw new SemantifoldDiagnostic({
|
|
218
|
+
code: "STDLIB_LINK_FAILURE",
|
|
219
|
+
language,
|
|
220
|
+
message: `Reachable canonical operation '${module}.${operations[0]}' has no declared standard-library contract.`
|
|
221
|
+
});
|
|
222
|
+
return { module, operations, ...(contract.contractVersion !== undefined ? { range: contract.contractVersion } : {}) };
|
|
223
|
+
}),
|
|
224
|
+
target: language
|
|
225
|
+
});
|
|
226
|
+
/** @type {Map<string, import("../stdlib-providers.js").StdlibProviderRecord>} */
|
|
227
|
+
const records = new Map();
|
|
228
|
+
for (const selected of negotiation.modules) {
|
|
229
|
+
const candidates = stdlibProviderRegistry.providersFor(language, selected.identity, selected.version);
|
|
230
|
+
if (candidates.length != 1) {
|
|
231
|
+
throw new SemantifoldDiagnostic({
|
|
232
|
+
code: "STDLIB_LINK_FAILURE",
|
|
233
|
+
language,
|
|
234
|
+
message: `Expected exactly one registered stdlib provider for '${selected.identity}' on '${language}'.`
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
records.set(selected.identity, /** @type {import("../stdlib-providers.js").StdlibProviderRecord} */ (candidates[0]));
|
|
238
|
+
}
|
|
239
|
+
const ownerModuleId = language == "java"
|
|
240
|
+
? program.modules.map((module) => module.id).find((id) => (usedOperationsByModule.get(id) ?? []).length > 0)
|
|
241
|
+
: null;
|
|
242
|
+
if (ownerModuleId === undefined)
|
|
243
|
+
throw new SemantifoldDiagnostic({
|
|
244
|
+
code: "STDLIB_LINK_FAILURE",
|
|
245
|
+
language,
|
|
246
|
+
message: "Java program linking requires one module using canonical operations."
|
|
247
|
+
});
|
|
248
|
+
return {
|
|
249
|
+
negotiation,
|
|
250
|
+
ownerModuleId,
|
|
251
|
+
providerImportsByModule: collectProviderImports(program, negotiation, records, usedOperationsByModule, language, ownerModuleId),
|
|
252
|
+
providerPathsByModule: collectProviderPaths(negotiation, records, usedOperationsByModule),
|
|
253
|
+
records,
|
|
254
|
+
usedOperations: [...programWide],
|
|
255
|
+
usedOperationsByModule
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Selects the exact provider/type dependency closure required by each emitting program module.
|
|
260
|
+
* @param {import("../stdlib-negotiation.js").StdlibNegotiationResult} negotiation - Negotiated program closure.
|
|
261
|
+
* @param {Map<string, import("../stdlib-providers.js").StdlibProviderRecord>} records - Selected provider records.
|
|
262
|
+
* @param {Map<string, QualifiedStdlibOperation[]>} usedOperationsByModule - Reachable operations by program module.
|
|
263
|
+
* @returns {Map<string, string[]>} Ordered provider paths by program module.
|
|
264
|
+
*/
|
|
265
|
+
function collectProviderPaths(negotiation, records, usedOperationsByModule) {
|
|
266
|
+
const paths = new Map();
|
|
267
|
+
for (const [moduleId, operations] of usedOperationsByModule) {
|
|
268
|
+
const selected = new Set(operations.map(({ module }) => module));
|
|
269
|
+
let changed = true;
|
|
270
|
+
while (changed) {
|
|
271
|
+
changed = false;
|
|
272
|
+
for (const module of [...selected]) {
|
|
273
|
+
for (const dependency of records.get(module)?.dependencies ?? []) {
|
|
274
|
+
if (!selected.has(dependency.module)) {
|
|
275
|
+
selected.add(dependency.module);
|
|
276
|
+
changed = true;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
paths.set(moduleId, negotiation.providers.filter(({ module }) => selected.has(module)).map(({ module }) =>
|
|
282
|
+
/** @type {import("../stdlib-providers.js").StdlibProviderRecord} */ (records.get(module)).artifact.path));
|
|
283
|
+
}
|
|
284
|
+
return paths;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Collects the canonical operations invoked by each program module in stable order.
|
|
288
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Validated semantic program.
|
|
289
|
+
* @returns {{programWide: QualifiedStdlibOperation[], usedOperationsByModule: Map<string, QualifiedStdlibOperation[]>}} Used operations.
|
|
290
|
+
*/
|
|
291
|
+
function collectUsedEffectOperations(program) {
|
|
292
|
+
/** @type {Map<string, QualifiedStdlibOperation[]>} */
|
|
293
|
+
const usedOperationsByModule = new Map();
|
|
294
|
+
/** @type {Map<string, QualifiedStdlibOperation>} */
|
|
295
|
+
const programWide = new Map();
|
|
296
|
+
/** @type {Map<string, {body: unknown, module: import("../semantic/types.js").SemanticProgramModule}>} */
|
|
297
|
+
const bodies = new Map();
|
|
298
|
+
for (const module of program.modules) {
|
|
299
|
+
for (const declaration of module.functions)
|
|
300
|
+
bodies.set(/** @type {string} */ (declaration.id), { body: declaration.body, module });
|
|
301
|
+
for (const declaration of module.classes ?? []) {
|
|
302
|
+
bodies.set(/** @type {string} */ (declaration.constructor.id), { body: declaration.constructor.body, module });
|
|
303
|
+
for (const method of declaration.methods)
|
|
304
|
+
bodies.set(/** @type {string} */ (method.id), { body: method.body, module });
|
|
305
|
+
}
|
|
306
|
+
usedOperationsByModule.set(module.id, []);
|
|
307
|
+
}
|
|
308
|
+
const entryModule = /** @type {import("../semantic/types.js").SemanticProgramModule} */ (program.modules.find(({ id }) => id == program.entryModule));
|
|
309
|
+
/** @type {{body: unknown, module: import("../semantic/types.js").SemanticProgramModule}[]} */
|
|
310
|
+
const pending = [{ body: entryModule.entryPoint?.body, module: entryModule }];
|
|
311
|
+
const reachedDeclarations = new Set();
|
|
312
|
+
while (pending.length > 0) {
|
|
313
|
+
const current = /** @type {{body: unknown, module: import("../semantic/types.js").SemanticProgramModule}} */ (pending.shift());
|
|
314
|
+
const operationNames = new Map(current.module.capabilities?.flatMap((capability) => capability.operations.map((operation) => [operation.id, { module: capability.authorityId, operation: operation.name }])) ?? []);
|
|
315
|
+
const seen = new Set();
|
|
316
|
+
/**
|
|
317
|
+
* Visits one reachable semantic subtree.
|
|
318
|
+
* @param {unknown} value - Candidate semantic subtree.
|
|
319
|
+
*/
|
|
320
|
+
const visit = (value) => {
|
|
321
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
322
|
+
return;
|
|
323
|
+
seen.add(value);
|
|
324
|
+
if (!Array.isArray(value)) {
|
|
325
|
+
const kind = Reflect.get(value, "kind");
|
|
326
|
+
if (kind == "EffectCallExpression") {
|
|
327
|
+
const operation = Reflect.get(value, "operation");
|
|
328
|
+
if (typeof operation == "string") {
|
|
329
|
+
const qualified = operationNames.get(operation);
|
|
330
|
+
if (qualified !== undefined) {
|
|
331
|
+
const key = qualifiedOperationKey(qualified.module, qualified.operation);
|
|
332
|
+
const moduleOperations = /** @type {QualifiedStdlibOperation[]} */ (usedOperationsByModule.get(current.module.id));
|
|
333
|
+
if (!moduleOperations.some((item) => qualifiedOperationKey(item.module, item.operation) == key))
|
|
334
|
+
moduleOperations.push(qualified);
|
|
335
|
+
programWide.set(key, qualified);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
const declarationId = isPlainObject(Reflect.get(value, "resolution"))
|
|
340
|
+
? Reflect.get(Reflect.get(value, "resolution"), "declarationId") : undefined;
|
|
341
|
+
if (typeof declarationId == "string" && !reachedDeclarations.has(declarationId)) {
|
|
342
|
+
const declaration = bodies.get(declarationId);
|
|
343
|
+
if (declaration) {
|
|
344
|
+
reachedDeclarations.add(declarationId);
|
|
345
|
+
pending.push(declaration);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
for (const [key, child] of Object.entries(value)) {
|
|
349
|
+
if (["capabilities", "location", "provenance", "resolution", "sourceProvenance"].includes(key))
|
|
350
|
+
continue;
|
|
351
|
+
visit(child);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
else
|
|
355
|
+
for (const child of value)
|
|
356
|
+
visit(child);
|
|
357
|
+
};
|
|
358
|
+
visit(current.body);
|
|
359
|
+
}
|
|
360
|
+
for (const operations of usedOperationsByModule.values()) {
|
|
361
|
+
operations.sort((left, right) => qualifiedOperationKey(left.module, left.operation)
|
|
362
|
+
.localeCompare(qualifiedOperationKey(right.module, right.operation), "en"));
|
|
363
|
+
}
|
|
364
|
+
return { programWide: [...programWide.values()].sort((left, right) => qualifiedOperationKey(left.module, left.operation)
|
|
365
|
+
.localeCompare(qualifiedOperationKey(right.module, right.operation), "en")), usedOperationsByModule };
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Builds an unambiguous internal key for one canonical operation authority.
|
|
369
|
+
* @param {string} module - Canonical module identity.
|
|
370
|
+
* @param {string} operation - Canonical operation name.
|
|
371
|
+
* @returns {string} Qualified internal key.
|
|
372
|
+
*/
|
|
373
|
+
function qualifiedOperationKey(module, operation) {
|
|
374
|
+
return `${module}\u0000${operation}`;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Collects the ordered provider import names each module must pull from the linked provider.
|
|
378
|
+
* Java modules list referenced capability type names only; the owner lists none.
|
|
379
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Validated semantic program.
|
|
380
|
+
* @param {import("../stdlib-negotiation.js").StdlibNegotiationResult} negotiation - Negotiated closure.
|
|
381
|
+
* @param {Map<string, import("../stdlib-providers.js").StdlibProviderRecord>} records - Provider records by canonical module.
|
|
382
|
+
* @param {Map<string, QualifiedStdlibOperation[]>} usedOperationsByModule - Used canonical operations by module identity.
|
|
383
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
384
|
+
* @param {string | null} [ownerModuleId] - Java owner module identity.
|
|
385
|
+
* @returns {Map<string, string[]>} Ordered provider import names by module identity.
|
|
386
|
+
*/
|
|
387
|
+
function collectProviderImports(program, negotiation, records, usedOperationsByModule, language, ownerModuleId = null) {
|
|
388
|
+
/** @type {Map<string, string[]>} */
|
|
389
|
+
const providerImportsByModule = new Map();
|
|
390
|
+
for (const module of program.modules) {
|
|
391
|
+
if (module.capabilities === undefined)
|
|
392
|
+
continue;
|
|
393
|
+
const used = new Set((usedOperationsByModule.get(module.id) ?? []).map(({ module: owner, operation }) => qualifiedOperationKey(owner, operation)));
|
|
394
|
+
/** @type {Set<string>} */
|
|
395
|
+
const surface = new Set();
|
|
396
|
+
/** @type {Map<string, string>} */
|
|
397
|
+
const resourceNameById = new Map();
|
|
398
|
+
/** @type {Map<string, string>} */
|
|
399
|
+
const declarationNames = new Map((module.records ?? []).map((declaration) => [/** @type {string} */ (declaration.id), declaration.name]));
|
|
400
|
+
for (const declaration of module.errors ?? []) {
|
|
401
|
+
declarationNames.set(/** @type {string} */ (declaration.id), declaration.name);
|
|
402
|
+
}
|
|
403
|
+
for (const capability of module.capabilities) {
|
|
404
|
+
for (const resource of capability.resources) {
|
|
405
|
+
surface.add(resource.name);
|
|
406
|
+
resourceNameById.set(resource.id, resource.name);
|
|
407
|
+
}
|
|
408
|
+
for (const failure of capability.failures) {
|
|
409
|
+
surface.add(failure.name);
|
|
410
|
+
declarationNames.set(failure.id, failure.name);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
const referenced = new Set();
|
|
414
|
+
const seen = new Set();
|
|
415
|
+
/**
|
|
416
|
+
* Visits one semantic value.
|
|
417
|
+
* @param {unknown} value - Candidate semantic subtree.
|
|
418
|
+
* @returns {void}
|
|
419
|
+
*/
|
|
420
|
+
const visit = (value) => {
|
|
421
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
422
|
+
return;
|
|
423
|
+
seen.add(value);
|
|
424
|
+
if (!Array.isArray(value)) {
|
|
425
|
+
const kind = Reflect.get(value, "kind");
|
|
426
|
+
if (kind == "OwnedResourceType") {
|
|
427
|
+
const resourceId = Reflect.get(value, "resourceId");
|
|
428
|
+
if (typeof resourceId == "string") {
|
|
429
|
+
const name = resourceNameById.get(resourceId);
|
|
430
|
+
if (name !== undefined)
|
|
431
|
+
referenced.add(name);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
else if (kind == "ReferenceType" || kind == "OwnedReferenceType" || kind == "ErrorType") {
|
|
435
|
+
const declarationId = Reflect.get(value, "declarationId");
|
|
436
|
+
if (typeof declarationId == "string") {
|
|
437
|
+
const name = declarationNames.get(declarationId);
|
|
438
|
+
if (name !== undefined && surface.has(name))
|
|
439
|
+
referenced.add(name);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
for (const [key, child] of Object.entries(value)) {
|
|
443
|
+
if (key == "capabilities" || key == "location" || key == "sourceProvenance")
|
|
444
|
+
continue;
|
|
445
|
+
visit(child);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else
|
|
449
|
+
for (const child of value)
|
|
450
|
+
visit(child);
|
|
451
|
+
};
|
|
452
|
+
visit(module);
|
|
453
|
+
const names = [];
|
|
454
|
+
if (language != "java" || module.id != ownerModuleId) {
|
|
455
|
+
for (const capability of module.capabilities) {
|
|
456
|
+
for (const resource of capability.resources)
|
|
457
|
+
if (referenced.has(resource.name))
|
|
458
|
+
names.push(resource.name);
|
|
459
|
+
for (const failure of capability.failures)
|
|
460
|
+
if (referenced.has(failure.name))
|
|
461
|
+
names.push(failure.name);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
if (language != "java") {
|
|
465
|
+
for (const provider of negotiation.providers) {
|
|
466
|
+
const record = records.get(provider.module);
|
|
467
|
+
for (const operation of provider.operations) {
|
|
468
|
+
if (used.has(qualifiedOperationKey(provider.module, operation))) {
|
|
469
|
+
names.push(/** @type {string} */ (record?.nativeEntries[operation]));
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
providerImportsByModule.set(module.id, names);
|
|
475
|
+
}
|
|
476
|
+
return providerImportsByModule;
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Builds the truthful generated stdlib link metadata for one negotiated closure.
|
|
480
|
+
* Java reports the owner module file as the provider carrier instead of a separate artifact.
|
|
481
|
+
* @param {StdlibProgramLinking | null} linking - Linking plan.
|
|
482
|
+
* @param {Map<string, string>} paths - Planned artifact path by module identity.
|
|
483
|
+
* @param {import("../semantic/types.js").StdlibFacadeProgramDescriptor | undefined} facades - Selected source facade closure.
|
|
484
|
+
* @returns {Record<string, unknown>} Plain JSON metadata.
|
|
485
|
+
*/
|
|
486
|
+
function stdlibLinkMetadata(linking, paths, facades) {
|
|
487
|
+
return {
|
|
488
|
+
...(facades ? { facades } : {}),
|
|
489
|
+
modules: (linking?.negotiation.modules ?? []).map((item) => ({
|
|
490
|
+
identity: item.identity,
|
|
491
|
+
operations: [...item.operations],
|
|
492
|
+
version: item.version
|
|
493
|
+
})),
|
|
494
|
+
providers: (linking?.negotiation.providers ?? []).map((item) => {
|
|
495
|
+
const record = linking?.records.get(item.module);
|
|
496
|
+
const artifactPath = linking?.ownerModuleId !== null && linking?.ownerModuleId !== undefined
|
|
497
|
+
? /** @type {string} */ (paths.get(linking.ownerModuleId))
|
|
498
|
+
: record?.artifact.path;
|
|
499
|
+
return {
|
|
500
|
+
artifact: { mediaType: record?.artifact.mediaType, path: artifactPath },
|
|
501
|
+
dependencies: (record?.dependencies ?? []).map((dependency) => ({ module: dependency.module, range: dependency.range })),
|
|
502
|
+
identity: item.identity,
|
|
503
|
+
module: item.module,
|
|
504
|
+
nativeEntries: { ...item.nativeEntries },
|
|
505
|
+
operations: [...item.operations],
|
|
506
|
+
target: item.target,
|
|
507
|
+
version: item.version
|
|
508
|
+
};
|
|
509
|
+
}),
|
|
510
|
+
schema: "SemantifoldStdlibLink",
|
|
511
|
+
version: 1
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Validates every mandatory semantic location against its owning module source before writer allocation.
|
|
516
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Structurally and semantically validated program.
|
|
517
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
518
|
+
* @returns {void}
|
|
519
|
+
*/
|
|
520
|
+
function validateProgramSourceOwnership(program, language) {
|
|
521
|
+
const sources = new Map(program.sources.map((source) => [source.filename, {
|
|
522
|
+
...source,
|
|
523
|
+
coordinates: createCoordinateIndex(/** @type {string} */ (source.content))
|
|
524
|
+
}]));
|
|
525
|
+
for (const module of program.modules) {
|
|
526
|
+
const source = sources.get(module.sourceFilename);
|
|
527
|
+
if (!source)
|
|
528
|
+
unsupportedCapability(language, "semantic program module source ownership", undefined);
|
|
529
|
+
const fallback = moduleLocation(source.filename, /** @type {string} */ (source.content));
|
|
530
|
+
for (const entry of semanticEntries(module)) {
|
|
531
|
+
const subject = entry.node.kind == "Module" ? "module" : entry.node.kind == "Import" ? "import" :
|
|
532
|
+
entry.node.kind == "Export" ? "export" : "semantic node";
|
|
533
|
+
if (!("location" in entry.node)) {
|
|
534
|
+
if (subject != "semantic node")
|
|
535
|
+
unsupportedCapability(language, `semantic program ${subject} location`, fallback);
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
const location = entry.node.location;
|
|
539
|
+
if (sourceOwnsLocation(source, location))
|
|
540
|
+
continue;
|
|
541
|
+
unsupportedCapability(language, `semantic program ${subject} location source ownership`, fallback);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Checks a normalized UTF-16 location against one exact registered source without throwing.
|
|
547
|
+
* @param {{filename: string, content: string | null, coordinates: ReturnType<typeof createCoordinateIndex>}} source - Owning source.
|
|
548
|
+
* @param {unknown} candidate - Candidate location.
|
|
549
|
+
* @returns {boolean} Whether the source owns the location.
|
|
550
|
+
*/
|
|
551
|
+
function sourceOwnsLocation(source, candidate) {
|
|
552
|
+
if (!isPlainObject(candidate) || candidate.filename != source.filename || !isPlainObject(candidate.start) ||
|
|
553
|
+
!isPlainObject(candidate.end) || !Number.isInteger(candidate.start.offset) || !Number.isInteger(candidate.end.offset) ||
|
|
554
|
+
!Number.isInteger(candidate.start.line) || !Number.isInteger(candidate.start.column) ||
|
|
555
|
+
!Number.isInteger(candidate.end.line) || !Number.isInteger(candidate.end.column))
|
|
556
|
+
return false;
|
|
557
|
+
const startOffset = /** @type {number} */ (candidate.start.offset);
|
|
558
|
+
const endOffset = /** @type {number} */ (candidate.end.offset);
|
|
559
|
+
if (startOffset < 0 || endOffset < startOffset || endOffset > source.coordinates.source.length)
|
|
560
|
+
return false;
|
|
561
|
+
const expectedStart = indexedPointAt(source.coordinates, startOffset);
|
|
562
|
+
const expectedEnd = indexedPointAt(source.coordinates, endOffset);
|
|
563
|
+
return samePoint(candidate.start, expectedStart) && samePoint(candidate.end, expectedEnd);
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Compares an untrusted point with one canonical indexed point.
|
|
567
|
+
* @param {Record<string, unknown>} candidate - Candidate point.
|
|
568
|
+
* @param {import("../semantic/types.js").SourcePoint} expected - Canonical point.
|
|
569
|
+
* @returns {boolean} Whether every coordinate agrees.
|
|
570
|
+
*/
|
|
571
|
+
function samePoint(candidate, expected) {
|
|
572
|
+
return candidate.offset == expected.offset && candidate.line == expected.line && candidate.column == expected.column;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Collects nominal failure identities referenced by executable/type nodes outside the module's authority declarations.
|
|
576
|
+
* @param {import("../semantic/types.js").SemanticProgramModule} module - Program module.
|
|
577
|
+
* @returns {Set<string>} Referenced failure declaration identities.
|
|
578
|
+
*/
|
|
579
|
+
function collectReferencedFailureIds(module) {
|
|
580
|
+
/** @type {Set<string>} */
|
|
581
|
+
const ids = new Set();
|
|
582
|
+
const seen = new Set();
|
|
583
|
+
/**
|
|
584
|
+
* Visits one semantic subtree for referenced failures.
|
|
585
|
+
* @param {unknown} value - Candidate semantic subtree.
|
|
586
|
+
*/
|
|
587
|
+
const visit = (value) => {
|
|
588
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
589
|
+
return;
|
|
590
|
+
seen.add(value);
|
|
591
|
+
if (!Array.isArray(value)) {
|
|
592
|
+
if (Reflect.get(value, "kind") == "ErrorType" && typeof Reflect.get(value, "declarationId") == "string") {
|
|
593
|
+
ids.add(Reflect.get(value, "declarationId"));
|
|
594
|
+
}
|
|
595
|
+
const failureIds = Reflect.get(value, "failureIds");
|
|
596
|
+
if (Array.isArray(failureIds))
|
|
597
|
+
for (const id of failureIds)
|
|
598
|
+
if (typeof id == "string")
|
|
599
|
+
ids.add(id);
|
|
600
|
+
for (const [key, child] of Object.entries(value)) {
|
|
601
|
+
if (["capabilities", "location", "provenance", "sourceProvenance"].includes(key))
|
|
602
|
+
continue;
|
|
603
|
+
visit(child);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
else
|
|
607
|
+
for (const child of value)
|
|
608
|
+
visit(child);
|
|
609
|
+
};
|
|
610
|
+
visit({ classes: module.classes, entryPoint: module.entryPoint, functions: module.functions });
|
|
611
|
+
return ids;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Creates and validates every backend-shaped module before any writer is allocated.
|
|
615
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Validated semantic program.
|
|
616
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
617
|
+
* @param {StdlibProgramLinking | null} [linking] - Planned stdlib provider link.
|
|
618
|
+
* @returns {import("../semantic/types.js").SemanticModule[]} Emission views in dependency order.
|
|
619
|
+
*/
|
|
620
|
+
function prepareEmissionModules(program, language, linking = null) {
|
|
621
|
+
/** @type {Map<string, import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").ErrorDeclaration>} */
|
|
622
|
+
const declarations = new Map();
|
|
623
|
+
for (const module of program.modules) {
|
|
624
|
+
for (const declaration of module.records ?? [])
|
|
625
|
+
declarations.set(/** @type {string} */ (declaration.id), declaration);
|
|
626
|
+
for (const declaration of module.classes ?? [])
|
|
627
|
+
declarations.set(/** @type {string} */ (declaration.id), declaration);
|
|
628
|
+
for (const declaration of module.errors ?? [])
|
|
629
|
+
declarations.set(/** @type {string} */ (declaration.id), declaration);
|
|
630
|
+
for (const declaration of module.functions)
|
|
631
|
+
declarations.set(/** @type {string} */ (declaration.id), declaration);
|
|
632
|
+
}
|
|
633
|
+
const modules = program.modules.map((module) => /** @type {import("../semantic/types.js").SemanticModule} */ ({
|
|
634
|
+
...module,
|
|
635
|
+
entryPoint: module.entryPoint ?? {
|
|
636
|
+
body: { kind: /** @type {const} */ ("Block"), location: module.location, statements: [] },
|
|
637
|
+
kind: /** @type {const} */ ("EntryPoint"),
|
|
638
|
+
location: module.location
|
|
639
|
+
}
|
|
640
|
+
}));
|
|
641
|
+
/** @type {Map<string, Set<string>>} */
|
|
642
|
+
const callEffectsByDeclarationId = new Map();
|
|
643
|
+
for (const module of modules) {
|
|
644
|
+
const programModule = /** @type {import("../semantic/types.js").SemanticProgramModule} */ ( /** @type {unknown} */(module));
|
|
645
|
+
const visibleFunctions = new Map();
|
|
646
|
+
const visibleCallEffects = new Map();
|
|
647
|
+
const visibleRecords = new Map();
|
|
648
|
+
const visibleClasses = new Map();
|
|
649
|
+
const visibleErrors = new Map();
|
|
650
|
+
const externalDeclarationIds = new Set();
|
|
651
|
+
const neededFailureIds = collectReferencedFailureIds(programModule);
|
|
652
|
+
const localFailureIds = new Set(programModule.capabilities?.flatMap(({ failures }) => failures.map(({ id }) => id)) ?? []);
|
|
653
|
+
for (const owner of program.modules) {
|
|
654
|
+
if (owner.id == programModule.id)
|
|
655
|
+
continue;
|
|
656
|
+
for (const capability of owner.capabilities ?? []) {
|
|
657
|
+
for (const failure of capability.failures) {
|
|
658
|
+
if (!localFailureIds.has(failure.id) && neededFailureIds.has(failure.id))
|
|
659
|
+
visibleErrors.set(failure.id, failure);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
for (const imported of programModule.imports) {
|
|
664
|
+
const declaration = declarations.get(imported.declarationId);
|
|
665
|
+
if (!declaration)
|
|
666
|
+
unsupportedCapability(language, "program import without a declaration", imported.location);
|
|
667
|
+
externalDeclarationIds.add(imported.declarationId);
|
|
668
|
+
if (imported.symbolKind == "function") {
|
|
669
|
+
visibleFunctions.set(imported.localName, /** @type {import("../semantic/types.js").FunctionDeclaration} */ (declaration));
|
|
670
|
+
visibleCallEffects.set(imported.localName, new Set(callEffectsByDeclarationId.get(imported.declarationId) ?? []));
|
|
671
|
+
}
|
|
672
|
+
else if (imported.symbolKind == "record") {
|
|
673
|
+
visibleRecords.set(imported.declarationId, /** @type {import("../semantic/types.js").RecordDeclaration} */ (declaration));
|
|
674
|
+
}
|
|
675
|
+
else if (imported.symbolKind == "class") {
|
|
676
|
+
visibleClasses.set(imported.declarationId, /** @type {import("../semantic/types.js").ClassDeclaration} */ (declaration));
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
visibleErrors.set(imported.declarationId, /** @type {import("../semantic/types.js").ErrorDeclaration} */ (declaration));
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
if (module.capabilities !== undefined || !linking) {
|
|
683
|
+
preflightEffectCapabilities(module, language, linking ? { usedOperations: (linking.usedOperationsByModule.get(programModule.id) ?? [])
|
|
684
|
+
.map(({ operation }) => operation) } : {});
|
|
685
|
+
}
|
|
686
|
+
validateBackendModule(module, language, {
|
|
687
|
+
externalDeclarationIds,
|
|
688
|
+
program: true,
|
|
689
|
+
visibleCallEffects,
|
|
690
|
+
visibleClasses,
|
|
691
|
+
visibleErrors,
|
|
692
|
+
visibleFunctions,
|
|
693
|
+
visibleRecords
|
|
694
|
+
});
|
|
695
|
+
const localCallEffects = moduleUncheckedErrorEffects(module, { callEffects: visibleCallEffects, functions: visibleFunctions });
|
|
696
|
+
for (const declaration of module.functions) {
|
|
697
|
+
callEffectsByDeclarationId.set(/** @type {string} */ (declaration.id), new Set(localCallEffects.get(declaration.name) ?? []));
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
return modules;
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* Validates the closed parser-neutral program graph before any target emission.
|
|
704
|
+
* @param {unknown} candidate - Candidate semantic program.
|
|
705
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
706
|
+
* @param {Readonly<Set<import("../semantic/types.js").SemanticLanguage>>} [sourceLanguages] - Accepted source languages.
|
|
707
|
+
* @returns {import("../semantic/types.js").SemanticProgram} Validated program.
|
|
708
|
+
*/
|
|
709
|
+
function validateProgram(candidate, language, sourceLanguages = programTargets) {
|
|
710
|
+
if (!isPlainObject(candidate) || candidate.kind != "Program" || typeof candidate.entryModule != "string" ||
|
|
711
|
+
!isDenseArray(candidate.modules) || candidate.modules.length == 0 || !isDenseArray(candidate.sources) || candidate.sources.length == 0) {
|
|
712
|
+
invalidProgramGeneration("Malformed semantic program.");
|
|
713
|
+
}
|
|
714
|
+
const program = /** @type {import("../semantic/types.js").SemanticProgram} */ (candidate);
|
|
715
|
+
const modules = new Map();
|
|
716
|
+
/** @type {Map<string, {declaration: import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").ErrorDeclaration, module: import("../semantic/types.js").SemanticProgramModule}>} */
|
|
717
|
+
const declarations = new Map();
|
|
718
|
+
/** @type {import("../semantic/types.js").SemanticProgramModule[]} */
|
|
719
|
+
const capabilityModules = [];
|
|
720
|
+
let entryCount = 0;
|
|
721
|
+
const sourceIds = new Set();
|
|
722
|
+
const sourceFilenames = new Set();
|
|
723
|
+
for (const source of program.sources) {
|
|
724
|
+
if (!isPlainObject(source) || typeof source.id != "string" || sourceIds.has(source.id) ||
|
|
725
|
+
typeof source.filename != "string" || !isSafeSourcePath(source.filename) || sourceFilenames.has(source.filename) ||
|
|
726
|
+
typeof source.content != "string" || typeof source.language != "string" || !sourceLanguages.has(source.language)) {
|
|
727
|
+
invalidProgramGeneration("Malformed or duplicate semantic program source registry.");
|
|
728
|
+
}
|
|
729
|
+
sourceIds.add(source.id);
|
|
730
|
+
sourceFilenames.add(source.filename);
|
|
731
|
+
}
|
|
732
|
+
for (const module of program.modules) {
|
|
733
|
+
if (!isPlainObject(module) || module.kind != "Module" || typeof module.id != "string" ||
|
|
734
|
+
!/^[a-z][a-z0-9_]*(?:[.-][a-z][a-z0-9_]*)*$/u.test(module.id) || modules.has(module.id) ||
|
|
735
|
+
!isDenseArray(module.functions) || module.records !== undefined && !isDenseArray(module.records) ||
|
|
736
|
+
module.errors !== undefined && !isDenseArray(module.errors) ||
|
|
737
|
+
!isDenseArray(module.imports) || !isDenseArray(module.exports)) {
|
|
738
|
+
unsupportedCapability(language, "malformed or duplicate semantic program module", module?.location);
|
|
739
|
+
}
|
|
740
|
+
if (Reflect.get(module, "classes") !== undefined && (!isDenseArray(module.classes) ||
|
|
741
|
+
Reflect.get(module, "stdlibFacade") === undefined)) {
|
|
742
|
+
unsupportedCapability(language, "Task 033 reference classes are not supported by semantic program generation", Reflect.get(module, "classes")?.[0]?.location ?? module.location);
|
|
743
|
+
}
|
|
744
|
+
if (Reflect.get(module, "capabilities") !== undefined) {
|
|
745
|
+
if (!isDenseArray(module.capabilities) || module.capabilities.length == 0) {
|
|
746
|
+
unsupportedCapability(language, "malformed or empty Task 034 capability graph", module.location);
|
|
747
|
+
}
|
|
748
|
+
capabilityModules.push(module);
|
|
749
|
+
}
|
|
750
|
+
if (typeof module.sourceFilename != "string" || !sourceFilenames.has(module.sourceFilename)) {
|
|
751
|
+
unsupportedCapability(language, "semantic program module source identity", module.location);
|
|
752
|
+
}
|
|
753
|
+
if (module.entryPoint) {
|
|
754
|
+
entryCount++;
|
|
755
|
+
if (module.id != program.entryModule)
|
|
756
|
+
unsupportedCapability(language, "entry point on an unselected module", module.entryPoint.location);
|
|
757
|
+
}
|
|
758
|
+
for (const declaration of [...module.records ?? [], ...module.classes ?? [], ...module.errors ?? [], ...module.functions]) {
|
|
759
|
+
if (!isPlainObject(declaration) || typeof declaration.id != "string" ||
|
|
760
|
+
!declaration.id.startsWith(`${module.id}#`) || declarations.has(declaration.id)) {
|
|
761
|
+
unsupportedCapability(language, "duplicate or unstable program declaration identity", declaration?.location ?? module.location);
|
|
762
|
+
}
|
|
763
|
+
declarations.set(declaration.id, { declaration, module });
|
|
764
|
+
}
|
|
765
|
+
for (const imported of module.imports) {
|
|
766
|
+
if (!isPlainObject(imported) || imported.kind != "Import" || typeof imported.moduleId != "string" ||
|
|
767
|
+
typeof imported.importedName != "string" || typeof imported.localName != "string" ||
|
|
768
|
+
typeof imported.declarationId != "string" || !["function", "record", "class", "error"].includes(imported.symbolKind) ||
|
|
769
|
+
typeof imported.typeOnly != "boolean") {
|
|
770
|
+
unsupportedCapability(language, "malformed semantic program import", imported?.location ?? module.location);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
for (const exported of module.exports) {
|
|
774
|
+
if (!isPlainObject(exported) || exported.kind != "Export" || typeof exported.exportedName != "string" ||
|
|
775
|
+
typeof exported.declarationId != "string" || !["function", "record", "class", "error"].includes(exported.symbolKind)) {
|
|
776
|
+
unsupportedCapability(language, "malformed semantic program export", exported?.location ?? module.location);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
modules.set(module.id, module);
|
|
780
|
+
}
|
|
781
|
+
if (entryCount != 1 || !modules.get(program.entryModule)?.entryPoint) {
|
|
782
|
+
unsupportedCapability(language, "program without exactly one selected entry point", modules.get(program.entryModule)?.location);
|
|
783
|
+
}
|
|
784
|
+
const selectedModule = /** @type {import("../semantic/types.js").SemanticProgramModule} */ (modules.get(program.entryModule));
|
|
785
|
+
const selectedEntry = selectedModule.entryPoint;
|
|
786
|
+
if (!isPlainObject(selectedEntry?.body) || !isDenseArray(selectedEntry.body.statements) || selectedEntry.body.statements.length == 0) {
|
|
787
|
+
unsupportedCapability(language, "program without a dense non-empty selected entry point block", selectedEntry?.location ?? selectedModule.location);
|
|
788
|
+
}
|
|
789
|
+
const earlier = new Set();
|
|
790
|
+
for (const module of program.modules) {
|
|
791
|
+
const localTargetNames = new Set([...module.records ?? [], ...module.classes ?? [], ...module.errors ?? [], ...module.functions]
|
|
792
|
+
.map(({ name }) => targetName(language, name)));
|
|
793
|
+
const importedTargetNames = new Set();
|
|
794
|
+
const localJavaClass = module.records?.[0]?.name ?? module.classes?.[0]?.name ?? module.errors?.[0]?.name ??
|
|
795
|
+
(module.id == program.entryModule ? "Main" : moduleClassName(module.id));
|
|
796
|
+
const javaImportClasses = new Map(language == "java" ? [[localJavaClass, module.id]] : []);
|
|
797
|
+
for (const imported of module.imports) {
|
|
798
|
+
const resolved = declarations.get(imported.declarationId);
|
|
799
|
+
const remoteExport = resolved?.module.exports.find((item) => item.declarationId == imported.declarationId && item.exportedName == imported.importedName);
|
|
800
|
+
if (!resolved || resolved.module.id != imported.moduleId || !earlier.has(imported.moduleId) ||
|
|
801
|
+
!remoteExport) {
|
|
802
|
+
unsupportedCapability(language, "unresolved, private, cyclic, or out-of-order program import", imported.location ?? module.location);
|
|
803
|
+
}
|
|
804
|
+
const declarationKind = resolved.declaration.kind == "FunctionDeclaration" ? "function" :
|
|
805
|
+
resolved.declaration.kind == "RecordDeclaration" ? "record" :
|
|
806
|
+
resolved.declaration.kind == "ClassDeclaration" ? "class" : "error";
|
|
807
|
+
if (imported.symbolKind != remoteExport.symbolKind || imported.symbolKind != declarationKind ||
|
|
808
|
+
imported.typeOnly && declarationKind != "record" && declarationKind != "class") {
|
|
809
|
+
unsupportedCapability(language, "program import declaration kind mismatch", imported.location ?? module.location);
|
|
810
|
+
}
|
|
811
|
+
const importName = programImportName(program, module, imported);
|
|
812
|
+
if (language != "ruby" && language != "java") {
|
|
813
|
+
if (imported.symbolKind != "function")
|
|
814
|
+
validateTargetTypeIdentifier(language, importName, imported.location);
|
|
815
|
+
else
|
|
816
|
+
validateTargetBindingIdentifier(language, importName, "import", imported.location);
|
|
817
|
+
}
|
|
818
|
+
const name = targetName(language, importName);
|
|
819
|
+
if (language != "ruby" && language != "java" && (localTargetNames.has(name) || importedTargetNames.has(name))) {
|
|
820
|
+
unsupportedCapability(language, `target import-name collision '${importName}'`, imported.location);
|
|
821
|
+
}
|
|
822
|
+
if (language == "java") {
|
|
823
|
+
const importedClass = imported.symbolKind == "function" ? moduleClassName(resolved.module.id) : resolved.declaration.name;
|
|
824
|
+
const existingOwner = javaImportClasses.get(importedClass);
|
|
825
|
+
if (existingOwner && existingOwner != resolved.module.id) {
|
|
826
|
+
unsupportedCapability(language, `target import-class collision '${importedClass}'`, imported.location);
|
|
827
|
+
}
|
|
828
|
+
javaImportClasses.set(importedClass, resolved.module.id);
|
|
829
|
+
}
|
|
830
|
+
if (language == "ruby") {
|
|
831
|
+
const importedModule = moduleClassName(resolved.module.id);
|
|
832
|
+
if (localTargetNames.has(importedModule)) {
|
|
833
|
+
unsupportedCapability(language, `target import-module collision '${importedModule}'`, imported.location);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
importedTargetNames.add(name);
|
|
837
|
+
}
|
|
838
|
+
const valueDeclarationIds = new Set(module.imports.filter(({ typeOnly }) => !typeOnly).map(({ declarationId }) => declarationId));
|
|
839
|
+
const typeOnlyDeclarationIds = new Set(module.imports
|
|
840
|
+
.filter(({ declarationId, typeOnly }) => typeOnly && !valueDeclarationIds.has(declarationId))
|
|
841
|
+
.map(({ declarationId }) => declarationId));
|
|
842
|
+
const valueConstruction = findTypeOnlyValueConstruction(module, typeOnlyDeclarationIds);
|
|
843
|
+
if (valueConstruction) {
|
|
844
|
+
unsupportedCapability(language, "type-only program import used as a value", valueConstruction.location ?? module.location);
|
|
845
|
+
}
|
|
846
|
+
const exportNames = new Set();
|
|
847
|
+
for (const exported of module.exports) {
|
|
848
|
+
const resolved = declarations.get(exported.declarationId);
|
|
849
|
+
const name = targetName(language, exported.exportedName);
|
|
850
|
+
if (language == "javascript" || language == "typescript") {
|
|
851
|
+
validateTargetIdentifier(language, exported.exportedName, "export", exported.location ?? module.location);
|
|
852
|
+
}
|
|
853
|
+
if (!resolved || resolved.module.id != module.id || exportNames.has(name)) {
|
|
854
|
+
unsupportedCapability(language, `unresolved or colliding target export '${exported.exportedName}'`, exported.location ?? module.location);
|
|
855
|
+
}
|
|
856
|
+
const declarationKind = resolved.declaration.kind == "FunctionDeclaration" ? "function" :
|
|
857
|
+
resolved.declaration.kind == "RecordDeclaration" ? "record" :
|
|
858
|
+
resolved.declaration.kind == "ClassDeclaration" ? "class" : "error";
|
|
859
|
+
if (exported.symbolKind != declarationKind) {
|
|
860
|
+
unsupportedCapability(language, "program export declaration kind mismatch", exported.location ?? module.location);
|
|
861
|
+
}
|
|
862
|
+
if (language != "javascript" && language != "typescript" && exported.exportedName != resolved.declaration.name) {
|
|
863
|
+
unsupportedCapability(language, `export alias '${exported.exportedName}' without an equivalent target binding`, exported.location ?? resolved.declaration.location);
|
|
864
|
+
}
|
|
865
|
+
exportNames.add(name);
|
|
866
|
+
}
|
|
867
|
+
if (language == "php") {
|
|
868
|
+
const exportedDeclarationIds = new Set(module.exports.map(({ declarationId }) => declarationId));
|
|
869
|
+
const privateDeclaration = [...module.records ?? [], ...module.classes ?? [], ...module.errors ?? [], ...module.functions].find(({ id }) => typeof id == "string" && !exportedDeclarationIds.has(id));
|
|
870
|
+
if (privateDeclaration) {
|
|
871
|
+
unsupportedCapability(language, `non-exported declaration '${privateDeclaration.name}' without target-private module visibility`, privateDeclaration.location);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
earlier.add(module.id);
|
|
875
|
+
}
|
|
876
|
+
validateProgramStdlibContract(program, language, capabilityModules);
|
|
877
|
+
validateProgramStdlibFacades(program, language);
|
|
878
|
+
return program;
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Validates compiler-selected facade descriptors, executable sources, module markers, and native identity evidence.
|
|
882
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Candidate program.
|
|
883
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language for diagnostics.
|
|
884
|
+
* @returns {void}
|
|
885
|
+
*/
|
|
886
|
+
function validateProgramStdlibFacades(program, language) {
|
|
887
|
+
const descriptor = Reflect.get(program, "stdlibFacades");
|
|
888
|
+
const markedModules = program.modules.filter((module) => Reflect.get(module, "stdlibFacade") !== undefined);
|
|
889
|
+
const facadeSources = program.sources.filter((source) => Reflect.get(source, "ownership") == "facade");
|
|
890
|
+
const evidencedImports = program.modules.flatMap((module) => module.imports.filter((item) => Reflect.get(item, "stdlibFacade") !== undefined));
|
|
891
|
+
if (descriptor === undefined) {
|
|
892
|
+
if (markedModules.length > 0 || facadeSources.length > 0 || evidencedImports.length > 0) {
|
|
893
|
+
invalidFacadeDescriptor(language, "Facade modules, sources, or import evidence require a complete program facade descriptor.");
|
|
894
|
+
}
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
if (!isPlainObject(descriptor) || descriptor.schema != "SemantifoldStdlibFacades" || descriptor.version != 1 ||
|
|
898
|
+
typeof descriptor.language != "string" || !programTargets.has(descriptor.language) || !isDenseArray(descriptor.modules) ||
|
|
899
|
+
descriptor.modules.length == 0) {
|
|
900
|
+
invalidFacadeDescriptor(language, "The program facade descriptor is malformed.");
|
|
901
|
+
}
|
|
902
|
+
const facadeLanguage = /** @type {import("../semantic/types.js").SemanticLanguage} */ (descriptor.language);
|
|
903
|
+
const records = descriptor.modules.map((item) => {
|
|
904
|
+
if (!isPlainObject(item) || typeof item.identity != "string" || typeof item.version != "string") {
|
|
905
|
+
invalidFacadeDescriptor(language, "The program facade module descriptor is malformed.");
|
|
906
|
+
}
|
|
907
|
+
return stdlibFacadeRegistry.resolveIdentity(item.identity, facadeLanguage, item.version);
|
|
908
|
+
});
|
|
909
|
+
const expected = stdlibFacadeProgramDescriptor(facadeLanguage, records);
|
|
910
|
+
if (!equalPlainData(descriptor, expected)) {
|
|
911
|
+
invalidFacadeDescriptor(language, "The program facade descriptor does not match the registered versioned facade closure.");
|
|
912
|
+
}
|
|
913
|
+
const selectedRecords = new Map();
|
|
914
|
+
for (const record of records) {
|
|
915
|
+
if (selectedRecords.has(record.identity)) {
|
|
916
|
+
invalidFacadeDescriptor(language, `Facade '${record.identity}' is selected more than once.`);
|
|
917
|
+
}
|
|
918
|
+
for (const dependency of record.dependencies) {
|
|
919
|
+
const resolved = stdlibFacadeRegistry.resolveIdentity(dependency.identity, facadeLanguage, dependency.range);
|
|
920
|
+
const selected = selectedRecords.get(resolved.identity);
|
|
921
|
+
if (!selected || selected.version != resolved.version) {
|
|
922
|
+
invalidFacadeDescriptor(language, `Facade '${record.identity}' dependency '${resolved.identity}@${resolved.version}' is missing or out of order.`);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
selectedRecords.set(record.identity, record);
|
|
926
|
+
}
|
|
927
|
+
if (markedModules.length != records.length) {
|
|
928
|
+
invalidFacadeDescriptor(language, "The program facade descriptor does not match its executable semantic modules.");
|
|
929
|
+
}
|
|
930
|
+
if (program.sources.some((source) => source.language != facadeLanguage ||
|
|
931
|
+
!["application", "facade"].includes(String(Reflect.get(source, "ownership"))))) {
|
|
932
|
+
invalidFacadeDescriptor(language, "Facade programs require one source language and explicit application/facade ownership.");
|
|
933
|
+
}
|
|
934
|
+
const selectedIdentities = new Set(records.map(({ identity }) => identity));
|
|
935
|
+
const registeredModules = reparseRegisteredFacadeModules(program, facadeLanguage, language);
|
|
936
|
+
for (let index = 0; index < records.length; index += 1) {
|
|
937
|
+
const record = records[index];
|
|
938
|
+
const module = markedModules[index];
|
|
939
|
+
const marker = Reflect.get(module, "stdlibFacade");
|
|
940
|
+
if (!isPlainObject(marker) || Object.keys(marker).sort().join(",") != "identity,version" ||
|
|
941
|
+
marker.identity != record.identity || marker.version != record.version || module.id != record.source.id ||
|
|
942
|
+
module.sourceFilename != record.source.filename) {
|
|
943
|
+
invalidFacadeDescriptor(language, `Facade '${record.identity}' semantic module identity is not canonical.`);
|
|
944
|
+
}
|
|
945
|
+
const source = program.sources.find(({ filename }) => filename == record.source.filename);
|
|
946
|
+
if (!source || source.content != record.source.content || Reflect.get(source, "ownership") != "facade") {
|
|
947
|
+
invalidFacadeDescriptor(language, `Facade '${record.identity}' executable source does not match its registered definition.`);
|
|
948
|
+
}
|
|
949
|
+
const registeredModule = registeredModules.get(record.identity);
|
|
950
|
+
if (!registeredModule || !equalPlainData(module, registeredModule)) {
|
|
951
|
+
invalidFacadeAuthority(language, `Facade '${record.identity}' semantic module does not match its registered executable source.`, module.location);
|
|
952
|
+
}
|
|
953
|
+
const allowedOperations = new Set(record.requirements.flatMap(({ operations }) => operations));
|
|
954
|
+
const usedOperations = collectDeclaredEffectOperations(module);
|
|
955
|
+
if (allowedOperations.size != usedOperations.size || [...allowedOperations].some((operation) => !usedOperations.has(operation))) {
|
|
956
|
+
invalidFacadeAuthority(language, `Facade '${record.identity}' semantic body does not match its declared canonical requirements.`, module.location);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
if (facadeSources.length != records.length) {
|
|
960
|
+
invalidFacadeDescriptor(language, "The program contains an unselected compiler-owned facade source.");
|
|
961
|
+
}
|
|
962
|
+
if (evidencedImports.length == 0) {
|
|
963
|
+
invalidFacadeDescriptor(language, "The selected facade closure has no parser-proved native import evidence.");
|
|
964
|
+
}
|
|
965
|
+
for (const imported of evidencedImports) {
|
|
966
|
+
const evidence = Reflect.get(imported, "stdlibFacade");
|
|
967
|
+
if (!isPlainObject(evidence) || Object.keys(evidence).sort().join(",") !=
|
|
968
|
+
"facadeIdentity,facadeVersion,nativeModule,nativeSymbol,schema,version" ||
|
|
969
|
+
evidence.schema != "SemantifoldStdlibFacadeResolution" || evidence.version != 1 ||
|
|
970
|
+
typeof evidence.facadeIdentity != "string" || typeof evidence.facadeVersion != "string" ||
|
|
971
|
+
typeof evidence.nativeModule != "string" || typeof evidence.nativeSymbol != "string") {
|
|
972
|
+
invalidFacadeDescriptor(language, "A facade import has malformed native identity evidence.");
|
|
973
|
+
}
|
|
974
|
+
const record = stdlibFacadeRegistry.resolveFacade(facadeLanguage, evidence.nativeModule, evidence.nativeSymbol, evidence.facadeVersion);
|
|
975
|
+
if (record.identity != evidence.facadeIdentity || !selectedIdentities.has(record.identity) || imported.moduleId != record.source.id ||
|
|
976
|
+
imported.importedName != evidence.nativeSymbol) {
|
|
977
|
+
invalidFacadeDescriptor(language, "A facade import does not match its registered native module and symbol identity.");
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* Collects every canonical operation present in one validated facade implementation.
|
|
983
|
+
* This checks the facade's complete declared authority independently from program reachability.
|
|
984
|
+
* @param {import("../semantic/types.js").SemanticProgramModule} module - Facade module.
|
|
985
|
+
* @returns {Set<string>} Used operation names.
|
|
986
|
+
*/
|
|
987
|
+
function collectDeclaredEffectOperations(module) {
|
|
988
|
+
const operationNames = new Map(module.capabilities?.flatMap(({ operations }) => operations.map((operation) => [operation.id, operation.name])) ?? []);
|
|
989
|
+
const used = new Set();
|
|
990
|
+
const seen = new Set();
|
|
991
|
+
/**
|
|
992
|
+
* Visits one facade semantic subtree.
|
|
993
|
+
* @param {unknown} value - Candidate semantic subtree.
|
|
994
|
+
*/
|
|
995
|
+
const visit = (value) => {
|
|
996
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
997
|
+
return;
|
|
998
|
+
seen.add(value);
|
|
999
|
+
if (!Array.isArray(value)) {
|
|
1000
|
+
const operation = Reflect.get(value, "kind") == "EffectCallExpression" ? Reflect.get(value, "operation") : undefined;
|
|
1001
|
+
if (typeof operation == "string" && operationNames.has(operation))
|
|
1002
|
+
used.add(/** @type {string} */ (operationNames.get(operation)));
|
|
1003
|
+
for (const [key, child] of Object.entries(value)) {
|
|
1004
|
+
if (["capabilities", "location", "provenance", "resolution", "sourceProvenance"].includes(key))
|
|
1005
|
+
continue;
|
|
1006
|
+
visit(child);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
else
|
|
1010
|
+
for (const child of value)
|
|
1011
|
+
visit(child);
|
|
1012
|
+
};
|
|
1013
|
+
visit({ classes: module.classes, entryPoint: module.entryPoint, functions: module.functions });
|
|
1014
|
+
return used;
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Recompiles the registry-selected facade closure from retained caller inputs and registered facade source.
|
|
1018
|
+
* This parser-backed reference graph is created during validation, before provider planning or writer allocation.
|
|
1019
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Untrusted mutable semantic program.
|
|
1020
|
+
* @param {import("../semantic/types.js").SemanticLanguage} facadeLanguage - Selected source-language facade profile.
|
|
1021
|
+
* @param {import("../semantic/types.js").SemanticLanguage} diagnosticLanguage - Target language for boundary diagnostics.
|
|
1022
|
+
* @returns {Map<string, import("../semantic/types.js").SemanticProgramModule>} Canonical semantic modules by facade identity.
|
|
1023
|
+
*/
|
|
1024
|
+
function reparseRegisteredFacadeModules(program, facadeLanguage, diagnosticLanguage) {
|
|
1025
|
+
const applicationModules = program.modules.filter((module) => Reflect.get(module, "stdlibFacade") === undefined);
|
|
1026
|
+
const modulesByFilename = new Map(applicationModules.map((module) => [module.sourceFilename, module]));
|
|
1027
|
+
const applicationSources = program.sources.filter((source) => Reflect.get(source, "ownership") == "application").map((source) => {
|
|
1028
|
+
const module = modulesByFilename.get(source.filename);
|
|
1029
|
+
if (!module)
|
|
1030
|
+
invalidFacadeDescriptor(diagnosticLanguage, `Application source '${source.filename}' has no matching semantic module for facade verification.`);
|
|
1031
|
+
return {
|
|
1032
|
+
filename: source.filename,
|
|
1033
|
+
id: /** @type {import("../semantic/types.js").SemanticProgramModule} */ (module).id,
|
|
1034
|
+
language: facadeLanguage,
|
|
1035
|
+
source: /** @type {string} */ (source.content)
|
|
1036
|
+
};
|
|
1037
|
+
});
|
|
1038
|
+
if (applicationSources.length != applicationModules.length) {
|
|
1039
|
+
invalidFacadeDescriptor(diagnosticLanguage, "Facade verification requires one retained application source per semantic module.");
|
|
1040
|
+
}
|
|
1041
|
+
const reparsed = parseProgramSource({ entryModule: program.entryModule, sources: applicationSources });
|
|
1042
|
+
const modules = new Map();
|
|
1043
|
+
for (const module of reparsed.modules) {
|
|
1044
|
+
if (!module.stdlibFacade)
|
|
1045
|
+
continue;
|
|
1046
|
+
if (modules.has(module.stdlibFacade.identity)) {
|
|
1047
|
+
invalidFacadeDescriptor(diagnosticLanguage, `Registered facade '${module.stdlibFacade.identity}' reparsed more than once.`);
|
|
1048
|
+
}
|
|
1049
|
+
modules.set(module.stdlibFacade.identity, module);
|
|
1050
|
+
}
|
|
1051
|
+
return modules;
|
|
1052
|
+
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Compares closed plain JSON-shaped data without coercion or key-order assumptions.
|
|
1055
|
+
* @param {unknown} left - Candidate value.
|
|
1056
|
+
* @param {unknown} right - Expected value.
|
|
1057
|
+
* @returns {boolean} Exact recursive equivalence.
|
|
1058
|
+
*/
|
|
1059
|
+
function equalPlainData(left, right) {
|
|
1060
|
+
if (left === right)
|
|
1061
|
+
return true;
|
|
1062
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
1063
|
+
return Array.isArray(left) && Array.isArray(right) && isDenseArray(left) && isDenseArray(right) &&
|
|
1064
|
+
left.length == right.length && left.every((value, index) => equalPlainData(value, right[index]));
|
|
1065
|
+
}
|
|
1066
|
+
if (!isPlainObject(left) || !isPlainObject(right))
|
|
1067
|
+
return false;
|
|
1068
|
+
const leftKeys = Object.keys(left).sort();
|
|
1069
|
+
const rightKeys = Object.keys(right).sort();
|
|
1070
|
+
return leftKeys.length == rightKeys.length && leftKeys.every((key, index) => key == rightKeys[index] && equalPlainData(left[key], right[key]));
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Throws one stable facade artifact-boundary diagnostic.
|
|
1074
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
1075
|
+
* @param {string} message - Diagnostic detail.
|
|
1076
|
+
* @returns {never} Always throws.
|
|
1077
|
+
*/
|
|
1078
|
+
function invalidFacadeDescriptor(language, message) {
|
|
1079
|
+
throw new SemantifoldDiagnostic({ code: "STDLIB_FACADE_DESCRIPTOR_INVALID", language, message });
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Throws when a facade semantic body exceeds or omits its registry-declared authority.
|
|
1083
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
1084
|
+
* @param {string} message - Diagnostic detail.
|
|
1085
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Facade source location.
|
|
1086
|
+
* @returns {never} Always throws.
|
|
1087
|
+
*/
|
|
1088
|
+
function invalidFacadeAuthority(language, message, location) {
|
|
1089
|
+
throw new SemantifoldDiagnostic({ code: "STDLIB_FACADE_AUTHORITY_FORGED", language, location, message });
|
|
1090
|
+
}
|
|
1091
|
+
/**
|
|
1092
|
+
* Validates the program stdlib link descriptor against its capability modules.
|
|
1093
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Candidate program.
|
|
1094
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
1095
|
+
* @param {import("../semantic/types.js").SemanticProgramModule[]} capabilityModules - Modules carrying capabilities.
|
|
1096
|
+
* @returns {void}
|
|
1097
|
+
*/
|
|
1098
|
+
function validateProgramStdlibContract(program, language, capabilityModules) {
|
|
1099
|
+
const contract = Reflect.get(program, "stdlibContract");
|
|
1100
|
+
const contracts = Reflect.get(program, "stdlibContracts");
|
|
1101
|
+
if (capabilityModules.length == 0) {
|
|
1102
|
+
if (contract !== undefined || contracts !== undefined) {
|
|
1103
|
+
throw new SemantifoldDiagnostic({
|
|
1104
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1105
|
+
language,
|
|
1106
|
+
message: "A declared standard-library contract requires capability modules."
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1111
|
+
if (contract !== undefined && contracts !== undefined) {
|
|
1112
|
+
throw new SemantifoldDiagnostic({
|
|
1113
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1114
|
+
language,
|
|
1115
|
+
message: "A program cannot declare both singular and plural standard-library contract descriptors."
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
if (contract === undefined && contracts === undefined) {
|
|
1119
|
+
unsupportedCapability(language, "program modules with capabilities require a declared standard-library contract", capabilityModules[0].location);
|
|
1120
|
+
}
|
|
1121
|
+
const declared = contracts === undefined ? [contract] : contracts;
|
|
1122
|
+
if (!isDenseArray(declared) || declared.length == 0) {
|
|
1123
|
+
throw new SemantifoldDiagnostic({
|
|
1124
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1125
|
+
language,
|
|
1126
|
+
message: "The declared standard-library contract descriptor list is malformed or empty."
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
1129
|
+
const identities = new Set();
|
|
1130
|
+
for (const descriptor of declared) {
|
|
1131
|
+
if (!isPlainObject(descriptor) || Object.keys(descriptor).some((key) => key != "identity" && key != "contractVersion")) {
|
|
1132
|
+
throw new SemantifoldDiagnostic({
|
|
1133
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1134
|
+
language,
|
|
1135
|
+
message: "The declared standard-library contract descriptor is malformed."
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
const identity = descriptor.identity;
|
|
1139
|
+
if (typeof identity != "string" || identity.length == 0 || identities.has(identity) ||
|
|
1140
|
+
!listStdlibModules().some(({ identity: registered }) => registered == identity)) {
|
|
1141
|
+
throw new SemantifoldDiagnostic({
|
|
1142
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1143
|
+
language,
|
|
1144
|
+
message: `Declared standard-library contract '${String(identity)}' is duplicate or not a registered canonical module.`
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
if (descriptor.contractVersion !== undefined && parseStdlibVersionRange(descriptor.contractVersion) === null) {
|
|
1148
|
+
throw new SemantifoldDiagnostic({
|
|
1149
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1150
|
+
language,
|
|
1151
|
+
message: `Declared standard-library contract version '${String(descriptor.contractVersion)}' is not canonical.`
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
identities.add(identity);
|
|
1155
|
+
}
|
|
1156
|
+
for (const module of capabilityModules) {
|
|
1157
|
+
for (const capability of module.capabilities ?? []) {
|
|
1158
|
+
if (!isPlainObject(capability) || typeof capability.authorityId != "string" || !identities.has(capability.authorityId)) {
|
|
1159
|
+
throw new SemantifoldDiagnostic({
|
|
1160
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1161
|
+
language,
|
|
1162
|
+
message: `Capability authority '${String(Reflect.get(capability, "authorityId"))}' does not match a declared standard-library contract.`
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
/**
|
|
1169
|
+
* Finds a record construction that crosses a type-only import edge.
|
|
1170
|
+
* @param {import("../semantic/types.js").SemanticProgramModule} module - Importing semantic module.
|
|
1171
|
+
* @param {Set<string>} typeOnlyDeclarationIds - Imported identities unavailable in value positions.
|
|
1172
|
+
* @returns {import("../semantic/types.js").RecordConstruction | undefined} Invalid construction when present.
|
|
1173
|
+
*/
|
|
1174
|
+
function findTypeOnlyValueConstruction(module, typeOnlyDeclarationIds) {
|
|
1175
|
+
if (typeOnlyDeclarationIds.size == 0)
|
|
1176
|
+
return undefined;
|
|
1177
|
+
const seen = new WeakSet();
|
|
1178
|
+
/**
|
|
1179
|
+
* Visits one semantic value.
|
|
1180
|
+
* @param {unknown} value - Candidate semantic subtree.
|
|
1181
|
+
* @returns {import("../semantic/types.js").RecordConstruction | undefined} Invalid construction when present.
|
|
1182
|
+
*/
|
|
1183
|
+
function visit(value) {
|
|
1184
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
1185
|
+
return undefined;
|
|
1186
|
+
seen.add(value);
|
|
1187
|
+
const object = /** @type {Record<string, unknown>} */ (value);
|
|
1188
|
+
if (object.kind == "RecordConstruction" && isPlainObject(object.record) &&
|
|
1189
|
+
typeof object.record.declarationId == "string" && typeOnlyDeclarationIds.has(object.record.declarationId)) {
|
|
1190
|
+
return /** @type {import("../semantic/types.js").RecordConstruction} */ (value);
|
|
1191
|
+
}
|
|
1192
|
+
for (const child of Object.values(object)) {
|
|
1193
|
+
const found = visit(child);
|
|
1194
|
+
if (found)
|
|
1195
|
+
return found;
|
|
1196
|
+
}
|
|
1197
|
+
return undefined;
|
|
1198
|
+
}
|
|
1199
|
+
return visit({ entryPoint: module.entryPoint, functions: module.functions });
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Plans all paths before emission and rejects exact/case/file-directory collisions.
|
|
1203
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Validated program.
|
|
1204
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
1205
|
+
* @param {StdlibProgramLinking | null} [linking] - Planned stdlib provider link.
|
|
1206
|
+
* @returns {Map<string, string>} Path by module identity.
|
|
1207
|
+
*/
|
|
1208
|
+
function planModulePaths(program, language, linking = null) {
|
|
1209
|
+
const extension = language == "javascript" ? ".js" : language == "typescript" ? ".ts" : language == "ruby" ? ".rb" :
|
|
1210
|
+
language == "php" ? ".php" : ".java";
|
|
1211
|
+
const paths = new Map();
|
|
1212
|
+
const folded = new Set();
|
|
1213
|
+
const targetModuleNames = new Set();
|
|
1214
|
+
const providerPaths = linking ? linking.negotiation.providers.map(({ module }) =>
|
|
1215
|
+
/** @type {import("../stdlib-providers.js").StdlibProviderRecord} */ (linking.records.get(module)).artifact.path) : [];
|
|
1216
|
+
const foldedProviders = new Map();
|
|
1217
|
+
for (const providerPath of providerPaths) {
|
|
1218
|
+
const key = providerPath.toLocaleLowerCase("en-US");
|
|
1219
|
+
if (!isSafeArtifactPath(providerPath) || folded.has(key)) {
|
|
1220
|
+
throw new SemantifoldDiagnostic({ code: "STDLIB_NAME_COLLISION", language,
|
|
1221
|
+
message: `Stdlib provider artifact path '${providerPath}' is unsafe or colliding.` });
|
|
1222
|
+
}
|
|
1223
|
+
folded.add(key);
|
|
1224
|
+
foldedProviders.set(providerPath.toLocaleLowerCase("en-US").replaceAll(".", "/"), providerPath);
|
|
1225
|
+
}
|
|
1226
|
+
for (const module of program.modules) {
|
|
1227
|
+
let path = `${module.id.replaceAll(".", "/")}${extension}`;
|
|
1228
|
+
const providerPath = foldedProviders.get(path.toLocaleLowerCase("en-US").replaceAll(".", "/"));
|
|
1229
|
+
if (providerPath !== undefined) {
|
|
1230
|
+
throw new SemantifoldDiagnostic({
|
|
1231
|
+
code: "STDLIB_NAME_COLLISION",
|
|
1232
|
+
language,
|
|
1233
|
+
message: `Module path '${path}' collides with the stdlib provider artifact '${providerPath}'.`
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
const targetModuleName = moduleClassName(module.id);
|
|
1237
|
+
if (language == "php" || language == "ruby") {
|
|
1238
|
+
const key = language == "php" ? targetModuleName.toLocaleLowerCase("en-US") : targetModuleName;
|
|
1239
|
+
if (targetModuleNames.has(key)) {
|
|
1240
|
+
unsupportedCapability(language, `target module-name collision '${targetModuleName}'`, module.location);
|
|
1241
|
+
}
|
|
1242
|
+
targetModuleNames.add(key);
|
|
1243
|
+
}
|
|
1244
|
+
if (language == "php") {
|
|
1245
|
+
validateTargetIdentifier(language, targetModuleName, "module", module.location);
|
|
1246
|
+
validateTargetTypeIdentifier(language, targetModuleName, module.location);
|
|
1247
|
+
}
|
|
1248
|
+
if (language == "ruby")
|
|
1249
|
+
validateTargetTypeIdentifier(language, targetModuleName, module.location);
|
|
1250
|
+
if (language == "java") {
|
|
1251
|
+
for (const segment of module.id.split("."))
|
|
1252
|
+
validateTargetIdentifier(language, segment, "module", module.location);
|
|
1253
|
+
const nominalCount = (module.records?.length ?? 0) + (module.classes?.length ?? 0) + (module.errors?.length ?? 0);
|
|
1254
|
+
if (module.id.includes("-") || nominalCount > 1 ||
|
|
1255
|
+
nominalCount > 0 && (module.functions.length > 0 || module.entryPoint)) {
|
|
1256
|
+
unsupportedCapability(language, "Java module layout requiring multiple public declarations in one semantic module", module.location);
|
|
1257
|
+
}
|
|
1258
|
+
const className = module.records?.[0]?.name ?? module.classes?.[0]?.name ?? module.errors?.[0]?.name ??
|
|
1259
|
+
(module.id == program.entryModule ? "Main" : targetModuleName);
|
|
1260
|
+
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/u.test(className)) {
|
|
1261
|
+
unsupportedCapability(language, `invalid Java public class name '${className}'`, module.location);
|
|
1262
|
+
}
|
|
1263
|
+
if (module.id != program.entryModule)
|
|
1264
|
+
validateTargetTypeIdentifier(language, className, module.location);
|
|
1265
|
+
path = `semantifold/generated/${module.id.replaceAll(".", "/")}/${className}.java`;
|
|
1266
|
+
}
|
|
1267
|
+
const key = path.toLocaleLowerCase("en-US");
|
|
1268
|
+
if (!isSafeArtifactPath(path) || folded.has(key))
|
|
1269
|
+
unsupportedCapability(language, `unsafe or colliding target path '${path}'`, module.location);
|
|
1270
|
+
folded.add(key);
|
|
1271
|
+
paths.set(module.id, path);
|
|
1272
|
+
}
|
|
1273
|
+
return paths;
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* Converts a logical module identity to its canonical target type segment.
|
|
1277
|
+
* @param {string} id - Logical module identity.
|
|
1278
|
+
* @returns {string} Target class name.
|
|
1279
|
+
*/
|
|
1280
|
+
function moduleClassName(id) {
|
|
1281
|
+
return id.split(/[._-]+/u).map((part) => `${part[0].toUpperCase()}${part.slice(1)}`).join("");
|
|
1282
|
+
}
|
|
1283
|
+
/**
|
|
1284
|
+
* Normalizes a declaration or binding name for target collision checks.
|
|
1285
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target.
|
|
1286
|
+
* @param {string} name - Name.
|
|
1287
|
+
* @returns {string} Collision key.
|
|
1288
|
+
*/
|
|
1289
|
+
function targetName(language, name) {
|
|
1290
|
+
return language == "php" ? name.toLocaleLowerCase("en-US") : name;
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* Reports whether a candidate is a direct plain object.
|
|
1294
|
+
* @param {unknown} value - Candidate.
|
|
1295
|
+
* @returns {value is Record<string, unknown>} Whether the value is a plain object.
|
|
1296
|
+
*/
|
|
1297
|
+
function isPlainObject(value) {
|
|
1298
|
+
return Boolean(value) && typeof value == "object" && !Array.isArray(value) && Object.getPrototypeOf(value) == Object.prototype;
|
|
1299
|
+
}
|
|
1300
|
+
/**
|
|
1301
|
+
* Raises a stable malformed program-generation request diagnostic.
|
|
1302
|
+
* @param {string} message - Stable failure.
|
|
1303
|
+
* @returns {never} Always throws.
|
|
1304
|
+
*/
|
|
1305
|
+
function invalidProgramGeneration(message) {
|
|
1306
|
+
throw new SemantifoldDiagnostic({ code: "INVALID_PROGRAM", language: "program", message });
|
|
1307
|
+
}
|
|
1308
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZ3JhbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZW5kcy9wcm9ncmFtLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sYUFBYSxDQUFBO0FBQ3hDLE9BQU8sRUFBQyxrQkFBa0IsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLHFCQUFxQixDQUFBO0FBQ3hFLE9BQU8sRUFBQywwQkFBMEIsRUFBQyxNQUFNLGlCQUFpQixDQUFBO0FBQzFELE9BQU8sRUFBQyxxQkFBcUIsRUFBRSxxQkFBcUIsRUFBRSxlQUFlLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUM5RixPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUMxRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUN4RCxPQUFPLEVBQUMsZUFBZSxFQUFFLGFBQWEsRUFBQyxNQUFNLGVBQWUsQ0FBQTtBQUM1RCxPQUFPLEVBQUMscUJBQXFCLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQzdGLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQTtBQUN6RCxPQUFPLEVBQUMsaUJBQWlCLEVBQUUsdUJBQXVCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQTtBQUNoRixPQUFPLEVBQUMsMkJBQTJCLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUNuRSxPQUFPLEVBQUMsd0JBQXdCLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQTtBQUNqRSxPQUFPLEVBQUMsNkJBQTZCLEVBQUUsb0JBQW9CLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQTtBQUN4RixPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQTtBQUM3RCxPQUFPLEVBQUMsMkJBQTJCLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFDeEQsT0FBTyxFQUFDLCtCQUEr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QyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0FBQy9GLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsVUFBVSxDQUFDLFFBQVEsRUFBRSxJQUFJO0lBQ2hDLE9BQU8sUUFBUSxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7QUFDbkUsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLGFBQWEsQ0FBQyxLQUFLO0lBQzFCLE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLE9BQU8sS0FBSyxJQUFJLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFBO0FBQ2hJLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyx3QkFBd0IsQ0FBQyxPQUFPO0lBQ3ZDLE1BQU0sSUFBSSxxQkFBcUIsQ0FBQyxFQUFDLElBQUksRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUE7QUFDMUYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge2lzRGVuc2VBcnJheX0gZnJvbSBcIi4uL2FycmF5LmpzXCJcbmltcG9ydCB7aXNTYWZlQXJ0aWZhY3RQYXRoLCBpc1NhZmVTb3VyY2VQYXRofSBmcm9tIFwiLi4vYXJ0aWZhY3QtcGF0aC5qc1wiXG5pbXBvcnQge2NyZWF0ZUdlbmVyYXRlZEFydGlmYWN0U2V0fSBmcm9tIFwiLi4vYXJ0aWZhY3RzLmpzXCJcbmltcG9ydCB7U2VtYW50aWZvbGREaWFnbm9zdGljLCB1bnN1cHBvcnRlZENhcGFiaWxpdHksIHVuc3VwcG9ydGVkUm9sZX0gZnJvbSBcIi4uL2RpYWdub3N0aWMuanNcIlxuaW1wb3J0IHtwYXJzZVByb2dyYW1Tb3VyY2V9IGZyb20gXCIuLi9mcm9udGVuZHMvcHJvZ3JhbS5qc1wiXG5pbXBvcnQge2xhbmd1YWdlUmVnaXN0cnl9IGZyb20gXCIuLi9sYW5ndWFnZS1yZWdpc3RyeS5qc1wiXG5pbXBvcnQge2ZpbmFsaXplTWFwcGluZywgdG9Tb3VyY2VNYXBWM30gZnJvbSBcIi4uL21hcHBpbmcuanNcIlxuaW1wb3J0IHtjcmVhdGVDb29yZGluYXRlSW5kZXgsIGluZGV4ZWRQb2ludEF0LCBtb2R1bGVMb2NhdGlvbn0gZnJvbSBcIi4uL3NlbWFudGljL2xvY2F0aW9uLmpzXCJcbmltcG9ydCB7c2VtYW50aWNFbnRyaWVzfSBmcm9tIFwiLi4vc2VtYW50aWMvcHJvdmVuYW5jZS5qc1wiXG5pbXBvcnQge2xpc3RTdGRsaWJNb2R1bGVzLCBwYXJzZVN0ZGxpYlZlcnNpb25SYW5nZX0gZnJvbSBcIi4uL3NlbWFudGljL3N0ZGxpYi5qc1wiXG5pbXBvcnQge21vZHVsZVVuY2hlY2tlZEVycm9yRWZmZWN0c30gZnJvbSBcIi4uL3NlbWFudGljL3ZhbGlkYXRlLmpzXCJcbmltcG9ydCB7bmVnb3RpYXRlU3RkbGliUHJvdmlkZXJzfSBmcm9tIFwiLi4vc3RkbGliLW5lZ290aWF0aW9uLmpzXCJcbmltcG9ydCB7c3RkbGliRmFjYWRlUHJvZ3JhbURlc2NyaXB0b3IsIHN0ZGxpYkZhY2FkZVJlZ2lzdHJ5fSBmcm9tIFwiLi4vc3RkbGliLWZhY2FkZXMuanNcIlxuaW1wb3J0IHtzdGRsaWJQcm92aWRlclJlZ2lzdHJ5fSBmcm9tIFwiLi4vc3RkbGliLXByb3ZpZGVycy5qc1wiXG5pbXBvcnQge3ByZWZsaWdodEVmZmVjdENhcGFiaWxpdGllc30gZnJvbSBcIi4vZWZmZWN0cy5qc1wiXG5pbXBvcnQge3ZhbGlkYXRlVGFyZ2V0QmluZGluZ0lkZW50aWZpZXIsIHZhbGlkYXRlVGFyZ2V0SWRlbnRpZmllciwgdmFsaWRhdGVUYXJnZXRUeXBlSWRlbnRpZmllcn0gZnJvbSBcIi4vaWRlbnRpZmllcnMuanNcIlxuaW1wb3J0IHtnZW5lcmF0ZVN0ZGxpYlByb3ZpZGVyQ29udGVudH0gZnJvbSBcIi4vc3RkbGliLXN1cHBvcnQuanNcIlxuaW1wb3J0IHt2YWxpZGF0ZUJhY2tlbmRNb2R1bGV9IGZyb20gXCIuL3NoYXJlZC5qc1wiXG5pbXBvcnQge3Byb2dyYW1JbXBvcnROYW1lLCBTb3VyY2VXcml0ZXJ9IGZyb20gXCIuL3dyaXRlci5qc1wiXG5cbi8qKiBAdHlwZSB7UmVhZG9ubHk8U2V0PGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2U+Pn0gKi9cbmNvbnN0IHByb2dyYW1UYXJnZXRzID0gbmV3IFNldChbXCJwaHBcIiwgXCJydWJ5XCIsIFwiamF2YXNjcmlwdFwiLCBcInR5cGVzY3JpcHRcIiwgXCJqYXZhXCJdKVxuLyoqIEB0eXBlIHtSZWFkb25seTxTZXQ8aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlPj59ICovXG5jb25zdCBwcm9ncmFtQXBwbGljYXRpb25UYXJnZXRzID0gbmV3IFNldChbXCJpb3NcIl0pXG5cbi8qKlxuICogVmFsaWRhdGVzIGFuZCBwcmVwYXJlcyBhIGNvbXBsZXRlIHNlbWFudGljIHByb2dyYW0gZm9yIGEgbm9uLXRleHQgYmFja2VuZCB3aXRob3V0IGFsbG9jYXRpbmcgYSB3cml0ZXIuXG4gKiBAcGFyYW0ge29iamVjdH0gaW5wdXQgLSBCYWNrZW5kIHByZWZsaWdodCByZXF1ZXN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBpbnB1dC5iYWNrZW5kTGFuZ3VhZ2UgLSBFeGlzdGluZyBzZW1hbnRpYyBiYWNrZW5kIHByb2ZpbGUgdG8gZW5mb3JjZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBpbnB1dC5kaWFnbm9zdGljTGFuZ3VhZ2UgLSBQdWJsaWMgdGFyZ2V0IGlkZW50aXR5IGZvciBjYXBhYmlsaXR5IGZhaWx1cmVzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW19IGlucHV0LnByb2dyYW0gLSBDb21wbGV0ZSBjYW5kaWRhdGUgcHJvZ3JhbS5cbiAqIEBwYXJhbSB7UmVhZG9ubHk8U2V0PGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2U+Pn0gW2lucHV0LnNvdXJjZUxhbmd1YWdlc10gLSBBY2NlcHRlZCBzb3VyY2UgcHJvdmVuYW5jZSBsYW5ndWFnZXMuXG4gKiBAcmV0dXJucyB7e21vZHVsZXM6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlW10sIHByb2dyYW06IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbSwgc291cmNlczoge2NvbnRlbnQ6IHN0cmluZywgZmlsZW5hbWU6IHN0cmluZywgbGFuZ3VhZ2U/OiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfVtdfX0gUHJlcGFyZWQgaW1tdXRhYmxlLWlucHV0IHZpZXdzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlZmxpZ2h0U2VtYW50aWNQcm9ncmFtKHtiYWNrZW5kTGFuZ3VhZ2UsIGRpYWdub3N0aWNMYW5ndWFnZSwgcHJvZ3JhbTogY2FuZGlkYXRlLCBzb3VyY2VMYW5ndWFnZXN9KSB7XG4gIHRyeSB7XG4gICAgY29uc3QgcHJvZ3JhbSA9IHZhbGlkYXRlUHJvZ3JhbShjYW5kaWRhdGUsIGJhY2tlbmRMYW5ndWFnZSwgc291cmNlTGFuZ3VhZ2VzKVxuICAgIGNvbnN0IG1vZHVsZXMgPSBwcmVwYXJlRW1pc3Npb25Nb2R1bGVzKHByb2dyYW0sIGJhY2tlbmRMYW5ndWFnZSlcblxuICAgIHZhbGlkYXRlUHJvZ3JhbVNvdXJjZU93bmVyc2hpcChwcm9ncmFtLCBiYWNrZW5kTGFuZ3VhZ2UpXG4gICAgY29uc3Qgc291cmNlcyA9IHByb2dyYW0uc291cmNlcy5tYXAoKHNvdXJjZSkgPT4ge1xuICAgICAgaWYgKHNvdXJjZS5jb250ZW50ID09PSBudWxsKSBpbnZhbGlkUHJvZ3JhbUdlbmVyYXRpb24oYFByb2dyYW0gc291cmNlICcke3NvdXJjZS5maWxlbmFtZX0nIGhhcyBubyByZXRhaW5lZCBjb250ZW50LmApXG5cbiAgICAgIHJldHVybiB7Y29udGVudDogc291cmNlLmNvbnRlbnQsIGZpbGVuYW1lOiBzb3VyY2UuZmlsZW5hbWUsIC4uLihzb3VyY2UubGFuZ3VhZ2UgPyB7bGFuZ3VhZ2U6IHNvdXJjZS5sYW5ndWFnZX0gOiB7fSl9XG4gICAgfSlcblxuICAgIHJldHVybiB7bW9kdWxlcywgcHJvZ3JhbSwgc291cmNlc31cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBTZW1hbnRpZm9sZERpYWdub3N0aWMgJiYgZXJyb3IuY29kZSA9PSBcIlVOU1VQUE9SVEVEX0NBUEFCSUxJVFlcIiAmJlxuICAgICAgZXJyb3IubGFuZ3VhZ2UgIT0gZGlhZ25vc3RpY0xhbmd1YWdlKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgICAgY2F1c2U6IGVycm9yLFxuICAgICAgICBjb2RlOiBlcnJvci5jb2RlLFxuICAgICAgICBsYW5ndWFnZTogZGlhZ25vc3RpY0xhbmd1YWdlLFxuICAgICAgICBsb2NhdGlvbjogZXJyb3IubG9jYXRpb24sXG4gICAgICAgIG1lc3NhZ2U6IGVycm9yLmRldGFpbFxuICAgICAgfSlcbiAgICB9XG4gICAgdGhyb3cgZXJyb3JcbiAgfVxufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIGNvbXBsZXRlIGRldGVybWluaXN0aWMgbWFwcGVkIGFydGlmYWN0IHNldCBmb3Igb25lIHNlbWFudGljIHByb2dyYW0uXG4gKiBAcGFyYW0ge29iamVjdH0gaW5wdXQgLSBQcm9ncmFtIGdlbmVyYXRpb24gcmVxdWVzdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBpbnB1dC5sYW5ndWFnZSAtIFJlZ2lzdGVyZWQgcHJvZ3JhbSB0YXJnZXQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbX0gaW5wdXQucHJvZ3JhbSAtIENvbXBsZXRlIHNlbWFudGljIHByb2dyYW0uXG4gKiBAcGFyYW0ge1widGV4dFwiIHwgXCJhcHBsaWNhdGlvblwifSBbaW5wdXQucm9sZV0gLSBFeHBsaWNpdCBhcnRpZmFjdCByb2xlOyBvbWl0dGVkIHByZXNlcnZlcyB0ZXh0IGdlbmVyYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLklvc0FwcGxpY2F0aW9uQ29uZmlndXJhdGlvbklucHV0fSBbaW5wdXQuY29uZmlndXJhdGlvbl0gLSBpT1MgYXBwbGljYXRpb24gY29uZmlndXJhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSW9zQXBwbGljYXRpb25Bc3NldElucHV0W119IFtpbnB1dC5hc3NldHNdIC0gRXhhY3QgaU9TIGNhbGxlciBhc3NldHMuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuR2VuZXJhdGVkQXJ0aWZhY3RTZXR9IFRyYW5zYWN0aW9uYWxseSB2YWxpZGF0ZWQgYXJ0aWZhY3Qgc2V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVQcm9ncmFtQXJ0aWZhY3RzKGlucHV0KSB7XG4gIGlmICghaXNQbGFpbk9iamVjdChpbnB1dCkgfHwgdHlwZW9mIGlucHV0Lmxhbmd1YWdlICE9IFwic3RyaW5nXCIpIGludmFsaWRQcm9ncmFtR2VuZXJhdGlvbihcIlByb2dyYW0gZ2VuZXJhdGlvbiByZXF1aXJlcyBhIHRhcmdldCBsYW5ndWFnZSBhbmQgcHJvZ3JhbS5cIilcbiAgY29uc3Qgcm9sZSA9IGlucHV0LnJvbGUgPz8gXCJ0ZXh0XCJcblxuICBpZiAocm9sZSAhPSBcInRleHRcIiAmJiByb2xlICE9IFwiYXBwbGljYXRpb25cIikgaW52YWxpZFByb2dyYW1HZW5lcmF0aW9uKFwiUHJvZ3JhbSBhcnRpZmFjdCByb2xlIG11c3QgYmUgJ3RleHQnIG9yICdhcHBsaWNhdGlvbicuXCIpXG4gIGxhbmd1YWdlUmVnaXN0cnkucmVjb3JkKGlucHV0Lmxhbmd1YWdlKVxuICBpZiAocm9sZSA9PSBcImFwcGxpY2F0aW9uXCIpIHtcbiAgICBpZiAoIXByb2dyYW1BcHBsaWNhdGlvblRhcmdldHMuaGFzKGlucHV0Lmxhbmd1YWdlKSkgdW5zdXBwb3J0ZWRSb2xlKGlucHV0Lmxhbmd1YWdlLCBcIm11bHRpLWZpbGUgYXBwbGljYXRpb24gYmFja2VuZFwiKVxuICAgIGNvbnN0IGJhY2tlbmQgPSBsYW5ndWFnZVJlZ2lzdHJ5LnJlc29sdmUoaW5wdXQubGFuZ3VhZ2UsIFwiYXBwbGljYXRpb25CYWNrZW5kXCIpXG5cbiAgICByZXR1cm4gY3JlYXRlR2VuZXJhdGVkQXJ0aWZhY3RTZXQoYmFja2VuZChpbnB1dCkpXG4gIH1cbiAgaWYgKCFwcm9ncmFtVGFyZ2V0cy5oYXMoLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSAqLyAoaW5wdXQubGFuZ3VhZ2UpKSkge1xuICAgIHVuc3VwcG9ydGVkUm9sZShpbnB1dC5sYW5ndWFnZSwgXCJtdWx0aS1maWxlIHRleHQgYmFja2VuZFwiKVxuICB9XG4gIGNvbnN0IGxhbmd1YWdlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSAqLyAoaW5wdXQubGFuZ3VhZ2UpXG4gIGNvbnN0IHByb2dyYW0gPSB2YWxpZGF0ZVByb2dyYW0oaW5wdXQucHJvZ3JhbSwgbGFuZ3VhZ2UpXG4gIGNvbnN0IGxpbmtpbmcgPSBwbGFuU3RkbGliTGlua2luZyhwcm9ncmFtLCBsYW5ndWFnZSlcbiAgY29uc3QgZW1pc3Npb25Nb2R1bGVzID0gcHJlcGFyZUVtaXNzaW9uTW9kdWxlcyhwcm9ncmFtLCBsYW5ndWFnZSwgbGlua2luZylcbiAgdmFsaWRhdGVQcm9ncmFtU291cmNlT3duZXJzaGlwKHByb2dyYW0sIGxhbmd1YWdlKVxuICBjb25zdCBwYXRocyA9IHBsYW5Nb2R1bGVQYXRocyhwcm9ncmFtLCBsYW5ndWFnZSwgbGlua2luZylcbiAgY29uc3Qgc291cmNlcyA9IHByb2dyYW0uc291cmNlcy5tYXAoKHNvdXJjZSkgPT4ge1xuICAgIGlmIChzb3VyY2UuY29udGVudCA9PT0gbnVsbCkgaW52YWxpZFByb2dyYW1HZW5lcmF0aW9uKGBQcm9ncmFtIHNvdXJjZSAnJHtzb3VyY2UuZmlsZW5hbWV9JyBoYXMgbm8gcmV0YWluZWQgY29udGVudC5gKVxuXG4gICAgcmV0dXJuIHtjb250ZW50OiBzb3VyY2UuY29udGVudCwgZmlsZW5hbWU6IHNvdXJjZS5maWxlbmFtZSwgLi4uKHNvdXJjZS5sYW5ndWFnZSA/IHtsYW5ndWFnZTogc291cmNlLmxhbmd1YWdlfSA6IHt9KX1cbiAgfSlcbiAgY29uc3QgYmFja2VuZCA9IC8qKiBAdHlwZSB7dHlwZW9mIGltcG9ydChcIi4vamF2YXNjcmlwdC5qc1wiKS5nZW5lcmF0ZUphdmFTY3JpcHR9ICovIChcbiAgICBsYW5ndWFnZVJlZ2lzdHJ5LnJlc29sdmUobGFuZ3VhZ2UsIFwidGV4dEJhY2tlbmRcIikpXG4gIGNvbnN0IG1lZGlhVHlwZSA9IGxhbmd1YWdlUmVnaXN0cnkucmVjb3JkKGxhbmd1YWdlKS5tZWRpYVR5cGVcbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5HZW5lcmF0ZWRTZXRBcnRpZmFjdFtdfSAqL1xuICBjb25zdCBhcnRpZmFjdHMgPSBsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIiB8fCBsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIiA/IFt7XG4gICAgY29udGVudDogXCJ7XFxuICBcXFwidHlwZVxcXCI6IFxcXCJtb2R1bGVcXFwiXFxufVxcblwiLFxuICAgIGNvbnRlbnRLaW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJ0ZXh0XCIpLFxuICAgIG1lZGlhVHlwZTogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgb3duZXJzaGlwOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJnZW5lcmF0ZWRcIiksXG4gICAgcGF0aDogXCJwYWNrYWdlLmpzb25cIixcbiAgICBwcm92ZW5hbmNlOiB7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJzeW50aGV0aWNcIiksXG4gICAgICByZWFzb246IFwiRGVjbGFyZXMgdGhlIGdlbmVyYXRlZCBKYXZhU2NyaXB0LWZhbWlseSBhcnRpZmFjdCBzZXQgYXMgY2Fub25pY2FsIEVTTS5cIixcbiAgICAgIHJlbGF0ZWRPcmlnaW5zOiBbXVxuICAgIH0sXG4gICAgcm9sZTogXCJtYW5pZmVzdFwiXG4gIH1dIDogW11cblxuICBpZiAobGlua2luZyAmJiBsYW5ndWFnZSAhPSBcImphdmFcIikge1xuICAgIGZvciAoY29uc3QgcHJvdmlkZXIgb2YgbGlua2luZy5uZWdvdGlhdGlvbi5wcm92aWRlcnMpIHtcbiAgICAgIGNvbnN0IHJlY29yZCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc3RkbGliLXByb3ZpZGVycy5qc1wiKS5TdGRsaWJQcm92aWRlclJlY29yZH0gKi8gKGxpbmtpbmcucmVjb3Jkcy5nZXQocHJvdmlkZXIubW9kdWxlKSlcblxuICAgICAgYXJ0aWZhY3RzLnB1c2goe1xuICAgICAgICBjb250ZW50OiBnZW5lcmF0ZVN0ZGxpYlByb3ZpZGVyQ29udGVudCgvKiogQHR5cGUge1wicGhwXCIgfCBcInJ1YnlcIiB8IFwiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9ICovIChsYW5ndWFnZSksXG4gICAgICAgICAgWy4uLnByb3ZpZGVyLm9wZXJhdGlvbnNdLCBwcm92aWRlci5tb2R1bGUpLFxuICAgICAgICBjb250ZW50S2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwidGV4dFwiKSxcbiAgICAgICAgbWVkaWFUeXBlOiByZWNvcmQuYXJ0aWZhY3QubWVkaWFUeXBlLFxuICAgICAgICBvd25lcnNoaXA6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcImdlbmVyYXRlZFwiKSxcbiAgICAgICAgcGF0aDogcmVjb3JkLmFydGlmYWN0LnBhdGgsXG4gICAgICAgIHByb3ZlbmFuY2U6IHtcbiAgICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJzeW50aGV0aWNcIiksXG4gICAgICAgICAgcmVhc29uOiBgc2VtYW50aWZvbGQtc3RkbGliLXByb3ZpZGVyOiR7cmVjb3JkLmlkZW50aXR5fWAsXG4gICAgICAgICAgcmVsYXRlZE9yaWdpbnM6IFtdXG4gICAgICAgIH0sXG4gICAgICAgIHJvbGU6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcInN1cHBvcnRcIilcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgZm9yIChjb25zdCBlbWlzc2lvbk1vZHVsZSBvZiBlbWlzc2lvbk1vZHVsZXMpIHtcbiAgICBjb25zdCBtb2R1bGVJZCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoUmVmbGVjdC5nZXQoZW1pc3Npb25Nb2R1bGUsIFwiaWRcIikpXG4gICAgY29uc3QgZmlsZW5hbWUgPSAvKiogQHR5cGUge3N0cmluZ30gKi8gKHBhdGhzLmdldChtb2R1bGVJZCkpXG4gICAgY29uc3Qgd3JpdGVyID0gbmV3IFNvdXJjZVdyaXRlcih7XG4gICAgICBmaWxlbmFtZSxcbiAgICAgIGxhbmd1YWdlLFxuICAgICAgbW9kdWxlOiBlbWlzc2lvbk1vZHVsZSxcbiAgICAgIHByb2dyYW0sXG4gICAgICBwcm9ncmFtUGF0aHM6IHBhdGhzLFxuICAgICAgc291cmNlcyxcbiAgICAgIC4uLihsaW5raW5nICYmIGVtaXNzaW9uTW9kdWxlLmNhcGFiaWxpdGllcyAhPT0gdW5kZWZpbmVkID8ge1xuICAgICAgICBzdGRsaWJQcm92aWRlckVudHJpZXM6IE9iamVjdC5mcm9tRW50cmllcygobGlua2luZy51c2VkT3BlcmF0aW9uc0J5TW9kdWxlLmdldChtb2R1bGVJZCkgPz8gW10pLm1hcCgoe21vZHVsZSwgb3BlcmF0aW9ufSkgPT4gW1xuICAgICAgICAgIHF1YWxpZmllZE9wZXJhdGlvbktleShtb2R1bGUsIG9wZXJhdGlvbiksXG4gICAgICAgICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovIChsaW5raW5nLnJlY29yZHMuZ2V0KG1vZHVsZSk/Lm5hdGl2ZUVudHJpZXNbb3BlcmF0aW9uXSlcbiAgICAgICAgXSkpLFxuICAgICAgICBzdGRsaWJQcm92aWRlckltcG9ydHM6IGxhbmd1YWdlID09IFwiamF2YVwiIHx8IGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiID9cbiAgICAgICAgICBsaW5raW5nLnByb3ZpZGVySW1wb3J0c0J5TW9kdWxlLmdldChtb2R1bGVJZCkgOiB1bmRlZmluZWQsXG4gICAgICAgIHN0ZGxpYlByb3ZpZGVyUGF0aHM6IGxpbmtpbmcucHJvdmlkZXJQYXRoc0J5TW9kdWxlLmdldChtb2R1bGVJZCksXG4gICAgICAgIC4uLihsYW5ndWFnZSA9PSBcImphdmFcIiA/IHtcbiAgICAgICAgICBzdGRsaWJQcm92aWRlck93bmVyTW9kdWxlOiAvKiogQHR5cGUge3N0cmluZ30gKi8gKGxpbmtpbmcub3duZXJNb2R1bGVJZCksXG4gICAgICAgICAgc3RkbGliUHJvdmlkZXJTaGltczogbW9kdWxlSWQgPT0gbGlua2luZy5vd25lck1vZHVsZUlkID8gbGlua2luZy51c2VkT3BlcmF0aW9ucy5tYXAoKHtvcGVyYXRpb259KSA9PiBvcGVyYXRpb24pIDogdW5kZWZpbmVkXG4gICAgICAgIH0gOiB7fSlcbiAgICAgIH0gOiB7fSlcbiAgICB9KVxuXG4gICAgYmFja2VuZChlbWlzc2lvbk1vZHVsZSwgd3JpdGVyKVxuICAgIGNvbnN0IG1hcHBpbmcgPSBmaW5hbGl6ZU1hcHBpbmcod3JpdGVyLmZpbmlzaCgpKVxuXG4gICAgYXJ0aWZhY3RzLnB1c2goe1xuICAgICAgY29udGVudDogbWFwcGluZy5nZW5lcmF0ZWQuY29udGVudCxcbiAgICAgIGNvbnRlbnRLaW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJ0ZXh0XCIpLFxuICAgICAgbWVkaWFUeXBlOiAvKiogQHR5cGUge3N0cmluZ30gKi8gKG1lZGlhVHlwZSksXG4gICAgICBvd25lcnNoaXA6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcImdlbmVyYXRlZFwiKSxcbiAgICAgIHBhdGg6IGZpbGVuYW1lLFxuICAgICAgcHJvdmVuYW5jZToge1xuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJ0ZXh0XCIpLFxuICAgICAgICBtYXBwaW5nLFxuICAgICAgICBzb3VyY2VNYXA6IHRvU291cmNlTWFwVjMobWFwcGluZyksXG4gICAgICAgIHNvdXJjZU1hcEZpbGVuYW1lOiBgJHtmaWxlbmFtZX0ubWFwYFxuICAgICAgfSxcbiAgICAgIHJvbGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuR2VuZXJhdGVkQXJ0aWZhY3RSb2xlfSAqLyAoXG4gICAgICAgIG1vZHVsZUlkID09IHByb2dyYW0uZW50cnlNb2R1bGUgPyBcImVudHJ5XCIgOiBSZWZsZWN0LmdldChlbWlzc2lvbk1vZHVsZSwgXCJzdGRsaWJGYWNhZGVcIikgPyBcInN1cHBvcnRcIiA6IFwic291cmNlXCIpXG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVHZW5lcmF0ZWRBcnRpZmFjdFNldCh7XG4gICAgYXJ0aWZhY3RzLFxuICAgIC4uLihsaW5raW5nIHx8IHByb2dyYW0uc3RkbGliRmFjYWRlcyA/IHttZXRhZGF0YTogc3RkbGliTGlua01ldGFkYXRhKGxpbmtpbmcsIHBhdGhzLCBwcm9ncmFtLnN0ZGxpYkZhY2FkZXMpfSA6IHt9KSxcbiAgICB0YXJnZXQ6IGxhbmd1YWdlXG4gIH0pXG59XG5cbi8qKlxuICogQHR5cGVkZWYgU3RkbGliUHJvZ3JhbUxpbmtpbmdcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc3RkbGliLW5lZ290aWF0aW9uLmpzXCIpLlN0ZGxpYk5lZ290aWF0aW9uUmVzdWx0fSBuZWdvdGlhdGlvbiAtIE5lZ290aWF0ZWQgcHJvdmlkZXIgY2xvc3VyZS5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc3RkbGliLXByb3ZpZGVycy5qc1wiKS5TdGRsaWJQcm92aWRlclJlY29yZD59IHJlY29yZHMgLSBNYXRlcmlhbGl6ZWQgcHJvdmlkZXIgcmVjb3JkcyBieSBjYW5vbmljYWwgbW9kdWxlLlxuICogQHByb3BlcnR5IHtRdWFsaWZpZWRTdGRsaWJPcGVyYXRpb25bXX0gdXNlZE9wZXJhdGlvbnMgLSBQcm9ncmFtLXdpZGUgdXNlZCBjYW5vbmljYWwgb3BlcmF0aW9ucyBpbiBzdGFibGUgb3JkZXIuXG4gKiBAcHJvcGVydHkge01hcDxzdHJpbmcsIFF1YWxpZmllZFN0ZGxpYk9wZXJhdGlvbltdPn0gdXNlZE9wZXJhdGlvbnNCeU1vZHVsZSAtIFVzZWQgY2Fub25pY2FsIG9wZXJhdGlvbnMgYnkgcHJvZ3JhbSBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcHJvcGVydHkge01hcDxzdHJpbmcsIHN0cmluZ1tdPn0gcHJvdmlkZXJJbXBvcnRzQnlNb2R1bGUgLSBPcmRlcmVkIHByb3ZpZGVyIGltcG9ydCBuYW1lcyBieSBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcHJvcGVydHkge01hcDxzdHJpbmcsIHN0cmluZ1tdPn0gcHJvdmlkZXJQYXRoc0J5TW9kdWxlIC0gUHJvdmlkZXIgYXJ0aWZhY3QgY2xvc3VyZSBieSBwcm9ncmFtIG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nIHwgbnVsbH0gb3duZXJNb2R1bGVJZCAtIEphdmEgdGFyZ2V0OiBmaXJzdCBvcGVyYXRpb24tdXNpbmcgbW9kdWxlIGlkZW50aXR5IGhvc3RpbmcgdGhlIHNoYXJlZCBzdXBwb3J0OyBudWxsIGZvciBhcnRpZmFjdC1tYXRlcmlhbGl6aW5nIHRhcmdldHMuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBRdWFsaWZpZWRTdGRsaWJPcGVyYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBtb2R1bGUgLSBDYW5vbmljYWwgbW9kdWxlIGlkZW50aXR5LlxuICogQHByb3BlcnR5IHtzdHJpbmd9IG9wZXJhdGlvbiAtIENhbm9uaWNhbCBvcGVyYXRpb24gbmFtZS5cbiAqL1xuXG4vKipcbiAqIFBsYW5zIHRoZSBsaW5rZWQgc3RkbGliIHByb3ZpZGVyIGZvciBvbmUgcHJvZ3JhbSwgb3IgcmVwb3J0cyB0aGF0IG5vIG9wZXJhdGlvbiBpcyB1c2VkLlxuICogSmF2YSByZXNvbHZlcyB0aGUgc2FtZSBuZWdvdGlhdGVkIHByb3ZpZGVyIHJlY29yZCBidXQgaG9zdHMgaXRzIHN1cHBvcnQgaW4gdGhlIGZpcnN0XG4gKiBvcGVyYXRpb24tdXNpbmcgbW9kdWxlIGluc3RlYWQgb2YgYSBzZXBhcmF0ZSBwcm92aWRlciBhcnRpZmFjdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtfSBwcm9ncmFtIC0gVmFsaWRhdGVkIHNlbWFudGljIHByb2dyYW0uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGxhbmd1YWdlLlxuICogQHJldHVybnMge1N0ZGxpYlByb2dyYW1MaW5raW5nIHwgbnVsbH0gTGlua2luZyBwbGFuLCBvciBudWxsIHdoZW4gbm90aGluZyBpcyB1c2VkLlxuICovXG5mdW5jdGlvbiBwbGFuU3RkbGliTGlua2luZyhwcm9ncmFtLCBsYW5ndWFnZSkge1xuICBjb25zdCB7cHJvZ3JhbVdpZGUsIHVzZWRPcGVyYXRpb25zQnlNb2R1bGV9ID0gY29sbGVjdFVzZWRFZmZlY3RPcGVyYXRpb25zKHByb2dyYW0pXG5cbiAgaWYgKHByb2dyYW1XaWRlLmxlbmd0aCA9PSAwKSByZXR1cm4gbnVsbFxuICBjb25zdCBjb250cmFjdHMgPSBwcm9ncmFtLnN0ZGxpYkNvbnRyYWN0cyA/PyBbLyoqIEB0eXBlIHt7aWRlbnRpdHk6IHN0cmluZywgY29udHJhY3RWZXJzaW9uPzogc3RyaW5nfX0gKi8gKHByb2dyYW0uc3RkbGliQ29udHJhY3QpXVxuICBjb25zdCBjb250cmFjdHNCeUlkZW50aXR5ID0gbmV3IE1hcChjb250cmFjdHMubWFwKChjb250cmFjdCkgPT4gW2NvbnRyYWN0LmlkZW50aXR5LCBjb250cmFjdF0pKVxuICBjb25zdCByZXF1aXJlbWVudHNCeU1vZHVsZSA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3QgcXVhbGlmaWVkIG9mIHByb2dyYW1XaWRlKSB7XG4gICAgY29uc3QgcmVxdWlyZW1lbnQgPSByZXF1aXJlbWVudHNCeU1vZHVsZS5nZXQocXVhbGlmaWVkLm1vZHVsZSkgPz8gW11cblxuICAgIHJlcXVpcmVtZW50LnB1c2gocXVhbGlmaWVkLm9wZXJhdGlvbilcbiAgICByZXF1aXJlbWVudHNCeU1vZHVsZS5zZXQocXVhbGlmaWVkLm1vZHVsZSwgcmVxdWlyZW1lbnQpXG4gIH1cbiAgY29uc3QgbmVnb3RpYXRpb24gPSBuZWdvdGlhdGVTdGRsaWJQcm92aWRlcnMoe1xuICAgIHJlcXVpcmVtZW50czogWy4uLnJlcXVpcmVtZW50c0J5TW9kdWxlXS5tYXAoKFttb2R1bGUsIG9wZXJhdGlvbnNdKSA9PiB7XG4gICAgICBjb25zdCBjb250cmFjdCA9IGNvbnRyYWN0c0J5SWRlbnRpdHkuZ2V0KG1vZHVsZSlcblxuICAgICAgaWYgKCFjb250cmFjdCkgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7XG4gICAgICAgIGNvZGU6IFwiU1RETElCX0xJTktfRkFJTFVSRVwiLFxuICAgICAgICBsYW5ndWFnZSxcbiAgICAgICAgbWVzc2FnZTogYFJlYWNoYWJsZSBjYW5vbmljYWwgb3BlcmF0aW9uICcke21vZHVsZX0uJHtvcGVyYXRpb25zWzBdfScgaGFzIG5vIGRlY2xhcmVkIHN0YW5kYXJkLWxpYnJhcnkgY29udHJhY3QuYFxuICAgICAgfSlcbiAgICAgIHJldHVybiB7bW9kdWxlLCBvcGVyYXRpb25zLCAuLi4oY29udHJhY3QuY29udHJhY3RWZXJzaW9uICE9PSB1bmRlZmluZWQgPyB7cmFuZ2U6IGNvbnRyYWN0LmNvbnRyYWN0VmVyc2lvbn0gOiB7fSl9XG4gICAgfSksXG4gICAgdGFyZ2V0OiBsYW5ndWFnZVxuICB9KVxuICAvKiogQHR5cGUge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3N0ZGxpYi1wcm92aWRlcnMuanNcIikuU3RkbGliUHJvdmlkZXJSZWNvcmQ+fSAqL1xuICBjb25zdCByZWNvcmRzID0gbmV3IE1hcCgpXG5cbiAgZm9yIChjb25zdCBzZWxlY3RlZCBvZiBuZWdvdGlhdGlvbi5tb2R1bGVzKSB7XG4gICAgY29uc3QgY2FuZGlkYXRlcyA9IHN0ZGxpYlByb3ZpZGVyUmVnaXN0cnkucHJvdmlkZXJzRm9yKGxhbmd1YWdlLCBzZWxlY3RlZC5pZGVudGl0eSwgc2VsZWN0ZWQudmVyc2lvbilcblxuICAgIGlmIChjYW5kaWRhdGVzLmxlbmd0aCAhPSAxKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgICAgY29kZTogXCJTVERMSUJfTElOS19GQUlMVVJFXCIsXG4gICAgICAgIGxhbmd1YWdlLFxuICAgICAgICBtZXNzYWdlOiBgRXhwZWN0ZWQgZXhhY3RseSBvbmUgcmVnaXN0ZXJlZCBzdGRsaWIgcHJvdmlkZXIgZm9yICcke3NlbGVjdGVkLmlkZW50aXR5fScgb24gJyR7bGFuZ3VhZ2V9Jy5gXG4gICAgICB9KVxuICAgIH1cbiAgICByZWNvcmRzLnNldChzZWxlY3RlZC5pZGVudGl0eSwgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zdGRsaWItcHJvdmlkZXJzLmpzXCIpLlN0ZGxpYlByb3ZpZGVyUmVjb3JkfSAqLyAoY2FuZGlkYXRlc1swXSkpXG4gIH1cbiAgY29uc3Qgb3duZXJNb2R1bGVJZCA9IGxhbmd1YWdlID09IFwiamF2YVwiXG4gICAgPyBwcm9ncmFtLm1vZHVsZXMubWFwKChtb2R1bGUpID0+IG1vZHVsZS5pZCkuZmluZCgoaWQpID0+ICh1c2VkT3BlcmF0aW9uc0J5TW9kdWxlLmdldChpZCkgPz8gW10pLmxlbmd0aCA+IDApXG4gICAgOiBudWxsXG5cbiAgaWYgKG93bmVyTW9kdWxlSWQgPT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7XG4gICAgY29kZTogXCJTVERMSUJfTElOS19GQUlMVVJFXCIsXG4gICAgbGFuZ3VhZ2UsXG4gICAgbWVzc2FnZTogXCJKYXZhIHByb2dyYW0gbGlua2luZyByZXF1aXJlcyBvbmUgbW9kdWxlIHVzaW5nIGNhbm9uaWNhbCBvcGVyYXRpb25zLlwiXG4gIH0pXG5cbiAgcmV0dXJuIHtcbiAgICBuZWdvdGlhdGlvbixcbiAgICBvd25lck1vZHVsZUlkLFxuICAgIHByb3ZpZGVySW1wb3J0c0J5TW9kdWxlOiBjb2xsZWN0UHJvdmlkZXJJbXBvcnRzKHByb2dyYW0sIG5lZ290aWF0aW9uLCByZWNvcmRzLCB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlLCBsYW5ndWFnZSwgb3duZXJNb2R1bGVJZCksXG4gICAgcHJvdmlkZXJQYXRoc0J5TW9kdWxlOiBjb2xsZWN0UHJvdmlkZXJQYXRocyhuZWdvdGlhdGlvbiwgcmVjb3JkcywgdXNlZE9wZXJhdGlvbnNCeU1vZHVsZSksXG4gICAgcmVjb3JkcyxcbiAgICB1c2VkT3BlcmF0aW9uczogWy4uLnByb2dyYW1XaWRlXSxcbiAgICB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlXG4gIH1cbn1cblxuLyoqXG4gKiBTZWxlY3RzIHRoZSBleGFjdCBwcm92aWRlci90eXBlIGRlcGVuZGVuY3kgY2xvc3VyZSByZXF1aXJlZCBieSBlYWNoIGVtaXR0aW5nIHByb2dyYW0gbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdGRsaWItbmVnb3RpYXRpb24uanNcIikuU3RkbGliTmVnb3RpYXRpb25SZXN1bHR9IG5lZ290aWF0aW9uIC0gTmVnb3RpYXRlZCBwcm9ncmFtIGNsb3N1cmUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3N0ZGxpYi1wcm92aWRlcnMuanNcIikuU3RkbGliUHJvdmlkZXJSZWNvcmQ+fSByZWNvcmRzIC0gU2VsZWN0ZWQgcHJvdmlkZXIgcmVjb3Jkcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgUXVhbGlmaWVkU3RkbGliT3BlcmF0aW9uW10+fSB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlIC0gUmVhY2hhYmxlIG9wZXJhdGlvbnMgYnkgcHJvZ3JhbSBtb2R1bGUuXG4gKiBAcmV0dXJucyB7TWFwPHN0cmluZywgc3RyaW5nW10+fSBPcmRlcmVkIHByb3ZpZGVyIHBhdGhzIGJ5IHByb2dyYW0gbW9kdWxlLlxuICovXG5mdW5jdGlvbiBjb2xsZWN0UHJvdmlkZXJQYXRocyhuZWdvdGlhdGlvbiwgcmVjb3JkcywgdXNlZE9wZXJhdGlvbnNCeU1vZHVsZSkge1xuICBjb25zdCBwYXRocyA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3QgW21vZHVsZUlkLCBvcGVyYXRpb25zXSBvZiB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlKSB7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSBuZXcgU2V0KG9wZXJhdGlvbnMubWFwKCh7bW9kdWxlfSkgPT4gbW9kdWxlKSlcbiAgICBsZXQgY2hhbmdlZCA9IHRydWVcblxuICAgIHdoaWxlIChjaGFuZ2VkKSB7XG4gICAgICBjaGFuZ2VkID0gZmFsc2VcbiAgICAgIGZvciAoY29uc3QgbW9kdWxlIG9mIFsuLi5zZWxlY3RlZF0pIHtcbiAgICAgICAgZm9yIChjb25zdCBkZXBlbmRlbmN5IG9mIHJlY29yZHMuZ2V0KG1vZHVsZSk/LmRlcGVuZGVuY2llcyA/PyBbXSkge1xuICAgICAgICAgIGlmICghc2VsZWN0ZWQuaGFzKGRlcGVuZGVuY3kubW9kdWxlKSkge1xuICAgICAgICAgICAgc2VsZWN0ZWQuYWRkKGRlcGVuZGVuY3kubW9kdWxlKVxuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcGF0aHMuc2V0KG1vZHVsZUlkLCBuZWdvdGlhdGlvbi5wcm92aWRlcnMuZmlsdGVyKCh7bW9kdWxlfSkgPT4gc2VsZWN0ZWQuaGFzKG1vZHVsZSkpLm1hcCgoe21vZHVsZX0pID0+XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3N0ZGxpYi1wcm92aWRlcnMuanNcIikuU3RkbGliUHJvdmlkZXJSZWNvcmR9ICovIChyZWNvcmRzLmdldChtb2R1bGUpKS5hcnRpZmFjdC5wYXRoKSlcbiAgfVxuICByZXR1cm4gcGF0aHNcbn1cblxuLyoqXG4gKiBDb2xsZWN0cyB0aGUgY2Fub25pY2FsIG9wZXJhdGlvbnMgaW52b2tlZCBieSBlYWNoIHByb2dyYW0gbW9kdWxlIGluIHN0YWJsZSBvcmRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtfSBwcm9ncmFtIC0gVmFsaWRhdGVkIHNlbWFudGljIHByb2dyYW0uXG4gKiBAcmV0dXJucyB7e3Byb2dyYW1XaWRlOiBRdWFsaWZpZWRTdGRsaWJPcGVyYXRpb25bXSwgdXNlZE9wZXJhdGlvbnNCeU1vZHVsZTogTWFwPHN0cmluZywgUXVhbGlmaWVkU3RkbGliT3BlcmF0aW9uW10+fX0gVXNlZCBvcGVyYXRpb25zLlxuICovXG5mdW5jdGlvbiBjb2xsZWN0VXNlZEVmZmVjdE9wZXJhdGlvbnMocHJvZ3JhbSkge1xuICAvKiogQHR5cGUge01hcDxzdHJpbmcsIFF1YWxpZmllZFN0ZGxpYk9wZXJhdGlvbltdPn0gKi9cbiAgY29uc3QgdXNlZE9wZXJhdGlvbnNCeU1vZHVsZSA9IG5ldyBNYXAoKVxuICAvKiogQHR5cGUge01hcDxzdHJpbmcsIFF1YWxpZmllZFN0ZGxpYk9wZXJhdGlvbj59ICovXG4gIGNvbnN0IHByb2dyYW1XaWRlID0gbmV3IE1hcCgpXG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywge2JvZHk6IHVua25vd24sIG1vZHVsZTogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtTW9kdWxlfT59ICovXG4gIGNvbnN0IGJvZGllcyA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3QgbW9kdWxlIG9mIHByb2dyYW0ubW9kdWxlcykge1xuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykgYm9kaWVzLnNldCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwge2JvZHk6IGRlY2xhcmF0aW9uLmJvZHksIG1vZHVsZX0pXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuY2xhc3NlcyA/PyBbXSkge1xuICAgICAgYm9kaWVzLnNldCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yLmlkKSwge2JvZHk6IGRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yLmJvZHksIG1vZHVsZX0pXG4gICAgICBmb3IgKGNvbnN0IG1ldGhvZCBvZiBkZWNsYXJhdGlvbi5tZXRob2RzKSBib2RpZXMuc2V0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAobWV0aG9kLmlkKSwge2JvZHk6IG1ldGhvZC5ib2R5LCBtb2R1bGV9KVxuICAgIH1cbiAgICB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlLnNldChtb2R1bGUuaWQsIFtdKVxuICB9XG4gIGNvbnN0IGVudHJ5TW9kdWxlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGV9ICovIChcbiAgICBwcm9ncmFtLm1vZHVsZXMuZmluZCgoe2lkfSkgPT4gaWQgPT0gcHJvZ3JhbS5lbnRyeU1vZHVsZSkpXG4gIC8qKiBAdHlwZSB7e2JvZHk6IHVua25vd24sIG1vZHVsZTogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtTW9kdWxlfVtdfSAqL1xuICBjb25zdCBwZW5kaW5nID0gW3tib2R5OiBlbnRyeU1vZHVsZS5lbnRyeVBvaW50Py5ib2R5LCBtb2R1bGU6IGVudHJ5TW9kdWxlfV1cbiAgY29uc3QgcmVhY2hlZERlY2xhcmF0aW9ucyA9IG5ldyBTZXQoKVxuXG4gIHdoaWxlIChwZW5kaW5nLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBjdXJyZW50ID0gLyoqIEB0eXBlIHt7Ym9keTogdW5rbm93biwgbW9kdWxlOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGV9fSAqLyAocGVuZGluZy5zaGlmdCgpKVxuICAgIGNvbnN0IG9wZXJhdGlvbk5hbWVzID0gbmV3IE1hcChjdXJyZW50Lm1vZHVsZS5jYXBhYmlsaXRpZXM/LmZsYXRNYXAoKGNhcGFiaWxpdHkpID0+XG4gICAgICBjYXBhYmlsaXR5Lm9wZXJhdGlvbnMubWFwKChvcGVyYXRpb24pID0+IFtvcGVyYXRpb24uaWQsIHttb2R1bGU6IGNhcGFiaWxpdHkuYXV0aG9yaXR5SWQsIG9wZXJhdGlvbjogb3BlcmF0aW9uLm5hbWV9XSkpID8/IFtdKVxuICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0KClcblxuICAgIC8qKlxuICAgICAqIFZpc2l0cyBvbmUgcmVhY2hhYmxlIHNlbWFudGljIHN1YnRyZWUuXG4gICAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSBzZW1hbnRpYyBzdWJ0cmVlLlxuICAgICAqL1xuICAgIGNvbnN0IHZpc2l0ID0gKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKHZhbHVlKSkgcmV0dXJuXG4gICAgICBzZWVuLmFkZCh2YWx1ZSlcblxuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICBjb25zdCBraW5kID0gUmVmbGVjdC5nZXQodmFsdWUsIFwia2luZFwiKVxuXG4gICAgICAgIGlmIChraW5kID09IFwiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIikge1xuICAgICAgICAgIGNvbnN0IG9wZXJhdGlvbiA9IFJlZmxlY3QuZ2V0KHZhbHVlLCBcIm9wZXJhdGlvblwiKVxuXG4gICAgICAgICAgaWYgKHR5cGVvZiBvcGVyYXRpb24gPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgY29uc3QgcXVhbGlmaWVkID0gb3BlcmF0aW9uTmFtZXMuZ2V0KG9wZXJhdGlvbilcblxuICAgICAgICAgICAgaWYgKHF1YWxpZmllZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGtleSA9IHF1YWxpZmllZE9wZXJhdGlvbktleShxdWFsaWZpZWQubW9kdWxlLCBxdWFsaWZpZWQub3BlcmF0aW9uKVxuICAgICAgICAgICAgICBjb25zdCBtb2R1bGVPcGVyYXRpb25zID0gLyoqIEB0eXBlIHtRdWFsaWZpZWRTdGRsaWJPcGVyYXRpb25bXX0gKi8gKHVzZWRPcGVyYXRpb25zQnlNb2R1bGUuZ2V0KGN1cnJlbnQubW9kdWxlLmlkKSlcblxuICAgICAgICAgICAgICBpZiAoIW1vZHVsZU9wZXJhdGlvbnMuc29tZSgoaXRlbSkgPT4gcXVhbGlmaWVkT3BlcmF0aW9uS2V5KGl0ZW0ubW9kdWxlLCBpdGVtLm9wZXJhdGlvbikgPT0ga2V5KSkgbW9kdWxlT3BlcmF0aW9ucy5wdXNoKHF1YWxpZmllZClcbiAgICAgICAgICAgICAgcHJvZ3JhbVdpZGUuc2V0KGtleSwgcXVhbGlmaWVkKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWNsYXJhdGlvbklkID0gaXNQbGFpbk9iamVjdChSZWZsZWN0LmdldCh2YWx1ZSwgXCJyZXNvbHV0aW9uXCIpKVxuICAgICAgICAgID8gUmVmbGVjdC5nZXQoUmVmbGVjdC5nZXQodmFsdWUsIFwicmVzb2x1dGlvblwiKSwgXCJkZWNsYXJhdGlvbklkXCIpIDogdW5kZWZpbmVkXG5cbiAgICAgICAgaWYgKHR5cGVvZiBkZWNsYXJhdGlvbklkID09IFwic3RyaW5nXCIgJiYgIXJlYWNoZWREZWNsYXJhdGlvbnMuaGFzKGRlY2xhcmF0aW9uSWQpKSB7XG4gICAgICAgICAgY29uc3QgZGVjbGFyYXRpb24gPSBib2RpZXMuZ2V0KGRlY2xhcmF0aW9uSWQpXG5cbiAgICAgICAgICBpZiAoZGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgIHJlYWNoZWREZWNsYXJhdGlvbnMuYWRkKGRlY2xhcmF0aW9uSWQpXG4gICAgICAgICAgICBwZW5kaW5nLnB1c2goZGVjbGFyYXRpb24pXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgY2hpbGRdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlKSkge1xuICAgICAgICAgIGlmIChbXCJjYXBhYmlsaXRpZXNcIiwgXCJsb2NhdGlvblwiLCBcInByb3ZlbmFuY2VcIiwgXCJyZXNvbHV0aW9uXCIsIFwic291cmNlUHJvdmVuYW5jZVwiXS5pbmNsdWRlcyhrZXkpKSBjb250aW51ZVxuICAgICAgICAgIHZpc2l0KGNoaWxkKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgZm9yIChjb25zdCBjaGlsZCBvZiB2YWx1ZSkgdmlzaXQoY2hpbGQpXG4gICAgfVxuXG4gICAgdmlzaXQoY3VycmVudC5ib2R5KVxuICB9XG4gIGZvciAoY29uc3Qgb3BlcmF0aW9ucyBvZiB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlLnZhbHVlcygpKSB7XG4gICAgb3BlcmF0aW9ucy5zb3J0KChsZWZ0LCByaWdodCkgPT4gcXVhbGlmaWVkT3BlcmF0aW9uS2V5KGxlZnQubW9kdWxlLCBsZWZ0Lm9wZXJhdGlvbilcbiAgICAgIC5sb2NhbGVDb21wYXJlKHF1YWxpZmllZE9wZXJhdGlvbktleShyaWdodC5tb2R1bGUsIHJpZ2h0Lm9wZXJhdGlvbiksIFwiZW5cIikpXG4gIH1cbiAgcmV0dXJuIHtwcm9ncmFtV2lkZTogWy4uLnByb2dyYW1XaWRlLnZhbHVlcygpXS5zb3J0KChsZWZ0LCByaWdodCkgPT4gcXVhbGlmaWVkT3BlcmF0aW9uS2V5KGxlZnQubW9kdWxlLCBsZWZ0Lm9wZXJhdGlvbilcbiAgICAubG9jYWxlQ29tcGFyZShxdWFsaWZpZWRPcGVyYXRpb25LZXkocmlnaHQubW9kdWxlLCByaWdodC5vcGVyYXRpb24pLCBcImVuXCIpKSwgdXNlZE9wZXJhdGlvbnNCeU1vZHVsZX1cbn1cblxuLyoqXG4gKiBCdWlsZHMgYW4gdW5hbWJpZ3VvdXMgaW50ZXJuYWwga2V5IGZvciBvbmUgY2Fub25pY2FsIG9wZXJhdGlvbiBhdXRob3JpdHkuXG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlIC0gQ2Fub25pY2FsIG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBvcGVyYXRpb24gLSBDYW5vbmljYWwgb3BlcmF0aW9uIG5hbWUuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBRdWFsaWZpZWQgaW50ZXJuYWwga2V5LlxuICovXG5mdW5jdGlvbiBxdWFsaWZpZWRPcGVyYXRpb25LZXkobW9kdWxlLCBvcGVyYXRpb24pIHtcbiAgcmV0dXJuIGAke21vZHVsZX1cXHUwMDAwJHtvcGVyYXRpb259YFxufVxuXG4vKipcbiAqIENvbGxlY3RzIHRoZSBvcmRlcmVkIHByb3ZpZGVyIGltcG9ydCBuYW1lcyBlYWNoIG1vZHVsZSBtdXN0IHB1bGwgZnJvbSB0aGUgbGlua2VkIHByb3ZpZGVyLlxuICogSmF2YSBtb2R1bGVzIGxpc3QgcmVmZXJlbmNlZCBjYXBhYmlsaXR5IHR5cGUgbmFtZXMgb25seTsgdGhlIG93bmVyIGxpc3RzIG5vbmUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbX0gcHJvZ3JhbSAtIFZhbGlkYXRlZCBzZW1hbnRpYyBwcm9ncmFtLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdGRsaWItbmVnb3RpYXRpb24uanNcIikuU3RkbGliTmVnb3RpYXRpb25SZXN1bHR9IG5lZ290aWF0aW9uIC0gTmVnb3RpYXRlZCBjbG9zdXJlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zdGRsaWItcHJvdmlkZXJzLmpzXCIpLlN0ZGxpYlByb3ZpZGVyUmVjb3JkPn0gcmVjb3JkcyAtIFByb3ZpZGVyIHJlY29yZHMgYnkgY2Fub25pY2FsIG1vZHVsZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgUXVhbGlmaWVkU3RkbGliT3BlcmF0aW9uW10+fSB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlIC0gVXNlZCBjYW5vbmljYWwgb3BlcmF0aW9ucyBieSBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmcgfCBudWxsfSBbb3duZXJNb2R1bGVJZF0gLSBKYXZhIG93bmVyIG1vZHVsZSBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHtNYXA8c3RyaW5nLCBzdHJpbmdbXT59IE9yZGVyZWQgcHJvdmlkZXIgaW1wb3J0IG5hbWVzIGJ5IG1vZHVsZSBpZGVudGl0eS5cbiAqL1xuZnVuY3Rpb24gY29sbGVjdFByb3ZpZGVySW1wb3J0cyhwcm9ncmFtLCBuZWdvdGlhdGlvbiwgcmVjb3JkcywgdXNlZE9wZXJhdGlvbnNCeU1vZHVsZSwgbGFuZ3VhZ2UsIG93bmVyTW9kdWxlSWQgPSBudWxsKSB7XG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgc3RyaW5nW10+fSAqL1xuICBjb25zdCBwcm92aWRlckltcG9ydHNCeU1vZHVsZSA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3QgbW9kdWxlIG9mIHByb2dyYW0ubW9kdWxlcykge1xuICAgIGlmIChtb2R1bGUuY2FwYWJpbGl0aWVzID09PSB1bmRlZmluZWQpIGNvbnRpbnVlXG4gICAgY29uc3QgdXNlZCA9IG5ldyBTZXQoKHVzZWRPcGVyYXRpb25zQnlNb2R1bGUuZ2V0KG1vZHVsZS5pZCkgPz8gW10pLm1hcCgoe21vZHVsZTogb3duZXIsIG9wZXJhdGlvbn0pID0+XG4gICAgICBxdWFsaWZpZWRPcGVyYXRpb25LZXkob3duZXIsIG9wZXJhdGlvbikpKVxuICAgIC8qKiBAdHlwZSB7U2V0PHN0cmluZz59ICovXG4gICAgY29uc3Qgc3VyZmFjZSA9IG5ldyBTZXQoKVxuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgc3RyaW5nPn0gKi9cbiAgICBjb25zdCByZXNvdXJjZU5hbWVCeUlkID0gbmV3IE1hcCgpXG5cbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIHN0cmluZz59ICovXG4gICAgY29uc3QgZGVjbGFyYXRpb25OYW1lcyA9IG5ldyBNYXAoKG1vZHVsZS5yZWNvcmRzID8/IFtdKS5tYXAoKGRlY2xhcmF0aW9uKSA9PiBbLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksIGRlY2xhcmF0aW9uLm5hbWVdKSlcblxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmVycm9ycyA/PyBbXSkge1xuICAgICAgZGVjbGFyYXRpb25OYW1lcy5zZXQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksIGRlY2xhcmF0aW9uLm5hbWUpXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBjYXBhYmlsaXR5IG9mIG1vZHVsZS5jYXBhYmlsaXRpZXMpIHtcbiAgICAgIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgY2FwYWJpbGl0eS5yZXNvdXJjZXMpIHtcbiAgICAgICAgc3VyZmFjZS5hZGQocmVzb3VyY2UubmFtZSlcbiAgICAgICAgcmVzb3VyY2VOYW1lQnlJZC5zZXQocmVzb3VyY2UuaWQsIHJlc291cmNlLm5hbWUpXG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGZhaWx1cmUgb2YgY2FwYWJpbGl0eS5mYWlsdXJlcykge1xuICAgICAgICBzdXJmYWNlLmFkZChmYWlsdXJlLm5hbWUpXG4gICAgICAgIGRlY2xhcmF0aW9uTmFtZXMuc2V0KGZhaWx1cmUuaWQsIGZhaWx1cmUubmFtZSlcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgcmVmZXJlbmNlZCA9IG5ldyBTZXQoKVxuICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0KClcblxuICAgIC8qKlxuICAgICAqIFZpc2l0cyBvbmUgc2VtYW50aWMgdmFsdWUuXG4gICAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSBzZW1hbnRpYyBzdWJ0cmVlLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIGNvbnN0IHZpc2l0ID0gKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKHZhbHVlKSkgcmV0dXJuXG4gICAgICBzZWVuLmFkZCh2YWx1ZSlcblxuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICBjb25zdCBraW5kID0gUmVmbGVjdC5nZXQodmFsdWUsIFwia2luZFwiKVxuXG4gICAgICAgIGlmIChraW5kID09IFwiT3duZWRSZXNvdXJjZVR5cGVcIikge1xuICAgICAgICAgIGNvbnN0IHJlc291cmNlSWQgPSBSZWZsZWN0LmdldCh2YWx1ZSwgXCJyZXNvdXJjZUlkXCIpXG5cbiAgICAgICAgICBpZiAodHlwZW9mIHJlc291cmNlSWQgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgY29uc3QgbmFtZSA9IHJlc291cmNlTmFtZUJ5SWQuZ2V0KHJlc291cmNlSWQpXG5cbiAgICAgICAgICAgIGlmIChuYW1lICE9PSB1bmRlZmluZWQpIHJlZmVyZW5jZWQuYWRkKG5hbWUpXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIgfHwga2luZCA9PSBcIk93bmVkUmVmZXJlbmNlVHlwZVwiIHx8IGtpbmQgPT0gXCJFcnJvclR5cGVcIikge1xuICAgICAgICAgIGNvbnN0IGRlY2xhcmF0aW9uSWQgPSBSZWZsZWN0LmdldCh2YWx1ZSwgXCJkZWNsYXJhdGlvbklkXCIpXG5cbiAgICAgICAgICBpZiAodHlwZW9mIGRlY2xhcmF0aW9uSWQgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgY29uc3QgbmFtZSA9IGRlY2xhcmF0aW9uTmFtZXMuZ2V0KGRlY2xhcmF0aW9uSWQpXG5cbiAgICAgICAgICAgIGlmIChuYW1lICE9PSB1bmRlZmluZWQgJiYgc3VyZmFjZS5oYXMobmFtZSkpIHJlZmVyZW5jZWQuYWRkKG5hbWUpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgY2hpbGRdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlKSkge1xuICAgICAgICAgIGlmIChrZXkgPT0gXCJjYXBhYmlsaXRpZXNcIiB8fCBrZXkgPT0gXCJsb2NhdGlvblwiIHx8IGtleSA9PSBcInNvdXJjZVByb3ZlbmFuY2VcIikgY29udGludWVcbiAgICAgICAgICB2aXNpdChjaGlsZClcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGZvciAoY29uc3QgY2hpbGQgb2YgdmFsdWUpIHZpc2l0KGNoaWxkKVxuICAgIH1cblxuICAgIHZpc2l0KG1vZHVsZSlcbiAgICBjb25zdCBuYW1lcyA9IFtdXG5cbiAgICBpZiAobGFuZ3VhZ2UgIT0gXCJqYXZhXCIgfHwgbW9kdWxlLmlkICE9IG93bmVyTW9kdWxlSWQpIHtcbiAgICAgIGZvciAoY29uc3QgY2FwYWJpbGl0eSBvZiBtb2R1bGUuY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgY2FwYWJpbGl0eS5yZXNvdXJjZXMpIGlmIChyZWZlcmVuY2VkLmhhcyhyZXNvdXJjZS5uYW1lKSkgbmFtZXMucHVzaChyZXNvdXJjZS5uYW1lKVxuICAgICAgICBmb3IgKGNvbnN0IGZhaWx1cmUgb2YgY2FwYWJpbGl0eS5mYWlsdXJlcykgaWYgKHJlZmVyZW5jZWQuaGFzKGZhaWx1cmUubmFtZSkpIG5hbWVzLnB1c2goZmFpbHVyZS5uYW1lKVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobGFuZ3VhZ2UgIT0gXCJqYXZhXCIpIHtcbiAgICAgIGZvciAoY29uc3QgcHJvdmlkZXIgb2YgbmVnb3RpYXRpb24ucHJvdmlkZXJzKSB7XG4gICAgICAgIGNvbnN0IHJlY29yZCA9IHJlY29yZHMuZ2V0KHByb3ZpZGVyLm1vZHVsZSlcblxuICAgICAgICBmb3IgKGNvbnN0IG9wZXJhdGlvbiBvZiBwcm92aWRlci5vcGVyYXRpb25zKSB7XG4gICAgICAgICAgaWYgKHVzZWQuaGFzKHF1YWxpZmllZE9wZXJhdGlvbktleShwcm92aWRlci5tb2R1bGUsIG9wZXJhdGlvbikpKSB7XG4gICAgICAgICAgICBuYW1lcy5wdXNoKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAocmVjb3JkPy5uYXRpdmVFbnRyaWVzW29wZXJhdGlvbl0pKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHByb3ZpZGVySW1wb3J0c0J5TW9kdWxlLnNldChtb2R1bGUuaWQsIG5hbWVzKVxuICB9XG4gIHJldHVybiBwcm92aWRlckltcG9ydHNCeU1vZHVsZVxufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUgdHJ1dGhmdWwgZ2VuZXJhdGVkIHN0ZGxpYiBsaW5rIG1ldGFkYXRhIGZvciBvbmUgbmVnb3RpYXRlZCBjbG9zdXJlLlxuICogSmF2YSByZXBvcnRzIHRoZSBvd25lciBtb2R1bGUgZmlsZSBhcyB0aGUgcHJvdmlkZXIgY2FycmllciBpbnN0ZWFkIG9mIGEgc2VwYXJhdGUgYXJ0aWZhY3QuXG4gKiBAcGFyYW0ge1N0ZGxpYlByb2dyYW1MaW5raW5nIHwgbnVsbH0gbGlua2luZyAtIExpbmtpbmcgcGxhbi5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgc3RyaW5nPn0gcGF0aHMgLSBQbGFubmVkIGFydGlmYWN0IHBhdGggYnkgbW9kdWxlIGlkZW50aXR5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TdGRsaWJGYWNhZGVQcm9ncmFtRGVzY3JpcHRvciB8IHVuZGVmaW5lZH0gZmFjYWRlcyAtIFNlbGVjdGVkIHNvdXJjZSBmYWNhZGUgY2xvc3VyZS5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gUGxhaW4gSlNPTiBtZXRhZGF0YS5cbiAqL1xuZnVuY3Rpb24gc3RkbGliTGlua01ldGFkYXRhKGxpbmtpbmcsIHBhdGhzLCBmYWNhZGVzKSB7XG4gIHJldHVybiB7XG4gICAgLi4uKGZhY2FkZXMgPyB7ZmFjYWRlc30gOiB7fSksXG4gICAgbW9kdWxlczogKGxpbmtpbmc/Lm5lZ290aWF0aW9uLm1vZHVsZXMgPz8gW10pLm1hcCgoaXRlbSkgPT4gKHtcbiAgICAgIGlkZW50aXR5OiBpdGVtLmlkZW50aXR5LFxuICAgICAgb3BlcmF0aW9uczogWy4uLml0ZW0ub3BlcmF0aW9uc10sXG4gICAgICB2ZXJzaW9uOiBpdGVtLnZlcnNpb25cbiAgICB9KSksXG4gICAgcHJvdmlkZXJzOiAobGlua2luZz8ubmVnb3RpYXRpb24ucHJvdmlkZXJzID8/IFtdKS5tYXAoKGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IHJlY29yZCA9IGxpbmtpbmc/LnJlY29yZHMuZ2V0KGl0ZW0ubW9kdWxlKVxuICAgICAgY29uc3QgYXJ0aWZhY3RQYXRoID0gbGlua2luZz8ub3duZXJNb2R1bGVJZCAhPT0gbnVsbCAmJiBsaW5raW5nPy5vd25lck1vZHVsZUlkICE9PSB1bmRlZmluZWRcbiAgICAgICAgPyAvKiogQHR5cGUge3N0cmluZ30gKi8gKHBhdGhzLmdldChsaW5raW5nLm93bmVyTW9kdWxlSWQpKVxuICAgICAgICA6IHJlY29yZD8uYXJ0aWZhY3QucGF0aFxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBhcnRpZmFjdDoge21lZGlhVHlwZTogcmVjb3JkPy5hcnRpZmFjdC5tZWRpYVR5cGUsIHBhdGg6IGFydGlmYWN0UGF0aH0sXG4gICAgICAgIGRlcGVuZGVuY2llczogKHJlY29yZD8uZGVwZW5kZW5jaWVzID8/IFtdKS5tYXAoKGRlcGVuZGVuY3kpID0+ICh7bW9kdWxlOiBkZXBlbmRlbmN5Lm1vZHVsZSwgcmFuZ2U6IGRlcGVuZGVuY3kucmFuZ2V9KSksXG4gICAgICAgIGlkZW50aXR5OiBpdGVtLmlkZW50aXR5LFxuICAgICAgICBtb2R1bGU6IGl0ZW0ubW9kdWxlLFxuICAgICAgICBuYXRpdmVFbnRyaWVzOiB7Li4uaXRlbS5uYXRpdmVFbnRyaWVzfSxcbiAgICAgICAgb3BlcmF0aW9uczogWy4uLml0ZW0ub3BlcmF0aW9uc10sXG4gICAgICAgIHRhcmdldDogaXRlbS50YXJnZXQsXG4gICAgICAgIHZlcnNpb246IGl0ZW0udmVyc2lvblxuICAgICAgfVxuICAgIH0pLFxuICAgIHNjaGVtYTogXCJTZW1hbnRpZm9sZFN0ZGxpYkxpbmtcIixcbiAgICB2ZXJzaW9uOiAxXG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgZXZlcnkgbWFuZGF0b3J5IHNlbWFudGljIGxvY2F0aW9uIGFnYWluc3QgaXRzIG93bmluZyBtb2R1bGUgc291cmNlIGJlZm9yZSB3cml0ZXIgYWxsb2NhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtfSBwcm9ncmFtIC0gU3RydWN0dXJhbGx5IGFuZCBzZW1hbnRpY2FsbHkgdmFsaWRhdGVkIHByb2dyYW0uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGxhbmd1YWdlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvZ3JhbVNvdXJjZU93bmVyc2hpcChwcm9ncmFtLCBsYW5ndWFnZSkge1xuICBjb25zdCBzb3VyY2VzID0gbmV3IE1hcChwcm9ncmFtLnNvdXJjZXMubWFwKChzb3VyY2UpID0+IFtzb3VyY2UuZmlsZW5hbWUsIHtcbiAgICAuLi5zb3VyY2UsXG4gICAgY29vcmRpbmF0ZXM6IGNyZWF0ZUNvb3JkaW5hdGVJbmRleCgvKiogQHR5cGUge3N0cmluZ30gKi8gKHNvdXJjZS5jb250ZW50KSlcbiAgfV0pKVxuXG4gIGZvciAoY29uc3QgbW9kdWxlIG9mIHByb2dyYW0ubW9kdWxlcykge1xuICAgIGNvbnN0IHNvdXJjZSA9IHNvdXJjZXMuZ2V0KG1vZHVsZS5zb3VyY2VGaWxlbmFtZSlcblxuICAgIGlmICghc291cmNlKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwic2VtYW50aWMgcHJvZ3JhbSBtb2R1bGUgc291cmNlIG93bmVyc2hpcFwiLCB1bmRlZmluZWQpXG4gICAgY29uc3QgZmFsbGJhY2sgPSBtb2R1bGVMb2NhdGlvbihzb3VyY2UuZmlsZW5hbWUsIC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoc291cmNlLmNvbnRlbnQpKVxuXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBzZW1hbnRpY0VudHJpZXMobW9kdWxlKSkge1xuICAgICAgY29uc3Qgc3ViamVjdCA9IGVudHJ5Lm5vZGUua2luZCA9PSBcIk1vZHVsZVwiID8gXCJtb2R1bGVcIiA6IGVudHJ5Lm5vZGUua2luZCA9PSBcIkltcG9ydFwiID8gXCJpbXBvcnRcIiA6XG4gICAgICAgIGVudHJ5Lm5vZGUua2luZCA9PSBcIkV4cG9ydFwiID8gXCJleHBvcnRcIiA6IFwic2VtYW50aWMgbm9kZVwiXG5cbiAgICAgIGlmICghKFwibG9jYXRpb25cIiBpbiBlbnRyeS5ub2RlKSkge1xuICAgICAgICBpZiAoc3ViamVjdCAhPSBcInNlbWFudGljIG5vZGVcIikgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgc2VtYW50aWMgcHJvZ3JhbSAke3N1YmplY3R9IGxvY2F0aW9uYCwgZmFsbGJhY2spXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBjb25zdCBsb2NhdGlvbiA9IGVudHJ5Lm5vZGUubG9jYXRpb25cblxuICAgICAgaWYgKHNvdXJjZU93bnNMb2NhdGlvbihzb3VyY2UsIGxvY2F0aW9uKSkgY29udGludWVcblxuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgc2VtYW50aWMgcHJvZ3JhbSAke3N1YmplY3R9IGxvY2F0aW9uIHNvdXJjZSBvd25lcnNoaXBgLCBmYWxsYmFjaylcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDaGVja3MgYSBub3JtYWxpemVkIFVURi0xNiBsb2NhdGlvbiBhZ2FpbnN0IG9uZSBleGFjdCByZWdpc3RlcmVkIHNvdXJjZSB3aXRob3V0IHRocm93aW5nLlxuICogQHBhcmFtIHt7ZmlsZW5hbWU6IHN0cmluZywgY29udGVudDogc3RyaW5nIHwgbnVsbCwgY29vcmRpbmF0ZXM6IFJldHVyblR5cGU8dHlwZW9mIGNyZWF0ZUNvb3JkaW5hdGVJbmRleD59fSBzb3VyY2UgLSBPd25pbmcgc291cmNlLlxuICogQHBhcmFtIHt1bmtub3dufSBjYW5kaWRhdGUgLSBDYW5kaWRhdGUgbG9jYXRpb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgc291cmNlIG93bnMgdGhlIGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBzb3VyY2VPd25zTG9jYXRpb24oc291cmNlLCBjYW5kaWRhdGUpIHtcbiAgaWYgKCFpc1BsYWluT2JqZWN0KGNhbmRpZGF0ZSkgfHwgY2FuZGlkYXRlLmZpbGVuYW1lICE9IHNvdXJjZS5maWxlbmFtZSB8fCAhaXNQbGFpbk9iamVjdChjYW5kaWRhdGUuc3RhcnQpIHx8XG4gICAgIWlzUGxhaW5PYmplY3QoY2FuZGlkYXRlLmVuZCkgfHwgIU51bWJlci5pc0ludGVnZXIoY2FuZGlkYXRlLnN0YXJ0Lm9mZnNldCkgfHwgIU51bWJlci5pc0ludGVnZXIoY2FuZGlkYXRlLmVuZC5vZmZzZXQpIHx8XG4gICAgIU51bWJlci5pc0ludGVnZXIoY2FuZGlkYXRlLnN0YXJ0LmxpbmUpIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKGNhbmRpZGF0ZS5zdGFydC5jb2x1bW4pIHx8XG4gICAgIU51bWJlci5pc0ludGVnZXIoY2FuZGlkYXRlLmVuZC5saW5lKSB8fCAhTnVtYmVyLmlzSW50ZWdlcihjYW5kaWRhdGUuZW5kLmNvbHVtbikpIHJldHVybiBmYWxzZVxuICBjb25zdCBzdGFydE9mZnNldCA9IC8qKiBAdHlwZSB7bnVtYmVyfSAqLyAoY2FuZGlkYXRlLnN0YXJ0Lm9mZnNldClcbiAgY29uc3QgZW5kT2Zmc2V0ID0gLyoqIEB0eXBlIHtudW1iZXJ9ICovIChjYW5kaWRhdGUuZW5kLm9mZnNldClcblxuICBpZiAoc3RhcnRPZmZzZXQgPCAwIHx8IGVuZE9mZnNldCA8IHN0YXJ0T2Zmc2V0IHx8IGVuZE9mZnNldCA+IHNvdXJjZS5jb29yZGluYXRlcy5zb3VyY2UubGVuZ3RoKSByZXR1cm4gZmFsc2VcbiAgY29uc3QgZXhwZWN0ZWRTdGFydCA9IGluZGV4ZWRQb2ludEF0KHNvdXJjZS5jb29yZGluYXRlcywgc3RhcnRPZmZzZXQpXG4gIGNvbnN0IGV4cGVjdGVkRW5kID0gaW5kZXhlZFBvaW50QXQoc291cmNlLmNvb3JkaW5hdGVzLCBlbmRPZmZzZXQpXG5cbiAgcmV0dXJuIHNhbWVQb2ludChjYW5kaWRhdGUuc3RhcnQsIGV4cGVjdGVkU3RhcnQpICYmIHNhbWVQb2ludChjYW5kaWRhdGUuZW5kLCBleHBlY3RlZEVuZClcbn1cblxuLyoqXG4gKiBDb21wYXJlcyBhbiB1bnRydXN0ZWQgcG9pbnQgd2l0aCBvbmUgY2Fub25pY2FsIGluZGV4ZWQgcG9pbnQuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSBjYW5kaWRhdGUgLSBDYW5kaWRhdGUgcG9pbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZVBvaW50fSBleHBlY3RlZCAtIENhbm9uaWNhbCBwb2ludC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIGV2ZXJ5IGNvb3JkaW5hdGUgYWdyZWVzLlxuICovXG5mdW5jdGlvbiBzYW1lUG9pbnQoY2FuZGlkYXRlLCBleHBlY3RlZCkge1xuICByZXR1cm4gY2FuZGlkYXRlLm9mZnNldCA9PSBleHBlY3RlZC5vZmZzZXQgJiYgY2FuZGlkYXRlLmxpbmUgPT0gZXhwZWN0ZWQubGluZSAmJiBjYW5kaWRhdGUuY29sdW1uID09IGV4cGVjdGVkLmNvbHVtblxufVxuXG4vKipcbiAqIENvbGxlY3RzIG5vbWluYWwgZmFpbHVyZSBpZGVudGl0aWVzIHJlZmVyZW5jZWQgYnkgZXhlY3V0YWJsZS90eXBlIG5vZGVzIG91dHNpZGUgdGhlIG1vZHVsZSdzIGF1dGhvcml0eSBkZWNsYXJhdGlvbnMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZX0gbW9kdWxlIC0gUHJvZ3JhbSBtb2R1bGUuXG4gKiBAcmV0dXJucyB7U2V0PHN0cmluZz59IFJlZmVyZW5jZWQgZmFpbHVyZSBkZWNsYXJhdGlvbiBpZGVudGl0aWVzLlxuICovXG5mdW5jdGlvbiBjb2xsZWN0UmVmZXJlbmNlZEZhaWx1cmVJZHMobW9kdWxlKSB7XG4gIC8qKiBAdHlwZSB7U2V0PHN0cmluZz59ICovXG4gIGNvbnN0IGlkcyA9IG5ldyBTZXQoKVxuICBjb25zdCBzZWVuID0gbmV3IFNldCgpXG4gIC8qKlxuICAgKiBWaXNpdHMgb25lIHNlbWFudGljIHN1YnRyZWUgZm9yIHJlZmVyZW5jZWQgZmFpbHVyZXMuXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgc2VtYW50aWMgc3VidHJlZS5cbiAgICovXG4gIGNvbnN0IHZpc2l0ID0gKHZhbHVlKSA9PiB7XG4gICAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT0gXCJvYmplY3RcIiB8fCBzZWVuLmhhcyh2YWx1ZSkpIHJldHVyblxuICAgIHNlZW4uYWRkKHZhbHVlKVxuICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIGlmIChSZWZsZWN0LmdldCh2YWx1ZSwgXCJraW5kXCIpID09IFwiRXJyb3JUeXBlXCIgJiYgdHlwZW9mIFJlZmxlY3QuZ2V0KHZhbHVlLCBcImRlY2xhcmF0aW9uSWRcIikgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICBpZHMuYWRkKFJlZmxlY3QuZ2V0KHZhbHVlLCBcImRlY2xhcmF0aW9uSWRcIikpXG4gICAgICB9XG4gICAgICBjb25zdCBmYWlsdXJlSWRzID0gUmVmbGVjdC5nZXQodmFsdWUsIFwiZmFpbHVyZUlkc1wiKVxuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShmYWlsdXJlSWRzKSkgZm9yIChjb25zdCBpZCBvZiBmYWlsdXJlSWRzKSBpZiAodHlwZW9mIGlkID09IFwic3RyaW5nXCIpIGlkcy5hZGQoaWQpXG4gICAgICBmb3IgKGNvbnN0IFtrZXksIGNoaWxkXSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZSkpIHtcbiAgICAgICAgaWYgKFtcImNhcGFiaWxpdGllc1wiLCBcImxvY2F0aW9uXCIsIFwicHJvdmVuYW5jZVwiLCBcInNvdXJjZVByb3ZlbmFuY2VcIl0uaW5jbHVkZXMoa2V5KSkgY29udGludWVcbiAgICAgICAgdmlzaXQoY2hpbGQpXG4gICAgICB9XG4gICAgfSBlbHNlIGZvciAoY29uc3QgY2hpbGQgb2YgdmFsdWUpIHZpc2l0KGNoaWxkKVxuICB9XG5cbiAgdmlzaXQoe2NsYXNzZXM6IG1vZHVsZS5jbGFzc2VzLCBlbnRyeVBvaW50OiBtb2R1bGUuZW50cnlQb2ludCwgZnVuY3Rpb25zOiBtb2R1bGUuZnVuY3Rpb25zfSlcbiAgcmV0dXJuIGlkc1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYW5kIHZhbGlkYXRlcyBldmVyeSBiYWNrZW5kLXNoYXBlZCBtb2R1bGUgYmVmb3JlIGFueSB3cml0ZXIgaXMgYWxsb2NhdGVkLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW19IHByb2dyYW0gLSBWYWxpZGF0ZWQgc2VtYW50aWMgcHJvZ3JhbS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge1N0ZGxpYlByb2dyYW1MaW5raW5nIHwgbnVsbH0gW2xpbmtpbmddIC0gUGxhbm5lZCBzdGRsaWIgcHJvdmlkZXIgbGluay5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZVtdfSBFbWlzc2lvbiB2aWV3cyBpbiBkZXBlbmRlbmN5IG9yZGVyLlxuICovXG5mdW5jdGlvbiBwcmVwYXJlRW1pc3Npb25Nb2R1bGVzKHByb2dyYW0sIGxhbmd1YWdlLCBsaW5raW5nID0gbnVsbCkge1xuICAvKiogQHR5cGUge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uPn0gKi9cbiAgY29uc3QgZGVjbGFyYXRpb25zID0gbmV3IE1hcCgpXG5cbiAgZm9yIChjb25zdCBtb2R1bGUgb2YgcHJvZ3JhbS5tb2R1bGVzKSB7XG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUucmVjb3JkcyA/PyBbXSkgZGVjbGFyYXRpb25zLnNldCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwgZGVjbGFyYXRpb24pXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuY2xhc3NlcyA/PyBbXSkgZGVjbGFyYXRpb25zLnNldCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwgZGVjbGFyYXRpb24pXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZXJyb3JzID8/IFtdKSBkZWNsYXJhdGlvbnMuc2V0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBkZWNsYXJhdGlvbilcbiAgICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5mdW5jdGlvbnMpIGRlY2xhcmF0aW9ucy5zZXQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksIGRlY2xhcmF0aW9uKVxuICB9XG4gIGNvbnN0IG1vZHVsZXMgPSBwcm9ncmFtLm1vZHVsZXMubWFwKChtb2R1bGUpID0+IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9ICovICh7XG4gICAgLi4ubW9kdWxlLFxuICAgIGVudHJ5UG9pbnQ6IG1vZHVsZS5lbnRyeVBvaW50ID8/IHtcbiAgICAgIGJvZHk6IHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCbG9ja1wiKSwgbG9jYXRpb246IG1vZHVsZS5sb2NhdGlvbiwgc3RhdGVtZW50czogW119LFxuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRW50cnlQb2ludFwiKSxcbiAgICAgIGxvY2F0aW9uOiBtb2R1bGUubG9jYXRpb25cbiAgICB9XG4gIH0pKVxuICAvKiogQHR5cGUge01hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn0gKi9cbiAgY29uc3QgY2FsbEVmZmVjdHNCeURlY2xhcmF0aW9uSWQgPSBuZXcgTWFwKClcblxuICBmb3IgKGNvbnN0IG1vZHVsZSBvZiBtb2R1bGVzKSB7XG4gICAgY29uc3QgcHJvZ3JhbU1vZHVsZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtTW9kdWxlfSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAobW9kdWxlKSlcbiAgICBjb25zdCB2aXNpYmxlRnVuY3Rpb25zID0gbmV3IE1hcCgpXG4gICAgY29uc3QgdmlzaWJsZUNhbGxFZmZlY3RzID0gbmV3IE1hcCgpXG4gICAgY29uc3QgdmlzaWJsZVJlY29yZHMgPSBuZXcgTWFwKClcbiAgICBjb25zdCB2aXNpYmxlQ2xhc3NlcyA9IG5ldyBNYXAoKVxuICAgIGNvbnN0IHZpc2libGVFcnJvcnMgPSBuZXcgTWFwKClcbiAgICBjb25zdCBleHRlcm5hbERlY2xhcmF0aW9uSWRzID0gbmV3IFNldCgpXG5cbiAgICBjb25zdCBuZWVkZWRGYWlsdXJlSWRzID0gY29sbGVjdFJlZmVyZW5jZWRGYWlsdXJlSWRzKHByb2dyYW1Nb2R1bGUpXG4gICAgY29uc3QgbG9jYWxGYWlsdXJlSWRzID0gbmV3IFNldChwcm9ncmFtTW9kdWxlLmNhcGFiaWxpdGllcz8uZmxhdE1hcCgoe2ZhaWx1cmVzfSkgPT4gZmFpbHVyZXMubWFwKCh7aWR9KSA9PiBpZCkpID8/IFtdKVxuXG4gICAgZm9yIChjb25zdCBvd25lciBvZiBwcm9ncmFtLm1vZHVsZXMpIHtcbiAgICAgIGlmIChvd25lci5pZCA9PSBwcm9ncmFtTW9kdWxlLmlkKSBjb250aW51ZVxuICAgICAgZm9yIChjb25zdCBjYXBhYmlsaXR5IG9mIG93bmVyLmNhcGFiaWxpdGllcyA/PyBbXSkge1xuICAgICAgICBmb3IgKGNvbnN0IGZhaWx1cmUgb2YgY2FwYWJpbGl0eS5mYWlsdXJlcykge1xuICAgICAgICAgIGlmICghbG9jYWxGYWlsdXJlSWRzLmhhcyhmYWlsdXJlLmlkKSAmJiBuZWVkZWRGYWlsdXJlSWRzLmhhcyhmYWlsdXJlLmlkKSkgdmlzaWJsZUVycm9ycy5zZXQoZmFpbHVyZS5pZCwgZmFpbHVyZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgaW1wb3J0ZWQgb2YgcHJvZ3JhbU1vZHVsZS5pbXBvcnRzKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGRlY2xhcmF0aW9ucy5nZXQoaW1wb3J0ZWQuZGVjbGFyYXRpb25JZClcblxuICAgICAgaWYgKCFkZWNsYXJhdGlvbikgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcInByb2dyYW0gaW1wb3J0IHdpdGhvdXQgYSBkZWNsYXJhdGlvblwiLCBpbXBvcnRlZC5sb2NhdGlvbilcbiAgICAgIGV4dGVybmFsRGVjbGFyYXRpb25JZHMuYWRkKGltcG9ydGVkLmRlY2xhcmF0aW9uSWQpXG4gICAgICBpZiAoaW1wb3J0ZWQuc3ltYm9sS2luZCA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdmlzaWJsZUZ1bmN0aW9ucy5zZXQoaW1wb3J0ZWQubG9jYWxOYW1lLCAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb259ICovIChkZWNsYXJhdGlvbikpXG4gICAgICAgIHZpc2libGVDYWxsRWZmZWN0cy5zZXQoaW1wb3J0ZWQubG9jYWxOYW1lLCBuZXcgU2V0KGNhbGxFZmZlY3RzQnlEZWNsYXJhdGlvbklkLmdldChpbXBvcnRlZC5kZWNsYXJhdGlvbklkKSA/PyBbXSkpXG4gICAgICB9IGVsc2UgaWYgKGltcG9ydGVkLnN5bWJvbEtpbmQgPT0gXCJyZWNvcmRcIikge1xuICAgICAgICB2aXNpYmxlUmVjb3Jkcy5zZXQoaW1wb3J0ZWQuZGVjbGFyYXRpb25JZCwgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbn0gKi8gKGRlY2xhcmF0aW9uKSlcbiAgICAgIH0gZWxzZSBpZiAoaW1wb3J0ZWQuc3ltYm9sS2luZCA9PSBcImNsYXNzXCIpIHtcbiAgICAgICAgdmlzaWJsZUNsYXNzZXMuc2V0KGltcG9ydGVkLmRlY2xhcmF0aW9uSWQsIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbn0gKi8gKGRlY2xhcmF0aW9uKSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpc2libGVFcnJvcnMuc2V0KGltcG9ydGVkLmRlY2xhcmF0aW9uSWQsIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXJyb3JEZWNsYXJhdGlvbn0gKi8gKGRlY2xhcmF0aW9uKSlcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG1vZHVsZS5jYXBhYmlsaXRpZXMgIT09IHVuZGVmaW5lZCB8fCAhbGlua2luZykge1xuICAgICAgcHJlZmxpZ2h0RWZmZWN0Q2FwYWJpbGl0aWVzKG1vZHVsZSwgbGFuZ3VhZ2UsIGxpbmtpbmcgPyB7dXNlZE9wZXJhdGlvbnM6IChsaW5raW5nLnVzZWRPcGVyYXRpb25zQnlNb2R1bGUuZ2V0KHByb2dyYW1Nb2R1bGUuaWQpID8/IFtdKVxuICAgICAgICAubWFwKCh7b3BlcmF0aW9ufSkgPT4gb3BlcmF0aW9uKX0gOiB7fSlcbiAgICB9XG4gICAgdmFsaWRhdGVCYWNrZW5kTW9kdWxlKG1vZHVsZSwgbGFuZ3VhZ2UsIHtcbiAgICAgIGV4dGVybmFsRGVjbGFyYXRpb25JZHMsXG4gICAgICBwcm9ncmFtOiB0cnVlLFxuICAgICAgdmlzaWJsZUNhbGxFZmZlY3RzLFxuICAgICAgdmlzaWJsZUNsYXNzZXMsXG4gICAgICB2aXNpYmxlRXJyb3JzLFxuICAgICAgdmlzaWJsZUZ1bmN0aW9ucyxcbiAgICAgIHZpc2libGVSZWNvcmRzXG4gICAgfSlcbiAgICBjb25zdCBsb2NhbENhbGxFZmZlY3RzID0gbW9kdWxlVW5jaGVja2VkRXJyb3JFZmZlY3RzKG1vZHVsZSwge2NhbGxFZmZlY3RzOiB2aXNpYmxlQ2FsbEVmZmVjdHMsIGZ1bmN0aW9uczogdmlzaWJsZUZ1bmN0aW9uc30pXG5cbiAgICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5mdW5jdGlvbnMpIHtcbiAgICAgIGNhbGxFZmZlY3RzQnlEZWNsYXJhdGlvbklkLnNldCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwgbmV3IFNldChsb2NhbENhbGxFZmZlY3RzLmdldChkZWNsYXJhdGlvbi5uYW1lKSA/PyBbXSkpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1vZHVsZXNcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgdGhlIGNsb3NlZCBwYXJzZXItbmV1dHJhbCBwcm9ncmFtIGdyYXBoIGJlZm9yZSBhbnkgdGFyZ2V0IGVtaXNzaW9uLlxuICogQHBhcmFtIHt1bmtub3dufSBjYW5kaWRhdGUgLSBDYW5kaWRhdGUgc2VtYW50aWMgcHJvZ3JhbS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge1JlYWRvbmx5PFNldDxpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlPj59IFtzb3VyY2VMYW5ndWFnZXNdIC0gQWNjZXB0ZWQgc291cmNlIGxhbmd1YWdlcy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW19IFZhbGlkYXRlZCBwcm9ncmFtLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVByb2dyYW0oY2FuZGlkYXRlLCBsYW5ndWFnZSwgc291cmNlTGFuZ3VhZ2VzID0gcHJvZ3JhbVRhcmdldHMpIHtcbiAgaWYgKCFpc1BsYWluT2JqZWN0KGNhbmRpZGF0ZSkgfHwgY2FuZGlkYXRlLmtpbmQgIT0gXCJQcm9ncmFtXCIgfHwgdHlwZW9mIGNhbmRpZGF0ZS5lbnRyeU1vZHVsZSAhPSBcInN0cmluZ1wiIHx8XG4gICAgIWlzRGVuc2VBcnJheShjYW5kaWRhdGUubW9kdWxlcykgfHwgY2FuZGlkYXRlLm1vZHVsZXMubGVuZ3RoID09IDAgfHwgIWlzRGVuc2VBcnJheShjYW5kaWRhdGUuc291cmNlcykgfHwgY2FuZGlkYXRlLnNvdXJjZXMubGVuZ3RoID09IDApIHtcbiAgICBpbnZhbGlkUHJvZ3JhbUdlbmVyYXRpb24oXCJNYWxmb3JtZWQgc2VtYW50aWMgcHJvZ3JhbS5cIilcbiAgfVxuICBjb25zdCBwcm9ncmFtID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW19ICovIChjYW5kaWRhdGUpXG4gIGNvbnN0IG1vZHVsZXMgPSBuZXcgTWFwKClcbiAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCB7ZGVjbGFyYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uLCBtb2R1bGU6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZX0+fSAqL1xuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBuZXcgTWFwKClcbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGVbXX0gKi9cbiAgY29uc3QgY2FwYWJpbGl0eU1vZHVsZXMgPSBbXVxuICBsZXQgZW50cnlDb3VudCA9IDBcbiAgY29uc3Qgc291cmNlSWRzID0gbmV3IFNldCgpXG4gIGNvbnN0IHNvdXJjZUZpbGVuYW1lcyA9IG5ldyBTZXQoKVxuXG4gIGZvciAoY29uc3Qgc291cmNlIG9mIHByb2dyYW0uc291cmNlcykge1xuICAgIGlmICghaXNQbGFpbk9iamVjdChzb3VyY2UpIHx8IHR5cGVvZiBzb3VyY2UuaWQgIT0gXCJzdHJpbmdcIiB8fCBzb3VyY2VJZHMuaGFzKHNvdXJjZS5pZCkgfHxcbiAgICAgIHR5cGVvZiBzb3VyY2UuZmlsZW5hbWUgIT0gXCJzdHJpbmdcIiB8fCAhaXNTYWZlU291cmNlUGF0aChzb3VyY2UuZmlsZW5hbWUpIHx8IHNvdXJjZUZpbGVuYW1lcy5oYXMoc291cmNlLmZpbGVuYW1lKSB8fFxuICAgICAgdHlwZW9mIHNvdXJjZS5jb250ZW50ICE9IFwic3RyaW5nXCIgfHwgdHlwZW9mIHNvdXJjZS5sYW5ndWFnZSAhPSBcInN0cmluZ1wiIHx8ICFzb3VyY2VMYW5ndWFnZXMuaGFzKHNvdXJjZS5sYW5ndWFnZSkpIHtcbiAgICAgIGludmFsaWRQcm9ncmFtR2VuZXJhdGlvbihcIk1hbGZvcm1lZCBvciBkdXBsaWNhdGUgc2VtYW50aWMgcHJvZ3JhbSBzb3VyY2UgcmVnaXN0cnkuXCIpXG4gICAgfVxuICAgIHNvdXJjZUlkcy5hZGQoc291cmNlLmlkKVxuICAgIHNvdXJjZUZpbGVuYW1lcy5hZGQoc291cmNlLmZpbGVuYW1lKVxuICB9XG5cbiAgZm9yIChjb25zdCBtb2R1bGUgb2YgcHJvZ3JhbS5tb2R1bGVzKSB7XG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KG1vZHVsZSkgfHwgbW9kdWxlLmtpbmQgIT0gXCJNb2R1bGVcIiB8fCB0eXBlb2YgbW9kdWxlLmlkICE9IFwic3RyaW5nXCIgfHxcbiAgICAgICEvXlthLXpdW2EtejAtOV9dKig/OlsuLV1bYS16XVthLXowLTlfXSopKiQvdS50ZXN0KG1vZHVsZS5pZCkgfHwgbW9kdWxlcy5oYXMobW9kdWxlLmlkKSB8fFxuICAgICAgIWlzRGVuc2VBcnJheShtb2R1bGUuZnVuY3Rpb25zKSB8fCBtb2R1bGUucmVjb3JkcyAhPT0gdW5kZWZpbmVkICYmICFpc0RlbnNlQXJyYXkobW9kdWxlLnJlY29yZHMpIHx8XG4gICAgICBtb2R1bGUuZXJyb3JzICE9PSB1bmRlZmluZWQgJiYgIWlzRGVuc2VBcnJheShtb2R1bGUuZXJyb3JzKSB8fFxuICAgICAgIWlzRGVuc2VBcnJheShtb2R1bGUuaW1wb3J0cykgfHwgIWlzRGVuc2VBcnJheShtb2R1bGUuZXhwb3J0cykpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgb3IgZHVwbGljYXRlIHNlbWFudGljIHByb2dyYW0gbW9kdWxlXCIsIG1vZHVsZT8ubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChSZWZsZWN0LmdldChtb2R1bGUsIFwiY2xhc3Nlc1wiKSAhPT0gdW5kZWZpbmVkICYmICghaXNEZW5zZUFycmF5KG1vZHVsZS5jbGFzc2VzKSB8fFxuICAgICAgUmVmbGVjdC5nZXQobW9kdWxlLCBcInN0ZGxpYkZhY2FkZVwiKSA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIlRhc2sgMDMzIHJlZmVyZW5jZSBjbGFzc2VzIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IHNlbWFudGljIHByb2dyYW0gZ2VuZXJhdGlvblwiLFxuICAgICAgICBSZWZsZWN0LmdldChtb2R1bGUsIFwiY2xhc3Nlc1wiKT8uWzBdPy5sb2NhdGlvbiA/PyBtb2R1bGUubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChSZWZsZWN0LmdldChtb2R1bGUsIFwiY2FwYWJpbGl0aWVzXCIpICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICghaXNEZW5zZUFycmF5KG1vZHVsZS5jYXBhYmlsaXRpZXMpIHx8IG1vZHVsZS5jYXBhYmlsaXRpZXMubGVuZ3RoID09IDApIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1hbGZvcm1lZCBvciBlbXB0eSBUYXNrIDAzNCBjYXBhYmlsaXR5IGdyYXBoXCIsIG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGNhcGFiaWxpdHlNb2R1bGVzLnB1c2gobW9kdWxlKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIG1vZHVsZS5zb3VyY2VGaWxlbmFtZSAhPSBcInN0cmluZ1wiIHx8ICFzb3VyY2VGaWxlbmFtZXMuaGFzKG1vZHVsZS5zb3VyY2VGaWxlbmFtZSkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJzZW1hbnRpYyBwcm9ncmFtIG1vZHVsZSBzb3VyY2UgaWRlbnRpdHlcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAobW9kdWxlLmVudHJ5UG9pbnQpIHtcbiAgICAgIGVudHJ5Q291bnQrK1xuICAgICAgaWYgKG1vZHVsZS5pZCAhPSBwcm9ncmFtLmVudHJ5TW9kdWxlKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiZW50cnkgcG9pbnQgb24gYW4gdW5zZWxlY3RlZCBtb2R1bGVcIiwgbW9kdWxlLmVudHJ5UG9pbnQubG9jYXRpb24pXG4gICAgfVxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgWy4uLm1vZHVsZS5yZWNvcmRzID8/IFtdLCAuLi5tb2R1bGUuY2xhc3NlcyA/PyBbXSwgLi4ubW9kdWxlLmVycm9ycyA/PyBbXSwgLi4ubW9kdWxlLmZ1bmN0aW9uc10pIHtcbiAgICAgIGlmICghaXNQbGFpbk9iamVjdChkZWNsYXJhdGlvbikgfHwgdHlwZW9mIGRlY2xhcmF0aW9uLmlkICE9IFwic3RyaW5nXCIgfHxcbiAgICAgICAgIWRlY2xhcmF0aW9uLmlkLnN0YXJ0c1dpdGgoYCR7bW9kdWxlLmlkfSNgKSB8fCBkZWNsYXJhdGlvbnMuaGFzKGRlY2xhcmF0aW9uLmlkKSkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiZHVwbGljYXRlIG9yIHVuc3RhYmxlIHByb2dyYW0gZGVjbGFyYXRpb24gaWRlbnRpdHlcIiwgZGVjbGFyYXRpb24/LmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGRlY2xhcmF0aW9ucy5zZXQoZGVjbGFyYXRpb24uaWQsIHtkZWNsYXJhdGlvbiwgbW9kdWxlfSlcbiAgICB9XG4gICAgZm9yIChjb25zdCBpbXBvcnRlZCBvZiBtb2R1bGUuaW1wb3J0cykge1xuICAgICAgaWYgKCFpc1BsYWluT2JqZWN0KGltcG9ydGVkKSB8fCBpbXBvcnRlZC5raW5kICE9IFwiSW1wb3J0XCIgfHwgdHlwZW9mIGltcG9ydGVkLm1vZHVsZUlkICE9IFwic3RyaW5nXCIgfHxcbiAgICAgICAgdHlwZW9mIGltcG9ydGVkLmltcG9ydGVkTmFtZSAhPSBcInN0cmluZ1wiIHx8IHR5cGVvZiBpbXBvcnRlZC5sb2NhbE5hbWUgIT0gXCJzdHJpbmdcIiB8fFxuICAgICAgICB0eXBlb2YgaW1wb3J0ZWQuZGVjbGFyYXRpb25JZCAhPSBcInN0cmluZ1wiIHx8ICFbXCJmdW5jdGlvblwiLCBcInJlY29yZFwiLCBcImNsYXNzXCIsIFwiZXJyb3JcIl0uaW5jbHVkZXMoaW1wb3J0ZWQuc3ltYm9sS2luZCkgfHxcbiAgICAgICAgdHlwZW9mIGltcG9ydGVkLnR5cGVPbmx5ICE9IFwiYm9vbGVhblwiKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgc2VtYW50aWMgcHJvZ3JhbSBpbXBvcnRcIiwgaW1wb3J0ZWQ/LmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yIChjb25zdCBleHBvcnRlZCBvZiBtb2R1bGUuZXhwb3J0cykge1xuICAgICAgaWYgKCFpc1BsYWluT2JqZWN0KGV4cG9ydGVkKSB8fCBleHBvcnRlZC5raW5kICE9IFwiRXhwb3J0XCIgfHwgdHlwZW9mIGV4cG9ydGVkLmV4cG9ydGVkTmFtZSAhPSBcInN0cmluZ1wiIHx8XG4gICAgICAgIHR5cGVvZiBleHBvcnRlZC5kZWNsYXJhdGlvbklkICE9IFwic3RyaW5nXCIgfHwgIVtcImZ1bmN0aW9uXCIsIFwicmVjb3JkXCIsIFwiY2xhc3NcIiwgXCJlcnJvclwiXS5pbmNsdWRlcyhleHBvcnRlZC5zeW1ib2xLaW5kKSkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWFsZm9ybWVkIHNlbWFudGljIHByb2dyYW0gZXhwb3J0XCIsIGV4cG9ydGVkPy5sb2NhdGlvbiA/PyBtb2R1bGUubG9jYXRpb24pXG4gICAgICB9XG4gICAgfVxuICAgIG1vZHVsZXMuc2V0KG1vZHVsZS5pZCwgbW9kdWxlKVxuICB9XG4gIGlmIChlbnRyeUNvdW50ICE9IDEgfHwgIW1vZHVsZXMuZ2V0KHByb2dyYW0uZW50cnlNb2R1bGUpPy5lbnRyeVBvaW50KSB7XG4gICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcInByb2dyYW0gd2l0aG91dCBleGFjdGx5IG9uZSBzZWxlY3RlZCBlbnRyeSBwb2ludFwiLCBtb2R1bGVzLmdldChwcm9ncmFtLmVudHJ5TW9kdWxlKT8ubG9jYXRpb24pXG4gIH1cbiAgY29uc3Qgc2VsZWN0ZWRNb2R1bGUgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZX0gKi8gKG1vZHVsZXMuZ2V0KHByb2dyYW0uZW50cnlNb2R1bGUpKVxuICBjb25zdCBzZWxlY3RlZEVudHJ5ID0gc2VsZWN0ZWRNb2R1bGUuZW50cnlQb2ludFxuXG4gIGlmICghaXNQbGFpbk9iamVjdChzZWxlY3RlZEVudHJ5Py5ib2R5KSB8fCAhaXNEZW5zZUFycmF5KHNlbGVjdGVkRW50cnkuYm9keS5zdGF0ZW1lbnRzKSB8fCBzZWxlY3RlZEVudHJ5LmJvZHkuc3RhdGVtZW50cy5sZW5ndGggPT0gMCkge1xuICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJwcm9ncmFtIHdpdGhvdXQgYSBkZW5zZSBub24tZW1wdHkgc2VsZWN0ZWQgZW50cnkgcG9pbnQgYmxvY2tcIixcbiAgICAgIHNlbGVjdGVkRW50cnk/LmxvY2F0aW9uID8/IHNlbGVjdGVkTW9kdWxlLmxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IGVhcmxpZXIgPSBuZXcgU2V0KClcblxuICBmb3IgKGNvbnN0IG1vZHVsZSBvZiBwcm9ncmFtLm1vZHVsZXMpIHtcbiAgICBjb25zdCBsb2NhbFRhcmdldE5hbWVzID0gbmV3IFNldChbLi4ubW9kdWxlLnJlY29yZHMgPz8gW10sIC4uLm1vZHVsZS5jbGFzc2VzID8/IFtdLCAuLi5tb2R1bGUuZXJyb3JzID8/IFtdLCAuLi5tb2R1bGUuZnVuY3Rpb25zXVxuICAgICAgLm1hcCgoe25hbWV9KSA9PiB0YXJnZXROYW1lKGxhbmd1YWdlLCBuYW1lKSkpXG4gICAgY29uc3QgaW1wb3J0ZWRUYXJnZXROYW1lcyA9IG5ldyBTZXQoKVxuICAgIGNvbnN0IGxvY2FsSmF2YUNsYXNzID0gbW9kdWxlLnJlY29yZHM/LlswXT8ubmFtZSA/PyBtb2R1bGUuY2xhc3Nlcz8uWzBdPy5uYW1lID8/IG1vZHVsZS5lcnJvcnM/LlswXT8ubmFtZSA/P1xuICAgICAgKG1vZHVsZS5pZCA9PSBwcm9ncmFtLmVudHJ5TW9kdWxlID8gXCJNYWluXCIgOiBtb2R1bGVDbGFzc05hbWUobW9kdWxlLmlkKSlcbiAgICBjb25zdCBqYXZhSW1wb3J0Q2xhc3NlcyA9IG5ldyBNYXAobGFuZ3VhZ2UgPT0gXCJqYXZhXCIgPyBbW2xvY2FsSmF2YUNsYXNzLCBtb2R1bGUuaWRdXSA6IFtdKVxuXG4gICAgZm9yIChjb25zdCBpbXBvcnRlZCBvZiBtb2R1bGUuaW1wb3J0cykge1xuICAgICAgY29uc3QgcmVzb2x2ZWQgPSBkZWNsYXJhdGlvbnMuZ2V0KGltcG9ydGVkLmRlY2xhcmF0aW9uSWQpXG4gICAgICBjb25zdCByZW1vdGVFeHBvcnQgPSByZXNvbHZlZD8ubW9kdWxlLmV4cG9ydHMuZmluZCgoaXRlbSkgPT5cbiAgICAgICAgaXRlbS5kZWNsYXJhdGlvbklkID09IGltcG9ydGVkLmRlY2xhcmF0aW9uSWQgJiYgaXRlbS5leHBvcnRlZE5hbWUgPT0gaW1wb3J0ZWQuaW1wb3J0ZWROYW1lKVxuXG4gICAgICBpZiAoIXJlc29sdmVkIHx8IHJlc29sdmVkLm1vZHVsZS5pZCAhPSBpbXBvcnRlZC5tb2R1bGVJZCB8fCAhZWFybGllci5oYXMoaW1wb3J0ZWQubW9kdWxlSWQpIHx8XG4gICAgICAgICFyZW1vdGVFeHBvcnQpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcInVucmVzb2x2ZWQsIHByaXZhdGUsIGN5Y2xpYywgb3Igb3V0LW9mLW9yZGVyIHByb2dyYW0gaW1wb3J0XCIsIGltcG9ydGVkLmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlY2xhcmF0aW9uS2luZCA9IHJlc29sdmVkLmRlY2xhcmF0aW9uLmtpbmQgPT0gXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIgPyBcImZ1bmN0aW9uXCIgOlxuICAgICAgICByZXNvbHZlZC5kZWNsYXJhdGlvbi5raW5kID09IFwiUmVjb3JkRGVjbGFyYXRpb25cIiA/IFwicmVjb3JkXCIgOlxuICAgICAgICAgIHJlc29sdmVkLmRlY2xhcmF0aW9uLmtpbmQgPT0gXCJDbGFzc0RlY2xhcmF0aW9uXCIgPyBcImNsYXNzXCIgOiBcImVycm9yXCJcblxuICAgICAgaWYgKGltcG9ydGVkLnN5bWJvbEtpbmQgIT0gcmVtb3RlRXhwb3J0LnN5bWJvbEtpbmQgfHwgaW1wb3J0ZWQuc3ltYm9sS2luZCAhPSBkZWNsYXJhdGlvbktpbmQgfHxcbiAgICAgICAgaW1wb3J0ZWQudHlwZU9ubHkgJiYgZGVjbGFyYXRpb25LaW5kICE9IFwicmVjb3JkXCIgJiYgZGVjbGFyYXRpb25LaW5kICE9IFwiY2xhc3NcIikge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwicHJvZ3JhbSBpbXBvcnQgZGVjbGFyYXRpb24ga2luZCBtaXNtYXRjaFwiLCBpbXBvcnRlZC5sb2NhdGlvbiA/PyBtb2R1bGUubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBjb25zdCBpbXBvcnROYW1lID0gcHJvZ3JhbUltcG9ydE5hbWUocHJvZ3JhbSwgbW9kdWxlLCBpbXBvcnRlZClcblxuICAgICAgaWYgKGxhbmd1YWdlICE9IFwicnVieVwiICYmIGxhbmd1YWdlICE9IFwiamF2YVwiKSB7XG4gICAgICAgIGlmIChpbXBvcnRlZC5zeW1ib2xLaW5kICE9IFwiZnVuY3Rpb25cIikgdmFsaWRhdGVUYXJnZXRUeXBlSWRlbnRpZmllcihsYW5ndWFnZSwgaW1wb3J0TmFtZSwgaW1wb3J0ZWQubG9jYXRpb24pXG4gICAgICAgIGVsc2UgdmFsaWRhdGVUYXJnZXRCaW5kaW5nSWRlbnRpZmllcihsYW5ndWFnZSwgaW1wb3J0TmFtZSwgXCJpbXBvcnRcIiwgaW1wb3J0ZWQubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lID0gdGFyZ2V0TmFtZShsYW5ndWFnZSwgaW1wb3J0TmFtZSlcblxuICAgICAgaWYgKGxhbmd1YWdlICE9IFwicnVieVwiICYmIGxhbmd1YWdlICE9IFwiamF2YVwiICYmIChsb2NhbFRhcmdldE5hbWVzLmhhcyhuYW1lKSB8fCBpbXBvcnRlZFRhcmdldE5hbWVzLmhhcyhuYW1lKSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgdGFyZ2V0IGltcG9ydC1uYW1lIGNvbGxpc2lvbiAnJHtpbXBvcnROYW1lfSdgLCBpbXBvcnRlZC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGlmIChsYW5ndWFnZSA9PSBcImphdmFcIikge1xuICAgICAgICBjb25zdCBpbXBvcnRlZENsYXNzID0gaW1wb3J0ZWQuc3ltYm9sS2luZCA9PSBcImZ1bmN0aW9uXCIgPyBtb2R1bGVDbGFzc05hbWUocmVzb2x2ZWQubW9kdWxlLmlkKSA6IHJlc29sdmVkLmRlY2xhcmF0aW9uLm5hbWVcbiAgICAgICAgY29uc3QgZXhpc3RpbmdPd25lciA9IGphdmFJbXBvcnRDbGFzc2VzLmdldChpbXBvcnRlZENsYXNzKVxuXG4gICAgICAgIGlmIChleGlzdGluZ093bmVyICYmIGV4aXN0aW5nT3duZXIgIT0gcmVzb2x2ZWQubW9kdWxlLmlkKSB7XG4gICAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgdGFyZ2V0IGltcG9ydC1jbGFzcyBjb2xsaXNpb24gJyR7aW1wb3J0ZWRDbGFzc30nYCwgaW1wb3J0ZWQubG9jYXRpb24pXG4gICAgICAgIH1cbiAgICAgICAgamF2YUltcG9ydENsYXNzZXMuc2V0KGltcG9ydGVkQ2xhc3MsIHJlc29sdmVkLm1vZHVsZS5pZClcbiAgICAgIH1cbiAgICAgIGlmIChsYW5ndWFnZSA9PSBcInJ1YnlcIikge1xuICAgICAgICBjb25zdCBpbXBvcnRlZE1vZHVsZSA9IG1vZHVsZUNsYXNzTmFtZShyZXNvbHZlZC5tb2R1bGUuaWQpXG5cbiAgICAgICAgaWYgKGxvY2FsVGFyZ2V0TmFtZXMuaGFzKGltcG9ydGVkTW9kdWxlKSkge1xuICAgICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYHRhcmdldCBpbXBvcnQtbW9kdWxlIGNvbGxpc2lvbiAnJHtpbXBvcnRlZE1vZHVsZX0nYCwgaW1wb3J0ZWQubG9jYXRpb24pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGltcG9ydGVkVGFyZ2V0TmFtZXMuYWRkKG5hbWUpXG4gICAgfVxuICAgIGNvbnN0IHZhbHVlRGVjbGFyYXRpb25JZHMgPSBuZXcgU2V0KG1vZHVsZS5pbXBvcnRzLmZpbHRlcigoe3R5cGVPbmx5fSkgPT4gIXR5cGVPbmx5KS5tYXAoKHtkZWNsYXJhdGlvbklkfSkgPT4gZGVjbGFyYXRpb25JZCkpXG4gICAgY29uc3QgdHlwZU9ubHlEZWNsYXJhdGlvbklkcyA9IG5ldyBTZXQobW9kdWxlLmltcG9ydHNcbiAgICAgIC5maWx0ZXIoKHtkZWNsYXJhdGlvbklkLCB0eXBlT25seX0pID0+IHR5cGVPbmx5ICYmICF2YWx1ZURlY2xhcmF0aW9uSWRzLmhhcyhkZWNsYXJhdGlvbklkKSlcbiAgICAgIC5tYXAoKHtkZWNsYXJhdGlvbklkfSkgPT4gZGVjbGFyYXRpb25JZCkpXG4gICAgY29uc3QgdmFsdWVDb25zdHJ1Y3Rpb24gPSBmaW5kVHlwZU9ubHlWYWx1ZUNvbnN0cnVjdGlvbihtb2R1bGUsIHR5cGVPbmx5RGVjbGFyYXRpb25JZHMpXG5cbiAgICBpZiAodmFsdWVDb25zdHJ1Y3Rpb24pIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJ0eXBlLW9ubHkgcHJvZ3JhbSBpbXBvcnQgdXNlZCBhcyBhIHZhbHVlXCIsIHZhbHVlQ29uc3RydWN0aW9uLmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgZXhwb3J0TmFtZXMgPSBuZXcgU2V0KClcblxuICAgIGZvciAoY29uc3QgZXhwb3J0ZWQgb2YgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gZGVjbGFyYXRpb25zLmdldChleHBvcnRlZC5kZWNsYXJhdGlvbklkKVxuICAgICAgY29uc3QgbmFtZSA9IHRhcmdldE5hbWUobGFuZ3VhZ2UsIGV4cG9ydGVkLmV4cG9ydGVkTmFtZSlcblxuICAgICAgaWYgKGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiKSB7XG4gICAgICAgIHZhbGlkYXRlVGFyZ2V0SWRlbnRpZmllcihsYW5ndWFnZSwgZXhwb3J0ZWQuZXhwb3J0ZWROYW1lLCBcImV4cG9ydFwiLCBleHBvcnRlZC5sb2NhdGlvbiA/PyBtb2R1bGUubG9jYXRpb24pXG4gICAgICB9XG5cbiAgICAgIGlmICghcmVzb2x2ZWQgfHwgcmVzb2x2ZWQubW9kdWxlLmlkICE9IG1vZHVsZS5pZCB8fCBleHBvcnROYW1lcy5oYXMobmFtZSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgdW5yZXNvbHZlZCBvciBjb2xsaWRpbmcgdGFyZ2V0IGV4cG9ydCAnJHtleHBvcnRlZC5leHBvcnRlZE5hbWV9J2AsIGV4cG9ydGVkLmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlY2xhcmF0aW9uS2luZCA9IHJlc29sdmVkLmRlY2xhcmF0aW9uLmtpbmQgPT0gXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIgPyBcImZ1bmN0aW9uXCIgOlxuICAgICAgICByZXNvbHZlZC5kZWNsYXJhdGlvbi5raW5kID09IFwiUmVjb3JkRGVjbGFyYXRpb25cIiA/IFwicmVjb3JkXCIgOlxuICAgICAgICAgIHJlc29sdmVkLmRlY2xhcmF0aW9uLmtpbmQgPT0gXCJDbGFzc0RlY2xhcmF0aW9uXCIgPyBcImNsYXNzXCIgOiBcImVycm9yXCJcblxuICAgICAgaWYgKGV4cG9ydGVkLnN5bWJvbEtpbmQgIT0gZGVjbGFyYXRpb25LaW5kKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJwcm9ncmFtIGV4cG9ydCBkZWNsYXJhdGlvbiBraW5kIG1pc21hdGNoXCIsIGV4cG9ydGVkLmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGlmIChsYW5ndWFnZSAhPSBcImphdmFzY3JpcHRcIiAmJiBsYW5ndWFnZSAhPSBcInR5cGVzY3JpcHRcIiAmJiBleHBvcnRlZC5leHBvcnRlZE5hbWUgIT0gcmVzb2x2ZWQuZGVjbGFyYXRpb24ubmFtZSkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBleHBvcnQgYWxpYXMgJyR7ZXhwb3J0ZWQuZXhwb3J0ZWROYW1lfScgd2l0aG91dCBhbiBlcXVpdmFsZW50IHRhcmdldCBiaW5kaW5nYCxcbiAgICAgICAgICBleHBvcnRlZC5sb2NhdGlvbiA/PyByZXNvbHZlZC5kZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGV4cG9ydE5hbWVzLmFkZChuYW1lKVxuICAgIH1cbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJwaHBcIikge1xuICAgICAgY29uc3QgZXhwb3J0ZWREZWNsYXJhdGlvbklkcyA9IG5ldyBTZXQobW9kdWxlLmV4cG9ydHMubWFwKCh7ZGVjbGFyYXRpb25JZH0pID0+IGRlY2xhcmF0aW9uSWQpKVxuICAgICAgY29uc3QgcHJpdmF0ZURlY2xhcmF0aW9uID0gWy4uLm1vZHVsZS5yZWNvcmRzID8/IFtdLCAuLi5tb2R1bGUuY2xhc3NlcyA/PyBbXSwgLi4ubW9kdWxlLmVycm9ycyA/PyBbXSwgLi4ubW9kdWxlLmZ1bmN0aW9uc10uZmluZCgoe2lkfSkgPT5cbiAgICAgICAgdHlwZW9mIGlkID09IFwic3RyaW5nXCIgJiYgIWV4cG9ydGVkRGVjbGFyYXRpb25JZHMuaGFzKGlkKSlcblxuICAgICAgaWYgKHByaXZhdGVEZWNsYXJhdGlvbikge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBub24tZXhwb3J0ZWQgZGVjbGFyYXRpb24gJyR7cHJpdmF0ZURlY2xhcmF0aW9uLm5hbWV9JyB3aXRob3V0IHRhcmdldC1wcml2YXRlIG1vZHVsZSB2aXNpYmlsaXR5YCxcbiAgICAgICAgICBwcml2YXRlRGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgICB9XG4gICAgfVxuICAgIGVhcmxpZXIuYWRkKG1vZHVsZS5pZClcbiAgfVxuXG4gIHZhbGlkYXRlUHJvZ3JhbVN0ZGxpYkNvbnRyYWN0KHByb2dyYW0sIGxhbmd1YWdlLCBjYXBhYmlsaXR5TW9kdWxlcylcbiAgdmFsaWRhdGVQcm9ncmFtU3RkbGliRmFjYWRlcyhwcm9ncmFtLCBsYW5ndWFnZSlcblxuICByZXR1cm4gcHJvZ3JhbVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBjb21waWxlci1zZWxlY3RlZCBmYWNhZGUgZGVzY3JpcHRvcnMsIGV4ZWN1dGFibGUgc291cmNlcywgbW9kdWxlIG1hcmtlcnMsIGFuZCBuYXRpdmUgaWRlbnRpdHkgZXZpZGVuY2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbX0gcHJvZ3JhbSAtIENhbmRpZGF0ZSBwcm9ncmFtLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZSBmb3IgZGlhZ25vc3RpY3MuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVQcm9ncmFtU3RkbGliRmFjYWRlcyhwcm9ncmFtLCBsYW5ndWFnZSkge1xuICBjb25zdCBkZXNjcmlwdG9yID0gUmVmbGVjdC5nZXQocHJvZ3JhbSwgXCJzdGRsaWJGYWNhZGVzXCIpXG4gIGNvbnN0IG1hcmtlZE1vZHVsZXMgPSBwcm9ncmFtLm1vZHVsZXMuZmlsdGVyKChtb2R1bGUpID0+IFJlZmxlY3QuZ2V0KG1vZHVsZSwgXCJzdGRsaWJGYWNhZGVcIikgIT09IHVuZGVmaW5lZClcbiAgY29uc3QgZmFjYWRlU291cmNlcyA9IHByb2dyYW0uc291cmNlcy5maWx0ZXIoKHNvdXJjZSkgPT4gUmVmbGVjdC5nZXQoc291cmNlLCBcIm93bmVyc2hpcFwiKSA9PSBcImZhY2FkZVwiKVxuICBjb25zdCBldmlkZW5jZWRJbXBvcnRzID0gcHJvZ3JhbS5tb2R1bGVzLmZsYXRNYXAoKG1vZHVsZSkgPT4gbW9kdWxlLmltcG9ydHMuZmlsdGVyKChpdGVtKSA9PiBSZWZsZWN0LmdldChpdGVtLCBcInN0ZGxpYkZhY2FkZVwiKSAhPT0gdW5kZWZpbmVkKSlcblxuICBpZiAoZGVzY3JpcHRvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKG1hcmtlZE1vZHVsZXMubGVuZ3RoID4gMCB8fCBmYWNhZGVTb3VyY2VzLmxlbmd0aCA+IDAgfHwgZXZpZGVuY2VkSW1wb3J0cy5sZW5ndGggPiAwKSB7XG4gICAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgXCJGYWNhZGUgbW9kdWxlcywgc291cmNlcywgb3IgaW1wb3J0IGV2aWRlbmNlIHJlcXVpcmUgYSBjb21wbGV0ZSBwcm9ncmFtIGZhY2FkZSBkZXNjcmlwdG9yLlwiKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBpZiAoIWlzUGxhaW5PYmplY3QoZGVzY3JpcHRvcikgfHwgZGVzY3JpcHRvci5zY2hlbWEgIT0gXCJTZW1hbnRpZm9sZFN0ZGxpYkZhY2FkZXNcIiB8fCBkZXNjcmlwdG9yLnZlcnNpb24gIT0gMSB8fFxuICAgIHR5cGVvZiBkZXNjcmlwdG9yLmxhbmd1YWdlICE9IFwic3RyaW5nXCIgfHwgIXByb2dyYW1UYXJnZXRzLmhhcyhkZXNjcmlwdG9yLmxhbmd1YWdlKSB8fCAhaXNEZW5zZUFycmF5KGRlc2NyaXB0b3IubW9kdWxlcykgfHxcbiAgICBkZXNjcmlwdG9yLm1vZHVsZXMubGVuZ3RoID09IDApIHtcbiAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgXCJUaGUgcHJvZ3JhbSBmYWNhZGUgZGVzY3JpcHRvciBpcyBtYWxmb3JtZWQuXCIpXG4gIH1cbiAgY29uc3QgZmFjYWRlTGFuZ3VhZ2UgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9ICovIChkZXNjcmlwdG9yLmxhbmd1YWdlKVxuICBjb25zdCByZWNvcmRzID0gZGVzY3JpcHRvci5tb2R1bGVzLm1hcCgoaXRlbSkgPT4ge1xuICAgIGlmICghaXNQbGFpbk9iamVjdChpdGVtKSB8fCB0eXBlb2YgaXRlbS5pZGVudGl0eSAhPSBcInN0cmluZ1wiIHx8IHR5cGVvZiBpdGVtLnZlcnNpb24gIT0gXCJzdHJpbmdcIikge1xuICAgICAgaW52YWxpZEZhY2FkZURlc2NyaXB0b3IobGFuZ3VhZ2UsIFwiVGhlIHByb2dyYW0gZmFjYWRlIG1vZHVsZSBkZXNjcmlwdG9yIGlzIG1hbGZvcm1lZC5cIilcbiAgICB9XG4gICAgcmV0dXJuIHN0ZGxpYkZhY2FkZVJlZ2lzdHJ5LnJlc29sdmVJZGVudGl0eShpdGVtLmlkZW50aXR5LCBmYWNhZGVMYW5ndWFnZSwgaXRlbS52ZXJzaW9uKVxuICB9KVxuICBjb25zdCBleHBlY3RlZCA9IHN0ZGxpYkZhY2FkZVByb2dyYW1EZXNjcmlwdG9yKGZhY2FkZUxhbmd1YWdlLCByZWNvcmRzKVxuXG4gIGlmICghZXF1YWxQbGFpbkRhdGEoZGVzY3JpcHRvciwgZXhwZWN0ZWQpKSB7XG4gICAgaW52YWxpZEZhY2FkZURlc2NyaXB0b3IobGFuZ3VhZ2UsIFwiVGhlIHByb2dyYW0gZmFjYWRlIGRlc2NyaXB0b3IgZG9lcyBub3QgbWF0Y2ggdGhlIHJlZ2lzdGVyZWQgdmVyc2lvbmVkIGZhY2FkZSBjbG9zdXJlLlwiKVxuICB9XG4gIGNvbnN0IHNlbGVjdGVkUmVjb3JkcyA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3QgcmVjb3JkIG9mIHJlY29yZHMpIHtcbiAgICBpZiAoc2VsZWN0ZWRSZWNvcmRzLmhhcyhyZWNvcmQuaWRlbnRpdHkpKSB7XG4gICAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgYEZhY2FkZSAnJHtyZWNvcmQuaWRlbnRpdHl9JyBpcyBzZWxlY3RlZCBtb3JlIHRoYW4gb25jZS5gKVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRlcGVuZGVuY3kgb2YgcmVjb3JkLmRlcGVuZGVuY2llcykge1xuICAgICAgY29uc3QgcmVzb2x2ZWQgPSBzdGRsaWJGYWNhZGVSZWdpc3RyeS5yZXNvbHZlSWRlbnRpdHkoZGVwZW5kZW5jeS5pZGVudGl0eSwgZmFjYWRlTGFuZ3VhZ2UsIGRlcGVuZGVuY3kucmFuZ2UpXG4gICAgICBjb25zdCBzZWxlY3RlZCA9IHNlbGVjdGVkUmVjb3Jkcy5nZXQocmVzb2x2ZWQuaWRlbnRpdHkpXG5cbiAgICAgIGlmICghc2VsZWN0ZWQgfHwgc2VsZWN0ZWQudmVyc2lvbiAhPSByZXNvbHZlZC52ZXJzaW9uKSB7XG4gICAgICAgIGludmFsaWRGYWNhZGVEZXNjcmlwdG9yKGxhbmd1YWdlLCBgRmFjYWRlICcke3JlY29yZC5pZGVudGl0eX0nIGRlcGVuZGVuY3kgJyR7cmVzb2x2ZWQuaWRlbnRpdHl9QCR7cmVzb2x2ZWQudmVyc2lvbn0nIGlzIG1pc3Npbmcgb3Igb3V0IG9mIG9yZGVyLmApXG4gICAgICB9XG4gICAgfVxuICAgIHNlbGVjdGVkUmVjb3Jkcy5zZXQocmVjb3JkLmlkZW50aXR5LCByZWNvcmQpXG4gIH1cbiAgaWYgKG1hcmtlZE1vZHVsZXMubGVuZ3RoICE9IHJlY29yZHMubGVuZ3RoKSB7XG4gICAgaW52YWxpZEZhY2FkZURlc2NyaXB0b3IobGFuZ3VhZ2UsIFwiVGhlIHByb2dyYW0gZmFjYWRlIGRlc2NyaXB0b3IgZG9lcyBub3QgbWF0Y2ggaXRzIGV4ZWN1dGFibGUgc2VtYW50aWMgbW9kdWxlcy5cIilcbiAgfVxuICBpZiAocHJvZ3JhbS5zb3VyY2VzLnNvbWUoKHNvdXJjZSkgPT4gc291cmNlLmxhbmd1YWdlICE9IGZhY2FkZUxhbmd1YWdlIHx8XG4gICAgIVtcImFwcGxpY2F0aW9uXCIsIFwiZmFjYWRlXCJdLmluY2x1ZGVzKFN0cmluZyhSZWZsZWN0LmdldChzb3VyY2UsIFwib3duZXJzaGlwXCIpKSkpKSB7XG4gICAgaW52YWxpZEZhY2FkZURlc2NyaXB0b3IobGFuZ3VhZ2UsIFwiRmFjYWRlIHByb2dyYW1zIHJlcXVpcmUgb25lIHNvdXJjZSBsYW5ndWFnZSBhbmQgZXhwbGljaXQgYXBwbGljYXRpb24vZmFjYWRlIG93bmVyc2hpcC5cIilcbiAgfVxuICBjb25zdCBzZWxlY3RlZElkZW50aXRpZXMgPSBuZXcgU2V0KHJlY29yZHMubWFwKCh7aWRlbnRpdHl9KSA9PiBpZGVudGl0eSkpXG4gIGNvbnN0IHJlZ2lzdGVyZWRNb2R1bGVzID0gcmVwYXJzZVJlZ2lzdGVyZWRGYWNhZGVNb2R1bGVzKHByb2dyYW0sIGZhY2FkZUxhbmd1YWdlLCBsYW5ndWFnZSlcblxuICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgcmVjb3Jkcy5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBjb25zdCByZWNvcmQgPSByZWNvcmRzW2luZGV4XVxuICAgIGNvbnN0IG1vZHVsZSA9IG1hcmtlZE1vZHVsZXNbaW5kZXhdXG4gICAgY29uc3QgbWFya2VyID0gUmVmbGVjdC5nZXQobW9kdWxlLCBcInN0ZGxpYkZhY2FkZVwiKVxuXG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KG1hcmtlcikgfHwgT2JqZWN0LmtleXMobWFya2VyKS5zb3J0KCkuam9pbihcIixcIikgIT0gXCJpZGVudGl0eSx2ZXJzaW9uXCIgfHxcbiAgICAgIG1hcmtlci5pZGVudGl0eSAhPSByZWNvcmQuaWRlbnRpdHkgfHwgbWFya2VyLnZlcnNpb24gIT0gcmVjb3JkLnZlcnNpb24gfHwgbW9kdWxlLmlkICE9IHJlY29yZC5zb3VyY2UuaWQgfHxcbiAgICAgIG1vZHVsZS5zb3VyY2VGaWxlbmFtZSAhPSByZWNvcmQuc291cmNlLmZpbGVuYW1lKSB7XG4gICAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgYEZhY2FkZSAnJHtyZWNvcmQuaWRlbnRpdHl9JyBzZW1hbnRpYyBtb2R1bGUgaWRlbnRpdHkgaXMgbm90IGNhbm9uaWNhbC5gKVxuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBwcm9ncmFtLnNvdXJjZXMuZmluZCgoe2ZpbGVuYW1lfSkgPT4gZmlsZW5hbWUgPT0gcmVjb3JkLnNvdXJjZS5maWxlbmFtZSlcblxuICAgIGlmICghc291cmNlIHx8IHNvdXJjZS5jb250ZW50ICE9IHJlY29yZC5zb3VyY2UuY29udGVudCB8fCBSZWZsZWN0LmdldChzb3VyY2UsIFwib3duZXJzaGlwXCIpICE9IFwiZmFjYWRlXCIpIHtcbiAgICAgIGludmFsaWRGYWNhZGVEZXNjcmlwdG9yKGxhbmd1YWdlLCBgRmFjYWRlICcke3JlY29yZC5pZGVudGl0eX0nIGV4ZWN1dGFibGUgc291cmNlIGRvZXMgbm90IG1hdGNoIGl0cyByZWdpc3RlcmVkIGRlZmluaXRpb24uYClcbiAgICB9XG4gICAgY29uc3QgcmVnaXN0ZXJlZE1vZHVsZSA9IHJlZ2lzdGVyZWRNb2R1bGVzLmdldChyZWNvcmQuaWRlbnRpdHkpXG5cbiAgICBpZiAoIXJlZ2lzdGVyZWRNb2R1bGUgfHwgIWVxdWFsUGxhaW5EYXRhKG1vZHVsZSwgcmVnaXN0ZXJlZE1vZHVsZSkpIHtcbiAgICAgIGludmFsaWRGYWNhZGVBdXRob3JpdHkobGFuZ3VhZ2UsXG4gICAgICAgIGBGYWNhZGUgJyR7cmVjb3JkLmlkZW50aXR5fScgc2VtYW50aWMgbW9kdWxlIGRvZXMgbm90IG1hdGNoIGl0cyByZWdpc3RlcmVkIGV4ZWN1dGFibGUgc291cmNlLmAsIG1vZHVsZS5sb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgYWxsb3dlZE9wZXJhdGlvbnMgPSBuZXcgU2V0KHJlY29yZC5yZXF1aXJlbWVudHMuZmxhdE1hcCgoe29wZXJhdGlvbnN9KSA9PiBvcGVyYXRpb25zKSlcbiAgICBjb25zdCB1c2VkT3BlcmF0aW9ucyA9IGNvbGxlY3REZWNsYXJlZEVmZmVjdE9wZXJhdGlvbnMobW9kdWxlKVxuXG4gICAgaWYgKGFsbG93ZWRPcGVyYXRpb25zLnNpemUgIT0gdXNlZE9wZXJhdGlvbnMuc2l6ZSB8fCBbLi4uYWxsb3dlZE9wZXJhdGlvbnNdLnNvbWUoKG9wZXJhdGlvbikgPT4gIXVzZWRPcGVyYXRpb25zLmhhcyhvcGVyYXRpb24pKSkge1xuICAgICAgaW52YWxpZEZhY2FkZUF1dGhvcml0eShsYW5ndWFnZSwgYEZhY2FkZSAnJHtyZWNvcmQuaWRlbnRpdHl9JyBzZW1hbnRpYyBib2R5IGRvZXMgbm90IG1hdGNoIGl0cyBkZWNsYXJlZCBjYW5vbmljYWwgcmVxdWlyZW1lbnRzLmAsIG1vZHVsZS5sb2NhdGlvbilcbiAgICB9XG4gIH1cbiAgaWYgKGZhY2FkZVNvdXJjZXMubGVuZ3RoICE9IHJlY29yZHMubGVuZ3RoKSB7XG4gICAgaW52YWxpZEZhY2FkZURlc2NyaXB0b3IobGFuZ3VhZ2UsIFwiVGhlIHByb2dyYW0gY29udGFpbnMgYW4gdW5zZWxlY3RlZCBjb21waWxlci1vd25lZCBmYWNhZGUgc291cmNlLlwiKVxuICB9XG4gIGlmIChldmlkZW5jZWRJbXBvcnRzLmxlbmd0aCA9PSAwKSB7XG4gICAgaW52YWxpZEZhY2FkZURlc2NyaXB0b3IobGFuZ3VhZ2UsIFwiVGhlIHNlbGVjdGVkIGZhY2FkZSBjbG9zdXJlIGhhcyBubyBwYXJzZXItcHJvdmVkIG5hdGl2ZSBpbXBvcnQgZXZpZGVuY2UuXCIpXG4gIH1cbiAgZm9yIChjb25zdCBpbXBvcnRlZCBvZiBldmlkZW5jZWRJbXBvcnRzKSB7XG4gICAgY29uc3QgZXZpZGVuY2UgPSBSZWZsZWN0LmdldChpbXBvcnRlZCwgXCJzdGRsaWJGYWNhZGVcIilcblxuICAgIGlmICghaXNQbGFpbk9iamVjdChldmlkZW5jZSkgfHwgT2JqZWN0LmtleXMoZXZpZGVuY2UpLnNvcnQoKS5qb2luKFwiLFwiKSAhPVxuICAgICAgXCJmYWNhZGVJZGVudGl0eSxmYWNhZGVWZXJzaW9uLG5hdGl2ZU1vZHVsZSxuYXRpdmVTeW1ib2wsc2NoZW1hLHZlcnNpb25cIiB8fFxuICAgICAgZXZpZGVuY2Uuc2NoZW1hICE9IFwiU2VtYW50aWZvbGRTdGRsaWJGYWNhZGVSZXNvbHV0aW9uXCIgfHwgZXZpZGVuY2UudmVyc2lvbiAhPSAxIHx8XG4gICAgICB0eXBlb2YgZXZpZGVuY2UuZmFjYWRlSWRlbnRpdHkgIT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgZXZpZGVuY2UuZmFjYWRlVmVyc2lvbiAhPSBcInN0cmluZ1wiIHx8XG4gICAgICB0eXBlb2YgZXZpZGVuY2UubmF0aXZlTW9kdWxlICE9IFwic3RyaW5nXCIgfHwgdHlwZW9mIGV2aWRlbmNlLm5hdGl2ZVN5bWJvbCAhPSBcInN0cmluZ1wiKSB7XG4gICAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgXCJBIGZhY2FkZSBpbXBvcnQgaGFzIG1hbGZvcm1lZCBuYXRpdmUgaWRlbnRpdHkgZXZpZGVuY2UuXCIpXG4gICAgfVxuICAgIGNvbnN0IHJlY29yZCA9IHN0ZGxpYkZhY2FkZVJlZ2lzdHJ5LnJlc29sdmVGYWNhZGUoZmFjYWRlTGFuZ3VhZ2UsIGV2aWRlbmNlLm5hdGl2ZU1vZHVsZSwgZXZpZGVuY2UubmF0aXZlU3ltYm9sLFxuICAgICAgZXZpZGVuY2UuZmFjYWRlVmVyc2lvbilcblxuICAgIGlmIChyZWNvcmQuaWRlbnRpdHkgIT0gZXZpZGVuY2UuZmFjYWRlSWRlbnRpdHkgfHwgIXNlbGVjdGVkSWRlbnRpdGllcy5oYXMocmVjb3JkLmlkZW50aXR5KSB8fCBpbXBvcnRlZC5tb2R1bGVJZCAhPSByZWNvcmQuc291cmNlLmlkIHx8XG4gICAgICBpbXBvcnRlZC5pbXBvcnRlZE5hbWUgIT0gZXZpZGVuY2UubmF0aXZlU3ltYm9sKSB7XG4gICAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgXCJBIGZhY2FkZSBpbXBvcnQgZG9lcyBub3QgbWF0Y2ggaXRzIHJlZ2lzdGVyZWQgbmF0aXZlIG1vZHVsZSBhbmQgc3ltYm9sIGlkZW50aXR5LlwiKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIENvbGxlY3RzIGV2ZXJ5IGNhbm9uaWNhbCBvcGVyYXRpb24gcHJlc2VudCBpbiBvbmUgdmFsaWRhdGVkIGZhY2FkZSBpbXBsZW1lbnRhdGlvbi5cbiAqIFRoaXMgY2hlY2tzIHRoZSBmYWNhZGUncyBjb21wbGV0ZSBkZWNsYXJlZCBhdXRob3JpdHkgaW5kZXBlbmRlbnRseSBmcm9tIHByb2dyYW0gcmVhY2hhYmlsaXR5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGV9IG1vZHVsZSAtIEZhY2FkZSBtb2R1bGUuXG4gKiBAcmV0dXJucyB7U2V0PHN0cmluZz59IFVzZWQgb3BlcmF0aW9uIG5hbWVzLlxuICovXG5mdW5jdGlvbiBjb2xsZWN0RGVjbGFyZWRFZmZlY3RPcGVyYXRpb25zKG1vZHVsZSkge1xuICBjb25zdCBvcGVyYXRpb25OYW1lcyA9IG5ldyBNYXAobW9kdWxlLmNhcGFiaWxpdGllcz8uZmxhdE1hcCgoe29wZXJhdGlvbnN9KSA9PlxuICAgIG9wZXJhdGlvbnMubWFwKChvcGVyYXRpb24pID0+IFtvcGVyYXRpb24uaWQsIG9wZXJhdGlvbi5uYW1lXSkpID8/IFtdKVxuICBjb25zdCB1c2VkID0gbmV3IFNldCgpXG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0KClcbiAgLyoqXG4gICAqIFZpc2l0cyBvbmUgZmFjYWRlIHNlbWFudGljIHN1YnRyZWUuXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgc2VtYW50aWMgc3VidHJlZS5cbiAgICovXG4gIGNvbnN0IHZpc2l0ID0gKHZhbHVlKSA9PiB7XG4gICAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT0gXCJvYmplY3RcIiB8fCBzZWVuLmhhcyh2YWx1ZSkpIHJldHVyblxuICAgIHNlZW4uYWRkKHZhbHVlKVxuICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIGNvbnN0IG9wZXJhdGlvbiA9IFJlZmxlY3QuZ2V0KHZhbHVlLCBcImtpbmRcIikgPT0gXCJFZmZlY3RDYWxsRXhwcmVzc2lvblwiID8gUmVmbGVjdC5nZXQodmFsdWUsIFwib3BlcmF0aW9uXCIpIDogdW5kZWZpbmVkXG5cbiAgICAgIGlmICh0eXBlb2Ygb3BlcmF0aW9uID09IFwic3RyaW5nXCIgJiYgb3BlcmF0aW9uTmFtZXMuaGFzKG9wZXJhdGlvbikpIHVzZWQuYWRkKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAob3BlcmF0aW9uTmFtZXMuZ2V0KG9wZXJhdGlvbikpKVxuICAgICAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG4gICAgICAgIGlmIChbXCJjYXBhYmlsaXRpZXNcIiwgXCJsb2NhdGlvblwiLCBcInByb3ZlbmFuY2VcIiwgXCJyZXNvbHV0aW9uXCIsIFwic291cmNlUHJvdmVuYW5jZVwiXS5pbmNsdWRlcyhrZXkpKSBjb250aW51ZVxuICAgICAgICB2aXNpdChjaGlsZClcbiAgICAgIH1cbiAgICB9IGVsc2UgZm9yIChjb25zdCBjaGlsZCBvZiB2YWx1ZSkgdmlzaXQoY2hpbGQpXG4gIH1cblxuICB2aXNpdCh7Y2xhc3NlczogbW9kdWxlLmNsYXNzZXMsIGVudHJ5UG9pbnQ6IG1vZHVsZS5lbnRyeVBvaW50LCBmdW5jdGlvbnM6IG1vZHVsZS5mdW5jdGlvbnN9KVxuICByZXR1cm4gdXNlZFxufVxuXG4vKipcbiAqIFJlY29tcGlsZXMgdGhlIHJlZ2lzdHJ5LXNlbGVjdGVkIGZhY2FkZSBjbG9zdXJlIGZyb20gcmV0YWluZWQgY2FsbGVyIGlucHV0cyBhbmQgcmVnaXN0ZXJlZCBmYWNhZGUgc291cmNlLlxuICogVGhpcyBwYXJzZXItYmFja2VkIHJlZmVyZW5jZSBncmFwaCBpcyBjcmVhdGVkIGR1cmluZyB2YWxpZGF0aW9uLCBiZWZvcmUgcHJvdmlkZXIgcGxhbm5pbmcgb3Igd3JpdGVyIGFsbG9jYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbX0gcHJvZ3JhbSAtIFVudHJ1c3RlZCBtdXRhYmxlIHNlbWFudGljIHByb2dyYW0uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGZhY2FkZUxhbmd1YWdlIC0gU2VsZWN0ZWQgc291cmNlLWxhbmd1YWdlIGZhY2FkZSBwcm9maWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBkaWFnbm9zdGljTGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UgZm9yIGJvdW5kYXJ5IGRpYWdub3N0aWNzLlxuICogQHJldHVybnMge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZT59IENhbm9uaWNhbCBzZW1hbnRpYyBtb2R1bGVzIGJ5IGZhY2FkZSBpZGVudGl0eS5cbiAqL1xuZnVuY3Rpb24gcmVwYXJzZVJlZ2lzdGVyZWRGYWNhZGVNb2R1bGVzKHByb2dyYW0sIGZhY2FkZUxhbmd1YWdlLCBkaWFnbm9zdGljTGFuZ3VhZ2UpIHtcbiAgY29uc3QgYXBwbGljYXRpb25Nb2R1bGVzID0gcHJvZ3JhbS5tb2R1bGVzLmZpbHRlcigobW9kdWxlKSA9PiBSZWZsZWN0LmdldChtb2R1bGUsIFwic3RkbGliRmFjYWRlXCIpID09PSB1bmRlZmluZWQpXG4gIGNvbnN0IG1vZHVsZXNCeUZpbGVuYW1lID0gbmV3IE1hcChhcHBsaWNhdGlvbk1vZHVsZXMubWFwKChtb2R1bGUpID0+IFttb2R1bGUuc291cmNlRmlsZW5hbWUsIG1vZHVsZV0pKVxuICBjb25zdCBhcHBsaWNhdGlvblNvdXJjZXMgPSBwcm9ncmFtLnNvdXJjZXMuZmlsdGVyKChzb3VyY2UpID0+IFJlZmxlY3QuZ2V0KHNvdXJjZSwgXCJvd25lcnNoaXBcIikgPT0gXCJhcHBsaWNhdGlvblwiKS5tYXAoKHNvdXJjZSkgPT4ge1xuICAgIGNvbnN0IG1vZHVsZSA9IG1vZHVsZXNCeUZpbGVuYW1lLmdldChzb3VyY2UuZmlsZW5hbWUpXG5cbiAgICBpZiAoIW1vZHVsZSkgaW52YWxpZEZhY2FkZURlc2NyaXB0b3IoZGlhZ25vc3RpY0xhbmd1YWdlLFxuICAgICAgYEFwcGxpY2F0aW9uIHNvdXJjZSAnJHtzb3VyY2UuZmlsZW5hbWV9JyBoYXMgbm8gbWF0Y2hpbmcgc2VtYW50aWMgbW9kdWxlIGZvciBmYWNhZGUgdmVyaWZpY2F0aW9uLmApXG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbGVuYW1lOiBzb3VyY2UuZmlsZW5hbWUsXG4gICAgICBpZDogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGV9ICovIChtb2R1bGUpLmlkLFxuICAgICAgbGFuZ3VhZ2U6IGZhY2FkZUxhbmd1YWdlLFxuICAgICAgc291cmNlOiAvKiogQHR5cGUge3N0cmluZ30gKi8gKHNvdXJjZS5jb250ZW50KVxuICAgIH1cbiAgfSlcblxuICBpZiAoYXBwbGljYXRpb25Tb3VyY2VzLmxlbmd0aCAhPSBhcHBsaWNhdGlvbk1vZHVsZXMubGVuZ3RoKSB7XG4gICAgaW52YWxpZEZhY2FkZURlc2NyaXB0b3IoZGlhZ25vc3RpY0xhbmd1YWdlLCBcIkZhY2FkZSB2ZXJpZmljYXRpb24gcmVxdWlyZXMgb25lIHJldGFpbmVkIGFwcGxpY2F0aW9uIHNvdXJjZSBwZXIgc2VtYW50aWMgbW9kdWxlLlwiKVxuICB9XG4gIGNvbnN0IHJlcGFyc2VkID0gcGFyc2VQcm9ncmFtU291cmNlKHtlbnRyeU1vZHVsZTogcHJvZ3JhbS5lbnRyeU1vZHVsZSwgc291cmNlczogYXBwbGljYXRpb25Tb3VyY2VzfSlcbiAgY29uc3QgbW9kdWxlcyA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3QgbW9kdWxlIG9mIHJlcGFyc2VkLm1vZHVsZXMpIHtcbiAgICBpZiAoIW1vZHVsZS5zdGRsaWJGYWNhZGUpIGNvbnRpbnVlXG4gICAgaWYgKG1vZHVsZXMuaGFzKG1vZHVsZS5zdGRsaWJGYWNhZGUuaWRlbnRpdHkpKSB7XG4gICAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihkaWFnbm9zdGljTGFuZ3VhZ2UsIGBSZWdpc3RlcmVkIGZhY2FkZSAnJHttb2R1bGUuc3RkbGliRmFjYWRlLmlkZW50aXR5fScgcmVwYXJzZWQgbW9yZSB0aGFuIG9uY2UuYClcbiAgICB9XG4gICAgbW9kdWxlcy5zZXQobW9kdWxlLnN0ZGxpYkZhY2FkZS5pZGVudGl0eSwgbW9kdWxlKVxuICB9XG4gIHJldHVybiBtb2R1bGVzXG59XG5cbi8qKlxuICogQ29tcGFyZXMgY2xvc2VkIHBsYWluIEpTT04tc2hhcGVkIGRhdGEgd2l0aG91dCBjb2VyY2lvbiBvciBrZXktb3JkZXIgYXNzdW1wdGlvbnMuXG4gKiBAcGFyYW0ge3Vua25vd259IGxlZnQgLSBDYW5kaWRhdGUgdmFsdWUuXG4gKiBAcGFyYW0ge3Vua25vd259IHJpZ2h0IC0gRXhwZWN0ZWQgdmFsdWUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gRXhhY3QgcmVjdXJzaXZlIGVxdWl2YWxlbmNlLlxuICovXG5mdW5jdGlvbiBlcXVhbFBsYWluRGF0YShsZWZ0LCByaWdodCkge1xuICBpZiAobGVmdCA9PT0gcmlnaHQpIHJldHVybiB0cnVlXG4gIGlmIChBcnJheS5pc0FycmF5KGxlZnQpIHx8IEFycmF5LmlzQXJyYXkocmlnaHQpKSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkobGVmdCkgJiYgQXJyYXkuaXNBcnJheShyaWdodCkgJiYgaXNEZW5zZUFycmF5KGxlZnQpICYmIGlzRGVuc2VBcnJheShyaWdodCkgJiZcbiAgICAgIGxlZnQubGVuZ3RoID09IHJpZ2h0Lmxlbmd0aCAmJiBsZWZ0LmV2ZXJ5KCh2YWx1ZSwgaW5kZXgpID0+IGVxdWFsUGxhaW5EYXRhKHZhbHVlLCByaWdodFtpbmRleF0pKVxuICB9XG4gIGlmICghaXNQbGFpbk9iamVjdChsZWZ0KSB8fCAhaXNQbGFpbk9iamVjdChyaWdodCkpIHJldHVybiBmYWxzZVxuICBjb25zdCBsZWZ0S2V5cyA9IE9iamVjdC5rZXlzKGxlZnQpLnNvcnQoKVxuICBjb25zdCByaWdodEtleXMgPSBPYmplY3Qua2V5cyhyaWdodCkuc29ydCgpXG5cbiAgcmV0dXJuIGxlZnRLZXlzLmxlbmd0aCA9PSByaWdodEtleXMubGVuZ3RoICYmIGxlZnRLZXlzLmV2ZXJ5KChrZXksIGluZGV4KSA9PlxuICAgIGtleSA9PSByaWdodEtleXNbaW5kZXhdICYmIGVxdWFsUGxhaW5EYXRhKGxlZnRba2V5XSwgcmlnaHRba2V5XSkpXG59XG5cbi8qKlxuICogVGhyb3dzIG9uZSBzdGFibGUgZmFjYWRlIGFydGlmYWN0LWJvdW5kYXJ5IGRpYWdub3N0aWMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBEaWFnbm9zdGljIGRldGFpbC5cbiAqIEByZXR1cm5zIHtuZXZlcn0gQWx3YXlzIHRocm93cy5cbiAqL1xuZnVuY3Rpb24gaW52YWxpZEZhY2FkZURlc2NyaXB0b3IobGFuZ3VhZ2UsIG1lc3NhZ2UpIHtcbiAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7Y29kZTogXCJTVERMSUJfRkFDQURFX0RFU0NSSVBUT1JfSU5WQUxJRFwiLCBsYW5ndWFnZSwgbWVzc2FnZX0pXG59XG5cbi8qKlxuICogVGhyb3dzIHdoZW4gYSBmYWNhZGUgc2VtYW50aWMgYm9keSBleGNlZWRzIG9yIG9taXRzIGl0cyByZWdpc3RyeS1kZWNsYXJlZCBhdXRob3JpdHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBEaWFnbm9zdGljIGRldGFpbC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gRmFjYWRlIHNvdXJjZSBsb2NhdGlvbi5cbiAqIEByZXR1cm5zIHtuZXZlcn0gQWx3YXlzIHRocm93cy5cbiAqL1xuZnVuY3Rpb24gaW52YWxpZEZhY2FkZUF1dGhvcml0eShsYW5ndWFnZSwgbWVzc2FnZSwgbG9jYXRpb24pIHtcbiAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7Y29kZTogXCJTVERMSUJfRkFDQURFX0FVVEhPUklUWV9GT1JHRURcIiwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBtZXNzYWdlfSlcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgdGhlIHByb2dyYW0gc3RkbGliIGxpbmsgZGVzY3JpcHRvciBhZ2FpbnN0IGl0cyBjYXBhYmlsaXR5IG1vZHVsZXMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbX0gcHJvZ3JhbSAtIENhbmRpZGF0ZSBwcm9ncmFtLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtTW9kdWxlW119IGNhcGFiaWxpdHlNb2R1bGVzIC0gTW9kdWxlcyBjYXJyeWluZyBjYXBhYmlsaXRpZXMuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVQcm9ncmFtU3RkbGliQ29udHJhY3QocHJvZ3JhbSwgbGFuZ3VhZ2UsIGNhcGFiaWxpdHlNb2R1bGVzKSB7XG4gIGNvbnN0IGNvbnRyYWN0ID0gUmVmbGVjdC5nZXQocHJvZ3JhbSwgXCJzdGRsaWJDb250cmFjdFwiKVxuICBjb25zdCBjb250cmFjdHMgPSBSZWZsZWN0LmdldChwcm9ncmFtLCBcInN0ZGxpYkNvbnRyYWN0c1wiKVxuXG4gIGlmIChjYXBhYmlsaXR5TW9kdWxlcy5sZW5ndGggPT0gMCkge1xuICAgIGlmIChjb250cmFjdCAhPT0gdW5kZWZpbmVkIHx8IGNvbnRyYWN0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgICAgY29kZTogXCJTVERMSUJfTElOS19GQUlMVVJFXCIsXG4gICAgICAgIGxhbmd1YWdlLFxuICAgICAgICBtZXNzYWdlOiBcIkEgZGVjbGFyZWQgc3RhbmRhcmQtbGlicmFyeSBjb250cmFjdCByZXF1aXJlcyBjYXBhYmlsaXR5IG1vZHVsZXMuXCJcbiAgICAgIH0pXG4gICAgfVxuICAgIHJldHVyblxuICB9XG4gIGlmIChjb250cmFjdCAhPT0gdW5kZWZpbmVkICYmIGNvbnRyYWN0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7XG4gICAgICBjb2RlOiBcIlNURExJQl9MSU5LX0ZBSUxVUkVcIixcbiAgICAgIGxhbmd1YWdlLFxuICAgICAgbWVzc2FnZTogXCJBIHByb2dyYW0gY2Fubm90IGRlY2xhcmUgYm90aCBzaW5ndWxhciBhbmQgcGx1cmFsIHN0YW5kYXJkLWxpYnJhcnkgY29udHJhY3QgZGVzY3JpcHRvcnMuXCJcbiAgICB9KVxuICB9XG4gIGlmIChjb250cmFjdCA9PT0gdW5kZWZpbmVkICYmIGNvbnRyYWN0cyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcInByb2dyYW0gbW9kdWxlcyB3aXRoIGNhcGFiaWxpdGllcyByZXF1aXJlIGEgZGVjbGFyZWQgc3RhbmRhcmQtbGlicmFyeSBjb250cmFjdFwiLFxuICAgICAgY2FwYWJpbGl0eU1vZHVsZXNbMF0ubG9jYXRpb24pXG4gIH1cbiAgY29uc3QgZGVjbGFyZWQgPSBjb250cmFjdHMgPT09IHVuZGVmaW5lZCA/IFtjb250cmFjdF0gOiBjb250cmFjdHNcblxuICBpZiAoIWlzRGVuc2VBcnJheShkZWNsYXJlZCkgfHwgZGVjbGFyZWQubGVuZ3RoID09IDApIHtcbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgIGNvZGU6IFwiU1RETElCX0xJTktfRkFJTFVSRVwiLFxuICAgICAgbGFuZ3VhZ2UsXG4gICAgICBtZXNzYWdlOiBcIlRoZSBkZWNsYXJlZCBzdGFuZGFyZC1saWJyYXJ5IGNvbnRyYWN0IGRlc2NyaXB0b3IgbGlzdCBpcyBtYWxmb3JtZWQgb3IgZW1wdHkuXCJcbiAgICB9KVxuICB9XG4gIGNvbnN0IGlkZW50aXRpZXMgPSBuZXcgU2V0KClcblxuICBmb3IgKGNvbnN0IGRlc2NyaXB0b3Igb2YgZGVjbGFyZWQpIHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3QoZGVzY3JpcHRvcikgfHwgT2JqZWN0LmtleXMoZGVzY3JpcHRvcikuc29tZSgoa2V5KSA9PiBrZXkgIT0gXCJpZGVudGl0eVwiICYmIGtleSAhPSBcImNvbnRyYWN0VmVyc2lvblwiKSkge1xuICAgICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7XG4gICAgICAgIGNvZGU6IFwiU1RETElCX0xJTktfRkFJTFVSRVwiLFxuICAgICAgICBsYW5ndWFnZSxcbiAgICAgICAgbWVzc2FnZTogXCJUaGUgZGVjbGFyZWQgc3RhbmRhcmQtbGlicmFyeSBjb250cmFjdCBkZXNjcmlwdG9yIGlzIG1hbGZvcm1lZC5cIlxuICAgICAgfSlcbiAgICB9XG4gICAgY29uc3QgaWRlbnRpdHkgPSBkZXNjcmlwdG9yLmlkZW50aXR5XG5cbiAgICBpZiAodHlwZW9mIGlkZW50aXR5ICE9IFwic3RyaW5nXCIgfHwgaWRlbnRpdHkubGVuZ3RoID09IDAgfHwgaWRlbnRpdGllcy5oYXMoaWRlbnRpdHkpIHx8XG4gICAgICAhbGlzdFN0ZGxpYk1vZHVsZXMoKS5zb21lKCh7aWRlbnRpdHk6IHJlZ2lzdGVyZWR9KSA9PiByZWdpc3RlcmVkID09IGlkZW50aXR5KSkge1xuICAgICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7XG4gICAgICAgIGNvZGU6IFwiU1RETElCX0xJTktfRkFJTFVSRVwiLFxuICAgICAgICBsYW5ndWFnZSxcbiAgICAgICAgbWVzc2FnZTogYERlY2xhcmVkIHN0YW5kYXJkLWxpYnJhcnkgY29udHJhY3QgJyR7U3RyaW5nKGlkZW50aXR5KX0nIGlzIGR1cGxpY2F0ZSBvciBub3QgYSByZWdpc3RlcmVkIGNhbm9uaWNhbCBtb2R1bGUuYFxuICAgICAgfSlcbiAgICB9XG4gICAgaWYgKGRlc2NyaXB0b3IuY29udHJhY3RWZXJzaW9uICE9PSB1bmRlZmluZWQgJiYgcGFyc2VTdGRsaWJWZXJzaW9uUmFuZ2UoZGVzY3JpcHRvci5jb250cmFjdFZlcnNpb24pID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgICAgY29kZTogXCJTVERMSUJfTElOS19GQUlMVVJFXCIsXG4gICAgICAgIGxhbmd1YWdlLFxuICAgICAgICBtZXNzYWdlOiBgRGVjbGFyZWQgc3RhbmRhcmQtbGlicmFyeSBjb250cmFjdCB2ZXJzaW9uICcke1N0cmluZyhkZXNjcmlwdG9yLmNvbnRyYWN0VmVyc2lvbil9JyBpcyBub3QgY2Fub25pY2FsLmBcbiAgICAgIH0pXG4gICAgfVxuICAgIGlkZW50aXRpZXMuYWRkKGlkZW50aXR5KVxuICB9XG4gIGZvciAoY29uc3QgbW9kdWxlIG9mIGNhcGFiaWxpdHlNb2R1bGVzKSB7XG4gICAgZm9yIChjb25zdCBjYXBhYmlsaXR5IG9mIG1vZHVsZS5jYXBhYmlsaXRpZXMgPz8gW10pIHtcbiAgICAgIGlmICghaXNQbGFpbk9iamVjdChjYXBhYmlsaXR5KSB8fCB0eXBlb2YgY2FwYWJpbGl0eS5hdXRob3JpdHlJZCAhPSBcInN0cmluZ1wiIHx8ICFpZGVudGl0aWVzLmhhcyhjYXBhYmlsaXR5LmF1dGhvcml0eUlkKSkge1xuICAgICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgICAgICBjb2RlOiBcIlNURExJQl9MSU5LX0ZBSUxVUkVcIixcbiAgICAgICAgICBsYW5ndWFnZSxcbiAgICAgICAgICBtZXNzYWdlOiBgQ2FwYWJpbGl0eSBhdXRob3JpdHkgJyR7U3RyaW5nKFJlZmxlY3QuZ2V0KGNhcGFiaWxpdHksIFwiYXV0aG9yaXR5SWRcIikpfScgZG9lcyBub3QgbWF0Y2ggYSBkZWNsYXJlZCBzdGFuZGFyZC1saWJyYXJ5IGNvbnRyYWN0LmBcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBGaW5kcyBhIHJlY29yZCBjb25zdHJ1Y3Rpb24gdGhhdCBjcm9zc2VzIGEgdHlwZS1vbmx5IGltcG9ydCBlZGdlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGV9IG1vZHVsZSAtIEltcG9ydGluZyBzZW1hbnRpYyBtb2R1bGUuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSB0eXBlT25seURlY2xhcmF0aW9uSWRzIC0gSW1wb3J0ZWQgaWRlbnRpdGllcyB1bmF2YWlsYWJsZSBpbiB2YWx1ZSBwb3NpdGlvbnMuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkQ29uc3RydWN0aW9uIHwgdW5kZWZpbmVkfSBJbnZhbGlkIGNvbnN0cnVjdGlvbiB3aGVuIHByZXNlbnQuXG4gKi9cbmZ1bmN0aW9uIGZpbmRUeXBlT25seVZhbHVlQ29uc3RydWN0aW9uKG1vZHVsZSwgdHlwZU9ubHlEZWNsYXJhdGlvbklkcykge1xuICBpZiAodHlwZU9ubHlEZWNsYXJhdGlvbklkcy5zaXplID09IDApIHJldHVybiB1bmRlZmluZWRcbiAgY29uc3Qgc2VlbiA9IG5ldyBXZWFrU2V0KClcblxuICAvKipcbiAgICogVmlzaXRzIG9uZSBzZW1hbnRpYyB2YWx1ZS5cbiAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSBzZW1hbnRpYyBzdWJ0cmVlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkQ29uc3RydWN0aW9uIHwgdW5kZWZpbmVkfSBJbnZhbGlkIGNvbnN0cnVjdGlvbiB3aGVuIHByZXNlbnQuXG4gICAqL1xuICBmdW5jdGlvbiB2aXNpdCh2YWx1ZSkge1xuICAgIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9IFwib2JqZWN0XCIgfHwgc2Vlbi5oYXModmFsdWUpKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgc2Vlbi5hZGQodmFsdWUpXG4gICAgY29uc3Qgb2JqZWN0ID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gKi8gKHZhbHVlKVxuXG4gICAgaWYgKG9iamVjdC5raW5kID09IFwiUmVjb3JkQ29uc3RydWN0aW9uXCIgJiYgaXNQbGFpbk9iamVjdChvYmplY3QucmVjb3JkKSAmJlxuICAgICAgdHlwZW9mIG9iamVjdC5yZWNvcmQuZGVjbGFyYXRpb25JZCA9PSBcInN0cmluZ1wiICYmIHR5cGVPbmx5RGVjbGFyYXRpb25JZHMuaGFzKG9iamVjdC5yZWNvcmQuZGVjbGFyYXRpb25JZCkpIHtcbiAgICAgIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZENvbnN0cnVjdGlvbn0gKi8gKHZhbHVlKVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIE9iamVjdC52YWx1ZXMob2JqZWN0KSkge1xuICAgICAgY29uc3QgZm91bmQgPSB2aXNpdChjaGlsZClcblxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cblxuICByZXR1cm4gdmlzaXQoe2VudHJ5UG9pbnQ6IG1vZHVsZS5lbnRyeVBvaW50LCBmdW5jdGlvbnM6IG1vZHVsZS5mdW5jdGlvbnN9KVxufVxuXG4vKipcbiAqIFBsYW5zIGFsbCBwYXRocyBiZWZvcmUgZW1pc3Npb24gYW5kIHJlamVjdHMgZXhhY3QvY2FzZS9maWxlLWRpcmVjdG9yeSBjb2xsaXNpb25zLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW19IHByb2dyYW0gLSBWYWxpZGF0ZWQgcHJvZ3JhbS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge1N0ZGxpYlByb2dyYW1MaW5raW5nIHwgbnVsbH0gW2xpbmtpbmddIC0gUGxhbm5lZCBzdGRsaWIgcHJvdmlkZXIgbGluay5cbiAqIEByZXR1cm5zIHtNYXA8c3RyaW5nLCBzdHJpbmc+fSBQYXRoIGJ5IG1vZHVsZSBpZGVudGl0eS5cbiAqL1xuZnVuY3Rpb24gcGxhbk1vZHVsZVBhdGhzKHByb2dyYW0sIGxhbmd1YWdlLCBsaW5raW5nID0gbnVsbCkge1xuICBjb25zdCBleHRlbnNpb24gPSBsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIiA/IFwiLmpzXCIgOiBsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIiA/IFwiLnRzXCIgOiBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IFwiLnJiXCIgOlxuICAgIGxhbmd1YWdlID09IFwicGhwXCIgPyBcIi5waHBcIiA6IFwiLmphdmFcIlxuICBjb25zdCBwYXRocyA9IG5ldyBNYXAoKVxuICBjb25zdCBmb2xkZWQgPSBuZXcgU2V0KClcbiAgY29uc3QgdGFyZ2V0TW9kdWxlTmFtZXMgPSBuZXcgU2V0KClcbiAgY29uc3QgcHJvdmlkZXJQYXRocyA9IGxpbmtpbmcgPyBsaW5raW5nLm5lZ290aWF0aW9uLnByb3ZpZGVycy5tYXAoKHttb2R1bGV9KSA9PlxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc3RkbGliLXByb3ZpZGVycy5qc1wiKS5TdGRsaWJQcm92aWRlclJlY29yZH0gKi8gKGxpbmtpbmcucmVjb3Jkcy5nZXQobW9kdWxlKSkuYXJ0aWZhY3QucGF0aCkgOiBbXVxuICBjb25zdCBmb2xkZWRQcm92aWRlcnMgPSBuZXcgTWFwKClcblxuICBmb3IgKGNvbnN0IHByb3ZpZGVyUGF0aCBvZiBwcm92aWRlclBhdGhzKSB7XG4gICAgY29uc3Qga2V5ID0gcHJvdmlkZXJQYXRoLnRvTG9jYWxlTG93ZXJDYXNlKFwiZW4tVVNcIilcblxuICAgIGlmICghaXNTYWZlQXJ0aWZhY3RQYXRoKHByb3ZpZGVyUGF0aCkgfHwgZm9sZGVkLmhhcyhrZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlNURExJQl9OQU1FX0NPTExJU0lPTlwiLCBsYW5ndWFnZSxcbiAgICAgICAgbWVzc2FnZTogYFN0ZGxpYiBwcm92aWRlciBhcnRpZmFjdCBwYXRoICcke3Byb3ZpZGVyUGF0aH0nIGlzIHVuc2FmZSBvciBjb2xsaWRpbmcuYH0pXG4gICAgfVxuICAgIGZvbGRlZC5hZGQoa2V5KVxuICAgIGZvbGRlZFByb3ZpZGVycy5zZXQocHJvdmlkZXJQYXRoLnRvTG9jYWxlTG93ZXJDYXNlKFwiZW4tVVNcIikucmVwbGFjZUFsbChcIi5cIiwgXCIvXCIpLCBwcm92aWRlclBhdGgpXG4gIH1cblxuICBmb3IgKGNvbnN0IG1vZHVsZSBvZiBwcm9ncmFtLm1vZHVsZXMpIHtcbiAgICBsZXQgcGF0aCA9IGAke21vZHVsZS5pZC5yZXBsYWNlQWxsKFwiLlwiLCBcIi9cIil9JHtleHRlbnNpb259YFxuICAgIGNvbnN0IHByb3ZpZGVyUGF0aCA9IGZvbGRlZFByb3ZpZGVycy5nZXQocGF0aC50b0xvY2FsZUxvd2VyQ2FzZShcImVuLVVTXCIpLnJlcGxhY2VBbGwoXCIuXCIsIFwiL1wiKSlcblxuICAgIGlmIChwcm92aWRlclBhdGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7XG4gICAgICAgIGNvZGU6IFwiU1RETElCX05BTUVfQ09MTElTSU9OXCIsXG4gICAgICAgIGxhbmd1YWdlLFxuICAgICAgICBtZXNzYWdlOiBgTW9kdWxlIHBhdGggJyR7cGF0aH0nIGNvbGxpZGVzIHdpdGggdGhlIHN0ZGxpYiBwcm92aWRlciBhcnRpZmFjdCAnJHtwcm92aWRlclBhdGh9Jy5gXG4gICAgICB9KVxuICAgIH1cbiAgICBjb25zdCB0YXJnZXRNb2R1bGVOYW1lID0gbW9kdWxlQ2xhc3NOYW1lKG1vZHVsZS5pZClcblxuICAgIGlmIChsYW5ndWFnZSA9PSBcInBocFwiIHx8IGxhbmd1YWdlID09IFwicnVieVwiKSB7XG4gICAgICBjb25zdCBrZXkgPSBsYW5ndWFnZSA9PSBcInBocFwiID8gdGFyZ2V0TW9kdWxlTmFtZS50b0xvY2FsZUxvd2VyQ2FzZShcImVuLVVTXCIpIDogdGFyZ2V0TW9kdWxlTmFtZVxuXG4gICAgICBpZiAodGFyZ2V0TW9kdWxlTmFtZXMuaGFzKGtleSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgdGFyZ2V0IG1vZHVsZS1uYW1lIGNvbGxpc2lvbiAnJHt0YXJnZXRNb2R1bGVOYW1lfSdgLCBtb2R1bGUubG9jYXRpb24pXG4gICAgICB9XG4gICAgICB0YXJnZXRNb2R1bGVOYW1lcy5hZGQoa2V5KVxuICAgIH1cblxuICAgIGlmIChsYW5ndWFnZSA9PSBcInBocFwiKSB7XG4gICAgICB2YWxpZGF0ZVRhcmdldElkZW50aWZpZXIobGFuZ3VhZ2UsIHRhcmdldE1vZHVsZU5hbWUsIFwibW9kdWxlXCIsIG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIHZhbGlkYXRlVGFyZ2V0VHlwZUlkZW50aWZpZXIobGFuZ3VhZ2UsIHRhcmdldE1vZHVsZU5hbWUsIG1vZHVsZS5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKGxhbmd1YWdlID09IFwicnVieVwiKSB2YWxpZGF0ZVRhcmdldFR5cGVJZGVudGlmaWVyKGxhbmd1YWdlLCB0YXJnZXRNb2R1bGVOYW1lLCBtb2R1bGUubG9jYXRpb24pXG5cbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhXCIpIHtcbiAgICAgIGZvciAoY29uc3Qgc2VnbWVudCBvZiBtb2R1bGUuaWQuc3BsaXQoXCIuXCIpKSB2YWxpZGF0ZVRhcmdldElkZW50aWZpZXIobGFuZ3VhZ2UsIHNlZ21lbnQsIFwibW9kdWxlXCIsIG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIGNvbnN0IG5vbWluYWxDb3VudCA9IChtb2R1bGUucmVjb3Jkcz8ubGVuZ3RoID8/IDApICsgKG1vZHVsZS5jbGFzc2VzPy5sZW5ndGggPz8gMCkgKyAobW9kdWxlLmVycm9ycz8ubGVuZ3RoID8/IDApXG5cbiAgICAgIGlmIChtb2R1bGUuaWQuaW5jbHVkZXMoXCItXCIpIHx8IG5vbWluYWxDb3VudCA+IDEgfHxcbiAgICAgICAgbm9taW5hbENvdW50ID4gMCAmJiAobW9kdWxlLmZ1bmN0aW9ucy5sZW5ndGggPiAwIHx8IG1vZHVsZS5lbnRyeVBvaW50KSkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiSmF2YSBtb2R1bGUgbGF5b3V0IHJlcXVpcmluZyBtdWx0aXBsZSBwdWJsaWMgZGVjbGFyYXRpb25zIGluIG9uZSBzZW1hbnRpYyBtb2R1bGVcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY29uc3QgY2xhc3NOYW1lID0gbW9kdWxlLnJlY29yZHM/LlswXT8ubmFtZSA/PyBtb2R1bGUuY2xhc3Nlcz8uWzBdPy5uYW1lID8/IG1vZHVsZS5lcnJvcnM/LlswXT8ubmFtZSA/P1xuICAgICAgICAobW9kdWxlLmlkID09IHByb2dyYW0uZW50cnlNb2R1bGUgPyBcIk1haW5cIiA6IHRhcmdldE1vZHVsZU5hbWUpXG5cbiAgICAgIGlmICghL15bQS1aYS16XyRdW0EtWmEtejAtOV8kXSokL3UudGVzdChjbGFzc05hbWUpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGludmFsaWQgSmF2YSBwdWJsaWMgY2xhc3MgbmFtZSAnJHtjbGFzc05hbWV9J2AsIG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGlmIChtb2R1bGUuaWQgIT0gcHJvZ3JhbS5lbnRyeU1vZHVsZSkgdmFsaWRhdGVUYXJnZXRUeXBlSWRlbnRpZmllcihsYW5ndWFnZSwgY2xhc3NOYW1lLCBtb2R1bGUubG9jYXRpb24pXG4gICAgICBwYXRoID0gYHNlbWFudGlmb2xkL2dlbmVyYXRlZC8ke21vZHVsZS5pZC5yZXBsYWNlQWxsKFwiLlwiLCBcIi9cIil9LyR7Y2xhc3NOYW1lfS5qYXZhYFxuICAgIH1cbiAgICBjb25zdCBrZXkgPSBwYXRoLnRvTG9jYWxlTG93ZXJDYXNlKFwiZW4tVVNcIilcblxuICAgIGlmICghaXNTYWZlQXJ0aWZhY3RQYXRoKHBhdGgpIHx8IGZvbGRlZC5oYXMoa2V5KSkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgdW5zYWZlIG9yIGNvbGxpZGluZyB0YXJnZXQgcGF0aCAnJHtwYXRofSdgLCBtb2R1bGUubG9jYXRpb24pXG4gICAgZm9sZGVkLmFkZChrZXkpXG4gICAgcGF0aHMuc2V0KG1vZHVsZS5pZCwgcGF0aClcbiAgfVxuXG4gIHJldHVybiBwYXRoc1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgbG9naWNhbCBtb2R1bGUgaWRlbnRpdHkgdG8gaXRzIGNhbm9uaWNhbCB0YXJnZXQgdHlwZSBzZWdtZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IGlkIC0gTG9naWNhbCBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUYXJnZXQgY2xhc3MgbmFtZS5cbiAqL1xuZnVuY3Rpb24gbW9kdWxlQ2xhc3NOYW1lKGlkKSB7XG4gIHJldHVybiBpZC5zcGxpdCgvWy5fLV0rL3UpLm1hcCgocGFydCkgPT4gYCR7cGFydFswXS50b1VwcGVyQ2FzZSgpfSR7cGFydC5zbGljZSgxKX1gKS5qb2luKFwiXCIpXG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBhIGRlY2xhcmF0aW9uIG9yIGJpbmRpbmcgbmFtZSBmb3IgdGFyZ2V0IGNvbGxpc2lvbiBjaGVja3MuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0LlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBOYW1lLlxuICogQHJldHVybnMge3N0cmluZ30gQ29sbGlzaW9uIGtleS5cbiAqL1xuZnVuY3Rpb24gdGFyZ2V0TmFtZShsYW5ndWFnZSwgbmFtZSkge1xuICByZXR1cm4gbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IG5hbWUudG9Mb2NhbGVMb3dlckNhc2UoXCJlbi1VU1wiKSA6IG5hbWVcbn1cblxuLyoqXG4gKiBSZXBvcnRzIHdoZXRoZXIgYSBjYW5kaWRhdGUgaXMgYSBkaXJlY3QgcGxhaW4gb2JqZWN0LlxuICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIHt2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gV2hldGhlciB0aGUgdmFsdWUgaXMgYSBwbGFpbiBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3QodmFsdWUpIHtcbiAgcmV0dXJuIEJvb2xlYW4odmFsdWUpICYmIHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsdWUpID09IE9iamVjdC5wcm90b3R5cGVcbn1cblxuLyoqXG4gKiBSYWlzZXMgYSBzdGFibGUgbWFsZm9ybWVkIHByb2dyYW0tZ2VuZXJhdGlvbiByZXF1ZXN0IGRpYWdub3N0aWMuXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIFN0YWJsZSBmYWlsdXJlLlxuICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICovXG5mdW5jdGlvbiBpbnZhbGlkUHJvZ3JhbUdlbmVyYXRpb24obWVzc2FnZSkge1xuICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIklOVkFMSURfUFJPR1JBTVwiLCBsYW5ndWFnZTogXCJwcm9ncmFtXCIsIG1lc3NhZ2V9KVxufVxuIl19
|