ts2famix 2.0.1 → 2.0.4
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/dist/analyze.js +19 -9
- package/dist/analyze_functions/process_functions.js +127 -67
- package/dist/famix_functions/EntityDictionary.js +803 -356
- package/dist/famix_functions/helpers_creation.js +35 -19
- package/dist/fqn.js +384 -18
- package/dist/lib/famix/famix_repository.js +76 -2
- package/dist/lib/famix/index.js +18 -8
- package/dist/refactorer/refactor-getter-setter.js +18 -8
- package/dist/ts2famix-cli-wrapper.js +18 -8
- package/dist/ts2famix-cli.js +18 -8
- package/dist/ts2famix-tsconfig.js +18 -8
- package/doc-uml/famix-typescript-model.puml +29 -17
- package/doc-uml/famix-typescript-model.svg +1 -1
- package/eslint.config.mjs +28 -0
- package/jest.config.json +1 -1
- package/package.json +32 -12
- package/src/analyze.ts +1 -1
- package/src/analyze_functions/process_functions.ts +168 -118
- package/src/famix_functions/EntityDictionary.ts +909 -441
- package/src/famix_functions/helpers_creation.ts +23 -15
- package/src/fqn.ts +450 -50
- package/src/lib/famix/famix_repository.ts +46 -1
- package/tsconfig.json +1 -0
package/dist/fqn.js
CHANGED
|
@@ -7,17 +7,224 @@ 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
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
13
15
|
function isFQNNode(node) {
|
|
14
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);
|
|
15
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
|
+
*/
|
|
16
221
|
function getFQN(node) {
|
|
17
|
-
const absolutePathProject = analyze_1.entityDictionary.famixRep.getAbsolutePath();
|
|
18
222
|
const sourceFile = node.getSourceFile();
|
|
19
|
-
|
|
223
|
+
const absolutePathProject = analyze_1.entityDictionary.famixRep.getAbsolutePath();
|
|
224
|
+
const parts = [];
|
|
20
225
|
let currentNode = node;
|
|
226
|
+
const stageMap = buildStageMethodMap(sourceFile);
|
|
227
|
+
const methodPositionMap = buildMethodPositionMap(sourceFile);
|
|
21
228
|
while (currentNode && !ts_morph_1.Node.isSourceFile(currentNode)) {
|
|
22
229
|
const { line, column } = sourceFile.getLineAndColumnAtPos(currentNode.getStart());
|
|
23
230
|
const lc = `${line}:${column}`;
|
|
@@ -30,10 +237,85 @@ function getFQN(node) {
|
|
|
30
237
|
ts_morph_1.Node.isVariableDeclaration(currentNode) ||
|
|
31
238
|
ts_morph_1.Node.isGetAccessorDeclaration(currentNode) ||
|
|
32
239
|
ts_morph_1.Node.isSetAccessorDeclaration(currentNode) ||
|
|
240
|
+
ts_morph_1.Node.isPropertyDeclaration(currentNode) ||
|
|
241
|
+
ts_morph_1.Node.isParameterDeclaration(currentNode) ||
|
|
242
|
+
ts_morph_1.Node.isDecorator(currentNode) ||
|
|
243
|
+
ts_morph_1.Node.isTypeAliasDeclaration(currentNode) ||
|
|
244
|
+
ts_morph_1.Node.isEnumDeclaration(currentNode) ||
|
|
245
|
+
ts_morph_1.Node.isEnumMember(currentNode) ||
|
|
246
|
+
ts_morph_1.Node.isParametered(currentNode) ||
|
|
247
|
+
ts_morph_1.Node.isPropertySignature(currentNode) ||
|
|
248
|
+
ts_morph_1.Node.isArrayLiteralExpression(currentNode) ||
|
|
249
|
+
ts_morph_1.Node.isImportSpecifier(currentNode) ||
|
|
33
250
|
ts_morph_1.Node.isIdentifier(currentNode)) {
|
|
34
|
-
let name
|
|
35
|
-
|
|
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
|
+
}
|
|
36
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
|
+
}
|
|
37
319
|
}
|
|
38
320
|
else if (ts_morph_1.Node.isArrowFunction(currentNode) ||
|
|
39
321
|
ts_morph_1.Node.isBlock(currentNode) ||
|
|
@@ -41,27 +323,43 @@ function getFQN(node) {
|
|
|
41
323
|
ts_morph_1.Node.isForOfStatement(currentNode) ||
|
|
42
324
|
ts_morph_1.Node.isForStatement(currentNode) ||
|
|
43
325
|
ts_morph_1.Node.isCatchClause(currentNode)) {
|
|
44
|
-
|
|
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
|
|
45
339
|
}
|
|
46
340
|
else if (ts_morph_1.Node.isConstructorDeclaration(currentNode)) {
|
|
47
|
-
|
|
341
|
+
const name = "constructor";
|
|
342
|
+
parts.unshift(name);
|
|
48
343
|
}
|
|
49
344
|
else {
|
|
50
|
-
|
|
51
|
-
//console.log(`Ignoring node kind: ${currentNode.getKindName()}`);
|
|
345
|
+
console.log(`[getFQN] Ignoring node kind: ${currentNode.getKindName()}`);
|
|
52
346
|
}
|
|
53
347
|
currentNode = currentNode.getParent();
|
|
54
348
|
}
|
|
55
|
-
|
|
56
|
-
|
|
349
|
+
let relativePath = analyze_1.entityDictionary.convertToRelativePath(path_1.default.normalize(sourceFile.getFilePath()), absolutePathProject).replace(/\\/g, "/");
|
|
350
|
+
// if (relativePath.includes("..")) {
|
|
351
|
+
// }
|
|
352
|
+
if (relativePath.startsWith("/")) {
|
|
353
|
+
relativePath = relativePath.slice(1);
|
|
354
|
+
}
|
|
57
355
|
parts.unshift(`{${relativePath}}`);
|
|
58
|
-
const fqn = parts.join(".") + `[${node.getKindName()}]`;
|
|
59
|
-
|
|
356
|
+
const fqn = parts.join(".") + `[${node.getKindName()}]`;
|
|
357
|
+
// console.log(`[getFQN] Final FQN: ${fqn}`);
|
|
60
358
|
return fqn;
|
|
61
359
|
}
|
|
62
360
|
function getUniqueFQN(node) {
|
|
63
361
|
const absolutePathProject = analyze_1.entityDictionary.famixRep.getAbsolutePath();
|
|
64
|
-
|
|
362
|
+
const parts = [];
|
|
65
363
|
if (node instanceof ts_morph_1.SourceFile) {
|
|
66
364
|
return analyze_1.entityDictionary.convertToRelativePath(path_1.default.normalize(node.getFilePath()), absolutePathProject).replace(/\\/g, "/");
|
|
67
365
|
}
|
|
@@ -69,6 +367,9 @@ function getUniqueFQN(node) {
|
|
|
69
367
|
while (currentNode) {
|
|
70
368
|
if (ts_morph_1.Node.isSourceFile(currentNode)) {
|
|
71
369
|
const relativePath = analyze_1.entityDictionary.convertToRelativePath(path_1.default.normalize(currentNode.getFilePath()), absolutePathProject).replace(/\\/g, "/");
|
|
370
|
+
if (relativePath.includes("..")) {
|
|
371
|
+
analyze_1.logger.error(`Relative path contains ../: ${relativePath}`);
|
|
372
|
+
}
|
|
72
373
|
parts.unshift(relativePath); // Add file path at the start
|
|
73
374
|
break;
|
|
74
375
|
}
|
|
@@ -88,13 +389,18 @@ function getUniqueFQN(node) {
|
|
|
88
389
|
* @returns The name of the node, or an empty string if it doesn't have one
|
|
89
390
|
*/
|
|
90
391
|
function getNameOfNode(a) {
|
|
392
|
+
let cKind;
|
|
393
|
+
let iKind;
|
|
394
|
+
let mKind;
|
|
395
|
+
let fKind;
|
|
396
|
+
let alias;
|
|
91
397
|
switch (a.getKind()) {
|
|
92
398
|
case ts_morph_1.SyntaxKind.SourceFile:
|
|
93
399
|
return a.asKind(ts_morph_1.SyntaxKind.SourceFile).getBaseName();
|
|
94
400
|
case ts_morph_1.SyntaxKind.ModuleDeclaration:
|
|
95
401
|
return a.asKind(ts_morph_1.SyntaxKind.ModuleDeclaration).getName();
|
|
96
402
|
case ts_morph_1.SyntaxKind.ClassDeclaration:
|
|
97
|
-
|
|
403
|
+
cKind = a.asKind(ts_morph_1.SyntaxKind.ClassDeclaration);
|
|
98
404
|
if (cKind && cKind.getTypeParameters().length > 0) {
|
|
99
405
|
return cKind.getName() + getParameters(a);
|
|
100
406
|
}
|
|
@@ -102,7 +408,7 @@ function getNameOfNode(a) {
|
|
|
102
408
|
return cKind?.getName() || "";
|
|
103
409
|
}
|
|
104
410
|
case ts_morph_1.SyntaxKind.InterfaceDeclaration:
|
|
105
|
-
|
|
411
|
+
iKind = a.asKind(ts_morph_1.SyntaxKind.InterfaceDeclaration);
|
|
106
412
|
if (iKind && iKind.getTypeParameters().length > 0) {
|
|
107
413
|
return iKind.getName() + getParameters(a);
|
|
108
414
|
}
|
|
@@ -114,7 +420,7 @@ function getNameOfNode(a) {
|
|
|
114
420
|
case ts_morph_1.SyntaxKind.PropertySignature:
|
|
115
421
|
return a.asKind(ts_morph_1.SyntaxKind.PropertySignature).getName();
|
|
116
422
|
case ts_morph_1.SyntaxKind.MethodDeclaration:
|
|
117
|
-
|
|
423
|
+
mKind = a.asKind(ts_morph_1.SyntaxKind.MethodDeclaration);
|
|
118
424
|
if (mKind && mKind.getTypeParameters().length > 0) {
|
|
119
425
|
return mKind.getName() + getParameters(a);
|
|
120
426
|
}
|
|
@@ -128,7 +434,7 @@ function getNameOfNode(a) {
|
|
|
128
434
|
case ts_morph_1.SyntaxKind.SetAccessor:
|
|
129
435
|
return a.asKind(ts_morph_1.SyntaxKind.SetAccessor).getName();
|
|
130
436
|
case ts_morph_1.SyntaxKind.FunctionDeclaration:
|
|
131
|
-
|
|
437
|
+
fKind = a.asKind(ts_morph_1.SyntaxKind.FunctionDeclaration);
|
|
132
438
|
if (fKind && fKind.getTypeParameters().length > 0) {
|
|
133
439
|
return fKind.getName() + getParameters(a);
|
|
134
440
|
}
|
|
@@ -150,10 +456,16 @@ function getNameOfNode(a) {
|
|
|
150
456
|
case ts_morph_1.SyntaxKind.EnumMember:
|
|
151
457
|
return a.asKind(ts_morph_1.SyntaxKind.EnumMember).getName();
|
|
152
458
|
case ts_morph_1.SyntaxKind.TypeAliasDeclaration:
|
|
459
|
+
// special case for parameterized types
|
|
460
|
+
alias = a.asKind(ts_morph_1.SyntaxKind.TypeAliasDeclaration);
|
|
461
|
+
if (alias && alias.getTypeParameters().length > 0) {
|
|
462
|
+
return alias.getName() + "<" + alias.getTypeParameters().map(tp => tp.getName()).join(", ") + ">";
|
|
463
|
+
}
|
|
153
464
|
return a.asKind(ts_morph_1.SyntaxKind.TypeAliasDeclaration).getName();
|
|
154
465
|
case ts_morph_1.SyntaxKind.Constructor:
|
|
155
466
|
return "constructor";
|
|
156
467
|
default:
|
|
468
|
+
// throw new Error(`getNameOfNode called on a node that doesn't have a name: ${a.getKindName()}`);
|
|
157
469
|
// ancestor hasn't got a useful name
|
|
158
470
|
return "";
|
|
159
471
|
}
|
|
@@ -183,4 +495,58 @@ function getParameters(a) {
|
|
|
183
495
|
}
|
|
184
496
|
return paramString;
|
|
185
497
|
}
|
|
186
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnFuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Zxbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVlBLHdCQWtEQztBQUdELG9DQXdCQztBQU9ELHNDQXNGQztBQU9ELHNDQW1CQztBQWhORCx1Q0FBZ2Q7QUFDaGQsdUNBQXFEO0FBQ3JELGdEQUF3QjtBQUt4QixTQUFTLFNBQVMsQ0FBQyxJQUFVO0lBQ3pCLE9BQU8sZUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFFblMsQ0FBQztBQUVELFNBQWdCLE1BQU0sQ0FBQyxJQUFvQjtJQUN2QyxNQUFNLG1CQUFtQixHQUFHLDBCQUFnQixDQUFDLFFBQVEsQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUV4RSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDeEMsSUFBSSxLQUFLLEdBQWEsRUFBRSxDQUFDO0lBQ3pCLElBQUksV0FBVyxHQUFxQixJQUFJLENBQUM7SUFFekMsT0FBTyxXQUFXLElBQUksQ0FBQyxlQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7UUFDcEQsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsR0FBRyxVQUFVLENBQUMscUJBQXFCLENBQUMsV0FBVyxDQUFDLFFB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QUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDO1lBQ3pILE1BQU07UUFDVixLQUFLLHFCQUFVLENBQUMsbUJBQW1CO1lBQy9CLFdBQVcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxxQkFBVSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDO1lBQzNILE1BQU07UUFDVjtZQUNJLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0VBQWdFLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDM0csQ0FBQztJQUNELE9BQU8sV0FBVyxDQUFDO0FBQ3ZCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBcnJvd0Z1bmN0aW9uLCBDYWxsRXhwcmVzc2lvbiwgQ2xhc3NEZWNsYXJhdGlvbiwgQ2xhc3NFeHByZXNzaW9uLCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uLCBEZWNvcmF0b3IsIEVudW1EZWNsYXJhdGlvbiwgRnVuY3Rpb25EZWNsYXJhdGlvbiwgRnVuY3Rpb25FeHByZXNzaW9uLCBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uLCBJZGVudGlmaWVyLCBJbXBvcnREZWNsYXJhdGlvbiwgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24sIEludGVyZmFjZURlY2xhcmF0aW9uLCBNZXRob2REZWNsYXJhdGlvbiwgTWV0aG9kU2lnbmF0dXJlLCBNb2R1bGVEZWNsYXJhdGlvbiwgTm9kZSwgUHJvcGVydHlEZWNsYXJhdGlvbiwgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbiwgU291cmNlRmlsZSwgU3ludGF4S2luZCwgVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uLCBWYXJpYWJsZURlY2xhcmF0aW9uIH0gZnJvbSBcInRzLW1vcnBoXCI7XHJcbmltcG9ydCB7IGVudGl0eURpY3Rpb25hcnksIGxvZ2dlciB9IGZyb20gXCIuL2FuYWx5emVcIjtcclxuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcclxuaW1wb3J0IHsgVHlwZURlY2xhcmF0aW9uIH0gZnJvbSBcIi4vZmFtaXhfZnVuY3Rpb25zL0VudGl0eURpY3Rpb25hcnlcIjtcclxuXHJcbnR5cGUgRlFOTm9kZSA9IFNvdXJjZUZpbGUgfCBWYXJpYWJsZURlY2xhcmF0aW9uIHwgQXJyb3dGdW5jdGlvbiB8IElkZW50aWZpZXIgfCBNZXRob2REZWNsYXJhdGlvbiB8IE1ldGhvZFNpZ25hdHVyZSB8IEZ1bmN0aW9uRGVjbGFyYXRpb24gfCBGdW5jdGlvbkV4cHJlc3Npb24gfCBQcm9wZXJ0eURlY2xhcmF0aW9uIHwgVHlwZURlY2xhcmF0aW9uIHwgRW51bURlY2xhcmF0aW9uIHwgSW1wb3J0RGVjbGFyYXRpb24gfCBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiB8IENhbGxFeHByZXNzaW9uIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uIHwgQ2xhc3NEZWNsYXJhdGlvbiB8IEludGVyZmFjZURlY2xhcmF0aW9uIHwgRGVjb3JhdG9yIHwgTW9kdWxlRGVjbGFyYXRpb247XHJcblxyXG5mdW5jdGlvbiBpc0ZRTk5vZGUobm9kZTogTm9kZSk6IG5vZGUgaXMgRlFOTm9kZSB7XHJcbiAgICByZXR1cm4gTm9kZS5pc1ZhcmlhYmxlRGVjbGFyYXRpb24obm9kZSkgfHwgTm9kZS5pc0Fycm93RnVuY3Rpb24obm9kZSkgfHwgTm9kZS5pc0lkZW50aWZpZXIobm9kZSkgfHwgTm9kZS5pc01ldGhvZERlY2xhcmF0aW9uKG5vZGUpIHx8IE5vZGUuaXNDbGFzc0RlY2xhcmF0aW9uKG5vZGUpIHx8IE5vZGUuaXNDbGFzc0V4cHJlc3Npb24obm9kZSkgfHwgTm9kZS5pc0RlY29yYXRvcihub2RlKSB8fCBOb2RlLmlzTW9kdWxlRGVjbGFyYXRpb24obm9kZSkgfHwgTm9kZS5pc0NhbGxFeHByZXNzaW9uKG5vZGUpO1xyXG5cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZRTihub2RlOiBGUU5Ob2RlIHwgTm9kZSk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBhYnNvbHV0ZVBhdGhQcm9qZWN0ID0gZW50aXR5RGljdGlvbmFyeS5mYW1peFJlcC5nZXRBYnNvbHV0ZVBhdGgoKTtcclxuXHJcbiAgICBjb25zdCBzb3VyY2VGaWxlID0gbm9kZS5nZXRTb3VyY2VGaWxlKCk7XHJcbiAgICBsZXQgcGFydHM6IHN0cmluZ1tdID0gW107XHJcbiAgICBsZXQgY3VycmVudE5vZGU6IE5vZGUgfCB1bmRlZmluZWQgPSBub2RlO1xyXG5cclxuICAgIHdoaWxlIChjdXJyZW50Tm9kZSAmJiAhTm9kZS5pc1NvdXJjZUZpbGUoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgY29uc3QgeyBsaW5lLCBjb2x1bW4gfSA9IHNvdXJjZUZpbGUuZ2V0TGluZUFuZENvbHVtbkF0UG9zKGN1cnJlbnROb2RlLmdldFN0YXJ0KCkpO1xyXG4gICAgICAgIGNvbnN0IGxjID0gYCR7bGluZX06JHtjb2x1bW59YDtcclxuICAgICAgICBpZiAoTm9kZS5pc0NsYXNzRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8IFxyXG4gICAgICAgICAgICBOb2RlLmlzQ2xhc3NFeHByZXNzaW9uKGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgTm9kZS5pc0ludGVyZmFjZURlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzRnVuY3Rpb25EZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgIE5vZGUuaXNNZXRob2REZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgIE5vZGUuaXNNb2R1bGVEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgIE5vZGUuaXNWYXJpYWJsZURlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgTm9kZS5pc0dldEFjY2Vzc29yRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNTZXRBY2Nlc3NvckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzSWRlbnRpZmllcihjdXJyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgbGV0IG5hbWUgPSBOb2RlLmlzSWRlbnRpZmllcihjdXJyZW50Tm9kZSkgPyBjdXJyZW50Tm9kZS5nZXRUZXh0KCkgXHJcbiAgICAgICAgICAgICAgICA6IGdldE5hbWVPZk5vZGUoY3VycmVudE5vZGUpIC8qIGN1cnJlbnROb2RlLmdldE5hbWUoKSAqLyB8fCAnVW5uYW1lZF8nICsgY3VycmVudE5vZGUuZ2V0S2luZE5hbWUoKSArIGAoJHtsY30pYDtcclxuICAgICAgICAgICAgcGFydHMudW5zaGlmdChuYW1lKTtcclxuICAgICAgICB9IGVsc2UgaWYgKE5vZGUuaXNBcnJvd0Z1bmN0aW9uKGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgICAgICAgIE5vZGUuaXNCbG9jayhjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgICAgICAgICBOb2RlLmlzRm9ySW5TdGF0ZW1lbnQoY3VycmVudE5vZGUpIHx8IFxyXG4gICAgICAgICAgICAgICAgICAgTm9kZS5pc0Zvck9mU3RhdGVtZW50KGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgICAgICAgIE5vZGUuaXNGb3JTdGF0ZW1lbnQoY3VycmVudE5vZGUpIHx8IFxyXG4gICAgICAgICAgICAgICAgICAgTm9kZS5pc0NhdGNoQ2xhdXNlKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICBwYXJ0cy51bnNoaWZ0KGAke2N1cnJlbnROb2RlLmdldEtpbmROYW1lKCl9KCR7bGN9KWApO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoTm9kZS5pc0NvbnN0cnVjdG9yRGVjbGFyYXRpb24oY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQoYGNvbnN0cnVjdG9yYCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gRm9yIG90aGVyIGtpbmRzLCB5b3UgbWlnaHQgd2FudCB0byBoYW5kbGUgdGhlbSBzcGVjaWZpY2FsbHkgb3IgaWdub3JlXHJcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coYElnbm9yaW5nIG5vZGUga2luZDogJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfWApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLmdldFBhcmVudCgpO1xyXG4gICAgfVxyXG5cclxuXHJcblxyXG4gICAgLy8gUHJlcGVuZCB0aGUgcmVsYXRpdmUgcGF0aCBvZiB0aGUgc291cmNlIGZpbGVcclxuICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IGVudGl0eURpY3Rpb25hcnkuY29udmVydFRvUmVsYXRpdmVQYXRoKFxyXG4gICAgICAgIHBhdGgubm9ybWFsaXplKHNvdXJjZUZpbGUuZ2V0RmlsZVBhdGgoKSksIFxyXG4gICAgICAgICAgICAgICAgICAgICAgIGFic29sdXRlUGF0aFByb2plY3QpLnJlcGxhY2UoL1xcXFwvc2csIFwiL1wiKTtcclxuICAgIHBhcnRzLnVuc2hpZnQoYHske3JlbGF0aXZlUGF0aH19YCk7XHJcbiAgICBjb25zdCBmcW4gPSBwYXJ0cy5qb2luKFwiLlwiKSArIGBbJHtub2RlLmdldEtpbmROYW1lKCl9XWA7ICAvLyBkaXNhbWJpZ3VhdGVcclxuXHJcbiAgICBsb2dnZXIuZGVidWcoZnFuKTtcclxuICAgIHJldHVybiBmcW47XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0VW5pcXVlRlFOKG5vZGU6IE5vZGUpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xyXG4gICAgY29uc3QgYWJzb2x1dGVQYXRoUHJvamVjdCA9IGVudGl0eURpY3Rpb25hcnkuZmFtaXhSZXAuZ2V0QWJzb2x1dGVQYXRoKCk7XHJcbiAgICBsZXQgcGFydHM6IHN0cmluZ1tdID0gW107XHJcblxyXG4gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBTb3VyY2VGaWxlKSB7XHJcbiAgICAgICAgcmV0dXJuIGVudGl0eURpY3Rpb25hcnkuY29udmVydFRvUmVsYXRpdmVQYXRoKHBhdGgubm9ybWFsaXplKG5vZGUuZ2V0RmlsZVBhdGgoKSksIGFic29sdXRlUGF0aFByb2plY3QpLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCBjdXJyZW50Tm9kZTogTm9kZSB8IHVuZGVmaW5lZCA9IG5vZGU7XHJcbiAgICB3aGlsZSAoY3VycmVudE5vZGUpIHtcclxuICAgICAgICBpZiAoTm9kZS5pc1NvdXJjZUZpbGUoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IGVudGl0eURpY3Rpb25hcnkuY29udmVydFRvUmVsYXRpdmVQYXRoKHBhdGgubm9ybWFsaXplKGN1cnJlbnROb2RlLmdldEZpbGVQYXRoKCkpLCBhYnNvbHV0ZVBhdGhQcm9qZWN0KS5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKTtcclxuICAgICAgICAgICAgcGFydHMudW5zaGlmdChyZWxhdGl2ZVBhdGgpOyAvLyBBZGQgZmlsZSBwYXRoIGF0IHRoZSBzdGFydFxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnROb2RlLmdldFN5bWJvbCgpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBjdXJyZW50Tm9kZS5nZXRTeW1ib2woKSEuZ2V0TmFtZSgpO1xyXG4gICAgICAgICAgICAvLyBGb3IgYW5vbnltb3VzIG5vZGVzLCB1c2Uga2luZCBhbmQgcG9zaXRpb24gYXMgdW5pcXVlIGlkZW50aWZpZXJzXHJcbiAgICAgICAgICAgIGNvbnN0IGlkZW50aWZpZXIgPSBuYW1lICE9PSBcIl9fY29tcHV0ZWRcIiA/IG5hbWUgOiBgJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfV8ke2N1cnJlbnROb2RlLmdldFN0YXJ0TGluZVBvcygpfWA7XHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQoaWRlbnRpZmllcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUuZ2V0UGFyZW50KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHBhcnRzLmpvaW4oXCI6OlwiKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIG5hbWUgb2YgYSBub2RlLCBpZiBpdCBoYXMgb25lXHJcbiAqIEBwYXJhbSBhIEEgbm9kZVxyXG4gKiBAcmV0dXJucyBUaGUgbmFtZSBvZiB0aGUgbm9kZSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmVcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXROYW1lT2ZOb2RlKGE6IE5vZGUpOiBzdHJpbmcge1xyXG4gICAgc3dpdGNoIChhLmdldEtpbmQoKSkge1xyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5Tb3VyY2VGaWxlOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5Tb3VyY2VGaWxlKSEuZ2V0QmFzZU5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLk1vZHVsZURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5Nb2R1bGVEZWNsYXJhdGlvbikhLmdldE5hbWUoKTsgXHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5DbGFzc0RlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICBjb25zdCBjS2luZCA9IGEuYXNLaW5kKFN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbik7XHJcbiAgICAgICAgICAgIGlmIChjS2luZCAmJiBjS2luZC5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjS2luZC5nZXROYW1lKCkgKyBnZXRQYXJhbWV0ZXJzKGEpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNLaW5kPy5nZXROYW1lKCkgfHwgXCJcIjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuSW50ZXJmYWNlRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIGNvbnN0IGlLaW5kID0gYS5hc0tpbmQoU3ludGF4S2luZC5JbnRlcmZhY2VEZWNsYXJhdGlvbik7XHJcbiAgICAgICAgICAgIGlmIChpS2luZCAmJiBpS2luZC5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpS2luZC5nZXROYW1lKCkgKyBnZXRQYXJhbWV0ZXJzKGEpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGlLaW5kPy5nZXROYW1lKCkgfHwgXCJcIjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlByb3BlcnR5RGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlByb3BlcnR5RGVjbGFyYXRpb24pIS5nZXROYW1lKCk7ICAgIFxyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuUHJvcGVydHlTaWduYXR1cmU6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlByb3BlcnR5U2lnbmF0dXJlKSEuZ2V0TmFtZSgpOyAgICBcclxuICAgIFxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5NZXRob2REZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgY29uc3QgbUtpbmQgPSBhLmFzS2luZChTeW50YXhLaW5kLk1ldGhvZERlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgaWYgKG1LaW5kICYmIG1LaW5kLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG1LaW5kLmdldE5hbWUoKSArIGdldFBhcmFtZXRlcnMoYSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbUtpbmQ/LmdldE5hbWUoKSB8fCBcIlwiO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5NZXRob2RTaWduYXR1cmU6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLk1ldGhvZFNpZ25hdHVyZSkhLmdldE5hbWUoKTsgICBcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkdldEFjY2Vzc29yOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5HZXRBY2Nlc3NvcikhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlNldEFjY2Vzc29yOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5TZXRBY2Nlc3NvcikhLmdldE5hbWUoKTtcclxuICAgIFxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5GdW5jdGlvbkRlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICBjb25zdCBmS2luZCA9IGEuYXNLaW5kKFN5bnRheEtpbmQuRnVuY3Rpb25EZWNsYXJhdGlvbik7XHJcbiAgICAgICAgICAgIGlmIChmS2luZCAmJiBmS2luZC5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmS2luZC5nZXROYW1lKCkgKyBnZXRQYXJhbWV0ZXJzKGEpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZLaW5kPy5nZXROYW1lKCkgfHwgXCJcIjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuRnVuY3Rpb25FeHByZXNzaW9uOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5GdW5jdGlvbkV4cHJlc3Npb24pPy5nZXROYW1lKCkgfHwgXCJhbm9ueW1vdXNcIjtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlBhcmFtZXRlcjpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuUGFyYW1ldGVyKSEuZ2V0TmFtZSgpO1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlZhcmlhYmxlRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlZhcmlhYmxlRGVjbGFyYXRpb24pIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5EZWNvcmF0b3I6XHJcbiAgICAgICAgICAgIHJldHVybiBcIkBcIiArIGEuYXNLaW5kKFN5bnRheEtpbmQuRGVjb3JhdG9yKSEuZ2V0TmFtZSgpOyAgICBcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlR5cGVQYXJhbWV0ZXI6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlR5cGVQYXJhbWV0ZXIpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5FbnVtRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLkVudW1EZWNsYXJhdGlvbikhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkVudW1NZW1iZXI6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLkVudW1NZW1iZXIpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5UeXBlQWxpYXNEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuVHlwZUFsaWFzRGVjbGFyYXRpb24pIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5Db25zdHJ1Y3RvcjpcclxuICAgICAgICAgICAgcmV0dXJuIFwiY29uc3RydWN0b3JcIjsgICBcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgLy8gYW5jZXN0b3IgaGFzbid0IGdvdCBhIHVzZWZ1bCBuYW1lXHJcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIG5hbWUgb2YgYSBub2RlLCBpZiBpdCBoYXMgb25lXHJcbiAqIEBwYXJhbSBhIEEgbm9kZVxyXG4gKiBAcmV0dXJucyBUaGUgbmFtZSBvZiB0aGUgbm9kZSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmVcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRQYXJhbWV0ZXJzKGE6IE5vZGUpOiBzdHJpbmcge1xyXG4gICAgbGV0IHBhcmFtU3RyaW5nID0gXCJcIjtcclxuICAgIHN3aXRjaCAoYS5nZXRLaW5kKCkpIHtcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcGFyYW1TdHJpbmcgPSBcIjxcIiArIGEuYXNLaW5kKFN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbik/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=
|