@decaf-ts/mcp-server 0.0.2 → 0.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/LICENSE.md +86 -21
- package/README.md +13 -13
- package/dist/mcp-server.cjs +893 -187
- package/dist/mcp-server.esm.cjs +888 -180
- package/lib/McpWrapper.cjs +189 -0
- package/lib/McpWrapper.d.ts +101 -0
- package/lib/bin/cli.cjs +30 -54
- package/lib/bin/cli.d.ts +18 -44
- package/lib/constants.cjs +12 -0
- package/lib/constants.d.ts +8 -0
- package/lib/esm/McpWrapper.d.ts +101 -0
- package/lib/esm/McpWrapper.js +182 -0
- package/lib/esm/bin/cli.d.ts +18 -44
- package/lib/esm/bin/cli.js +28 -55
- package/lib/esm/constants.d.ts +8 -0
- package/lib/esm/constants.js +9 -0
- package/lib/esm/index.d.ts +5 -26
- package/lib/esm/index.js +6 -27
- package/lib/esm/mcp/index.d.ts +1 -0
- package/lib/esm/mcp/index.js +2 -0
- package/lib/esm/metadata.d.ts +9 -0
- package/lib/esm/metadata.js +22 -0
- package/lib/esm/modules/decoration/index.d.ts +0 -0
- package/lib/esm/modules/decoration/index.js +2 -0
- package/lib/esm/modules/mcp/decoration-assist.d.ts +39 -0
- package/lib/esm/modules/mcp/decoration-assist.js +353 -0
- package/lib/esm/modules/mcp/decorator-tools.d.ts +118 -0
- package/lib/esm/modules/mcp/decorator-tools.js +237 -0
- package/lib/esm/modules/mcp/index.d.ts +2 -0
- package/lib/esm/modules/mcp/index.js +3 -0
- package/lib/esm/modules/mcp/mcp-module.d.ts +230 -0
- package/lib/esm/modules/mcp/mcp-module.js +406 -0
- package/lib/esm/types.d.ts +15 -0
- package/lib/esm/types.js +2 -0
- package/lib/esm/utils.d.ts +54 -13
- package/lib/esm/utils.js +78 -15
- package/lib/index.cjs +6 -28
- package/lib/index.d.ts +5 -26
- package/lib/mcp/index.cjs +17 -0
- package/lib/mcp/index.d.ts +1 -0
- package/lib/metadata.cjs +25 -0
- package/lib/metadata.d.ts +9 -0
- package/lib/modules/decoration/index.cjs +2 -0
- package/lib/modules/decoration/index.d.ts +0 -0
- package/lib/modules/mcp/decoration-assist.cjs +360 -0
- package/lib/modules/mcp/decoration-assist.d.ts +39 -0
- package/lib/modules/mcp/decorator-tools.cjs +243 -0
- package/lib/modules/mcp/decorator-tools.d.ts +118 -0
- package/lib/modules/mcp/index.cjs +24 -0
- package/lib/modules/mcp/index.d.ts +2 -0
- package/lib/modules/mcp/mcp-module.cjs +452 -0
- package/lib/modules/mcp/mcp-module.d.ts +230 -0
- package/lib/types.cjs +3 -0
- package/lib/types.d.ts +15 -0
- package/lib/utils.cjs +116 -16
- package/lib/utils.d.ts +54 -13
- package/package.json +35 -7
- package/lib/esm/namespace/Class.d.ts +0 -74
- package/lib/esm/namespace/Class.js +0 -73
- package/lib/esm/namespace/Interface.d.ts +0 -17
- package/lib/esm/namespace/Interface.js +0 -2
- package/lib/esm/namespace/children/ChildClass.d.ts +0 -44
- package/lib/esm/namespace/children/ChildClass.js +0 -43
- package/lib/esm/namespace/children/ChildInterface.d.ts +0 -22
- package/lib/esm/namespace/children/ChildInterface.js +0 -2
- package/lib/esm/namespace/children/Enum.d.ts +0 -14
- package/lib/esm/namespace/children/Enum.js +0 -16
- package/lib/esm/namespace/children/function.d.ts +0 -31
- package/lib/esm/namespace/children/function.js +0 -33
- package/lib/esm/namespace/children/index.d.ts +0 -25
- package/lib/esm/namespace/children/index.js +0 -26
- package/lib/esm/namespace/index.d.ts +0 -18
- package/lib/esm/namespace/index.js +0 -19
- package/lib/esm/namespace/type.d.ts +0 -28
- package/lib/esm/namespace/type.js +0 -2
- package/lib/namespace/Class.cjs +0 -77
- package/lib/namespace/Class.d.ts +0 -74
- package/lib/namespace/Interface.cjs +0 -3
- package/lib/namespace/Interface.d.ts +0 -17
- package/lib/namespace/children/ChildClass.cjs +0 -47
- package/lib/namespace/children/ChildClass.d.ts +0 -44
- package/lib/namespace/children/ChildInterface.cjs +0 -3
- package/lib/namespace/children/ChildInterface.d.ts +0 -22
- package/lib/namespace/children/Enum.cjs +0 -19
- package/lib/namespace/children/Enum.d.ts +0 -14
- package/lib/namespace/children/function.cjs +0 -36
- package/lib/namespace/children/function.d.ts +0 -31
- package/lib/namespace/children/index.cjs +0 -42
- package/lib/namespace/children/index.d.ts +0 -25
- package/lib/namespace/index.cjs +0 -35
- package/lib/namespace/index.d.ts +0 -18
- package/lib/namespace/type.cjs +0 -3
- package/lib/namespace/type.d.ts +0 -28
package/dist/mcp-server.cjs
CHANGED
|
@@ -1,230 +1,936 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["mcp-server"] = {}));
|
|
5
|
-
})(this, (function (exports) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('fs'), require('path'), require('diff'), require('zod'), require('@decaf-ts/decoration'), require('fastmcp'), require('@decaf-ts/logging')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'fs', 'path', 'diff', 'zod', '@decaf-ts/decoration', 'fastmcp', '@decaf-ts/logging'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["mcp-server"] = {}, global.fs, global.path, global.diff, global.zod, global.decoration, global.fastmcp, global.logging));
|
|
5
|
+
})(this, (function (exports, fs, path, diff, zod, decoration, fastmcp, logging) { 'use strict';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @
|
|
9
|
-
* @
|
|
10
|
-
* @
|
|
11
|
-
*
|
|
12
|
-
* @
|
|
13
|
-
* @return {string} The resulting concatenated string
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* // returns "Hello Worlddefault"
|
|
17
|
-
* complexFunction();
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* // returns "Hello World!"
|
|
21
|
-
* complexFunction("!");
|
|
22
|
-
*
|
|
23
|
-
* @memberOf module:ts-workspace
|
|
8
|
+
* @const VERSION
|
|
9
|
+
* @name VERSION
|
|
10
|
+
* @description Represents the current version of the ts-workspace module.
|
|
11
|
+
* @summary The actual version number is replaced during the build process.
|
|
12
|
+
* @type {string}
|
|
24
13
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
14
|
+
const VERSION$1 = "0.0.3";
|
|
15
|
+
const PACKAGE_NAME$1 = "##PACKAGE_NAME##";
|
|
16
|
+
try {
|
|
17
|
+
decoration.Metadata.registerLibrary(PACKAGE_NAME$1, VERSION$1);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
if (error instanceof Error && error.message.includes("already")) ;
|
|
21
|
+
else {
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function escapeRegExp(value) {
|
|
27
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
28
|
+
}
|
|
29
|
+
function formatDecorator(spec) {
|
|
30
|
+
const args = (spec.args || []).map((arg) => JSON.stringify(arg)).join(", ");
|
|
31
|
+
return `@${spec.name}(${args})`;
|
|
32
|
+
}
|
|
33
|
+
function ensureDirectory(filePath) {
|
|
34
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
35
|
+
}
|
|
36
|
+
function collectDecoratorNames(classDecorators, properties) {
|
|
37
|
+
const names = new Set();
|
|
38
|
+
names.add("model");
|
|
39
|
+
for (const decorator of classDecorators || []) {
|
|
40
|
+
names.add(decorator.name);
|
|
41
|
+
}
|
|
42
|
+
for (const property of properties || []) {
|
|
43
|
+
for (const decorator of property.decorators || []) {
|
|
44
|
+
names.add(decorator.name);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return names;
|
|
48
|
+
}
|
|
49
|
+
function ensureImport(content, importsFrom, decorators) {
|
|
50
|
+
/* istanbul ignore next */
|
|
51
|
+
if (!decorators.size)
|
|
52
|
+
return content;
|
|
53
|
+
const importRegex = new RegExp(`import\\s+\\{([^}]+)\\}\\s+from\\s+["']${escapeRegExp(importsFrom)}["'];`);
|
|
54
|
+
const match = content.match(importRegex);
|
|
55
|
+
const sorted = Array.from(decorators).sort();
|
|
56
|
+
if (match) {
|
|
57
|
+
const existing = match[1]
|
|
58
|
+
.split(",")
|
|
59
|
+
.map((name) => name.trim())
|
|
60
|
+
.filter(Boolean);
|
|
61
|
+
const merged = Array.from(new Set([...existing, ...sorted])).sort();
|
|
62
|
+
return content.replace(importRegex, `import { ${merged.join(", ")} } from "${importsFrom}";`);
|
|
63
|
+
}
|
|
64
|
+
const importLine = `import { ${sorted.join(", ")} } from "${importsFrom}";`;
|
|
65
|
+
return `${importLine}\n\n${content}`;
|
|
66
|
+
}
|
|
67
|
+
function addPropertyBlock(property) {
|
|
68
|
+
const decorators = (property.decorators || [])
|
|
69
|
+
.map(formatDecorator)
|
|
70
|
+
.join("\n ");
|
|
71
|
+
const decoratorBlock = decorators ? ` ${decorators}\n` : "";
|
|
72
|
+
return `${decoratorBlock} ${property.name}: ${property.type};`;
|
|
73
|
+
}
|
|
74
|
+
function removePropertyBlock(content, propertyName) {
|
|
75
|
+
const lines = content.split(/\r?\n/);
|
|
76
|
+
const result = [];
|
|
77
|
+
for (let i = 0; i < lines.length; i++) {
|
|
78
|
+
const line = lines[i];
|
|
79
|
+
if (line.trim().startsWith(`@`) &&
|
|
80
|
+
lines[i + 1]?.includes(`${propertyName}:`)) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (line.includes(`${propertyName}:`)) {
|
|
84
|
+
// skip this line and any trailing blank line
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
result.push(line);
|
|
88
|
+
}
|
|
89
|
+
return result.join("\n");
|
|
90
|
+
}
|
|
91
|
+
function insertDecorator(content, decorator, target) {
|
|
92
|
+
const decoratorLine = formatDecorator(decorator);
|
|
93
|
+
if (target.kind === "class") {
|
|
94
|
+
const classRegex = /(export\s+class\s+[^\s{]+\s*\{)/;
|
|
95
|
+
if (content.includes(decoratorLine))
|
|
96
|
+
return content;
|
|
97
|
+
return content.replace(classRegex, `${decoratorLine}\n$1`);
|
|
98
|
+
}
|
|
99
|
+
if (!target.name)
|
|
100
|
+
return content;
|
|
101
|
+
const propertyRegex = new RegExp(`(^\\s*)(?:@.*\\n\\1)*${escapeRegExp(target.name)}:`, "m");
|
|
102
|
+
const match = propertyRegex.exec(content);
|
|
103
|
+
if (!match)
|
|
104
|
+
return content;
|
|
105
|
+
const indent = match[1] || " ";
|
|
106
|
+
if (content.includes(`${indent}${decoratorLine}`))
|
|
107
|
+
return content;
|
|
108
|
+
return (content.slice(0, match.index) +
|
|
109
|
+
`${indent}${decoratorLine}\n` +
|
|
110
|
+
content.slice(match.index));
|
|
111
|
+
}
|
|
112
|
+
function removeDecorator(content, decoratorName, target) {
|
|
113
|
+
const decoratorRegex = new RegExp(`^\\s*@${escapeRegExp(decoratorName)}\\([^)]*\\)`, "m");
|
|
114
|
+
if (target.kind === "class") {
|
|
115
|
+
return content.replace(decoratorRegex, "");
|
|
116
|
+
}
|
|
117
|
+
if (target.name) {
|
|
118
|
+
const pattern = new RegExp(`(^\\s*@${escapeRegExp(decoratorName)}\\([^)]*\\)\\s*$\\n)(?=\\s*${escapeRegExp(target.name)}:)`, "m");
|
|
119
|
+
return content.replace(pattern, "");
|
|
120
|
+
}
|
|
121
|
+
return content;
|
|
122
|
+
}
|
|
123
|
+
function writeIfChanged(filePath, content) {
|
|
124
|
+
ensureDirectory(filePath);
|
|
125
|
+
fs.writeFileSync(filePath, content);
|
|
126
|
+
}
|
|
127
|
+
const decoratorTools = {
|
|
128
|
+
createOrUpdateModelTool: {
|
|
129
|
+
name: "create-or-update-model",
|
|
130
|
+
description: "Create or update a validation-ready model class",
|
|
131
|
+
execute: async (args) => {
|
|
132
|
+
if (!args.overwrite && fs.existsSync(args.filePath)) {
|
|
133
|
+
throw new Error(`File already exists at ${args.filePath}`);
|
|
134
|
+
}
|
|
135
|
+
const decorators = collectDecoratorNames(args.classDecorators, args.properties);
|
|
136
|
+
let content = `@model()`;
|
|
137
|
+
for (const decorator of args.classDecorators || []) {
|
|
138
|
+
content += `\n${formatDecorator(decorator)}`;
|
|
139
|
+
}
|
|
140
|
+
const properties = (args.properties || [])
|
|
141
|
+
.map(addPropertyBlock)
|
|
142
|
+
.join("\n\n");
|
|
143
|
+
content += `\nexport class ${args.className} {\n${properties ? `${properties}\n` : ""}}\n`;
|
|
144
|
+
content = ensureImport(content, args.importsFrom, decorators);
|
|
145
|
+
writeIfChanged(args.filePath, content);
|
|
146
|
+
return { filePath: args.filePath };
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
addAttributeTool: {
|
|
150
|
+
name: "add-attribute",
|
|
151
|
+
description: "Add a decorated attribute to an existing model",
|
|
152
|
+
execute: async (args) => {
|
|
153
|
+
if (!fs.existsSync(args.filePath)) {
|
|
154
|
+
throw new Error(`Model file not found at ${args.filePath}`);
|
|
155
|
+
}
|
|
156
|
+
let content = fs.readFileSync(args.filePath, "utf8");
|
|
157
|
+
if (content.includes(`${args.attribute.name}:`)) {
|
|
158
|
+
return { filePath: args.filePath };
|
|
159
|
+
}
|
|
160
|
+
const decorators = collectDecoratorNames(undefined, [args.attribute]);
|
|
161
|
+
content = ensureImport(content, args.importsFrom, decorators);
|
|
162
|
+
const insertionPoint = content.lastIndexOf("}");
|
|
163
|
+
const block = addPropertyBlock(args.attribute);
|
|
164
|
+
const before = content.slice(0, insertionPoint).replace(/\s*$/, "");
|
|
165
|
+
const after = content.slice(insertionPoint);
|
|
166
|
+
const updated = `${before}\n${block}\n${after}`;
|
|
167
|
+
writeIfChanged(args.filePath, updated);
|
|
168
|
+
return { filePath: args.filePath };
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
removeAttributeTool: {
|
|
172
|
+
name: "remove-attribute",
|
|
173
|
+
description: "Remove an attribute from a model class",
|
|
174
|
+
execute: async (args) => {
|
|
175
|
+
if (!fs.existsSync(args.filePath))
|
|
176
|
+
return { filePath: args.filePath };
|
|
177
|
+
const content = fs.readFileSync(args.filePath, "utf8");
|
|
178
|
+
const updated = removePropertyBlock(content, args.attributeName);
|
|
179
|
+
writeIfChanged(args.filePath, updated);
|
|
180
|
+
return { filePath: args.filePath };
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
applyDecoratorTool: {
|
|
184
|
+
name: "apply-decorator",
|
|
185
|
+
description: "Apply a decorator to a class or property",
|
|
186
|
+
execute: async (args) => {
|
|
187
|
+
if (!fs.existsSync(args.filePath)) {
|
|
188
|
+
throw new Error(`Model file not found at ${args.filePath}`);
|
|
189
|
+
}
|
|
190
|
+
let content = fs.readFileSync(args.filePath, "utf8");
|
|
191
|
+
const decorators = new Set([args.decorator.name]);
|
|
192
|
+
content = ensureImport(content, args.importsFrom, decorators);
|
|
193
|
+
content = insertDecorator(content, args.decorator, args.target);
|
|
194
|
+
writeIfChanged(args.filePath, content);
|
|
195
|
+
return { filePath: args.filePath };
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
removeDecoratorTool: {
|
|
199
|
+
name: "remove-decorator",
|
|
200
|
+
description: "Remove a decorator from a class or property",
|
|
201
|
+
execute: async (args) => {
|
|
202
|
+
if (!fs.existsSync(args.filePath))
|
|
203
|
+
return { filePath: args.filePath };
|
|
204
|
+
let content = fs.readFileSync(args.filePath, "utf8");
|
|
205
|
+
content = removeDecorator(content, args.decoratorName, args.target);
|
|
206
|
+
writeIfChanged(args.filePath, content);
|
|
207
|
+
return { filePath: args.filePath };
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
scaffoldValidatorTool: {
|
|
211
|
+
name: "scaffold-validator",
|
|
212
|
+
description: "Scaffold a validator class and optional decorator",
|
|
213
|
+
execute: async (args) => {
|
|
214
|
+
const classFile = path.join(args.validatorsDir, `${args.name}.ts`);
|
|
215
|
+
ensureDirectory(classFile);
|
|
216
|
+
const classContent = `export class ${args.name} {\n validate(value: unknown): boolean {\n return value !== undefined;\n }\n}\n`;
|
|
217
|
+
fs.writeFileSync(classFile, classContent);
|
|
218
|
+
let decoratorFile;
|
|
219
|
+
if (args.decoratorDir) {
|
|
220
|
+
decoratorFile = path.join(args.decoratorDir, `${args.name}Decorator.ts`);
|
|
221
|
+
ensureDirectory(decoratorFile);
|
|
222
|
+
fs.writeFileSync(decoratorFile, `export function ${args.name}Decorator() {\n return () => void 0;\n}\n`);
|
|
223
|
+
}
|
|
224
|
+
return { classFile, decoratorFile };
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
scaffoldSerializerTool: {
|
|
228
|
+
name: "scaffold-serializer",
|
|
229
|
+
description: "Scaffold a serializer class and optional registry",
|
|
230
|
+
execute: async (args) => {
|
|
231
|
+
const classFile = path.join(args.dir, `${args.name}.ts`);
|
|
232
|
+
ensureDirectory(classFile);
|
|
233
|
+
fs.writeFileSync(classFile, `export class ${args.name} {\n serialize(value: unknown): string {\n return JSON.stringify(value);\n }\n}\n`);
|
|
234
|
+
let registerFile;
|
|
235
|
+
if (args.registerDir) {
|
|
236
|
+
registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
|
|
237
|
+
ensureDirectory(registerFile);
|
|
238
|
+
fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
|
|
239
|
+
}
|
|
240
|
+
return { classFile, registerFile };
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
scaffoldHashingTool: {
|
|
244
|
+
name: "scaffold-hashing",
|
|
245
|
+
description: "Scaffold a hashing function and optional registry",
|
|
246
|
+
execute: async (args) => {
|
|
247
|
+
const functionFile = path.join(args.dir, `${args.name}.ts`);
|
|
248
|
+
ensureDirectory(functionFile);
|
|
249
|
+
fs.writeFileSync(functionFile, `export function ${args.name}(value: string): string {\n return value.split('').reverse().join('');\n}\n`);
|
|
250
|
+
let registerFile;
|
|
251
|
+
if (args.registerDir) {
|
|
252
|
+
registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
|
|
253
|
+
ensureDirectory(registerFile);
|
|
254
|
+
fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
|
|
255
|
+
}
|
|
256
|
+
return { functionFile, registerFile };
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const WORKSPACE_ROOT_ENV = "MCP_WORKSPACE_ROOT";
|
|
262
|
+
const PROMPT_DIRECTORIES = [".code/prompts", ".codex/prompts"];
|
|
263
|
+
const DEFAULT_PROMPT_NAME = "doc";
|
|
264
|
+
const CLIENT_INTEGRATIONS = [
|
|
265
|
+
{
|
|
266
|
+
id: "vscode",
|
|
267
|
+
display: "Visual Studio Code",
|
|
268
|
+
instructions: "When interacting from Visual Studio Code, prefer the vscode://workspace/{path} resource template to fetch file contents and use the apply-code-change tool to commit edits with previewable diffs.",
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
id: "cursor",
|
|
272
|
+
display: "Cursor",
|
|
273
|
+
instructions: "Cursor clients can retrieve and update files through the cursor://workspace/{path} resource template. Always validate patches in dryRun mode before applying permanent changes.",
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
id: "copilot",
|
|
277
|
+
display: "GitHub Copilot",
|
|
278
|
+
instructions: "Use the copilot://workspace/{path} resource template to stream file content into Copilot chat sessions. Prefer returning unified diffs to maintain alignment with Copilot's diff visualization.",
|
|
279
|
+
},
|
|
280
|
+
];
|
|
281
|
+
const documentCodeSchema = zod.z
|
|
282
|
+
.object({
|
|
283
|
+
filePath: zod.z.string().min(1, "filePath is required"),
|
|
284
|
+
promptName: zod.z.string().optional(),
|
|
285
|
+
includePrompt: zod.z.boolean().default(true),
|
|
286
|
+
includeCode: zod.z.boolean().default(true),
|
|
287
|
+
includeMetadata: zod.z.boolean().default(true),
|
|
288
|
+
additionalContext: zod.z.string().optional(),
|
|
289
|
+
encoding: zod.z.string().default("utf8"),
|
|
290
|
+
})
|
|
291
|
+
.strict();
|
|
292
|
+
const codeChangeSchema = zod.z
|
|
293
|
+
.object({
|
|
294
|
+
filePath: zod.z.string().min(1, "filePath is required"),
|
|
295
|
+
patch: zod.z.string().min(1, "patch is required"),
|
|
296
|
+
dryRun: zod.z.boolean().default(false),
|
|
297
|
+
showDiff: zod.z.boolean().default(true),
|
|
298
|
+
diffContext: zod.z.number().int().min(0).max(100).default(3),
|
|
299
|
+
encoding: zod.z.string().default("utf8"),
|
|
300
|
+
})
|
|
301
|
+
.strict();
|
|
302
|
+
let workspaceRoot = initializeWorkspaceRoot();
|
|
303
|
+
let userErrorCtor;
|
|
304
|
+
class WorkspaceError extends Error {
|
|
305
|
+
constructor(message) {
|
|
306
|
+
super(message);
|
|
307
|
+
this.name = "WorkspaceError";
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
async function getUserErrorCtor() {
|
|
311
|
+
if (!userErrorCtor) {
|
|
312
|
+
try {
|
|
313
|
+
const mod = await import('fastmcp');
|
|
314
|
+
userErrorCtor = mod
|
|
315
|
+
.UserError;
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
userErrorCtor = class MCPUserError extends Error {
|
|
319
|
+
constructor(message) {
|
|
320
|
+
super(message);
|
|
321
|
+
this.name = "MCPUserError";
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return userErrorCtor;
|
|
327
|
+
}
|
|
328
|
+
async function throwUserError(message) {
|
|
329
|
+
const Ctor = await getUserErrorCtor();
|
|
330
|
+
throw new Ctor(message);
|
|
331
|
+
}
|
|
332
|
+
const documentCodeTool = {
|
|
333
|
+
annotations: {
|
|
334
|
+
idempotentHint: true,
|
|
335
|
+
openWorldHint: false,
|
|
336
|
+
readOnlyHint: true,
|
|
337
|
+
title: "Document Source File",
|
|
338
|
+
},
|
|
339
|
+
description: "Generate documentation guidance for a file by combining repository prompts with the target source code.",
|
|
340
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
341
|
+
execute: async (input, _context) => {
|
|
342
|
+
const args = documentCodeSchema.parse(input);
|
|
343
|
+
const root = getWorkspaceRoot();
|
|
344
|
+
let filePath;
|
|
345
|
+
try {
|
|
346
|
+
filePath = resolveInWorkspace(root, args.filePath);
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
if (error instanceof WorkspaceError) {
|
|
350
|
+
return throwUserError(error.message);
|
|
351
|
+
}
|
|
352
|
+
/* istanbul ignore next */
|
|
353
|
+
throw error;
|
|
354
|
+
}
|
|
355
|
+
if (!fs.existsSync(filePath)) {
|
|
356
|
+
return throwUserError(`Cannot document missing file at ${args.filePath}`);
|
|
357
|
+
}
|
|
358
|
+
const fileContent = fs.readFileSync(filePath, {
|
|
359
|
+
encoding: args.encoding,
|
|
360
|
+
});
|
|
361
|
+
const prompts = discoverDocPrompts(root);
|
|
362
|
+
if (!prompts.length) {
|
|
363
|
+
return throwUserError("No documentation prompts found under .code/prompts or .codex/prompts");
|
|
364
|
+
}
|
|
365
|
+
const prompt = selectPrompt(prompts, args.promptName ?? DEFAULT_PROMPT_NAME);
|
|
366
|
+
return buildDocumentationPayload({
|
|
367
|
+
filePath: args.filePath,
|
|
368
|
+
fileContent,
|
|
369
|
+
prompt,
|
|
370
|
+
includeCode: args.includeCode,
|
|
371
|
+
includePrompt: args.includePrompt,
|
|
372
|
+
includeMetadata: args.includeMetadata,
|
|
373
|
+
additionalContext: args.additionalContext,
|
|
374
|
+
});
|
|
375
|
+
},
|
|
376
|
+
name: "document-code",
|
|
377
|
+
parameters: documentCodeSchema,
|
|
378
|
+
};
|
|
379
|
+
const applyCodeChangeTool = {
|
|
380
|
+
annotations: {
|
|
381
|
+
destructiveHint: true,
|
|
382
|
+
idempotentHint: false,
|
|
383
|
+
openWorldHint: false,
|
|
384
|
+
readOnlyHint: false,
|
|
385
|
+
title: "Apply Code Patch",
|
|
386
|
+
},
|
|
387
|
+
description: "Apply a unified diff patch to a workspace file with optional dry-run validation and diff preview.",
|
|
388
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
389
|
+
execute: async (input, _context) => {
|
|
390
|
+
const args = codeChangeSchema.parse(input);
|
|
391
|
+
const root = getWorkspaceRoot();
|
|
392
|
+
let filePath;
|
|
393
|
+
try {
|
|
394
|
+
filePath = resolveInWorkspace(root, args.filePath);
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
if (error instanceof WorkspaceError) {
|
|
398
|
+
return throwUserError(error.message);
|
|
399
|
+
}
|
|
400
|
+
throw error;
|
|
401
|
+
}
|
|
402
|
+
const original = fs.existsSync(filePath)
|
|
403
|
+
? fs.readFileSync(filePath, args.encoding)
|
|
404
|
+
: "";
|
|
405
|
+
let patched;
|
|
406
|
+
try {
|
|
407
|
+
patched = diff.applyPatch(original, args.patch);
|
|
408
|
+
}
|
|
409
|
+
catch (error) {
|
|
410
|
+
return throwUserError(`Failed to apply provided patch to ${args.filePath}: ${error instanceof Error ? error.message : error}`);
|
|
411
|
+
}
|
|
412
|
+
/* istanbul ignore next */
|
|
413
|
+
if (patched === false) {
|
|
414
|
+
return throwUserError(`Failed to apply provided patch to ${args.filePath}`);
|
|
415
|
+
}
|
|
416
|
+
if (!args.dryRun) {
|
|
417
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
418
|
+
fs.writeFileSync(filePath, patched, {
|
|
419
|
+
encoding: args.encoding,
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
if (!args.showDiff) {
|
|
423
|
+
return `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`;
|
|
424
|
+
}
|
|
425
|
+
const preview = diff.createTwoFilesPatch(args.filePath, args.filePath, original, patched, undefined, undefined, { context: args.diffContext });
|
|
426
|
+
return {
|
|
427
|
+
content: [
|
|
428
|
+
{
|
|
429
|
+
type: "text",
|
|
430
|
+
text: `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`,
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
type: "text",
|
|
434
|
+
text: ["```diff", preview.trim(), "```"].join("\n"),
|
|
435
|
+
},
|
|
436
|
+
],
|
|
437
|
+
};
|
|
438
|
+
},
|
|
439
|
+
name: "apply-code-change",
|
|
440
|
+
parameters: codeChangeSchema,
|
|
441
|
+
};
|
|
442
|
+
const tools = {
|
|
443
|
+
...decoratorTools,
|
|
444
|
+
documentCodeTool,
|
|
445
|
+
applyCodeChangeTool,
|
|
446
|
+
};
|
|
447
|
+
function enrich(mcp) {
|
|
448
|
+
for (const prompt of buildDocPrompts()) {
|
|
449
|
+
mcp.addPrompt(prompt);
|
|
450
|
+
}
|
|
451
|
+
for (const tool of Object.values(tools)) {
|
|
452
|
+
mcp.addTool(tool);
|
|
453
|
+
}
|
|
454
|
+
for (const template of buildResourceTemplates()) {
|
|
455
|
+
mcp.addResourceTemplate(template);
|
|
456
|
+
}
|
|
457
|
+
return mcp;
|
|
458
|
+
}
|
|
459
|
+
const PACKAGE_NAME = PACKAGE_NAME$1;
|
|
460
|
+
const VERSION = VERSION$1;
|
|
461
|
+
function setWorkspaceRoot(root) {
|
|
462
|
+
workspaceRoot = path.resolve(root);
|
|
463
|
+
}
|
|
464
|
+
function getWorkspaceRoot() {
|
|
465
|
+
return workspaceRoot;
|
|
466
|
+
}
|
|
467
|
+
function buildResourceTemplates() {
|
|
468
|
+
const root = getWorkspaceRoot();
|
|
469
|
+
const sharedArguments = [
|
|
470
|
+
{
|
|
471
|
+
name: "path",
|
|
472
|
+
description: "Path relative to the workspace root",
|
|
473
|
+
required: true,
|
|
474
|
+
},
|
|
475
|
+
];
|
|
476
|
+
return [
|
|
477
|
+
{
|
|
478
|
+
name: "vscode-workspace-file",
|
|
479
|
+
description: "Expose workspace files to Visual Studio Code via vscode:// URIs",
|
|
480
|
+
uriTemplate: "vscode://workspace/{path}",
|
|
481
|
+
mimeType: "text/plain",
|
|
482
|
+
arguments: sharedArguments,
|
|
483
|
+
load: async (args) => {
|
|
484
|
+
const text = await readWorkspaceFile(root, args.path);
|
|
485
|
+
return { text };
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: "cursor-workspace-file",
|
|
490
|
+
description: "Expose workspace files to Cursor via cursor:// URIs",
|
|
491
|
+
uriTemplate: "cursor://workspace/{path}",
|
|
492
|
+
mimeType: "text/plain",
|
|
493
|
+
arguments: sharedArguments,
|
|
494
|
+
load: async (args) => {
|
|
495
|
+
const text = await readWorkspaceFile(root, args.path);
|
|
496
|
+
return { text };
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
name: "copilot-workspace-file",
|
|
501
|
+
description: "Expose workspace files to GitHub Copilot via copilot:// URIs",
|
|
502
|
+
uriTemplate: "copilot://workspace/{path}",
|
|
503
|
+
mimeType: "text/plain",
|
|
504
|
+
arguments: sharedArguments,
|
|
505
|
+
load: async (args) => {
|
|
506
|
+
const text = await readWorkspaceFile(root, args.path);
|
|
507
|
+
return { text };
|
|
508
|
+
},
|
|
509
|
+
},
|
|
510
|
+
];
|
|
511
|
+
}
|
|
512
|
+
function initializeWorkspaceRoot() {
|
|
513
|
+
const configured = process.env[WORKSPACE_ROOT_ENV];
|
|
514
|
+
if (configured && configured.trim().length > 0) {
|
|
515
|
+
return path.resolve(configured.trim());
|
|
516
|
+
}
|
|
517
|
+
return process.cwd();
|
|
518
|
+
}
|
|
519
|
+
function buildDocPrompts() {
|
|
520
|
+
const root = getWorkspaceRoot();
|
|
521
|
+
const fileBasedPrompts = discoverDocPrompts(root).map((prompt) => ({
|
|
522
|
+
name: `doc/${prompt.name}`,
|
|
523
|
+
description: prompt.description,
|
|
524
|
+
load: async () => prompt.content,
|
|
525
|
+
}));
|
|
526
|
+
const integrationPrompts = CLIENT_INTEGRATIONS.map((integration) => ({
|
|
527
|
+
name: `integration/${integration.id}`,
|
|
528
|
+
description: `${integration.display} integration guidance`,
|
|
529
|
+
load: async () => `You are coordinating with ${integration.display}. ${integration.instructions}\n\nTools available:\n- document-code\n- apply-code-change\n\nEnsure responses include actionable steps for the client.`,
|
|
530
|
+
}));
|
|
531
|
+
return [...fileBasedPrompts, ...integrationPrompts];
|
|
532
|
+
}
|
|
533
|
+
function resolveInWorkspace(root, targetPath) {
|
|
534
|
+
const resolved = path.isAbsolute(targetPath)
|
|
535
|
+
? path.normalize(targetPath)
|
|
536
|
+
: path.resolve(root, targetPath);
|
|
537
|
+
const relative = path.relative(root, resolved);
|
|
538
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
539
|
+
throw new WorkspaceError(`Path ${targetPath} escapes the workspace root at ${root}`);
|
|
540
|
+
}
|
|
541
|
+
return resolved;
|
|
542
|
+
}
|
|
543
|
+
async function readWorkspaceFile(root, target) {
|
|
544
|
+
try {
|
|
545
|
+
const absolute = resolveInWorkspace(root, target);
|
|
546
|
+
return fs.readFileSync(absolute, "utf8");
|
|
547
|
+
}
|
|
548
|
+
catch (error) {
|
|
549
|
+
if (error instanceof WorkspaceError) {
|
|
550
|
+
await throwUserError(error.message);
|
|
551
|
+
}
|
|
552
|
+
/* istanbul ignore next */
|
|
553
|
+
throw error;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
function discoverDocPrompts(root) {
|
|
557
|
+
const discovered = [];
|
|
558
|
+
for (const directory of PROMPT_DIRECTORIES) {
|
|
559
|
+
const promptDir = path.join(root, directory);
|
|
560
|
+
if (!fs.existsSync(promptDir) || !fs.statSync(promptDir).isDirectory()) {
|
|
561
|
+
continue;
|
|
562
|
+
}
|
|
563
|
+
for (const entry of fs.readdirSync(promptDir)) {
|
|
564
|
+
const fullPath = path.join(promptDir, entry);
|
|
565
|
+
if (!fs.statSync(fullPath).isFile())
|
|
566
|
+
continue;
|
|
567
|
+
const name = path.parse(entry).name;
|
|
568
|
+
const content = fs.readFileSync(fullPath, "utf8");
|
|
569
|
+
const title = toTitleCase(name.replace(/[-_]/g, " "));
|
|
570
|
+
const description = extractDescription(content, fullPath);
|
|
571
|
+
discovered.push({
|
|
572
|
+
name,
|
|
573
|
+
title,
|
|
574
|
+
description,
|
|
575
|
+
content,
|
|
576
|
+
absolutePath: fullPath,
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
const unique = new Map();
|
|
581
|
+
for (const prompt of discovered) {
|
|
582
|
+
if (!unique.has(prompt.name)) {
|
|
583
|
+
unique.set(prompt.name, prompt);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return Array.from(unique.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
587
|
+
}
|
|
588
|
+
function selectPrompt(prompts, requestedName) {
|
|
589
|
+
const direct = prompts.find((prompt) => prompt.name === requestedName);
|
|
590
|
+
if (direct)
|
|
591
|
+
return direct;
|
|
592
|
+
const fallback = prompts.find((prompt) => prompt.name === DEFAULT_PROMPT_NAME);
|
|
593
|
+
if (fallback)
|
|
594
|
+
return fallback;
|
|
595
|
+
if (!prompts.length) {
|
|
596
|
+
throw new WorkspaceError("No documentation prompts available");
|
|
597
|
+
}
|
|
598
|
+
return prompts[0];
|
|
599
|
+
}
|
|
600
|
+
function buildDocumentationPayload({ filePath, fileContent, prompt, includePrompt, includeCode, includeMetadata, additionalContext, }) {
|
|
601
|
+
const sections = [];
|
|
602
|
+
if (includeMetadata) {
|
|
603
|
+
sections.push(`# Documentation Request\n- prompt: ${prompt.name}\n- file: ${filePath}`);
|
|
604
|
+
}
|
|
605
|
+
if (includePrompt) {
|
|
606
|
+
sections.push(`## Prompt Guidance (${prompt.title})\n\n${prompt.content.trim()}`);
|
|
607
|
+
}
|
|
608
|
+
if (additionalContext?.trim()) {
|
|
609
|
+
sections.push(`## Additional Context\n\n${additionalContext.trim()}`);
|
|
610
|
+
}
|
|
611
|
+
if (includeCode) {
|
|
612
|
+
sections.push(`## Source\n\n\`\`\`${inferLanguageFromPath(filePath)}\n${fileContent}\n\`\`\``);
|
|
613
|
+
}
|
|
614
|
+
return {
|
|
615
|
+
content: [
|
|
616
|
+
{
|
|
617
|
+
type: "text",
|
|
618
|
+
text: sections.join("\n\n"),
|
|
619
|
+
},
|
|
620
|
+
],
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
function extractDescription(content, filePath) {
|
|
624
|
+
const firstLine = content
|
|
625
|
+
.split(/\r?\n/)
|
|
626
|
+
.map((line) => line.trim())
|
|
627
|
+
.find((line) => line.length > 0);
|
|
628
|
+
return (firstLine?.slice(0, 240) ??
|
|
629
|
+
`Documentation prompt loaded from ${path.basename(filePath)}`);
|
|
630
|
+
}
|
|
631
|
+
function toTitleCase(value) {
|
|
632
|
+
return value
|
|
633
|
+
.split(/\s+/)
|
|
634
|
+
.filter(Boolean)
|
|
635
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
|
|
636
|
+
.join(" ");
|
|
637
|
+
}
|
|
638
|
+
function inferLanguageFromPath(filePath) {
|
|
639
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
640
|
+
switch (extension) {
|
|
641
|
+
case ".ts":
|
|
642
|
+
case ".tsx":
|
|
643
|
+
return "ts";
|
|
644
|
+
case ".js":
|
|
645
|
+
case ".jsx":
|
|
646
|
+
return "js";
|
|
647
|
+
case ".json":
|
|
648
|
+
return "json";
|
|
649
|
+
case ".md":
|
|
650
|
+
return "md";
|
|
651
|
+
default:
|
|
652
|
+
return "text";
|
|
653
|
+
}
|
|
27
654
|
}
|
|
28
655
|
|
|
29
656
|
/**
|
|
30
|
-
* @
|
|
31
|
-
* @
|
|
32
|
-
* @summary This class provides an implementation of the Interface contract with additional static functionality.
|
|
33
|
-
* It manages an internal state through a private property and offers both instance and static methods.
|
|
657
|
+
* @description The filename that identifies Decaf CLI modules
|
|
658
|
+
* @summary The standard filename for CLI module files where each library must export a single CliModule function
|
|
34
659
|
*
|
|
35
|
-
* @
|
|
36
|
-
* @
|
|
37
|
-
|
|
38
|
-
|
|
660
|
+
* @const MCP_FILE_NAME
|
|
661
|
+
* @memberOf module:MCP
|
|
662
|
+
*/
|
|
663
|
+
const MCP_FILE_NAME = "mcp-module";
|
|
664
|
+
|
|
665
|
+
/* istanbul ignore file */
|
|
666
|
+
/**
|
|
667
|
+
* @description Utility class for CLI operations
|
|
668
|
+
* @summary A static utility class that provides methods for loading modules, retrieving package information, and initializing CLI commands
|
|
39
669
|
*
|
|
40
670
|
* @example
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* // Using the generic method
|
|
46
|
-
* await instance.method<string>()
|
|
47
|
-
* .catch(error => console.error(error));
|
|
48
|
-
*
|
|
49
|
-
* // Using the static method
|
|
50
|
-
* Class.method();
|
|
51
|
-
* ```
|
|
671
|
+
* // Initialize a Command object with package information
|
|
672
|
+
* const command = new Command();
|
|
673
|
+
* CLIUtils.initialize(command, './path/to/package');
|
|
52
674
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* participant Client
|
|
56
|
-
* participant Instance
|
|
57
|
-
* participant Static
|
|
675
|
+
* // Load a CLI module from a file
|
|
676
|
+
* const module = await CLIUtils.loadFromFile('./path/to/cli-module.js');
|
|
58
677
|
*
|
|
59
|
-
*
|
|
60
|
-
* activate Instance
|
|
61
|
-
* Instance-->>Client: class instance
|
|
62
|
-
* deactivate Instance
|
|
63
|
-
*
|
|
64
|
-
* Client->>Instance: method<T>()
|
|
65
|
-
* activate Instance
|
|
66
|
-
* Instance-->>Client: Promise<string>
|
|
67
|
-
* deactivate Instance
|
|
68
|
-
*
|
|
69
|
-
* Client->>Static: Class.method()
|
|
70
|
-
* activate Static
|
|
71
|
-
* Static-->>Client: void
|
|
72
|
-
* deactivate Static
|
|
678
|
+
* @class McpUtils
|
|
73
679
|
*/
|
|
74
|
-
class
|
|
75
|
-
constructor(arg1, arg2) {
|
|
76
|
-
console.log(arg1, arg2);
|
|
77
|
-
}
|
|
680
|
+
class McpUtils {
|
|
78
681
|
/**
|
|
79
|
-
* @description
|
|
80
|
-
* @summary
|
|
682
|
+
* @description Dynamically imports a module file
|
|
683
|
+
* @summary Loads a JavaScript file and returns it as a CliModule, handling both ESM and CommonJS formats
|
|
81
684
|
*
|
|
82
|
-
* @
|
|
83
|
-
* @return {Promise<
|
|
84
|
-
* @throws {Error} Always throws an error
|
|
685
|
+
* @param {string} path The file path to the module to load
|
|
686
|
+
* @return {Promise<McpModule>} A promise that resolves to the loaded CliModule
|
|
85
687
|
*/
|
|
86
|
-
async
|
|
87
|
-
|
|
688
|
+
static async loadFromFile(path) {
|
|
689
|
+
try {
|
|
690
|
+
return McpUtils.normalizeImport(import(path));
|
|
691
|
+
}
|
|
692
|
+
catch (e) {
|
|
693
|
+
throw new Error(`Failed to load from ${path}: ${e instanceof Error ? e.message : e}`);
|
|
694
|
+
}
|
|
88
695
|
}
|
|
89
696
|
/**
|
|
90
|
-
* @description
|
|
91
|
-
* @summary
|
|
697
|
+
* @description Normalizes module imports to handle both ESM and CommonJS formats
|
|
698
|
+
* @summary Properly imports JavaScript files regardless of their module format by handling the ESM wrapper for CommonJS modules
|
|
92
699
|
*
|
|
93
|
-
* @
|
|
94
|
-
* @
|
|
95
|
-
* @
|
|
700
|
+
* @template T The type of the imported module
|
|
701
|
+
* @param {Promise<T>} importPromise The promise returned by the dynamic import
|
|
702
|
+
* @return {Promise<T>} A promise that resolves to the normalized module
|
|
703
|
+
* @private
|
|
96
704
|
*/
|
|
97
|
-
static
|
|
98
|
-
|
|
705
|
+
static async normalizeImport(importPromise) {
|
|
706
|
+
// CommonJS's `module.exports` is wrapped as `default` in ESModule.
|
|
707
|
+
return importPromise.then((m) => (m.default || m));
|
|
99
708
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
class ChildClass extends Class {
|
|
116
|
-
constructor(arg1, arg2) {
|
|
117
|
-
super(arg1, arg2);
|
|
118
|
-
this.prop2 = arg1;
|
|
709
|
+
/**
|
|
710
|
+
* @description Retrieves and parses the package.json file
|
|
711
|
+
* @summary Reads the package.json file from the specified path and parses it into a JavaScript object
|
|
712
|
+
*
|
|
713
|
+
* @param {string} basePath The base path where the package.json file is located
|
|
714
|
+
* @return {Record<string, unknown>} The parsed package.json content as an object
|
|
715
|
+
* @private
|
|
716
|
+
*/
|
|
717
|
+
static getPackage(basePath) {
|
|
718
|
+
try {
|
|
719
|
+
return JSON.parse(fs.readFileSync(path.join(basePath, "package.json"), "utf8"));
|
|
720
|
+
}
|
|
721
|
+
catch (e) {
|
|
722
|
+
throw new Error(`Unable to read version from ${basePath}: ${e}`);
|
|
723
|
+
}
|
|
119
724
|
}
|
|
120
725
|
/**
|
|
121
|
-
* @description
|
|
122
|
-
* @summary
|
|
726
|
+
* @description Returns the version from package.json
|
|
727
|
+
* @summary Retrieves the version field from the package.json file at the specified path
|
|
123
728
|
*
|
|
124
|
-
* @
|
|
125
|
-
* @return {
|
|
126
|
-
* @override
|
|
729
|
+
* @param {string} basePath The base path where the package.json file is located
|
|
730
|
+
* @return {string} The package version string
|
|
127
731
|
*/
|
|
128
|
-
|
|
129
|
-
return "
|
|
732
|
+
static packageVersion(basePath) {
|
|
733
|
+
return McpUtils.getPackage(basePath)["version"];
|
|
130
734
|
}
|
|
131
735
|
/**
|
|
132
|
-
* @description
|
|
133
|
-
* @summary
|
|
736
|
+
* @description Returns the name from package.json
|
|
737
|
+
* @summary Retrieves the name field from the package.json file at the specified path and extracts the package name without the scope
|
|
134
738
|
*
|
|
135
|
-
* @param {
|
|
136
|
-
* @return {
|
|
137
|
-
* @throws {Error} Always throws an error with a message including arg1
|
|
739
|
+
* @param {string} basePath The base path where the package.json file is located
|
|
740
|
+
* @return {string} The package name without the scope (e.g., "cli" from "@decaf-ts/cli")
|
|
138
741
|
*/
|
|
139
|
-
|
|
140
|
-
|
|
742
|
+
static packageName(basePath) {
|
|
743
|
+
const name = McpUtils.getPackage(basePath)["name"].split("/");
|
|
744
|
+
return name[name.length - 1];
|
|
141
745
|
}
|
|
142
746
|
}
|
|
143
747
|
|
|
748
|
+
/* istanbul ignore file */
|
|
144
749
|
/**
|
|
145
|
-
* @
|
|
146
|
-
* @
|
|
147
|
-
*
|
|
148
|
-
* @summary Enumeration of string options for consistent value representation.
|
|
149
|
-
* @type {enum}
|
|
150
|
-
* @readonly
|
|
151
|
-
*
|
|
152
|
-
* @memberOf module:ts-workspace.Namespace.ChildNamespace
|
|
153
|
-
*/
|
|
154
|
-
exports.Enum = void 0;
|
|
155
|
-
(function (Enum) {
|
|
156
|
-
/** Represents the first option with value "something" */
|
|
157
|
-
Enum["OPTION1"] = "something";
|
|
158
|
-
})(exports.Enum || (exports.Enum = {}));
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* @function something
|
|
162
|
-
* @description This function is a generic method that extends the Class type.
|
|
163
|
-
* @summary Generic function that logs arguments and returns the context (this) of the function.
|
|
164
|
-
* It logs all provided arguments to the console and returns the context (this) of the function.
|
|
750
|
+
* @description Utility class to handle CLI functionality from all Decaf modules
|
|
751
|
+
* @summary This class provides a wrapper around Commander.js to handle CLI commands from different Decaf modules.
|
|
752
|
+
* It crawls the filesystem to find CLI modules, loads them, and registers their commands.
|
|
165
753
|
*
|
|
166
|
-
* @
|
|
167
|
-
* @
|
|
168
|
-
* @this {T}
|
|
169
|
-
* @param {...V} args - Variable number of arguments of type V
|
|
170
|
-
* @return {Type<T>} Returns the context (this) of the function
|
|
754
|
+
* @param {string} [basePath] The base path to look for modules in. Defaults to `./`
|
|
755
|
+
* @param {number} [crawlLevels] Number of folder levels to crawl to find modules from the basePath. Defaults to 4
|
|
171
756
|
*
|
|
172
757
|
* @example
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* }
|
|
758
|
+
* // Create a new CLI wrapper and run it with custom options
|
|
759
|
+
* const cli = new CliWrapper('./src', 2);
|
|
760
|
+
* cli.run(process.argv).then(() => {
|
|
761
|
+
* console.log('CLI commands executed successfully');
|
|
762
|
+
* });
|
|
178
763
|
*
|
|
179
|
-
*
|
|
180
|
-
* const result = instance.myMethod();
|
|
181
|
-
* // Logs: 'arg1', 'arg2'
|
|
182
|
-
* // result is the instance of MyClass
|
|
183
|
-
*
|
|
184
|
-
* @memberOf module:ts-workspace.Namespace.ChildNamespace
|
|
185
|
-
* @see {@link Class}
|
|
186
|
-
* @see {@link Type}
|
|
764
|
+
* @class McpWrapper
|
|
187
765
|
*/
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
766
|
+
class McpWrapper extends logging.LoggedClass {
|
|
767
|
+
constructor(basePath = "./", crawlLevels = 4) {
|
|
768
|
+
super();
|
|
769
|
+
this.basePath = basePath;
|
|
770
|
+
this.crawlLevels = crawlLevels;
|
|
771
|
+
this.modules = {};
|
|
772
|
+
this.rootPath = path.resolve(__dirname, "..");
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* @description Retrieves and initializes the Commander Command object
|
|
776
|
+
* @summary Lazy-loads the Command object, initializing it with the package name, description, and version
|
|
777
|
+
* @return {Command} The initialized Command object
|
|
778
|
+
* @private
|
|
779
|
+
*/
|
|
780
|
+
get mcp() {
|
|
781
|
+
if (!this._mcp) {
|
|
782
|
+
this._mcp = new fastmcp.FastMCP({
|
|
783
|
+
name: "decaf-ts MCP server",
|
|
784
|
+
instructions: "",
|
|
785
|
+
version: VERSION$1,
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
return this._mcp;
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* @description Loads and registers an mcp extension module from a file
|
|
792
|
+
* @summary Dynamically imports an mcp extension module from the specified file path, initializes it, and registers it in the modules collection
|
|
793
|
+
*
|
|
794
|
+
*/
|
|
795
|
+
async load(server, filePath) {
|
|
796
|
+
const log = this.log.for(this.load);
|
|
797
|
+
let pkg, version, enrich;
|
|
798
|
+
try {
|
|
799
|
+
const res = await McpUtils.loadFromFile(filePath);
|
|
800
|
+
pkg = res.PACKAGE_NAME;
|
|
801
|
+
version = res.VERSION;
|
|
802
|
+
enrich = res.enrich;
|
|
803
|
+
}
|
|
804
|
+
catch (e) {
|
|
805
|
+
throw new Error(e.message || e);
|
|
806
|
+
}
|
|
807
|
+
try {
|
|
808
|
+
log.info(`Enriching mcp server with module ${pkg} v${version}`);
|
|
809
|
+
const result = enrich(server);
|
|
810
|
+
server = result instanceof Promise ? await result : result;
|
|
811
|
+
}
|
|
812
|
+
catch (e) {
|
|
813
|
+
throw new Error(`failed to enrich mcp with module ${pkg || "unnamed"} under ${filePath}: ${e instanceof Error ? e.message : e}`);
|
|
814
|
+
}
|
|
815
|
+
return {
|
|
816
|
+
mcp: server,
|
|
817
|
+
package: pkg,
|
|
818
|
+
version: version,
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* @description Finds and loads all CLI modules in the basePath
|
|
823
|
+
* @summary Uses the crawl method to find all CLI modules in the specified base path,
|
|
824
|
+
* then loads and registers each module as a subcommand
|
|
825
|
+
*
|
|
826
|
+
* @return {Promise<void>} A promise that resolves when all modules are loaded
|
|
827
|
+
*
|
|
828
|
+
* @private
|
|
829
|
+
* @mermaid
|
|
830
|
+
* sequenceDiagram
|
|
831
|
+
* participant CliWrapper
|
|
832
|
+
* participant Filesystem
|
|
833
|
+
* participant Module
|
|
834
|
+
*
|
|
835
|
+
* CliWrapper->>Filesystem: Join basePath with cwd
|
|
836
|
+
* CliWrapper->>CliWrapper: crawl(basePath, crawlLevels)
|
|
837
|
+
* CliWrapper-->>CliWrapper: modules[]
|
|
838
|
+
* loop For each module
|
|
839
|
+
* alt Not @decaf-ts/cli
|
|
840
|
+
* CliWrapper->>CliWrapper: load(module, cwd)
|
|
841
|
+
* CliWrapper-->>CliWrapper: name
|
|
842
|
+
* CliWrapper->>CliWrapper: Check if command exists
|
|
843
|
+
* alt Command doesn't exist
|
|
844
|
+
* CliWrapper->>Command: command(name).addCommand(modules[name])
|
|
845
|
+
* end
|
|
846
|
+
* end
|
|
847
|
+
* end
|
|
848
|
+
* CliWrapper->>Console: Log loaded modules
|
|
849
|
+
*/
|
|
850
|
+
async boot() {
|
|
851
|
+
const log = this.log.for(this.boot);
|
|
852
|
+
const basePath = path.resolve(this.rootPath, this.basePath);
|
|
853
|
+
const modules = this.crawl(basePath, this.crawlLevels);
|
|
854
|
+
let server = this.mcp;
|
|
855
|
+
for (const module of modules) {
|
|
856
|
+
if (module.includes("@decaf-ts/mcp")) {
|
|
857
|
+
continue;
|
|
858
|
+
}
|
|
859
|
+
try {
|
|
860
|
+
const res = await this.load(server, module);
|
|
861
|
+
server = res.mcp;
|
|
862
|
+
}
|
|
863
|
+
catch (e) {
|
|
864
|
+
log.error(`Failed to load MCP configs for ${module}: ${e}`);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
console.log(`loaded modules:\n${Object.keys(this.modules)
|
|
868
|
+
.map((k) => `- ${k}`)
|
|
869
|
+
.join("\n")}`);
|
|
870
|
+
return server;
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* @description Recursively searches for CLI module files in the directory structure
|
|
874
|
+
* @summary Crawls the basePath up to the specified number of folder levels to find files named according to CLI_FILE_NAME
|
|
875
|
+
*
|
|
876
|
+
* @param {string} basePath The absolute base path to start searching in
|
|
877
|
+
* @param {number} [levels=2] The maximum number of directory levels to crawl
|
|
878
|
+
* @return {string[]} An array of file paths to CLI modules
|
|
879
|
+
*
|
|
880
|
+
* @private
|
|
881
|
+
*/
|
|
882
|
+
crawl(basePath, levels = 2) {
|
|
883
|
+
if (levels <= 0)
|
|
884
|
+
return [];
|
|
885
|
+
return fs.readdirSync(basePath).reduce((accum, file) => {
|
|
886
|
+
file = path.join(basePath, file);
|
|
887
|
+
if (fs.statSync(file).isDirectory()) {
|
|
888
|
+
accum.push(...this.crawl(file, levels - 1));
|
|
889
|
+
}
|
|
890
|
+
else if (file.match(new RegExp(`${MCP_FILE_NAME}.[cm]?js$`, "gm"))) {
|
|
891
|
+
accum.push(file);
|
|
892
|
+
}
|
|
893
|
+
return accum;
|
|
894
|
+
}, []);
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* @description Executes the CLI with the provided arguments
|
|
898
|
+
* @summary Boots the CLI by loading all modules, then parses and executes the command specified in the arguments
|
|
899
|
+
*
|
|
900
|
+
* @param {string[]} [args=process.argv] Command line arguments to parse and execute
|
|
901
|
+
* @return {Promise<void>} A promise that resolves when the command execution is complete
|
|
902
|
+
*
|
|
903
|
+
* @mermaid
|
|
904
|
+
* sequenceDiagram
|
|
905
|
+
* participant Client
|
|
906
|
+
* participant CliWrapper
|
|
907
|
+
* participant Command
|
|
908
|
+
*
|
|
909
|
+
* Client->>CliWrapper: run(args)
|
|
910
|
+
* CliWrapper->>CliWrapper: boot()
|
|
911
|
+
* Note over CliWrapper: Loads all modules
|
|
912
|
+
* CliWrapper->>Command: parseAsync(args)
|
|
913
|
+
* Command-->>CliWrapper: result
|
|
914
|
+
* CliWrapper-->>Client: result
|
|
915
|
+
*/
|
|
916
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
917
|
+
async run(args = process.argv) {
|
|
918
|
+
const server = await this.boot();
|
|
919
|
+
await server.start({ transportType: "stdio" });
|
|
920
|
+
}
|
|
191
921
|
}
|
|
192
922
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
*
|
|
198
|
-
* The module includes:
|
|
199
|
-
* 1. Utility functions and types from the "./utils" directory:
|
|
200
|
-
* - These likely contain helper functions, common types, and shared functionality used throughout the project.
|
|
201
|
-
* - May include operations for data manipulation, type checking, or other general-purpose utilities.
|
|
202
|
-
*
|
|
203
|
-
* 2. A namespace and related types from the "./namespace" directory:
|
|
204
|
-
* - This could contain domain-specific code or a collection of related functionality.
|
|
205
|
-
* - Might include interfaces, types, or classes that represent core concepts in the library.
|
|
206
|
-
*
|
|
207
|
-
* 3. A VERSION constant:
|
|
208
|
-
* - Represents the current version of the module.
|
|
209
|
-
* - Useful for version checking and compatibility purposes.
|
|
210
|
-
*
|
|
211
|
-
* This structure provides a clean and organized export of the module's functionality, allowing consumers
|
|
212
|
-
* to easily import and use specific parts of the library as needed.
|
|
213
|
-
*/
|
|
214
|
-
/**
|
|
215
|
-
* @const VERSION
|
|
216
|
-
* @name VERSION
|
|
217
|
-
* @description Represents the current version of the ts-workspace module.
|
|
218
|
-
* @summary The actual version number is replaced during the build process.
|
|
219
|
-
* @type {string}
|
|
220
|
-
*/
|
|
221
|
-
const VERSION = "0.0.2";
|
|
222
|
-
|
|
223
|
-
exports.ChildClass = ChildClass;
|
|
224
|
-
exports.Class = Class;
|
|
923
|
+
exports.MCP_FILE_NAME = MCP_FILE_NAME;
|
|
924
|
+
exports.McpUtils = McpUtils;
|
|
925
|
+
exports.McpWrapper = McpWrapper;
|
|
926
|
+
exports.PACKAGE_NAME = PACKAGE_NAME;
|
|
225
927
|
exports.VERSION = VERSION;
|
|
226
|
-
exports.
|
|
227
|
-
exports.
|
|
928
|
+
exports.buildDocPrompts = buildDocPrompts;
|
|
929
|
+
exports.buildResourceTemplates = buildResourceTemplates;
|
|
930
|
+
exports.enrich = enrich;
|
|
931
|
+
exports.getWorkspaceRoot = getWorkspaceRoot;
|
|
932
|
+
exports.setWorkspaceRoot = setWorkspaceRoot;
|
|
933
|
+
exports.tools = tools;
|
|
228
934
|
|
|
229
935
|
}));
|
|
230
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy91dGlscy50cyIsIi4uL3NyYy9uYW1lc3BhY2UvQ2xhc3MudHMiLCIuLi9zcmMvbmFtZXNwYWNlL2NoaWxkcmVuL0NoaWxkQ2xhc3MudHMiLCIuLi9zcmMvbmFtZXNwYWNlL2NoaWxkcmVuL0VudW0udHMiLCIuLi9zcmMvbmFtZXNwYWNlL2NoaWxkcmVuL2Z1bmN0aW9uLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGZ1bmN0aW9uIGNvbXBsZXhGdW5jdGlvblxuICogQGRlc2NyaXB0aW9uIFRoaXMgZnVuY3Rpb24gdGFrZXMgYW4gb3B0aW9uYWwgc3RyaW5nIGFyZ3VtZW50IGFuZCBjb25jYXRlbmF0ZXMgaXQgd2l0aCBcIkhlbGxvIFdvcmxkXCIuXG4gKiBAc3VtbWFyeSBDb25jYXRlbmF0ZXMgXCJIZWxsbyBXb3JsZFwiIHdpdGggYSBnaXZlbiBzdHJpbmcuIERlc3BpdGUgaXRzIG5hbWUsIGl0J3MgYSBzaW1wbGUgc3RyaW5nIGNvbmNhdGVuYXRpb24gb3BlcmF0aW9uLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbYXJnMT1cImRlZmF1bHRcIl0gLSBUaGUgc3RyaW5nIHRvIGFwcGVuZCB0byBcIkhlbGxvIFdvcmxkXCIuIElmIG5vdCBwcm92aWRlZCwgZGVmYXVsdHMgdG8gXCJkZWZhdWx0XCIuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSByZXN1bHRpbmcgY29uY2F0ZW5hdGVkIHN0cmluZ1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyByZXR1cm5zIFwiSGVsbG8gV29ybGRkZWZhdWx0XCJcbiAqIGNvbXBsZXhGdW5jdGlvbigpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyByZXR1cm5zIFwiSGVsbG8gV29ybGQhXCJcbiAqIGNvbXBsZXhGdW5jdGlvbihcIiFcIik7XG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp0cy13b3Jrc3BhY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBsZXhGdW5jdGlvbihhcmcxOiBzdHJpbmcgPSBcImRlZmF1bHRcIikge1xuICByZXR1cm4gXCJIZWxsbyBXb3JsZFwiICsgYXJnMTtcbn1cbiIsImltcG9ydCB7IEludGVyZmFjZSB9IGZyb20gXCIuL0ludGVyZmFjZVwiO1xuXG4vKipcbiAqIEBjbGFzcyBDbGFzc1xuICogQGRlc2NyaXB0aW9uIEEgY2xhc3MgaW1wbGVtZW50aW5nIHRoZSBJbnRlcmZhY2UgY29udHJhY3QuXG4gKiBAc3VtbWFyeSBUaGlzIGNsYXNzIHByb3ZpZGVzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSBJbnRlcmZhY2UgY29udHJhY3Qgd2l0aCBhZGRpdGlvbmFsIHN0YXRpYyBmdW5jdGlvbmFsaXR5LlxuICogSXQgbWFuYWdlcyBhbiBpbnRlcm5hbCBzdGF0ZSB0aHJvdWdoIGEgcHJpdmF0ZSBwcm9wZXJ0eSBhbmQgb2ZmZXJzIGJvdGggaW5zdGFuY2UgYW5kIHN0YXRpYyBtZXRob2RzLlxuICpcbiAqIEBwYXJhbSB7dW5rbm93bn0gYXJnMSAtIEZpcnN0IGFyZ3VtZW50IG9mIHVua25vd24gdHlwZVxuICogQHBhcmFtIHtzdHJpbmd9IGFyZzIgLSBTZWNvbmQgYXJndW1lbnQgYXMgc3RyaW5nXG4gKlxuICogQGltcGxlbWVudHMge0ludGVyZmFjZX1cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlXG4gKiBjb25zdCBpbnN0YW5jZSA9IG5ldyBDbGFzcygnc29tZVZhbHVlJywgJ3N0cmluZ1ZhbHVlJyk7XG4gKlxuICogLy8gVXNpbmcgdGhlIGdlbmVyaWMgbWV0aG9kXG4gKiBhd2FpdCBpbnN0YW5jZS5tZXRob2Q8c3RyaW5nPigpXG4gKiAgIC5jYXRjaChlcnJvciA9PiBjb25zb2xlLmVycm9yKGVycm9yKSk7XG4gKlxuICogLy8gVXNpbmcgdGhlIHN0YXRpYyBtZXRob2RcbiAqIENsYXNzLm1ldGhvZCgpO1xuICogYGBgXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgSW5zdGFuY2VcbiAqICAgcGFydGljaXBhbnQgU3RhdGljXG4gKlxuICogICBDbGllbnQtPj5JbnN0YW5jZTogbmV3IENsYXNzKGFyZzEsIGFyZzIpXG4gKiAgIGFjdGl2YXRlIEluc3RhbmNlXG4gKiAgIEluc3RhbmNlLS0+PkNsaWVudDogY2xhc3MgaW5zdGFuY2VcbiAqICAgZGVhY3RpdmF0ZSBJbnN0YW5jZVxuICpcbiAqICAgQ2xpZW50LT4+SW5zdGFuY2U6IG1ldGhvZDxUPigpXG4gKiAgIGFjdGl2YXRlIEluc3RhbmNlXG4gKiAgIEluc3RhbmNlLS0+PkNsaWVudDogUHJvbWlzZTxzdHJpbmc+XG4gKiAgIGRlYWN0aXZhdGUgSW5zdGFuY2VcbiAqXG4gKiAgIENsaWVudC0+PlN0YXRpYzogQ2xhc3MubWV0aG9kKClcbiAqICAgYWN0aXZhdGUgU3RhdGljXG4gKiAgIFN0YXRpYy0tPj5DbGllbnQ6IHZvaWRcbiAqICAgZGVhY3RpdmF0ZSBTdGF0aWNcbiAqL1xuZXhwb3J0IGNsYXNzIENsYXNzIGltcGxlbWVudHMgSW50ZXJmYWNlIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcml2YXRlIHByb3BlcnR5IHRvIHN0b3JlIGludGVybmFsIHN0YXRlLlxuICAgKiBAc3VtbWFyeSBBbiB1bmtub3duIHR5cGUgcHJvcGVydHkgdXNlZCBmb3IgaW50ZXJuYWwgc3RhdGUgbWFuYWdlbWVudC5cbiAgICogQHByaXZhdGVcbiAgICogQHR5cGUge3Vua25vd259XG4gICAqL1xuICBwcml2YXRlIHByb3AhOiB1bmtub3duO1xuXG4gIGNvbnN0cnVjdG9yKGFyZzE6IHVua25vd24sIGFyZzI6IHN0cmluZykge1xuICAgIGNvbnNvbGUubG9nKGFyZzEsIGFyZzIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBc3luY2hyb25vdXMgbWV0aG9kIGltcGxlbWVudGluZyB0aGUgSW50ZXJmYWNlIGNvbnRyYWN0LlxuICAgKiBAc3VtbWFyeSBUaHJvd3MgYW4gZXJyb3Igd2l0aCB0eXBlIGNhc3RpbmcgY2hhaW4uXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBUIFRoZSB0eXBlIHBhcmFtZXRlciB1c2VkIGluIHRoZSBlcnJvciBjYXN0aW5nIGNoYWluXG4gICAqIEByZXR1cm4ge1Byb21pc2U8c3RyaW5nPn0gQSBQcm9taXNlIHRoYXQgYWx3YXlzIHJlamVjdHMgd2l0aCBhbiBlcnJvclxuICAgKiBAdGhyb3dzIHtFcnJvcn0gQWx3YXlzIHRocm93cyBhbiBlcnJvclxuICAgKi9cbiAgYXN5bmMgbWV0aG9kPFQ+KCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiZXJyb3JcIiBhcyBUIGFzIHVua25vd24gYXMgc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3RhdGljIG1ldGhvZCB0aGF0IHRocm93cyBhbiBlcnJvci5cbiAgICogQHN1bW1hcnkgQSBzdGF0aWMgdXRpbGl0eSBtZXRob2QgdGhhdCBhbHdheXMgdGhyb3dzIGFuIGVycm9yLlxuICAgKlxuICAgKiBAcmV0dXJuIHtuZXZlcn0gTmV2ZXIgcmV0dXJucyBhcyBpdCBhbHdheXMgdGhyb3dzIGFuIGVycm9yXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBBbHdheXMgdGhyb3dzIGFuIGVycm9yXG4gICAqIEBzdGF0aWNcbiAgICovXG4gIHN0YXRpYyBtZXRob2QoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiZXJyb3JcIik7XG4gIH1cbn1cbiIsImltcG9ydCB7IENsYXNzIH0gZnJvbSBcIi4uL0NsYXNzXCI7XG5pbXBvcnQgeyBDaGlsZEludGVyZmFjZSB9IGZyb20gXCIuL0NoaWxkSW50ZXJmYWNlXCI7XG5cbi8qKlxuICogQGNsYXNzIENoaWxkQ2xhc3NcbiAqIEBkZXNjcmlwdGlvbiBUaGlzIGNsYXNzIGV4dGVuZHMgdGhlIGJhc2UgQ2xhc3MgYW5kIGltcGxlbWVudHMgdGhlIENoaWxkSW50ZXJmYWNlLlxuICogQHN1bW1hcnkgR2VuZXJpYyBjbGFzcyBleHRlbmRpbmcgQ2xhc3MgYW5kIGltcGxlbWVudGluZyBDaGlsZEludGVyZmFjZSB3aXRoIGFkZGl0aW9uYWwgZnVuY3Rpb25hbGl0eS5cbiAqIEl0IHByb3ZpZGVzIGEgZ2VuZXJpYyBpbXBsZW1lbnRhdGlvbiB3aXRoIGFkZGl0aW9uYWwgcHJvcGVydGllcyBhbmQgbWV0aG9kcy5cbiAqXG4gKiBAcGFyYW0ge3Vua25vd259IGFyZzEgLSBGaXJzdCBhcmd1bWVudCBvZiB1bmtub3duIHR5cGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmcyIC0gU2Vjb25kIGFyZ3VtZW50IGFzIHN0cmluZ1xuICpcbiAqIEB0ZW1wbGF0ZSBUIC0gVGhlIGdlbmVyaWMgdHlwZSBwYXJhbWV0ZXJcbiAqIEBleHRlbmRzIHtDbGFzc31cbiAqIEBpbXBsZW1lbnRzIHtDaGlsZEludGVyZmFjZTxUPn1cbiAqL1xuZXhwb3J0IGNsYXNzIENoaWxkQ2xhc3M8VD4gZXh0ZW5kcyBDbGFzcyBpbXBsZW1lbnRzIENoaWxkSW50ZXJmYWNlPFQ+IHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBIHByaXZhdGUgcHJvcGVydHkgb2YgZ2VuZXJpYyB0eXBlIFQuXG4gICAqIEB0ZW1wbGF0ZSB7VH1cbiAgICogQHN1bW1hcnkgU3RvcmVzIHRoZSBmaXJzdCBjb25zdHJ1Y3RvciBhcmd1bWVudCBmb3IgbGF0ZXIgdXNlLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAdHlwZSB7VH1cbiAgICovXG4gIHByaXZhdGUgcHJvcDI/OiBUO1xuXG4gIGNvbnN0cnVjdG9yKGFyZzE6IFQsIGFyZzI6IHN0cmluZykge1xuICAgIHN1cGVyKGFyZzEsIGFyZzIpO1xuICAgIHRoaXMucHJvcDIgPSBhcmcxO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBvdmVycmlkZXMgdGhlIGJhc2UgY2xhc3MgbWV0aG9kLlxuICAgKiBAc3VtbWFyeSBBc3luY2hyb25vdXMgbWV0aG9kIHRoYXQgcmV0dXJucyBhIHN0cmluZyBhZnRlciBhIHNlcmllcyBvZiB0eXBlIGFzc2VydGlvbnMuXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBWIC0gVGhlIGdlbmVyaWMgdHlwZSBwYXJhbWV0ZXJcbiAgICogQHJldHVybiB7UHJvbWlzZTxzdHJpbmc+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHN0cmluZ1xuICAgKiBAb3ZlcnJpZGVcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIG1ldGhvZDxWPigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBcIm9rXCIgYXMgdW5rbm93biBhcyBWIGFzIHVua25vd24gYXMgc3RyaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpbXBsZW1lbnRzIHRoZSBtZXRob2QyIGZyb20gQ2hpbGRJbnRlcmZhY2UuXG4gICAqIEBzdW1tYXJ5IE1ldGhvZCB0aGF0IHRocm93cyBhbiBlcnJvciB3aXRoIGEgbWVzc2FnZSB0aGF0IGluY2x1ZGVzIHRoZSBpbnB1dCBhcmd1bWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtUfSBhcmcxIC0gVGhlIGlucHV0IGFyZ3VtZW50IG9mIGdlbmVyaWMgdHlwZSBUXG4gICAqIEByZXR1cm4ge1Byb21pc2U8c3RyaW5nPn0gQSBQcm9taXNlIHRoYXQgYWx3YXlzIHJlamVjdHMgd2l0aCBhbiBlcnJvclxuICAgKiBAdGhyb3dzIHtFcnJvcn0gQWx3YXlzIHRocm93cyBhbiBlcnJvciB3aXRoIGEgbWVzc2FnZSBpbmNsdWRpbmcgYXJnMVxuICAgKi9cbiAgbWV0aG9kMihhcmcxOiBUKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJlcnJvclwiICsgYXJnMSk7XG4gIH1cbn1cbiIsIi8qKlxuICogQGNvbnN0IEVudW1cbiAqIEBuYW1lIEVudW1cbiAqIEBkZXNjcmlwdGlvbiBUaGlzIGVudW0gcHJvdmlkZXMgYSBzZXQgb2YgcHJlZGVmaW5lZCBvcHRpb25zIHRoYXQgY2FuIGJlIHVzZWQgdGhyb3VnaG91dCB0aGUgYXBwbGljYXRpb24uXG4gKiBAc3VtbWFyeSBFbnVtZXJhdGlvbiBvZiBzdHJpbmcgb3B0aW9ucyBmb3IgY29uc2lzdGVudCB2YWx1ZSByZXByZXNlbnRhdGlvbi5cbiAqIEB0eXBlIHtlbnVtfVxuICogQHJlYWRvbmx5XG4gKiBcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dHMtd29ya3NwYWNlLk5hbWVzcGFjZS5DaGlsZE5hbWVzcGFjZVxuICovXG5leHBvcnQgZW51bSBFbnVtIHtcbiAgLyoqIFJlcHJlc2VudHMgdGhlIGZpcnN0IG9wdGlvbiB3aXRoIHZhbHVlIFwic29tZXRoaW5nXCIgKi9cbiAgT1BUSU9OMSA9IFwic29tZXRoaW5nXCIsXG59XG4iLCJpbXBvcnQgeyBDbGFzcyB9IGZyb20gXCIuLi9DbGFzc1wiO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCIuLi90eXBlXCI7XG5cbi8qKlxuICogQGZ1bmN0aW9uIHNvbWV0aGluZ1xuICogQGRlc2NyaXB0aW9uIFRoaXMgZnVuY3Rpb24gaXMgYSBnZW5lcmljIG1ldGhvZCB0aGF0IGV4dGVuZHMgdGhlIENsYXNzIHR5cGUuXG4gKiBAc3VtbWFyeSBHZW5lcmljIGZ1bmN0aW9uIHRoYXQgbG9ncyBhcmd1bWVudHMgYW5kIHJldHVybnMgdGhlIGNvbnRleHQgKHRoaXMpIG9mIHRoZSBmdW5jdGlvbi5cbiAqIEl0IGxvZ3MgYWxsIHByb3ZpZGVkIGFyZ3VtZW50cyB0byB0aGUgY29uc29sZSBhbmQgcmV0dXJucyB0aGUgY29udGV4dCAodGhpcykgb2YgdGhlIGZ1bmN0aW9uLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIC0gVHlwZSBleHRlbmRpbmcge0BsaW5rIENsYXNzfVxuICogQHRlbXBsYXRlIFYgLSBUeXBlIG9mIHRoZSBhcmd1bWVudHNcbiAqIEB0aGlzIHtUfVxuICogQHBhcmFtIHsuLi5WfSBhcmdzIC0gVmFyaWFibGUgbnVtYmVyIG9mIGFyZ3VtZW50cyBvZiB0eXBlIFZcbiAqIEByZXR1cm4ge1R5cGU8VD59IFJldHVybnMgdGhlIGNvbnRleHQgKHRoaXMpIG9mIHRoZSBmdW5jdGlvblxuICpcbiAqIEBleGFtcGxlXG4gKiBjbGFzcyBNeUNsYXNzIGV4dGVuZHMgQ2xhc3Mge1xuICogICBteU1ldGhvZCgpIHtcbiAqICAgICByZXR1cm4gc29tZXRoaW5nLmNhbGwodGhpcywgJ2FyZzEnLCAnYXJnMicpO1xuICogICB9XG4gKiB9XG4gKiBcbiAqIGNvbnN0IGluc3RhbmNlID0gbmV3IE15Q2xhc3MoKTtcbiAqIGNvbnN0IHJlc3VsdCA9IGluc3RhbmNlLm15TWV0aG9kKCk7XG4gKiAvLyBMb2dzOiAnYXJnMScsICdhcmcyJ1xuICogLy8gcmVzdWx0IGlzIHRoZSBpbnN0YW5jZSBvZiBNeUNsYXNzXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp0cy13b3Jrc3BhY2UuTmFtZXNwYWNlLkNoaWxkTmFtZXNwYWNlXG4gKiBAc2VlIHtAbGluayBDbGFzc31cbiAqIEBzZWUge0BsaW5rIFR5cGV9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzb21ldGhpbmc8VCBleHRlbmRzIENsYXNzLCBWPih0aGlzOiBULCAuLi5hcmdzOiBWW10pOiBUeXBlPFQ+IHtcbiAgY29uc29sZS5sb2coLi4uYXJncyk7XG4gIHJldHVybiB0aGlzO1xufVxuIiwiLyoqXG4gKiBAbW9kdWxlIHRzLXdvcmtzcGFjZVxuICogQGRlc2NyaXB0aW9uIFRoaXMgbW9kdWxlIHNlcnZlcyBhcyB0aGUgbWFpbiBlbnRyeSBwb2ludCBmb3IgdGhlIHRzLXdvcmtzcGFjZSBsaWJyYXJ5LlxuICogQHN1bW1hcnkgQWdncmVnYXRlcyBhbmQgZXhwb3J0cyBmdW5jdGlvbmFsaXR5IGZyb20gdmFyaW91cyBzdWJtb2R1bGVzIGFuZCB1dGlsaXRpZXMgd2l0aGluIHRoZSBwcm9qZWN0LlxuICogXG4gKiBUaGUgbW9kdWxlIGluY2x1ZGVzOlxuICogMS4gVXRpbGl0eSBmdW5jdGlvbnMgYW5kIHR5cGVzIGZyb20gdGhlIFwiLi91dGlsc1wiIGRpcmVjdG9yeTpcbiAqICAgIC0gVGhlc2UgbGlrZWx5IGNvbnRhaW4gaGVscGVyIGZ1bmN0aW9ucywgY29tbW9uIHR5cGVzLCBhbmQgc2hhcmVkIGZ1bmN0aW9uYWxpdHkgdXNlZCB0aHJvdWdob3V0IHRoZSBwcm9qZWN0LlxuICogICAgLSBNYXkgaW5jbHVkZSBvcGVyYXRpb25zIGZvciBkYXRhIG1hbmlwdWxhdGlvbiwgdHlwZSBjaGVja2luZywgb3Igb3RoZXIgZ2VuZXJhbC1wdXJwb3NlIHV0aWxpdGllcy5cbiAqIFxuICogMi4gQSBuYW1lc3BhY2UgYW5kIHJlbGF0ZWQgdHlwZXMgZnJvbSB0aGUgXCIuL25hbWVzcGFjZVwiIGRpcmVjdG9yeTpcbiAqICAgIC0gVGhpcyBjb3VsZCBjb250YWluIGRvbWFpbi1zcGVjaWZpYyBjb2RlIG9yIGEgY29sbGVjdGlvbiBvZiByZWxhdGVkIGZ1bmN0aW9uYWxpdHkuXG4gKiAgICAtIE1pZ2h0IGluY2x1ZGUgaW50ZXJmYWNlcywgdHlwZXMsIG9yIGNsYXNzZXMgdGhhdCByZXByZXNlbnQgY29yZSBjb25jZXB0cyBpbiB0aGUgbGlicmFyeS5cbiAqIFxuICogMy4gQSBWRVJTSU9OIGNvbnN0YW50OlxuICogICAgLSBSZXByZXNlbnRzIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIG1vZHVsZS5cbiAqICAgIC0gVXNlZnVsIGZvciB2ZXJzaW9uIGNoZWNraW5nIGFuZCBjb21wYXRpYmlsaXR5IHB1cnBvc2VzLlxuICogXG4gKiBUaGlzIHN0cnVjdHVyZSBwcm92aWRlcyBhIGNsZWFuIGFuZCBvcmdhbml6ZWQgZXhwb3J0IG9mIHRoZSBtb2R1bGUncyBmdW5jdGlvbmFsaXR5LCBhbGxvd2luZyBjb25zdW1lcnNcbiAqIHRvIGVhc2lseSBpbXBvcnQgYW5kIHVzZSBzcGVjaWZpYyBwYXJ0cyBvZiB0aGUgbGlicmFyeSBhcyBuZWVkZWQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSBcIi4vdXRpbHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL25hbWVzcGFjZVwiO1xuXG4vKipcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbmFtZSBWRVJTSU9OXG4gKiBAZGVzY3JpcHRpb24gUmVwcmVzZW50cyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSB0cy13b3Jrc3BhY2UgbW9kdWxlLlxuICogQHN1bW1hcnkgVGhlIGFjdHVhbCB2ZXJzaW9uIG51bWJlciBpcyByZXBsYWNlZCBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6WyJFbnVtIl0sIm1hcHBpbmdzIjoiOzs7Ozs7SUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFpQkc7SUFDYSxTQUFBLGVBQWUsQ0FBQyxJQUFBLEdBQWUsU0FBUyxFQUFBO1FBQ3RELE9BQU8sYUFBYSxHQUFHLElBQUk7SUFDN0I7O0lDbEJBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQTRDRztVQUNVLEtBQUssQ0FBQTtRQVNoQixXQUFZLENBQUEsSUFBYSxFQUFFLElBQVksRUFBQTtJQUNyQyxRQUFBLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQzs7SUFHekI7Ozs7Ozs7SUFPRztJQUNILElBQUEsTUFBTSxNQUFNLEdBQUE7SUFDVixRQUFBLE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBaUMsQ0FBQzs7SUFHcEQ7Ozs7Ozs7SUFPRztJQUNILElBQUEsT0FBTyxNQUFNLEdBQUE7SUFDWCxRQUFBLE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDOztJQUUzQjs7SUNoRkQ7Ozs7Ozs7Ozs7OztJQVlHO0lBQ0csTUFBTyxVQUFjLFNBQVEsS0FBSyxDQUFBO1FBVXRDLFdBQVksQ0FBQSxJQUFPLEVBQUUsSUFBWSxFQUFBO0lBQy9CLFFBQUEsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUM7SUFDakIsUUFBQSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUk7O0lBR25COzs7Ozs7O0lBT0c7SUFDTSxJQUFBLE1BQU0sTUFBTSxHQUFBO0lBQ25CLFFBQUEsT0FBTyxJQUF5Qzs7SUFHbEQ7Ozs7Ozs7SUFPRztJQUNILElBQUEsT0FBTyxDQUFDLElBQU8sRUFBQTtJQUNiLFFBQUEsTUFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDOztJQUVsQzs7SUN0REQ7Ozs7Ozs7OztJQVNHO0FBQ1NBO0lBQVosQ0FBQSxVQUFZLElBQUksRUFBQTs7SUFFZCxJQUFBLElBQUEsQ0FBQSxTQUFBLENBQUEsR0FBQSxXQUFxQjtJQUN2QixDQUFDLEVBSFdBLFlBQUksS0FBSkEsWUFBSSxHQUdmLEVBQUEsQ0FBQSxDQUFBOztJQ1ZEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUEyQkc7SUFDYSxTQUFBLFNBQVMsQ0FBOEIsR0FBRyxJQUFTLEVBQUE7SUFDakUsSUFBQSxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO0lBQ3BCLElBQUEsT0FBTyxJQUFJO0lBQ2I7O0lDbENBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQW9CRztJQUtIOzs7Ozs7SUFNRztBQUNJLFVBQU0sT0FBTyxHQUFHOzs7Ozs7Ozs7Ozs7In0=
|
|
936
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9tZXRhZGF0YS50cyIsIi4uL3NyYy9tb2R1bGVzL21jcC9kZWNvcmF0b3ItdG9vbHMudHMiLCIuLi9zcmMvbW9kdWxlcy9tY3AvbWNwLW1vZHVsZS50cyIsIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvTWNwV3JhcHBlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdGlvblwiO1xuXG4vKipcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbmFtZSBWRVJTSU9OXG4gKiBAZGVzY3JpcHRpb24gUmVwcmVzZW50cyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSB0cy13b3Jrc3BhY2UgbW9kdWxlLlxuICogQHN1bW1hcnkgVGhlIGFjdHVhbCB2ZXJzaW9uIG51bWJlciBpcyByZXBsYWNlZCBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX05BTUUgPSBcIiMjUEFDS0FHRV9OQU1FIyNcIjtcblxudHJ5IHtcbiAgTWV0YWRhdGEucmVnaXN0ZXJMaWJyYXJ5KFBBQ0tBR0VfTkFNRSwgVkVSU0lPTik7XG59IGNhdGNoIChlcnJvcikge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKFwiYWxyZWFkeVwiKSkge1xuICAgIC8vIElnbm9yZSBkdXBsaWNhdGUgcmVnaXN0cmF0aW9uIGR1cmluZyB0ZXN0cy9idW5kbGluZyBjaGVja3MuXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmV4cG9ydCB0eXBlIERlY29yYXRvclNwZWMgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJncz86IHVua25vd25bXTtcbn07XG5cbmV4cG9ydCB0eXBlIEF0dHJpYnV0ZVNwZWMgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICBkZWNvcmF0b3JzPzogRGVjb3JhdG9yU3BlY1tdO1xufTtcblxuZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHZhbHVlOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCBcIlxcXFwkJlwiKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0RGVjb3JhdG9yKHNwZWM6IERlY29yYXRvclNwZWMpOiBzdHJpbmcge1xuICBjb25zdCBhcmdzID0gKHNwZWMuYXJncyB8fCBbXSkubWFwKChhcmcpID0+IEpTT04uc3RyaW5naWZ5KGFyZykpLmpvaW4oXCIsIFwiKTtcbiAgcmV0dXJuIGBAJHtzcGVjLm5hbWV9KCR7YXJnc30pYDtcbn1cblxuZnVuY3Rpb24gZW5zdXJlRGlyZWN0b3J5KGZpbGVQYXRoOiBzdHJpbmcpIHtcbiAgZnMubWtkaXJTeW5jKHBhdGguZGlybmFtZShmaWxlUGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0RGVjb3JhdG9yTmFtZXMoXG4gIGNsYXNzRGVjb3JhdG9yczogRGVjb3JhdG9yU3BlY1tdIHwgdW5kZWZpbmVkLFxuICBwcm9wZXJ0aWVzOiBBdHRyaWJ1dGVTcGVjW10gfCB1bmRlZmluZWRcbikge1xuICBjb25zdCBuYW1lcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBuYW1lcy5hZGQoXCJtb2RlbFwiKTtcbiAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgY2xhc3NEZWNvcmF0b3JzIHx8IFtdKSB7XG4gICAgbmFtZXMuYWRkKGRlY29yYXRvci5uYW1lKTtcbiAgfVxuICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIHByb3BlcnRpZXMgfHwgW10pIHtcbiAgICBmb3IgKGNvbnN0IGRlY29yYXRvciBvZiBwcm9wZXJ0eS5kZWNvcmF0b3JzIHx8IFtdKSB7XG4gICAgICBuYW1lcy5hZGQoZGVjb3JhdG9yLm5hbWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmFtZXM7XG59XG5cbmZ1bmN0aW9uIGVuc3VyZUltcG9ydChcbiAgY29udGVudDogc3RyaW5nLFxuICBpbXBvcnRzRnJvbTogc3RyaW5nLFxuICBkZWNvcmF0b3JzOiBTZXQ8c3RyaW5nPlxuKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmICghZGVjb3JhdG9ycy5zaXplKSByZXR1cm4gY29udGVudDtcbiAgY29uc3QgaW1wb3J0UmVnZXggPSBuZXcgUmVnRXhwKFxuICAgIGBpbXBvcnRcXFxccytcXFxceyhbXn1dKylcXFxcfVxcXFxzK2Zyb21cXFxccytbXCInXSR7ZXNjYXBlUmVnRXhwKGltcG9ydHNGcm9tKX1bXCInXTtgXG4gICk7XG4gIGNvbnN0IG1hdGNoID0gY29udGVudC5tYXRjaChpbXBvcnRSZWdleCk7XG4gIGNvbnN0IHNvcnRlZCA9IEFycmF5LmZyb20oZGVjb3JhdG9ycykuc29ydCgpO1xuXG4gIGlmIChtYXRjaCkge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gbWF0Y2hbMV1cbiAgICAgIC5zcGxpdChcIixcIilcbiAgICAgIC5tYXAoKG5hbWUpID0+IG5hbWUudHJpbSgpKVxuICAgICAgLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCBtZXJnZWQgPSBBcnJheS5mcm9tKG5ldyBTZXQoWy4uLmV4aXN0aW5nLCAuLi5zb3J0ZWRdKSkuc29ydCgpO1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoXG4gICAgICBpbXBvcnRSZWdleCxcbiAgICAgIGBpbXBvcnQgeyAke21lcmdlZC5qb2luKFwiLCBcIil9IH0gZnJvbSBcIiR7aW1wb3J0c0Zyb219XCI7YFxuICAgICk7XG4gIH1cblxuICBjb25zdCBpbXBvcnRMaW5lID0gYGltcG9ydCB7ICR7c29ydGVkLmpvaW4oXCIsIFwiKX0gfSBmcm9tIFwiJHtpbXBvcnRzRnJvbX1cIjtgO1xuICByZXR1cm4gYCR7aW1wb3J0TGluZX1cXG5cXG4ke2NvbnRlbnR9YDtcbn1cblxuZnVuY3Rpb24gYWRkUHJvcGVydHlCbG9jayhwcm9wZXJ0eTogQXR0cmlidXRlU3BlYykge1xuICBjb25zdCBkZWNvcmF0b3JzID0gKHByb3BlcnR5LmRlY29yYXRvcnMgfHwgW10pXG4gICAgLm1hcChmb3JtYXREZWNvcmF0b3IpXG4gICAgLmpvaW4oXCJcXG4gIFwiKTtcbiAgY29uc3QgZGVjb3JhdG9yQmxvY2sgPSBkZWNvcmF0b3JzID8gYCAgJHtkZWNvcmF0b3JzfVxcbmAgOiBcIlwiO1xuICByZXR1cm4gYCR7ZGVjb3JhdG9yQmxvY2t9ICAke3Byb3BlcnR5Lm5hbWV9OiAke3Byb3BlcnR5LnR5cGV9O2A7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVByb3BlcnR5QmxvY2soY29udGVudDogc3RyaW5nLCBwcm9wZXJ0eU5hbWU6IHN0cmluZykge1xuICBjb25zdCBsaW5lcyA9IGNvbnRlbnQuc3BsaXQoL1xccj9cXG4vKTtcbiAgY29uc3QgcmVzdWx0OiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgbGluZSA9IGxpbmVzW2ldO1xuICAgIGlmIChcbiAgICAgIGxpbmUudHJpbSgpLnN0YXJ0c1dpdGgoYEBgKSAmJlxuICAgICAgbGluZXNbaSArIDFdPy5pbmNsdWRlcyhgJHtwcm9wZXJ0eU5hbWV9OmApXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGxpbmUuaW5jbHVkZXMoYCR7cHJvcGVydHlOYW1lfTpgKSkge1xuICAgICAgLy8gc2tpcCB0aGlzIGxpbmUgYW5kIGFueSB0cmFpbGluZyBibGFuayBsaW5lXG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgcmVzdWx0LnB1c2gobGluZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5qb2luKFwiXFxuXCIpO1xufVxuXG5mdW5jdGlvbiBpbnNlcnREZWNvcmF0b3IoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgZGVjb3JhdG9yOiBEZWNvcmF0b3JTcGVjLFxuICB0YXJnZXQ6IHtcbiAgICBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7XG4gICAgbmFtZT86IHN0cmluZztcbiAgfVxuKSB7XG4gIGNvbnN0IGRlY29yYXRvckxpbmUgPSBmb3JtYXREZWNvcmF0b3IoZGVjb3JhdG9yKTtcbiAgaWYgKHRhcmdldC5raW5kID09PSBcImNsYXNzXCIpIHtcbiAgICBjb25zdCBjbGFzc1JlZ2V4ID0gLyhleHBvcnRcXHMrY2xhc3NcXHMrW15cXHN7XStcXHMqXFx7KS87XG4gICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoZGVjb3JhdG9yTGluZSkpIHJldHVybiBjb250ZW50O1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoY2xhc3NSZWdleCwgYCR7ZGVjb3JhdG9yTGluZX1cXG4kMWApO1xuICB9XG4gIGlmICghdGFyZ2V0Lm5hbWUpIHJldHVybiBjb250ZW50O1xuICBjb25zdCBwcm9wZXJ0eVJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICBgKF5cXFxccyopKD86QC4qXFxcXG5cXFxcMSkqJHtlc2NhcGVSZWdFeHAodGFyZ2V0Lm5hbWUpfTpgLFxuICAgIFwibVwiXG4gICk7XG4gIGNvbnN0IG1hdGNoID0gcHJvcGVydHlSZWdleC5leGVjKGNvbnRlbnQpO1xuICBpZiAoIW1hdGNoKSByZXR1cm4gY29udGVudDtcbiAgY29uc3QgaW5kZW50ID0gbWF0Y2hbMV0gfHwgXCIgIFwiO1xuICBpZiAoY29udGVudC5pbmNsdWRlcyhgJHtpbmRlbnR9JHtkZWNvcmF0b3JMaW5lfWApKSByZXR1cm4gY29udGVudDtcbiAgcmV0dXJuIChcbiAgICBjb250ZW50LnNsaWNlKDAsIG1hdGNoLmluZGV4KSArXG4gICAgYCR7aW5kZW50fSR7ZGVjb3JhdG9yTGluZX1cXG5gICtcbiAgICBjb250ZW50LnNsaWNlKG1hdGNoLmluZGV4KVxuICApO1xufVxuXG5mdW5jdGlvbiByZW1vdmVEZWNvcmF0b3IoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgZGVjb3JhdG9yTmFtZTogc3RyaW5nLFxuICB0YXJnZXQ6IHtcbiAgICBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7XG4gICAgbmFtZT86IHN0cmluZztcbiAgfVxuKSB7XG4gIGNvbnN0IGRlY29yYXRvclJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICBgXlxcXFxzKkAke2VzY2FwZVJlZ0V4cChkZWNvcmF0b3JOYW1lKX1cXFxcKFteKV0qXFxcXClgLFxuICAgIFwibVwiXG4gICk7XG4gIGlmICh0YXJnZXQua2luZCA9PT0gXCJjbGFzc1wiKSB7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShkZWNvcmF0b3JSZWdleCwgXCJcIik7XG4gIH1cbiAgaWYgKHRhcmdldC5uYW1lKSB7XG4gICAgY29uc3QgcGF0dGVybiA9IG5ldyBSZWdFeHAoXG4gICAgICBgKF5cXFxccypAJHtlc2NhcGVSZWdFeHAoZGVjb3JhdG9yTmFtZSl9XFxcXChbXildKlxcXFwpXFxcXHMqJFxcXFxuKSg/PVxcXFxzKiR7ZXNjYXBlUmVnRXhwKHRhcmdldC5uYW1lKX06KWAsXG4gICAgICBcIm1cIlxuICAgICk7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShwYXR0ZXJuLCBcIlwiKTtcbiAgfVxuICByZXR1cm4gY29udGVudDtcbn1cblxuZnVuY3Rpb24gd3JpdGVJZkNoYW5nZWQoZmlsZVBhdGg6IHN0cmluZywgY29udGVudDogc3RyaW5nKSB7XG4gIGVuc3VyZURpcmVjdG9yeShmaWxlUGF0aCk7XG4gIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIGNvbnRlbnQpO1xufVxuXG5leHBvcnQgY29uc3QgZGVjb3JhdG9yVG9vbHMgPSB7XG4gIGNyZWF0ZU9yVXBkYXRlTW9kZWxUb29sOiB7XG4gICAgbmFtZTogXCJjcmVhdGUtb3ItdXBkYXRlLW1vZGVsXCIsXG4gICAgZGVzY3JpcHRpb246IFwiQ3JlYXRlIG9yIHVwZGF0ZSBhIHZhbGlkYXRpb24tcmVhZHkgbW9kZWwgY2xhc3NcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgY2xhc3NEZWNvcmF0b3JzPzogRGVjb3JhdG9yU3BlY1tdO1xuICAgICAgcHJvcGVydGllczogQXR0cmlidXRlU3BlY1tdO1xuICAgICAgaW1wb3J0c0Zyb206IHN0cmluZztcbiAgICAgIG92ZXJ3cml0ZT86IGJvb2xlYW47XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFhcmdzLm92ZXJ3cml0ZSAmJiBmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRmlsZSBhbHJlYWR5IGV4aXN0cyBhdCAke2FyZ3MuZmlsZVBhdGh9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBkZWNvcmF0b3JzID0gY29sbGVjdERlY29yYXRvck5hbWVzKFxuICAgICAgICBhcmdzLmNsYXNzRGVjb3JhdG9ycyxcbiAgICAgICAgYXJncy5wcm9wZXJ0aWVzXG4gICAgICApO1xuICAgICAgbGV0IGNvbnRlbnQgPSBgQG1vZGVsKClgO1xuICAgICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgYXJncy5jbGFzc0RlY29yYXRvcnMgfHwgW10pIHtcbiAgICAgICAgY29udGVudCArPSBgXFxuJHtmb3JtYXREZWNvcmF0b3IoZGVjb3JhdG9yKX1gO1xuICAgICAgfVxuICAgICAgY29uc3QgcHJvcGVydGllcyA9IChhcmdzLnByb3BlcnRpZXMgfHwgW10pXG4gICAgICAgIC5tYXAoYWRkUHJvcGVydHlCbG9jaylcbiAgICAgICAgLmpvaW4oXCJcXG5cXG5cIik7XG4gICAgICBjb250ZW50ICs9IGBcXG5leHBvcnQgY2xhc3MgJHthcmdzLmNsYXNzTmFtZX0ge1xcbiR7cHJvcGVydGllcyA/IGAke3Byb3BlcnRpZXN9XFxuYCA6IFwiXCJ9fVxcbmA7XG4gICAgICBjb250ZW50ID0gZW5zdXJlSW1wb3J0KGNvbnRlbnQsIGFyZ3MuaW1wb3J0c0Zyb20sIGRlY29yYXRvcnMpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIGFkZEF0dHJpYnV0ZVRvb2w6IHtcbiAgICBuYW1lOiBcImFkZC1hdHRyaWJ1dGVcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBZGQgYSBkZWNvcmF0ZWQgYXR0cmlidXRlIHRvIGFuIGV4aXN0aW5nIG1vZGVsXCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIGF0dHJpYnV0ZTogQXR0cmlidXRlU3BlYztcbiAgICAgIGltcG9ydHNGcm9tOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTW9kZWwgZmlsZSBub3QgZm91bmQgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgICAgfVxuICAgICAgbGV0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoYCR7YXJncy5hdHRyaWJ1dGUubmFtZX06YCkpIHtcbiAgICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlY29yYXRvcnMgPSBjb2xsZWN0RGVjb3JhdG9yTmFtZXModW5kZWZpbmVkLCBbYXJncy5hdHRyaWJ1dGVdKTtcbiAgICAgIGNvbnRlbnQgPSBlbnN1cmVJbXBvcnQoY29udGVudCwgYXJncy5pbXBvcnRzRnJvbSwgZGVjb3JhdG9ycyk7XG4gICAgICBjb25zdCBpbnNlcnRpb25Qb2ludCA9IGNvbnRlbnQubGFzdEluZGV4T2YoXCJ9XCIpO1xuICAgICAgY29uc3QgYmxvY2sgPSBhZGRQcm9wZXJ0eUJsb2NrKGFyZ3MuYXR0cmlidXRlKTtcbiAgICAgIGNvbnN0IGJlZm9yZSA9IGNvbnRlbnQuc2xpY2UoMCwgaW5zZXJ0aW9uUG9pbnQpLnJlcGxhY2UoL1xccyokLywgXCJcIik7XG4gICAgICBjb25zdCBhZnRlciA9IGNvbnRlbnQuc2xpY2UoaW5zZXJ0aW9uUG9pbnQpO1xuICAgICAgY29uc3QgdXBkYXRlZCA9IGAke2JlZm9yZX1cXG4ke2Jsb2NrfVxcbiR7YWZ0ZXJ9YDtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIHVwZGF0ZWQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICByZW1vdmVBdHRyaWJ1dGVUb29sOiB7XG4gICAgbmFtZTogXCJyZW1vdmUtYXR0cmlidXRlXCIsXG4gICAgZGVzY3JpcHRpb246IFwiUmVtb3ZlIGFuIGF0dHJpYnV0ZSBmcm9tIGEgbW9kZWwgY2xhc3NcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgYXR0cmlidXRlTmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgdXBkYXRlZCA9IHJlbW92ZVByb3BlcnR5QmxvY2soY29udGVudCwgYXJncy5hdHRyaWJ1dGVOYW1lKTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIHVwZGF0ZWQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICBhcHBseURlY29yYXRvclRvb2w6IHtcbiAgICBuYW1lOiBcImFwcGx5LWRlY29yYXRvclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkFwcGx5IGEgZGVjb3JhdG9yIHRvIGEgY2xhc3Mgb3IgcHJvcGVydHlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgdGFyZ2V0OiB7IGtpbmQ6IFwiY2xhc3NcIiB8IFwicHJvcGVydHlcIjsgbmFtZT86IHN0cmluZyB9O1xuICAgICAgZGVjb3JhdG9yOiBEZWNvcmF0b3JTcGVjO1xuICAgICAgaW1wb3J0c0Zyb206IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb2RlbCBmaWxlIG5vdCBmb3VuZCBhdCAke2FyZ3MuZmlsZVBhdGh9YCk7XG4gICAgICB9XG4gICAgICBsZXQgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhhcmdzLmZpbGVQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCBkZWNvcmF0b3JzID0gbmV3IFNldDxzdHJpbmc+KFthcmdzLmRlY29yYXRvci5uYW1lXSk7XG4gICAgICBjb250ZW50ID0gZW5zdXJlSW1wb3J0KGNvbnRlbnQsIGFyZ3MuaW1wb3J0c0Zyb20sIGRlY29yYXRvcnMpO1xuICAgICAgY29udGVudCA9IGluc2VydERlY29yYXRvcihjb250ZW50LCBhcmdzLmRlY29yYXRvciwgYXJncy50YXJnZXQpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIHJlbW92ZURlY29yYXRvclRvb2w6IHtcbiAgICBuYW1lOiBcInJlbW92ZS1kZWNvcmF0b3JcIixcbiAgICBkZXNjcmlwdGlvbjogXCJSZW1vdmUgYSBkZWNvcmF0b3IgZnJvbSBhIGNsYXNzIG9yIHByb3BlcnR5XCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIHRhcmdldDogeyBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7IG5hbWU/OiBzdHJpbmcgfTtcbiAgICAgIGRlY29yYXRvck5hbWU6IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgICBsZXQgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhhcmdzLmZpbGVQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb250ZW50ID0gcmVtb3ZlRGVjb3JhdG9yKGNvbnRlbnQsIGFyZ3MuZGVjb3JhdG9yTmFtZSwgYXJncy50YXJnZXQpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIHNjYWZmb2xkVmFsaWRhdG9yVG9vbDoge1xuICAgIG5hbWU6IFwic2NhZmZvbGQtdmFsaWRhdG9yXCIsXG4gICAgZGVzY3JpcHRpb246IFwiU2NhZmZvbGQgYSB2YWxpZGF0b3IgY2xhc3MgYW5kIG9wdGlvbmFsIGRlY29yYXRvclwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICB2YWxpZGF0b3JzRGlyOiBzdHJpbmc7XG4gICAgICBkZWNvcmF0b3JEaXI/OiBzdHJpbmc7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgY29uc3QgY2xhc3NGaWxlID0gcGF0aC5qb2luKGFyZ3MudmFsaWRhdG9yc0RpciwgYCR7YXJncy5uYW1lfS50c2ApO1xuICAgICAgZW5zdXJlRGlyZWN0b3J5KGNsYXNzRmlsZSk7XG4gICAgICBjb25zdCBjbGFzc0NvbnRlbnQgPSBgZXhwb3J0IGNsYXNzICR7YXJncy5uYW1lfSB7XFxuICB2YWxpZGF0ZSh2YWx1ZTogdW5rbm93bik6IGJvb2xlYW4ge1xcbiAgICByZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZDtcXG4gIH1cXG59XFxuYDtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoY2xhc3NGaWxlLCBjbGFzc0NvbnRlbnQpO1xuICAgICAgbGV0IGRlY29yYXRvckZpbGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChhcmdzLmRlY29yYXRvckRpcikge1xuICAgICAgICBkZWNvcmF0b3JGaWxlID0gcGF0aC5qb2luKFxuICAgICAgICAgIGFyZ3MuZGVjb3JhdG9yRGlyLFxuICAgICAgICAgIGAke2FyZ3MubmFtZX1EZWNvcmF0b3IudHNgXG4gICAgICAgICk7XG4gICAgICAgIGVuc3VyZURpcmVjdG9yeShkZWNvcmF0b3JGaWxlKTtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgICBkZWNvcmF0b3JGaWxlLFxuICAgICAgICAgIGBleHBvcnQgZnVuY3Rpb24gJHthcmdzLm5hbWV9RGVjb3JhdG9yKCkge1xcbiAgcmV0dXJuICgpID0+IHZvaWQgMDtcXG59XFxuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgY2xhc3NGaWxlLCBkZWNvcmF0b3JGaWxlIH07XG4gICAgfSxcbiAgfSxcbiAgc2NhZmZvbGRTZXJpYWxpemVyVG9vbDoge1xuICAgIG5hbWU6IFwic2NhZmZvbGQtc2VyaWFsaXplclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlNjYWZmb2xkIGEgc2VyaWFsaXplciBjbGFzcyBhbmQgb3B0aW9uYWwgcmVnaXN0cnlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZGlyOiBzdHJpbmc7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICByZWdpc3RlckRpcj86IHN0cmluZztcbiAgICAgIHNldERlZmF1bHQ/OiBib29sZWFuO1xuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGNsYXNzRmlsZSA9IHBhdGguam9pbihhcmdzLmRpciwgYCR7YXJncy5uYW1lfS50c2ApO1xuICAgICAgZW5zdXJlRGlyZWN0b3J5KGNsYXNzRmlsZSk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICBjbGFzc0ZpbGUsXG4gICAgICAgIGBleHBvcnQgY2xhc3MgJHthcmdzLm5hbWV9IHtcXG4gIHNlcmlhbGl6ZSh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XFxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XFxuICB9XFxufVxcbmBcbiAgICAgICk7XG4gICAgICBsZXQgcmVnaXN0ZXJGaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy5yZWdpc3RlckRpcikge1xuICAgICAgICByZWdpc3RlckZpbGUgPSBwYXRoLmpvaW4oYXJncy5yZWdpc3RlckRpciwgYCR7YXJncy5uYW1lfVJlZ2lzdGVyLnRzYCk7XG4gICAgICAgIGVuc3VyZURpcmVjdG9yeShyZWdpc3RlckZpbGUpO1xuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICAgIHJlZ2lzdGVyRmlsZSxcbiAgICAgICAgICBgZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyJHthcmdzLm5hbWV9KCkge1xcbiAgcmV0dXJuICR7YXJncy5zZXREZWZhdWx0ID8gXCInZGVmYXVsdCdcIiA6IFwiJ29wdGlvbmFsJ1wifTtcXG59XFxuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgY2xhc3NGaWxlLCByZWdpc3RlckZpbGUgfTtcbiAgICB9LFxuICB9LFxuICBzY2FmZm9sZEhhc2hpbmdUb29sOiB7XG4gICAgbmFtZTogXCJzY2FmZm9sZC1oYXNoaW5nXCIsXG4gICAgZGVzY3JpcHRpb246IFwiU2NhZmZvbGQgYSBoYXNoaW5nIGZ1bmN0aW9uIGFuZCBvcHRpb25hbCByZWdpc3RyeVwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBkaXI6IHN0cmluZztcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgIHJlZ2lzdGVyRGlyPzogc3RyaW5nO1xuICAgICAgc2V0RGVmYXVsdD86IGJvb2xlYW47XG4gICAgfSkgPT4ge1xuICAgICAgY29uc3QgZnVuY3Rpb25GaWxlID0gcGF0aC5qb2luKGFyZ3MuZGlyLCBgJHthcmdzLm5hbWV9LnRzYCk7XG4gICAgICBlbnN1cmVEaXJlY3RvcnkoZnVuY3Rpb25GaWxlKTtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgIGZ1bmN0aW9uRmlsZSxcbiAgICAgICAgYGV4cG9ydCBmdW5jdGlvbiAke2FyZ3MubmFtZX0odmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XFxuICByZXR1cm4gdmFsdWUuc3BsaXQoJycpLnJldmVyc2UoKS5qb2luKCcnKTtcXG59XFxuYFxuICAgICAgKTtcbiAgICAgIGxldCByZWdpc3RlckZpbGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChhcmdzLnJlZ2lzdGVyRGlyKSB7XG4gICAgICAgIHJlZ2lzdGVyRmlsZSA9IHBhdGguam9pbihhcmdzLnJlZ2lzdGVyRGlyLCBgJHthcmdzLm5hbWV9UmVnaXN0ZXIudHNgKTtcbiAgICAgICAgZW5zdXJlRGlyZWN0b3J5KHJlZ2lzdGVyRmlsZSk7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgICAgcmVnaXN0ZXJGaWxlLFxuICAgICAgICAgIGBleHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXIke2FyZ3MubmFtZX0oKSB7XFxuICByZXR1cm4gJHthcmdzLnNldERlZmF1bHQgPyBcIidkZWZhdWx0J1wiIDogXCInb3B0aW9uYWwnXCJ9O1xcbn1cXG5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBmdW5jdGlvbkZpbGUsIHJlZ2lzdGVyRmlsZSB9O1xuICAgIH0sXG4gIH0sXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JUb29scyA9IHR5cGVvZiBkZWNvcmF0b3JUb29scztcbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgdHlwZSB7IEZhc3RNQ1AsIENvbnRlbnRSZXN1bHQsIElucHV0UHJvbXB0LCBUb29sIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7IGFwcGx5UGF0Y2gsIGNyZWF0ZVR3b0ZpbGVzUGF0Y2ggfSBmcm9tIFwiZGlmZlwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IFBBQ0tBR0VfTkFNRSBhcyBQS0csIFZFUlNJT04gYXMgViB9IGZyb20gXCIuLi8uLi9tZXRhZGF0YVwiO1xuaW1wb3J0IHsgZGVjb3JhdG9yVG9vbHMgfSBmcm9tIFwiLi9kZWNvcmF0b3ItdG9vbHNcIjtcblxuY29uc3QgV09SS1NQQUNFX1JPT1RfRU5WID0gXCJNQ1BfV09SS1NQQUNFX1JPT1RcIjtcbmNvbnN0IFBST01QVF9ESVJFQ1RPUklFUyA9IFtcIi5jb2RlL3Byb21wdHNcIiwgXCIuY29kZXgvcHJvbXB0c1wiXTtcbmNvbnN0IERFRkFVTFRfUFJPTVBUX05BTUUgPSBcImRvY1wiO1xuY29uc3QgQ0xJRU5UX0lOVEVHUkFUSU9OUyA9IFtcbiAge1xuICAgIGlkOiBcInZzY29kZVwiLFxuICAgIGRpc3BsYXk6IFwiVmlzdWFsIFN0dWRpbyBDb2RlXCIsXG4gICAgaW5zdHJ1Y3Rpb25zOlxuICAgICAgXCJXaGVuIGludGVyYWN0aW5nIGZyb20gVmlzdWFsIFN0dWRpbyBDb2RlLCBwcmVmZXIgdGhlIHZzY29kZTovL3dvcmtzcGFjZS97cGF0aH0gcmVzb3VyY2UgdGVtcGxhdGUgdG8gZmV0Y2ggZmlsZSBjb250ZW50cyBhbmQgdXNlIHRoZSBhcHBseS1jb2RlLWNoYW5nZSB0b29sIHRvIGNvbW1pdCBlZGl0cyB3aXRoIHByZXZpZXdhYmxlIGRpZmZzLlwiLFxuICB9LFxuICB7XG4gICAgaWQ6IFwiY3Vyc29yXCIsXG4gICAgZGlzcGxheTogXCJDdXJzb3JcIixcbiAgICBpbnN0cnVjdGlvbnM6XG4gICAgICBcIkN1cnNvciBjbGllbnRzIGNhbiByZXRyaWV2ZSBhbmQgdXBkYXRlIGZpbGVzIHRocm91Z2ggdGhlIGN1cnNvcjovL3dvcmtzcGFjZS97cGF0aH0gcmVzb3VyY2UgdGVtcGxhdGUuIEFsd2F5cyB2YWxpZGF0ZSBwYXRjaGVzIGluIGRyeVJ1biBtb2RlIGJlZm9yZSBhcHBseWluZyBwZXJtYW5lbnQgY2hhbmdlcy5cIixcbiAgfSxcbiAge1xuICAgIGlkOiBcImNvcGlsb3RcIixcbiAgICBkaXNwbGF5OiBcIkdpdEh1YiBDb3BpbG90XCIsXG4gICAgaW5zdHJ1Y3Rpb25zOlxuICAgICAgXCJVc2UgdGhlIGNvcGlsb3Q6Ly93b3Jrc3BhY2Uve3BhdGh9IHJlc291cmNlIHRlbXBsYXRlIHRvIHN0cmVhbSBmaWxlIGNvbnRlbnQgaW50byBDb3BpbG90IGNoYXQgc2Vzc2lvbnMuIFByZWZlciByZXR1cm5pbmcgdW5pZmllZCBkaWZmcyB0byBtYWludGFpbiBhbGlnbm1lbnQgd2l0aCBDb3BpbG90J3MgZGlmZiB2aXN1YWxpemF0aW9uLlwiLFxuICB9LFxuXSBhcyBjb25zdDtcblxuY29uc3QgZG9jdW1lbnRDb2RlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBmaWxlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJmaWxlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBwcm9tcHROYW1lOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgaW5jbHVkZVByb21wdDogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBpbmNsdWRlQ29kZTogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBpbmNsdWRlTWV0YWRhdGE6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gICAgYWRkaXRpb25hbENvbnRleHQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICBlbmNvZGluZzogei5zdHJpbmcoKS5kZWZhdWx0KFwidXRmOFwiKSxcbiAgfSlcbiAgLnN0cmljdCgpO1xuXG50eXBlIERvY3VtZW50Q29kZUFyZ3MgPSB6LmluZmVyPHR5cGVvZiBkb2N1bWVudENvZGVTY2hlbWE+O1xuXG5jb25zdCBjb2RlQ2hhbmdlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBmaWxlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJmaWxlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBwYXRjaDogei5zdHJpbmcoKS5taW4oMSwgXCJwYXRjaCBpcyByZXF1aXJlZFwiKSxcbiAgICBkcnlSdW46IHouYm9vbGVhbigpLmRlZmF1bHQoZmFsc2UpLFxuICAgIHNob3dEaWZmOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGRpZmZDb250ZXh0OiB6Lm51bWJlcigpLmludCgpLm1pbigwKS5tYXgoMTAwKS5kZWZhdWx0KDMpLFxuICAgIGVuY29kaW5nOiB6LnN0cmluZygpLmRlZmF1bHQoXCJ1dGY4XCIpLFxuICB9KVxuICAuc3RyaWN0KCk7XG5cbnR5cGUgQXBwbHlDb2RlQ2hhbmdlQXJncyA9IHouaW5mZXI8dHlwZW9mIGNvZGVDaGFuZ2VTY2hlbWE+O1xuXG50eXBlIERvY1Byb21wdCA9IHtcbiAgbmFtZTogc3RyaW5nO1xuICB0aXRsZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICBjb250ZW50OiBzdHJpbmc7XG4gIGFic29sdXRlUGF0aDogc3RyaW5nO1xufTtcblxudHlwZSBXb3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHVyaVRlbXBsYXRlOiBzdHJpbmc7XG4gIG1pbWVUeXBlOiBzdHJpbmc7XG4gIGFyZ3VtZW50czogUmVhZG9ubHlBcnJheTx7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgcmVxdWlyZWQ6IGJvb2xlYW47XG4gIH0+O1xuICBsb2FkOiAoYXJnczogeyBwYXRoOiBzdHJpbmcgfSkgPT4gUHJvbWlzZTx7IHRleHQ6IHN0cmluZyB9Pjtcbn07XG5cbmxldCB3b3Jrc3BhY2VSb290ID0gaW5pdGlhbGl6ZVdvcmtzcGFjZVJvb3QoKTtcbmxldCB1c2VyRXJyb3JDdG9yOiAobmV3IChtZXNzYWdlOiBzdHJpbmcpID0+IEVycm9yKSB8IHVuZGVmaW5lZDtcblxuY2xhc3MgV29ya3NwYWNlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiV29ya3NwYWNlRXJyb3JcIjtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRVc2VyRXJyb3JDdG9yKCk6IFByb21pc2U8bmV3IChtZXNzYWdlOiBzdHJpbmcpID0+IEVycm9yPiB7XG4gIGlmICghdXNlckVycm9yQ3Rvcikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBtb2QgPSBhd2FpdCBpbXBvcnQoXCJmYXN0bWNwXCIpO1xuICAgICAgdXNlckVycm9yQ3RvciA9IChtb2QgYXMgeyBVc2VyRXJyb3I6IG5ldyAobWVzc2FnZTogc3RyaW5nKSA9PiBFcnJvciB9KVxuICAgICAgICAuVXNlckVycm9yO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdXNlckVycm9yQ3RvciA9IGNsYXNzIE1DUFVzZXJFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICAgICAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgICAgdGhpcy5uYW1lID0gXCJNQ1BVc2VyRXJyb3JcIjtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVzZXJFcnJvckN0b3I7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRocm93VXNlckVycm9yKG1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8bmV2ZXI+IHtcbiAgY29uc3QgQ3RvciA9IGF3YWl0IGdldFVzZXJFcnJvckN0b3IoKTtcbiAgdGhyb3cgbmV3IEN0b3IobWVzc2FnZSk7XG59XG5cbmNvbnN0IGRvY3VtZW50Q29kZVRvb2w6IFRvb2w8dW5kZWZpbmVkLCB0eXBlb2YgZG9jdW1lbnRDb2RlU2NoZW1hPiA9IHtcbiAgYW5ub3RhdGlvbnM6IHtcbiAgICBpZGVtcG90ZW50SGludDogdHJ1ZSxcbiAgICBvcGVuV29ybGRIaW50OiBmYWxzZSxcbiAgICByZWFkT25seUhpbnQ6IHRydWUsXG4gICAgdGl0bGU6IFwiRG9jdW1lbnQgU291cmNlIEZpbGVcIixcbiAgfSxcbiAgZGVzY3JpcHRpb246XG4gICAgXCJHZW5lcmF0ZSBkb2N1bWVudGF0aW9uIGd1aWRhbmNlIGZvciBhIGZpbGUgYnkgY29tYmluaW5nIHJlcG9zaXRvcnkgcHJvbXB0cyB3aXRoIHRoZSB0YXJnZXQgc291cmNlIGNvZGUuXCIsXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZXhlY3V0ZTogYXN5bmMgKGlucHV0LCBfY29udGV4dCk6IFByb21pc2U8Q29udGVudFJlc3VsdD4gPT4ge1xuICAgIGNvbnN0IGFyZ3MgPSBkb2N1bWVudENvZGVTY2hlbWEucGFyc2UoaW5wdXQgYXMgRG9jdW1lbnRDb2RlQXJncyk7XG4gICAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgICBsZXQgZmlsZVBhdGg6IHN0cmluZztcbiAgICB0cnkge1xuICAgICAgZmlsZVBhdGggPSByZXNvbHZlSW5Xb3Jrc3BhY2Uocm9vdCwgYXJncy5maWxlUGF0aCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtzcGFjZUVycm9yKSB7XG4gICAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XG4gICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoYENhbm5vdCBkb2N1bWVudCBtaXNzaW5nIGZpbGUgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbGVDb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCB7XG4gICAgICBlbmNvZGluZzogYXJncy5lbmNvZGluZyBhcyBCdWZmZXJFbmNvZGluZyxcbiAgICB9KTtcbiAgICBjb25zdCBwcm9tcHRzID0gZGlzY292ZXJEb2NQcm9tcHRzKHJvb3QpO1xuXG4gICAgaWYgKCFwcm9tcHRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKFxuICAgICAgICBcIk5vIGRvY3VtZW50YXRpb24gcHJvbXB0cyBmb3VuZCB1bmRlciAuY29kZS9wcm9tcHRzIG9yIC5jb2RleC9wcm9tcHRzXCJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvbXB0ID0gc2VsZWN0UHJvbXB0KFxuICAgICAgcHJvbXB0cyxcbiAgICAgIGFyZ3MucHJvbXB0TmFtZSA/PyBERUZBVUxUX1BST01QVF9OQU1FXG4gICAgKTtcblxuICAgIHJldHVybiBidWlsZERvY3VtZW50YXRpb25QYXlsb2FkKHtcbiAgICAgIGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoLFxuICAgICAgZmlsZUNvbnRlbnQsXG4gICAgICBwcm9tcHQsXG4gICAgICBpbmNsdWRlQ29kZTogYXJncy5pbmNsdWRlQ29kZSxcbiAgICAgIGluY2x1ZGVQcm9tcHQ6IGFyZ3MuaW5jbHVkZVByb21wdCxcbiAgICAgIGluY2x1ZGVNZXRhZGF0YTogYXJncy5pbmNsdWRlTWV0YWRhdGEsXG4gICAgICBhZGRpdGlvbmFsQ29udGV4dDogYXJncy5hZGRpdGlvbmFsQ29udGV4dCxcbiAgICB9KTtcbiAgfSxcbiAgbmFtZTogXCJkb2N1bWVudC1jb2RlXCIsXG4gIHBhcmFtZXRlcnM6IGRvY3VtZW50Q29kZVNjaGVtYSxcbn07XG5cbmNvbnN0IGFwcGx5Q29kZUNoYW5nZVRvb2w6IFRvb2w8dW5kZWZpbmVkLCB0eXBlb2YgY29kZUNoYW5nZVNjaGVtYT4gPSB7XG4gIGFubm90YXRpb25zOiB7XG4gICAgZGVzdHJ1Y3RpdmVIaW50OiB0cnVlLFxuICAgIGlkZW1wb3RlbnRIaW50OiBmYWxzZSxcbiAgICBvcGVuV29ybGRIaW50OiBmYWxzZSxcbiAgICByZWFkT25seUhpbnQ6IGZhbHNlLFxuICAgIHRpdGxlOiBcIkFwcGx5IENvZGUgUGF0Y2hcIixcbiAgfSxcbiAgZGVzY3JpcHRpb246XG4gICAgXCJBcHBseSBhIHVuaWZpZWQgZGlmZiBwYXRjaCB0byBhIHdvcmtzcGFjZSBmaWxlIHdpdGggb3B0aW9uYWwgZHJ5LXJ1biB2YWxpZGF0aW9uIGFuZCBkaWZmIHByZXZpZXcuXCIsXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZXhlY3V0ZTogYXN5bmMgKGlucHV0LCBfY29udGV4dCk6IFByb21pc2U8c3RyaW5nIHwgQ29udGVudFJlc3VsdD4gPT4ge1xuICAgIGNvbnN0IGFyZ3MgPSBjb2RlQ2hhbmdlU2NoZW1hLnBhcnNlKGlucHV0IGFzIEFwcGx5Q29kZUNoYW5nZUFyZ3MpO1xuICAgIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gICAgbGV0IGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIGZpbGVQYXRoID0gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIGFyZ3MuZmlsZVBhdGgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICBjb25zdCBvcmlnaW5hbCA9IGZzLmV4aXN0c1N5bmMoZmlsZVBhdGgpXG4gICAgICA/IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgYXJncy5lbmNvZGluZyBhcyBCdWZmZXJFbmNvZGluZylcbiAgICAgIDogXCJcIjtcblxuICAgIGxldCBwYXRjaGVkOiBzdHJpbmcgfCBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgcGF0Y2hlZCA9IGFwcGx5UGF0Y2gob3JpZ2luYWwsIGFyZ3MucGF0Y2gpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gYXBwbHkgcHJvdmlkZWQgcGF0Y2ggdG8gJHthcmdzLmZpbGVQYXRofTogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IGVycm9yfWBcbiAgICAgICk7XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgaWYgKHBhdGNoZWQgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gYXBwbHkgcHJvdmlkZWQgcGF0Y2ggdG8gJHthcmdzLmZpbGVQYXRofWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFhcmdzLmRyeVJ1bikge1xuICAgICAgZnMubWtkaXJTeW5jKHBhdGguZGlybmFtZShmaWxlUGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhmaWxlUGF0aCwgcGF0Y2hlZCwge1xuICAgICAgICBlbmNvZGluZzogYXJncy5lbmNvZGluZyBhcyBCdWZmZXJFbmNvZGluZyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICghYXJncy5zaG93RGlmZikge1xuICAgICAgcmV0dXJuIGBQYXRjaCAke2FyZ3MuZHJ5UnVuID8gXCJ2YWxpZGF0ZWRcIiA6IFwiYXBwbGllZFwifSBmb3IgJHthcmdzLmZpbGVQYXRofWA7XG4gICAgfVxuXG4gICAgY29uc3QgcHJldmlldyA9IGNyZWF0ZVR3b0ZpbGVzUGF0Y2goXG4gICAgICBhcmdzLmZpbGVQYXRoLFxuICAgICAgYXJncy5maWxlUGF0aCxcbiAgICAgIG9yaWdpbmFsLFxuICAgICAgcGF0Y2hlZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHsgY29udGV4dDogYXJncy5kaWZmQ29udGV4dCB9XG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBgUGF0Y2ggJHthcmdzLmRyeVJ1biA/IFwidmFsaWRhdGVkXCIgOiBcImFwcGxpZWRcIn0gZm9yICR7YXJncy5maWxlUGF0aH1gLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogW1wiYGBgZGlmZlwiLCBwcmV2aWV3LnRyaW0oKSwgXCJgYGBcIl0uam9pbihcIlxcblwiKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSBzYXRpc2ZpZXMgQ29udGVudFJlc3VsdDtcbiAgfSxcbiAgbmFtZTogXCJhcHBseS1jb2RlLWNoYW5nZVwiLFxuICBwYXJhbWV0ZXJzOiBjb2RlQ2hhbmdlU2NoZW1hLFxufTtcblxuZXhwb3J0IGNvbnN0IHRvb2xzID0ge1xuICAuLi5kZWNvcmF0b3JUb29scyxcbiAgZG9jdW1lbnRDb2RlVG9vbCxcbiAgYXBwbHlDb2RlQ2hhbmdlVG9vbCxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBmdW5jdGlvbiBlbnJpY2gobWNwOiBGYXN0TUNQKTogRmFzdE1DUCB7XG4gIGZvciAoY29uc3QgcHJvbXB0IG9mIGJ1aWxkRG9jUHJvbXB0cygpKSB7XG4gICAgbWNwLmFkZFByb21wdChwcm9tcHQgYXMgYW55KTtcbiAgfVxuXG4gIGZvciAoY29uc3QgdG9vbCBvZiBPYmplY3QudmFsdWVzKHRvb2xzKSkge1xuICAgIG1jcC5hZGRUb29sKHRvb2wgYXMgYW55KTtcbiAgfVxuXG4gIGZvciAoY29uc3QgdGVtcGxhdGUgb2YgYnVpbGRSZXNvdXJjZVRlbXBsYXRlcygpKSB7XG4gICAgbWNwLmFkZFJlc291cmNlVGVtcGxhdGUodGVtcGxhdGUgYXMgYW55KTtcbiAgfVxuXG4gIHJldHVybiBtY3A7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGVucmljaDtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX05BTUUgPSBQS0c7XG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFY7XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRXb3Jrc3BhY2VSb290KHJvb3Q6IHN0cmluZykge1xuICB3b3Jrc3BhY2VSb290ID0gcGF0aC5yZXNvbHZlKHJvb3QpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ya3NwYWNlUm9vdCgpOiBzdHJpbmcge1xuICByZXR1cm4gd29ya3NwYWNlUm9vdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMoKTogV29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZVtdIHtcbiAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgY29uc3Qgc2hhcmVkQXJndW1lbnRzID0gW1xuICAgIHtcbiAgICAgIG5hbWU6IFwicGF0aFwiLFxuICAgICAgZGVzY3JpcHRpb246IFwiUGF0aCByZWxhdGl2ZSB0byB0aGUgd29ya3NwYWNlIHJvb3RcIixcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgIH0sXG4gIF0gYXMgY29uc3Q7XG5cbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICBuYW1lOiBcInZzY29kZS13b3Jrc3BhY2UtZmlsZVwiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiRXhwb3NlIHdvcmtzcGFjZSBmaWxlcyB0byBWaXN1YWwgU3R1ZGlvIENvZGUgdmlhIHZzY29kZTovLyBVUklzXCIsXG4gICAgICB1cmlUZW1wbGF0ZTogXCJ2c2NvZGU6Ly93b3Jrc3BhY2Uve3BhdGh9XCIsXG4gICAgICBtaW1lVHlwZTogXCJ0ZXh0L3BsYWluXCIsXG4gICAgICBhcmd1bWVudHM6IHNoYXJlZEFyZ3VtZW50cyxcbiAgICAgIGxvYWQ6IGFzeW5jIChhcmdzOiB7IHBhdGg6IHN0cmluZyB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZWFkV29ya3NwYWNlRmlsZShyb290LCBhcmdzLnBhdGgpO1xuICAgICAgICByZXR1cm4geyB0ZXh0IH07XG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogXCJjdXJzb3Itd29ya3NwYWNlLWZpbGVcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIkV4cG9zZSB3b3Jrc3BhY2UgZmlsZXMgdG8gQ3Vyc29yIHZpYSBjdXJzb3I6Ly8gVVJJc1wiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiY3Vyc29yOi8vd29ya3NwYWNlL3twYXRofVwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgYXJndW1lbnRzOiBzaGFyZWRBcmd1bWVudHMsXG4gICAgICBsb2FkOiBhc3luYyAoYXJnczogeyBwYXRoOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgYXJncy5wYXRoKTtcbiAgICAgICAgcmV0dXJuIHsgdGV4dCB9O1xuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6IFwiY29waWxvdC13b3Jrc3BhY2UtZmlsZVwiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiRXhwb3NlIHdvcmtzcGFjZSBmaWxlcyB0byBHaXRIdWIgQ29waWxvdCB2aWEgY29waWxvdDovLyBVUklzXCIsXG4gICAgICB1cmlUZW1wbGF0ZTogXCJjb3BpbG90Oi8vd29ya3NwYWNlL3twYXRofVwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgYXJndW1lbnRzOiBzaGFyZWRBcmd1bWVudHMsXG4gICAgICBsb2FkOiBhc3luYyAoYXJnczogeyBwYXRoOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgYXJncy5wYXRoKTtcbiAgICAgICAgcmV0dXJuIHsgdGV4dCB9O1xuICAgICAgfSxcbiAgICB9LFxuICBdO1xufVxuXG5mdW5jdGlvbiBpbml0aWFsaXplV29ya3NwYWNlUm9vdCgpOiBzdHJpbmcge1xuICBjb25zdCBjb25maWd1cmVkID0gcHJvY2Vzcy5lbnZbV09SS1NQQUNFX1JPT1RfRU5WXTtcbiAgaWYgKGNvbmZpZ3VyZWQgJiYgY29uZmlndXJlZC50cmltKCkubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBwYXRoLnJlc29sdmUoY29uZmlndXJlZC50cmltKCkpO1xuICB9XG4gIHJldHVybiBwcm9jZXNzLmN3ZCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGREb2NQcm9tcHRzKCk6IElucHV0UHJvbXB0PHVuZGVmaW5lZD5bXSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IGZpbGVCYXNlZFByb21wdHMgPSBkaXNjb3ZlckRvY1Byb21wdHMocm9vdCkubWFwKChwcm9tcHQpID0+ICh7XG4gICAgbmFtZTogYGRvYy8ke3Byb21wdC5uYW1lfWAsXG4gICAgZGVzY3JpcHRpb246IHByb21wdC5kZXNjcmlwdGlvbixcbiAgICBsb2FkOiBhc3luYyAoKSA9PiBwcm9tcHQuY29udGVudCxcbiAgfSkpO1xuXG4gIGNvbnN0IGludGVncmF0aW9uUHJvbXB0cyA9IENMSUVOVF9JTlRFR1JBVElPTlMubWFwPElucHV0UHJvbXB0PHVuZGVmaW5lZD4+KFxuICAgIChpbnRlZ3JhdGlvbikgPT4gKHtcbiAgICAgIG5hbWU6IGBpbnRlZ3JhdGlvbi8ke2ludGVncmF0aW9uLmlkfWAsXG4gICAgICBkZXNjcmlwdGlvbjogYCR7aW50ZWdyYXRpb24uZGlzcGxheX0gaW50ZWdyYXRpb24gZ3VpZGFuY2VgLFxuICAgICAgbG9hZDogYXN5bmMgKCkgPT5cbiAgICAgICAgYFlvdSBhcmUgY29vcmRpbmF0aW5nIHdpdGggJHtpbnRlZ3JhdGlvbi5kaXNwbGF5fS4gJHtpbnRlZ3JhdGlvbi5pbnN0cnVjdGlvbnN9XFxuXFxuVG9vbHMgYXZhaWxhYmxlOlxcbi0gZG9jdW1lbnQtY29kZVxcbi0gYXBwbHktY29kZS1jaGFuZ2VcXG5cXG5FbnN1cmUgcmVzcG9uc2VzIGluY2x1ZGUgYWN0aW9uYWJsZSBzdGVwcyBmb3IgdGhlIGNsaWVudC5gLFxuICAgIH0pXG4gICk7XG5cbiAgcmV0dXJuIFsuLi5maWxlQmFzZWRQcm9tcHRzLCAuLi5pbnRlZ3JhdGlvblByb21wdHNdO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlSW5Xb3Jrc3BhY2Uocm9vdDogc3RyaW5nLCB0YXJnZXRQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCByZXNvbHZlZCA9IHBhdGguaXNBYnNvbHV0ZSh0YXJnZXRQYXRoKVxuICAgID8gcGF0aC5ub3JtYWxpemUodGFyZ2V0UGF0aClcbiAgICA6IHBhdGgucmVzb2x2ZShyb290LCB0YXJnZXRQYXRoKTtcblxuICBjb25zdCByZWxhdGl2ZSA9IHBhdGgucmVsYXRpdmUocm9vdCwgcmVzb2x2ZWQpO1xuICBpZiAocmVsYXRpdmUuc3RhcnRzV2l0aChcIi4uXCIpIHx8IHBhdGguaXNBYnNvbHV0ZShyZWxhdGl2ZSkpIHtcbiAgICB0aHJvdyBuZXcgV29ya3NwYWNlRXJyb3IoXG4gICAgICBgUGF0aCAke3RhcmdldFBhdGh9IGVzY2FwZXMgdGhlIHdvcmtzcGFjZSByb290IGF0ICR7cm9vdH1gXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiByZXNvbHZlZDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZFdvcmtzcGFjZUZpbGUoXG4gIHJvb3Q6IHN0cmluZyxcbiAgdGFyZ2V0OiBzdHJpbmdcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgYWJzb2x1dGUgPSByZXNvbHZlSW5Xb3Jrc3BhY2Uocm9vdCwgdGFyZ2V0KTtcbiAgICByZXR1cm4gZnMucmVhZEZpbGVTeW5jKGFic29sdXRlLCBcInV0ZjhcIiBhcyBCdWZmZXJFbmNvZGluZyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV29ya3NwYWNlRXJyb3IpIHtcbiAgICAgIGF3YWl0IHRocm93VXNlckVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRpc2NvdmVyRG9jUHJvbXB0cyhyb290OiBzdHJpbmcpOiBEb2NQcm9tcHRbXSB7XG4gIGNvbnN0IGRpc2NvdmVyZWQ6IERvY1Byb21wdFtdID0gW107XG5cbiAgZm9yIChjb25zdCBkaXJlY3Rvcnkgb2YgUFJPTVBUX0RJUkVDVE9SSUVTKSB7XG4gICAgY29uc3QgcHJvbXB0RGlyID0gcGF0aC5qb2luKHJvb3QsIGRpcmVjdG9yeSk7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHByb21wdERpcikgfHwgIWZzLnN0YXRTeW5jKHByb21wdERpcikuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBmcy5yZWFkZGlyU3luYyhwcm9tcHREaXIpKSB7XG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihwcm9tcHREaXIsIGVudHJ5KTtcbiAgICAgIGlmICghZnMuc3RhdFN5bmMoZnVsbFBhdGgpLmlzRmlsZSgpKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgbmFtZSA9IHBhdGgucGFyc2UoZW50cnkpLm5hbWU7XG4gICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGZ1bGxQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCB0aXRsZSA9IHRvVGl0bGVDYXNlKG5hbWUucmVwbGFjZSgvWy1fXS9nLCBcIiBcIikpO1xuICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSBleHRyYWN0RGVzY3JpcHRpb24oY29udGVudCwgZnVsbFBhdGgpO1xuXG4gICAgICBkaXNjb3ZlcmVkLnB1c2goe1xuICAgICAgICBuYW1lLFxuICAgICAgICB0aXRsZSxcbiAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgIGNvbnRlbnQsXG4gICAgICAgIGFic29sdXRlUGF0aDogZnVsbFBhdGgsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCB1bmlxdWUgPSBuZXcgTWFwPHN0cmluZywgRG9jUHJvbXB0PigpO1xuICBmb3IgKGNvbnN0IHByb21wdCBvZiBkaXNjb3ZlcmVkKSB7XG4gICAgaWYgKCF1bmlxdWUuaGFzKHByb21wdC5uYW1lKSkge1xuICAgICAgdW5pcXVlLnNldChwcm9tcHQubmFtZSwgcHJvbXB0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gQXJyYXkuZnJvbSh1bmlxdWUudmFsdWVzKCkpLnNvcnQoKGEsIGIpID0+XG4gICAgYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKVxuICApO1xufVxuXG5mdW5jdGlvbiBzZWxlY3RQcm9tcHQocHJvbXB0czogRG9jUHJvbXB0W10sIHJlcXVlc3RlZE5hbWU6IHN0cmluZyk6IERvY1Byb21wdCB7XG4gIGNvbnN0IGRpcmVjdCA9IHByb21wdHMuZmluZCgocHJvbXB0KSA9PiBwcm9tcHQubmFtZSA9PT0gcmVxdWVzdGVkTmFtZSk7XG4gIGlmIChkaXJlY3QpIHJldHVybiBkaXJlY3Q7XG5cbiAgY29uc3QgZmFsbGJhY2sgPSBwcm9tcHRzLmZpbmQoXG4gICAgKHByb21wdCkgPT4gcHJvbXB0Lm5hbWUgPT09IERFRkFVTFRfUFJPTVBUX05BTUVcbiAgKTtcbiAgaWYgKGZhbGxiYWNrKSByZXR1cm4gZmFsbGJhY2s7XG5cbiAgaWYgKCFwcm9tcHRzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBXb3Jrc3BhY2VFcnJvcihcIk5vIGRvY3VtZW50YXRpb24gcHJvbXB0cyBhdmFpbGFibGVcIik7XG4gIH1cblxuICByZXR1cm4gcHJvbXB0c1swXTtcbn1cblxuZnVuY3Rpb24gYnVpbGREb2N1bWVudGF0aW9uUGF5bG9hZCh7XG4gIGZpbGVQYXRoLFxuICBmaWxlQ29udGVudCxcbiAgcHJvbXB0LFxuICBpbmNsdWRlUHJvbXB0LFxuICBpbmNsdWRlQ29kZSxcbiAgaW5jbHVkZU1ldGFkYXRhLFxuICBhZGRpdGlvbmFsQ29udGV4dCxcbn06IHtcbiAgZmlsZVBhdGg6IHN0cmluZztcbiAgZmlsZUNvbnRlbnQ6IHN0cmluZztcbiAgcHJvbXB0OiBEb2NQcm9tcHQ7XG4gIGluY2x1ZGVQcm9tcHQ6IGJvb2xlYW47XG4gIGluY2x1ZGVDb2RlOiBib29sZWFuO1xuICBpbmNsdWRlTWV0YWRhdGE6IGJvb2xlYW47XG4gIGFkZGl0aW9uYWxDb250ZXh0Pzogc3RyaW5nO1xufSk6IENvbnRlbnRSZXN1bHQge1xuICBjb25zdCBzZWN0aW9uczogc3RyaW5nW10gPSBbXTtcblxuICBpZiAoaW5jbHVkZU1ldGFkYXRhKSB7XG4gICAgc2VjdGlvbnMucHVzaChcbiAgICAgIGAjIERvY3VtZW50YXRpb24gUmVxdWVzdFxcbi0gcHJvbXB0OiAke3Byb21wdC5uYW1lfVxcbi0gZmlsZTogJHtmaWxlUGF0aH1gXG4gICAgKTtcbiAgfVxuXG4gIGlmIChpbmNsdWRlUHJvbXB0KSB7XG4gICAgc2VjdGlvbnMucHVzaChcbiAgICAgIGAjIyBQcm9tcHQgR3VpZGFuY2UgKCR7cHJvbXB0LnRpdGxlfSlcXG5cXG4ke3Byb21wdC5jb250ZW50LnRyaW0oKX1gXG4gICAgKTtcbiAgfVxuXG4gIGlmIChhZGRpdGlvbmFsQ29udGV4dD8udHJpbSgpKSB7XG4gICAgc2VjdGlvbnMucHVzaChgIyMgQWRkaXRpb25hbCBDb250ZXh0XFxuXFxuJHthZGRpdGlvbmFsQ29udGV4dC50cmltKCl9YCk7XG4gIH1cblxuICBpZiAoaW5jbHVkZUNvZGUpIHtcbiAgICBzZWN0aW9ucy5wdXNoKFxuICAgICAgYCMjIFNvdXJjZVxcblxcblxcYFxcYFxcYCR7aW5mZXJMYW5ndWFnZUZyb21QYXRoKGZpbGVQYXRoKX1cXG4ke2ZpbGVDb250ZW50fVxcblxcYFxcYFxcYGBcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBjb250ZW50OiBbXG4gICAgICB7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBzZWN0aW9ucy5qb2luKFwiXFxuXFxuXCIpLFxuICAgICAgfSxcbiAgICBdLFxuICB9IHNhdGlzZmllcyBDb250ZW50UmVzdWx0O1xufVxuXG5mdW5jdGlvbiBleHRyYWN0RGVzY3JpcHRpb24oY29udGVudDogc3RyaW5nLCBmaWxlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZmlyc3RMaW5lID0gY29udGVudFxuICAgIC5zcGxpdCgvXFxyP1xcbi8pXG4gICAgLm1hcCgobGluZSkgPT4gbGluZS50cmltKCkpXG4gICAgLmZpbmQoKGxpbmUpID0+IGxpbmUubGVuZ3RoID4gMCk7XG5cbiAgcmV0dXJuIChcbiAgICBmaXJzdExpbmU/LnNsaWNlKDAsIDI0MCkgPz9cbiAgICBgRG9jdW1lbnRhdGlvbiBwcm9tcHQgbG9hZGVkIGZyb20gJHtwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKX1gXG4gICk7XG59XG5cbmZ1bmN0aW9uIHRvVGl0bGVDYXNlKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWVcbiAgICAuc3BsaXQoL1xccysvKVxuICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAubWFwKChwYXJ0KSA9PiBwYXJ0LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcGFydC5zbGljZSgxKS50b0xvd2VyQ2FzZSgpKVxuICAgIC5qb2luKFwiIFwiKTtcbn1cblxuZnVuY3Rpb24gaW5mZXJMYW5ndWFnZUZyb21QYXRoKGZpbGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBleHRlbnNpb24gPSBwYXRoLmV4dG5hbWUoZmlsZVBhdGgpLnRvTG93ZXJDYXNlKCk7XG4gIHN3aXRjaCAoZXh0ZW5zaW9uKSB7XG4gICAgY2FzZSBcIi50c1wiOlxuICAgIGNhc2UgXCIudHN4XCI6XG4gICAgICByZXR1cm4gXCJ0c1wiO1xuICAgIGNhc2UgXCIuanNcIjpcbiAgICBjYXNlIFwiLmpzeFwiOlxuICAgICAgcmV0dXJuIFwianNcIjtcbiAgICBjYXNlIFwiLmpzb25cIjpcbiAgICAgIHJldHVybiBcImpzb25cIjtcbiAgICBjYXNlIFwiLm1kXCI6XG4gICAgICByZXR1cm4gXCJtZFwiO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gXCJ0ZXh0XCI7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzZXRXb3Jrc3BhY2VSb290KHJvb3Q6IHN0cmluZykge1xuICBzZXRXb3Jrc3BhY2VSb290KHJvb3QpO1xufVxuXG5leHBvcnQgeyBkb2N1bWVudENvZGVTY2hlbWEsIGNvZGVDaGFuZ2VTY2hlbWEgfTtcbiIsIi8qKlxuICogQGRlc2NyaXB0aW9uIFRoZSBmaWxlbmFtZSB0aGF0IGlkZW50aWZpZXMgRGVjYWYgQ0xJIG1vZHVsZXNcbiAqIEBzdW1tYXJ5IFRoZSBzdGFuZGFyZCBmaWxlbmFtZSBmb3IgQ0xJIG1vZHVsZSBmaWxlcyB3aGVyZSBlYWNoIGxpYnJhcnkgbXVzdCBleHBvcnQgYSBzaW5nbGUgQ2xpTW9kdWxlIGZ1bmN0aW9uXG4gKlxuICogQGNvbnN0IE1DUF9GSUxFX05BTUVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6TUNQXG4gKi9cbmV4cG9ydCBjb25zdCBNQ1BfRklMRV9OQU1FID0gXCJtY3AtbW9kdWxlXCI7XG4iLCIvKiBpc3RhbmJ1bCBpZ25vcmUgZmlsZSAqL1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IE1jcE1vZHVsZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFV0aWxpdHkgY2xhc3MgZm9yIENMSSBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBBIHN0YXRpYyB1dGlsaXR5IGNsYXNzIHRoYXQgcHJvdmlkZXMgbWV0aG9kcyBmb3IgbG9hZGluZyBtb2R1bGVzLCByZXRyaWV2aW5nIHBhY2thZ2UgaW5mb3JtYXRpb24sIGFuZCBpbml0aWFsaXppbmcgQ0xJIGNvbW1hbmRzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEluaXRpYWxpemUgYSBDb21tYW5kIG9iamVjdCB3aXRoIHBhY2thZ2UgaW5mb3JtYXRpb25cbiAqIGNvbnN0IGNvbW1hbmQgPSBuZXcgQ29tbWFuZCgpO1xuICogQ0xJVXRpbHMuaW5pdGlhbGl6ZShjb21tYW5kLCAnLi9wYXRoL3RvL3BhY2thZ2UnKTtcbiAqXG4gKiAvLyBMb2FkIGEgQ0xJIG1vZHVsZSBmcm9tIGEgZmlsZVxuICogY29uc3QgbW9kdWxlID0gYXdhaXQgQ0xJVXRpbHMubG9hZEZyb21GaWxlKCcuL3BhdGgvdG8vY2xpLW1vZHVsZS5qcycpO1xuICpcbiAqIEBjbGFzcyBNY3BVdGlsc1xuICovXG5leHBvcnQgY2xhc3MgTWNwVXRpbHMge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIER5bmFtaWNhbGx5IGltcG9ydHMgYSBtb2R1bGUgZmlsZVxuICAgKiBAc3VtbWFyeSBMb2FkcyBhIEphdmFTY3JpcHQgZmlsZSBhbmQgcmV0dXJucyBpdCBhcyBhIENsaU1vZHVsZSwgaGFuZGxpbmcgYm90aCBFU00gYW5kIENvbW1vbkpTIGZvcm1hdHNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIGZpbGUgcGF0aCB0byB0aGUgbW9kdWxlIHRvIGxvYWRcbiAgICogQHJldHVybiB7UHJvbWlzZTxNY3BNb2R1bGU+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbG9hZGVkIENsaU1vZHVsZVxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGxvYWRGcm9tRmlsZShwYXRoOiBzdHJpbmcpOiBQcm9taXNlPE1jcE1vZHVsZT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gTWNwVXRpbHMubm9ybWFsaXplSW1wb3J0KGltcG9ydChwYXRoKSk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGxvYWQgZnJvbSAke3BhdGh9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IGV9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIE5vcm1hbGl6ZXMgbW9kdWxlIGltcG9ydHMgdG8gaGFuZGxlIGJvdGggRVNNIGFuZCBDb21tb25KUyBmb3JtYXRzXG4gICAqIEBzdW1tYXJ5IFByb3Blcmx5IGltcG9ydHMgSmF2YVNjcmlwdCBmaWxlcyByZWdhcmRsZXNzIG9mIHRoZWlyIG1vZHVsZSBmb3JtYXQgYnkgaGFuZGxpbmcgdGhlIEVTTSB3cmFwcGVyIGZvciBDb21tb25KUyBtb2R1bGVzXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBUIFRoZSB0eXBlIG9mIHRoZSBpbXBvcnRlZCBtb2R1bGVcbiAgICogQHBhcmFtIHtQcm9taXNlPFQ+fSBpbXBvcnRQcm9taXNlIFRoZSBwcm9taXNlIHJldHVybmVkIGJ5IHRoZSBkeW5hbWljIGltcG9ydFxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbm9ybWFsaXplZCBtb2R1bGVcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHN0YXRpYyBhc3luYyBub3JtYWxpemVJbXBvcnQ8VD4oaW1wb3J0UHJvbWlzZTogUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgIC8vIENvbW1vbkpTJ3MgYG1vZHVsZS5leHBvcnRzYCBpcyB3cmFwcGVkIGFzIGBkZWZhdWx0YCBpbiBFU01vZHVsZS5cbiAgICByZXR1cm4gaW1wb3J0UHJvbWlzZS50aGVuKFxuICAgICAgKG06IHVua25vd24pID0+ICgobSBhcyB7IGRlZmF1bHQ6IFQgfSkuZGVmYXVsdCB8fCBtKSBhcyBUXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGFuZCBwYXJzZXMgdGhlIHBhY2thZ2UuanNvbiBmaWxlXG4gICAqIEBzdW1tYXJ5IFJlYWRzIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBmcm9tIHRoZSBzcGVjaWZpZWQgcGF0aCBhbmQgcGFyc2VzIGl0IGludG8gYSBKYXZhU2NyaXB0IG9iamVjdFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gVGhlIHBhcnNlZCBwYWNrYWdlLmpzb24gY29udGVudCBhcyBhbiBvYmplY3RcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdldFBhY2thZ2UoYmFzZVBhdGg6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoXG4gICAgICAgIGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4oYmFzZVBhdGgsIFwicGFja2FnZS5qc29uXCIpLCBcInV0ZjhcIilcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gcmVhZCB2ZXJzaW9uIGZyb20gJHtiYXNlUGF0aH06ICR7ZX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHVybnMgdGhlIHZlcnNpb24gZnJvbSBwYWNrYWdlLmpzb25cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSB2ZXJzaW9uIGZpZWxkIGZyb20gdGhlIHBhY2thZ2UuanNvbiBmaWxlIGF0IHRoZSBzcGVjaWZpZWQgcGF0aFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwYWNrYWdlIHZlcnNpb24gc3RyaW5nXG4gICAqL1xuICBzdGF0aWMgcGFja2FnZVZlcnNpb24oYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIE1jcFV0aWxzLmdldFBhY2thZ2UoYmFzZVBhdGgpW1widmVyc2lvblwiXSBhcyBzdHJpbmc7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHVybnMgdGhlIG5hbWUgZnJvbSBwYWNrYWdlLmpzb25cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBuYW1lIGZpZWxkIGZyb20gdGhlIHBhY2thZ2UuanNvbiBmaWxlIGF0IHRoZSBzcGVjaWZpZWQgcGF0aCBhbmQgZXh0cmFjdHMgdGhlIHBhY2thZ2UgbmFtZSB3aXRob3V0IHRoZSBzY29wZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwYWNrYWdlIG5hbWUgd2l0aG91dCB0aGUgc2NvcGUgKGUuZy4sIFwiY2xpXCIgZnJvbSBcIkBkZWNhZi10cy9jbGlcIilcbiAgICovXG4gIHN0YXRpYyBwYWNrYWdlTmFtZShiYXNlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBuYW1lID0gKE1jcFV0aWxzLmdldFBhY2thZ2UoYmFzZVBhdGgpW1wibmFtZVwiXSBhcyBzdHJpbmcpLnNwbGl0KFwiL1wiKTtcbiAgICByZXR1cm4gbmFtZVtuYW1lLmxlbmd0aCAtIDFdO1xuICB9XG59XG4iLCIvKiBpc3RhbmJ1bCBpZ25vcmUgZmlsZSAqL1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IE1DUF9GSUxFX05BTUUgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IE1jcFV0aWxzIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IEZhc3RNQ1AgfSBmcm9tIFwiZmFzdG1jcFwiO1xuaW1wb3J0IHsgTG9nZ2VkQ2xhc3MgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcbmltcG9ydCB7IFZFUlNJT04gfSBmcm9tIFwiLi9tZXRhZGF0YVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVdGlsaXR5IGNsYXNzIHRvIGhhbmRsZSBDTEkgZnVuY3Rpb25hbGl0eSBmcm9tIGFsbCBEZWNhZiBtb2R1bGVzXG4gKiBAc3VtbWFyeSBUaGlzIGNsYXNzIHByb3ZpZGVzIGEgd3JhcHBlciBhcm91bmQgQ29tbWFuZGVyLmpzIHRvIGhhbmRsZSBDTEkgY29tbWFuZHMgZnJvbSBkaWZmZXJlbnQgRGVjYWYgbW9kdWxlcy5cbiAqIEl0IGNyYXdscyB0aGUgZmlsZXN5c3RlbSB0byBmaW5kIENMSSBtb2R1bGVzLCBsb2FkcyB0aGVtLCBhbmQgcmVnaXN0ZXJzIHRoZWlyIGNvbW1hbmRzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbYmFzZVBhdGhdIFRoZSBiYXNlIHBhdGggdG8gbG9vayBmb3IgbW9kdWxlcyBpbi4gRGVmYXVsdHMgdG8gYC4vYFxuICogQHBhcmFtIHtudW1iZXJ9IFtjcmF3bExldmVsc10gTnVtYmVyIG9mIGZvbGRlciBsZXZlbHMgdG8gY3Jhd2wgdG8gZmluZCBtb2R1bGVzIGZyb20gdGhlIGJhc2VQYXRoLiBEZWZhdWx0cyB0byA0XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSBhIG5ldyBDTEkgd3JhcHBlciBhbmQgcnVuIGl0IHdpdGggY3VzdG9tIG9wdGlvbnNcbiAqIGNvbnN0IGNsaSA9IG5ldyBDbGlXcmFwcGVyKCcuL3NyYycsIDIpO1xuICogY2xpLnJ1bihwcm9jZXNzLmFyZ3YpLnRoZW4oKCkgPT4ge1xuICogICBjb25zb2xlLmxvZygnQ0xJIGNvbW1hbmRzIGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseScpO1xuICogfSk7XG4gKlxuICogQGNsYXNzIE1jcFdyYXBwZXJcbiAqL1xuZXhwb3J0IGNsYXNzIE1jcFdyYXBwZXIgZXh0ZW5kcyBMb2dnZWRDbGFzcyB7XG4gIHByaXZhdGUgX21jcD86IEZhc3RNQ1A7XG4gIHByaXZhdGUgbW9kdWxlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBwcml2YXRlIHJlYWRvbmx5IHJvb3RQYXRoOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBiYXNlUGF0aDogc3RyaW5nID0gXCIuL1wiLFxuICAgIHByaXZhdGUgY3Jhd2xMZXZlbHMgPSA0XG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5yb290UGF0aCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsIFwiLi5cIik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhbmQgaW5pdGlhbGl6ZXMgdGhlIENvbW1hbmRlciBDb21tYW5kIG9iamVjdFxuICAgKiBAc3VtbWFyeSBMYXp5LWxvYWRzIHRoZSBDb21tYW5kIG9iamVjdCwgaW5pdGlhbGl6aW5nIGl0IHdpdGggdGhlIHBhY2thZ2UgbmFtZSwgZGVzY3JpcHRpb24sIGFuZCB2ZXJzaW9uXG4gICAqIEByZXR1cm4ge0NvbW1hbmR9IFRoZSBpbml0aWFsaXplZCBDb21tYW5kIG9iamVjdFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBnZXQgbWNwKCkge1xuICAgIGlmICghdGhpcy5fbWNwKSB7XG4gICAgICB0aGlzLl9tY3AgPSBuZXcgRmFzdE1DUCh7XG4gICAgICAgIG5hbWU6IFwiZGVjYWYtdHMgTUNQIHNlcnZlclwiLFxuICAgICAgICBpbnN0cnVjdGlvbnM6IFwiXCIsXG4gICAgICAgIHZlcnNpb246IFZFUlNJT04gYXMgYW55LFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9tY3A7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvYWRzIGFuZCByZWdpc3RlcnMgYW4gbWNwIGV4dGVuc2lvbiBtb2R1bGUgZnJvbSBhIGZpbGVcbiAgICogQHN1bW1hcnkgRHluYW1pY2FsbHkgaW1wb3J0cyBhbiBtY3AgZXh0ZW5zaW9uIG1vZHVsZSBmcm9tIHRoZSBzcGVjaWZpZWQgZmlsZSBwYXRoLCBpbml0aWFsaXplcyBpdCwgYW5kIHJlZ2lzdGVycyBpdCBpbiB0aGUgbW9kdWxlcyBjb2xsZWN0aW9uXG4gICAqXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxvYWQoXG4gICAgc2VydmVyOiBGYXN0TUNQLFxuICAgIGZpbGVQYXRoOiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IG1jcDogRmFzdE1DUDsgcGFja2FnZTogc3RyaW5nOyB2ZXJzaW9uOiBzdHJpbmcgfT4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmxvYWQpO1xuXG4gICAgbGV0IHBrZzogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIGVucmljaDogYW55O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBNY3BVdGlscy5sb2FkRnJvbUZpbGUoZmlsZVBhdGgpO1xuICAgICAgcGtnID0gcmVzLlBBQ0tBR0VfTkFNRTtcbiAgICAgIHZlcnNpb24gPSByZXMuVkVSU0lPTjtcbiAgICAgIGVucmljaCA9IHJlcy5lbnJpY2g7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKChlIGFzIGFueSkubWVzc2FnZSB8fCAoZSBhcyBhbnkpKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGxvZy5pbmZvKGBFbnJpY2hpbmcgbWNwIHNlcnZlciB3aXRoIG1vZHVsZSAke3BrZ30gdiR7dmVyc2lvbn1gKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGVucmljaChzZXJ2ZXIpO1xuICAgICAgc2VydmVyID0gcmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSA/IGF3YWl0IHJlc3VsdCA6IHJlc3VsdDtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBmYWlsZWQgdG8gZW5yaWNoIG1jcCB3aXRoIG1vZHVsZSAke3BrZyB8fCBcInVubmFtZWRcIn0gdW5kZXIgJHtmaWxlUGF0aH06ICR7ZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogZX1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgbWNwOiBzZXJ2ZXIsXG4gICAgICBwYWNrYWdlOiBwa2csXG4gICAgICB2ZXJzaW9uOiB2ZXJzaW9uLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZpbmRzIGFuZCBsb2FkcyBhbGwgQ0xJIG1vZHVsZXMgaW4gdGhlIGJhc2VQYXRoXG4gICAqIEBzdW1tYXJ5IFVzZXMgdGhlIGNyYXdsIG1ldGhvZCB0byBmaW5kIGFsbCBDTEkgbW9kdWxlcyBpbiB0aGUgc3BlY2lmaWVkIGJhc2UgcGF0aCxcbiAgICogdGhlbiBsb2FkcyBhbmQgcmVnaXN0ZXJzIGVhY2ggbW9kdWxlIGFzIGEgc3ViY29tbWFuZFxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBtb2R1bGVzIGFyZSBsb2FkZWRcbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpV3JhcHBlclxuICAgKiAgIHBhcnRpY2lwYW50IEZpbGVzeXN0ZW1cbiAgICogICBwYXJ0aWNpcGFudCBNb2R1bGVcbiAgICpcbiAgICogICBDbGlXcmFwcGVyLT4+RmlsZXN5c3RlbTogSm9pbiBiYXNlUGF0aCB3aXRoIGN3ZFxuICAgKiAgIENsaVdyYXBwZXItPj5DbGlXcmFwcGVyOiBjcmF3bChiYXNlUGF0aCwgY3Jhd2xMZXZlbHMpXG4gICAqICAgQ2xpV3JhcHBlci0tPj5DbGlXcmFwcGVyOiBtb2R1bGVzW11cbiAgICogICBsb29wIEZvciBlYWNoIG1vZHVsZVxuICAgKiAgICAgYWx0IE5vdCBAZGVjYWYtdHMvY2xpXG4gICAqICAgICAgIENsaVdyYXBwZXItPj5DbGlXcmFwcGVyOiBsb2FkKG1vZHVsZSwgY3dkKVxuICAgKiAgICAgICBDbGlXcmFwcGVyLS0+PkNsaVdyYXBwZXI6IG5hbWVcbiAgICogICAgICAgQ2xpV3JhcHBlci0+PkNsaVdyYXBwZXI6IENoZWNrIGlmIGNvbW1hbmQgZXhpc3RzXG4gICAqICAgICAgIGFsdCBDb21tYW5kIGRvZXNuJ3QgZXhpc3RcbiAgICogICAgICAgICBDbGlXcmFwcGVyLT4+Q29tbWFuZDogY29tbWFuZChuYW1lKS5hZGRDb21tYW5kKG1vZHVsZXNbbmFtZV0pXG4gICAqICAgICAgIGVuZFxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqICAgQ2xpV3JhcHBlci0+PkNvbnNvbGU6IExvZyBsb2FkZWQgbW9kdWxlc1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBib290KCkge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmJvb3QpO1xuXG4gICAgY29uc3QgYmFzZVBhdGggPSBwYXRoLnJlc29sdmUodGhpcy5yb290UGF0aCwgdGhpcy5iYXNlUGF0aCk7XG4gICAgY29uc3QgbW9kdWxlcyA9IHRoaXMuY3Jhd2woYmFzZVBhdGgsIHRoaXMuY3Jhd2xMZXZlbHMpO1xuICAgIGxldCBzZXJ2ZXIgPSB0aGlzLm1jcDtcbiAgICBmb3IgKGNvbnN0IG1vZHVsZSBvZiBtb2R1bGVzKSB7XG4gICAgICBpZiAobW9kdWxlLmluY2x1ZGVzKFwiQGRlY2FmLXRzL21jcFwiKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMubG9hZChzZXJ2ZXIsIG1vZHVsZSk7XG4gICAgICAgIHNlcnZlciA9IHJlcy5tY3A7XG4gICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgIGxvZy5lcnJvcihgRmFpbGVkIHRvIGxvYWQgTUNQIGNvbmZpZ3MgZm9yICR7bW9kdWxlfTogJHtlfWApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGBsb2FkZWQgbW9kdWxlczpcXG4ke09iamVjdC5rZXlzKHRoaXMubW9kdWxlcylcbiAgICAgICAgLm1hcCgoaykgPT4gYC0gJHtrfWApXG4gICAgICAgIC5qb2luKFwiXFxuXCIpfWBcbiAgICApO1xuICAgIHJldHVybiBzZXJ2ZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlY3Vyc2l2ZWx5IHNlYXJjaGVzIGZvciBDTEkgbW9kdWxlIGZpbGVzIGluIHRoZSBkaXJlY3Rvcnkgc3RydWN0dXJlXG4gICAqIEBzdW1tYXJ5IENyYXdscyB0aGUgYmFzZVBhdGggdXAgdG8gdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgZm9sZGVyIGxldmVscyB0byBmaW5kIGZpbGVzIG5hbWVkIGFjY29yZGluZyB0byBDTElfRklMRV9OQU1FXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aCBUaGUgYWJzb2x1dGUgYmFzZSBwYXRoIHRvIHN0YXJ0IHNlYXJjaGluZyBpblxuICAgKiBAcGFyYW0ge251bWJlcn0gW2xldmVscz0yXSBUaGUgbWF4aW11bSBudW1iZXIgb2YgZGlyZWN0b3J5IGxldmVscyB0byBjcmF3bFxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXX0gQW4gYXJyYXkgb2YgZmlsZSBwYXRocyB0byBDTEkgbW9kdWxlc1xuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjcmF3bChiYXNlUGF0aDogc3RyaW5nLCBsZXZlbHM6IG51bWJlciA9IDIpIHtcbiAgICBpZiAobGV2ZWxzIDw9IDApIHJldHVybiBbXTtcbiAgICByZXR1cm4gZnMucmVhZGRpclN5bmMoYmFzZVBhdGgpLnJlZHVjZSgoYWNjdW06IHN0cmluZ1tdLCBmaWxlKSA9PiB7XG4gICAgICBmaWxlID0gcGF0aC5qb2luKGJhc2VQYXRoLCBmaWxlKTtcbiAgICAgIGlmIChmcy5zdGF0U3luYyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGFjY3VtLnB1c2goLi4udGhpcy5jcmF3bChmaWxlLCBsZXZlbHMgLSAxKSk7XG4gICAgICB9IGVsc2UgaWYgKGZpbGUubWF0Y2gobmV3IFJlZ0V4cChgJHtNQ1BfRklMRV9OQU1FfS5bY21dP2pzJGAsIFwiZ21cIikpKSB7XG4gICAgICAgIGFjY3VtLnB1c2goZmlsZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSwgW10pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeGVjdXRlcyB0aGUgQ0xJIHdpdGggdGhlIHByb3ZpZGVkIGFyZ3VtZW50c1xuICAgKiBAc3VtbWFyeSBCb290cyB0aGUgQ0xJIGJ5IGxvYWRpbmcgYWxsIG1vZHVsZXMsIHRoZW4gcGFyc2VzIGFuZCBleGVjdXRlcyB0aGUgY29tbWFuZCBzcGVjaWZpZWQgaW4gdGhlIGFyZ3VtZW50c1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbYXJncz1wcm9jZXNzLmFyZ3ZdIENvbW1hbmQgbGluZSBhcmd1bWVudHMgdG8gcGFyc2UgYW5kIGV4ZWN1dGVcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29tbWFuZCBleGVjdXRpb24gaXMgY29tcGxldGVcbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgQ2xpV3JhcHBlclxuICAgKiAgIHBhcnRpY2lwYW50IENvbW1hbmRcbiAgICpcbiAgICogICBDbGllbnQtPj5DbGlXcmFwcGVyOiBydW4oYXJncylcbiAgICogICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogYm9vdCgpXG4gICAqICAgTm90ZSBvdmVyIENsaVdyYXBwZXI6IExvYWRzIGFsbCBtb2R1bGVzXG4gICAqICAgQ2xpV3JhcHBlci0+PkNvbW1hbmQ6IHBhcnNlQXN5bmMoYXJncylcbiAgICogICBDb21tYW5kLS0+PkNsaVdyYXBwZXI6IHJlc3VsdFxuICAgKiAgIENsaVdyYXBwZXItLT4+Q2xpZW50OiByZXN1bHRcbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgYXN5bmMgcnVuKGFyZ3M6IHN0cmluZ1tdID0gcHJvY2Vzcy5hcmd2KSB7XG4gICAgY29uc3Qgc2VydmVyID0gYXdhaXQgdGhpcy5ib290KCk7XG4gICAgYXdhaXQgc2VydmVyLnN0YXJ0KHsgdHJhbnNwb3J0VHlwZTogXCJzdGRpb1wiIH0pO1xuICB9XG59XG4iXSwibmFtZXMiOlsiVkVSU0lPTiIsIlBBQ0tBR0VfTkFNRSIsIk1ldGFkYXRhIiwieiIsImFwcGx5UGF0Y2giLCJjcmVhdGVUd29GaWxlc1BhdGNoIiwiUEtHIiwiViIsIkxvZ2dlZENsYXNzIiwiRmFzdE1DUCJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBRUE7Ozs7OztJQU1HO0lBQ0ksTUFBTUEsU0FBTyxHQUFHLGFBQWE7SUFDN0IsTUFBTUMsY0FBWSxHQUFHLGtCQUFrQjtJQUU5QyxJQUFJO0lBQ0YsSUFBQUMsbUJBQVEsQ0FBQyxlQUFlLENBQUNELGNBQVksRUFBRUQsU0FBTyxDQUFDO0lBQ2pEO0lBQUUsT0FBTyxLQUFLLEVBQUU7SUFDZCxJQUFBLElBQUksS0FBSyxZQUFZLEtBQUssSUFBSSxLQUFLLENB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
|