ts2famix 2.1.0-beta.2 → 3.1.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/.eslintrc.json +24 -24
- package/LICENSE +24 -24
- package/README.md +78 -78
- package/dist/analyze.js +3 -3
- package/dist/analyze_functions/process_functions.js +92 -62
- package/dist/famix_functions/EntityDictionary.js +674 -599
- package/dist/famix_functions/helpers_creation.js +18 -12
- package/dist/fqn.js +351 -18
- package/dist/lib/famix/famix_JSON_exporter.js +1 -1
- package/dist/lib/famix/famix_base_element.js +1 -1
- package/dist/lib/famix/famix_repository.js +14 -5
- package/dist/lib/famix/index.js +1 -1
- package/dist/lib/famix/model/famix/access.js +1 -1
- package/dist/lib/famix/model/famix/accessor.js +1 -1
- package/dist/lib/famix/model/famix/alias.js +1 -1
- package/dist/lib/famix/model/famix/arrow_function.js +1 -1
- package/dist/lib/famix/model/famix/behavioral_entity.js +1 -1
- package/dist/lib/famix/model/famix/class.js +1 -1
- package/dist/lib/famix/model/famix/comment.js +1 -1
- package/dist/lib/famix/model/famix/concretisation.js +1 -1
- package/dist/lib/famix/model/famix/container_entity.js +1 -1
- package/dist/lib/famix/model/famix/decorator.js +1 -1
- package/dist/lib/famix/model/famix/entity.js +1 -1
- package/dist/lib/famix/model/famix/enum.js +1 -1
- package/dist/lib/famix/model/famix/enum_value.js +1 -1
- package/dist/lib/famix/model/famix/function.js +1 -1
- package/dist/lib/famix/model/famix/import_clause.js +1 -1
- package/dist/lib/famix/model/famix/index.js +1 -1
- package/dist/lib/famix/model/famix/indexed_file_anchor.js +1 -1
- package/dist/lib/famix/model/famix/inheritance.js +1 -1
- package/dist/lib/famix/model/famix/interface.js +1 -1
- package/dist/lib/famix/model/famix/invocation.js +1 -1
- package/dist/lib/famix/model/famix/method.js +1 -1
- package/dist/lib/famix/model/famix/module.js +2 -2
- package/dist/lib/famix/model/famix/named_entity.js +1 -1
- package/dist/lib/famix/model/famix/parameter.js +1 -1
- package/dist/lib/famix/model/famix/parameter_concretisation.js +1 -1
- package/dist/lib/famix/model/famix/parameter_type.js +1 -1
- package/dist/lib/famix/model/famix/parametric_arrow_function.js +1 -1
- package/dist/lib/famix/model/famix/parametric_class.js +1 -1
- package/dist/lib/famix/model/famix/parametric_function.js +1 -1
- package/dist/lib/famix/model/famix/parametric_interface.js +1 -1
- package/dist/lib/famix/model/famix/parametric_method.js +1 -1
- package/dist/lib/famix/model/famix/primitive_type.js +1 -1
- package/dist/lib/famix/model/famix/property.js +1 -1
- package/dist/lib/famix/model/famix/reference.js +1 -1
- package/dist/lib/famix/model/famix/scoping_entity.js +1 -1
- package/dist/lib/famix/model/famix/script_entity.js +1 -1
- package/dist/lib/famix/model/famix/source_anchor.js +1 -1
- package/dist/lib/famix/model/famix/source_language.js +1 -1
- package/dist/lib/famix/model/famix/sourced_entity.js +1 -1
- package/dist/lib/famix/model/famix/structural_entity.js +1 -1
- package/dist/lib/famix/model/famix/type.js +1 -1
- package/dist/lib/famix/model/famix/variable.js +1 -1
- package/dist/lib/ts-complex/cyclomatic-service.js +1 -1
- package/dist/refactorer/refactor-getter-setter.js +1 -1
- package/dist/ts2famix-cli-wrapper.js +1 -1
- package/dist/ts2famix-cli.js +3 -1
- package/doc-uml/famix-typescript-model.puml +619 -607
- package/doc-uml/famix-typescript-model.svg +1 -1
- package/eslint.config.mjs +28 -28
- package/jest.config.json +1 -1
- package/package.json +70 -70
- package/src/analyze.ts +120 -120
- package/src/analyze_functions/process_functions.ts +1069 -1040
- package/src/famix_functions/EntityDictionary.ts +2061 -2016
- package/src/famix_functions/helpers_creation.ts +143 -135
- package/src/fqn.ts +416 -50
- package/src/generate_uml.sh +20 -20
- package/src/lib/famix/License.md +22 -22
- package/src/lib/famix/famix_JSON_exporter.ts +56 -56
- package/src/lib/famix/famix_base_element.ts +22 -22
- package/src/lib/famix/famix_repository.ts +288 -278
- package/src/lib/famix/index.ts +8 -8
- package/src/lib/famix/model/famix/access.ts +50 -50
- package/src/lib/famix/model/famix/accessor.ts +15 -15
- package/src/lib/famix/model/famix/alias.ts +39 -39
- package/src/lib/famix/model/famix/arrow_function.ts +15 -15
- package/src/lib/famix/model/famix/behavioral_entity.ts +97 -97
- package/src/lib/famix/model/famix/class.ts +85 -85
- package/src/lib/famix/model/famix/comment.ts +47 -47
- package/src/lib/famix/model/famix/concretisation.ts +40 -40
- package/src/lib/famix/model/famix/container_entity.ts +160 -160
- package/src/lib/famix/model/famix/decorator.ts +37 -37
- package/src/lib/famix/model/famix/entity.ts +15 -15
- package/src/lib/famix/model/famix/enum.ts +30 -30
- package/src/lib/famix/model/famix/enum_value.ts +28 -28
- package/src/lib/famix/model/famix/function.ts +15 -15
- package/src/lib/famix/model/famix/import_clause.ts +51 -51
- package/src/lib/famix/model/famix/index.ts +41 -41
- package/src/lib/famix/model/famix/indexed_file_anchor.ts +46 -46
- package/src/lib/famix/model/famix/inheritance.ts +40 -40
- package/src/lib/famix/model/famix/interface.ts +75 -75
- package/src/lib/famix/model/famix/invocation.ts +65 -65
- package/src/lib/famix/model/famix/method.ts +89 -89
- package/src/lib/famix/model/famix/module.ts +71 -71
- package/src/lib/famix/model/famix/named_entity.ts +95 -95
- package/src/lib/famix/model/famix/parameter.ts +28 -28
- package/src/lib/famix/model/famix/parameter_concretisation.ts +51 -51
- package/src/lib/famix/model/famix/parameter_type.ts +58 -58
- package/src/lib/famix/model/famix/parametric_arrow_function.ts +32 -32
- package/src/lib/famix/model/famix/parametric_class.ts +49 -49
- package/src/lib/famix/model/famix/parametric_function.ts +32 -32
- package/src/lib/famix/model/famix/parametric_interface.ts +49 -49
- package/src/lib/famix/model/famix/parametric_method.ts +32 -32
- package/src/lib/famix/model/famix/primitive_type.ts +15 -15
- package/src/lib/famix/model/famix/property.ts +94 -94
- package/src/lib/famix/model/famix/reference.ts +40 -40
- package/src/lib/famix/model/famix/scoping_entity.ts +35 -35
- package/src/lib/famix/model/famix/script_entity.ts +34 -34
- package/src/lib/famix/model/famix/source_anchor.ts +30 -30
- package/src/lib/famix/model/famix/source_language.ts +35 -35
- package/src/lib/famix/model/famix/sourced_entity.ts +70 -70
- package/src/lib/famix/model/famix/structural_entity.ts +43 -43
- package/src/lib/famix/model/famix/type.ts +87 -87
- package/src/lib/famix/model/famix/variable.ts +27 -27
- package/src/lib/famix/package.json +28 -28
- package/src/lib/ts-complex/cyclomatic-service.ts +83 -83
- package/src/refactorer/refactor-getter-setter.ts +140 -140
- package/src/ts2famix-cli-wrapper.ts +21 -21
- package/src/ts2famix-cli.ts +62 -60
- package/tsconfig.check-tests.json +14 -14
- package/tsconfig.json +73 -72
- package/.vscode/settings.json +0 -4
- package/TODO +0 -1
- package/arwea-fix.json +0 -1
- package/bogus.ts +0 -3
- package/class-diagram.puml +0 -792
- package/debug.txt +0 -13332
- package/debuglog.txt +0 -12073
- package/dist/famix2puml.js +0 -126
- package/dist/getClasses-arrow-body.js +0 -43
- package/dist/lib/famix/src/famix_JSON_exporter.js +0 -55
- package/dist/lib/famix/src/famix_base_element.js +0 -18
- package/dist/lib/famix/src/famix_repository.js +0 -224
- package/dist/lib/famix/src/index.js +0 -31
- package/dist/lib/famix/src/model/famix/access.js +0 -40
- package/dist/lib/famix/src/model/famix/accessor.js +0 -17
- package/dist/lib/famix/src/model/famix/alias.js +0 -33
- package/dist/lib/famix/src/model/famix/arrowFunction.js +0 -17
- package/dist/lib/famix/src/model/famix/arrow_function.js +0 -17
- package/dist/lib/famix/src/model/famix/behavioral_entity.js +0 -79
- package/dist/lib/famix/src/model/famix/class.js +0 -71
- package/dist/lib/famix/src/model/famix/comment.js +0 -39
- package/dist/lib/famix/src/model/famix/concretisation.js +0 -31
- package/dist/lib/famix/src/model/famix/container_entity.js +0 -126
- package/dist/lib/famix/src/model/famix/decorator.js +0 -32
- package/dist/lib/famix/src/model/famix/entity.js +0 -17
- package/dist/lib/famix/src/model/famix/enum.js +0 -31
- package/dist/lib/famix/src/model/famix/enum_value.js +0 -25
- package/dist/lib/famix/src/model/famix/function.js +0 -17
- package/dist/lib/famix/src/model/famix/implicit_variable.js +0 -17
- package/dist/lib/famix/src/model/famix/import_clause.js +0 -41
- package/dist/lib/famix/src/model/famix/index.js +0 -86
- package/dist/lib/famix/src/model/famix/indexed_file_anchor.js +0 -38
- package/dist/lib/famix/src/model/famix/inheritance.js +0 -33
- package/dist/lib/famix/src/model/famix/interface.js +0 -64
- package/dist/lib/famix/src/model/famix/invocation.js +0 -54
- package/dist/lib/famix/src/model/famix/method.js +0 -67
- package/dist/lib/famix/src/model/famix/module.js +0 -60
- package/dist/lib/famix/src/model/famix/named_entity.js +0 -78
- package/dist/lib/famix/src/model/famix/parameter.js +0 -25
- package/dist/lib/famix/src/model/famix/parameterConcretisation.js +0 -44
- package/dist/lib/famix/src/model/famix/parameter_concretisation.js +0 -44
- package/dist/lib/famix/src/model/famix/parameter_type.js +0 -45
- package/dist/lib/famix/src/model/famix/parametricArrowFunction.js +0 -29
- package/dist/lib/famix/src/model/famix/parametric_arrow_function.js +0 -31
- package/dist/lib/famix/src/model/famix/parametric_class.js +0 -44
- package/dist/lib/famix/src/model/famix/parametric_function.js +0 -31
- package/dist/lib/famix/src/model/famix/parametric_interface.js +0 -44
- package/dist/lib/famix/src/model/famix/parametric_method.js +0 -31
- package/dist/lib/famix/src/model/famix/primitive_type.js +0 -17
- package/dist/lib/famix/src/model/famix/property.js +0 -73
- package/dist/lib/famix/src/model/famix/reference.js +0 -33
- package/dist/lib/famix/src/model/famix/scoping_entity.js +0 -36
- package/dist/lib/famix/src/model/famix/script_entity.js +0 -29
- package/dist/lib/famix/src/model/famix/source_anchor.js +0 -27
- package/dist/lib/famix/src/model/famix/source_language.js +0 -35
- package/dist/lib/famix/src/model/famix/sourced_entity.js +0 -60
- package/dist/lib/famix/src/model/famix/structural_entity.js +0 -39
- package/dist/lib/famix/src/model/famix/text_anchor.js +0 -38
- package/dist/lib/famix/src/model/famix/type.js +0 -73
- package/dist/lib/famix/src/model/famix/variable.js +0 -24
- package/fqn-model.json +0 -1
- package/iterateGenericTypes.ts +0 -69
- package/out/class-diagram/class-diagram.svg +0 -1
- package/sample.json +0 -1
- package/sample.ts +0 -1
- package/stats.txt +0 -3091
- package/tabby-debug-output.txt +0 -19433
- package/ts2famix.log +0 -22656
- package/validate-references.js +0 -103
package/dist/fqn.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.getFQN = getFQN;
|
|
|
7
7
|
exports.getUniqueFQN = getUniqueFQN;
|
|
8
8
|
exports.getNameOfNode = getNameOfNode;
|
|
9
9
|
exports.getParameters = getParameters;
|
|
10
|
+
exports.getFQNUnresolvedInheritedClassOrInterface = getFQNUnresolvedInheritedClassOrInterface;
|
|
10
11
|
const ts_morph_1 = require("ts-morph");
|
|
11
12
|
const analyze_1 = require("./analyze");
|
|
12
13
|
const path_1 = __importDefault(require("path"));
|
|
@@ -14,11 +15,216 @@ const path_1 = __importDefault(require("path"));
|
|
|
14
15
|
function isFQNNode(node) {
|
|
15
16
|
return ts_morph_1.Node.isVariableDeclaration(node) || ts_morph_1.Node.isArrowFunction(node) || ts_morph_1.Node.isIdentifier(node) || ts_morph_1.Node.isMethodDeclaration(node) || ts_morph_1.Node.isClassDeclaration(node) || ts_morph_1.Node.isClassExpression(node) || ts_morph_1.Node.isDecorator(node) || ts_morph_1.Node.isModuleDeclaration(node) || ts_morph_1.Node.isCallExpression(node);
|
|
16
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Builds a map of method positions to their property keys in object literals.
|
|
20
|
+
* Scans all variable declarations in a source file, targeting object literals with any keys
|
|
21
|
+
* (e.g., `3: { method() {} }` or `add: { compute() {} }`), and maps each method's start position to its key.
|
|
22
|
+
* Logs each step for debugging.
|
|
23
|
+
*
|
|
24
|
+
* @param sourceFile The TypeScript source file to analyze
|
|
25
|
+
* @returns A Map where keys are method start positions and values are their property keys (e.g., "3", "add")
|
|
26
|
+
*/
|
|
27
|
+
function buildStageMethodMap(sourceFile) {
|
|
28
|
+
const stageMap = new Map();
|
|
29
|
+
sourceFile.getVariableDeclarations().forEach(varDecl => {
|
|
30
|
+
// const varName = varDecl.getName();
|
|
31
|
+
const initializer = varDecl.getInitializer();
|
|
32
|
+
if (!initializer || !ts_morph_1.Node.isObjectLiteralExpression(initializer)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
initializer.getProperties().forEach(prop => {
|
|
36
|
+
let key;
|
|
37
|
+
if (ts_morph_1.Node.isPropertyAssignment(prop)) {
|
|
38
|
+
const nameNode = prop.getNameNode();
|
|
39
|
+
if (ts_morph_1.Node.isIdentifier(nameNode)) {
|
|
40
|
+
key = nameNode.getText();
|
|
41
|
+
}
|
|
42
|
+
else if (ts_morph_1.Node.isStringLiteral(nameNode)) {
|
|
43
|
+
key = nameNode.getText().replace(/^"(.+)"$/, '$1').replace(/^'(.+)'$/, '$1');
|
|
44
|
+
}
|
|
45
|
+
else if (ts_morph_1.Node.isNumericLiteral(nameNode)) {
|
|
46
|
+
key = nameNode.getText();
|
|
47
|
+
}
|
|
48
|
+
else if (ts_morph_1.Node.isComputedPropertyName(nameNode)) {
|
|
49
|
+
const expression = nameNode.getExpression();
|
|
50
|
+
if (ts_morph_1.Node.isIdentifier(expression)) {
|
|
51
|
+
// Resolve variable value if possible
|
|
52
|
+
const symbol = expression.getSymbol();
|
|
53
|
+
if (symbol) {
|
|
54
|
+
const decl = symbol.getDeclarations()[0];
|
|
55
|
+
if (ts_morph_1.Node.isVariableDeclaration(decl) && decl.getInitializer()) {
|
|
56
|
+
const init = decl.getInitializer();
|
|
57
|
+
if (ts_morph_1.Node.isStringLiteral(init) || ts_morph_1.Node.isNumericLiteral(init)) {
|
|
58
|
+
key = init.getText().replace(/^"(.+)"$/, '$1').replace(/^'(.+)'$/, '$1');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!key) {
|
|
63
|
+
key = expression.getText();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (ts_morph_1.Node.isBinaryExpression(expression) && expression.getOperatorToken().getText() === '+') {
|
|
67
|
+
// Handle simple string concatenation (e.g., "A" + "B")
|
|
68
|
+
const left = expression.getLeft();
|
|
69
|
+
const right = expression.getRight();
|
|
70
|
+
if (ts_morph_1.Node.isStringLiteral(left) && ts_morph_1.Node.isStringLiteral(right)) {
|
|
71
|
+
key = left.getLiteralText() + right.getLiteralText();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (ts_morph_1.Node.isTemplateExpression(expression)) {
|
|
75
|
+
// Handle template literals (e.g., `key-${1}`)
|
|
76
|
+
const head = expression.getHead().getLiteralText();
|
|
77
|
+
const spans = expression.getTemplateSpans();
|
|
78
|
+
if (spans.length === 1 && ts_morph_1.Node.isNumericLiteral(spans[0].getExpression())) {
|
|
79
|
+
const num = spans[0].getExpression().getText();
|
|
80
|
+
key = `${head}${num}`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (!key) {
|
|
84
|
+
key = expression.getText(); // Fallback
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const propInitializer = prop.getInitializer();
|
|
91
|
+
if (propInitializer && ts_morph_1.Node.isObjectLiteralExpression(propInitializer)) {
|
|
92
|
+
propInitializer.getDescendantsOfKind(ts_morph_1.SyntaxKind.MethodDeclaration).forEach(method => {
|
|
93
|
+
// const methodName = method.getName();
|
|
94
|
+
const pos = method.getStart();
|
|
95
|
+
if (key) {
|
|
96
|
+
stageMap.set(pos, key);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
return stageMap;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Builds a map of method positions to their index in class/interface/namespace declarations
|
|
107
|
+
* @param sourceFile The TypeScript source file to analyze
|
|
108
|
+
* @returns A Map where keys are method start positions and values are their positional index (1-based)
|
|
109
|
+
*/
|
|
110
|
+
function buildMethodPositionMap(sourceFile) {
|
|
111
|
+
const positionMap = new Map();
|
|
112
|
+
// console.log(`[buildMethodPositionMap] Starting analysis for file: ${sourceFile.getFilePath()}`);
|
|
113
|
+
// Helper function to process modules recursively
|
|
114
|
+
function processModule(moduleNode, modulePath) {
|
|
115
|
+
// console.log(`[buildMethodPositionMap] Processing module: ${modulePath}`);
|
|
116
|
+
// Handle functions directly in the module
|
|
117
|
+
const functions = moduleNode.getFunctions();
|
|
118
|
+
const functionCounts = new Map();
|
|
119
|
+
functions.forEach(func => {
|
|
120
|
+
const funcName = func.getName() || `Unnamed_Function(${func.getStart()})`;
|
|
121
|
+
const count = (functionCounts.get(funcName) || 0) + 1;
|
|
122
|
+
functionCounts.set(funcName, count);
|
|
123
|
+
positionMap.set(func.getStart(), count);
|
|
124
|
+
// console.log(`[buildMethodPositionMap] Module function: ${funcName}, position: ${func.getStart()}, index: ${count}`);
|
|
125
|
+
});
|
|
126
|
+
// Handle classes within the module
|
|
127
|
+
const classes = moduleNode.getClasses();
|
|
128
|
+
classes.forEach(classNode => {
|
|
129
|
+
// console.log(`[buildMethodPositionMap] Processing class in module: ${classNode.getName() || 'Unnamed'}`);
|
|
130
|
+
const methods = classNode.getMethods();
|
|
131
|
+
const methodCounts = new Map();
|
|
132
|
+
methods.forEach(method => {
|
|
133
|
+
const methodName = method.getName();
|
|
134
|
+
const count = (methodCounts.get(methodName) || 0) + 1;
|
|
135
|
+
methodCounts.set(methodName, count);
|
|
136
|
+
positionMap.set(method.getStart(), count);
|
|
137
|
+
// console.log(`[buildMethodPositionMap] Module class method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
// Handle interfaces within the module
|
|
141
|
+
const interfaces = moduleNode.getInterfaces();
|
|
142
|
+
interfaces.forEach(interfaceNode => {
|
|
143
|
+
// console.log(`[buildMethodPositionMap] Processing interface in module: ${interfaceNode.getName() || 'Unnamed'}`);
|
|
144
|
+
const methods = interfaceNode.getMethods();
|
|
145
|
+
const methodCounts = new Map();
|
|
146
|
+
methods.forEach(method => {
|
|
147
|
+
const methodName = method.getName();
|
|
148
|
+
const count = (methodCounts.get(methodName) || 0) + 1;
|
|
149
|
+
methodCounts.set(methodName, count);
|
|
150
|
+
positionMap.set(method.getStart(), count);
|
|
151
|
+
// console.log(`[buildMethodPositionMap] Module interface method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
// Recursively process nested modules
|
|
155
|
+
const nestedModules = moduleNode.getModules();
|
|
156
|
+
nestedModules.forEach(nestedModule => {
|
|
157
|
+
if (ts_morph_1.Node.isModuleDeclaration(nestedModule)) {
|
|
158
|
+
const nestedModuleName = nestedModule.getName();
|
|
159
|
+
const newModulePath = `${modulePath}.${nestedModuleName}`;
|
|
160
|
+
processModule(nestedModule, newModulePath);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function trackArrowFunctions(container) {
|
|
165
|
+
const arrows = container.getDescendantsOfKind(ts_morph_1.SyntaxKind.ArrowFunction);
|
|
166
|
+
arrows.forEach(arrow => {
|
|
167
|
+
const parent = arrow.getParent();
|
|
168
|
+
if (ts_morph_1.Node.isBlock(parent) || ts_morph_1.Node.isSourceFile(parent)) {
|
|
169
|
+
// Use negative numbers for arrow functions to distinguish from methods
|
|
170
|
+
positionMap.set(arrow.getStart(), -1 * (positionMap.size + 1));
|
|
171
|
+
// console.log(`[buildMethodPositionMap] Arrow function at ${arrow.getStart()}`);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
// Handle top-level classes
|
|
176
|
+
sourceFile.getClasses().forEach(classNode => {
|
|
177
|
+
// console.log(`[buildMethodPositionMap] Processing class: ${classNode.getName() || 'Unnamed'}`);
|
|
178
|
+
const methods = classNode.getMethods();
|
|
179
|
+
const methodCounts = new Map();
|
|
180
|
+
methods.forEach(method => {
|
|
181
|
+
const methodName = method.getName();
|
|
182
|
+
const count = (methodCounts.get(methodName) || 0) + 1;
|
|
183
|
+
methodCounts.set(methodName, count);
|
|
184
|
+
positionMap.set(method.getStart(), count);
|
|
185
|
+
// console.log(`[buildMethodPositionMap] Class method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
|
|
186
|
+
});
|
|
187
|
+
methods.forEach(method => trackArrowFunctions(method));
|
|
188
|
+
});
|
|
189
|
+
// Handle top-level interfaces
|
|
190
|
+
sourceFile.getInterfaces().forEach(interfaceNode => {
|
|
191
|
+
// console.log(`[buildMethodPositionMap] Processing interface: ${interfaceNode.getName() || 'Unnamed'}`);
|
|
192
|
+
const methods = interfaceNode.getMethods();
|
|
193
|
+
const methodCounts = new Map();
|
|
194
|
+
methods.forEach(method => {
|
|
195
|
+
const methodName = method.getName();
|
|
196
|
+
const count = (methodCounts.get(methodName) || 0) + 1;
|
|
197
|
+
methodCounts.set(methodName, count);
|
|
198
|
+
positionMap.set(method.getStart(), count);
|
|
199
|
+
// console.log(`[buildMethodPositionMap] Interface method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
|
|
200
|
+
});
|
|
201
|
+
methods.forEach(method => trackArrowFunctions(method));
|
|
202
|
+
});
|
|
203
|
+
// Handle top-level namespaces/modules
|
|
204
|
+
sourceFile.getModules().forEach(moduleNode => {
|
|
205
|
+
if (ts_morph_1.Node.isModuleDeclaration(moduleNode)) {
|
|
206
|
+
const moduleName = moduleNode.getName();
|
|
207
|
+
processModule(moduleNode, moduleName);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
// console.log(`[buildMethodPositionMap] Final positionMap:`, Array.from(positionMap.entries()));
|
|
211
|
+
return positionMap;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Generates a fully qualified name (FQN) for a given AST node.
|
|
215
|
+
* Constructs an FQN by traversing the node's ancestry, adding names and keys
|
|
216
|
+
* (numeric or string from object literals ...) as needed, prefixed with the file's relative path.
|
|
217
|
+
*
|
|
218
|
+
* @param node The AST node to generate an FQN for
|
|
219
|
+
* @returns A string representing the node's FQN (e.g., "{path}.operations.add.compute[MethodDeclaration]")
|
|
220
|
+
*/
|
|
17
221
|
function getFQN(node) {
|
|
18
|
-
const absolutePathProject = analyze_1.entityDictionary.famixRep.getAbsolutePath();
|
|
19
222
|
const sourceFile = node.getSourceFile();
|
|
223
|
+
const absolutePathProject = analyze_1.entityDictionary.famixRep.getAbsolutePath();
|
|
20
224
|
const parts = [];
|
|
21
225
|
let currentNode = node;
|
|
226
|
+
const stageMap = buildStageMethodMap(sourceFile);
|
|
227
|
+
const methodPositionMap = buildMethodPositionMap(sourceFile);
|
|
22
228
|
while (currentNode && !ts_morph_1.Node.isSourceFile(currentNode)) {
|
|
23
229
|
const { line, column } = sourceFile.getLineAndColumnAtPos(currentNode.getStart());
|
|
24
230
|
const lc = `${line}:${column}`;
|
|
@@ -31,7 +237,6 @@ function getFQN(node) {
|
|
|
31
237
|
ts_morph_1.Node.isVariableDeclaration(currentNode) ||
|
|
32
238
|
ts_morph_1.Node.isGetAccessorDeclaration(currentNode) ||
|
|
33
239
|
ts_morph_1.Node.isSetAccessorDeclaration(currentNode) ||
|
|
34
|
-
ts_morph_1.Node.isTypeParameterDeclaration(currentNode) ||
|
|
35
240
|
ts_morph_1.Node.isPropertyDeclaration(currentNode) ||
|
|
36
241
|
ts_morph_1.Node.isParameterDeclaration(currentNode) ||
|
|
37
242
|
ts_morph_1.Node.isDecorator(currentNode) ||
|
|
@@ -43,39 +248,113 @@ function getFQN(node) {
|
|
|
43
248
|
ts_morph_1.Node.isArrayLiteralExpression(currentNode) ||
|
|
44
249
|
ts_morph_1.Node.isImportSpecifier(currentNode) ||
|
|
45
250
|
ts_morph_1.Node.isIdentifier(currentNode)) {
|
|
46
|
-
|
|
47
|
-
|
|
251
|
+
let name;
|
|
252
|
+
if (ts_morph_1.Node.isImportSpecifier(currentNode)) {
|
|
253
|
+
const alias = currentNode.getAliasNode()?.getText();
|
|
254
|
+
if (alias) {
|
|
255
|
+
let importDecl = currentNode;
|
|
256
|
+
while (importDecl && !ts_morph_1.Node.isImportDeclaration(importDecl)) {
|
|
257
|
+
importDecl = importDecl.getParent();
|
|
258
|
+
}
|
|
259
|
+
const moduleSpecifier = importDecl && ts_morph_1.Node.isImportDeclaration(importDecl)
|
|
260
|
+
? importDecl.getModuleSpecifier().getLiteralText()
|
|
261
|
+
: "unknown";
|
|
262
|
+
name = currentNode.getName();
|
|
263
|
+
name = `${name} as ${alias}[ImportSpecifier<${moduleSpecifier}>]`;
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
name = currentNode.getName();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
// if constructor, use "constructor" as name
|
|
271
|
+
if (ts_morph_1.Node.isConstructorDeclaration(currentNode)) {
|
|
272
|
+
name = "constructor";
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
name = ts_morph_1.Node.isIdentifier(currentNode) ? currentNode.getText()
|
|
276
|
+
: 'getName' in currentNode && typeof currentNode['getName'] === 'function'
|
|
277
|
+
? (currentNode.getName() +
|
|
278
|
+
((ts_morph_1.Node.isClassDeclaration(currentNode) ||
|
|
279
|
+
ts_morph_1.Node.isInterfaceDeclaration(currentNode) ||
|
|
280
|
+
ts_morph_1.Node.isMethodDeclaration(currentNode) ||
|
|
281
|
+
ts_morph_1.Node.isFunctionDeclaration(currentNode)) &&
|
|
282
|
+
'getTypeParameters' in currentNode &&
|
|
283
|
+
currentNode.getTypeParameters().length > 0
|
|
284
|
+
? getParameters(currentNode)
|
|
285
|
+
: ''))
|
|
286
|
+
: `Unnamed_${currentNode.getKindName()}(${lc})`;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (ts_morph_1.Node.isMethodSignature(currentNode)) {
|
|
290
|
+
const method = currentNode;
|
|
291
|
+
const params = method.getParameters().map(p => {
|
|
292
|
+
const typeText = p.getType().getText().replace(/\s+/g, "");
|
|
293
|
+
return typeText || "any"; // Fallback for untyped parameters
|
|
294
|
+
});
|
|
295
|
+
const returnType = method.getReturnType().getText().replace(/\s+/g, "") || "void";
|
|
296
|
+
name = `${name}(${params.join(",")}):${returnType}`;
|
|
297
|
+
}
|
|
48
298
|
parts.unshift(name);
|
|
299
|
+
// Apply positional index for MethodDeclaration, MethodSignature, and FunctionDeclaration
|
|
300
|
+
if (ts_morph_1.Node.isMethodDeclaration(currentNode) ||
|
|
301
|
+
ts_morph_1.Node.isMethodSignature(currentNode) ||
|
|
302
|
+
ts_morph_1.Node.isFunctionDeclaration(currentNode)) {
|
|
303
|
+
const key = stageMap.get(currentNode.getStart());
|
|
304
|
+
if (key) {
|
|
305
|
+
parts.unshift(key);
|
|
306
|
+
// console.log(`[getFQN] Applied stageMap key: ${key} for ${currentNode.getKindName()} at position ${currentNode.getStart()}`);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
const positionIndex = methodPositionMap.get(currentNode.getStart());
|
|
310
|
+
if (positionIndex && positionIndex > 1) {
|
|
311
|
+
parts.unshift(positionIndex.toString());
|
|
312
|
+
// console.log(`[getFQN] Applied positionIndex: ${positionIndex} for ${currentNode.getKindName()} at position ${currentNode.getStart()}`);
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
console.log(`[getFQN] No positionIndex applied for ${currentNode.getKindName()} at position ${currentNode.getStart()}, positionIndex: ${positionIndex || 'none'}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
49
319
|
}
|
|
50
|
-
// unnamed nodes
|
|
51
320
|
else if (ts_morph_1.Node.isArrowFunction(currentNode) ||
|
|
52
321
|
ts_morph_1.Node.isBlock(currentNode) ||
|
|
53
322
|
ts_morph_1.Node.isForInStatement(currentNode) ||
|
|
54
323
|
ts_morph_1.Node.isForOfStatement(currentNode) ||
|
|
55
324
|
ts_morph_1.Node.isForStatement(currentNode) ||
|
|
56
325
|
ts_morph_1.Node.isCatchClause(currentNode)) {
|
|
57
|
-
|
|
326
|
+
const name = `${currentNode.getKindName()}(${lc})`;
|
|
327
|
+
parts.unshift(name);
|
|
328
|
+
}
|
|
329
|
+
else if (ts_morph_1.Node.isTypeParameterDeclaration(currentNode)) {
|
|
330
|
+
const arrowParent = currentNode.getFirstAncestorByKind(ts_morph_1.SyntaxKind.ArrowFunction);
|
|
331
|
+
if (arrowParent) {
|
|
332
|
+
const arrowIndex = Math.abs(methodPositionMap.get(arrowParent.getStart()) || 0);
|
|
333
|
+
if (arrowIndex > 0) {
|
|
334
|
+
parts.unshift(arrowIndex.toString());
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
parts.unshift(currentNode.getName());
|
|
338
|
+
// Removed continue to allow ancestor processing
|
|
58
339
|
}
|
|
59
340
|
else if (ts_morph_1.Node.isConstructorDeclaration(currentNode)) {
|
|
60
|
-
|
|
341
|
+
const name = "constructor";
|
|
342
|
+
parts.unshift(name);
|
|
61
343
|
}
|
|
62
344
|
else {
|
|
63
|
-
|
|
64
|
-
analyze_1.logger.debug(`Ignoring node kind: ${currentNode.getKindName()}`);
|
|
345
|
+
console.log(`[getFQN] Ignoring node kind: ${currentNode.getKindName()}`);
|
|
65
346
|
}
|
|
66
347
|
currentNode = currentNode.getParent();
|
|
67
348
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
analyze_1.logger.error(`Relative path contains ../: ${relativePath}`);
|
|
72
|
-
}
|
|
349
|
+
let relativePath = analyze_1.entityDictionary.convertToRelativePath(path_1.default.normalize(sourceFile.getFilePath()), absolutePathProject).replace(/\\/g, "/");
|
|
350
|
+
// if (relativePath.includes("..")) {
|
|
351
|
+
// }
|
|
73
352
|
if (relativePath.startsWith("/")) {
|
|
74
|
-
relativePath = relativePath.
|
|
353
|
+
relativePath = relativePath.slice(1);
|
|
75
354
|
}
|
|
76
355
|
parts.unshift(`{${relativePath}}`);
|
|
77
|
-
const fqn = parts.join(".") + `[${node.getKindName()}]`;
|
|
78
|
-
|
|
356
|
+
const fqn = parts.join(".") + `[${node.getKindName()}]`;
|
|
357
|
+
// console.log(`[getFQN] Final FQN: ${fqn}`);
|
|
79
358
|
return fqn;
|
|
80
359
|
}
|
|
81
360
|
function getUniqueFQN(node) {
|
|
@@ -216,4 +495,58 @@ function getParameters(a) {
|
|
|
216
495
|
}
|
|
217
496
|
return paramString;
|
|
218
497
|
}
|
|
219
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnFuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Zxbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVlBLHdCQXNFQztBQUdELG9DQTJCQztBQU9ELHNDQWlHQztBQU9ELHNDQW1CQztBQWxQRCx1Q0FBK2I7QUFDL2IsdUNBQXFEO0FBQ3JELGdEQUF3QjtBQUt4Qiw2REFBNkQ7QUFDN0QsU0FBUyxTQUFTLENBQUMsSUFBVTtJQUN6QixPQUFPLGVBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25TLENBQUM7QUFFRCxTQUFnQixNQUFNLENBQUMsSUFBb0I7SUFDdkMsTUFBTSxtQkFBbUIsR0FBRywwQkFBZ0IsQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUM7SUFFeEUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3hDLE1BQU0sS0FBSyxHQUFhLEVBQUUsQ0FBQztJQUMzQixJQUFJLFdBQVcsR0FBcUIsSUFBSSxDQUFDO0lBRXpDLE9BQU8sV0FBVyxJQUFJLENBQUMsZUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1FBQ3BELE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsVUFBVSxDQUFDLHFCQUFxQixDQUFD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biwgQ2xhc3NEZWNsYXJhdGlvbiwgQ29uc3RydWN0b3JEZWNsYXJhdGlvbiwgRGVjb3JhdG9yLCBFbnVtRGVjbGFyYXRpb24sIEZ1bmN0aW9uRGVjbGFyYXRpb24sIEZ1bmN0aW9uRXhwcmVzc2lvbiwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiwgSWRlbnRpZmllciwgSW1wb3J0RGVjbGFyYXRpb24sIEltcG9ydEVxdWFsc0RlY2xhcmF0aW9uLCBJbnRlcmZhY2VEZWNsYXJhdGlvbiwgTWV0aG9kRGVjbGFyYXRpb24sIE1ldGhvZFNpZ25hdHVyZSwgTW9kdWxlRGVjbGFyYXRpb24sIE5vZGUsIFByb3BlcnR5RGVjbGFyYXRpb24sIFNldEFjY2Vzc29yRGVjbGFyYXRpb24sIFNvdXJjZUZpbGUsIFN5bnRheEtpbmQsIFR5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbiwgVmFyaWFibGVEZWNsYXJhdGlvbiB9IGZyb20gXCJ0cy1tb3JwaFwiO1xyXG5pbXBvcnQgeyBlbnRpdHlEaWN0aW9uYXJ5LCBsb2dnZXIgfSBmcm9tIFwiLi9hbmFseXplXCI7XHJcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XHJcbmltcG9ydCB7IFRTTW9ycGhUeXBlRGVjbGFyYXRpb24gfSBmcm9tIFwiLi9mYW1peF9mdW5jdGlvbnMvRW50aXR5RGljdGlvbmFyeVwiO1xyXG5cclxudHlwZSBGUU5Ob2RlID0gU291cmNlRmlsZSB8IFZhcmlhYmxlRGVjbGFyYXRpb24gfCBBcnJvd0Z1bmN0aW9uIHwgSWRlbnRpZmllciB8IE1ldGhvZERlY2xhcmF0aW9uIHwgTWV0aG9kU2lnbmF0dXJlIHwgRnVuY3Rpb25EZWNsYXJhdGlvbiB8IEZ1bmN0aW9uRXhwcmVzc2lvbiB8IFByb3BlcnR5RGVjbGFyYXRpb24gfCBUU01vcnBoVHlwZURlY2xhcmF0aW9uIHwgRW51bURlY2xhcmF0aW9uIHwgSW1wb3J0RGVjbGFyYXRpb24gfCBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiB8IENhbGxFeHByZXNzaW9uIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uIHwgQ2xhc3NEZWNsYXJhdGlvbiB8IEludGVyZmFjZURlY2xhcmF0aW9uIHwgRGVjb3JhdG9yIHwgTW9kdWxlRGVjbGFyYXRpb247XHJcblxyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXHJcbmZ1bmN0aW9uIGlzRlFOTm9kZShub2RlOiBOb2RlKTogbm9kZSBpcyBGUU5Ob2RlIHtcclxuICAgIHJldHVybiBOb2RlLmlzVmFyaWFibGVEZWNsYXJhdGlvbihub2RlKSB8fCBOb2RlLmlzQXJyb3dGdW5jdGlvbihub2RlKSB8fCBOb2RlLmlzSWRlbnRpZmllcihub2RlKSB8fCBOb2RlLmlzTWV0aG9kRGVjbGFyYXRpb24obm9kZSkgfHwgTm9kZS5pc0NsYXNzRGVjbGFyYXRpb24obm9kZSkgfHwgTm9kZS5pc0NsYXNzRXhwcmVzc2lvbihub2RlKSB8fCBOb2RlLmlzRGVjb3JhdG9yKG5vZGUpIHx8IE5vZGUuaXNNb2R1bGVEZWNsYXJhdGlvbihub2RlKSB8fCBOb2RlLmlzQ2FsbEV4cHJlc3Npb24obm9kZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGUU4obm9kZTogRlFOTm9kZSB8IE5vZGUpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgYWJzb2x1dGVQYXRoUHJvamVjdCA9IGVudGl0eURpY3Rpb25hcnkuZmFtaXhSZXAuZ2V0QWJzb2x1dGVQYXRoKCk7XHJcblxyXG4gICAgY29uc3Qgc291cmNlRmlsZSA9IG5vZGUuZ2V0U291cmNlRmlsZSgpO1xyXG4gICAgY29uc3QgcGFydHM6IHN0cmluZ1tdID0gW107XHJcbiAgICBsZXQgY3VycmVudE5vZGU6IE5vZGUgfCB1bmRlZmluZWQgPSBub2RlO1xyXG5cclxuICAgIHdoaWxlIChjdXJyZW50Tm9kZSAmJiAhTm9kZS5pc1NvdXJjZUZpbGUoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgY29uc3QgeyBsaW5lLCBjb2x1bW4gfSA9IHNvdXJjZUZpbGUuZ2V0TGluZUFuZENvbHVtbkF0UG9zKGN1cnJlbnROb2RlLmdldFN0YXJ0KCkpO1xyXG4gICAgICAgIGNvbnN0IGxjID0gYCR7bGluZX06JHtjb2x1bW59YDtcclxuICAgICAgICBpZiAoTm9kZS5pc0NsYXNzRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8IFxyXG4gICAgICAgICAgICBOb2RlLmlzQ2xhc3NFeHByZXNzaW9uKGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgTm9kZS5pc0ludGVyZmFjZURlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzRnVuY3Rpb25EZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgIE5vZGUuaXNNZXRob2REZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgIE5vZGUuaXNNb2R1bGVEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgIE5vZGUuaXNWYXJpYWJsZURlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgTm9kZS5pc0dldEFjY2Vzc29yRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNTZXRBY2Nlc3NvckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzUHJvcGVydHlEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc1BhcmFtZXRlckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzRGVjb3JhdG9yKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzVHlwZUFsaWFzRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNFbnVtRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNFbnVtTWVtYmVyKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzUGFyYW1ldGVyZWQoY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNQcm9wZXJ0eVNpZ25hdHVyZShjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc0FycmF5TGl0ZXJhbEV4cHJlc3Npb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNJbXBvcnRTcGVjaWZpZXIoY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNJZGVudGlmaWVyKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICBjb25zdCBuYW1lID0gTm9kZS5pc0lkZW50aWZpZXIoY3VycmVudE5vZGUpID8gY3VycmVudE5vZGUuZ2V0VGV4dCgpIFxyXG4gICAgICAgICAgICAgICAgOiBnZXROYW1lT2ZOb2RlKGN1cnJlbnROb2RlKSAvKiBjdXJyZW50Tm9kZS5nZXROYW1lKCkgKi8gfHwgJ1VubmFtZWRfJyArIGN1cnJlbnROb2RlLmdldEtpbmROYW1lKCkgKyBgKCR7bGN9KWA7XHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQobmFtZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHVubmFtZWQgbm9kZXNcclxuICAgICAgICBlbHNlIGlmIChOb2RlLmlzQXJyb3dGdW5jdGlvbihjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgICAgICAgICBOb2RlLmlzQmxvY2soY3VycmVudE5vZGUpIHx8IFxyXG4gICAgICAgICAgICAgICAgICAgTm9kZS5pc0ZvckluU3RhdGVtZW50KGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgICAgICAgIE5vZGUuaXNGb3JPZlN0YXRlbWVudChjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgICAgICAgICBOb2RlLmlzRm9yU3RhdGVtZW50KGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgICAgICAgIE5vZGUuaXNDYXRjaENsYXVzZShjdXJyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgcGFydHMudW5zaGlmdChgJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfSgke2xjfSlgKTtcclxuICAgICAgICB9IGVsc2UgaWYgKE5vZGUuaXNDb25zdHJ1Y3RvckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICBwYXJ0cy51bnNoaWZ0KGBjb25zdHJ1Y3RvcmApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIEZvciBvdGhlciBraW5kcywgeW91IG1pZ2h0IHdhbnQgdG8gaGFuZGxlIHRoZW0gc3BlY2lmaWNhbGx5IG9yIGlnbm9yZVxyXG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYElnbm9yaW5nIG5vZGUga2luZDogJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfWApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLmdldFBhcmVudCgpO1xyXG4gICAgfVxyXG5cclxuXHJcblxyXG4gICAgLy8gUHJlcGVuZCB0aGUgcmVsYXRpdmUgcGF0aCBvZiB0aGUgc291cmNlIGZpbGVcclxuICAgIGxldCByZWxhdGl2ZVBhdGggPSBlbnRpdHlEaWN0aW9uYXJ5LmNvbnZlcnRUb1JlbGF0aXZlUGF0aChcclxuICAgICAgICBwYXRoLm5vcm1hbGl6ZShzb3VyY2VGaWxlLmdldEZpbGVQYXRoKCkpLCBcclxuICAgICAgICAgICAgICAgICAgICAgICBhYnNvbHV0ZVBhdGhQcm9qZWN0KS5yZXBsYWNlKC9cXFxcL3NnLCBcIi9cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICBpZiAocmVsYXRpdmVQYXRoLmluY2x1ZGVzKFwiLi5cIikpIHtcclxuICAgICAgICBsb2dnZXIuZXJyb3IoYFJlbGF0aXZlIHBhdGggY29udGFpbnMgLi4vOiAke3JlbGF0aXZlUGF0aH1gKTtcclxuICAgIH1cclxuICAgIGlmIChyZWxhdGl2ZVBhdGguc3RhcnRzV2l0aChcIi9cIikpIHtcclxuICAgICAgICByZWxhdGl2ZVBhdGggPSByZWxhdGl2ZVBhdGguc3Vic3RyaW5nKDEpO1xyXG4gICAgfVxyXG4gICAgcGFydHMudW5zaGlmdChgeyR7cmVsYXRpdmVQYXRofX1gKTtcclxuICAgIGNvbnN0IGZxbiA9IHBhcnRzLmpvaW4oXCIuXCIpICsgYFske25vZGUuZ2V0S2luZE5hbWUoKX1dYDsgIC8vIGRpc2FtYmlndWF0ZVxyXG5cclxuICAgIGxvZ2dlci5kZWJ1ZyhgR2VuZXJhdGVkIEZRTjogJHtmcW59IGZvciBub2RlOiAke25vZGUuZ2V0S2luZE5hbWUoKX1gKTtcclxuICAgIHJldHVybiBmcW47XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0VW5pcXVlRlFOKG5vZGU6IE5vZGUpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xyXG4gICAgY29uc3QgYWJzb2x1dGVQYXRoUHJvamVjdCA9IGVudGl0eURpY3Rpb25hcnkuZmFtaXhSZXAuZ2V0QWJzb2x1dGVQYXRoKCk7XHJcbiAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcclxuXHJcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFNvdXJjZUZpbGUpIHtcclxuICAgICAgICByZXR1cm4gZW50aXR5RGljdGlvbmFyeS5jb252ZXJ0VG9SZWxhdGl2ZVBhdGgocGF0aC5ub3JtYWxpemUobm9kZS5nZXRGaWxlUGF0aCgpKSwgYWJzb2x1dGVQYXRoUHJvamVjdCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGN1cnJlbnROb2RlOiBOb2RlIHwgdW5kZWZpbmVkID0gbm9kZTtcclxuICAgIHdoaWxlIChjdXJyZW50Tm9kZSkge1xyXG4gICAgICAgIGlmIChOb2RlLmlzU291cmNlRmlsZShjdXJyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gZW50aXR5RGljdGlvbmFyeS5jb252ZXJ0VG9SZWxhdGl2ZVBhdGgocGF0aC5ub3JtYWxpemUoY3VycmVudE5vZGUuZ2V0RmlsZVBhdGgoKSksIGFic29sdXRlUGF0aFByb2plY3QpLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpO1xyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmVQYXRoLmluY2x1ZGVzKFwiLi5cIikpIHtcclxuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgUmVsYXRpdmUgcGF0aCBjb250YWlucyAuLi86ICR7cmVsYXRpdmVQYXRofWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQocmVsYXRpdmVQYXRoKTsgLy8gQWRkIGZpbGUgcGF0aCBhdCB0aGUgc3RhcnRcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50Tm9kZS5nZXRTeW1ib2woKSkge1xyXG4gICAgICAgICAgICBjb25zdCBuYW1lID0gY3VycmVudE5vZGUuZ2V0U3ltYm9sKCkhLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgLy8gRm9yIGFub255bW91cyBub2RlcywgdXNlIGtpbmQgYW5kIHBvc2l0aW9uIGFzIHVuaXF1ZSBpZGVudGlmaWVyc1xyXG4gICAgICAgICAgICBjb25zdCBpZGVudGlmaWVyID0gbmFtZSAhPT0gXCJfX2NvbXB1dGVkXCIgPyBuYW1lIDogYCR7Y3VycmVudE5vZGUuZ2V0S2luZE5hbWUoKX1fJHtjdXJyZW50Tm9kZS5nZXRTdGFydExpbmVQb3MoKX1gO1xyXG4gICAgICAgICAgICBwYXJ0cy51bnNoaWZ0KGlkZW50aWZpZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLmdldFBhcmVudCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwYXJ0cy5qb2luKFwiOjpcIik7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBuYW1lIG9mIGEgbm9kZSwgaWYgaXQgaGFzIG9uZVxyXG4gKiBAcGFyYW0gYSBBIG5vZGVcclxuICogQHJldHVybnMgVGhlIG5hbWUgb2YgdGhlIG5vZGUsIG9yIGFuIGVtcHR5IHN0cmluZyBpZiBpdCBkb2Vzbid0IGhhdmUgb25lXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmFtZU9mTm9kZShhOiBOb2RlKTogc3RyaW5nIHtcclxuICAgIGxldCBjS2luZDogQ2xhc3NEZWNsYXJhdGlvbiB8IHVuZGVmaW5lZDtcclxuICAgIGxldCBpS2luZDogSW50ZXJmYWNlRGVjbGFyYXRpb24gfCB1bmRlZmluZWQ7XHJcbiAgICBsZXQgbUtpbmQ6IE1ldGhvZERlY2xhcmF0aW9uIHwgdW5kZWZpbmVkO1xyXG4gICAgbGV0IGZLaW5kOiBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgdW5kZWZpbmVkOyBcclxuICAgIGxldCBhbGlhczogVFNNb3JwaFR5cGVEZWNsYXJhdGlvbiB8IHVuZGVmaW5lZDtcclxuICAgIHN3aXRjaCAoYS5nZXRLaW5kKCkpIHtcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuU291cmNlRmlsZTpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuU291cmNlRmlsZSkhLmdldEJhc2VOYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5Nb2R1bGVEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuTW9kdWxlRGVjbGFyYXRpb24pIS5nZXROYW1lKCk7IFxyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgY0tpbmQgPSBhLmFzS2luZChTeW50YXhLaW5kLkNsYXNzRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoY0tpbmQgJiYgY0tpbmQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY0tpbmQuZ2V0TmFtZSgpICsgZ2V0UGFyYW1ldGVycyhhKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjS2luZD8uZ2V0TmFtZSgpIHx8IFwiXCI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkludGVyZmFjZURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICBpS2luZCA9IGEuYXNLaW5kKFN5bnRheEtpbmQuSW50ZXJmYWNlRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoaUtpbmQgJiYgaUtpbmQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaUtpbmQuZ2V0TmFtZSgpICsgZ2V0UGFyYW1ldGVycyhhKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpS2luZD8uZ2V0TmFtZSgpIHx8IFwiXCI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5Qcm9wZXJ0eURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5Qcm9wZXJ0eURlY2xhcmF0aW9uKSEuZ2V0TmFtZSgpOyAgICBcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlByb3BlcnR5U2lnbmF0dXJlOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5Qcm9wZXJ0eVNpZ25hdHVyZSkhLmdldE5hbWUoKTsgICAgXHJcbiAgICBcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuTWV0aG9kRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIG1LaW5kID0gYS5hc0tpbmQoU3ludGF4S2luZC5NZXRob2REZWNsYXJhdGlvbik7XHJcbiAgICAgICAgICAgIGlmIChtS2luZCAmJiBtS2luZC5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBtS2luZC5nZXROYW1lKCkgKyBnZXRQYXJhbWV0ZXJzKGEpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG1LaW5kPy5nZXROYW1lKCkgfHwgXCJcIjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuTWV0aG9kU2lnbmF0dXJlOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5NZXRob2RTaWduYXR1cmUpIS5nZXROYW1lKCk7ICAgXHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5HZXRBY2Nlc3NvcjpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuR2V0QWNjZXNzb3IpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5TZXRBY2Nlc3NvcjpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuU2V0QWNjZXNzb3IpIS5nZXROYW1lKCk7XHJcbiAgICBcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuRnVuY3Rpb25EZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgZktpbmQgPSBhLmFzS2luZChTeW50YXhLaW5kLkZ1bmN0aW9uRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoZktpbmQgJiYgZktpbmQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZktpbmQuZ2V0TmFtZSgpICsgZ2V0UGFyYW1ldGVycyhhKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmS2luZD8uZ2V0TmFtZSgpIHx8IFwiXCI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkZ1bmN0aW9uRXhwcmVzc2lvbjpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuRnVuY3Rpb25FeHByZXNzaW9uKT8uZ2V0TmFtZSgpIHx8IFwiYW5vbnltb3VzXCI7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5QYXJhbWV0ZXI6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlBhcmFtZXRlcikhLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5WYXJpYWJsZURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5WYXJpYWJsZURlY2xhcmF0aW9uKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuRGVjb3JhdG9yOlxyXG4gICAgICAgICAgICByZXR1cm4gXCJAXCIgKyBhLmFzS2luZChTeW50YXhLaW5kLkRlY29yYXRvcikhLmdldE5hbWUoKTsgICAgXHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5UeXBlUGFyYW1ldGVyOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5UeXBlUGFyYW1ldGVyKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuRW51bURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5FbnVtRGVjbGFyYXRpb24pIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5FbnVtTWVtYmVyOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5FbnVtTWVtYmVyKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuVHlwZUFsaWFzRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIC8vIHNwZWNpYWwgY2FzZSBmb3IgcGFyYW1ldGVyaXplZCB0eXBlc1xyXG4gICAgICAgICAgICBhbGlhcyA9IGEuYXNLaW5kKFN5bnRheEtpbmQuVHlwZUFsaWFzRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoYWxpYXMgJiYgYWxpYXMuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYWxpYXMuZ2V0TmFtZSgpICsgXCI8XCIgKyBhbGlhcy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCh0cCA9PiB0cC5nZXROYW1lKCkpLmpvaW4oXCIsIFwiKSArIFwiPlwiO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlR5cGVBbGlhc0RlY2xhcmF0aW9uKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuQ29uc3RydWN0b3I6XHJcbiAgICAgICAgICAgIHJldHVybiBcImNvbnN0cnVjdG9yXCI7ICAgXHJcbiAgICAgICAgXHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKGBnZXROYW1lT2ZOb2RlIGNhbGxlZCBvbiBhIG5vZGUgdGhhdCBkb2Vzbid0IGhhdmUgYSBuYW1lOiAke2EuZ2V0S2luZE5hbWUoKX1gKTtcclxuICAgICAgICAgICAgLy8gYW5jZXN0b3IgaGFzbid0IGdvdCBhIHVzZWZ1bCBuYW1lXHJcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIG5hbWUgb2YgYSBub2RlLCBpZiBpdCBoYXMgb25lXHJcbiAqIEBwYXJhbSBhIEEgbm9kZVxyXG4gKiBAcmV0dXJucyBUaGUgbmFtZSBvZiB0aGUgbm9kZSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmVcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRQYXJhbWV0ZXJzKGE6IE5vZGUpOiBzdHJpbmcge1xyXG4gICAgbGV0IHBhcmFtU3RyaW5nID0gXCJcIjtcclxuICAgIHN3aXRjaCAoYS5nZXRLaW5kKCkpIHtcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcGFyYW1TdHJpbmcgPSBcIjxcIiArIGEuYXNLaW5kKFN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbik/LmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKHRwID0+IHRwLmdldE5hbWUoKSkuam9pbihcIiwgXCIpICsgXCI+XCI7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5JbnRlcmZhY2VEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcGFyYW1TdHJpbmcgPSBcIjxcIiArIGEuYXNLaW5kKFN5bnRheEtpbmQuSW50ZXJmYWNlRGVjbGFyYXRpb24pPy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCh0cCA9PiB0cC5nZXROYW1lKCkpLmpvaW4oXCIsIFwiKSArIFwiPlwiO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuTWV0aG9kRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHBhcmFtU3RyaW5nID0gXCI8XCIgKyBhLmFzS2luZChTeW50YXhLaW5kLk1ldGhvZERlY2xhcmF0aW9uKT8uZ2V0VHlwZVBhcmFtZXRlcnMoKS5tYXAodHAgPT4gdHAuZ2V0TmFtZSgpKS5qb2luKFwiLCBcIikgKyBcIj5cIjtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkZ1bmN0aW9uRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHBhcmFtU3RyaW5nID0gXCI8XCIgKyBhLmFzS2luZChTeW50YXhLaW5kLkZ1bmN0aW9uRGVjbGFyYXRpb24pPy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCh0cCA9PiB0cC5nZXROYW1lKCkpLmpvaW4oXCIsIFwiKSArIFwiPlwiO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGdldFBhcmFtZXRlcnMgY2FsbGVkIG9uIGEgbm9kZSB0aGF0IGRvZXNuJ3QgaGF2ZSBwYXJhbWV0ZXJzOiAke2EuZ2V0S2luZE5hbWUoKX1gKTtcclxuICAgIH1cclxuICAgIHJldHVybiBwYXJhbVN0cmluZztcclxufVxyXG4iXX0=
|
|
498
|
+
/**
|
|
499
|
+
* Gets the FQN of an unresolved interface that is being implemented or extended
|
|
500
|
+
* @param unresolvedInheritedClassOrInterface The expression with type arguments representing the interface
|
|
501
|
+
* @returns The FQN of the unresolved interface
|
|
502
|
+
*/
|
|
503
|
+
function getFQNUnresolvedInheritedClassOrInterface(unresolvedInheritedClassOrInterface) {
|
|
504
|
+
// Check for either ClassDeclaration or InterfaceDeclaration ancestor
|
|
505
|
+
const classAncestor = unresolvedInheritedClassOrInterface.getFirstAncestorByKind(ts_morph_1.SyntaxKind.ClassDeclaration);
|
|
506
|
+
const interfaceAncestor = unresolvedInheritedClassOrInterface.getFirstAncestorByKind(ts_morph_1.SyntaxKind.InterfaceDeclaration);
|
|
507
|
+
// Validate the context
|
|
508
|
+
if (!classAncestor && !interfaceAncestor) {
|
|
509
|
+
throw new Error("getFQNUnresolvedClassOrInterface called on a node that is not in an implements or extends context");
|
|
510
|
+
}
|
|
511
|
+
// Check if it's a valid implements/extends context
|
|
512
|
+
let isValidContext = false;
|
|
513
|
+
let classExtendsClass = false;
|
|
514
|
+
if (classAncestor) {
|
|
515
|
+
// check if the class is extending or implementing an interface
|
|
516
|
+
const extendsClause = classAncestor.getExtends();
|
|
517
|
+
const implementsClause = classAncestor.getImplements();
|
|
518
|
+
isValidContext = (extendsClause !== undefined) || (implementsClause && implementsClause.length > 0);
|
|
519
|
+
classExtendsClass = extendsClause !== undefined;
|
|
520
|
+
}
|
|
521
|
+
else if (interfaceAncestor) {
|
|
522
|
+
// Check extends clause for interfaces
|
|
523
|
+
const extendsClause = interfaceAncestor.getExtends();
|
|
524
|
+
isValidContext = extendsClause && extendsClause.length > 0;
|
|
525
|
+
}
|
|
526
|
+
if (!isValidContext) {
|
|
527
|
+
throw new Error("getFQNUnresolvedInterface called on a node that is not in a valid implements or extends context");
|
|
528
|
+
}
|
|
529
|
+
// get the name of the interface
|
|
530
|
+
const name = unresolvedInheritedClassOrInterface.getExpression().getText();
|
|
531
|
+
// Find where it's imported - search the entire source file
|
|
532
|
+
const sourceFile = unresolvedInheritedClassOrInterface.getSourceFile();
|
|
533
|
+
const importDecls = sourceFile.getImportDeclarations();
|
|
534
|
+
for (const importDecl of importDecls) {
|
|
535
|
+
const moduleSpecifier = importDecl.getModuleSpecifierValue();
|
|
536
|
+
const importClause = importDecl.getImportClause();
|
|
537
|
+
if (importClause) {
|
|
538
|
+
const namedImports = importClause.getNamedImports();
|
|
539
|
+
// declarationName is ClassDeclaration if "class extends class"
|
|
540
|
+
const declarationName = classExtendsClass ? "ClassDeclaration" : "InterfaceDeclaration";
|
|
541
|
+
for (const namedImport of namedImports) {
|
|
542
|
+
if (namedImport.getName() === name) {
|
|
543
|
+
analyze_1.logger.debug(`Found import for ${name} in ${moduleSpecifier}`);
|
|
544
|
+
return `{module:${moduleSpecifier}}.${name}[${declarationName}]`;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
// If not found, return a default FQN format
|
|
550
|
+
return `{unknown-module}.${name}[InterfaceDeclaration]`;
|
|
551
|
+
}
|
|
552
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnFuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Zxbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQTZPQSx3QkFpSkM7QUFHRCxvQ0EyQkM7QUFPRCxzQ0FpR0M7QUFPRCxzQ0FtQkM7QUFPRCw4RkEwREM7QUEvbEJELHVDQUE0ZDtBQUM1ZCx1Q0FBcUQ7QUFDckQsZ0RBQXdCO0FBS3hCLDZEQUE2RDtBQUM3RCxTQUFTLFNBQVMsQ0FBQyxJQUFVO0lBQ3pCLE9BQU8sZUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDblMsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FBQyxVQUFzQjtJQUMvQyxNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUUzQyxVQUFVLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDbkQscUNBQXFDO1FBQ3JDLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUU3QyxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsZUFBSSxDQUFDLHlCQUF5QixDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDL0QsT0FBTztRQUNYLENBQUM7UUFFRCxXQUFXLENB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R0FBRyxVQUFVLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUV2RCxLQUFLLE1BQU0sVUFBVSxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQ25DLE1BQU0sZUFBZSxHQUFHLFVBQVUsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQzdELE1BQU0sWUFBWSxHQUFHLFVBQVUsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUVsRCxJQUFJLFlBQVksRUFBRSxDQUFDO1lBQ2YsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3BELCtEQUErRDtZQUMvRCxNQUFNLGVBQWUsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLHNCQUFzQixDQUFDO1lBRXhGLEtBQUssTUFBTSxXQUFXLElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ3JDLElBQUksV0FBVyxDQUFDLE9BQU8sRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDO29CQUNqQyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsSUFBSSxPQUFPLGVBQWUsRUFBRSxDQUFDLENBQUM7b0JBQy9ELE9BQU8sV0FBVyxlQUFlLEtBQUssSUFBSSxJQUFJLGVBQWUsR0FBRyxDQUFDO2dCQUNyRSxDQUFDO1lBQ0wsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBRUQsNENBQTRDO0lBQzVDLE9BQU8sb0JBQW9CLElBQUksd0JBQXdCLENBQUM7QUFDNUQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFycm93RnVuY3Rpb24sIENhbGxFeHByZXNzaW9uLCBDbGFzc0RlY2xhcmF0aW9uLCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uLCBEZWNvcmF0b3IsIEVudW1EZWNsYXJhdGlvbiwgRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzLCBGdW5jdGlvbkRlY2xhcmF0aW9uLCBGdW5jdGlvbkV4cHJlc3Npb24sIEdldEFjY2Vzc29yRGVjbGFyYXRpb24sIElkZW50aWZpZXIsIEltcG9ydERlY2xhcmF0aW9uLCBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiwgSW50ZXJmYWNlRGVjbGFyYXRpb24sIE1ldGhvZERlY2xhcmF0aW9uLCBNZXRob2RTaWduYXR1cmUsIE1vZHVsZURlY2xhcmF0aW9uLCBOb2RlLCBQcm9wZXJ0eURlY2xhcmF0aW9uLCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uLCBTb3VyY2VGaWxlLCBTeW50YXhLaW5kLCBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb24sIFZhcmlhYmxlRGVjbGFyYXRpb24gfSBmcm9tIFwidHMtbW9ycGhcIjtcclxuaW1wb3J0IHsgZW50aXR5RGljdGlvbmFyeSwgbG9nZ2VyIH0gZnJvbSBcIi4vYW5hbHl6ZVwiO1xyXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xyXG5pbXBvcnQgeyBUU01vcnBoVHlwZURlY2xhcmF0aW9uIH0gZnJvbSBcIi4vZmFtaXhfZnVuY3Rpb25zL0VudGl0eURpY3Rpb25hcnlcIjtcclxuXHJcbnR5cGUgRlFOTm9kZSA9IFNvdXJjZUZpbGUgfCBWYXJpYWJsZURlY2xhcmF0aW9uIHwgQXJyb3dGdW5jdGlvbiB8IElkZW50aWZpZXIgfCBNZXRob2REZWNsYXJhdGlvbiB8IE1ldGhvZFNpZ25hdHVyZSB8IEZ1bmN0aW9uRGVjbGFyYXRpb24gfCBGdW5jdGlvbkV4cHJlc3Npb24gfCBQcm9wZXJ0eURlY2xhcmF0aW9uIHwgVFNNb3JwaFR5cGVEZWNsYXJhdGlvbiB8IEVudW1EZWNsYXJhdGlvbiB8IEltcG9ydERlY2xhcmF0aW9uIHwgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24gfCBDYWxsRXhwcmVzc2lvbiB8IEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgQ29uc3RydWN0b3JEZWNsYXJhdGlvbiB8IFR5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbiB8IENsYXNzRGVjbGFyYXRpb24gfCBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IERlY29yYXRvciB8IE1vZHVsZURlY2xhcmF0aW9uO1xyXG5cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xyXG5mdW5jdGlvbiBpc0ZRTk5vZGUobm9kZTogTm9kZSk6IG5vZGUgaXMgRlFOTm9kZSB7XHJcbiAgICByZXR1cm4gTm9kZS5pc1ZhcmlhYmxlRGVjbGFyYXRpb24obm9kZSkgfHwgTm9kZS5pc0Fycm93RnVuY3Rpb24obm9kZSkgfHwgTm9kZS5pc0lkZW50aWZpZXIobm9kZSkgfHwgTm9kZS5pc01ldGhvZERlY2xhcmF0aW9uKG5vZGUpIHx8IE5vZGUuaXNDbGFzc0RlY2xhcmF0aW9uKG5vZGUpIHx8IE5vZGUuaXNDbGFzc0V4cHJlc3Npb24obm9kZSkgfHwgTm9kZS5pc0RlY29yYXRvcihub2RlKSB8fCBOb2RlLmlzTW9kdWxlRGVjbGFyYXRpb24obm9kZSkgfHwgTm9kZS5pc0NhbGxFeHByZXNzaW9uKG5vZGUpO1xyXG59XHJcblxyXG4vKipcclxuICogQnVpbGRzIGEgbWFwIG9mIG1ldGhvZCBwb3NpdGlvbnMgdG8gdGhlaXIgcHJvcGVydHkga2V5cyBpbiBvYmplY3QgbGl0ZXJhbHMuXHJcbiAqIFNjYW5zIGFsbCB2YXJpYWJsZSBkZWNsYXJhdGlvbnMgaW4gYSBzb3VyY2UgZmlsZSwgdGFyZ2V0aW5nIG9iamVjdCBsaXRlcmFscyB3aXRoIGFueSBrZXlzXHJcbiAqIChlLmcuLCBgMzogeyBtZXRob2QoKSB7fSB9YCBvciBgYWRkOiB7IGNvbXB1dGUoKSB7fSB9YCksIGFuZCBtYXBzIGVhY2ggbWV0aG9kJ3Mgc3RhcnQgcG9zaXRpb24gdG8gaXRzIGtleS5cclxuICogTG9ncyBlYWNoIHN0ZXAgZm9yIGRlYnVnZ2luZy5cclxuICogXHJcbiAqIEBwYXJhbSBzb3VyY2VGaWxlIFRoZSBUeXBlU2NyaXB0IHNvdXJjZSBmaWxlIHRvIGFuYWx5emVcclxuICogQHJldHVybnMgQSBNYXAgd2hlcmUga2V5cyBhcmUgbWV0aG9kIHN0YXJ0IHBvc2l0aW9ucyBhbmQgdmFsdWVzIGFyZSB0aGVpciBwcm9wZXJ0eSBrZXlzIChlLmcuLCBcIjNcIiwgXCJhZGRcIilcclxuICovXHJcbmZ1bmN0aW9uIGJ1aWxkU3RhZ2VNZXRob2RNYXAoc291cmNlRmlsZTogU291cmNlRmlsZSk6IE1hcDxudW1iZXIsIHN0cmluZz4ge1xyXG4gICAgY29uc3Qgc3RhZ2VNYXAgPSBuZXcgTWFwPG51bWJlciwgc3RyaW5nPigpO1xyXG5cclxuICAgIHNvdXJjZUZpbGUuZ2V0VmFyaWFibGVEZWNsYXJhdGlvbnMoKS5mb3JFYWNoKHZhckRlY2wgPT4ge1xyXG4gICAgICAgIC8vIGNvbnN0IHZhck5hbWUgPSB2YXJEZWNsLmdldE5hbWUoKTtcclxuICAgICAgICBjb25zdCBpbml0aWFsaXplciA9IHZhckRlY2wuZ2V0SW5pdGlhbGl6ZXIoKTtcclxuXHJcbiAgICAgICAgaWYgKCFpbml0aWFsaXplciB8fCAhTm9kZS5pc09iamVjdExpdGVyYWxFeHByZXNzaW9uKGluaXRpYWxpemVyKSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpbml0aWFsaXplci5nZXRQcm9wZXJ0aWVzKCkuZm9yRWFjaChwcm9wID0+IHtcclxuICAgICAgICAgICAgbGV0IGtleTogc3RyaW5nIHwgdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAgICAgaWYgKE5vZGUuaXNQcm9wZXJ0eUFzc2lnbm1lbnQocHJvcCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWVOb2RlID0gcHJvcC5nZXROYW1lTm9kZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChOb2RlLmlzSWRlbnRpZmllcihuYW1lTm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBrZXkgPSBuYW1lTm9kZS5nZXRUZXh0KCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE5vZGUuaXNTdHJpbmdMaXRlcmFsKG5hbWVOb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleSA9IG5hbWVOb2RlLmdldFRleHQoKS5yZXBsYWNlKC9eXCIoLispXCIkLywgJyQxJykucmVwbGFjZSgvXicoLispJyQvLCAnJDEnKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoTm9kZS5pc051bWVyaWNMaXRlcmFsKG5hbWVOb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleSA9IG5hbWVOb2RlLmdldFRleHQoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoTm9kZS5pc0NvbXB1dGVkUHJvcGVydHlOYW1lKG5hbWVOb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBuYW1lTm9kZS5nZXRFeHByZXNzaW9uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKE5vZGUuaXNJZGVudGlmaWVyKGV4cHJlc3Npb24pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgdmFyaWFibGUgdmFsdWUgaWYgcG9zc2libGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3ltYm9sID0gZXhwcmVzc2lvbi5nZXRTeW1ib2woKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN5bWJvbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVjbCA9IHN5bWJvbC5nZXREZWNsYXJhdGlvbnMoKVswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChOb2RlLmlzVmFyaWFibGVEZWNsYXJhdGlvbihkZWNsKSAmJiBkZWNsLmdldEluaXRpYWxpemVyKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbml0ID0gZGVjbC5nZXRJbml0aWFsaXplcigpITtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoTm9kZS5pc1N0cmluZ0xpdGVyYWwoaW5pdCkgfHwgTm9kZS5pc051bWVyaWNMaXRlcmFsKGluaXQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGluaXQuZ2V0VGV4dCgpLnJlcGxhY2UoL15cIiguKylcIiQvLCAnJDEnKS5yZXBsYWNlKC9eJyguKyknJC8sICckMScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gZXhwcmVzc2lvbi5nZXRUZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE5vZGUuaXNCaW5hcnlFeHByZXNzaW9uKGV4cHJlc3Npb24pICYmIGV4cHJlc3Npb24uZ2V0T3BlcmF0b3JUb2tlbigpLmdldFRleHQoKSA9PT0gJysnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBzaW1wbGUgc3RyaW5nIGNvbmNhdGVuYXRpb24gKGUuZy4sIFwiQVwiICsgXCJCXCIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxlZnQgPSBleHByZXNzaW9uLmdldExlZnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmlnaHQgPSBleHByZXNzaW9uLmdldFJpZ2h0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChOb2RlLmlzU3RyaW5nTGl0ZXJhbChsZWZ0KSAmJiBOb2RlLmlzU3RyaW5nTGl0ZXJhbChyaWdodCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGxlZnQuZ2V0TGl0ZXJhbFRleHQoKSArIHJpZ2h0LmdldExpdGVyYWxUZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE5vZGUuaXNUZW1wbGF0ZUV4cHJlc3Npb24oZXhwcmVzc2lvbikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSGFuZGxlIHRlbXBsYXRlIGxpdGVyYWxzIChlLmcuLCBga2V5LSR7MX1gKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBoZWFkID0gZXhwcmVzc2lvbi5nZXRIZWFkKCkuZ2V0TGl0ZXJhbFRleHQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3BhbnMgPSBleHByZXNzaW9uLmdldFRlbXBsYXRlU3BhbnMoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNwYW5zLmxlbmd0aCA9PT0gMSAmJiBOb2RlLmlzTnVtZXJpY0xpdGVyYWwoc3BhbnNbMF0uZ2V0RXhwcmVzc2lvbigpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtID0gc3BhbnNbMF0uZ2V0RXhwcmVzc2lvbigpLmdldFRleHQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGAke2hlYWR9JHtudW19YDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBleHByZXNzaW9uLmdldFRleHQoKTsgLy8gRmFsbGJhY2tcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9wSW5pdGlhbGl6ZXIgPSBwcm9wLmdldEluaXRpYWxpemVyKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAocHJvcEluaXRpYWxpemVyICYmIE5vZGUuaXNPYmplY3RMaXRlcmFsRXhwcmVzc2lvbihwcm9wSW5pdGlhbGl6ZXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvcEluaXRpYWxpemVyLmdldERlc2NlbmRhbnRzT2ZLaW5kKFN5bnRheEtpbmQuTWV0aG9kRGVjbGFyYXRpb24pLmZvckVhY2gobWV0aG9kID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc3QgbWV0aG9kTmFtZSA9IG1ldGhvZC5nZXROYW1lKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvcyA9IG1ldGhvZC5nZXRTdGFydCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFnZU1hcC5zZXQocG9zLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiBzdGFnZU1hcDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEJ1aWxkcyBhIG1hcCBvZiBtZXRob2QgcG9zaXRpb25zIHRvIHRoZWlyIGluZGV4IGluIGNsYXNzL2ludGVyZmFjZS9uYW1lc3BhY2UgZGVjbGFyYXRpb25zXHJcbiAqIEBwYXJhbSBzb3VyY2VGaWxlIFRoZSBUeXBlU2NyaXB0IHNvdXJjZSBmaWxlIHRvIGFuYWx5emVcclxuICogQHJldHVybnMgQSBNYXAgd2hlcmUga2V5cyBhcmUgbWV0aG9kIHN0YXJ0IHBvc2l0aW9ucyBhbmQgdmFsdWVzIGFyZSB0aGVpciBwb3NpdGlvbmFsIGluZGV4ICgxLWJhc2VkKVxyXG4gKi9cclxuZnVuY3Rpb24gYnVpbGRNZXRob2RQb3NpdGlvbk1hcChzb3VyY2VGaWxlOiBTb3VyY2VGaWxlKTogTWFwPG51bWJlciwgbnVtYmVyPiB7XHJcbiAgICBjb25zdCBwb3NpdGlvbk1hcCA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXI+KCk7XHJcbiAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIFN0YXJ0aW5nIGFuYWx5c2lzIGZvciBmaWxlOiAke3NvdXJjZUZpbGUuZ2V0RmlsZVBhdGgoKX1gKTtcclxuXHJcbiAgICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gcHJvY2VzcyBtb2R1bGVzIHJlY3Vyc2l2ZWx5XHJcbiAgICBmdW5jdGlvbiBwcm9jZXNzTW9kdWxlKG1vZHVsZU5vZGU6IE1vZHVsZURlY2xhcmF0aW9uLCBtb2R1bGVQYXRoOiBzdHJpbmcpIHtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIFByb2Nlc3NpbmcgbW9kdWxlOiAke21vZHVsZVBhdGh9YCk7XHJcblxyXG4gICAgICAgIC8vIEhhbmRsZSBmdW5jdGlvbnMgZGlyZWN0bHkgaW4gdGhlIG1vZHVsZVxyXG4gICAgICAgIGNvbnN0IGZ1bmN0aW9ucyA9IG1vZHVsZU5vZGUuZ2V0RnVuY3Rpb25zKCk7XHJcbiAgICAgICAgY29uc3QgZnVuY3Rpb25Db3VudHMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xyXG5cclxuICAgICAgICBmdW5jdGlvbnMuZm9yRWFjaChmdW5jID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZnVuY05hbWUgPSBmdW5jLmdldE5hbWUoKSB8fCBgVW5uYW1lZF9GdW5jdGlvbigke2Z1bmMuZ2V0U3RhcnQoKX0pYDtcclxuICAgICAgICAgICAgY29uc3QgY291bnQgPSAoZnVuY3Rpb25Db3VudHMuZ2V0KGZ1bmNOYW1lKSB8fCAwKSArIDE7XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uQ291bnRzLnNldChmdW5jTmFtZSwgY291bnQpO1xyXG4gICAgICAgICAgICBwb3NpdGlvbk1hcC5zZXQoZnVuYy5nZXRTdGFydCgpLCBjb3VudCk7XHJcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBbYnVpbGRNZXRob2RQb3NpdGlvbk1hcF0gTW9kdWxlIGZ1bmN0aW9uOiAke2Z1bmNOYW1lfSwgcG9zaXRpb246ICR7ZnVuYy5nZXRTdGFydCgpfSwgaW5kZXg6ICR7Y291bnR9YCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIEhhbmRsZSBjbGFzc2VzIHdpdGhpbiB0aGUgbW9kdWxlXHJcbiAgICAgICAgY29uc3QgY2xhc3NlcyA9IG1vZHVsZU5vZGUuZ2V0Q2xhc3NlcygpO1xyXG4gICAgICAgIGNsYXNzZXMuZm9yRWFjaChjbGFzc05vZGUgPT4ge1xyXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIFByb2Nlc3NpbmcgY2xhc3MgaW4gbW9kdWxlOiAke2NsYXNzTm9kZS5nZXROYW1lKCkgfHwgJ1VubmFtZWQnfWApO1xyXG4gICAgICAgICAgICBjb25zdCBtZXRob2RzID0gY2xhc3NOb2RlLmdldE1ldGhvZHMoKTtcclxuICAgICAgICAgICAgY29uc3QgbWV0aG9kQ291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcclxuXHJcbiAgICAgICAgICAgIG1ldGhvZHMuZm9yRWFjaChtZXRob2QgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbWV0aG9kTmFtZSA9IG1ldGhvZC5nZXROYW1lKCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb3VudCA9IChtZXRob2RDb3VudHMuZ2V0KG1ldGhvZE5hbWUpIHx8IDApICsgMTtcclxuICAgICAgICAgICAgICAgIG1ldGhvZENvdW50cy5zZXQobWV0aG9kTmFtZSwgY291bnQpO1xyXG4gICAgICAgICAgICAgICAgcG9zaXRpb25NYXAuc2V0KG1ldGhvZC5nZXRTdGFydCgpLCBjb3VudCk7XHJcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIE1vZHVsZSBjbGFzcyBtZXRob2Q6ICR7bWV0aG9kTmFtZX0sIHBvc2l0aW9uOiAke21ldGhvZC5nZXRTdGFydCgpfSwgaW5kZXg6ICR7Y291bnR9YCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBIYW5kbGUgaW50ZXJmYWNlcyB3aXRoaW4gdGhlIG1vZHVsZVxyXG4gICAgICAgIGNvbnN0IGludGVyZmFjZXMgPSBtb2R1bGVOb2RlLmdldEludGVyZmFjZXMoKTtcclxuICAgICAgICBpbnRlcmZhY2VzLmZvckVhY2goaW50ZXJmYWNlTm9kZSA9PiB7XHJcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBbYnVpbGRNZXRob2RQb3NpdGlvbk1hcF0gUHJvY2Vzc2luZyBpbnRlcmZhY2UgaW4gbW9kdWxlOiAke2ludGVyZmFjZU5vZGUuZ2V0TmFtZSgpIHx8ICdVbm5hbWVkJ31gKTtcclxuICAgICAgICAgICAgY29uc3QgbWV0aG9kcyA9IGludGVyZmFjZU5vZGUuZ2V0TWV0aG9kcygpO1xyXG4gICAgICAgICAgICBjb25zdCBtZXRob2RDb3VudHMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xyXG5cclxuICAgICAgICAgICAgbWV0aG9kcy5mb3JFYWNoKG1ldGhvZCA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtZXRob2ROYW1lID0gbWV0aG9kLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gKG1ldGhvZENvdW50cy5nZXQobWV0aG9kTmFtZSkgfHwgMCkgKyAxO1xyXG4gICAgICAgICAgICAgICAgbWV0aG9kQ291bnRzLnNldChtZXRob2ROYW1lLCBjb3VudCk7XHJcbiAgICAgICAgICAgICAgICBwb3NpdGlvbk1hcC5zZXQobWV0aG9kLmdldFN0YXJ0KCksIGNvdW50KTtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBbYnVpbGRNZXRob2RQb3NpdGlvbk1hcF0gTW9kdWxlIGludGVyZmFjZSBtZXRob2Q6ICR7bWV0aG9kTmFtZX0sIHBvc2l0aW9uOiAke21ldGhvZC5nZXRTdGFydCgpfSwgaW5kZXg6ICR7Y291bnR9YCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBSZWN1cnNpdmVseSBwcm9jZXNzIG5lc3RlZCBtb2R1bGVzXHJcbiAgICAgICAgY29uc3QgbmVzdGVkTW9kdWxlcyA9IG1vZHVsZU5vZGUuZ2V0TW9kdWxlcygpO1xyXG4gICAgICAgIG5lc3RlZE1vZHVsZXMuZm9yRWFjaChuZXN0ZWRNb2R1bGUgPT4ge1xyXG4gICAgICAgICAgICBpZiAoTm9kZS5pc01vZHVsZURlY2xhcmF0aW9uKG5lc3RlZE1vZHVsZSkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5lc3RlZE1vZHVsZU5hbWUgPSBuZXN0ZWRNb2R1bGUuZ2V0TmFtZSgpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3TW9kdWxlUGF0aCA9IGAke21vZHVsZVBhdGh9LiR7bmVzdGVkTW9kdWxlTmFtZX1gO1xyXG4gICAgICAgICAgICAgICAgcHJvY2Vzc01vZHVsZShuZXN0ZWRNb2R1bGUsIG5ld01vZHVsZVBhdGgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIHRyYWNrQXJyb3dGdW5jdGlvbnMoY29udGFpbmVyOiBOb2RlKSB7XHJcbiAgICAgICAgY29uc3QgYXJyb3dzID0gY29udGFpbmVyLmdldERlc2NlbmRhbnRzT2ZLaW5kKFN5bnRheEtpbmQuQXJyb3dGdW5jdGlvbik7XHJcbiAgICAgICAgYXJyb3dzLmZvckVhY2goYXJyb3cgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwYXJlbnQgPSBhcnJvdy5nZXRQYXJlbnQoKTtcclxuICAgICAgICAgICAgaWYgKE5vZGUuaXNCbG9jayhwYXJlbnQpIHx8IE5vZGUuaXNTb3VyY2VGaWxlKHBhcmVudCkpIHtcclxuICAgICAgICAgICAgICAgIC8vIFVzZSBuZWdhdGl2ZSBudW1iZXJzIGZvciBhcnJvdyBmdW5jdGlvbnMgdG8gZGlzdGluZ3Vpc2ggZnJvbSBtZXRob2RzXHJcbiAgICAgICAgICAgICAgICBwb3NpdGlvbk1hcC5zZXQoYXJyb3cuZ2V0U3RhcnQoKSwgLTEgKiAocG9zaXRpb25NYXAuc2l6ZSArIDEpKTtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBbYnVpbGRNZXRob2RQb3NpdGlvbk1hcF0gQXJyb3cgZnVuY3Rpb24gYXQgJHthcnJvdy5nZXRTdGFydCgpfWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSGFuZGxlIHRvcC1sZXZlbCBjbGFzc2VzXHJcbiAgICBzb3VyY2VGaWxlLmdldENsYXNzZXMoKS5mb3JFYWNoKGNsYXNzTm9kZSA9PiB7XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coYFtidWlsZE1ldGhvZFBvc2l0aW9uTWFwXSBQcm9jZXNzaW5nIGNsYXNzOiAke2NsYXNzTm9kZS5nZXROYW1lKCkgfHwgJ1VubmFtZWQnfWApO1xyXG4gICAgICAgIGNvbnN0IG1ldGhvZHMgPSBjbGFzc05vZGUuZ2V0TWV0aG9kcygpO1xyXG4gICAgICAgIGNvbnN0IG1ldGhvZENvdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XHJcblxyXG4gICAgICAgIG1ldGhvZHMuZm9yRWFjaChtZXRob2QgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBtZXRob2ROYW1lID0gbWV0aG9kLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgY29uc3QgY291bnQgPSAobWV0aG9kQ291bnRzLmdldChtZXRob2ROYW1lKSB8fCAwKSArIDE7XHJcbiAgICAgICAgICAgIG1ldGhvZENvdW50cy5zZXQobWV0aG9kTmFtZSwgY291bnQpO1xyXG4gICAgICAgICAgICBwb3NpdGlvbk1hcC5zZXQobWV0aG9kLmdldFN0YXJ0KCksIGNvdW50KTtcclxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYFtidWlsZE1ldGhvZFBvc2l0aW9uTWFwXSBDbGFzcyBtZXRob2Q6ICR7bWV0aG9kTmFtZX0sIHBvc2l0aW9uOiAke21ldGhvZC5nZXRTdGFydCgpfSwgaW5kZXg6ICR7Y291bnR9YCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIG1ldGhvZHMuZm9yRWFjaChtZXRob2QgPT4gdHJhY2tBcnJvd0Z1bmN0aW9ucyhtZXRob2QpKTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIEhhbmRsZSB0b3AtbGV2ZWwgaW50ZXJmYWNlc1xyXG4gICAgc291cmNlRmlsZS5nZXRJbnRlcmZhY2VzKCkuZm9yRWFjaChpbnRlcmZhY2VOb2RlID0+IHtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIFByb2Nlc3NpbmcgaW50ZXJmYWNlOiAke2ludGVyZmFjZU5vZGUuZ2V0TmFtZSgpIHx8ICdVbm5hbWVkJ31gKTtcclxuICAgICAgICBjb25zdCBtZXRob2RzID0gaW50ZXJmYWNlTm9kZS5nZXRNZXRob2RzKCk7XHJcbiAgICAgICAgY29uc3QgbWV0aG9kQ291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcclxuXHJcbiAgICAgICAgbWV0aG9kcy5mb3JFYWNoKG1ldGhvZCA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1ldGhvZE5hbWUgPSBtZXRob2QuZ2V0TmFtZSgpO1xyXG4gICAgICAgICAgICBjb25zdCBjb3VudCA9IChtZXRob2RDb3VudHMuZ2V0KG1ldGhvZE5hbWUpIHx8IDApICsgMTtcclxuICAgICAgICAgICAgbWV0aG9kQ291bnRzLnNldChtZXRob2ROYW1lLCBjb3VudCk7XHJcbiAgICAgICAgICAgIHBvc2l0aW9uTWFwLnNldChtZXRob2QuZ2V0U3RhcnQoKSwgY291bnQpO1xyXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIEludGVyZmFjZSBtZXRob2Q6ICR7bWV0aG9kTmFtZX0sIHBvc2l0aW9uOiAke21ldGhvZC5nZXRTdGFydCgpfSwgaW5kZXg6ICR7Y291bnR9YCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgbWV0aG9kcy5mb3JFYWNoKG1ldGhvZCA9PiB0cmFja0Fycm93RnVuY3Rpb25zKG1ldGhvZCkpO1xyXG5cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIEhhbmRsZSB0b3AtbGV2ZWwgbmFtZXNwYWNlcy9tb2R1bGVzXHJcbiAgICBzb3VyY2VGaWxlLmdldE1vZHVsZXMoKS5mb3JFYWNoKG1vZHVsZU5vZGUgPT4ge1xyXG4gICAgICAgIGlmIChOb2RlLmlzTW9kdWxlRGVjbGFyYXRpb24obW9kdWxlTm9kZSkpIHtcclxuICAgICAgICAgICAgY29uc3QgbW9kdWxlTmFtZSA9IG1vZHVsZU5vZGUuZ2V0TmFtZSgpO1xyXG4gICAgICAgICAgICBwcm9jZXNzTW9kdWxlKG1vZHVsZU5vZGUsIG1vZHVsZU5hbWUpO1xyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuXHJcbiAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIEZpbmFsIHBvc2l0aW9uTWFwOmAsIEFycmF5LmZyb20ocG9zaXRpb25NYXAuZW50cmllcygpKSk7XHJcbiAgICByZXR1cm4gcG9zaXRpb25NYXA7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZXMgYSBmdWxseSBxdWFsaWZpZWQgbmFtZSAoRlFOKSBmb3IgYSBnaXZlbiBBU1Qgbm9kZS5cclxuICogQ29uc3RydWN0cyBhbiBGUU4gYnkgdHJhdmVyc2luZyB0aGUgbm9kZSdzIGFuY2VzdHJ5LCBhZGRpbmcgbmFtZXMgYW5kIGtleXNcclxuICogKG51bWVyaWMgb3Igc3RyaW5nIGZyb20gb2JqZWN0IGxpdGVyYWxzIC4uLikgYXMgbmVlZGVkLCBwcmVmaXhlZCB3aXRoIHRoZSBmaWxlJ3MgcmVsYXRpdmUgcGF0aC5cclxuICogXHJcbiAqIEBwYXJhbSBub2RlIFRoZSBBU1Qgbm9kZSB0byBnZW5lcmF0ZSBhbiBGUU4gZm9yXHJcbiAqIEByZXR1cm5zIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgbm9kZSdzIEZRTiAoZS5nLiwgXCJ7cGF0aH0ub3BlcmF0aW9ucy5hZGQuY29tcHV0ZVtNZXRob2REZWNsYXJhdGlvbl1cIilcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGUU4obm9kZTogRlFOTm9kZSB8IE5vZGUpOiBzdHJpbmcge1xyXG4gICAgY29uc3Qgc291cmNlRmlsZSA9IG5vZGUuZ2V0U291cmNlRmlsZSgpO1xyXG4gICAgY29uc3QgYWJzb2x1dGVQYXRoUHJvamVjdCA9IGVudGl0eURpY3Rpb25hcnkuZmFtaXhSZXAuZ2V0QWJzb2x1dGVQYXRoKCk7XHJcbiAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcclxuICAgIGxldCBjdXJyZW50Tm9kZTogTm9kZSB8IHVuZGVmaW5lZCA9IG5vZGU7XHJcblxyXG4gICAgY29uc3Qgc3RhZ2VNYXAgPSBidWlsZFN0YWdlTWV0aG9kTWFwKHNvdXJjZUZpbGUpO1xyXG4gICAgY29uc3QgbWV0aG9kUG9zaXRpb25NYXAgPSBidWlsZE1ldGhvZFBvc2l0aW9uTWFwKHNvdXJjZUZpbGUpO1xyXG5cclxuICAgIHdoaWxlIChjdXJyZW50Tm9kZSAmJiAhTm9kZS5pc1NvdXJjZUZpbGUoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgY29uc3QgeyBsaW5lLCBjb2x1bW4gfSA9IHNvdXJjZUZpbGUuZ2V0TGluZUFuZENvbHVtbkF0UG9zKGN1cnJlbnROb2RlLmdldFN0YXJ0KCkpO1xyXG4gICAgICAgIGNvbnN0IGxjID0gYCR7bGluZX06JHtjb2x1bW59YDtcclxuXHJcbiAgICAgICAgaWYgKE5vZGUuaXNDbGFzc0RlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzQ2xhc3NFeHByZXNzaW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzSW50ZXJmYWNlRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNGdW5jdGlvbkRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzTWV0aG9kRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNNb2R1bGVEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc1ZhcmlhYmxlRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNHZXRBY2Nlc3NvckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzU2V0QWNjZXNzb3JEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc1Byb3BlcnR5RGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNQYXJhbWV0ZXJEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc0RlY29yYXRvcihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc1R5cGVBbGlhc0RlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzRW51bURlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzRW51bU1lbWJlcihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc1BhcmFtZXRlcmVkKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzUHJvcGVydHlTaWduYXR1cmUoY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNBcnJheUxpdGVyYWxFeHByZXNzaW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzSW1wb3J0U3BlY2lmaWVyKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzSWRlbnRpZmllcihjdXJyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgbGV0IG5hbWU6IHN0cmluZztcclxuICAgICAgICAgICAgaWYgKE5vZGUuaXNJbXBvcnRTcGVjaWZpZXIoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhbGlhcyA9IGN1cnJlbnROb2RlLmdldEFsaWFzTm9kZSgpPy5nZXRUZXh0KCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYWxpYXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgaW1wb3J0RGVjbDogTm9kZSB8IHVuZGVmaW5lZCA9IGN1cnJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChpbXBvcnREZWNsICYmICFOb2RlLmlzSW1wb3J0RGVjbGFyYXRpb24oaW1wb3J0RGVjbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW1wb3J0RGVjbCA9IGltcG9ydERlY2wuZ2V0UGFyZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1vZHVsZVNwZWNpZmllciA9IGltcG9ydERlY2wgJiYgTm9kZS5pc0ltcG9ydERlY2xhcmF0aW9uKGltcG9ydERlY2wpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gaW1wb3J0RGVjbC5nZXRNb2R1bGVTcGVjaWZpZXIoKS5nZXRMaXRlcmFsVGV4dCgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogXCJ1bmtub3duXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGN1cnJlbnROb2RlLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gYCR7bmFtZX0gYXMgJHthbGlhc31bSW1wb3J0U3BlY2lmaWVyPCR7bW9kdWxlU3BlY2lmaWVyfT5dYDtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGN1cnJlbnROb2RlLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIGlmIGNvbnN0cnVjdG9yLCB1c2UgXCJjb25zdHJ1Y3RvclwiIGFzIG5hbWVcclxuICAgICAgICAgICAgICAgIGlmIChOb2RlLmlzQ29uc3RydWN0b3JEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gXCJjb25zdHJ1Y3RvclwiO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gTm9kZS5pc0lkZW50aWZpZXIoY3VycmVudE5vZGUpID8gY3VycmVudE5vZGUuZ2V0VGV4dCgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogJ2dldE5hbWUnIGluIGN1cnJlbnROb2RlICYmIHR5cGVvZiBjdXJyZW50Tm9kZVsnZ2V0TmFtZSddID09PSAnZnVuY3Rpb24nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICgoY3VycmVudE5vZGUgYXMgeyBnZXROYW1lKCk6IHN0cmluZyB9KS5nZXROYW1lKCkgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoTm9kZS5pc0NsYXNzRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUuaXNJbnRlcmZhY2VEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZS5pc01ldGhvZERlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlLmlzRnVuY3Rpb25EZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdnZXRUeXBlUGFyYW1ldGVycycgaW4gY3VycmVudE5vZGUgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE5vZGUuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZ2V0UGFyYW1ldGVycyhjdXJyZW50Tm9kZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnJykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGBVbm5hbWVkXyR7Y3VycmVudE5vZGUuZ2V0S2luZE5hbWUoKX0oJHtsY30pYDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKE5vZGUuaXNNZXRob2RTaWduYXR1cmUoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtZXRob2QgPSBjdXJyZW50Tm9kZSBhcyBNZXRob2RTaWduYXR1cmU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJhbXMgPSBtZXRob2QuZ2V0UGFyYW1ldGVycygpLm1hcChwID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlVGV4dCA9IHAuZ2V0VHlwZSgpLmdldFRleHQoKS5yZXBsYWNlKC9cXHMrL2csIFwiXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlVGV4dCB8fCBcImFueVwiOyAvLyBGYWxsYmFjayBmb3IgdW50eXBlZCBwYXJhbWV0ZXJzXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJldHVyblR5cGUgPSBtZXRob2QuZ2V0UmV0dXJuVHlwZSgpLmdldFRleHQoKS5yZXBsYWNlKC9cXHMrL2csIFwiXCIpIHx8IFwidm9pZFwiO1xyXG4gICAgICAgICAgICAgICAgbmFtZSA9IGAke25hbWV9KCR7cGFyYW1zLmpvaW4oXCIsXCIpfSk6JHtyZXR1cm5UeXBlfWA7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQobmFtZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBBcHBseSBwb3NpdGlvbmFsIGluZGV4IGZvciBNZXRob2REZWNsYXJhdGlvbiwgTWV0aG9kU2lnbmF0dXJlLCBhbmQgRnVuY3Rpb25EZWNsYXJhdGlvblxyXG4gICAgICAgICAgICBpZiAoTm9kZS5pc01ldGhvZERlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICAgICAgTm9kZS5pc01ldGhvZFNpZ25hdHVyZShjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgICAgIE5vZGUuaXNGdW5jdGlvbkRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gc3RhZ2VNYXAuZ2V0KGN1cnJlbnROb2RlLmdldFN0YXJ0KCkpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQoa2V5KTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2dldEZRTl0gQXBwbGllZCBzdGFnZU1hcCBrZXk6ICR7a2V5fSBmb3IgJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfSBhdCBwb3NpdGlvbiAke2N1cnJlbnROb2RlLmdldFN0YXJ0KCl9YCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uSW5kZXggPSBtZXRob2RQb3NpdGlvbk1hcC5nZXQoY3VycmVudE5vZGUuZ2V0U3RhcnQoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uSW5kZXggJiYgcG9zaXRpb25JbmRleCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFydHMudW5zaGlmdChwb3NpdGlvbkluZGV4LnRvU3RyaW5nKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2dldEZRTl0gQXBwbGllZCBwb3NpdGlvbkluZGV4OiAke3Bvc2l0aW9uSW5kZXh9IGZvciAke2N1cnJlbnROb2RlLmdldEtpbmROYW1lKCl9IGF0IHBvc2l0aW9uICR7Y3VycmVudE5vZGUuZ2V0U3RhcnQoKX1gKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgW2dldEZRTl0gTm8gcG9zaXRpb25JbmRleCBhcHBsaWVkIGZvciAke2N1cnJlbnROb2RlLmdldEtpbmROYW1lKCl9IGF0IHBvc2l0aW9uICR7Y3VycmVudE5vZGUuZ2V0U3RhcnQoKX0sIHBvc2l0aW9uSW5kZXg6ICR7cG9zaXRpb25JbmRleCB8fCAnbm9uZSd9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKE5vZGUuaXNBcnJvd0Z1bmN0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzQmxvY2soY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNGb3JJblN0YXRlbWVudChjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc0Zvck9mU3RhdGVtZW50KGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzRm9yU3RhdGVtZW50KGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzQ2F0Y2hDbGF1c2UoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBgJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfSgke2xjfSlgO1xyXG4gICAgICAgICAgICBwYXJ0cy51bnNoaWZ0KG5hbWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChOb2RlLmlzVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICBjb25zdCBhcnJvd1BhcmVudCA9IGN1cnJlbnROb2RlLmdldEZpcnN0QW5jZXN0b3JCeUtpbmQoU3ludGF4S2luZC5BcnJvd0Z1bmN0aW9uKTtcclxuICAgICAgICAgICAgaWYgKGFycm93UGFyZW50KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhcnJvd0luZGV4ID0gTWF0aC5hYnMobWV0aG9kUG9zaXRpb25NYXAuZ2V0KGFycm93UGFyZW50LmdldFN0YXJ0KCkpIHx8IDApO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFycm93SW5kZXggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFydHMudW5zaGlmdChhcnJvd0luZGV4LnRvU3RyaW5nKCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQoY3VycmVudE5vZGUuZ2V0TmFtZSgpKTtcclxuICAgICAgICAgICAgLy8gUmVtb3ZlZCBjb250aW51ZSB0byBhbGxvdyBhbmNlc3RvciBwcm9jZXNzaW5nXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKE5vZGUuaXNDb25zdHJ1Y3RvckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICBjb25zdCBuYW1lID0gXCJjb25zdHJ1Y3RvclwiO1xyXG4gICAgICAgICAgICBwYXJ0cy51bnNoaWZ0KG5hbWUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbZ2V0RlFOXSBJZ25vcmluZyBub2RlIGtpbmQ6ICR7Y3VycmVudE5vZGUuZ2V0S2luZE5hbWUoKX1gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUuZ2V0UGFyZW50KCk7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHJlbGF0aXZlUGF0aCA9IGVudGl0eURpY3Rpb25hcnkuY29udmVydFRvUmVsYXRpdmVQYXRoKFxyXG4gICAgICAgIHBhdGgubm9ybWFsaXplKHNvdXJjZUZpbGUuZ2V0RmlsZVBhdGgoKSksXHJcbiAgICAgICAgYWJzb2x1dGVQYXRoUHJvamVjdFxyXG4gICAgKS5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKTtcclxuXHJcbiAgICAvLyBpZiAocmVsYXRpdmVQYXRoLmluY2x1ZGVzKFwiLi5cIikpIHtcclxuICAgIC8vIH1cclxuICAgIGlmIChyZWxhdGl2ZVBhdGguc3RhcnRzV2l0aChcIi9cIikpIHtcclxuICAgICAgICByZWxhdGl2ZVBhdGggPSByZWxhdGl2ZVBhdGguc2xpY2UoMSk7XHJcbiAgICB9XHJcbiAgICBwYXJ0cy51bnNoaWZ0KGB7JHtyZWxhdGl2ZVBhdGh9fWApO1xyXG5cclxuICAgIGNvbnN0IGZxbiA9IHBhcnRzLmpvaW4oXCIuXCIpICsgYFske25vZGUuZ2V0S2luZE5hbWUoKX1dYDtcclxuICAgIC8vIGNvbnNvbGUubG9nKGBbZ2V0RlFOXSBGaW5hbCBGUU46ICR7ZnFufWApO1xyXG4gICAgcmV0dXJuIGZxbjtcclxufVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRVbmlxdWVGUU4obm9kZTogTm9kZSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XHJcbiAgICBjb25zdCBhYnNvbHV0ZVBhdGhQcm9qZWN0ID0gZW50aXR5RGljdGlvbmFyeS5mYW1peFJlcC5nZXRBYnNvbHV0ZVBhdGgoKTtcclxuICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICAgIGlmIChub2RlIGluc3RhbmNlb2YgU291cmNlRmlsZSkge1xyXG4gICAgICAgIHJldHVybiBlbnRpdHlEaWN0aW9uYXJ5LmNvbnZlcnRUb1JlbGF0aXZlUGF0aChwYXRoLm5vcm1hbGl6ZShub2RlLmdldEZpbGVQYXRoKCkpLCBhYnNvbHV0ZVBhdGhQcm9qZWN0KS5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgY3VycmVudE5vZGU6IE5vZGUgfCB1bmRlZmluZWQgPSBub2RlO1xyXG4gICAgd2hpbGUgKGN1cnJlbnROb2RlKSB7XHJcbiAgICAgICAgaWYgKE5vZGUuaXNTb3VyY2VGaWxlKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBlbnRpdHlEaWN0aW9uYXJ5LmNvbnZlcnRUb1JlbGF0aXZlUGF0aChwYXRoLm5vcm1hbGl6ZShjdXJyZW50Tm9kZS5nZXRGaWxlUGF0aCgpKSwgYWJzb2x1dGVQYXRoUHJvamVjdCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZVBhdGguaW5jbHVkZXMoXCIuLlwiKSkge1xyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBSZWxhdGl2ZSBwYXRoIGNvbnRhaW5zIC4uLzogJHtyZWxhdGl2ZVBhdGh9YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcGFydHMudW5zaGlmdChyZWxhdGl2ZVBhdGgpOyAvLyBBZGQgZmlsZSBwYXRoIGF0IHRoZSBzdGFydFxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnROb2RlLmdldFN5bWJvbCgpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBjdXJyZW50Tm9kZS5nZXRTeW1ib2woKSEuZ2V0TmFtZSgpO1xyXG4gICAgICAgICAgICAvLyBGb3IgYW5vbnltb3VzIG5vZGVzLCB1c2Uga2luZCBhbmQgcG9zaXRpb24gYXMgdW5pcXVlIGlkZW50aWZpZXJzXHJcbiAgICAgICAgICAgIGNvbnN0IGlkZW50aWZpZXIgPSBuYW1lICE9PSBcIl9fY29tcHV0ZWRcIiA/IG5hbWUgOiBgJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfV8ke2N1cnJlbnROb2RlLmdldFN0YXJ0TGluZVBvcygpfWA7XHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQoaWRlbnRpZmllcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUuZ2V0UGFyZW50KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHBhcnRzLmpvaW4oXCI6OlwiKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIG5hbWUgb2YgYSBub2RlLCBpZiBpdCBoYXMgb25lXHJcbiAqIEBwYXJhbSBhIEEgbm9kZVxyXG4gKiBAcmV0dXJucyBUaGUgbmFtZSBvZiB0aGUgbm9kZSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmVcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXROYW1lT2ZOb2RlKGE6IE5vZGUpOiBzdHJpbmcge1xyXG4gICAgbGV0IGNLaW5kOiBDbGFzc0RlY2xhcmF0aW9uIHwgdW5kZWZpbmVkO1xyXG4gICAgbGV0IGlLaW5kOiBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IHVuZGVmaW5lZDtcclxuICAgIGxldCBtS2luZDogTWV0aG9kRGVjbGFyYXRpb24gfCB1bmRlZmluZWQ7XHJcbiAgICBsZXQgZktpbmQ6IEZ1bmN0aW9uRGVjbGFyYXRpb24gfCB1bmRlZmluZWQ7XHJcbiAgICBsZXQgYWxpYXM6IFRTTW9ycGhUeXBlRGVjbGFyYXRpb24gfCB1bmRlZmluZWQ7XHJcbiAgICBzd2l0Y2ggKGEuZ2V0S2luZCgpKSB7XHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlNvdXJjZUZpbGU6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlNvdXJjZUZpbGUpIS5nZXRCYXNlTmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuTW9kdWxlRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLk1vZHVsZURlY2xhcmF0aW9uKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgY0tpbmQgPSBhLmFzS2luZChTeW50YXhLaW5kLkNsYXNzRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoY0tpbmQgJiYgY0tpbmQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY0tpbmQuZ2V0TmFtZSgpICsgZ2V0UGFyYW1ldGVycyhhKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjS2luZD8uZ2V0TmFtZSgpIHx8IFwiXCI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkludGVyZmFjZURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICBpS2luZCA9IGEuYXNLaW5kKFN5bnRheEtpbmQuSW50ZXJmYWNlRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoaUtpbmQgJiYgaUtpbmQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaUtpbmQuZ2V0TmFtZSgpICsgZ2V0UGFyYW1ldGVycyhhKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpS2luZD8uZ2V0TmFtZSgpIHx8IFwiXCI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlByb3BlcnR5RGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlByb3BlcnR5RGVjbGFyYXRpb24pIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5Qcm9wZXJ0eVNpZ25hdHVyZTpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuUHJvcGVydHlTaWduYXR1cmUpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5NZXRob2REZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgbUtpbmQgPSBhLmFzS2luZChTeW50YXhLaW5kLk1ldGhvZERlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgaWYgKG1LaW5kICYmIG1LaW5kLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG1LaW5kLmdldE5hbWUoKSArIGdldFBhcmFtZXRlcnMoYSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbUtpbmQ/LmdldE5hbWUoKSB8fCBcIlwiO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5NZXRob2RTaWduYXR1cmU6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLk1ldGhvZFNpZ25hdHVyZSkhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkdldEFjY2Vzc29yOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5HZXRBY2Nlc3NvcikhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlNldEFjY2Vzc29yOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5TZXRBY2Nlc3NvcikhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkZ1bmN0aW9uRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIGZLaW5kID0gYS5hc0tpbmQoU3ludGF4S2luZC5GdW5jdGlvbkRlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgaWYgKGZLaW5kICYmIGZLaW5kLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZLaW5kLmdldE5hbWUoKSArIGdldFBhcmFtZXRlcnMoYSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZktpbmQ/LmdldE5hbWUoKSB8fCBcIlwiO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5GdW5jdGlvbkV4cHJlc3Npb246XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLkZ1bmN0aW9uRXhwcmVzc2lvbik/LmdldE5hbWUoKSB8fCBcImFub255bW91c1wiO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuUGFyYW1ldGVyOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5QYXJhbWV0ZXIpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5WYXJpYWJsZURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5WYXJpYWJsZURlY2xhcmF0aW9uKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuRGVjb3JhdG9yOlxyXG4gICAgICAgICAgICByZXR1cm4gXCJAXCIgKyBhLmFzS2luZChTeW50YXhLaW5kLkRlY29yYXRvcikhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlR5cGVQYXJhbWV0ZXI6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlR5cGVQYXJhbWV0ZXIpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5FbnVtRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLkVudW1EZWNsYXJhdGlvbikhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkVudW1NZW1iZXI6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLkVudW1NZW1iZXIpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5UeXBlQWxpYXNEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgLy8gc3BlY2lhbCBjYXNlIGZvciBwYXJhbWV0ZXJpemVkIHR5cGVzXHJcbiAgICAgICAgICAgIGFsaWFzID0gYS5hc0tpbmQoU3ludGF4S2luZC5UeXBlQWxpYXNEZWNsYXJhdGlvbik7XHJcbiAgICAgICAgICAgIGlmIChhbGlhcyAmJiBhbGlhcy5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhbGlhcy5nZXROYW1lKCkgKyBcIjxcIiArIGFsaWFzLmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKHRwID0+IHRwLmdldE5hbWUoKSkuam9pbihcIiwgXCIpICsgXCI+XCI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuVHlwZUFsaWFzRGVjbGFyYXRpb24pIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5Db25zdHJ1Y3RvcjpcclxuICAgICAgICAgICAgcmV0dXJuIFwiY29uc3RydWN0b3JcIjtcclxuXHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKGBnZXROYW1lT2ZOb2RlIGNhbGxlZCBvbiBhIG5vZGUgdGhhdCBkb2Vzbid0IGhhdmUgYSBuYW1lOiAke2EuZ2V0S2luZE5hbWUoKX1gKTtcclxuICAgICAgICAgICAgLy8gYW5jZXN0b3IgaGFzbid0IGdvdCBhIHVzZWZ1bCBuYW1lXHJcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgbmFtZSBvZiBhIG5vZGUsIGlmIGl0IGhhcyBvbmVcclxuICogQHBhcmFtIGEgQSBub2RlXHJcbiAqIEByZXR1cm5zIFRoZSBuYW1lIG9mIHRoZSBub2RlLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgaXQgZG9lc24ndCBoYXZlIG9uZVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldFBhcmFtZXRlcnMoYTogTm9kZSk6IHN0cmluZyB7XHJcbiAgICBsZXQgcGFyYW1TdHJpbmcgPSBcIlwiO1xyXG4gICAgc3dpdGNoIChhLmdldEtpbmQoKSkge1xyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5DbGFzc0RlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICBwYXJhbVN0cmluZyA9IFwiPFwiICsgYS5hc0tpbmQoU3ludGF4S2luZC5DbGFzc0RlY2xhcmF0aW9uKT8uZ2V0VHlwZVBhcmFtZXRlcnMoKS5tYXAodHAgPT4gdHAuZ2V0TmFtZSgpKS5qb2luKFwiLCBcIikgKyBcIj5cIjtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkludGVyZmFjZURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICBwYXJhbVN0cmluZyA9IFwiPFwiICsgYS5hc0tpbmQoU3ludGF4S2luZC5JbnRlcmZhY2VEZWNsYXJhdGlvbik/LmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKHRwID0+IHRwLmdldE5hbWUoKSkuam9pbihcIiwgXCIpICsgXCI+XCI7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5NZXRob2REZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcGFyYW1TdHJpbmcgPSBcIjxcIiArIGEuYXNLaW5kKFN5bnRheEtpbmQuTWV0aG9kRGVjbGFyYXRpb24pPy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCh0cCA9PiB0cC5nZXROYW1lKCkpLmpvaW4oXCIsIFwiKSArIFwiPlwiO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuRnVuY3Rpb25EZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcGFyYW1TdHJpbmcgPSBcIjxcIiArIGEuYXNLaW5kKFN5bnRheEtpbmQuRnVuY3Rpb25EZWNsYXJhdGlvbik/LmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKHRwID0+IHRwLmdldE5hbWUoKSkuam9pbihcIiwgXCIpICsgXCI+XCI7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZ2V0UGFyYW1ldGVycyBjYWxsZWQgb24gYSBub2RlIHRoYXQgZG9lc24ndCBoYXZlIHBhcmFtZXRlcnM6ICR7YS5nZXRLaW5kTmFtZSgpfWApO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHBhcmFtU3RyaW5nO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgRlFOIG9mIGFuIHVucmVzb2x2ZWQgaW50ZXJmYWNlIHRoYXQgaXMgYmVpbmcgaW1wbGVtZW50ZWQgb3IgZXh0ZW5kZWRcclxuICogQHBhcmFtIHVucmVzb2x2ZWRJbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlIFRoZSBleHByZXNzaW9uIHdpdGggdHlwZSBhcmd1bWVudHMgcmVwcmVzZW50aW5nIHRoZSBpbnRlcmZhY2VcclxuICogQHJldHVybnMgVGhlIEZRTiBvZiB0aGUgdW5yZXNvbHZlZCBpbnRlcmZhY2VcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGUU5VbnJlc29sdmVkSW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZSh1bnJlc29sdmVkSW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZTogRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzKTogc3RyaW5nIHtcclxuICAgIC8vIENoZWNrIGZvciBlaXRoZXIgQ2xhc3NEZWNsYXJhdGlvbiBvciBJbnRlcmZhY2VEZWNsYXJhdGlvbiBhbmNlc3RvclxyXG4gICAgY29uc3QgY2xhc3NBbmNlc3RvciA9IHVucmVzb2x2ZWRJbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlLmdldEZpcnN0QW5jZXN0b3JCeUtpbmQoU3ludGF4S2luZC5DbGFzc0RlY2xhcmF0aW9uKTtcclxuICAgIGNvbnN0IGludGVyZmFjZUFuY2VzdG9yID0gdW5yZXNvbHZlZEluaGVyaXRlZENsYXNzT3JJbnRlcmZhY2UuZ2V0Rmlyc3RBbmNlc3RvckJ5S2luZChTeW50YXhLaW5kLkludGVyZmFjZURlY2xhcmF0aW9uKTtcclxuXHJcbiAgICAvLyBWYWxpZGF0ZSB0aGUgY29udGV4dFxyXG4gICAgaWYgKCFjbGFzc0FuY2VzdG9yICYmICFpbnRlcmZhY2VBbmNlc3Rvcikge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImdldEZRTlVucmVzb2x2ZWRDbGFzc09ySW50ZXJmYWNlIGNhbGxlZCBvbiBhIG5vZGUgdGhhdCBpcyBub3QgaW4gYW4gaW1wbGVtZW50cyBvciBleHRlbmRzIGNvbnRleHRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIGltcGxlbWVudHMvZXh0ZW5kcyBjb250ZXh0XHJcbiAgICBsZXQgaXNWYWxpZENvbnRleHQgPSBmYWxzZTtcclxuXHJcbiAgICBsZXQgY2xhc3NFeHRlbmRzQ2xhc3MgPSBmYWxzZTtcclxuXHJcbiAgICBpZiAoY2xhc3NBbmNlc3Rvcikge1xyXG4gICAgICAgIC8vIGNoZWNrIGlmIHRoZSBjbGFzcyBpcyBleHRlbmRpbmcgb3IgaW1wbGVtZW50aW5nIGFuIGludGVyZmFjZVxyXG4gICAgICAgIGNvbnN0IGV4dGVuZHNDbGF1c2UgPSBjbGFzc0FuY2VzdG9yLmdldEV4dGVuZHMoKTtcclxuICAgICAgICBjb25zdCBpbXBsZW1lbnRzQ2xhdXNlID0gY2xhc3NBbmNlc3Rvci5nZXRJbXBsZW1lbnRzKCk7XHJcbiAgICAgICAgaXNWYWxpZENvbnRleHQgPSAoZXh0ZW5kc0NsYXVzZSAhPT0gdW5kZWZpbmVkKSB8fCAoaW1wbGVtZW50c0NsYXVzZSAmJiBpbXBsZW1lbnRzQ2xhdXNlLmxlbmd0aCA+IDApO1xyXG4gICAgICAgIGNsYXNzRXh0ZW5kc0NsYXNzID0gZXh0ZW5kc0NsYXVzZSAhPT0gdW5kZWZpbmVkO1xyXG4gICAgfSBlbHNlIGlmIChpbnRlcmZhY2VBbmNlc3Rvcikge1xyXG4gICAgICAgIC8vIENoZWNrIGV4dGVuZHMgY2xhdXNlIGZvciBpbnRlcmZhY2VzXHJcbiAgICAgICAgY29uc3QgZXh0ZW5kc0NsYXVzZSA9IGludGVyZmFjZUFuY2VzdG9yLmdldEV4dGVuZHMoKTtcclxuICAgICAgICBpc1ZhbGlkQ29udGV4dCA9IGV4dGVuZHNDbGF1c2UgJiYgZXh0ZW5kc0NsYXVzZS5sZW5ndGggPiAwO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghaXNWYWxpZENvbnRleHQpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJnZXRGUU5VbnJlc29sdmVkSW50ZXJmYWNlIGNhbGxlZCBvbiBhIG5vZGUgdGhhdCBpcyBub3QgaW4gYSB2YWxpZCBpbXBsZW1lbnRzIG9yIGV4dGVuZHMgY29udGV4dFwiKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBnZXQgdGhlIG5hbWUgb2YgdGhlIGludGVyZmFjZVxyXG4gICAgY29uc3QgbmFtZSA9IHVucmVzb2x2ZWRJbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlLmdldEV4cHJlc3Npb24oKS5nZXRUZXh0KCk7XHJcblxyXG4gICAgLy8gRmluZCB3aGVyZSBpdCdzIGltcG9ydGVkIC0gc2VhcmNoIHRoZSBlbnRpcmUgc291cmNlIGZpbGVcclxuICAgIGNvbnN0IHNvdXJjZUZpbGUgPSB1bnJlc29sdmVkSW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZS5nZXRTb3VyY2VGaWxlKCk7XHJcbiAgICBjb25zdCBpbXBvcnREZWNscyA9IHNvdXJjZUZpbGUuZ2V0SW1wb3J0RGVjbGFyYXRpb25zKCk7XHJcblxyXG4gICAgZm9yIChjb25zdCBpbXBvcnREZWNsIG9mIGltcG9ydERlY2xzKSB7XHJcbiAgICAgICAgY29uc3QgbW9kdWxlU3BlY2lmaWVyID0gaW1wb3J0RGVjbC5nZXRNb2R1bGVTcGVjaWZpZXJWYWx1ZSgpO1xyXG4gICAgICAgIGNvbnN0IGltcG9ydENsYXVzZSA9IGltcG9ydERlY2wuZ2V0SW1wb3J0Q2xhdXNlKCk7XHJcblxyXG4gICAgICAgIGlmIChpbXBvcnRDbGF1c2UpIHtcclxuICAgICAgICAgICAgY29uc3QgbmFtZWRJbXBvcnRzID0gaW1wb3J0Q2xhdXNlLmdldE5hbWVkSW1wb3J0cygpO1xyXG4gICAgICAgICAgICAvLyBkZWNsYXJhdGlvbk5hbWUgaXMgQ2xhc3NEZWNsYXJhdGlvbiBpZiBcImNsYXNzIGV4dGVuZHMgY2xhc3NcIlxyXG4gICAgICAgICAgICBjb25zdCBkZWNsYXJhdGlvbk5hbWUgPSBjbGFzc0V4dGVuZHNDbGFzcyA/IFwiQ2xhc3NEZWNsYXJhdGlvblwiIDogXCJJbnRlcmZhY2VEZWNsYXJhdGlvblwiO1xyXG5cclxuICAgICAgICAgICAgZm9yIChjb25zdCBuYW1lZEltcG9ydCBvZiBuYW1lZEltcG9ydHMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChuYW1lZEltcG9ydC5nZXROYW1lKCkgPT09IG5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGltcG9ydCBmb3IgJHtuYW1lfSBpbiAke21vZHVsZVNwZWNpZmllcn1gKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYHttb2R1bGU6JHttb2R1bGVTcGVjaWZpZXJ9fS4ke25hbWV9WyR7ZGVjbGFyYXRpb25OYW1lfV1gO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIElmIG5vdCBmb3VuZCwgcmV0dXJuIGEgZGVmYXVsdCBGUU4gZm9ybWF0XHJcbiAgICByZXR1cm4gYHt1bmtub3duLW1vZHVsZX0uJHtuYW1lfVtJbnRlcmZhY2VEZWNsYXJhdGlvbl1gO1xyXG59XHJcblxyXG4iXX0=
|