@decaf-ts/mcp-server 0.0.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -2
- package/dist/mcp-server.cjs +1989 -341
- package/dist/mcp-server.esm.cjs +1963 -338
- package/lib/McpWrapper.cjs +12 -10
- package/lib/McpWrapper.d.ts +1 -1
- package/lib/bin/validate-modules.cjs +24 -0
- package/lib/bin/validate-modules.d.ts +2 -0
- package/lib/constants.cjs +22 -2
- package/lib/constants.d.ts +16 -0
- package/lib/esm/McpWrapper.d.ts +1 -1
- package/lib/esm/McpWrapper.js +12 -10
- package/lib/esm/bin/validate-modules.d.ts +2 -0
- package/lib/esm/bin/validate-modules.js +22 -0
- package/lib/esm/constants.d.ts +16 -0
- package/lib/esm/constants.js +21 -1
- package/lib/esm/mcp/aggregateModules.d.ts +26 -0
- package/lib/esm/mcp/aggregateModules.js +185 -0
- package/lib/esm/mcp/code.d.ts +23 -0
- package/lib/esm/mcp/code.js +70 -0
- package/lib/esm/mcp/decorator-tools.js +237 -0
- package/lib/esm/mcp/fastmcp-wiring.d.ts +14 -0
- package/lib/esm/mcp/fastmcp-wiring.js +56 -0
- package/lib/esm/mcp/index.d.ts +7 -1
- package/lib/esm/mcp/index.js +26 -2
- package/lib/esm/mcp/mcp-module.d.ts +11 -0
- package/lib/esm/mcp/mcp-module.js +31 -0
- package/lib/esm/mcp/moduleRegistry.d.ts +12 -0
- package/lib/esm/mcp/moduleRegistry.js +46 -0
- package/lib/esm/mcp/prompts/index.d.ts +4 -0
- package/lib/esm/mcp/prompts/index.js +7 -0
- package/lib/esm/mcp/prompts/prompts.d.ts +22 -0
- package/lib/esm/mcp/prompts/prompts.js +197 -0
- package/lib/esm/mcp/resources/index.d.ts +1 -0
- package/lib/esm/mcp/resources/index.js +2 -0
- package/lib/esm/mcp/resources/resources.d.ts +2 -0
- package/lib/esm/mcp/resources/resources.js +69 -0
- package/lib/esm/mcp/schemas.d.ts +53 -0
- package/lib/esm/mcp/schemas.js +97 -0
- package/lib/esm/mcp/templates/codex-templates.d.ts +3 -0
- package/lib/esm/mcp/templates/codex-templates.js +33 -0
- package/lib/esm/mcp/templates/index.d.ts +71 -0
- package/lib/esm/mcp/templates/index.js +66 -0
- package/lib/esm/mcp/templates/resource-templates.d.ts +3 -0
- package/lib/esm/mcp/templates/resource-templates.js +60 -0
- package/lib/esm/mcp/templates/workspace-templates.d.ts +3 -0
- package/lib/esm/mcp/templates/workspace-templates.js +66 -0
- package/lib/esm/mcp/tools/codex-tools.d.ts +5 -0
- package/lib/esm/mcp/tools/codex-tools.js +244 -0
- package/lib/esm/mcp/tools/generateMcpModule.d.ts +9 -0
- package/lib/esm/mcp/tools/generateMcpModule.js +133 -0
- package/lib/esm/mcp/tools/index.d.ts +321 -0
- package/lib/esm/mcp/tools/index.js +29 -0
- package/lib/esm/mcp/tools/tools.d.ts +10 -0
- package/lib/esm/mcp/tools/tools.js +273 -0
- package/lib/esm/mcp/types.d.ts +66 -0
- package/lib/esm/mcp/types.js +2 -0
- package/lib/esm/mcp/utils.d.ts +4 -0
- package/lib/esm/mcp/utils.js +46 -0
- package/lib/esm/mcp/validation/index.d.ts +13 -0
- package/lib/esm/mcp/validation/index.js +116 -0
- package/lib/esm/mcp/validation/scaffoldModule.d.ts +9 -0
- package/lib/esm/mcp/validation/scaffoldModule.js +88 -0
- package/lib/esm/mcp/workspace.d.ts +9 -0
- package/lib/esm/mcp/workspace.js +73 -0
- package/lib/esm/metadata.d.ts +1 -1
- package/lib/esm/metadata.js +1 -1
- package/lib/esm/modules/_template/index.d.ts +32 -0
- package/lib/esm/modules/_template/index.js +16 -0
- package/lib/esm/modules/_template/prompts/index.d.ts +6 -0
- package/lib/esm/modules/_template/prompts/index.js +9 -0
- package/lib/esm/modules/_template/resources/index.d.ts +6 -0
- package/lib/esm/modules/_template/resources/index.js +9 -0
- package/lib/esm/modules/_template/templates/index.d.ts +7 -0
- package/lib/esm/modules/_template/templates/index.js +10 -0
- package/lib/esm/modules/_template/tools/index.d.ts +6 -0
- package/lib/esm/modules/_template/tools/index.js +15 -0
- package/lib/esm/modules/decoration/index.d.ts +46 -0
- package/lib/esm/modules/decoration/index.js +10 -2
- package/lib/esm/modules/decoration/prompts/index.d.ts +1 -0
- package/lib/esm/modules/decoration/prompts/index.js +2 -0
- package/lib/esm/modules/decoration/resources/index.d.ts +7 -0
- package/lib/esm/modules/decoration/resources/index.js +10 -0
- package/lib/esm/modules/decoration/templates/index.d.ts +6 -0
- package/lib/esm/modules/decoration/templates/index.js +9 -0
- package/lib/esm/modules/decoration/tools/index.d.ts +26 -0
- package/lib/esm/modules/decoration/tools/index.js +7 -0
- package/lib/esm/modules/index.d.ts +2 -0
- package/lib/esm/modules/index.js +10 -0
- package/lib/esm/modules/mcp/decoration-assist.d.ts +4 -0
- package/lib/esm/modules/mcp/decoration-assist.js +6 -0
- package/lib/esm/modules/mcp/index.d.ts +6 -2
- package/lib/esm/modules/mcp/index.js +16 -3
- package/lib/esm/modules/mcp/prompts/index.d.ts +2 -0
- package/lib/esm/modules/mcp/prompts/index.js +9 -0
- package/lib/esm/modules/mcp/resources/index.d.ts +2 -0
- package/lib/esm/modules/mcp/resources/index.js +24 -0
- package/lib/esm/modules/mcp/templates/index.d.ts +2 -0
- package/lib/esm/modules/mcp/templates/index.js +28 -0
- package/lib/esm/modules/mcp/tools/index.d.ts +6 -0
- package/lib/esm/modules/mcp/tools/index.js +15 -0
- package/lib/esm/types.d.ts +41 -1
- package/lib/esm/types.js +1 -1
- package/lib/esm/utils/modulePaths.d.ts +6 -0
- package/lib/esm/utils/modulePaths.js +33 -0
- package/lib/esm/utils/moduleValidator.d.ts +14 -0
- package/lib/esm/utils/moduleValidator.js +176 -0
- package/lib/esm/utils.d.ts +1 -0
- package/lib/esm/utils.js +2 -1
- package/lib/mcp/aggregateModules.cjs +225 -0
- package/lib/mcp/aggregateModules.d.ts +26 -0
- package/lib/mcp/code.cjs +81 -0
- package/lib/mcp/code.d.ts +23 -0
- package/lib/mcp/decorator-tools.cjs +243 -0
- package/lib/mcp/fastmcp-wiring.cjs +59 -0
- package/lib/mcp/fastmcp-wiring.d.ts +14 -0
- package/lib/mcp/index.cjs +47 -12
- package/lib/mcp/index.d.ts +7 -1
- package/lib/mcp/mcp-module.cjs +53 -0
- package/lib/mcp/mcp-module.d.ts +11 -0
- package/lib/mcp/moduleRegistry.cjs +50 -0
- package/lib/mcp/moduleRegistry.d.ts +12 -0
- package/lib/mcp/prompts/index.cjs +25 -0
- package/lib/mcp/prompts/index.d.ts +4 -0
- package/lib/mcp/prompts/prompts.cjs +211 -0
- package/lib/mcp/prompts/prompts.d.ts +22 -0
- package/lib/mcp/resources/index.cjs +18 -0
- package/lib/mcp/resources/index.d.ts +1 -0
- package/lib/mcp/resources/resources.cjs +72 -0
- package/lib/mcp/resources/resources.d.ts +2 -0
- package/lib/mcp/schemas.cjs +100 -0
- package/lib/mcp/schemas.d.ts +53 -0
- package/lib/mcp/templates/codex-templates.cjs +40 -0
- package/lib/mcp/templates/codex-templates.d.ts +3 -0
- package/lib/mcp/templates/index.cjs +76 -0
- package/lib/mcp/templates/index.d.ts +71 -0
- package/lib/mcp/templates/resource-templates.cjs +67 -0
- package/lib/mcp/templates/resource-templates.d.ts +3 -0
- package/lib/mcp/templates/workspace-templates.cjs +70 -0
- package/lib/mcp/templates/workspace-templates.d.ts +3 -0
- package/lib/mcp/tools/codex-tools.cjs +250 -0
- package/lib/mcp/tools/codex-tools.d.ts +5 -0
- package/lib/mcp/tools/generateMcpModule.cjs +139 -0
- package/lib/mcp/tools/generateMcpModule.d.ts +9 -0
- package/lib/mcp/tools/index.cjs +46 -0
- package/lib/mcp/tools/index.d.ts +321 -0
- package/lib/mcp/tools/tools.cjs +282 -0
- package/lib/mcp/tools/tools.d.ts +10 -0
- package/lib/mcp/types.cjs +3 -0
- package/lib/mcp/types.d.ts +66 -0
- package/lib/mcp/utils.cjs +54 -0
- package/lib/mcp/utils.d.ts +4 -0
- package/lib/mcp/validation/index.cjs +123 -0
- package/lib/mcp/validation/index.d.ts +13 -0
- package/lib/mcp/validation/scaffoldModule.cjs +94 -0
- package/lib/mcp/validation/scaffoldModule.d.ts +9 -0
- package/lib/mcp/workspace.cjs +119 -0
- package/lib/mcp/workspace.d.ts +9 -0
- package/lib/metadata.cjs +1 -1
- package/lib/metadata.d.ts +1 -1
- package/lib/modules/_template/index.cjs +23 -0
- package/lib/modules/_template/index.d.ts +32 -0
- package/lib/modules/_template/prompts/index.cjs +12 -0
- package/lib/modules/_template/prompts/index.d.ts +6 -0
- package/lib/modules/_template/resources/index.cjs +12 -0
- package/lib/modules/_template/resources/index.d.ts +6 -0
- package/lib/modules/_template/templates/index.cjs +13 -0
- package/lib/modules/_template/templates/index.d.ts +7 -0
- package/lib/modules/_template/tools/index.cjs +18 -0
- package/lib/modules/_template/tools/index.d.ts +6 -0
- package/lib/modules/decoration/index.cjs +16 -1
- package/lib/modules/decoration/index.d.ts +46 -0
- package/lib/modules/decoration/prompts/index.cjs +5 -0
- package/lib/modules/decoration/prompts/index.d.ts +1 -0
- package/lib/modules/decoration/resources/index.cjs +13 -0
- package/lib/modules/decoration/resources/index.d.ts +7 -0
- package/lib/modules/decoration/templates/index.cjs +12 -0
- package/lib/modules/decoration/templates/index.d.ts +6 -0
- package/lib/modules/decoration/tools/index.cjs +10 -0
- package/lib/modules/decoration/tools/index.d.ts +26 -0
- package/lib/modules/index.cjs +13 -0
- package/lib/modules/index.d.ts +2 -0
- package/lib/modules/mcp/decoration-assist.cjs +13 -0
- package/lib/modules/mcp/decoration-assist.d.ts +4 -0
- package/lib/modules/mcp/index.cjs +21 -22
- package/lib/modules/mcp/index.d.ts +6 -2
- package/lib/modules/mcp/prompts/index.cjs +12 -0
- package/lib/modules/mcp/prompts/index.d.ts +2 -0
- package/lib/modules/mcp/resources/index.cjs +27 -0
- package/lib/modules/mcp/resources/index.d.ts +2 -0
- package/lib/modules/mcp/templates/index.cjs +31 -0
- package/lib/modules/mcp/templates/index.d.ts +2 -0
- package/lib/modules/mcp/tools/index.cjs +18 -0
- package/lib/modules/mcp/tools/index.d.ts +6 -0
- package/lib/types.cjs +1 -1
- package/lib/types.d.ts +41 -1
- package/lib/utils/modulePaths.cjs +43 -0
- package/lib/utils/modulePaths.d.ts +6 -0
- package/lib/utils/moduleValidator.cjs +184 -0
- package/lib/utils/moduleValidator.d.ts +14 -0
- package/lib/utils.cjs +5 -1
- package/lib/utils.d.ts +1 -0
- package/package.json +18 -12
- package/lib/esm/modules/decoration-assist/index.d.ts +0 -39
- package/lib/esm/modules/decoration-assist/index.js +0 -353
- package/lib/esm/modules/mcp/decorator-tools.js +0 -237
- package/lib/esm/modules/mcp/mcp-module.d.ts +0 -230
- package/lib/esm/modules/mcp/mcp-module.js +0 -406
- package/lib/modules/decoration-assist/index.cjs +0 -360
- package/lib/modules/decoration-assist/index.d.ts +0 -39
- package/lib/modules/mcp/decorator-tools.cjs +0 -243
- package/lib/modules/mcp/mcp-module.cjs +0 -452
- package/lib/modules/mcp/mcp-module.d.ts +0 -230
- /package/lib/esm/{modules/mcp → mcp}/decorator-tools.d.ts +0 -0
- /package/lib/{modules/mcp → mcp}/decorator-tools.d.ts +0 -0
package/dist/mcp-server.esm.cjs
CHANGED
|
@@ -2,29 +2,997 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { applyPatch, createTwoFilesPatch } from 'diff';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
+
import { spawnSync } from 'child_process';
|
|
5
6
|
import { Metadata } from '@decaf-ts/decoration';
|
|
7
|
+
import { pathToFileURL } from 'url';
|
|
8
|
+
import fs$1 from 'node:fs';
|
|
9
|
+
import path$1 from 'node:path';
|
|
6
10
|
import { FastMCP } from 'fastmcp';
|
|
7
11
|
import { LoggedClass } from '@decaf-ts/logging';
|
|
8
12
|
|
|
9
13
|
/**
|
|
10
|
-
* @
|
|
11
|
-
* @
|
|
12
|
-
*
|
|
13
|
-
* @
|
|
14
|
-
* @
|
|
14
|
+
* @description The filename that identifies Decaf CLI modules
|
|
15
|
+
* @summary The standard filename for CLI module files where each library must export a single CliModule function
|
|
16
|
+
*
|
|
17
|
+
* @const MCP_FILE_NAME
|
|
18
|
+
* @memberOf module:MCP
|
|
15
19
|
*/
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
const MCP_FILE_NAME = "mcp-module";
|
|
21
|
+
const WORKSPACE_ROOT_ENV = "MCP_WORKSPACE_ROOT";
|
|
22
|
+
const PROMPT_DIRECTORIES = [".code/prompts", ".codex/prompts"];
|
|
23
|
+
const DEFAULT_PROMPT_NAME = "doc";
|
|
24
|
+
const CLIENT_INTEGRATIONS = [
|
|
25
|
+
{
|
|
26
|
+
id: "vscode",
|
|
27
|
+
display: "Visual Studio Code",
|
|
28
|
+
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.",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "cursor",
|
|
32
|
+
display: "Cursor",
|
|
33
|
+
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.",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "copilot",
|
|
37
|
+
display: "GitHub Copilot",
|
|
38
|
+
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.",
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
let workspaceRoot = initializeWorkspaceRoot();
|
|
43
|
+
let userErrorCtor;
|
|
44
|
+
class WorkspaceError extends Error {
|
|
45
|
+
constructor(message) {
|
|
46
|
+
super(message);
|
|
47
|
+
this.name = "WorkspaceError";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function initializeWorkspaceRoot() {
|
|
51
|
+
const configured = process.env[WORKSPACE_ROOT_ENV];
|
|
52
|
+
if (configured && configured.trim().length > 0) {
|
|
53
|
+
return path.resolve(configured.trim());
|
|
54
|
+
}
|
|
55
|
+
return process.cwd();
|
|
56
|
+
}
|
|
57
|
+
async function getUserErrorCtor() {
|
|
58
|
+
if (!userErrorCtor) {
|
|
59
|
+
try {
|
|
60
|
+
const mod = await import('fastmcp');
|
|
61
|
+
userErrorCtor = mod
|
|
62
|
+
.UserError;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
userErrorCtor = class MCPUserError extends Error {
|
|
66
|
+
constructor(message) {
|
|
67
|
+
super(message);
|
|
68
|
+
this.name = "MCPUserError";
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return userErrorCtor;
|
|
74
|
+
}
|
|
75
|
+
async function throwUserError(message) {
|
|
76
|
+
const Ctor = await getUserErrorCtor();
|
|
77
|
+
throw new Ctor(message);
|
|
78
|
+
}
|
|
79
|
+
function setWorkspaceRoot(root) {
|
|
80
|
+
workspaceRoot = path.resolve(root);
|
|
81
|
+
}
|
|
82
|
+
function getWorkspaceRoot() {
|
|
83
|
+
return workspaceRoot;
|
|
84
|
+
}
|
|
85
|
+
function resolveInWorkspace(root, targetPath) {
|
|
86
|
+
const resolved = path.isAbsolute(targetPath)
|
|
87
|
+
? path.normalize(targetPath)
|
|
88
|
+
: path.resolve(root, targetPath);
|
|
89
|
+
const relative = path.relative(root, resolved);
|
|
90
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
91
|
+
throw new WorkspaceError(`Path ${targetPath} escapes the workspace root at ${root}`);
|
|
92
|
+
}
|
|
93
|
+
return resolved;
|
|
94
|
+
}
|
|
95
|
+
async function readWorkspaceFile(root, target) {
|
|
96
|
+
try {
|
|
97
|
+
const absolute = resolveInWorkspace(root, target);
|
|
98
|
+
return fs.readFileSync(absolute, "utf8");
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
if (error instanceof WorkspaceError) {
|
|
102
|
+
await throwUserError(error.message);
|
|
103
|
+
}
|
|
104
|
+
/* istanbul ignore next */
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function __resetWorkspaceRoot(root) {
|
|
109
|
+
setWorkspaceRoot(root);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const prompts$3 = [];
|
|
113
|
+
|
|
114
|
+
const resources$3 = [
|
|
115
|
+
{
|
|
116
|
+
"id": "decoration.repo",
|
|
117
|
+
"name": "decoration repository",
|
|
118
|
+
"description": "Source repository",
|
|
119
|
+
"uri": "file:///home/tvenceslau/local-workspace/decaf-ts/mcp-server/src/modules/decoration",
|
|
120
|
+
"absolutePath": "/home/tvenceslau/local-workspace/decaf-ts/mcp-server/src/modules/decoration"
|
|
121
|
+
}
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
const templates$2 = [
|
|
125
|
+
{
|
|
126
|
+
"name": "readme-template",
|
|
127
|
+
"description": "README as guidance",
|
|
128
|
+
"uriTemplate": "file:///home/tvenceslau/local-workspace/decaf-ts/mcp-server/src/modules/decoration/README.md",
|
|
129
|
+
"mimeType": "text/markdown"
|
|
130
|
+
}
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
const analyzeRepoSchema = z
|
|
134
|
+
.object({
|
|
135
|
+
repoPath: z
|
|
136
|
+
.string()
|
|
137
|
+
.min(1, "repoPath is required")
|
|
138
|
+
.describe("Relative or absolute path to the target repository inside this monorepo, e.g. './decoration'."),
|
|
139
|
+
includeTests: z
|
|
140
|
+
.boolean()
|
|
141
|
+
.default(true)
|
|
142
|
+
.describe("If true, analyze the tests directory (if present) to derive expected behaviors."),
|
|
143
|
+
includeDocs: z
|
|
144
|
+
.boolean()
|
|
145
|
+
.default(true)
|
|
146
|
+
.describe("If true, analyze README.md and docs directories to extract documented features."),
|
|
147
|
+
})
|
|
148
|
+
.strict()
|
|
149
|
+
.describe("Analyze a local repository (e.g. ./decoration) to extract APIs, features, tests, and documentation cues.");
|
|
150
|
+
const enumerateCapabilitiesSchema = z
|
|
151
|
+
.object({
|
|
152
|
+
repoPath: z
|
|
153
|
+
.string()
|
|
154
|
+
.min(1, "repoPath is required")
|
|
155
|
+
.describe("Relative or absolute path to the target repository to enumerate developer-facing capabilities."),
|
|
156
|
+
})
|
|
157
|
+
.strict()
|
|
158
|
+
.describe("Enumerate the complete set of capabilities a developer is expected to use from the given repository.");
|
|
159
|
+
const planFeatureSchema = z
|
|
160
|
+
.object({
|
|
161
|
+
feature: z
|
|
162
|
+
.string()
|
|
163
|
+
.min(5, "feature must describe the goal clearly")
|
|
164
|
+
.describe("Natural-language description of a developer's requested feature or task to implement using the repository and available MCP tools."),
|
|
165
|
+
repoPath: z
|
|
166
|
+
.string()
|
|
167
|
+
.default("./decoration")
|
|
168
|
+
.describe("Target repository path providing the library to use, e.g. './decoration'."),
|
|
169
|
+
})
|
|
170
|
+
.strict()
|
|
171
|
+
.describe("Plan which MCP tools to use and in what sequence to implement a requested feature using the repository.");
|
|
172
|
+
const documentCodeSchema = z
|
|
173
|
+
.object({
|
|
174
|
+
filePath: z.string().min(1, "filePath is required"),
|
|
175
|
+
promptName: z.string().optional(),
|
|
176
|
+
includePrompt: z.boolean().default(true),
|
|
177
|
+
includeCode: z.boolean().default(true),
|
|
178
|
+
includeMetadata: z.boolean().default(true),
|
|
179
|
+
additionalContext: z.string().optional(),
|
|
180
|
+
encoding: z.string().default("utf8"),
|
|
181
|
+
})
|
|
182
|
+
.strict();
|
|
183
|
+
const codeChangeSchema = z
|
|
184
|
+
.object({
|
|
185
|
+
filePath: z.string().min(1, "filePath is required"),
|
|
186
|
+
patch: z.string().min(1, "patch is required"),
|
|
187
|
+
dryRun: z.boolean().default(false),
|
|
188
|
+
showDiff: z.boolean().default(true),
|
|
189
|
+
diffContext: z.number().int().min(0).max(100).default(3),
|
|
190
|
+
encoding: z.string().default("utf8"),
|
|
191
|
+
})
|
|
192
|
+
.strict();
|
|
193
|
+
const OBJECT_TYPES = [
|
|
194
|
+
"module",
|
|
195
|
+
"file",
|
|
196
|
+
"class",
|
|
197
|
+
"function",
|
|
198
|
+
"interface",
|
|
199
|
+
"decorator",
|
|
200
|
+
"constant",
|
|
201
|
+
];
|
|
202
|
+
const documentObjectSchema = z
|
|
203
|
+
.object({
|
|
204
|
+
basePath: z.string().min(1, "basePath is required"),
|
|
205
|
+
objectType: z.enum(OBJECT_TYPES),
|
|
206
|
+
targetFile: z.string().optional(),
|
|
207
|
+
includeContent: z.boolean().default(false),
|
|
208
|
+
})
|
|
209
|
+
.strict();
|
|
210
|
+
const coverageTaskSchema = z
|
|
211
|
+
.object({
|
|
212
|
+
basePath: z.string().min(1, "basePath is required"),
|
|
213
|
+
coverage: z
|
|
214
|
+
.number()
|
|
215
|
+
.min(0)
|
|
216
|
+
.max(100)
|
|
217
|
+
.default(90)
|
|
218
|
+
.describe("Target coverage percentage"),
|
|
219
|
+
dryRun: z.boolean().default(false),
|
|
220
|
+
})
|
|
221
|
+
.strict();
|
|
222
|
+
const readmeImprovementSchema = z
|
|
223
|
+
.object({
|
|
224
|
+
basePath: z.string().min(1, "basePath is required"),
|
|
225
|
+
includeExamples: z.boolean().default(true),
|
|
226
|
+
})
|
|
227
|
+
.strict();
|
|
228
|
+
|
|
229
|
+
function readFileSafe(filePath, encoding = "utf8") {
|
|
230
|
+
try {
|
|
231
|
+
return fs.readFileSync(filePath, { encoding });
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
return undefined;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function listFilesRecursive(root, matcher) {
|
|
238
|
+
const out = [];
|
|
239
|
+
const stack = [root];
|
|
240
|
+
while (stack.length) {
|
|
241
|
+
const cur = stack.pop();
|
|
242
|
+
const stat = fs.statSync(cur);
|
|
243
|
+
if (stat.isDirectory()) {
|
|
244
|
+
for (const f of fs.readdirSync(cur))
|
|
245
|
+
stack.push(path.join(cur, f));
|
|
246
|
+
}
|
|
247
|
+
else if (!matcher || matcher(cur)) {
|
|
248
|
+
out.push(cur);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return out.sort();
|
|
252
|
+
}
|
|
253
|
+
function deriveCapabilities(analysis) {
|
|
254
|
+
const cap = new Set();
|
|
255
|
+
// heuristics: if decorators like Decoration, flavouredAs, extend, override appear, add capabilities
|
|
256
|
+
const allDecs = new Set();
|
|
257
|
+
for (const k of Object.keys(analysis.api)) {
|
|
258
|
+
for (const d of analysis.api[k].decorators)
|
|
259
|
+
allDecs.add(d);
|
|
260
|
+
for (const e of analysis.api[k].exports)
|
|
261
|
+
if (/Decoration|decorate|Builder|Flavour/i.test(e))
|
|
262
|
+
cap.add("use-decoration-api");
|
|
263
|
+
}
|
|
264
|
+
if ([...allDecs].some((d) => /override|extend/i.test(d)))
|
|
265
|
+
cap.add("override-and-extend-decorations");
|
|
266
|
+
if (Object.keys(analysis.tests).length > 0)
|
|
267
|
+
cap.add("validate-with-tests");
|
|
268
|
+
if (analysis.readme)
|
|
269
|
+
cap.add("follow-readme-guides");
|
|
270
|
+
return [...cap].sort();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Analysis helpers (minimal yet effective, text-based to avoid heavy AST deps)
|
|
274
|
+
function isSourceFile(p) {
|
|
275
|
+
return /\.(ts|tsx|js|jsx)$/.test(p) && !p.endsWith(".d.ts");
|
|
276
|
+
}
|
|
277
|
+
function isTestFile(p) {
|
|
278
|
+
return /(\.test\.|\.spec\.)/.test(p);
|
|
279
|
+
}
|
|
280
|
+
function extractExports(fileContent) {
|
|
281
|
+
const names = new Set();
|
|
282
|
+
const exportRe = /(export\s+(?:default\s+)?(?:class|function|const|let|var|interface|type|enum)\s+)([A-Za-z0-9_]+)/g;
|
|
283
|
+
const namedRe = /export\s*\{([^}]+)\}/g;
|
|
284
|
+
let m;
|
|
285
|
+
while ((m = exportRe.exec(fileContent)))
|
|
286
|
+
names.add(m[2]);
|
|
287
|
+
while ((m = namedRe.exec(fileContent))) {
|
|
288
|
+
m[1]
|
|
289
|
+
.split(",")
|
|
290
|
+
.map((s) => s.trim().split(" as ")[0].trim())
|
|
291
|
+
.forEach((n) => {
|
|
292
|
+
if (n)
|
|
293
|
+
names.add(n);
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
return [...names].sort();
|
|
297
|
+
}
|
|
298
|
+
function extractDecorators(fileContent) {
|
|
299
|
+
const decs = new Set();
|
|
300
|
+
const decRe = /@([A-Za-z_][A-Za-z0-9_]*)/g;
|
|
301
|
+
let m;
|
|
302
|
+
while ((m = decRe.exec(fileContent)))
|
|
303
|
+
decs.add(m[1]);
|
|
304
|
+
return [...decs].sort();
|
|
305
|
+
}
|
|
306
|
+
function summarizeReadme(readme) {
|
|
307
|
+
if (!readme)
|
|
308
|
+
return undefined;
|
|
309
|
+
const lines = readme.split(/\r?\n/).filter(Boolean);
|
|
310
|
+
const title = lines.find((l) => /^#\s+/.test(l))?.replace(/^#\s+/, "") || "README";
|
|
311
|
+
const bullets = lines.filter((l) => /^[-*]\s+/.test(l)).slice(0, 20);
|
|
312
|
+
return { title, bullets };
|
|
313
|
+
}
|
|
314
|
+
function analyzeRepo(root) {
|
|
315
|
+
const src = path.join(root, "src");
|
|
316
|
+
const testDir = path.join(root, "tests");
|
|
317
|
+
const readmePath = path.join(root, "README.md");
|
|
318
|
+
const readme = readFileSafe(readmePath);
|
|
319
|
+
const files = fs.existsSync(src) ? listFilesRecursive(src, isSourceFile) : [];
|
|
320
|
+
const testFiles = fs.existsSync(testDir)
|
|
321
|
+
? listFilesRecursive(testDir, (f) => isSourceFile(f) && isTestFile(f))
|
|
322
|
+
: [];
|
|
323
|
+
const api = {};
|
|
324
|
+
for (const f of files) {
|
|
325
|
+
const content = readFileSafe(f) || "";
|
|
326
|
+
api[path.relative(root, f)] = {
|
|
327
|
+
exports: extractExports(content),
|
|
328
|
+
decorators: extractDecorators(content),
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
const tests = {};
|
|
332
|
+
for (const f of testFiles) {
|
|
333
|
+
const content = readFileSafe(f) || "";
|
|
334
|
+
const mentions = Array.from(new Set([...extractExports(content), ...extractDecorators(content)])).sort();
|
|
335
|
+
tests[path.relative(root, f)] = { mentions };
|
|
336
|
+
}
|
|
337
|
+
return { files, testFiles, api, tests, readme: summarizeReadme(readme) };
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function buildAnalyzeRepositoryTool() {
|
|
341
|
+
return {
|
|
342
|
+
name: "analyze-repository",
|
|
343
|
+
description: "Analyze a local repository's source, tests, and docs to extract exported APIs, decorators, and test mentions.",
|
|
344
|
+
parameters: analyzeRepoSchema,
|
|
345
|
+
execute: async (input) => {
|
|
346
|
+
let repoRoot = path.resolve(process.cwd(), input.repoPath);
|
|
347
|
+
if (!fs.existsSync(repoRoot)) {
|
|
348
|
+
// try resolving from monorepo root (parent of current cwd)
|
|
349
|
+
const alt = path.resolve(process.cwd(), "..", input.repoPath);
|
|
350
|
+
if (fs.existsSync(alt))
|
|
351
|
+
repoRoot = alt;
|
|
352
|
+
}
|
|
353
|
+
if (!fs.existsSync(repoRoot)) {
|
|
354
|
+
// if input was absolute and still not found, try ../<basename>
|
|
355
|
+
const alt2 = path.resolve(process.cwd(), "..", path.basename(input.repoPath));
|
|
356
|
+
if (fs.existsSync(alt2))
|
|
357
|
+
repoRoot = alt2;
|
|
358
|
+
}
|
|
359
|
+
if (!fs.existsSync(repoRoot))
|
|
360
|
+
throw new Error(`Repository not found at ${repoRoot}`);
|
|
361
|
+
const result = analyzeRepo(repoRoot);
|
|
362
|
+
return {
|
|
363
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
364
|
+
};
|
|
365
|
+
},
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
function buildEnumerateCapabilitiesTool() {
|
|
369
|
+
return {
|
|
370
|
+
name: "enumerate-capabilities",
|
|
371
|
+
description: "Enumerate developer-facing capabilities of the given repository, inferred from code, tests, and docs.",
|
|
372
|
+
parameters: enumerateCapabilitiesSchema,
|
|
373
|
+
execute: async (input) => {
|
|
374
|
+
let repoRoot = path.resolve(process.cwd(), input.repoPath);
|
|
375
|
+
if (!fs.existsSync(repoRoot)) {
|
|
376
|
+
const alt = path.resolve(process.cwd(), "..", input.repoPath);
|
|
377
|
+
if (fs.existsSync(alt))
|
|
378
|
+
repoRoot = alt;
|
|
379
|
+
}
|
|
380
|
+
if (!fs.existsSync(repoRoot)) {
|
|
381
|
+
const alt2 = path.resolve(process.cwd(), "..", path.basename(input.repoPath));
|
|
382
|
+
if (fs.existsSync(alt2))
|
|
383
|
+
repoRoot = alt2;
|
|
384
|
+
}
|
|
385
|
+
if (!fs.existsSync(repoRoot))
|
|
386
|
+
throw new Error(`Repository not found at ${repoRoot}`);
|
|
387
|
+
const analysis = analyzeRepo(repoRoot);
|
|
388
|
+
const capabilities = deriveCapabilities(analysis);
|
|
389
|
+
return {
|
|
390
|
+
content: [
|
|
391
|
+
{
|
|
392
|
+
type: "text",
|
|
393
|
+
text: JSON.stringify({
|
|
394
|
+
capabilities,
|
|
395
|
+
analysisSummary: {
|
|
396
|
+
files: analysis.files.length,
|
|
397
|
+
testFiles: analysis.testFiles.length,
|
|
398
|
+
readme: analysis.readme?.title,
|
|
399
|
+
},
|
|
400
|
+
}, null, 2),
|
|
401
|
+
},
|
|
402
|
+
],
|
|
403
|
+
};
|
|
404
|
+
},
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
function buildPlanFeatureTool() {
|
|
408
|
+
return {
|
|
409
|
+
name: "plan-feature-implementation",
|
|
410
|
+
description: "Given a feature request, select appropriate MCP tools (including existing and new ones) and produce an execution plan.",
|
|
411
|
+
parameters: planFeatureSchema,
|
|
412
|
+
execute: async (input) => {
|
|
413
|
+
const steps = [];
|
|
414
|
+
let i = 1;
|
|
415
|
+
steps.push({
|
|
416
|
+
step: i++,
|
|
417
|
+
action: "Analyze repository to enumerate APIs and decorators",
|
|
418
|
+
tool: "analyze-repository",
|
|
419
|
+
arguments: { repoPath: input.repoPath },
|
|
420
|
+
rationale: "Understand available building blocks.",
|
|
421
|
+
});
|
|
422
|
+
steps.push({
|
|
423
|
+
step: i++,
|
|
424
|
+
action: "List capabilities expected for developers",
|
|
425
|
+
tool: "enumerate-capabilities",
|
|
426
|
+
arguments: { repoPath: input.repoPath },
|
|
427
|
+
rationale: "Align the plan with supported capabilities.",
|
|
428
|
+
});
|
|
429
|
+
// Suggest existing generic tools from mcp-module
|
|
430
|
+
steps.push({
|
|
431
|
+
step: i++,
|
|
432
|
+
action: "Select documentation prompt and gather relevant source file(s)",
|
|
433
|
+
tool: "document-code",
|
|
434
|
+
arguments: { filePath: "<target-file>" },
|
|
435
|
+
rationale: "Provide context and instructions for changes.",
|
|
436
|
+
});
|
|
437
|
+
steps.push({
|
|
438
|
+
step: i++,
|
|
439
|
+
action: "Apply code changes using unified diff patch",
|
|
440
|
+
tool: "apply-code-change",
|
|
441
|
+
arguments: {
|
|
442
|
+
filePath: "<target-file>",
|
|
443
|
+
patch: "<unified-diff>",
|
|
444
|
+
dryRun: true,
|
|
445
|
+
},
|
|
446
|
+
rationale: "Validate changes safely before committing.",
|
|
447
|
+
});
|
|
448
|
+
steps.push({
|
|
449
|
+
step: i++,
|
|
450
|
+
action: "Commit code changes",
|
|
451
|
+
tool: "apply-code-change",
|
|
452
|
+
arguments: {
|
|
453
|
+
filePath: "<target-file>",
|
|
454
|
+
patch: "<unified-diff>",
|
|
455
|
+
dryRun: false,
|
|
456
|
+
},
|
|
457
|
+
rationale: "Persist the update.",
|
|
458
|
+
});
|
|
459
|
+
// If decoration-related terms present, suggest decorator tools
|
|
460
|
+
if (/decorat|flavour|override|extend|builder/i.test(input.feature)) {
|
|
461
|
+
steps.unshift({
|
|
462
|
+
step: 0,
|
|
463
|
+
action: "Use decorator tooling to insert/remove/modify decorators",
|
|
464
|
+
tool: "decorator-tools",
|
|
465
|
+
arguments: { action: "help" },
|
|
466
|
+
rationale: "Leverage specialized utilities for decoration patterns.",
|
|
467
|
+
});
|
|
468
|
+
steps.forEach((s, idx) => (s.step = idx + 1));
|
|
469
|
+
}
|
|
470
|
+
return {
|
|
471
|
+
content: [
|
|
472
|
+
{
|
|
473
|
+
type: "text",
|
|
474
|
+
text: JSON.stringify({
|
|
475
|
+
plan: steps,
|
|
476
|
+
notes: "Replace placeholder arguments like <target-file> and <unified-diff> based on the analysis output.",
|
|
477
|
+
}, null, 2),
|
|
478
|
+
},
|
|
479
|
+
],
|
|
480
|
+
};
|
|
481
|
+
},
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
const documentCodeTool = {
|
|
485
|
+
annotations: {
|
|
486
|
+
idempotentHint: true,
|
|
487
|
+
openWorldHint: false,
|
|
488
|
+
readOnlyHint: true,
|
|
489
|
+
title: "Document Source File",
|
|
490
|
+
},
|
|
491
|
+
description: "Generate documentation guidance for a file by combining repository prompts with the target source code.",
|
|
492
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
493
|
+
execute: async (input, _context) => {
|
|
494
|
+
const args = documentCodeSchema.parse(input);
|
|
495
|
+
const root = getWorkspaceRoot();
|
|
496
|
+
let filePath;
|
|
497
|
+
try {
|
|
498
|
+
filePath = resolveInWorkspace(root, args.filePath);
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
if (error instanceof WorkspaceError) {
|
|
502
|
+
return throwUserError(error.message);
|
|
503
|
+
}
|
|
504
|
+
/* istanbul ignore next */
|
|
505
|
+
throw error;
|
|
506
|
+
}
|
|
507
|
+
if (!fs.existsSync(filePath)) {
|
|
508
|
+
return throwUserError(`Cannot document missing file at ${args.filePath}`);
|
|
509
|
+
}
|
|
510
|
+
const fileContent = fs.readFileSync(filePath, {
|
|
511
|
+
encoding: args.encoding,
|
|
512
|
+
});
|
|
513
|
+
const prompts = discoverDocPrompts(root);
|
|
514
|
+
if (!prompts.length) {
|
|
515
|
+
return throwUserError("No documentation prompts found under .code/prompts or .codex/prompts");
|
|
516
|
+
}
|
|
517
|
+
const prompt = selectPrompt(prompts, args.promptName ?? DEFAULT_PROMPT_NAME);
|
|
518
|
+
return buildDocumentationPayload({
|
|
519
|
+
filePath: args.filePath,
|
|
520
|
+
fileContent,
|
|
521
|
+
prompt,
|
|
522
|
+
includeCode: args.includeCode,
|
|
523
|
+
includePrompt: args.includePrompt,
|
|
524
|
+
includeMetadata: args.includeMetadata,
|
|
525
|
+
additionalContext: args.additionalContext,
|
|
526
|
+
});
|
|
527
|
+
},
|
|
528
|
+
name: "document-code",
|
|
529
|
+
parameters: documentCodeSchema,
|
|
530
|
+
};
|
|
531
|
+
const applyCodeChangeTool = {
|
|
532
|
+
annotations: {
|
|
533
|
+
destructiveHint: true,
|
|
534
|
+
idempotentHint: false,
|
|
535
|
+
openWorldHint: false,
|
|
536
|
+
readOnlyHint: false,
|
|
537
|
+
title: "Apply Code Patch",
|
|
538
|
+
},
|
|
539
|
+
description: "Apply a unified diff patch to a workspace file with optional dry-run validation and diff preview.",
|
|
540
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
541
|
+
execute: async (input, _context) => {
|
|
542
|
+
const args = codeChangeSchema.parse(input);
|
|
543
|
+
const root = getWorkspaceRoot();
|
|
544
|
+
let filePath;
|
|
545
|
+
try {
|
|
546
|
+
filePath = resolveInWorkspace(root, args.filePath);
|
|
547
|
+
}
|
|
548
|
+
catch (error) {
|
|
549
|
+
if (error instanceof WorkspaceError) {
|
|
550
|
+
return throwUserError(error.message);
|
|
551
|
+
}
|
|
552
|
+
throw error;
|
|
553
|
+
}
|
|
554
|
+
const original = fs.existsSync(filePath)
|
|
555
|
+
? fs.readFileSync(filePath, args.encoding)
|
|
556
|
+
: "";
|
|
557
|
+
let patched;
|
|
558
|
+
try {
|
|
559
|
+
patched = applyPatch(original, args.patch);
|
|
560
|
+
}
|
|
561
|
+
catch (error) {
|
|
562
|
+
return throwUserError(`Failed to apply provided patch to ${args.filePath}: ${error instanceof Error ? error.message : error}`);
|
|
563
|
+
}
|
|
564
|
+
/* istanbul ignore next */
|
|
565
|
+
if (patched === false) {
|
|
566
|
+
return throwUserError(`Failed to apply provided patch to ${args.filePath}`);
|
|
567
|
+
}
|
|
568
|
+
if (!args.dryRun) {
|
|
569
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
570
|
+
fs.writeFileSync(filePath, patched, {
|
|
571
|
+
encoding: args.encoding,
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
if (!args.showDiff) {
|
|
575
|
+
return `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`;
|
|
576
|
+
}
|
|
577
|
+
const preview = createTwoFilesPatch(args.filePath, args.filePath, original, patched, undefined, undefined, { context: args.diffContext });
|
|
578
|
+
return {
|
|
579
|
+
content: [
|
|
580
|
+
{
|
|
581
|
+
type: "text",
|
|
582
|
+
text: `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`,
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
type: "text",
|
|
586
|
+
text: ["```diff", preview.trim(), "```"].join("\n"),
|
|
587
|
+
},
|
|
588
|
+
],
|
|
589
|
+
};
|
|
590
|
+
},
|
|
591
|
+
name: "apply-code-change",
|
|
592
|
+
parameters: codeChangeSchema,
|
|
593
|
+
};
|
|
594
|
+
const analyticTools = [
|
|
595
|
+
buildAnalyzeRepositoryTool(),
|
|
596
|
+
buildEnumerateCapabilitiesTool(),
|
|
597
|
+
buildPlanFeatureTool(),
|
|
598
|
+
];
|
|
599
|
+
const toolList$1 = [
|
|
600
|
+
...analyticTools,
|
|
601
|
+
documentCodeTool,
|
|
602
|
+
applyCodeChangeTool,
|
|
603
|
+
];
|
|
604
|
+
|
|
605
|
+
const tools$3 = [
|
|
606
|
+
{ id: 'decoration.analyze', title: 'Analyze decoration', description: 'Analyze the target repository', tool: buildAnalyzeRepositoryTool() },
|
|
607
|
+
{ id: 'decoration.enumerate', title: 'Enumerate capabilities for decoration', description: 'Enumerate capabilities', tool: buildEnumerateCapabilitiesTool() },
|
|
608
|
+
{ id: 'decoration.plan', title: 'Plan features for decoration', description: 'Plan feature implementation', tool: buildPlanFeatureTool() },
|
|
609
|
+
];
|
|
610
|
+
|
|
611
|
+
const modulePackage$2 = { name: 'decoration', prompts: prompts$3, resources: resources$3, templates: templates$2, tools: tools$3 };
|
|
612
|
+
|
|
613
|
+
const prompts$2 = [
|
|
614
|
+
{
|
|
615
|
+
id: "mcp.prompt.module-catalog",
|
|
616
|
+
title: "Decaf MCP Module Catalog",
|
|
617
|
+
description: "Summarizes the modules contributing prompts/resources/templates/tools to FASTMCP.",
|
|
618
|
+
load: async () => "Use the module catalog tool to enumerate available module assets before fulfilling assistant requests.",
|
|
619
|
+
},
|
|
620
|
+
];
|
|
621
|
+
|
|
622
|
+
const resources$2 = [
|
|
623
|
+
{
|
|
624
|
+
id: "mcp.resource.registry-overview",
|
|
625
|
+
title: "Module Registry Overview",
|
|
626
|
+
description: "Explains how the ModuleRegistry aggregates module exports into FASTMCP catalogs.",
|
|
627
|
+
uri: "decaf://mcp/module-registry",
|
|
628
|
+
mimeType: "text/markdown",
|
|
629
|
+
load: async () => ({
|
|
630
|
+
content: [
|
|
631
|
+
{
|
|
632
|
+
type: "text",
|
|
633
|
+
text: [
|
|
634
|
+
"# Module Registry",
|
|
635
|
+
"",
|
|
636
|
+
"The Decaf MCP server aggregates prompts, resources, templates, and tools from every module under src/modules.",
|
|
637
|
+
"Validators ensure each module contains the canonical folder layout before the registry loads it.",
|
|
638
|
+
].join("\n"),
|
|
639
|
+
mimeType: "text/markdown",
|
|
640
|
+
},
|
|
641
|
+
],
|
|
642
|
+
}),
|
|
643
|
+
},
|
|
644
|
+
];
|
|
645
|
+
|
|
646
|
+
const templates$1 = [
|
|
647
|
+
{
|
|
648
|
+
id: "mcp.template.module-readme",
|
|
649
|
+
title: "Module README Template",
|
|
650
|
+
description: "Guides maintainers through documenting a new MCP-aware module.",
|
|
651
|
+
content: `# {{moduleName}} Module
|
|
652
|
+
|
|
653
|
+
## Purpose
|
|
654
|
+
Describe why this module exists and how assistants should use it.
|
|
655
|
+
|
|
656
|
+
## Assets
|
|
657
|
+
- Prompts: {{promptSummary}}
|
|
658
|
+
- Resources: {{resourceSummary}}
|
|
659
|
+
- Templates: {{templateSummary}}
|
|
660
|
+
- Tools: {{toolSummary}}
|
|
661
|
+
|
|
662
|
+
## Validation
|
|
663
|
+
Explain what needs to happen when this module changes (tests, docs, etc.).`,
|
|
664
|
+
placeholders: [
|
|
665
|
+
"moduleName",
|
|
666
|
+
"promptSummary",
|
|
667
|
+
"resourceSummary",
|
|
668
|
+
"templateSummary",
|
|
669
|
+
"toolSummary",
|
|
670
|
+
],
|
|
671
|
+
},
|
|
672
|
+
];
|
|
673
|
+
|
|
674
|
+
const describeModulesTool = {
|
|
675
|
+
name: "describe-modules",
|
|
676
|
+
description: "Summarize the purpose of Decaf MCP modules for assistant operators.",
|
|
677
|
+
// Minimal execute implementation to return a text result
|
|
678
|
+
execute: async () => "Modules contribute prompts, resources, templates, and tools that the registry exposes to FASTMCP clients.",
|
|
679
|
+
};
|
|
680
|
+
const tools$2 = [
|
|
681
|
+
{
|
|
682
|
+
id: "mcp.tool.describe-modules",
|
|
683
|
+
title: "Describe MCP Modules",
|
|
684
|
+
description: "Explains how module exports feed into the FASTMCP server.",
|
|
685
|
+
tool: describeModulesTool,
|
|
686
|
+
},
|
|
687
|
+
];
|
|
688
|
+
|
|
689
|
+
const modulePackage$1 = {
|
|
690
|
+
name: "mcp",
|
|
691
|
+
prompts: prompts$2,
|
|
692
|
+
resources: resources$2,
|
|
693
|
+
templates: templates$1,
|
|
694
|
+
tools: tools$2,
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
const prompts$1 = [
|
|
698
|
+
{
|
|
699
|
+
id: "_template.readme",
|
|
700
|
+
title: "Template README",
|
|
701
|
+
description: "A README prompt for module template",
|
|
702
|
+
load: () => "Template prompt content",
|
|
703
|
+
},
|
|
704
|
+
];
|
|
705
|
+
|
|
706
|
+
const resources$1 = [
|
|
707
|
+
{
|
|
708
|
+
id: "_template.repo",
|
|
709
|
+
name: "template repo",
|
|
710
|
+
description: "Template resource",
|
|
711
|
+
uri: "file:///tmp/template",
|
|
712
|
+
},
|
|
713
|
+
];
|
|
714
|
+
|
|
715
|
+
const templates = [
|
|
716
|
+
{
|
|
717
|
+
id: "_template.readme",
|
|
718
|
+
name: "template-readme",
|
|
719
|
+
description: "README guidance",
|
|
720
|
+
uriTemplate: "file:///tmp/template/README.md",
|
|
721
|
+
mimeType: "text/markdown",
|
|
722
|
+
},
|
|
723
|
+
];
|
|
724
|
+
|
|
725
|
+
const placeholderTool = {
|
|
726
|
+
name: "_template.tool",
|
|
727
|
+
description: "A placeholder tool",
|
|
728
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
729
|
+
execute: async (_input, _context) => "ok",
|
|
730
|
+
};
|
|
731
|
+
const tools$1 = [
|
|
732
|
+
{
|
|
733
|
+
id: "_template.tool",
|
|
734
|
+
title: "template tool",
|
|
735
|
+
description: "A placeholder tool",
|
|
736
|
+
tool: placeholderTool,
|
|
737
|
+
},
|
|
738
|
+
];
|
|
739
|
+
|
|
740
|
+
const modulePackage = {
|
|
741
|
+
name: "_template",
|
|
742
|
+
prompts: prompts$1,
|
|
743
|
+
resources: resources$1,
|
|
744
|
+
templates,
|
|
745
|
+
tools: tools$1,
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
// modulePackage objects may be declared with readonly arrays (as const). Cast to the mutable type expected by runtime APIs.
|
|
749
|
+
const modulePackages = [
|
|
750
|
+
modulePackage$2,
|
|
751
|
+
modulePackage$1,
|
|
752
|
+
modulePackage,
|
|
753
|
+
];
|
|
754
|
+
|
|
755
|
+
class ModuleRegistry {
|
|
756
|
+
// Defensive default: modulePackages may be undefined during circular imports
|
|
757
|
+
constructor(packages = Array.isArray(modulePackages)
|
|
758
|
+
? modulePackages
|
|
759
|
+
: []) {
|
|
760
|
+
this.packages = packages;
|
|
761
|
+
}
|
|
762
|
+
listPackages() {
|
|
763
|
+
return this.packages;
|
|
764
|
+
}
|
|
765
|
+
listPrompts() {
|
|
766
|
+
return this.collectAssets("prompts");
|
|
767
|
+
}
|
|
768
|
+
listResources() {
|
|
769
|
+
return this.collectAssets("resources");
|
|
770
|
+
}
|
|
771
|
+
listTemplates() {
|
|
772
|
+
return this.collectAssets("templates");
|
|
773
|
+
}
|
|
774
|
+
listTools() {
|
|
775
|
+
return this.collectAssets("tools");
|
|
776
|
+
}
|
|
777
|
+
collectAssets(key) {
|
|
778
|
+
const seen = new Map();
|
|
779
|
+
const aggregated = [];
|
|
780
|
+
for (const pkg of this.packages) {
|
|
781
|
+
if (pkg.status === "disabled")
|
|
782
|
+
continue;
|
|
783
|
+
for (const asset of pkg[key]) {
|
|
784
|
+
// asset.name is not guaranteed on all asset types; use type-safe fallback
|
|
785
|
+
const maybeName = asset.name;
|
|
786
|
+
const assetKey = (asset && (asset.id ?? maybeName)) || JSON.stringify(asset);
|
|
787
|
+
if (seen.has(assetKey)) {
|
|
788
|
+
const conflict = seen.get(assetKey);
|
|
789
|
+
throw new Error(`Duplicate ${key} id '${assetKey}' from modules ${conflict} and ${pkg.name}`);
|
|
790
|
+
}
|
|
791
|
+
seen.set(assetKey, pkg.name);
|
|
792
|
+
aggregated.push({ ...asset, provenance: pkg.name });
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
return aggregated;
|
|
796
|
+
}
|
|
20
797
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
798
|
+
const moduleRegistry = new ModuleRegistry();
|
|
799
|
+
|
|
800
|
+
const prompts = [];
|
|
801
|
+
const OBJECT_PROMPT_DEPENDENCIES = {
|
|
802
|
+
module: ["doc", "module"],
|
|
803
|
+
file: ["doc", "file"],
|
|
804
|
+
class: ["doc", "class"],
|
|
805
|
+
function: ["doc", "function"],
|
|
806
|
+
interface: ["doc", "interface"],
|
|
807
|
+
decorator: ["doc", "decorator"],
|
|
808
|
+
constant: ["doc", "constant"],
|
|
809
|
+
"bulk-docs": ["bulk-docs"],
|
|
810
|
+
"bulk-tests": ["bulk-tests"],
|
|
811
|
+
"update-readme": ["update-readme"],
|
|
812
|
+
"repo-setup": ["repo-setup"],
|
|
813
|
+
"release-notes": ["release-notes"],
|
|
814
|
+
"mcp-module": ["mcp-module"],
|
|
815
|
+
};
|
|
816
|
+
function getObjectPromptDependencies() {
|
|
817
|
+
return OBJECT_PROMPT_DEPENDENCIES;
|
|
818
|
+
}
|
|
819
|
+
function buildPrompts(repoPath) {
|
|
820
|
+
return [
|
|
821
|
+
{
|
|
822
|
+
name: "decoration-overview",
|
|
823
|
+
description: "High-level guidance on using the decoration library: key exports, decorators, and common workflows.",
|
|
824
|
+
load: async () => `You are assisting with the Decaf.ts decoration module located at ${repoPath}. Prefer using exported builders and decorators over ad-hoc patterns.\n\nProvide a concise, actionable overview of how to use the decoration APIs for extending and overriding behaviors.`,
|
|
825
|
+
},
|
|
826
|
+
];
|
|
827
|
+
}
|
|
828
|
+
function buildDocPrompts() {
|
|
829
|
+
const root = getWorkspaceRoot();
|
|
830
|
+
const fileBasedPrompts = discoverDocPrompts(root).map((prompt) => ({
|
|
831
|
+
name: `doc/${prompt.name}`,
|
|
832
|
+
description: prompt.description,
|
|
833
|
+
load: async () => prompt.content,
|
|
834
|
+
}));
|
|
835
|
+
const integrationPrompts = CLIENT_INTEGRATIONS.map((integration) => ({
|
|
836
|
+
name: `integration/${integration.id}`,
|
|
837
|
+
description: `${integration.display} integration guidance`,
|
|
838
|
+
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.`,
|
|
839
|
+
}));
|
|
840
|
+
return [...fileBasedPrompts, ...integrationPrompts];
|
|
841
|
+
}
|
|
842
|
+
function summarizePromptContent(prompt, headingPrefix) {
|
|
843
|
+
return [`## ${headingPrefix}`, "", prompt.content.trim()].join("\n");
|
|
844
|
+
}
|
|
845
|
+
function buildObjectPrompts() {
|
|
846
|
+
const root = getWorkspaceRoot();
|
|
847
|
+
const discovered = discoverDocPrompts(root);
|
|
848
|
+
const promptByName = new Map();
|
|
849
|
+
for (const prompt of discovered) {
|
|
850
|
+
promptByName.set(prompt.name, prompt);
|
|
851
|
+
}
|
|
852
|
+
const outputs = [];
|
|
853
|
+
for (const [objectType, dependencies] of Object.entries(OBJECT_PROMPT_DEPENDENCIES)) {
|
|
854
|
+
const existing = dependencies
|
|
855
|
+
.map((name) => promptByName.get(name))
|
|
856
|
+
.filter((prompt) => Boolean(prompt));
|
|
857
|
+
if (!existing.length)
|
|
858
|
+
continue;
|
|
859
|
+
outputs.push({
|
|
860
|
+
name: `codex/${objectType}`,
|
|
861
|
+
description: `Guidance derived from .codex prompts for ${objectType} tasks.`,
|
|
862
|
+
load: async () => {
|
|
863
|
+
const sections = existing.map((prompt) => summarizePromptContent(prompt, toTitleCase(prompt.name)));
|
|
864
|
+
return [`# Codex guidance for ${objectType}`, "", ...sections].join("\n");
|
|
865
|
+
},
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
return outputs.sort((a, b) => a.name.localeCompare(b.name));
|
|
869
|
+
}
|
|
870
|
+
function toInputPrompt(asset) {
|
|
871
|
+
const provenance = asset.provenance ? ` (module: ${asset.provenance})` : "";
|
|
872
|
+
return {
|
|
873
|
+
name: asset.id,
|
|
874
|
+
description: `${asset.description ?? asset.title}${provenance}`,
|
|
875
|
+
load: async () => asset.load(),
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
function buildModulePrompts() {
|
|
879
|
+
return moduleRegistry.listPrompts().map(toInputPrompt);
|
|
880
|
+
}
|
|
881
|
+
function refreshPrompts(repoPath) {
|
|
882
|
+
const docPrompts = buildDocPrompts();
|
|
883
|
+
const objectPrompts = buildObjectPrompts();
|
|
884
|
+
const repoPrompts = repoPath ? buildPrompts(repoPath) : [];
|
|
885
|
+
const modulePrompts = buildModulePrompts();
|
|
886
|
+
prompts.splice(0, prompts.length, ...docPrompts, ...objectPrompts, ...repoPrompts, ...modulePrompts);
|
|
887
|
+
return prompts;
|
|
888
|
+
}
|
|
889
|
+
function discoverDocPrompts(root) {
|
|
890
|
+
const discovered = [];
|
|
891
|
+
for (const directory of PROMPT_DIRECTORIES) {
|
|
892
|
+
const promptDir = path.join(root, directory);
|
|
893
|
+
// debug logging to help tests diagnose prompt discovery
|
|
894
|
+
console.debug("[discoverDocPrompts] checking", promptDir);
|
|
895
|
+
if (!fs.existsSync(promptDir) || !fs.statSync(promptDir).isDirectory()) {
|
|
896
|
+
continue;
|
|
897
|
+
}
|
|
898
|
+
for (const entry of fs.readdirSync(promptDir)) {
|
|
899
|
+
const fullPath = path.join(promptDir, entry);
|
|
900
|
+
if (!fs.statSync(fullPath).isFile())
|
|
901
|
+
continue;
|
|
902
|
+
const name = path.parse(entry).name;
|
|
903
|
+
const content = fs.readFileSync(fullPath, "utf8");
|
|
904
|
+
const title = toTitleCase(name.replace(/[-_]/g, " "));
|
|
905
|
+
const description = extractDescription(content, fullPath);
|
|
906
|
+
discovered.push({
|
|
907
|
+
name,
|
|
908
|
+
title,
|
|
909
|
+
description,
|
|
910
|
+
content,
|
|
911
|
+
absolutePath: fullPath,
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
const unique = new Map();
|
|
916
|
+
for (const prompt of discovered) {
|
|
917
|
+
if (!unique.has(prompt.name)) {
|
|
918
|
+
unique.set(prompt.name, prompt);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
return Array.from(unique.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
922
|
+
}
|
|
923
|
+
function selectPrompt(promptList, requestedName) {
|
|
924
|
+
const direct = promptList.find((prompt) => prompt.name === requestedName);
|
|
925
|
+
if (direct)
|
|
926
|
+
return direct;
|
|
927
|
+
const fallback = promptList.find((prompt) => prompt.name === DEFAULT_PROMPT_NAME);
|
|
928
|
+
if (fallback)
|
|
929
|
+
return fallback;
|
|
930
|
+
if (!promptList.length) {
|
|
931
|
+
throw new Error("No documentation prompts available");
|
|
932
|
+
}
|
|
933
|
+
return promptList[0];
|
|
934
|
+
}
|
|
935
|
+
function buildDocumentationPayload({ filePath, fileContent, prompt, includePrompt, includeCode, includeMetadata, additionalContext, }) {
|
|
936
|
+
const sections = [];
|
|
937
|
+
if (includeMetadata) {
|
|
938
|
+
sections.push(`# Documentation Request\n- prompt: ${prompt.name}\n- file: ${filePath}`);
|
|
939
|
+
}
|
|
940
|
+
if (includePrompt) {
|
|
941
|
+
sections.push(`## Prompt Guidance (${prompt.title})\n\n${prompt.content.trim()}`);
|
|
942
|
+
}
|
|
943
|
+
if (additionalContext?.trim()) {
|
|
944
|
+
sections.push(`## Additional Context\n\n${additionalContext.trim()}`);
|
|
945
|
+
}
|
|
946
|
+
if (includeCode) {
|
|
947
|
+
sections.push(`## Source\n\n\`\`\`${inferLanguageFromPath(filePath)}\n${fileContent}\n\`\`\``);
|
|
948
|
+
}
|
|
949
|
+
return {
|
|
950
|
+
content: [
|
|
951
|
+
{
|
|
952
|
+
type: "text",
|
|
953
|
+
text: sections.join("\n\n"),
|
|
954
|
+
},
|
|
955
|
+
],
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
function extractDescription(content, filePath) {
|
|
959
|
+
const firstLine = content
|
|
960
|
+
.split(/\r?\n/)
|
|
961
|
+
.map((line) => line.trim())
|
|
962
|
+
.find((line) => line.length > 0);
|
|
963
|
+
return (firstLine?.slice(0, 240) ??
|
|
964
|
+
`Documentation prompt loaded from ${path.basename(filePath)}`);
|
|
965
|
+
}
|
|
966
|
+
function toTitleCase(value) {
|
|
967
|
+
return value
|
|
968
|
+
.split(/\s+/)
|
|
969
|
+
.filter(Boolean)
|
|
970
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
|
|
971
|
+
.join(" ");
|
|
972
|
+
}
|
|
973
|
+
function inferLanguageFromPath(filePath) {
|
|
974
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
975
|
+
switch (extension) {
|
|
976
|
+
case ".ts":
|
|
977
|
+
case ".tsx":
|
|
978
|
+
return "ts";
|
|
979
|
+
case ".js":
|
|
980
|
+
case ".jsx":
|
|
981
|
+
return "js";
|
|
982
|
+
case ".json":
|
|
983
|
+
return "json";
|
|
984
|
+
case ".md":
|
|
985
|
+
return "md";
|
|
986
|
+
default:
|
|
987
|
+
return "text";
|
|
25
988
|
}
|
|
26
989
|
}
|
|
27
990
|
|
|
991
|
+
const promptList = prompts;
|
|
992
|
+
function loadPrompts(repoPath) {
|
|
993
|
+
return refreshPrompts(repoPath);
|
|
994
|
+
}
|
|
995
|
+
|
|
28
996
|
function escapeRegExp(value) {
|
|
29
997
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
30
998
|
}
|
|
@@ -249,224 +1217,522 @@ const decoratorTools = {
|
|
|
249
1217
|
const functionFile = path.join(args.dir, `${args.name}.ts`);
|
|
250
1218
|
ensureDirectory(functionFile);
|
|
251
1219
|
fs.writeFileSync(functionFile, `export function ${args.name}(value: string): string {\n return value.split('').reverse().join('');\n}\n`);
|
|
252
|
-
let registerFile;
|
|
253
|
-
if (args.registerDir) {
|
|
254
|
-
registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
|
|
255
|
-
ensureDirectory(registerFile);
|
|
256
|
-
fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
|
|
257
|
-
}
|
|
258
|
-
return { functionFile, registerFile };
|
|
259
|
-
},
|
|
260
|
-
},
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
const WORKSPACE_ROOT_ENV = "MCP_WORKSPACE_ROOT";
|
|
264
|
-
const PROMPT_DIRECTORIES = [".code/prompts", ".codex/prompts"];
|
|
265
|
-
const DEFAULT_PROMPT_NAME = "doc";
|
|
266
|
-
const CLIENT_INTEGRATIONS = [
|
|
267
|
-
{
|
|
268
|
-
id: "vscode",
|
|
269
|
-
display: "Visual Studio Code",
|
|
270
|
-
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.",
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
id: "cursor",
|
|
274
|
-
display: "Cursor",
|
|
275
|
-
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.",
|
|
276
|
-
},
|
|
277
|
-
{
|
|
278
|
-
id: "copilot",
|
|
279
|
-
display: "GitHub Copilot",
|
|
280
|
-
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.",
|
|
1220
|
+
let registerFile;
|
|
1221
|
+
if (args.registerDir) {
|
|
1222
|
+
registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
|
|
1223
|
+
ensureDirectory(registerFile);
|
|
1224
|
+
fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
|
|
1225
|
+
}
|
|
1226
|
+
return { functionFile, registerFile };
|
|
1227
|
+
},
|
|
281
1228
|
},
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
promptName: z.string().optional(),
|
|
287
|
-
includePrompt: z.boolean().default(true),
|
|
288
|
-
includeCode: z.boolean().default(true),
|
|
289
|
-
includeMetadata: z.boolean().default(true),
|
|
290
|
-
additionalContext: z.string().optional(),
|
|
291
|
-
encoding: z.string().default("utf8"),
|
|
292
|
-
})
|
|
293
|
-
.strict();
|
|
294
|
-
const codeChangeSchema = z
|
|
295
|
-
.object({
|
|
296
|
-
filePath: z.string().min(1, "filePath is required"),
|
|
297
|
-
patch: z.string().min(1, "patch is required"),
|
|
298
|
-
dryRun: z.boolean().default(false),
|
|
299
|
-
showDiff: z.boolean().default(true),
|
|
300
|
-
diffContext: z.number().int().min(0).max(100).default(3),
|
|
301
|
-
encoding: z.string().default("utf8"),
|
|
302
|
-
})
|
|
303
|
-
.strict();
|
|
304
|
-
let workspaceRoot = initializeWorkspaceRoot();
|
|
305
|
-
let userErrorCtor;
|
|
306
|
-
class WorkspaceError extends Error {
|
|
307
|
-
constructor(message) {
|
|
308
|
-
super(message);
|
|
309
|
-
this.name = "WorkspaceError";
|
|
310
|
-
}
|
|
1229
|
+
};
|
|
1230
|
+
|
|
1231
|
+
function relativeFiles(root, files) {
|
|
1232
|
+
return files.map((file) => path.relative(root, file)).sort();
|
|
311
1233
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
1234
|
+
function collectPromptSections(names) {
|
|
1235
|
+
const root = getWorkspaceRoot();
|
|
1236
|
+
const promptIndex = new Map(discoverDocPrompts(root).map((prompt) => [prompt.name, prompt]));
|
|
1237
|
+
return names
|
|
1238
|
+
.map((name) => promptIndex.get(name))
|
|
1239
|
+
.filter((prompt) => Boolean(prompt))
|
|
1240
|
+
.map((prompt) => ({
|
|
1241
|
+
name: prompt.name,
|
|
1242
|
+
title: prompt.title,
|
|
1243
|
+
description: prompt.description,
|
|
1244
|
+
content: prompt.content,
|
|
1245
|
+
absolutePath: prompt.absolutePath,
|
|
1246
|
+
}));
|
|
1247
|
+
}
|
|
1248
|
+
function parseTaskLines(content) {
|
|
1249
|
+
return content
|
|
1250
|
+
.split(/\r?\n/)
|
|
1251
|
+
.map((line) => line.trim())
|
|
1252
|
+
.filter((line) => /^task\s+\d+/i.test(line));
|
|
1253
|
+
}
|
|
1254
|
+
function computeCoverageFromFinal(coveragePath) {
|
|
1255
|
+
const payload = JSON.parse(fs.readFileSync(coveragePath, "utf8"));
|
|
1256
|
+
const totals = {
|
|
1257
|
+
statements: { covered: 0, total: 0 },
|
|
1258
|
+
functions: { covered: 0, total: 0 },
|
|
1259
|
+
branches: { covered: 0, total: 0 },
|
|
1260
|
+
};
|
|
1261
|
+
const files = Object.entries(payload).map(([filePath, info]) => {
|
|
1262
|
+
const statementCounts = Object.values(info.s);
|
|
1263
|
+
const functionCounts = Object.values(info.f);
|
|
1264
|
+
const branchCounts = Object.values(info.b).flatMap((value) => Array.isArray(value) ? value : [value]);
|
|
1265
|
+
const statementTotal = statementCounts.length;
|
|
1266
|
+
const functionTotal = functionCounts.length;
|
|
1267
|
+
const branchTotal = branchCounts.length;
|
|
1268
|
+
const statementCovered = statementCounts.filter((count) => count > 0).length;
|
|
1269
|
+
const functionCovered = functionCounts.filter((count) => count > 0).length;
|
|
1270
|
+
const branchCovered = branchCounts.filter((count) => count > 0).length;
|
|
1271
|
+
totals.statements.covered += statementCovered;
|
|
1272
|
+
totals.statements.total += statementTotal;
|
|
1273
|
+
totals.functions.covered += functionCovered;
|
|
1274
|
+
totals.functions.total += functionTotal;
|
|
1275
|
+
totals.branches.covered += branchCovered;
|
|
1276
|
+
totals.branches.total += branchTotal;
|
|
1277
|
+
const pct = (covered, total) => total === 0 ? 100 : Number(((covered / total) * 100).toFixed(2));
|
|
1278
|
+
return {
|
|
1279
|
+
path: filePath,
|
|
1280
|
+
statements: pct(statementCovered, statementTotal),
|
|
1281
|
+
functions: pct(functionCovered, functionTotal),
|
|
1282
|
+
branches: pct(branchCovered, branchTotal),
|
|
1283
|
+
};
|
|
1284
|
+
});
|
|
1285
|
+
const pct = (covered, total) => total === 0 ? 100 : Number(((covered / total) * 100).toFixed(2));
|
|
1286
|
+
return {
|
|
1287
|
+
totals: {
|
|
1288
|
+
statements: {
|
|
1289
|
+
...totals.statements,
|
|
1290
|
+
pct: pct(totals.statements.covered, totals.statements.total),
|
|
1291
|
+
},
|
|
1292
|
+
functions: {
|
|
1293
|
+
...totals.functions,
|
|
1294
|
+
pct: pct(totals.functions.covered, totals.functions.total),
|
|
1295
|
+
},
|
|
1296
|
+
branches: {
|
|
1297
|
+
...totals.branches,
|
|
1298
|
+
pct: pct(totals.branches.covered, totals.branches.total),
|
|
1299
|
+
},
|
|
1300
|
+
},
|
|
1301
|
+
files,
|
|
1302
|
+
};
|
|
1303
|
+
}
|
|
1304
|
+
function normalizePromptSections(sections) {
|
|
1305
|
+
return sections.map((section) => ({
|
|
1306
|
+
name: section.name,
|
|
1307
|
+
title: section.title,
|
|
1308
|
+
tasks: parseTaskLines(section.content),
|
|
1309
|
+
content: section.content,
|
|
1310
|
+
}));
|
|
1311
|
+
}
|
|
1312
|
+
async function resolveRepoRoot(basePath) {
|
|
1313
|
+
const root = getWorkspaceRoot();
|
|
1314
|
+
try {
|
|
1315
|
+
return resolveInWorkspace(root, basePath);
|
|
1316
|
+
}
|
|
1317
|
+
catch (error) {
|
|
1318
|
+
if (error instanceof WorkspaceError) {
|
|
1319
|
+
await throwUserError(error.message);
|
|
326
1320
|
}
|
|
1321
|
+
throw error;
|
|
327
1322
|
}
|
|
328
|
-
return userErrorCtor;
|
|
329
1323
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const documentCodeTool = {
|
|
335
|
-
annotations: {
|
|
336
|
-
idempotentHint: true,
|
|
337
|
-
openWorldHint: false,
|
|
338
|
-
readOnlyHint: true,
|
|
339
|
-
title: "Document Source File",
|
|
340
|
-
},
|
|
341
|
-
description: "Generate documentation guidance for a file by combining repository prompts with the target source code.",
|
|
1324
|
+
const documentObjectTool = {
|
|
1325
|
+
name: "document-object",
|
|
1326
|
+
description: "Create a documentation plan for a specific object type using .codex prompts and repository analysis.",
|
|
1327
|
+
parameters: documentObjectSchema,
|
|
342
1328
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
343
1329
|
execute: async (input, _context) => {
|
|
344
|
-
const args =
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
1330
|
+
const args = documentObjectSchema.parse(input);
|
|
1331
|
+
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
1332
|
+
const dependencies = getObjectPromptDependencies()[args.objectType] ?? [];
|
|
1333
|
+
if (!dependencies.length) {
|
|
1334
|
+
await throwUserError(`No prompt guidance configured for object type ${args.objectType}`);
|
|
349
1335
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
1336
|
+
const sections = normalizePromptSections(collectPromptSections(dependencies));
|
|
1337
|
+
const srcDir = path.join(repoRoot, "src");
|
|
1338
|
+
const testDir = path.join(repoRoot, "tests");
|
|
1339
|
+
const sourceFiles = fs.existsSync(srcDir)
|
|
1340
|
+
? listFilesRecursive(srcDir, isSourceFile)
|
|
1341
|
+
: [];
|
|
1342
|
+
const testFiles = fs.existsSync(testDir)
|
|
1343
|
+
? listFilesRecursive(testDir, (file) => isSourceFile(file) && isTestFile(file))
|
|
1344
|
+
: [];
|
|
1345
|
+
let targetFileContent;
|
|
1346
|
+
if (args.targetFile) {
|
|
1347
|
+
try {
|
|
1348
|
+
const absolute = resolveInWorkspace(repoRoot, args.targetFile);
|
|
1349
|
+
targetFileContent = readFileSafe(absolute) ?? undefined;
|
|
1350
|
+
}
|
|
1351
|
+
catch (error) {
|
|
1352
|
+
if (error instanceof WorkspaceError) {
|
|
1353
|
+
await throwUserError(error.message);
|
|
1354
|
+
}
|
|
1355
|
+
throw error;
|
|
353
1356
|
}
|
|
354
|
-
/* istanbul ignore next */
|
|
355
|
-
throw error;
|
|
356
|
-
}
|
|
357
|
-
if (!fs.existsSync(filePath)) {
|
|
358
|
-
return throwUserError(`Cannot document missing file at ${args.filePath}`);
|
|
359
|
-
}
|
|
360
|
-
const fileContent = fs.readFileSync(filePath, {
|
|
361
|
-
encoding: args.encoding,
|
|
362
|
-
});
|
|
363
|
-
const prompts = discoverDocPrompts(root);
|
|
364
|
-
if (!prompts.length) {
|
|
365
|
-
return throwUserError("No documentation prompts found under .code/prompts or .codex/prompts");
|
|
366
1357
|
}
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
1358
|
+
const payload = {
|
|
1359
|
+
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
1360
|
+
objectType: args.objectType,
|
|
1361
|
+
targetFile: args.targetFile,
|
|
1362
|
+
guidance: sections,
|
|
1363
|
+
files: {
|
|
1364
|
+
source: relativeFiles(repoRoot, sourceFiles),
|
|
1365
|
+
tests: relativeFiles(repoRoot, testFiles),
|
|
1366
|
+
},
|
|
1367
|
+
targetFileContent: args.includeContent ? targetFileContent : undefined,
|
|
1368
|
+
};
|
|
1369
|
+
return {
|
|
1370
|
+
content: [
|
|
1371
|
+
{
|
|
1372
|
+
type: "text",
|
|
1373
|
+
text: JSON.stringify(payload, null, 2),
|
|
1374
|
+
},
|
|
1375
|
+
],
|
|
1376
|
+
};
|
|
377
1377
|
},
|
|
378
|
-
name: "document-code",
|
|
379
|
-
parameters: documentCodeSchema,
|
|
380
1378
|
};
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
openWorldHint: false,
|
|
386
|
-
readOnlyHint: false,
|
|
387
|
-
title: "Apply Code Patch",
|
|
388
|
-
},
|
|
389
|
-
description: "Apply a unified diff patch to a workspace file with optional dry-run validation and diff preview.",
|
|
1379
|
+
const coverageEnforcerTool = {
|
|
1380
|
+
name: "ensure-test-coverage",
|
|
1381
|
+
description: "Run the configured coverage command and report whether the target percentage is met, highlighting weak files.",
|
|
1382
|
+
parameters: coverageTaskSchema,
|
|
390
1383
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
391
1384
|
execute: async (input, _context) => {
|
|
392
|
-
const args =
|
|
393
|
-
const
|
|
394
|
-
let filePath;
|
|
395
|
-
try {
|
|
396
|
-
filePath = resolveInWorkspace(root, args.filePath);
|
|
397
|
-
}
|
|
398
|
-
catch (error) {
|
|
399
|
-
if (error instanceof WorkspaceError) {
|
|
400
|
-
return throwUserError(error.message);
|
|
401
|
-
}
|
|
402
|
-
throw error;
|
|
403
|
-
}
|
|
404
|
-
const original = fs.existsSync(filePath)
|
|
405
|
-
? fs.readFileSync(filePath, args.encoding)
|
|
406
|
-
: "";
|
|
407
|
-
let patched;
|
|
408
|
-
try {
|
|
409
|
-
patched = applyPatch(original, args.patch);
|
|
410
|
-
}
|
|
411
|
-
catch (error) {
|
|
412
|
-
return throwUserError(`Failed to apply provided patch to ${args.filePath}: ${error instanceof Error ? error.message : error}`);
|
|
413
|
-
}
|
|
414
|
-
/* istanbul ignore next */
|
|
415
|
-
if (patched === false) {
|
|
416
|
-
return throwUserError(`Failed to apply provided patch to ${args.filePath}`);
|
|
417
|
-
}
|
|
1385
|
+
const args = coverageTaskSchema.parse(input);
|
|
1386
|
+
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
418
1387
|
if (!args.dryRun) {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
1388
|
+
const env = {
|
|
1389
|
+
...process.env,
|
|
1390
|
+
USE_WATCHMAN: "false",
|
|
1391
|
+
WATCHMAN_DISABLE: "1",
|
|
1392
|
+
JEST_DISABLE_WATCHMAN: "1",
|
|
1393
|
+
};
|
|
1394
|
+
const result = spawnSync("npm", ["run", "coverage", "--", "--watchman=false", "--runInBand"], { cwd: repoRoot, env, encoding: "utf8" });
|
|
1395
|
+
if (result.status !== 0) {
|
|
1396
|
+
const message = result.stderr || result.stdout || "Coverage command failed";
|
|
1397
|
+
await throwUserError(message.trim());
|
|
1398
|
+
}
|
|
423
1399
|
}
|
|
424
|
-
|
|
425
|
-
|
|
1400
|
+
const coveragePath = path.join(repoRoot, "workdocs", "reports", "coverage", "coverage-final.json");
|
|
1401
|
+
if (!fs.existsSync(coveragePath)) {
|
|
1402
|
+
await throwUserError(`Coverage report not found at ${path.relative(repoRoot, coveragePath)}`);
|
|
426
1403
|
}
|
|
427
|
-
const
|
|
1404
|
+
const summary = computeCoverageFromFinal(coveragePath);
|
|
1405
|
+
const meetsThreshold = summary.totals.statements.pct >= args.coverage &&
|
|
1406
|
+
summary.totals.functions.pct >= args.coverage &&
|
|
1407
|
+
summary.totals.branches.pct >= args.coverage;
|
|
1408
|
+
const weakest = [...summary.files]
|
|
1409
|
+
.sort((a, b) => a.statements - b.statements)
|
|
1410
|
+
.slice(0, 10);
|
|
1411
|
+
const guidance = normalizePromptSections(collectPromptSections(["bulk-tests"]));
|
|
1412
|
+
const payload = {
|
|
1413
|
+
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
1414
|
+
target: args.coverage,
|
|
1415
|
+
meetsThreshold,
|
|
1416
|
+
totals: summary.totals,
|
|
1417
|
+
weakest,
|
|
1418
|
+
guidance,
|
|
1419
|
+
};
|
|
428
1420
|
return {
|
|
429
1421
|
content: [
|
|
430
1422
|
{
|
|
431
1423
|
type: "text",
|
|
432
|
-
text:
|
|
1424
|
+
text: JSON.stringify(payload, null, 2),
|
|
433
1425
|
},
|
|
1426
|
+
],
|
|
1427
|
+
};
|
|
1428
|
+
},
|
|
1429
|
+
};
|
|
1430
|
+
const readmeImprovementTool = {
|
|
1431
|
+
name: "improve-readme",
|
|
1432
|
+
description: "Summarize required steps to refresh README and workdocs content using .codex guidance and repository analysis.",
|
|
1433
|
+
parameters: readmeImprovementSchema,
|
|
1434
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1435
|
+
execute: async (input, _context) => {
|
|
1436
|
+
const args = readmeImprovementSchema.parse(input);
|
|
1437
|
+
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
1438
|
+
const analysis = analyzeRepo(repoRoot);
|
|
1439
|
+
const modules = analysis.files
|
|
1440
|
+
.filter((file) => /index\.ts$/.test(file))
|
|
1441
|
+
.map((file) => path.relative(repoRoot, file));
|
|
1442
|
+
const promptSections = normalizePromptSections(collectPromptSections(["update-readme", "doc", "module"]));
|
|
1443
|
+
const testExamples = Object.keys(analysis.tests ?? {});
|
|
1444
|
+
const examples = args.includeExamples ? testExamples.slice(0, 20) : [];
|
|
1445
|
+
const payload = {
|
|
1446
|
+
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
1447
|
+
summary: {
|
|
1448
|
+
modules,
|
|
1449
|
+
totalSourceFiles: analysis.files.length,
|
|
1450
|
+
totalTestFiles: analysis.testFiles.length,
|
|
1451
|
+
hasReadme: Boolean(analysis.readme),
|
|
1452
|
+
},
|
|
1453
|
+
guidance: promptSections,
|
|
1454
|
+
suggestedExamples: examples,
|
|
1455
|
+
};
|
|
1456
|
+
return {
|
|
1457
|
+
content: [
|
|
434
1458
|
{
|
|
435
1459
|
type: "text",
|
|
436
|
-
text:
|
|
1460
|
+
text: JSON.stringify(payload, null, 2),
|
|
437
1461
|
},
|
|
438
1462
|
],
|
|
439
1463
|
};
|
|
440
1464
|
},
|
|
441
|
-
name: "apply-code-change",
|
|
442
|
-
parameters: codeChangeSchema,
|
|
443
1465
|
};
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
1466
|
+
|
|
1467
|
+
const DEFAULT_PLACEHOLDERS = {
|
|
1468
|
+
prompts: `export const promptList = [
|
|
1469
|
+
{
|
|
1470
|
+
id: "example-prompt",
|
|
1471
|
+
title: "Example prompt",
|
|
1472
|
+
description: "A placeholder prompt created by scaffoldModule",
|
|
1473
|
+
content: "Describe the task for the assistant...",
|
|
1474
|
+
absolutePath: __filename,
|
|
1475
|
+
},
|
|
1476
|
+
] as const;
|
|
1477
|
+
`,
|
|
1478
|
+
resources: `export const resources = [
|
|
1479
|
+
{
|
|
1480
|
+
id: "example-resource",
|
|
1481
|
+
name: "Example Resource",
|
|
1482
|
+
description: "A placeholder resource created by scaffoldModule",
|
|
1483
|
+
uri: "file://placeholder",
|
|
1484
|
+
absolutePath: __filename,
|
|
1485
|
+
},
|
|
1486
|
+
] as const;
|
|
1487
|
+
`,
|
|
1488
|
+
templates: `export const templates = [
|
|
1489
|
+
{
|
|
1490
|
+
name: "example-template",
|
|
1491
|
+
description: "A placeholder template created by scaffoldModule",
|
|
1492
|
+
uriTemplate: "file://template/{path}",
|
|
1493
|
+
mimeType: "text/plain",
|
|
1494
|
+
},
|
|
1495
|
+
] as const;
|
|
1496
|
+
`,
|
|
1497
|
+
tools: `export const toolList = [
|
|
1498
|
+
{
|
|
1499
|
+
id: "example-tool",
|
|
1500
|
+
name: "example-tool",
|
|
1501
|
+
description: "A placeholder tool created by scaffoldModule",
|
|
1502
|
+
run: async () => ({ result: "placeholder" }),
|
|
1503
|
+
},
|
|
1504
|
+
] as const;
|
|
1505
|
+
`,
|
|
448
1506
|
};
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
1507
|
+
/**
|
|
1508
|
+
* Create a module scaffold under repoRoot/src/modules/<moduleName>
|
|
1509
|
+
* Returns created files list.
|
|
1510
|
+
*/
|
|
1511
|
+
function scaffoldModule(repoRoot, moduleName) {
|
|
1512
|
+
if (!repoRoot)
|
|
1513
|
+
throw new Error("repoRoot is required");
|
|
1514
|
+
if (!moduleName)
|
|
1515
|
+
throw new Error("moduleName is required");
|
|
1516
|
+
const modulePath = path.join(repoRoot, "src", "modules", moduleName);
|
|
1517
|
+
const createdFiles = [];
|
|
1518
|
+
const subfolders = ["prompts", "resources", "templates", "tools"];
|
|
1519
|
+
for (const folder of subfolders) {
|
|
1520
|
+
const folderPath = path.join(modulePath, folder);
|
|
1521
|
+
fs.mkdirSync(folderPath, { recursive: true });
|
|
1522
|
+
const indexPath = path.join(folderPath, "index.ts");
|
|
1523
|
+
// if file exists, skip writing
|
|
1524
|
+
if (!fs.existsSync(indexPath)) {
|
|
1525
|
+
// insert __filename for absolutePath in placeholders
|
|
1526
|
+
const content = DEFAULT_PLACEHOLDERS[folder].replace(/__filename/g, JSON.stringify(indexPath));
|
|
1527
|
+
fs.writeFileSync(indexPath, content, { encoding: "utf8" });
|
|
1528
|
+
createdFiles.push(indexPath);
|
|
1529
|
+
}
|
|
452
1530
|
}
|
|
453
|
-
|
|
454
|
-
|
|
1531
|
+
return { modulePath, createdFiles };
|
|
1532
|
+
}
|
|
1533
|
+
// CLI support when required directly via ts-node registration
|
|
1534
|
+
if (require.main === module) {
|
|
1535
|
+
const [, , moduleName] = process.argv;
|
|
1536
|
+
if (!moduleName) {
|
|
1537
|
+
console.error("Usage: scaffold-module <module-name>");
|
|
1538
|
+
process.exit(1);
|
|
455
1539
|
}
|
|
456
|
-
|
|
457
|
-
|
|
1540
|
+
try {
|
|
1541
|
+
const res = scaffoldModule(process.cwd(), moduleName);
|
|
1542
|
+
console.log("Scaffolded module:", res.modulePath);
|
|
1543
|
+
for (const f of res.createdFiles)
|
|
1544
|
+
console.log(" created:", f);
|
|
1545
|
+
process.exit(0);
|
|
1546
|
+
}
|
|
1547
|
+
catch (err) {
|
|
1548
|
+
console.error(err && err.message ? err.message : err);
|
|
1549
|
+
process.exit(2);
|
|
458
1550
|
}
|
|
459
|
-
return mcp;
|
|
460
1551
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
1552
|
+
|
|
1553
|
+
// New tool: generate-mcp-module
|
|
1554
|
+
z.object({
|
|
1555
|
+
repoPath: z.string().optional().default("."),
|
|
1556
|
+
moduleName: z.string().optional(),
|
|
1557
|
+
includeDocs: z.boolean().default(true),
|
|
1558
|
+
});
|
|
1559
|
+
|
|
1560
|
+
const codexToolList = [
|
|
1561
|
+
documentObjectTool,
|
|
1562
|
+
coverageEnforcerTool,
|
|
1563
|
+
readmeImprovementTool,
|
|
1564
|
+
];
|
|
1565
|
+
const moduleToolList = moduleRegistry.listTools().map((asset) => asset.tool);
|
|
1566
|
+
const toolList = [...toolList$1, ...codexToolList, ...moduleToolList];
|
|
1567
|
+
const [analyzeRepositoryTool, enumerateCapabilitiesTool, planFeatureTool, documentCodeToolRef, applyCodeChangeToolRef,] = toolList$1;
|
|
1568
|
+
const tools = {
|
|
1569
|
+
analyzeRepositoryTool,
|
|
1570
|
+
enumerateCapabilitiesTool,
|
|
1571
|
+
planFeatureTool,
|
|
1572
|
+
documentCodeTool: documentCodeToolRef,
|
|
1573
|
+
applyCodeChangeTool: applyCodeChangeToolRef,
|
|
1574
|
+
documentObjectTool,
|
|
1575
|
+
coverageEnforcerTool,
|
|
1576
|
+
readmeImprovementTool,
|
|
1577
|
+
...decoratorTools,
|
|
1578
|
+
};
|
|
1579
|
+
|
|
1580
|
+
function toResource(asset) {
|
|
1581
|
+
return {
|
|
1582
|
+
name: asset.id,
|
|
1583
|
+
uri: asset.uri,
|
|
1584
|
+
description: asset.description ?? asset.title,
|
|
1585
|
+
mimeType: asset.mimeType,
|
|
1586
|
+
load: async () => {
|
|
1587
|
+
const res = await asset.load();
|
|
1588
|
+
// asset.load may return a ContentResult or a Promise of ContentResult; ensure we return ResourceResult-like object
|
|
1589
|
+
if (res?.content) {
|
|
1590
|
+
const cr = res;
|
|
1591
|
+
// If ContentResult, convert to simple text result expected by Resource.load consumers
|
|
1592
|
+
return {
|
|
1593
|
+
text: Array.isArray(cr.content)
|
|
1594
|
+
? cr.content.map((c) => c.text).join("\n")
|
|
1595
|
+
: String(cr),
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
// fallback for objects with text
|
|
1599
|
+
return res;
|
|
1600
|
+
},
|
|
1601
|
+
};
|
|
465
1602
|
}
|
|
466
|
-
function
|
|
467
|
-
return
|
|
1603
|
+
function buildModuleResources() {
|
|
1604
|
+
return moduleRegistry.listResources().map(toResource);
|
|
1605
|
+
}
|
|
1606
|
+
const resources = [
|
|
1607
|
+
{
|
|
1608
|
+
name: "codex-prompt-index",
|
|
1609
|
+
uri: "codex://prompts/index",
|
|
1610
|
+
description: "Enumerate available .codex prompt files with titles and descriptions.",
|
|
1611
|
+
mimeType: "application/json",
|
|
1612
|
+
load: async () => {
|
|
1613
|
+
const root = getWorkspaceRoot();
|
|
1614
|
+
const prompts = discoverDocPrompts(root).map((prompt) => ({
|
|
1615
|
+
name: prompt.name,
|
|
1616
|
+
title: prompt.title,
|
|
1617
|
+
description: prompt.description,
|
|
1618
|
+
path: prompt.absolutePath,
|
|
1619
|
+
}));
|
|
1620
|
+
return {
|
|
1621
|
+
text: JSON.stringify({ prompts }, null, 2),
|
|
1622
|
+
mimeType: "application/json",
|
|
1623
|
+
};
|
|
1624
|
+
},
|
|
1625
|
+
},
|
|
1626
|
+
{
|
|
1627
|
+
name: "codex-object-prompts",
|
|
1628
|
+
uri: "codex://prompts/objects",
|
|
1629
|
+
description: "Provides the resolved prompt content for each documented object workflow.",
|
|
1630
|
+
mimeType: "application/json",
|
|
1631
|
+
load: async () => {
|
|
1632
|
+
const entries = await Promise.all(buildObjectPrompts().map(async (prompt) => ({
|
|
1633
|
+
name: prompt.name,
|
|
1634
|
+
description: prompt.description,
|
|
1635
|
+
content: await prompt.load({}),
|
|
1636
|
+
})));
|
|
1637
|
+
return {
|
|
1638
|
+
text: JSON.stringify({ prompts: entries }, null, 2),
|
|
1639
|
+
mimeType: "application/json",
|
|
1640
|
+
};
|
|
1641
|
+
},
|
|
1642
|
+
},
|
|
1643
|
+
...buildModuleResources(),
|
|
1644
|
+
];
|
|
1645
|
+
|
|
1646
|
+
const codexPromptTemplates = [];
|
|
1647
|
+
function buildCodexPromptTemplates() {
|
|
1648
|
+
const root = getWorkspaceRoot();
|
|
1649
|
+
const templates = [
|
|
1650
|
+
{
|
|
1651
|
+
name: "codex-prompt",
|
|
1652
|
+
description: "Load a .codex prompt file by name (without extension) as markdown.",
|
|
1653
|
+
uriTemplate: "codex-prompt://{name}",
|
|
1654
|
+
mimeType: "text/markdown",
|
|
1655
|
+
arguments: [
|
|
1656
|
+
{
|
|
1657
|
+
name: "name",
|
|
1658
|
+
description: "Name of the prompt file inside .codex/prompts (without .md).",
|
|
1659
|
+
required: true,
|
|
1660
|
+
},
|
|
1661
|
+
],
|
|
1662
|
+
load: async ({ name }) => {
|
|
1663
|
+
const promptPath = resolveInWorkspace(root, path.join(".codex", "prompts", `${name}.md`));
|
|
1664
|
+
if (!fs.existsSync(promptPath)) {
|
|
1665
|
+
throw new Error(`Prompt .codex/prompts/${name}.md not found`);
|
|
1666
|
+
}
|
|
1667
|
+
const text = fs.readFileSync(promptPath, "utf8");
|
|
1668
|
+
return { text, uri: `codex-prompt:///${name}` };
|
|
1669
|
+
},
|
|
1670
|
+
},
|
|
1671
|
+
];
|
|
1672
|
+
codexPromptTemplates.splice(0, codexPromptTemplates.length, ...templates);
|
|
1673
|
+
return codexPromptTemplates;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
const decorationResourceTemplates = [];
|
|
1677
|
+
function makeLoader(type) {
|
|
1678
|
+
return async ({ path: relative }) => {
|
|
1679
|
+
const root = getWorkspaceRoot();
|
|
1680
|
+
const target = path.join(type, relative);
|
|
1681
|
+
const text = await readWorkspaceFile(root, target);
|
|
1682
|
+
return { text };
|
|
1683
|
+
};
|
|
1684
|
+
}
|
|
1685
|
+
function buildDecorationResourceTemplates() {
|
|
1686
|
+
const templates = [
|
|
1687
|
+
{
|
|
1688
|
+
name: "read-code-from-source",
|
|
1689
|
+
description: "Read a file from the <base_path>/src tree by relative path.",
|
|
1690
|
+
mimeType: "text/plain",
|
|
1691
|
+
uriTemplate: "from-source://src/{path}",
|
|
1692
|
+
arguments: [
|
|
1693
|
+
{
|
|
1694
|
+
name: "path",
|
|
1695
|
+
description: "Path under <base_path>/src to load, e.g. 'decoration/types.ts'",
|
|
1696
|
+
required: true,
|
|
1697
|
+
},
|
|
1698
|
+
],
|
|
1699
|
+
load: makeLoader("src"),
|
|
1700
|
+
},
|
|
1701
|
+
{
|
|
1702
|
+
name: "read-test-from-source",
|
|
1703
|
+
description: "Read a file from the <base_path>/tests tree by relative path.",
|
|
1704
|
+
mimeType: "text/plain",
|
|
1705
|
+
uriTemplate: "from-source://tests/{path}",
|
|
1706
|
+
arguments: [
|
|
1707
|
+
{
|
|
1708
|
+
name: "path",
|
|
1709
|
+
description: "Path under <base_path>/tests to load, e.g. 'decoration/tests/types.test.ts'",
|
|
1710
|
+
required: true,
|
|
1711
|
+
},
|
|
1712
|
+
],
|
|
1713
|
+
load: makeLoader("tests"),
|
|
1714
|
+
},
|
|
1715
|
+
{
|
|
1716
|
+
name: "read-doc-from-source",
|
|
1717
|
+
description: "Read a file from the <base_path>/workdocs tree by relative path.",
|
|
1718
|
+
mimeType: "text/plain",
|
|
1719
|
+
uriTemplate: "from-source://workdocs/{path}",
|
|
1720
|
+
arguments: [
|
|
1721
|
+
{
|
|
1722
|
+
name: "path",
|
|
1723
|
+
description: "Path under <base_path>/workdocs to load, e.g. 'decoration/workdocs/tutorials/for-developers.md'",
|
|
1724
|
+
required: true,
|
|
1725
|
+
},
|
|
1726
|
+
],
|
|
1727
|
+
load: makeLoader("workdocs"),
|
|
1728
|
+
},
|
|
1729
|
+
];
|
|
1730
|
+
decorationResourceTemplates.splice(0, decorationResourceTemplates.length, ...templates);
|
|
1731
|
+
return decorationResourceTemplates;
|
|
468
1732
|
}
|
|
469
|
-
|
|
1733
|
+
|
|
1734
|
+
const workspaceResourceTemplates = [];
|
|
1735
|
+
function buildWorkspaceResourceTemplates() {
|
|
470
1736
|
const root = getWorkspaceRoot();
|
|
471
1737
|
const sharedArguments = [
|
|
472
1738
|
{
|
|
@@ -475,7 +1741,7 @@ function buildResourceTemplates() {
|
|
|
475
1741
|
required: true,
|
|
476
1742
|
},
|
|
477
1743
|
];
|
|
478
|
-
|
|
1744
|
+
const templates = [
|
|
479
1745
|
{
|
|
480
1746
|
name: "vscode-workspace-file",
|
|
481
1747
|
description: "Expose workspace files to Visual Studio Code via vscode:// URIs",
|
|
@@ -483,8 +1749,14 @@ function buildResourceTemplates() {
|
|
|
483
1749
|
mimeType: "text/plain",
|
|
484
1750
|
arguments: sharedArguments,
|
|
485
1751
|
load: async (args) => {
|
|
486
|
-
|
|
487
|
-
|
|
1752
|
+
try {
|
|
1753
|
+
const text = await readWorkspaceFile(root, args.path);
|
|
1754
|
+
return { text: String(text) };
|
|
1755
|
+
}
|
|
1756
|
+
catch (err) {
|
|
1757
|
+
// propagate as-is for tests to assert errors
|
|
1758
|
+
throw err;
|
|
1759
|
+
}
|
|
488
1760
|
},
|
|
489
1761
|
},
|
|
490
1762
|
{
|
|
@@ -494,8 +1766,13 @@ function buildResourceTemplates() {
|
|
|
494
1766
|
mimeType: "text/plain",
|
|
495
1767
|
arguments: sharedArguments,
|
|
496
1768
|
load: async (args) => {
|
|
497
|
-
|
|
498
|
-
|
|
1769
|
+
try {
|
|
1770
|
+
const text = await readWorkspaceFile(root, args.path);
|
|
1771
|
+
return { text: String(text) };
|
|
1772
|
+
}
|
|
1773
|
+
catch (err) {
|
|
1774
|
+
throw err;
|
|
1775
|
+
}
|
|
499
1776
|
},
|
|
500
1777
|
},
|
|
501
1778
|
{
|
|
@@ -505,164 +1782,510 @@ function buildResourceTemplates() {
|
|
|
505
1782
|
mimeType: "text/plain",
|
|
506
1783
|
arguments: sharedArguments,
|
|
507
1784
|
load: async (args) => {
|
|
508
|
-
|
|
509
|
-
|
|
1785
|
+
try {
|
|
1786
|
+
const text = await readWorkspaceFile(root, args.path);
|
|
1787
|
+
return { text: String(text) };
|
|
1788
|
+
}
|
|
1789
|
+
catch (err) {
|
|
1790
|
+
throw err;
|
|
1791
|
+
}
|
|
510
1792
|
},
|
|
511
1793
|
},
|
|
512
1794
|
];
|
|
1795
|
+
workspaceResourceTemplates.splice(0, workspaceResourceTemplates.length, ...templates);
|
|
1796
|
+
return workspaceResourceTemplates;
|
|
513
1797
|
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
load: async () =>
|
|
1798
|
+
|
|
1799
|
+
function buildResourceTemplates() {
|
|
1800
|
+
const moduleTemplates = moduleRegistry.listTemplates().map((template) => ({
|
|
1801
|
+
name: template.id,
|
|
1802
|
+
description: template.description ?? template.title,
|
|
1803
|
+
mimeType: "text/markdown",
|
|
1804
|
+
uriTemplate: `module-template://${template.id}`,
|
|
1805
|
+
arguments: (template.placeholders ?? []).map((name) => ({
|
|
1806
|
+
name,
|
|
1807
|
+
description: `Value for ${name}`,
|
|
1808
|
+
required: true,
|
|
1809
|
+
})),
|
|
1810
|
+
load: async () => ({
|
|
1811
|
+
text: typeof template.content === "string"
|
|
1812
|
+
? template.content
|
|
1813
|
+
: `# ${template.description ?? template.title ?? template.id}\n\nNo template content available for ${template.id}`,
|
|
1814
|
+
}),
|
|
527
1815
|
}));
|
|
528
|
-
const
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
1816
|
+
const all = [
|
|
1817
|
+
...buildWorkspaceResourceTemplates(),
|
|
1818
|
+
...buildCodexPromptTemplates(),
|
|
1819
|
+
...buildDecorationResourceTemplates(),
|
|
1820
|
+
...moduleTemplates,
|
|
1821
|
+
];
|
|
1822
|
+
// Normalise all loaders to always return { text: string }
|
|
1823
|
+
function normaliseResult(res) {
|
|
1824
|
+
if (res == null)
|
|
1825
|
+
return { text: "" };
|
|
1826
|
+
if (typeof res === "string")
|
|
1827
|
+
return { text: res };
|
|
1828
|
+
if (typeof res.text === "string")
|
|
1829
|
+
return res;
|
|
1830
|
+
// handle legacy ContentResult shapes with content or content array
|
|
1831
|
+
if (Array.isArray(res.content)) {
|
|
1832
|
+
const parts = res.content
|
|
1833
|
+
.map((c) => (c && typeof c.text === "string" ? c.text : String(c)))
|
|
1834
|
+
.join("\n");
|
|
1835
|
+
return { text: parts };
|
|
1836
|
+
}
|
|
1837
|
+
if (res.content && typeof res.content.text === "string") {
|
|
1838
|
+
return { text: res.content.text };
|
|
1839
|
+
}
|
|
1840
|
+
// fallback: stringify
|
|
1841
|
+
try {
|
|
1842
|
+
return { text: JSON.stringify(res) };
|
|
1843
|
+
}
|
|
1844
|
+
catch {
|
|
1845
|
+
return { text: String(res) };
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
return all.map((t) => ({
|
|
1849
|
+
...t,
|
|
1850
|
+
load: async (args) => {
|
|
1851
|
+
const raw = await t.load(args);
|
|
1852
|
+
return normaliseResult(raw);
|
|
1853
|
+
},
|
|
532
1854
|
}));
|
|
533
|
-
return [...fileBasedPrompts, ...integrationPrompts];
|
|
534
1855
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
1856
|
+
const templateList = buildResourceTemplates();
|
|
1857
|
+
|
|
1858
|
+
/**
|
|
1859
|
+
* @const VERSION
|
|
1860
|
+
* @name VERSION
|
|
1861
|
+
* @description Represents the current version of the ts-workspace module.
|
|
1862
|
+
* @summary The actual version number is replaced during the build process.
|
|
1863
|
+
* @type {string}
|
|
1864
|
+
*/
|
|
1865
|
+
const VERSION$1 = "0.1.0";
|
|
1866
|
+
const PACKAGE_NAME$1 = "##PACKAGE_NAME##";
|
|
1867
|
+
try {
|
|
1868
|
+
Metadata.registerLibrary(PACKAGE_NAME$1, VERSION$1);
|
|
1869
|
+
}
|
|
1870
|
+
catch (error) {
|
|
1871
|
+
if (error instanceof Error && error.message.includes("already")) ;
|
|
1872
|
+
else {
|
|
1873
|
+
throw error;
|
|
542
1874
|
}
|
|
543
|
-
return resolved;
|
|
544
1875
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
1876
|
+
|
|
1877
|
+
function enrich(mcp) {
|
|
1878
|
+
const promptEntries = loadPrompts();
|
|
1879
|
+
for (const prompt of promptEntries) {
|
|
1880
|
+
mcp.addPrompt(prompt);
|
|
549
1881
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
1882
|
+
for (const tool of toolList) {
|
|
1883
|
+
mcp.addTool(tool);
|
|
1884
|
+
}
|
|
1885
|
+
const templates = buildResourceTemplates();
|
|
1886
|
+
for (const template of templates) {
|
|
1887
|
+
mcp.addResourceTemplate(template);
|
|
1888
|
+
}
|
|
1889
|
+
for (const resource of resources) {
|
|
1890
|
+
const addResource = mcp.addResource;
|
|
1891
|
+
if (typeof addResource === "function") {
|
|
1892
|
+
addResource.call(mcp, resource);
|
|
553
1893
|
}
|
|
554
|
-
/* istanbul ignore next */
|
|
555
|
-
throw error;
|
|
556
1894
|
}
|
|
1895
|
+
return mcp;
|
|
1896
|
+
}
|
|
1897
|
+
const PACKAGE_NAME = PACKAGE_NAME$1;
|
|
1898
|
+
const VERSION = VERSION$1;
|
|
1899
|
+
|
|
1900
|
+
// New: validation entrypoint for module structure
|
|
1901
|
+
const REQUIRED_SUBFOLDERS = ["prompts", "resources", "templates", "tools"];
|
|
1902
|
+
function findModuleDirs(repoRoot) {
|
|
1903
|
+
const modulesPath = path.resolve(repoRoot, "src", "modules");
|
|
1904
|
+
if (!fs.existsSync(modulesPath) || !fs.statSync(modulesPath).isDirectory()) {
|
|
1905
|
+
return [];
|
|
1906
|
+
}
|
|
1907
|
+
return fs
|
|
1908
|
+
.readdirSync(modulesPath, { withFileTypes: true })
|
|
1909
|
+
.filter((d) => d.isDirectory())
|
|
1910
|
+
.map((d) => path.join(modulesPath, d.name));
|
|
557
1911
|
}
|
|
558
|
-
function
|
|
559
|
-
const
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
1912
|
+
function hasIndexExport(folderPath) {
|
|
1913
|
+
const candidates = [
|
|
1914
|
+
"index.ts",
|
|
1915
|
+
"index.tsx",
|
|
1916
|
+
"index.js",
|
|
1917
|
+
"index.cjs",
|
|
1918
|
+
"index.mjs",
|
|
1919
|
+
];
|
|
1920
|
+
for (const c of candidates) {
|
|
1921
|
+
if (fs.existsSync(path.join(folderPath, c)))
|
|
1922
|
+
return true;
|
|
1923
|
+
}
|
|
1924
|
+
return false;
|
|
1925
|
+
}
|
|
1926
|
+
function validateModules(repoRoot) {
|
|
1927
|
+
const dirs = findModuleDirs(repoRoot);
|
|
1928
|
+
const issues = [];
|
|
1929
|
+
for (const moduleDir of dirs) {
|
|
1930
|
+
const moduleName = path.basename(moduleDir);
|
|
1931
|
+
for (const sub of REQUIRED_SUBFOLDERS) {
|
|
1932
|
+
const subPath = path.join(moduleDir, sub);
|
|
1933
|
+
if (!fs.existsSync(subPath) || !fs.statSync(subPath).isDirectory()) {
|
|
1934
|
+
issues.push({
|
|
1935
|
+
module: moduleName,
|
|
1936
|
+
path: subPath,
|
|
1937
|
+
type: "missing-folder",
|
|
1938
|
+
detail: `Required folder '${sub}' is missing in module '${moduleName}'`,
|
|
1939
|
+
});
|
|
568
1940
|
continue;
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
}
|
|
1941
|
+
}
|
|
1942
|
+
// If folder exists, check for index export
|
|
1943
|
+
if (!hasIndexExport(subPath)) {
|
|
1944
|
+
issues.push({
|
|
1945
|
+
module: moduleName,
|
|
1946
|
+
path: subPath,
|
|
1947
|
+
type: "missing-export",
|
|
1948
|
+
detail: `No index export found in '${subPath}'. Expected one of index.ts, index.js, etc.`,
|
|
1949
|
+
});
|
|
1950
|
+
continue;
|
|
1951
|
+
}
|
|
1952
|
+
// Optionally inspect the index file to see if it exports a list (lightweight check)
|
|
1953
|
+
try {
|
|
1954
|
+
const indexFile = candidatesFindingIndex(subPath);
|
|
1955
|
+
if (indexFile) {
|
|
1956
|
+
const content = fs.readFileSync(indexFile, "utf8");
|
|
1957
|
+
// crude heuristics: look for `export const name = [` or `export const name: Type[] = [`,
|
|
1958
|
+
// or any named export like `export { something }` which implies exports exist.
|
|
1959
|
+
const exportListPattern = /export\s+(const|let|var)\s+[\w$]+(?:\s*:\s*[^=]+)?\s*=\s*\[/;
|
|
1960
|
+
if (!exportListPattern.test(content) &&
|
|
1961
|
+
!/export\s+\{/.test(content)) {
|
|
1962
|
+
issues.push({
|
|
1963
|
+
module: moduleName,
|
|
1964
|
+
path: indexFile,
|
|
1965
|
+
type: "empty-list",
|
|
1966
|
+
detail: `Index file does not appear to export a list of assets: ${path.basename(indexFile)}`,
|
|
1967
|
+
});
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
catch (err) {
|
|
1972
|
+
issues.push({
|
|
1973
|
+
module: moduleName,
|
|
1974
|
+
path: subPath,
|
|
1975
|
+
type: "other",
|
|
1976
|
+
detail: `Error reading index file: ${err.message}`,
|
|
1977
|
+
});
|
|
1978
|
+
}
|
|
580
1979
|
}
|
|
581
1980
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
1981
|
+
return {
|
|
1982
|
+
ok: issues.length === 0,
|
|
1983
|
+
modulesChecked: dirs.length,
|
|
1984
|
+
issues,
|
|
1985
|
+
};
|
|
1986
|
+
}
|
|
1987
|
+
function candidatesFindingIndex(folderPath) {
|
|
1988
|
+
const candidates = [
|
|
1989
|
+
"index.ts",
|
|
1990
|
+
"index.tsx",
|
|
1991
|
+
"index.js",
|
|
1992
|
+
"index.cjs",
|
|
1993
|
+
"index.mjs",
|
|
1994
|
+
];
|
|
1995
|
+
for (const c of candidates) {
|
|
1996
|
+
const full = path.join(folderPath, c);
|
|
1997
|
+
if (fs.existsSync(full))
|
|
1998
|
+
return full;
|
|
587
1999
|
}
|
|
588
|
-
return
|
|
2000
|
+
return undefined;
|
|
589
2001
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
if (!prompts.length) {
|
|
598
|
-
throw new WorkspaceError("No documentation prompts available");
|
|
2002
|
+
// CLI helper
|
|
2003
|
+
if (require.main === module) {
|
|
2004
|
+
const repoRoot = process.cwd();
|
|
2005
|
+
const report = validateModules(repoRoot);
|
|
2006
|
+
if (!report.ok) {
|
|
2007
|
+
console.error("Module validation failed:\n", JSON.stringify(report, null, 2));
|
|
2008
|
+
process.exit(2);
|
|
599
2009
|
}
|
|
600
|
-
|
|
2010
|
+
console.log("Module validation passed");
|
|
2011
|
+
process.exit(0);
|
|
601
2012
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
2013
|
+
|
|
2014
|
+
// Aggregator: import module index files and merge exported arrays with provenance + duplicate detection
|
|
2015
|
+
const SUBFOLDERS = ["prompts", "resources", "templates", "tools"];
|
|
2016
|
+
const INDEX_CANDIDATES = [
|
|
2017
|
+
"index.ts",
|
|
2018
|
+
"index.tsx",
|
|
2019
|
+
"index.js",
|
|
2020
|
+
"index.cjs",
|
|
2021
|
+
"index.mjs",
|
|
2022
|
+
];
|
|
2023
|
+
function findIndexFile(folder) {
|
|
2024
|
+
for (const c of INDEX_CANDIDATES) {
|
|
2025
|
+
const f = path.join(folder, c);
|
|
2026
|
+
if (fs.existsSync(f))
|
|
2027
|
+
return f;
|
|
606
2028
|
}
|
|
607
|
-
|
|
608
|
-
|
|
2029
|
+
return undefined;
|
|
2030
|
+
}
|
|
2031
|
+
function makeKeyForItem(item) {
|
|
2032
|
+
if (!item)
|
|
2033
|
+
return JSON.stringify(item);
|
|
2034
|
+
if (typeof item === "string")
|
|
2035
|
+
return `str:${item}`;
|
|
2036
|
+
if (typeof item === "number")
|
|
2037
|
+
return `num:${item}`;
|
|
2038
|
+
if (item.id)
|
|
2039
|
+
return `id:${item.id}`;
|
|
2040
|
+
if (item.name)
|
|
2041
|
+
return `name:${item.name}`;
|
|
2042
|
+
// fallback to stable string
|
|
2043
|
+
try {
|
|
2044
|
+
return `obj:${JSON.stringify(item)}`;
|
|
609
2045
|
}
|
|
610
|
-
|
|
611
|
-
|
|
2046
|
+
catch (e) {
|
|
2047
|
+
return `obj:${String(item)}`;
|
|
612
2048
|
}
|
|
613
|
-
|
|
614
|
-
|
|
2049
|
+
}
|
|
2050
|
+
async function loadArrayFromIndex(filePath) {
|
|
2051
|
+
// Prefer a fast, static parse of the first array literal found in the file.
|
|
2052
|
+
try {
|
|
2053
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
2054
|
+
const start = content.indexOf("[");
|
|
2055
|
+
if (start !== -1) {
|
|
2056
|
+
let depth = 0;
|
|
2057
|
+
let end = -1;
|
|
2058
|
+
for (let i = start; i < content.length; i++) {
|
|
2059
|
+
const ch = content[i];
|
|
2060
|
+
if (ch === "[")
|
|
2061
|
+
depth++;
|
|
2062
|
+
else if (ch === "]") {
|
|
2063
|
+
depth--;
|
|
2064
|
+
if (depth === 0) {
|
|
2065
|
+
end = i;
|
|
2066
|
+
break;
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
if (end !== -1) {
|
|
2071
|
+
const arrText = content.slice(start, end + 1);
|
|
2072
|
+
try {
|
|
2073
|
+
return JSON.parse(arrText);
|
|
2074
|
+
}
|
|
2075
|
+
catch (e) {
|
|
2076
|
+
// Normalize TS object literals to JSON:
|
|
2077
|
+
// - convert single quotes to double quotes
|
|
2078
|
+
// - quote unquoted object keys
|
|
2079
|
+
// - strip trailing commas
|
|
2080
|
+
const normalized = arrText
|
|
2081
|
+
// unify quotes in string literals
|
|
2082
|
+
.replace(/'(?:\\'|[^'])*'/g, (m) => m.replace(/'/g, '"'))
|
|
2083
|
+
// quote unquoted keys after { or ,
|
|
2084
|
+
.replace(/([\{,]\s*)([A-Za-z_$][\w$]*)(\s*:)/g, '$1"$2"$3')
|
|
2085
|
+
// remove trailing commas before ] or }
|
|
2086
|
+
.replace(/,(\s*[\}\]])/g, '$1');
|
|
2087
|
+
try {
|
|
2088
|
+
return JSON.parse(normalized);
|
|
2089
|
+
}
|
|
2090
|
+
catch (e2) {
|
|
2091
|
+
// fallthrough to import attempt below
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
615
2096
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
2097
|
+
catch (e) {
|
|
2098
|
+
// ignore static parse errors and fall back to import
|
|
2099
|
+
}
|
|
2100
|
+
try {
|
|
2101
|
+
const fileUrl = pathToFileURL(filePath).href;
|
|
2102
|
+
const mod = await import(fileUrl);
|
|
2103
|
+
// Find first export that is an array
|
|
2104
|
+
for (const key of Object.keys(mod)) {
|
|
2105
|
+
const val = mod[key];
|
|
2106
|
+
if (Array.isArray(val))
|
|
2107
|
+
return val;
|
|
2108
|
+
}
|
|
2109
|
+
// default export check
|
|
2110
|
+
if (Array.isArray(mod.default))
|
|
2111
|
+
return mod.default;
|
|
2112
|
+
return undefined;
|
|
2113
|
+
}
|
|
2114
|
+
catch (err) {
|
|
2115
|
+
// fallback: if import fails, try to static-parse again (already attempted) and finally return undefined
|
|
2116
|
+
return undefined;
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
async function aggregateModules(repoRoot) {
|
|
2120
|
+
const dirs = findModuleDirs(repoRoot);
|
|
2121
|
+
const master = {
|
|
2122
|
+
prompts: [],
|
|
2123
|
+
resources: [],
|
|
2124
|
+
templates: [],
|
|
2125
|
+
tools: [],
|
|
2126
|
+
conflicts: [],
|
|
2127
|
+
};
|
|
2128
|
+
// maps to detect duplicates per type
|
|
2129
|
+
const maps = {
|
|
2130
|
+
prompts: new Map(),
|
|
2131
|
+
resources: new Map(),
|
|
2132
|
+
templates: new Map(),
|
|
2133
|
+
tools: new Map(),
|
|
623
2134
|
};
|
|
2135
|
+
for (const moduleDir of dirs) {
|
|
2136
|
+
const moduleName = path.basename(moduleDir);
|
|
2137
|
+
for (const sub of SUBFOLDERS) {
|
|
2138
|
+
const folder = path.join(moduleDir, sub);
|
|
2139
|
+
const indexFile = findIndexFile(folder);
|
|
2140
|
+
if (!indexFile)
|
|
2141
|
+
continue;
|
|
2142
|
+
let arr;
|
|
2143
|
+
try {
|
|
2144
|
+
arr = await loadArrayFromIndex(indexFile);
|
|
2145
|
+
}
|
|
2146
|
+
catch (err) {
|
|
2147
|
+
// skip module on import error but record as conflict-like issue
|
|
2148
|
+
master.conflicts.push({
|
|
2149
|
+
key: `import-error:${moduleName}:${sub}`,
|
|
2150
|
+
existing: { moduleName, modulePath: moduleDir },
|
|
2151
|
+
incoming: { moduleName, modulePath: moduleDir },
|
|
2152
|
+
});
|
|
2153
|
+
continue;
|
|
2154
|
+
}
|
|
2155
|
+
if (!arr || !Array.isArray(arr))
|
|
2156
|
+
continue;
|
|
2157
|
+
for (const item of arr) {
|
|
2158
|
+
const key = makeKeyForItem(item);
|
|
2159
|
+
const provenance = { moduleName, modulePath: moduleDir };
|
|
2160
|
+
const map = maps[sub];
|
|
2161
|
+
if (map.has(key)) {
|
|
2162
|
+
// record conflict deterministically (existing vs incoming)
|
|
2163
|
+
const existing = map.get(key);
|
|
2164
|
+
master.conflicts.push({ key, existing, incoming: provenance });
|
|
2165
|
+
// skip adding duplicate
|
|
2166
|
+
continue;
|
|
2167
|
+
}
|
|
2168
|
+
map.set(key, provenance);
|
|
2169
|
+
master[sub].push({ ...item, provenance });
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
return master;
|
|
624
2174
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
2175
|
+
// For compatibility with CommonJS call sites (not exported by ESM), provide a sync wrapper
|
|
2176
|
+
function aggregateModulesSync(repoRoot) {
|
|
2177
|
+
// synchronous wrapper that runs the async function and blocks — suitable for small module sets
|
|
2178
|
+
const p = aggregateModules(repoRoot);
|
|
2179
|
+
let result;
|
|
2180
|
+
let done = false;
|
|
2181
|
+
p.then((r) => {
|
|
2182
|
+
result = r;
|
|
2183
|
+
done = true;
|
|
2184
|
+
}).catch((e) => {
|
|
2185
|
+
throw e;
|
|
2186
|
+
});
|
|
2187
|
+
if (!done)
|
|
2188
|
+
throw new Error("aggregateModulesSync: timeout waiting for async aggregation");
|
|
2189
|
+
return result;
|
|
632
2190
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
2191
|
+
|
|
2192
|
+
/**
|
|
2193
|
+
* Aggregate module assets and register them on the provided FastMCP-like server.
|
|
2194
|
+
* Falls back to built-in lists if aggregation yields none.
|
|
2195
|
+
*/
|
|
2196
|
+
async function EnrichCoreWithAggregation(server, repoRoot = process.cwd()) {
|
|
2197
|
+
// First register built-in prompts/tools/resources/templates (legacy behavior)
|
|
2198
|
+
try {
|
|
2199
|
+
loadPrompts();
|
|
2200
|
+
for (const prompt of promptList)
|
|
2201
|
+
server.addPrompt(prompt);
|
|
2202
|
+
}
|
|
2203
|
+
catch (e) {
|
|
2204
|
+
// ignore if loadPrompts not available or fails
|
|
2205
|
+
}
|
|
2206
|
+
try {
|
|
2207
|
+
for (const tool of toolList)
|
|
2208
|
+
server.addTool(tool);
|
|
2209
|
+
}
|
|
2210
|
+
catch (e) { }
|
|
2211
|
+
try {
|
|
2212
|
+
for (const resource of resources)
|
|
2213
|
+
server.addResource(resource);
|
|
2214
|
+
}
|
|
2215
|
+
catch (e) { }
|
|
2216
|
+
try {
|
|
2217
|
+
const templates = buildResourceTemplates();
|
|
2218
|
+
for (const template of templates)
|
|
2219
|
+
server.addResourceTemplate(template);
|
|
2220
|
+
}
|
|
2221
|
+
catch (e) { }
|
|
2222
|
+
// Now aggregate modules and register aggregated assets with provenance
|
|
2223
|
+
const agg = await aggregateModules(repoRoot);
|
|
2224
|
+
for (const p of agg.prompts) {
|
|
2225
|
+
server.addPrompt(p);
|
|
2226
|
+
}
|
|
2227
|
+
for (const t of agg.tools) {
|
|
2228
|
+
server.addTool(t);
|
|
2229
|
+
}
|
|
2230
|
+
for (const r of agg.resources) {
|
|
2231
|
+
server.addResource(r);
|
|
2232
|
+
}
|
|
2233
|
+
for (const tpl of agg.templates) {
|
|
2234
|
+
server.addResourceTemplate(tpl);
|
|
2235
|
+
}
|
|
2236
|
+
// return aggregation summary for calling tests/CI
|
|
2237
|
+
return {
|
|
2238
|
+
modulesChecked: agg.prompts.concat(agg.tools).length,
|
|
2239
|
+
conflicts: agg.conflicts,
|
|
2240
|
+
};
|
|
639
2241
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
2242
|
+
|
|
2243
|
+
function EnrichCore(server) {
|
|
2244
|
+
loadPrompts();
|
|
2245
|
+
for (const prompt of promptList) {
|
|
2246
|
+
server.addPrompt(prompt);
|
|
2247
|
+
}
|
|
2248
|
+
for (const tool of toolList) {
|
|
2249
|
+
server.addTool(tool);
|
|
2250
|
+
}
|
|
2251
|
+
for (const resource of resources) {
|
|
2252
|
+
server.addResource(resource);
|
|
2253
|
+
}
|
|
2254
|
+
const templates = buildResourceTemplates();
|
|
2255
|
+
for (const template of templates) {
|
|
2256
|
+
server.addResourceTemplate(template);
|
|
655
2257
|
}
|
|
656
2258
|
}
|
|
657
2259
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
2260
|
+
const REQUIRED_MODULE_FOLDERS = [
|
|
2261
|
+
"prompts",
|
|
2262
|
+
"resources",
|
|
2263
|
+
"templates",
|
|
2264
|
+
"tools",
|
|
2265
|
+
];
|
|
2266
|
+
function resolveModulesRoot(workspaceRoot = getWorkspaceRoot()) {
|
|
2267
|
+
return path$1.resolve(workspaceRoot, "src/modules");
|
|
2268
|
+
}
|
|
2269
|
+
function listModuleDirectories(workspaceRoot = getWorkspaceRoot()) {
|
|
2270
|
+
const root = resolveModulesRoot(workspaceRoot);
|
|
2271
|
+
if (!fs$1.existsSync(root))
|
|
2272
|
+
return [];
|
|
2273
|
+
return fs$1
|
|
2274
|
+
.readdirSync(root)
|
|
2275
|
+
.map((entry) => ({
|
|
2276
|
+
entry,
|
|
2277
|
+
absolute: path$1.join(root, entry),
|
|
2278
|
+
}))
|
|
2279
|
+
.filter(({ absolute }) => fs$1.statSync(absolute).isDirectory())
|
|
2280
|
+
.map(({ entry }) => entry)
|
|
2281
|
+
.sort();
|
|
2282
|
+
}
|
|
2283
|
+
function resolveModulePath(moduleName, workspaceRoot = getWorkspaceRoot()) {
|
|
2284
|
+
return path$1.join(resolveModulesRoot(workspaceRoot), moduleName);
|
|
2285
|
+
}
|
|
2286
|
+
function resolveModuleFolderPath(moduleName, folder, workspaceRoot = getWorkspaceRoot()) {
|
|
2287
|
+
return path$1.join(resolveModulePath(moduleName, workspaceRoot), folder);
|
|
2288
|
+
}
|
|
666
2289
|
|
|
667
2290
|
/* istanbul ignore file */
|
|
668
2291
|
/**
|
|
@@ -747,7 +2370,6 @@ class McpUtils {
|
|
|
747
2370
|
}
|
|
748
2371
|
}
|
|
749
2372
|
|
|
750
|
-
/* istanbul ignore file */
|
|
751
2373
|
/**
|
|
752
2374
|
* @description Utility class to handle CLI functionality from all Decaf modules
|
|
753
2375
|
* @summary This class provides a wrapper around Commander.js to handle CLI commands from different Decaf modules.
|
|
@@ -776,7 +2398,7 @@ class McpWrapper extends LoggedClass {
|
|
|
776
2398
|
/**
|
|
777
2399
|
* @description Retrieves and initializes the Commander Command object
|
|
778
2400
|
* @summary Lazy-loads the Command object, initializing it with the package name, description, and version
|
|
779
|
-
* @return {
|
|
2401
|
+
* @return {FastMCP} The initialized Command object
|
|
780
2402
|
* @private
|
|
781
2403
|
*/
|
|
782
2404
|
get mcp() {
|
|
@@ -851,24 +2473,26 @@ class McpWrapper extends LoggedClass {
|
|
|
851
2473
|
*/
|
|
852
2474
|
async boot() {
|
|
853
2475
|
const log = this.log.for(this.boot);
|
|
854
|
-
const basePath = path.resolve(this.rootPath, this.basePath);
|
|
855
|
-
const modules = this.crawl(basePath, this.crawlLevels);
|
|
856
2476
|
let server = this.mcp;
|
|
857
|
-
|
|
858
|
-
|
|
2477
|
+
// discover modules by crawling basePath
|
|
2478
|
+
const moduleFiles = this.crawl(path.resolve(this.basePath), this.crawlLevels);
|
|
2479
|
+
for (const moduleFile of moduleFiles) {
|
|
2480
|
+
if (moduleFile.includes("@decaf-ts/mcp")) {
|
|
859
2481
|
continue;
|
|
860
2482
|
}
|
|
861
2483
|
try {
|
|
862
|
-
const res = await this.load(server,
|
|
2484
|
+
const res = await this.load(server, moduleFile);
|
|
863
2485
|
server = res.mcp;
|
|
2486
|
+
this.modules[res.package] = moduleFile;
|
|
864
2487
|
}
|
|
865
2488
|
catch (e) {
|
|
866
|
-
log.error(`Failed to load MCP configs for ${
|
|
2489
|
+
log.error(`Failed to load MCP configs for ${moduleFile}: ${e instanceof Error ? e.message : e}`);
|
|
867
2490
|
}
|
|
868
2491
|
}
|
|
869
2492
|
console.log(`loaded modules:\n${Object.keys(this.modules)
|
|
870
2493
|
.map((k) => `- ${k}`)
|
|
871
2494
|
.join("\n")}`);
|
|
2495
|
+
return server;
|
|
872
2496
|
}
|
|
873
2497
|
/**
|
|
874
2498
|
* @description Recursively searches for CLI module files in the directory structure
|
|
@@ -916,9 +2540,10 @@ class McpWrapper extends LoggedClass {
|
|
|
916
2540
|
*/
|
|
917
2541
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
918
2542
|
async run(args = process.argv) {
|
|
919
|
-
await this.boot();
|
|
2543
|
+
const server = await this.boot();
|
|
2544
|
+
await server.start({ transportType: "stdio" });
|
|
920
2545
|
}
|
|
921
2546
|
}
|
|
922
2547
|
|
|
923
|
-
export { MCP_FILE_NAME, McpUtils, McpWrapper, PACKAGE_NAME, VERSION, buildDocPrompts, buildResourceTemplates, enrich, getWorkspaceRoot, setWorkspaceRoot, tools };
|
|
924
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5lc20uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvbWV0YWRhdGEudHMiLCIuLi9zcmMvbW9kdWxlcy9tY3AvZGVjb3JhdG9yLXRvb2xzLnRzIiwiLi4vc3JjL21vZHVsZXMvbWNwL21jcC1tb2R1bGUudHMiLCIuLi9zcmMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3V0aWxzLnRzIiwiLi4vc3JjL01jcFdyYXBwZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRpb25cIjtcblxuLyoqXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG5hbWUgVkVSU0lPTlxuICogQGRlc2NyaXB0aW9uIFJlcHJlc2VudHMgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgdHMtd29ya3NwYWNlIG1vZHVsZS5cbiAqIEBzdW1tYXJ5IFRoZSBhY3R1YWwgdmVyc2lvbiBudW1iZXIgaXMgcmVwbGFjZWQgZHVyaW5nIHRoZSBidWlsZCBwcm9jZXNzLlxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG5leHBvcnQgY29uc3QgUEFDS0FHRV9OQU1FID0gXCIjI1BBQ0tBR0VfTkFNRSMjXCI7XG5cbnRyeSB7XG4gIE1ldGFkYXRhLnJlZ2lzdGVyTGlicmFyeShQQUNLQUdFX05BTUUsIFZFUlNJT04pO1xufSBjYXRjaCAoZXJyb3IpIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubWVzc2FnZS5pbmNsdWRlcyhcImFscmVhZHlcIikpIHtcbiAgICAvLyBJZ25vcmUgZHVwbGljYXRlIHJlZ2lzdHJhdGlvbiBkdXJpbmcgdGVzdHMvYnVuZGxpbmcgY2hlY2tzLlxuICB9IGVsc2Uge1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JTcGVjID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIGFyZ3M/OiB1bmtub3duW107XG59O1xuXG5leHBvcnQgdHlwZSBBdHRyaWJ1dGVTcGVjID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHR5cGU6IHN0cmluZztcbiAgZGVjb3JhdG9ycz86IERlY29yYXRvclNwZWNbXTtcbn07XG5cbmZ1bmN0aW9uIGVzY2FwZVJlZ0V4cCh2YWx1ZTogc3RyaW5nKSB7XG4gIHJldHVybiB2YWx1ZS5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgXCJcXFxcJCZcIik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdERlY29yYXRvcihzcGVjOiBEZWNvcmF0b3JTcGVjKTogc3RyaW5nIHtcbiAgY29uc3QgYXJncyA9IChzcGVjLmFyZ3MgfHwgW10pLm1hcCgoYXJnKSA9PiBKU09OLnN0cmluZ2lmeShhcmcpKS5qb2luKFwiLCBcIik7XG4gIHJldHVybiBgQCR7c3BlYy5uYW1lfSgke2FyZ3N9KWA7XG59XG5cbmZ1bmN0aW9uIGVuc3VyZURpcmVjdG9yeShmaWxlUGF0aDogc3RyaW5nKSB7XG4gIGZzLm1rZGlyU3luYyhwYXRoLmRpcm5hbWUoZmlsZVBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbn1cblxuZnVuY3Rpb24gY29sbGVjdERlY29yYXRvck5hbWVzKFxuICBjbGFzc0RlY29yYXRvcnM6IERlY29yYXRvclNwZWNbXSB8IHVuZGVmaW5lZCxcbiAgcHJvcGVydGllczogQXR0cmlidXRlU3BlY1tdIHwgdW5kZWZpbmVkXG4pIHtcbiAgY29uc3QgbmFtZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgbmFtZXMuYWRkKFwibW9kZWxcIik7XG4gIGZvciAoY29uc3QgZGVjb3JhdG9yIG9mIGNsYXNzRGVjb3JhdG9ycyB8fCBbXSkge1xuICAgIG5hbWVzLmFkZChkZWNvcmF0b3IubmFtZSk7XG4gIH1cbiAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBwcm9wZXJ0aWVzIHx8IFtdKSB7XG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgcHJvcGVydHkuZGVjb3JhdG9ycyB8fCBbXSkge1xuICAgICAgbmFtZXMuYWRkKGRlY29yYXRvci5uYW1lKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5hbWVzO1xufVxuXG5mdW5jdGlvbiBlbnN1cmVJbXBvcnQoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgaW1wb3J0c0Zyb206IHN0cmluZyxcbiAgZGVjb3JhdG9yczogU2V0PHN0cmluZz5cbikge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAoIWRlY29yYXRvcnMuc2l6ZSkgcmV0dXJuIGNvbnRlbnQ7XG4gIGNvbnN0IGltcG9ydFJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICBgaW1wb3J0XFxcXHMrXFxcXHsoW159XSspXFxcXH1cXFxccytmcm9tXFxcXHMrW1wiJ10ke2VzY2FwZVJlZ0V4cChpbXBvcnRzRnJvbSl9W1wiJ107YFxuICApO1xuICBjb25zdCBtYXRjaCA9IGNvbnRlbnQubWF0Y2goaW1wb3J0UmVnZXgpO1xuICBjb25zdCBzb3J0ZWQgPSBBcnJheS5mcm9tKGRlY29yYXRvcnMpLnNvcnQoKTtcblxuICBpZiAobWF0Y2gpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IG1hdGNoWzFdXG4gICAgICAuc3BsaXQoXCIsXCIpXG4gICAgICAubWFwKChuYW1lKSA9PiBuYW1lLnRyaW0oKSlcbiAgICAgIC5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgbWVyZ2VkID0gQXJyYXkuZnJvbShuZXcgU2V0KFsuLi5leGlzdGluZywgLi4uc29ydGVkXSkpLnNvcnQoKTtcbiAgICByZXR1cm4gY29udGVudC5yZXBsYWNlKFxuICAgICAgaW1wb3J0UmVnZXgsXG4gICAgICBgaW1wb3J0IHsgJHttZXJnZWQuam9pbihcIiwgXCIpfSB9IGZyb20gXCIke2ltcG9ydHNGcm9tfVwiO2BcbiAgICApO1xuICB9XG5cbiAgY29uc3QgaW1wb3J0TGluZSA9IGBpbXBvcnQgeyAke3NvcnRlZC5qb2luKFwiLCBcIil9IH0gZnJvbSBcIiR7aW1wb3J0c0Zyb219XCI7YDtcbiAgcmV0dXJuIGAke2ltcG9ydExpbmV9XFxuXFxuJHtjb250ZW50fWA7XG59XG5cbmZ1bmN0aW9uIGFkZFByb3BlcnR5QmxvY2socHJvcGVydHk6IEF0dHJpYnV0ZVNwZWMpIHtcbiAgY29uc3QgZGVjb3JhdG9ycyA9IChwcm9wZXJ0eS5kZWNvcmF0b3JzIHx8IFtdKVxuICAgIC5tYXAoZm9ybWF0RGVjb3JhdG9yKVxuICAgIC5qb2luKFwiXFxuICBcIik7XG4gIGNvbnN0IGRlY29yYXRvckJsb2NrID0gZGVjb3JhdG9ycyA/IGAgICR7ZGVjb3JhdG9yc31cXG5gIDogXCJcIjtcbiAgcmV0dXJuIGAke2RlY29yYXRvckJsb2NrfSAgJHtwcm9wZXJ0eS5uYW1lfTogJHtwcm9wZXJ0eS50eXBlfTtgO1xufVxuXG5mdW5jdGlvbiByZW1vdmVQcm9wZXJ0eUJsb2NrKGNvbnRlbnQ6IHN0cmluZywgcHJvcGVydHlOYW1lOiBzdHJpbmcpIHtcbiAgY29uc3QgbGluZXMgPSBjb250ZW50LnNwbGl0KC9cXHI/XFxuLyk7XG4gIGNvbnN0IHJlc3VsdDogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGxpbmUgPSBsaW5lc1tpXTtcbiAgICBpZiAoXG4gICAgICBsaW5lLnRyaW0oKS5zdGFydHNXaXRoKGBAYCkgJiZcbiAgICAgIGxpbmVzW2kgKyAxXT8uaW5jbHVkZXMoYCR7cHJvcGVydHlOYW1lfTpgKVxuICAgICkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChsaW5lLmluY2x1ZGVzKGAke3Byb3BlcnR5TmFtZX06YCkpIHtcbiAgICAgIC8vIHNraXAgdGhpcyBsaW5lIGFuZCBhbnkgdHJhaWxpbmcgYmxhbmsgbGluZVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHJlc3VsdC5wdXNoKGxpbmUpO1xuICB9XG4gIHJldHVybiByZXN1bHQuam9pbihcIlxcblwiKTtcbn1cblxuZnVuY3Rpb24gaW5zZXJ0RGVjb3JhdG9yKFxuICBjb250ZW50OiBzdHJpbmcsXG4gIGRlY29yYXRvcjogRGVjb3JhdG9yU3BlYyxcbiAgdGFyZ2V0OiB7XG4gICAga2luZDogXCJjbGFzc1wiIHwgXCJwcm9wZXJ0eVwiO1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gIH1cbikge1xuICBjb25zdCBkZWNvcmF0b3JMaW5lID0gZm9ybWF0RGVjb3JhdG9yKGRlY29yYXRvcik7XG4gIGlmICh0YXJnZXQua2luZCA9PT0gXCJjbGFzc1wiKSB7XG4gICAgY29uc3QgY2xhc3NSZWdleCA9IC8oZXhwb3J0XFxzK2NsYXNzXFxzK1teXFxze10rXFxzKlxceykvO1xuICAgIGlmIChjb250ZW50LmluY2x1ZGVzKGRlY29yYXRvckxpbmUpKSByZXR1cm4gY29udGVudDtcbiAgICByZXR1cm4gY29udGVudC5yZXBsYWNlKGNsYXNzUmVnZXgsIGAke2RlY29yYXRvckxpbmV9XFxuJDFgKTtcbiAgfVxuICBpZiAoIXRhcmdldC5uYW1lKSByZXR1cm4gY29udGVudDtcbiAgY29uc3QgcHJvcGVydHlSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgYCheXFxcXHMqKSg/OkAuKlxcXFxuXFxcXDEpKiR7ZXNjYXBlUmVnRXhwKHRhcmdldC5uYW1lKX06YCxcbiAgICBcIm1cIlxuICApO1xuICBjb25zdCBtYXRjaCA9IHByb3BlcnR5UmVnZXguZXhlYyhjb250ZW50KTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuIGNvbnRlbnQ7XG4gIGNvbnN0IGluZGVudCA9IG1hdGNoWzFdIHx8IFwiICBcIjtcbiAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoYCR7aW5kZW50fSR7ZGVjb3JhdG9yTGluZX1gKSkgcmV0dXJuIGNvbnRlbnQ7XG4gIHJldHVybiAoXG4gICAgY29udGVudC5zbGljZSgwLCBtYXRjaC5pbmRleCkgK1xuICAgIGAke2luZGVudH0ke2RlY29yYXRvckxpbmV9XFxuYCArXG4gICAgY29udGVudC5zbGljZShtYXRjaC5pbmRleClcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlRGVjb3JhdG9yKFxuICBjb250ZW50OiBzdHJpbmcsXG4gIGRlY29yYXRvck5hbWU6IHN0cmluZyxcbiAgdGFyZ2V0OiB7XG4gICAga2luZDogXCJjbGFzc1wiIHwgXCJwcm9wZXJ0eVwiO1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gIH1cbikge1xuICBjb25zdCBkZWNvcmF0b3JSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgYF5cXFxccypAJHtlc2NhcGVSZWdFeHAoZGVjb3JhdG9yTmFtZSl9XFxcXChbXildKlxcXFwpYCxcbiAgICBcIm1cIlxuICApO1xuICBpZiAodGFyZ2V0LmtpbmQgPT09IFwiY2xhc3NcIikge1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoZGVjb3JhdG9yUmVnZXgsIFwiXCIpO1xuICB9XG4gIGlmICh0YXJnZXQubmFtZSkge1xuICAgIGNvbnN0IHBhdHRlcm4gPSBuZXcgUmVnRXhwKFxuICAgICAgYCheXFxcXHMqQCR7ZXNjYXBlUmVnRXhwKGRlY29yYXRvck5hbWUpfVxcXFwoW14pXSpcXFxcKVxcXFxzKiRcXFxcbikoPz1cXFxccyoke2VzY2FwZVJlZ0V4cCh0YXJnZXQubmFtZSl9OilgLFxuICAgICAgXCJtXCJcbiAgICApO1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UocGF0dGVybiwgXCJcIik7XG4gIH1cbiAgcmV0dXJuIGNvbnRlbnQ7XG59XG5cbmZ1bmN0aW9uIHdyaXRlSWZDaGFuZ2VkKGZpbGVQYXRoOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZykge1xuICBlbnN1cmVEaXJlY3RvcnkoZmlsZVBhdGgpO1xuICBmcy53cml0ZUZpbGVTeW5jKGZpbGVQYXRoLCBjb250ZW50KTtcbn1cblxuZXhwb3J0IGNvbnN0IGRlY29yYXRvclRvb2xzID0ge1xuICBjcmVhdGVPclVwZGF0ZU1vZGVsVG9vbDoge1xuICAgIG5hbWU6IFwiY3JlYXRlLW9yLXVwZGF0ZS1tb2RlbFwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkNyZWF0ZSBvciB1cGRhdGUgYSB2YWxpZGF0aW9uLXJlYWR5IG1vZGVsIGNsYXNzXCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIGNsYXNzRGVjb3JhdG9ycz86IERlY29yYXRvclNwZWNbXTtcbiAgICAgIHByb3BlcnRpZXM6IEF0dHJpYnV0ZVNwZWNbXTtcbiAgICAgIGltcG9ydHNGcm9tOiBzdHJpbmc7XG4gICAgICBvdmVyd3JpdGU/OiBib29sZWFuO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghYXJncy5vdmVyd3JpdGUgJiYgZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZpbGUgYWxyZWFkeSBleGlzdHMgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgICAgfVxuICAgICAgY29uc3QgZGVjb3JhdG9ycyA9IGNvbGxlY3REZWNvcmF0b3JOYW1lcyhcbiAgICAgICAgYXJncy5jbGFzc0RlY29yYXRvcnMsXG4gICAgICAgIGFyZ3MucHJvcGVydGllc1xuICAgICAgKTtcbiAgICAgIGxldCBjb250ZW50ID0gYEBtb2RlbCgpYDtcbiAgICAgIGZvciAoY29uc3QgZGVjb3JhdG9yIG9mIGFyZ3MuY2xhc3NEZWNvcmF0b3JzIHx8IFtdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gYFxcbiR7Zm9ybWF0RGVjb3JhdG9yKGRlY29yYXRvcil9YDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSAoYXJncy5wcm9wZXJ0aWVzIHx8IFtdKVxuICAgICAgICAubWFwKGFkZFByb3BlcnR5QmxvY2spXG4gICAgICAgIC5qb2luKFwiXFxuXFxuXCIpO1xuICAgICAgY29udGVudCArPSBgXFxuZXhwb3J0IGNsYXNzICR7YXJncy5jbGFzc05hbWV9IHtcXG4ke3Byb3BlcnRpZXMgPyBgJHtwcm9wZXJ0aWVzfVxcbmAgOiBcIlwifX1cXG5gO1xuICAgICAgY29udGVudCA9IGVuc3VyZUltcG9ydChjb250ZW50LCBhcmdzLmltcG9ydHNGcm9tLCBkZWNvcmF0b3JzKTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICBhZGRBdHRyaWJ1dGVUb29sOiB7XG4gICAgbmFtZTogXCJhZGQtYXR0cmlidXRlXCIsXG4gICAgZGVzY3JpcHRpb246IFwiQWRkIGEgZGVjb3JhdGVkIGF0dHJpYnV0ZSB0byBhbiBleGlzdGluZyBtb2RlbFwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBmaWxlUGF0aDogc3RyaW5nO1xuICAgICAgY2xhc3NOYW1lOiBzdHJpbmc7XG4gICAgICBhdHRyaWJ1dGU6IEF0dHJpYnV0ZVNwZWM7XG4gICAgICBpbXBvcnRzRnJvbTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1vZGVsIGZpbGUgbm90IGZvdW5kIGF0ICR7YXJncy5maWxlUGF0aH1gKTtcbiAgICAgIH1cbiAgICAgIGxldCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGFyZ3MuZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICAgIGlmIChjb250ZW50LmluY2x1ZGVzKGAke2FyZ3MuYXR0cmlidXRlLm5hbWV9OmApKSB7XG4gICAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgICB9XG4gICAgICBjb25zdCBkZWNvcmF0b3JzID0gY29sbGVjdERlY29yYXRvck5hbWVzKHVuZGVmaW5lZCwgW2FyZ3MuYXR0cmlidXRlXSk7XG4gICAgICBjb250ZW50ID0gZW5zdXJlSW1wb3J0KGNvbnRlbnQsIGFyZ3MuaW1wb3J0c0Zyb20sIGRlY29yYXRvcnMpO1xuICAgICAgY29uc3QgaW5zZXJ0aW9uUG9pbnQgPSBjb250ZW50Lmxhc3RJbmRleE9mKFwifVwiKTtcbiAgICAgIGNvbnN0IGJsb2NrID0gYWRkUHJvcGVydHlCbG9jayhhcmdzLmF0dHJpYnV0ZSk7XG4gICAgICBjb25zdCBiZWZvcmUgPSBjb250ZW50LnNsaWNlKDAsIGluc2VydGlvblBvaW50KS5yZXBsYWNlKC9cXHMqJC8sIFwiXCIpO1xuICAgICAgY29uc3QgYWZ0ZXIgPSBjb250ZW50LnNsaWNlKGluc2VydGlvblBvaW50KTtcbiAgICAgIGNvbnN0IHVwZGF0ZWQgPSBgJHtiZWZvcmV9XFxuJHtibG9ja31cXG4ke2FmdGVyfWA7XG4gICAgICB3cml0ZUlmQ2hhbmdlZChhcmdzLmZpbGVQYXRoLCB1cGRhdGVkKTtcbiAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgfSxcbiAgfSxcbiAgcmVtb3ZlQXR0cmlidXRlVG9vbDoge1xuICAgIG5hbWU6IFwicmVtb3ZlLWF0dHJpYnV0ZVwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlJlbW92ZSBhbiBhdHRyaWJ1dGUgZnJvbSBhIG1vZGVsIGNsYXNzXCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIGF0dHJpYnV0ZU5hbWU6IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGFyZ3MuZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICAgIGNvbnN0IHVwZGF0ZWQgPSByZW1vdmVQcm9wZXJ0eUJsb2NrKGNvbnRlbnQsIGFyZ3MuYXR0cmlidXRlTmFtZSk7XG4gICAgICB3cml0ZUlmQ2hhbmdlZChhcmdzLmZpbGVQYXRoLCB1cGRhdGVkKTtcbiAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgfSxcbiAgfSxcbiAgYXBwbHlEZWNvcmF0b3JUb29sOiB7XG4gICAgbmFtZTogXCJhcHBseS1kZWNvcmF0b3JcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBcHBseSBhIGRlY29yYXRvciB0byBhIGNsYXNzIG9yIHByb3BlcnR5XCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIHRhcmdldDogeyBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7IG5hbWU/OiBzdHJpbmcgfTtcbiAgICAgIGRlY29yYXRvcjogRGVjb3JhdG9yU3BlYztcbiAgICAgIGltcG9ydHNGcm9tOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTW9kZWwgZmlsZSBub3QgZm91bmQgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgICAgfVxuICAgICAgbGV0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgZGVjb3JhdG9ycyA9IG5ldyBTZXQ8c3RyaW5nPihbYXJncy5kZWNvcmF0b3IubmFtZV0pO1xuICAgICAgY29udGVudCA9IGVuc3VyZUltcG9ydChjb250ZW50LCBhcmdzLmltcG9ydHNGcm9tLCBkZWNvcmF0b3JzKTtcbiAgICAgIGNvbnRlbnQgPSBpbnNlcnREZWNvcmF0b3IoY29udGVudCwgYXJncy5kZWNvcmF0b3IsIGFyZ3MudGFyZ2V0KTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICByZW1vdmVEZWNvcmF0b3JUb29sOiB7XG4gICAgbmFtZTogXCJyZW1vdmUtZGVjb3JhdG9yXCIsXG4gICAgZGVzY3JpcHRpb246IFwiUmVtb3ZlIGEgZGVjb3JhdG9yIGZyb20gYSBjbGFzcyBvciBwcm9wZXJ0eVwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBmaWxlUGF0aDogc3RyaW5nO1xuICAgICAgY2xhc3NOYW1lOiBzdHJpbmc7XG4gICAgICB0YXJnZXQ6IHsga2luZDogXCJjbGFzc1wiIHwgXCJwcm9wZXJ0eVwiOyBuYW1lPzogc3RyaW5nIH07XG4gICAgICBkZWNvcmF0b3JOYW1lOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgICAgbGV0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29udGVudCA9IHJlbW92ZURlY29yYXRvcihjb250ZW50LCBhcmdzLmRlY29yYXRvck5hbWUsIGFyZ3MudGFyZ2V0KTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICBzY2FmZm9sZFZhbGlkYXRvclRvb2w6IHtcbiAgICBuYW1lOiBcInNjYWZmb2xkLXZhbGlkYXRvclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlNjYWZmb2xkIGEgdmFsaWRhdG9yIGNsYXNzIGFuZCBvcHRpb25hbCBkZWNvcmF0b3JcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgdmFsaWRhdG9yc0Rpcjogc3RyaW5nO1xuICAgICAgZGVjb3JhdG9yRGlyPzogc3RyaW5nO1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGNsYXNzRmlsZSA9IHBhdGguam9pbihhcmdzLnZhbGlkYXRvcnNEaXIsIGAke2FyZ3MubmFtZX0udHNgKTtcbiAgICAgIGVuc3VyZURpcmVjdG9yeShjbGFzc0ZpbGUpO1xuICAgICAgY29uc3QgY2xhc3NDb250ZW50ID0gYGV4cG9ydCBjbGFzcyAke2FyZ3MubmFtZX0ge1xcbiAgdmFsaWRhdGUodmFsdWU6IHVua25vd24pOiBib29sZWFuIHtcXG4gICAgcmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQ7XFxuICB9XFxufVxcbmA7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKGNsYXNzRmlsZSwgY2xhc3NDb250ZW50KTtcbiAgICAgIGxldCBkZWNvcmF0b3JGaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy5kZWNvcmF0b3JEaXIpIHtcbiAgICAgICAgZGVjb3JhdG9yRmlsZSA9IHBhdGguam9pbihcbiAgICAgICAgICBhcmdzLmRlY29yYXRvckRpcixcbiAgICAgICAgICBgJHthcmdzLm5hbWV9RGVjb3JhdG9yLnRzYFxuICAgICAgICApO1xuICAgICAgICBlbnN1cmVEaXJlY3RvcnkoZGVjb3JhdG9yRmlsZSk7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgICAgZGVjb3JhdG9yRmlsZSxcbiAgICAgICAgICBgZXhwb3J0IGZ1bmN0aW9uICR7YXJncy5uYW1lfURlY29yYXRvcigpIHtcXG4gIHJldHVybiAoKSA9PiB2b2lkIDA7XFxufVxcbmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGNsYXNzRmlsZSwgZGVjb3JhdG9yRmlsZSB9O1xuICAgIH0sXG4gIH0sXG4gIHNjYWZmb2xkU2VyaWFsaXplclRvb2w6IHtcbiAgICBuYW1lOiBcInNjYWZmb2xkLXNlcmlhbGl6ZXJcIixcbiAgICBkZXNjcmlwdGlvbjogXCJTY2FmZm9sZCBhIHNlcmlhbGl6ZXIgY2xhc3MgYW5kIG9wdGlvbmFsIHJlZ2lzdHJ5XCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGRpcjogc3RyaW5nO1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgICAgcmVnaXN0ZXJEaXI/OiBzdHJpbmc7XG4gICAgICBzZXREZWZhdWx0PzogYm9vbGVhbjtcbiAgICB9KSA9PiB7XG4gICAgICBjb25zdCBjbGFzc0ZpbGUgPSBwYXRoLmpvaW4oYXJncy5kaXIsIGAke2FyZ3MubmFtZX0udHNgKTtcbiAgICAgIGVuc3VyZURpcmVjdG9yeShjbGFzc0ZpbGUpO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgY2xhc3NGaWxlLFxuICAgICAgICBgZXhwb3J0IGNsYXNzICR7YXJncy5uYW1lfSB7XFxuICBzZXJpYWxpemUodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xcbiAgfVxcbn1cXG5gXG4gICAgICApO1xuICAgICAgbGV0IHJlZ2lzdGVyRmlsZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGFyZ3MucmVnaXN0ZXJEaXIpIHtcbiAgICAgICAgcmVnaXN0ZXJGaWxlID0gcGF0aC5qb2luKGFyZ3MucmVnaXN0ZXJEaXIsIGAke2FyZ3MubmFtZX1SZWdpc3Rlci50c2ApO1xuICAgICAgICBlbnN1cmVEaXJlY3RvcnkocmVnaXN0ZXJGaWxlKTtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgICByZWdpc3RlckZpbGUsXG4gICAgICAgICAgYGV4cG9ydCBmdW5jdGlvbiByZWdpc3RlciR7YXJncy5uYW1lfSgpIHtcXG4gIHJldHVybiAke2FyZ3Muc2V0RGVmYXVsdCA/IFwiJ2RlZmF1bHQnXCIgOiBcIidvcHRpb25hbCdcIn07XFxufVxcbmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGNsYXNzRmlsZSwgcmVnaXN0ZXJGaWxlIH07XG4gICAgfSxcbiAgfSxcbiAgc2NhZmZvbGRIYXNoaW5nVG9vbDoge1xuICAgIG5hbWU6IFwic2NhZmZvbGQtaGFzaGluZ1wiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlNjYWZmb2xkIGEgaGFzaGluZyBmdW5jdGlvbiBhbmQgb3B0aW9uYWwgcmVnaXN0cnlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZGlyOiBzdHJpbmc7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICByZWdpc3RlckRpcj86IHN0cmluZztcbiAgICAgIHNldERlZmF1bHQ/OiBib29sZWFuO1xuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGZ1bmN0aW9uRmlsZSA9IHBhdGguam9pbihhcmdzLmRpciwgYCR7YXJncy5uYW1lfS50c2ApO1xuICAgICAgZW5zdXJlRGlyZWN0b3J5KGZ1bmN0aW9uRmlsZSk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICBmdW5jdGlvbkZpbGUsXG4gICAgICAgIGBleHBvcnQgZnVuY3Rpb24gJHthcmdzLm5hbWV9KHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xcbiAgcmV0dXJuIHZhbHVlLnNwbGl0KCcnKS5yZXZlcnNlKCkuam9pbignJyk7XFxufVxcbmBcbiAgICAgICk7XG4gICAgICBsZXQgcmVnaXN0ZXJGaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy5yZWdpc3RlckRpcikge1xuICAgICAgICByZWdpc3RlckZpbGUgPSBwYXRoLmpvaW4oYXJncy5yZWdpc3RlckRpciwgYCR7YXJncy5uYW1lfVJlZ2lzdGVyLnRzYCk7XG4gICAgICAgIGVuc3VyZURpcmVjdG9yeShyZWdpc3RlckZpbGUpO1xuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICAgIHJlZ2lzdGVyRmlsZSxcbiAgICAgICAgICBgZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyJHthcmdzLm5hbWV9KCkge1xcbiAgcmV0dXJuICR7YXJncy5zZXREZWZhdWx0ID8gXCInZGVmYXVsdCdcIiA6IFwiJ29wdGlvbmFsJ1wifTtcXG59XFxuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgZnVuY3Rpb25GaWxlLCByZWdpc3RlckZpbGUgfTtcbiAgICB9LFxuICB9LFxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgRGVjb3JhdG9yVG9vbHMgPSB0eXBlb2YgZGVjb3JhdG9yVG9vbHM7XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBGYXN0TUNQLCBDb250ZW50UmVzdWx0LCBJbnB1dFByb21wdCwgVG9vbCB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQgeyBhcHBseVBhdGNoLCBjcmVhdGVUd29GaWxlc1BhdGNoIH0gZnJvbSBcImRpZmZcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyBQQUNLQUdFX05BTUUgYXMgUEtHLCBWRVJTSU9OIGFzIFYgfSBmcm9tIFwiLi4vLi4vbWV0YWRhdGFcIjtcbmltcG9ydCB7IGRlY29yYXRvclRvb2xzIH0gZnJvbSBcIi4vZGVjb3JhdG9yLXRvb2xzXCI7XG5cbmNvbnN0IFdPUktTUEFDRV9ST09UX0VOViA9IFwiTUNQX1dPUktTUEFDRV9ST09UXCI7XG5jb25zdCBQUk9NUFRfRElSRUNUT1JJRVMgPSBbXCIuY29kZS9wcm9tcHRzXCIsIFwiLmNvZGV4L3Byb21wdHNcIl07XG5jb25zdCBERUZBVUxUX1BST01QVF9OQU1FID0gXCJkb2NcIjtcbmNvbnN0IENMSUVOVF9JTlRFR1JBVElPTlMgPSBbXG4gIHtcbiAgICBpZDogXCJ2c2NvZGVcIixcbiAgICBkaXNwbGF5OiBcIlZpc3VhbCBTdHVkaW8gQ29kZVwiLFxuICAgIGluc3RydWN0aW9uczpcbiAgICAgIFwiV2hlbiBpbnRlcmFjdGluZyBmcm9tIFZpc3VhbCBTdHVkaW8gQ29kZSwgcHJlZmVyIHRoZSB2c2NvZGU6Ly93b3Jrc3BhY2Uve3BhdGh9IHJlc291cmNlIHRlbXBsYXRlIHRvIGZldGNoIGZpbGUgY29udGVudHMgYW5kIHVzZSB0aGUgYXBwbHktY29kZS1jaGFuZ2UgdG9vbCB0byBjb21taXQgZWRpdHMgd2l0aCBwcmV2aWV3YWJsZSBkaWZmcy5cIixcbiAgfSxcbiAge1xuICAgIGlkOiBcImN1cnNvclwiLFxuICAgIGRpc3BsYXk6IFwiQ3Vyc29yXCIsXG4gICAgaW5zdHJ1Y3Rpb25zOlxuICAgICAgXCJDdXJzb3IgY2xpZW50cyBjYW4gcmV0cmlldmUgYW5kIHVwZGF0ZSBmaWxlcyB0aHJvdWdoIHRoZSBjdXJzb3I6Ly93b3Jrc3BhY2Uve3BhdGh9IHJlc291cmNlIHRlbXBsYXRlLiBBbHdheXMgdmFsaWRhdGUgcGF0Y2hlcyBpbiBkcnlSdW4gbW9kZSBiZWZvcmUgYXBwbHlpbmcgcGVybWFuZW50IGNoYW5nZXMuXCIsXG4gIH0sXG4gIHtcbiAgICBpZDogXCJjb3BpbG90XCIsXG4gICAgZGlzcGxheTogXCJHaXRIdWIgQ29waWxvdFwiLFxuICAgIGluc3RydWN0aW9uczpcbiAgICAgIFwiVXNlIHRoZSBjb3BpbG90Oi8vd29ya3NwYWNlL3twYXRofSByZXNvdXJjZSB0ZW1wbGF0ZSB0byBzdHJlYW0gZmlsZSBjb250ZW50IGludG8gQ29waWxvdCBjaGF0IHNlc3Npb25zLiBQcmVmZXIgcmV0dXJuaW5nIHVuaWZpZWQgZGlmZnMgdG8gbWFpbnRhaW4gYWxpZ25tZW50IHdpdGggQ29waWxvdCdzIGRpZmYgdmlzdWFsaXphdGlvbi5cIixcbiAgfSxcbl0gYXMgY29uc3Q7XG5cbmNvbnN0IGRvY3VtZW50Q29kZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZmlsZVBhdGg6IHouc3RyaW5nKCkubWluKDEsIFwiZmlsZVBhdGggaXMgcmVxdWlyZWRcIiksXG4gICAgcHJvbXB0TmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgIGluY2x1ZGVQcm9tcHQ6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gICAgaW5jbHVkZUNvZGU6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gICAgaW5jbHVkZU1ldGFkYXRhOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGFkZGl0aW9uYWxDb250ZXh0OiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgZW5jb2Rpbmc6IHouc3RyaW5nKCkuZGVmYXVsdChcInV0ZjhcIiksXG4gIH0pXG4gIC5zdHJpY3QoKTtcblxudHlwZSBEb2N1bWVudENvZGVBcmdzID0gei5pbmZlcjx0eXBlb2YgZG9jdW1lbnRDb2RlU2NoZW1hPjtcblxuY29uc3QgY29kZUNoYW5nZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZmlsZVBhdGg6IHouc3RyaW5nKCkubWluKDEsIFwiZmlsZVBhdGggaXMgcmVxdWlyZWRcIiksXG4gICAgcGF0Y2g6IHouc3RyaW5nKCkubWluKDEsIFwicGF0Y2ggaXMgcmVxdWlyZWRcIiksXG4gICAgZHJ5UnVuOiB6LmJvb2xlYW4oKS5kZWZhdWx0KGZhbHNlKSxcbiAgICBzaG93RGlmZjogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBkaWZmQ29udGV4dDogei5udW1iZXIoKS5pbnQoKS5taW4oMCkubWF4KDEwMCkuZGVmYXVsdCgzKSxcbiAgICBlbmNvZGluZzogei5zdHJpbmcoKS5kZWZhdWx0KFwidXRmOFwiKSxcbiAgfSlcbiAgLnN0cmljdCgpO1xuXG50eXBlIEFwcGx5Q29kZUNoYW5nZUFyZ3MgPSB6LmluZmVyPHR5cGVvZiBjb2RlQ2hhbmdlU2NoZW1hPjtcblxudHlwZSBEb2NQcm9tcHQgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgZGVzY3JpcHRpb246IHN0cmluZztcbiAgY29udGVudDogc3RyaW5nO1xuICBhYnNvbHV0ZVBhdGg6IHN0cmluZztcbn07XG5cbnR5cGUgV29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZSA9IHtcbiAgbmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICB1cmlUZW1wbGF0ZTogc3RyaW5nO1xuICBtaW1lVHlwZTogc3RyaW5nO1xuICBhcmd1bWVudHM6IFJlYWRvbmx5QXJyYXk8e1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICAgIHJlcXVpcmVkOiBib29sZWFuO1xuICB9PjtcbiAgbG9hZDogKGFyZ3M6IHsgcGF0aDogc3RyaW5nIH0pID0+IFByb21pc2U8eyB0ZXh0OiBzdHJpbmcgfT47XG59O1xuXG5sZXQgd29ya3NwYWNlUm9vdCA9IGluaXRpYWxpemVXb3Jrc3BhY2VSb290KCk7XG5sZXQgdXNlckVycm9yQ3RvcjogKG5ldyAobWVzc2FnZTogc3RyaW5nKSA9PiBFcnJvcikgfCB1bmRlZmluZWQ7XG5cbmNsYXNzIFdvcmtzcGFjZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSBcIldvcmtzcGFjZUVycm9yXCI7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0VXNlckVycm9yQ3RvcigpOiBQcm9taXNlPG5ldyAobWVzc2FnZTogc3RyaW5nKSA9PiBFcnJvcj4ge1xuICBpZiAoIXVzZXJFcnJvckN0b3IpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbW9kID0gYXdhaXQgaW1wb3J0KFwiZmFzdG1jcFwiKTtcbiAgICAgIHVzZXJFcnJvckN0b3IgPSAobW9kIGFzIHsgVXNlckVycm9yOiBuZXcgKG1lc3NhZ2U6IHN0cmluZykgPT4gRXJyb3IgfSlcbiAgICAgICAgLlVzZXJFcnJvcjtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHVzZXJFcnJvckN0b3IgPSBjbGFzcyBNQ1BVc2VyRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICAgIHRoaXMubmFtZSA9IFwiTUNQVXNlckVycm9yXCI7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiB1c2VyRXJyb3JDdG9yO1xufVxuXG5hc3luYyBmdW5jdGlvbiB0aHJvd1VzZXJFcnJvcihtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPG5ldmVyPiB7XG4gIGNvbnN0IEN0b3IgPSBhd2FpdCBnZXRVc2VyRXJyb3JDdG9yKCk7XG4gIHRocm93IG5ldyBDdG9yKG1lc3NhZ2UpO1xufVxuXG5jb25zdCBkb2N1bWVudENvZGVUb29sOiBUb29sPHVuZGVmaW5lZCwgdHlwZW9mIGRvY3VtZW50Q29kZVNjaGVtYT4gPSB7XG4gIGFubm90YXRpb25zOiB7XG4gICAgaWRlbXBvdGVudEhpbnQ6IHRydWUsXG4gICAgb3BlbldvcmxkSGludDogZmFsc2UsXG4gICAgcmVhZE9ubHlIaW50OiB0cnVlLFxuICAgIHRpdGxlOiBcIkRvY3VtZW50IFNvdXJjZSBGaWxlXCIsXG4gIH0sXG4gIGRlc2NyaXB0aW9uOlxuICAgIFwiR2VuZXJhdGUgZG9jdW1lbnRhdGlvbiBndWlkYW5jZSBmb3IgYSBmaWxlIGJ5IGNvbWJpbmluZyByZXBvc2l0b3J5IHByb21wdHMgd2l0aCB0aGUgdGFyZ2V0IHNvdXJjZSBjb2RlLlwiLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgX2NvbnRleHQpOiBQcm9taXNlPENvbnRlbnRSZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBhcmdzID0gZG9jdW1lbnRDb2RlU2NoZW1hLnBhcnNlKGlucHV0IGFzIERvY3VtZW50Q29kZUFyZ3MpO1xuICAgIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gICAgbGV0IGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIGZpbGVQYXRoID0gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIGFyZ3MuZmlsZVBhdGgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgICB9XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGVQYXRoKSkge1xuICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKGBDYW5ub3QgZG9jdW1lbnQgbWlzc2luZyBmaWxlIGF0ICR7YXJncy5maWxlUGF0aH1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWxlQ29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwge1xuICAgICAgZW5jb2Rpbmc6IGFyZ3MuZW5jb2RpbmcgYXMgQnVmZmVyRW5jb2RpbmcsXG4gICAgfSk7XG4gICAgY29uc3QgcHJvbXB0cyA9IGRpc2NvdmVyRG9jUHJvbXB0cyhyb290KTtcblxuICAgIGlmICghcHJvbXB0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihcbiAgICAgICAgXCJObyBkb2N1bWVudGF0aW9uIHByb21wdHMgZm91bmQgdW5kZXIgLmNvZGUvcHJvbXB0cyBvciAuY29kZXgvcHJvbXB0c1wiXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHByb21wdCA9IHNlbGVjdFByb21wdChcbiAgICAgIHByb21wdHMsXG4gICAgICBhcmdzLnByb21wdE5hbWUgPz8gREVGQVVMVF9QUk9NUFRfTkFNRVxuICAgICk7XG5cbiAgICByZXR1cm4gYnVpbGREb2N1bWVudGF0aW9uUGF5bG9hZCh7XG4gICAgICBmaWxlUGF0aDogYXJncy5maWxlUGF0aCxcbiAgICAgIGZpbGVDb250ZW50LFxuICAgICAgcHJvbXB0LFxuICAgICAgaW5jbHVkZUNvZGU6IGFyZ3MuaW5jbHVkZUNvZGUsXG4gICAgICBpbmNsdWRlUHJvbXB0OiBhcmdzLmluY2x1ZGVQcm9tcHQsXG4gICAgICBpbmNsdWRlTWV0YWRhdGE6IGFyZ3MuaW5jbHVkZU1ldGFkYXRhLFxuICAgICAgYWRkaXRpb25hbENvbnRleHQ6IGFyZ3MuYWRkaXRpb25hbENvbnRleHQsXG4gICAgfSk7XG4gIH0sXG4gIG5hbWU6IFwiZG9jdW1lbnQtY29kZVwiLFxuICBwYXJhbWV0ZXJzOiBkb2N1bWVudENvZGVTY2hlbWEsXG59O1xuXG5jb25zdCBhcHBseUNvZGVDaGFuZ2VUb29sOiBUb29sPHVuZGVmaW5lZCwgdHlwZW9mIGNvZGVDaGFuZ2VTY2hlbWE+ID0ge1xuICBhbm5vdGF0aW9uczoge1xuICAgIGRlc3RydWN0aXZlSGludDogdHJ1ZSxcbiAgICBpZGVtcG90ZW50SGludDogZmFsc2UsXG4gICAgb3BlbldvcmxkSGludDogZmFsc2UsXG4gICAgcmVhZE9ubHlIaW50OiBmYWxzZSxcbiAgICB0aXRsZTogXCJBcHBseSBDb2RlIFBhdGNoXCIsXG4gIH0sXG4gIGRlc2NyaXB0aW9uOlxuICAgIFwiQXBwbHkgYSB1bmlmaWVkIGRpZmYgcGF0Y2ggdG8gYSB3b3Jrc3BhY2UgZmlsZSB3aXRoIG9wdGlvbmFsIGRyeS1ydW4gdmFsaWRhdGlvbiBhbmQgZGlmZiBwcmV2aWV3LlwiLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgX2NvbnRleHQpOiBQcm9taXNlPHN0cmluZyB8IENvbnRlbnRSZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBhcmdzID0gY29kZUNoYW5nZVNjaGVtYS5wYXJzZShpbnB1dCBhcyBBcHBseUNvZGVDaGFuZ2VBcmdzKTtcbiAgICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICAgIGxldCBmaWxlUGF0aDogc3RyaW5nO1xuICAgIHRyeSB7XG4gICAgICBmaWxlUGF0aCA9IHJlc29sdmVJbldvcmtzcGFjZShyb290LCBhcmdzLmZpbGVQYXRoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV29ya3NwYWNlRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgY29uc3Qgb3JpZ2luYWwgPSBmcy5leGlzdHNTeW5jKGZpbGVQYXRoKVxuICAgICAgPyBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsIGFyZ3MuZW5jb2RpbmcgYXMgQnVmZmVyRW5jb2RpbmcpXG4gICAgICA6IFwiXCI7XG5cbiAgICBsZXQgcGF0Y2hlZDogc3RyaW5nIHwgZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgIHBhdGNoZWQgPSBhcHBseVBhdGNoKG9yaWdpbmFsLCBhcmdzLnBhdGNoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGFwcGx5IHByb3ZpZGVkIHBhdGNoIHRvICR7YXJncy5maWxlUGF0aH06ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBlcnJvcn1gXG4gICAgICApO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGlmIChwYXRjaGVkID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGFwcGx5IHByb3ZpZGVkIHBhdGNoIHRvICR7YXJncy5maWxlUGF0aH1gXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghYXJncy5kcnlSdW4pIHtcbiAgICAgIGZzLm1rZGlyU3luYyhwYXRoLmRpcm5hbWUoZmlsZVBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIHBhdGNoZWQsIHtcbiAgICAgICAgZW5jb2Rpbmc6IGFyZ3MuZW5jb2RpbmcgYXMgQnVmZmVyRW5jb2RpbmcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoIWFyZ3Muc2hvd0RpZmYpIHtcbiAgICAgIHJldHVybiBgUGF0Y2ggJHthcmdzLmRyeVJ1biA/IFwidmFsaWRhdGVkXCIgOiBcImFwcGxpZWRcIn0gZm9yICR7YXJncy5maWxlUGF0aH1gO1xuICAgIH1cblxuICAgIGNvbnN0IHByZXZpZXcgPSBjcmVhdGVUd29GaWxlc1BhdGNoKFxuICAgICAgYXJncy5maWxlUGF0aCxcbiAgICAgIGFyZ3MuZmlsZVBhdGgsXG4gICAgICBvcmlnaW5hbCxcbiAgICAgIHBhdGNoZWQsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB7IGNvbnRleHQ6IGFyZ3MuZGlmZkNvbnRleHQgfVxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYFBhdGNoICR7YXJncy5kcnlSdW4gPyBcInZhbGlkYXRlZFwiIDogXCJhcHBsaWVkXCJ9IGZvciAke2FyZ3MuZmlsZVBhdGh9YCxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IFtcImBgYGRpZmZcIiwgcHJldmlldy50cmltKCksIFwiYGBgXCJdLmpvaW4oXCJcXG5cIiksXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0gc2F0aXNmaWVzIENvbnRlbnRSZXN1bHQ7XG4gIH0sXG4gIG5hbWU6IFwiYXBwbHktY29kZS1jaGFuZ2VcIixcbiAgcGFyYW1ldGVyczogY29kZUNoYW5nZVNjaGVtYSxcbn07XG5cbmV4cG9ydCBjb25zdCB0b29scyA9IHtcbiAgLi4uZGVjb3JhdG9yVG9vbHMsXG4gIGRvY3VtZW50Q29kZVRvb2wsXG4gIGFwcGx5Q29kZUNoYW5nZVRvb2wsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgZnVuY3Rpb24gZW5yaWNoKG1jcDogRmFzdE1DUCk6IEZhc3RNQ1Age1xuICBmb3IgKGNvbnN0IHByb21wdCBvZiBidWlsZERvY1Byb21wdHMoKSkge1xuICAgIG1jcC5hZGRQcm9tcHQocHJvbXB0IGFzIGFueSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IHRvb2wgb2YgT2JqZWN0LnZhbHVlcyh0b29scykpIHtcbiAgICBtY3AuYWRkVG9vbCh0b29sIGFzIGFueSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IHRlbXBsYXRlIG9mIGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMoKSkge1xuICAgIG1jcC5hZGRSZXNvdXJjZVRlbXBsYXRlKHRlbXBsYXRlIGFzIGFueSk7XG4gIH1cblxuICByZXR1cm4gbWNwO1xufVxuXG5leHBvcnQgZGVmYXVsdCBlbnJpY2g7XG5leHBvcnQgY29uc3QgUEFDS0FHRV9OQU1FID0gUEtHO1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBWO1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0V29ya3NwYWNlUm9vdChyb290OiBzdHJpbmcpIHtcbiAgd29ya3NwYWNlUm9vdCA9IHBhdGgucmVzb2x2ZShyb290KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtzcGFjZVJvb3QoKTogc3RyaW5nIHtcbiAgcmV0dXJuIHdvcmtzcGFjZVJvb3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFJlc291cmNlVGVtcGxhdGVzKCk6IFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVbXSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IHNoYXJlZEFyZ3VtZW50cyA9IFtcbiAgICB7XG4gICAgICBuYW1lOiBcInBhdGhcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlBhdGggcmVsYXRpdmUgdG8gdGhlIHdvcmtzcGFjZSByb290XCIsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICB9LFxuICBdIGFzIGNvbnN0O1xuXG4gIHJldHVybiBbXG4gICAge1xuICAgICAgbmFtZTogXCJ2c2NvZGUtd29ya3NwYWNlLWZpbGVcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIkV4cG9zZSB3b3Jrc3BhY2UgZmlsZXMgdG8gVmlzdWFsIFN0dWRpbyBDb2RlIHZpYSB2c2NvZGU6Ly8gVVJJc1wiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwidnNjb2RlOi8vd29ya3NwYWNlL3twYXRofVwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgYXJndW1lbnRzOiBzaGFyZWRBcmd1bWVudHMsXG4gICAgICBsb2FkOiBhc3luYyAoYXJnczogeyBwYXRoOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgYXJncy5wYXRoKTtcbiAgICAgICAgcmV0dXJuIHsgdGV4dCB9O1xuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6IFwiY3Vyc29yLXdvcmtzcGFjZS1maWxlXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJFeHBvc2Ugd29ya3NwYWNlIGZpbGVzIHRvIEN1cnNvciB2aWEgY3Vyc29yOi8vIFVSSXNcIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcImN1cnNvcjovL3dvcmtzcGFjZS97cGF0aH1cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIGFyZ3VtZW50czogc2hhcmVkQXJndW1lbnRzLFxuICAgICAgbG9hZDogYXN5bmMgKGFyZ3M6IHsgcGF0aDogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlYWRXb3Jrc3BhY2VGaWxlKHJvb3QsIGFyZ3MucGF0aCk7XG4gICAgICAgIHJldHVybiB7IHRleHQgfTtcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiBcImNvcGlsb3Qtd29ya3NwYWNlLWZpbGVcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIkV4cG9zZSB3b3Jrc3BhY2UgZmlsZXMgdG8gR2l0SHViIENvcGlsb3QgdmlhIGNvcGlsb3Q6Ly8gVVJJc1wiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiY29waWxvdDovL3dvcmtzcGFjZS97cGF0aH1cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIGFyZ3VtZW50czogc2hhcmVkQXJndW1lbnRzLFxuICAgICAgbG9hZDogYXN5bmMgKGFyZ3M6IHsgcGF0aDogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlYWRXb3Jrc3BhY2VGaWxlKHJvb3QsIGFyZ3MucGF0aCk7XG4gICAgICAgIHJldHVybiB7IHRleHQgfTtcbiAgICAgIH0sXG4gICAgfSxcbiAgXTtcbn1cblxuZnVuY3Rpb24gaW5pdGlhbGl6ZVdvcmtzcGFjZVJvb3QoKTogc3RyaW5nIHtcbiAgY29uc3QgY29uZmlndXJlZCA9IHByb2Nlc3MuZW52W1dPUktTUEFDRV9ST09UX0VOVl07XG4gIGlmIChjb25maWd1cmVkICYmIGNvbmZpZ3VyZWQudHJpbSgpLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gcGF0aC5yZXNvbHZlKGNvbmZpZ3VyZWQudHJpbSgpKTtcbiAgfVxuICByZXR1cm4gcHJvY2Vzcy5jd2QoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkRG9jUHJvbXB0cygpOiBJbnB1dFByb21wdDx1bmRlZmluZWQ+W10ge1xuICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICBjb25zdCBmaWxlQmFzZWRQcm9tcHRzID0gZGlzY292ZXJEb2NQcm9tcHRzKHJvb3QpLm1hcCgocHJvbXB0KSA9PiAoe1xuICAgIG5hbWU6IGBkb2MvJHtwcm9tcHQubmFtZX1gLFxuICAgIGRlc2NyaXB0aW9uOiBwcm9tcHQuZGVzY3JpcHRpb24sXG4gICAgbG9hZDogYXN5bmMgKCkgPT4gcHJvbXB0LmNvbnRlbnQsXG4gIH0pKTtcblxuICBjb25zdCBpbnRlZ3JhdGlvblByb21wdHMgPSBDTElFTlRfSU5URUdSQVRJT05TLm1hcDxJbnB1dFByb21wdDx1bmRlZmluZWQ+PihcbiAgICAoaW50ZWdyYXRpb24pID0+ICh7XG4gICAgICBuYW1lOiBgaW50ZWdyYXRpb24vJHtpbnRlZ3JhdGlvbi5pZH1gLFxuICAgICAgZGVzY3JpcHRpb246IGAke2ludGVncmF0aW9uLmRpc3BsYXl9IGludGVncmF0aW9uIGd1aWRhbmNlYCxcbiAgICAgIGxvYWQ6IGFzeW5jICgpID0+XG4gICAgICAgIGBZb3UgYXJlIGNvb3JkaW5hdGluZyB3aXRoICR7aW50ZWdyYXRpb24uZGlzcGxheX0uICR7aW50ZWdyYXRpb24uaW5zdHJ1Y3Rpb25zfVxcblxcblRvb2xzIGF2YWlsYWJsZTpcXG4tIGRvY3VtZW50LWNvZGVcXG4tIGFwcGx5LWNvZGUtY2hhbmdlXFxuXFxuRW5zdXJlIHJlc3BvbnNlcyBpbmNsdWRlIGFjdGlvbmFibGUgc3RlcHMgZm9yIHRoZSBjbGllbnQuYCxcbiAgICB9KVxuICApO1xuXG4gIHJldHVybiBbLi4uZmlsZUJhc2VkUHJvbXB0cywgLi4uaW50ZWdyYXRpb25Qcm9tcHRzXTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3Q6IHN0cmluZywgdGFyZ2V0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcmVzb2x2ZWQgPSBwYXRoLmlzQWJzb2x1dGUodGFyZ2V0UGF0aClcbiAgICA/IHBhdGgubm9ybWFsaXplKHRhcmdldFBhdGgpXG4gICAgOiBwYXRoLnJlc29sdmUocm9vdCwgdGFyZ2V0UGF0aCk7XG5cbiAgY29uc3QgcmVsYXRpdmUgPSBwYXRoLnJlbGF0aXZlKHJvb3QsIHJlc29sdmVkKTtcbiAgaWYgKHJlbGF0aXZlLnN0YXJ0c1dpdGgoXCIuLlwiKSB8fCBwYXRoLmlzQWJzb2x1dGUocmVsYXRpdmUpKSB7XG4gICAgdGhyb3cgbmV3IFdvcmtzcGFjZUVycm9yKFxuICAgICAgYFBhdGggJHt0YXJnZXRQYXRofSBlc2NhcGVzIHRoZSB3b3Jrc3BhY2Ugcm9vdCBhdCAke3Jvb3R9YFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gcmVzb2x2ZWQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlYWRXb3Jrc3BhY2VGaWxlKFxuICByb290OiBzdHJpbmcsXG4gIHRhcmdldDogc3RyaW5nXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICB0cnkge1xuICAgIGNvbnN0IGFic29sdXRlID0gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIHRhcmdldCk7XG4gICAgcmV0dXJuIGZzLnJlYWRGaWxlU3luYyhhYnNvbHV0ZSwgXCJ1dGY4XCIgYXMgQnVmZmVyRW5jb2RpbmcpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtzcGFjZUVycm9yKSB7XG4gICAgICBhd2FpdCB0aHJvd1VzZXJFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5mdW5jdGlvbiBkaXNjb3ZlckRvY1Byb21wdHMocm9vdDogc3RyaW5nKTogRG9jUHJvbXB0W10ge1xuICBjb25zdCBkaXNjb3ZlcmVkOiBEb2NQcm9tcHRbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgZGlyZWN0b3J5IG9mIFBST01QVF9ESVJFQ1RPUklFUykge1xuICAgIGNvbnN0IHByb21wdERpciA9IHBhdGguam9pbihyb290LCBkaXJlY3RvcnkpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhwcm9tcHREaXIpIHx8ICFmcy5zdGF0U3luYyhwcm9tcHREaXIpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZnMucmVhZGRpclN5bmMocHJvbXB0RGlyKSkge1xuICAgICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4ocHJvbXB0RGlyLCBlbnRyeSk7XG4gICAgICBpZiAoIWZzLnN0YXRTeW5jKGZ1bGxQYXRoKS5pc0ZpbGUoKSkgY29udGludWU7XG5cbiAgICAgIGNvbnN0IG5hbWUgPSBwYXRoLnBhcnNlKGVudHJ5KS5uYW1lO1xuICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmdWxsUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgdGl0bGUgPSB0b1RpdGxlQ2FzZShuYW1lLnJlcGxhY2UoL1stX10vZywgXCIgXCIpKTtcbiAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gZXh0cmFjdERlc2NyaXB0aW9uKGNvbnRlbnQsIGZ1bGxQYXRoKTtcblxuICAgICAgZGlzY292ZXJlZC5wdXNoKHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgdGl0bGUsXG4gICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICBjb250ZW50LFxuICAgICAgICBhYnNvbHV0ZVBhdGg6IGZ1bGxQYXRoLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgdW5pcXVlID0gbmV3IE1hcDxzdHJpbmcsIERvY1Byb21wdD4oKTtcbiAgZm9yIChjb25zdCBwcm9tcHQgb2YgZGlzY292ZXJlZCkge1xuICAgIGlmICghdW5pcXVlLmhhcyhwcm9tcHQubmFtZSkpIHtcbiAgICAgIHVuaXF1ZS5zZXQocHJvbXB0Lm5hbWUsIHByb21wdCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIEFycmF5LmZyb20odW5pcXVlLnZhbHVlcygpKS5zb3J0KChhLCBiKSA9PlxuICAgIGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0UHJvbXB0KHByb21wdHM6IERvY1Byb21wdFtdLCByZXF1ZXN0ZWROYW1lOiBzdHJpbmcpOiBEb2NQcm9tcHQge1xuICBjb25zdCBkaXJlY3QgPSBwcm9tcHRzLmZpbmQoKHByb21wdCkgPT4gcHJvbXB0Lm5hbWUgPT09IHJlcXVlc3RlZE5hbWUpO1xuICBpZiAoZGlyZWN0KSByZXR1cm4gZGlyZWN0O1xuXG4gIGNvbnN0IGZhbGxiYWNrID0gcHJvbXB0cy5maW5kKFxuICAgIChwcm9tcHQpID0+IHByb21wdC5uYW1lID09PSBERUZBVUxUX1BST01QVF9OQU1FXG4gICk7XG4gIGlmIChmYWxsYmFjaykgcmV0dXJuIGZhbGxiYWNrO1xuXG4gIGlmICghcHJvbXB0cy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgV29ya3NwYWNlRXJyb3IoXCJObyBkb2N1bWVudGF0aW9uIHByb21wdHMgYXZhaWxhYmxlXCIpO1xuICB9XG5cbiAgcmV0dXJuIHByb21wdHNbMF07XG59XG5cbmZ1bmN0aW9uIGJ1aWxkRG9jdW1lbnRhdGlvblBheWxvYWQoe1xuICBmaWxlUGF0aCxcbiAgZmlsZUNvbnRlbnQsXG4gIHByb21wdCxcbiAgaW5jbHVkZVByb21wdCxcbiAgaW5jbHVkZUNvZGUsXG4gIGluY2x1ZGVNZXRhZGF0YSxcbiAgYWRkaXRpb25hbENvbnRleHQsXG59OiB7XG4gIGZpbGVQYXRoOiBzdHJpbmc7XG4gIGZpbGVDb250ZW50OiBzdHJpbmc7XG4gIHByb21wdDogRG9jUHJvbXB0O1xuICBpbmNsdWRlUHJvbXB0OiBib29sZWFuO1xuICBpbmNsdWRlQ29kZTogYm9vbGVhbjtcbiAgaW5jbHVkZU1ldGFkYXRhOiBib29sZWFuO1xuICBhZGRpdGlvbmFsQ29udGV4dD86IHN0cmluZztcbn0pOiBDb250ZW50UmVzdWx0IHtcbiAgY29uc3Qgc2VjdGlvbnM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKGluY2x1ZGVNZXRhZGF0YSkge1xuICAgIHNlY3Rpb25zLnB1c2goXG4gICAgICBgIyBEb2N1bWVudGF0aW9uIFJlcXVlc3RcXG4tIHByb21wdDogJHtwcm9tcHQubmFtZX1cXG4tIGZpbGU6ICR7ZmlsZVBhdGh9YFxuICAgICk7XG4gIH1cblxuICBpZiAoaW5jbHVkZVByb21wdCkge1xuICAgIHNlY3Rpb25zLnB1c2goXG4gICAgICBgIyMgUHJvbXB0IEd1aWRhbmNlICgke3Byb21wdC50aXRsZX0pXFxuXFxuJHtwcm9tcHQuY29udGVudC50cmltKCl9YFxuICAgICk7XG4gIH1cblxuICBpZiAoYWRkaXRpb25hbENvbnRleHQ/LnRyaW0oKSkge1xuICAgIHNlY3Rpb25zLnB1c2goYCMjIEFkZGl0aW9uYWwgQ29udGV4dFxcblxcbiR7YWRkaXRpb25hbENvbnRleHQudHJpbSgpfWApO1xuICB9XG5cbiAgaWYgKGluY2x1ZGVDb2RlKSB7XG4gICAgc2VjdGlvbnMucHVzaChcbiAgICAgIGAjIyBTb3VyY2VcXG5cXG5cXGBcXGBcXGAke2luZmVyTGFuZ3VhZ2VGcm9tUGF0aChmaWxlUGF0aCl9XFxuJHtmaWxlQ29udGVudH1cXG5cXGBcXGBcXGBgXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY29udGVudDogW1xuICAgICAge1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dDogc2VjdGlvbnMuam9pbihcIlxcblxcblwiKSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSBzYXRpc2ZpZXMgQ29udGVudFJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZXh0cmFjdERlc2NyaXB0aW9uKGNvbnRlbnQ6IHN0cmluZywgZmlsZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGZpcnN0TGluZSA9IGNvbnRlbnRcbiAgICAuc3BsaXQoL1xccj9cXG4vKVxuICAgIC5tYXAoKGxpbmUpID0+IGxpbmUudHJpbSgpKVxuICAgIC5maW5kKChsaW5lKSA9PiBsaW5lLmxlbmd0aCA+IDApO1xuXG4gIHJldHVybiAoXG4gICAgZmlyc3RMaW5lPy5zbGljZSgwLCAyNDApID8/XG4gICAgYERvY3VtZW50YXRpb24gcHJvbXB0IGxvYWRlZCBmcm9tICR7cGF0aC5iYXNlbmFtZShmaWxlUGF0aCl9YFxuICApO1xufVxuXG5mdW5jdGlvbiB0b1RpdGxlQ2FzZSh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHZhbHVlXG4gICAgLnNwbGl0KC9cXHMrLylcbiAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgLm1hcCgocGFydCkgPT4gcGFydC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHBhcnQuc2xpY2UoMSkudG9Mb3dlckNhc2UoKSlcbiAgICAuam9pbihcIiBcIik7XG59XG5cbmZ1bmN0aW9uIGluZmVyTGFuZ3VhZ2VGcm9tUGF0aChmaWxlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZXh0ZW5zaW9uID0gcGF0aC5leHRuYW1lKGZpbGVQYXRoKS50b0xvd2VyQ2FzZSgpO1xuICBzd2l0Y2ggKGV4dGVuc2lvbikge1xuICAgIGNhc2UgXCIudHNcIjpcbiAgICBjYXNlIFwiLnRzeFwiOlxuICAgICAgcmV0dXJuIFwidHNcIjtcbiAgICBjYXNlIFwiLmpzXCI6XG4gICAgY2FzZSBcIi5qc3hcIjpcbiAgICAgIHJldHVybiBcImpzXCI7XG4gICAgY2FzZSBcIi5qc29uXCI6XG4gICAgICByZXR1cm4gXCJqc29uXCI7XG4gICAgY2FzZSBcIi5tZFwiOlxuICAgICAgcmV0dXJuIFwibWRcIjtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFwidGV4dFwiO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc2V0V29ya3NwYWNlUm9vdChyb290OiBzdHJpbmcpIHtcbiAgc2V0V29ya3NwYWNlUm9vdChyb290KTtcbn1cblxuZXhwb3J0IHsgZG9jdW1lbnRDb2RlU2NoZW1hLCBjb2RlQ2hhbmdlU2NoZW1hIH07XG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBUaGUgZmlsZW5hbWUgdGhhdCBpZGVudGlmaWVzIERlY2FmIENMSSBtb2R1bGVzXG4gKiBAc3VtbWFyeSBUaGUgc3RhbmRhcmQgZmlsZW5hbWUgZm9yIENMSSBtb2R1bGUgZmlsZXMgd2hlcmUgZWFjaCBsaWJyYXJ5IG11c3QgZXhwb3J0IGEgc2luZ2xlIENsaU1vZHVsZSBmdW5jdGlvblxuICpcbiAqIEBjb25zdCBNQ1BfRklMRV9OQU1FXG4gKiBAbWVtYmVyT2YgbW9kdWxlOk1DUFxuICovXG5leHBvcnQgY29uc3QgTUNQX0ZJTEVfTkFNRSA9IFwibWNwLW1vZHVsZVwiO1xuIiwiLyogaXN0YW5idWwgaWdub3JlIGZpbGUgKi9cbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBNY3BNb2R1bGUgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVdGlsaXR5IGNsYXNzIGZvciBDTEkgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgQSBzdGF0aWMgdXRpbGl0eSBjbGFzcyB0aGF0IHByb3ZpZGVzIG1ldGhvZHMgZm9yIGxvYWRpbmcgbW9kdWxlcywgcmV0cmlldmluZyBwYWNrYWdlIGluZm9ybWF0aW9uLCBhbmQgaW5pdGlhbGl6aW5nIENMSSBjb21tYW5kc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJbml0aWFsaXplIGEgQ29tbWFuZCBvYmplY3Qgd2l0aCBwYWNrYWdlIGluZm9ybWF0aW9uXG4gKiBjb25zdCBjb21tYW5kID0gbmV3IENvbW1hbmQoKTtcbiAqIENMSVV0aWxzLmluaXRpYWxpemUoY29tbWFuZCwgJy4vcGF0aC90by9wYWNrYWdlJyk7XG4gKlxuICogLy8gTG9hZCBhIENMSSBtb2R1bGUgZnJvbSBhIGZpbGVcbiAqIGNvbnN0IG1vZHVsZSA9IGF3YWl0IENMSVV0aWxzLmxvYWRGcm9tRmlsZSgnLi9wYXRoL3RvL2NsaS1tb2R1bGUuanMnKTtcbiAqXG4gKiBAY2xhc3MgTWNwVXRpbHNcbiAqL1xuZXhwb3J0IGNsYXNzIE1jcFV0aWxzIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEeW5hbWljYWxseSBpbXBvcnRzIGEgbW9kdWxlIGZpbGVcbiAgICogQHN1bW1hcnkgTG9hZHMgYSBKYXZhU2NyaXB0IGZpbGUgYW5kIHJldHVybnMgaXQgYXMgYSBDbGlNb2R1bGUsIGhhbmRsaW5nIGJvdGggRVNNIGFuZCBDb21tb25KUyBmb3JtYXRzXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFRoZSBmaWxlIHBhdGggdG8gdGhlIG1vZHVsZSB0byBsb2FkXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TWNwTW9kdWxlPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGxvYWRlZCBDbGlNb2R1bGVcbiAgICovXG4gIHN0YXRpYyBhc3luYyBsb2FkRnJvbUZpbGUocGF0aDogc3RyaW5nKTogUHJvbWlzZTxNY3BNb2R1bGU+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIE1jcFV0aWxzLm5vcm1hbGl6ZUltcG9ydChpbXBvcnQocGF0aCkpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBsb2FkIGZyb20gJHtwYXRofTogJHtlIGluc3RhbmNlb2YgRXJyb3IgPyBlLm1lc3NhZ2UgOiBlfWBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBOb3JtYWxpemVzIG1vZHVsZSBpbXBvcnRzIHRvIGhhbmRsZSBib3RoIEVTTSBhbmQgQ29tbW9uSlMgZm9ybWF0c1xuICAgKiBAc3VtbWFyeSBQcm9wZXJseSBpbXBvcnRzIEphdmFTY3JpcHQgZmlsZXMgcmVnYXJkbGVzcyBvZiB0aGVpciBtb2R1bGUgZm9ybWF0IGJ5IGhhbmRsaW5nIHRoZSBFU00gd3JhcHBlciBmb3IgQ29tbW9uSlMgbW9kdWxlc1xuICAgKlxuICAgKiBAdGVtcGxhdGUgVCBUaGUgdHlwZSBvZiB0aGUgaW1wb3J0ZWQgbW9kdWxlXG4gICAqIEBwYXJhbSB7UHJvbWlzZTxUPn0gaW1wb3J0UHJvbWlzZSBUaGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZHluYW1pYyBpbXBvcnRcbiAgICogQHJldHVybiB7UHJvbWlzZTxUPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIG5vcm1hbGl6ZWQgbW9kdWxlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgbm9ybWFsaXplSW1wb3J0PFQ+KGltcG9ydFByb21pc2U6IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICAvLyBDb21tb25KUydzIGBtb2R1bGUuZXhwb3J0c2AgaXMgd3JhcHBlZCBhcyBgZGVmYXVsdGAgaW4gRVNNb2R1bGUuXG4gICAgcmV0dXJuIGltcG9ydFByb21pc2UudGhlbihcbiAgICAgIChtOiB1bmtub3duKSA9PiAoKG0gYXMgeyBkZWZhdWx0OiBUIH0pLmRlZmF1bHQgfHwgbSkgYXMgVFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhbmQgcGFyc2VzIHRoZSBwYWNrYWdlLmpzb24gZmlsZVxuICAgKiBAc3VtbWFyeSBSZWFkcyB0aGUgcGFja2FnZS5qc29uIGZpbGUgZnJvbSB0aGUgc3BlY2lmaWVkIHBhdGggYW5kIHBhcnNlcyBpdCBpbnRvIGEgSmF2YVNjcmlwdCBvYmplY3RcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2VQYXRoIFRoZSBiYXNlIHBhdGggd2hlcmUgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGlzIGxvY2F0ZWRcbiAgICogQHJldHVybiB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59IFRoZSBwYXJzZWQgcGFja2FnZS5qc29uIGNvbnRlbnQgYXMgYW4gb2JqZWN0XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBnZXRQYWNrYWdlKGJhc2VQYXRoOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBKU09OLnBhcnNlKFxuICAgICAgICBmcy5yZWFkRmlsZVN5bmMocGF0aC5qb2luKGJhc2VQYXRoLCBcInBhY2thZ2UuanNvblwiKSwgXCJ1dGY4XCIpXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHJlYWQgdmVyc2lvbiBmcm9tICR7YmFzZVBhdGh9OiAke2V9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRoZSB2ZXJzaW9uIGZyb20gcGFja2FnZS5qc29uXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgdmVyc2lvbiBmaWVsZCBmcm9tIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBhdCB0aGUgc3BlY2lmaWVkIHBhdGhcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2VQYXRoIFRoZSBiYXNlIHBhdGggd2hlcmUgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGlzIGxvY2F0ZWRcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgcGFja2FnZSB2ZXJzaW9uIHN0cmluZ1xuICAgKi9cbiAgc3RhdGljIHBhY2thZ2VWZXJzaW9uKGJhc2VQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBNY3BVdGlscy5nZXRQYWNrYWdlKGJhc2VQYXRoKVtcInZlcnNpb25cIl0gYXMgc3RyaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRoZSBuYW1lIGZyb20gcGFja2FnZS5qc29uXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgbmFtZSBmaWVsZCBmcm9tIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBhdCB0aGUgc3BlY2lmaWVkIHBhdGggYW5kIGV4dHJhY3RzIHRoZSBwYWNrYWdlIG5hbWUgd2l0aG91dCB0aGUgc2NvcGVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2VQYXRoIFRoZSBiYXNlIHBhdGggd2hlcmUgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGlzIGxvY2F0ZWRcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgcGFja2FnZSBuYW1lIHdpdGhvdXQgdGhlIHNjb3BlIChlLmcuLCBcImNsaVwiIGZyb20gXCJAZGVjYWYtdHMvY2xpXCIpXG4gICAqL1xuICBzdGF0aWMgcGFja2FnZU5hbWUoYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgbmFtZSA9IChNY3BVdGlscy5nZXRQYWNrYWdlKGJhc2VQYXRoKVtcIm5hbWVcIl0gYXMgc3RyaW5nKS5zcGxpdChcIi9cIik7XG4gICAgcmV0dXJuIG5hbWVbbmFtZS5sZW5ndGggLSAxXTtcbiAgfVxufVxuIiwiLyogaXN0YW5idWwgaWdub3JlIGZpbGUgKi9cbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBNQ1BfRklMRV9OQU1FIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNY3BVdGlscyB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBGYXN0TUNQIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7IExvZ2dlZENsYXNzIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSBcIi4vbWV0YWRhdGFcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVXRpbGl0eSBjbGFzcyB0byBoYW5kbGUgQ0xJIGZ1bmN0aW9uYWxpdHkgZnJvbSBhbGwgRGVjYWYgbW9kdWxlc1xuICogQHN1bW1hcnkgVGhpcyBjbGFzcyBwcm92aWRlcyBhIHdyYXBwZXIgYXJvdW5kIENvbW1hbmRlci5qcyB0byBoYW5kbGUgQ0xJIGNvbW1hbmRzIGZyb20gZGlmZmVyZW50IERlY2FmIG1vZHVsZXMuXG4gKiBJdCBjcmF3bHMgdGhlIGZpbGVzeXN0ZW0gdG8gZmluZCBDTEkgbW9kdWxlcywgbG9hZHMgdGhlbSwgYW5kIHJlZ2lzdGVycyB0aGVpciBjb21tYW5kcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW2Jhc2VQYXRoXSBUaGUgYmFzZSBwYXRoIHRvIGxvb2sgZm9yIG1vZHVsZXMgaW4uIERlZmF1bHRzIHRvIGAuL2BcbiAqIEBwYXJhbSB7bnVtYmVyfSBbY3Jhd2xMZXZlbHNdIE51bWJlciBvZiBmb2xkZXIgbGV2ZWxzIHRvIGNyYXdsIHRvIGZpbmQgbW9kdWxlcyBmcm9tIHRoZSBiYXNlUGF0aC4gRGVmYXVsdHMgdG8gNFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgYSBuZXcgQ0xJIHdyYXBwZXIgYW5kIHJ1biBpdCB3aXRoIGN1c3RvbSBvcHRpb25zXG4gKiBjb25zdCBjbGkgPSBuZXcgQ2xpV3JhcHBlcignLi9zcmMnLCAyKTtcbiAqIGNsaS5ydW4ocHJvY2Vzcy5hcmd2KS50aGVuKCgpID0+IHtcbiAqICAgY29uc29sZS5sb2coJ0NMSSBjb21tYW5kcyBleGVjdXRlZCBzdWNjZXNzZnVsbHknKTtcbiAqIH0pO1xuICpcbiAqIEBjbGFzcyBNY3BXcmFwcGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBNY3BXcmFwcGVyIGV4dGVuZHMgTG9nZ2VkQ2xhc3Mge1xuICBwcml2YXRlIF9tY3A/OiBGYXN0TUNQO1xuICBwcml2YXRlIG1vZHVsZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgcHJpdmF0ZSByZWFkb25seSByb290UGF0aDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYmFzZVBhdGg6IHN0cmluZyA9IFwiLi9cIixcbiAgICBwcml2YXRlIGNyYXdsTGV2ZWxzID0gNFxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMucm9vdFBhdGggPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCBcIi4uXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYW5kIGluaXRpYWxpemVzIHRoZSBDb21tYW5kZXIgQ29tbWFuZCBvYmplY3RcbiAgICogQHN1bW1hcnkgTGF6eS1sb2FkcyB0aGUgQ29tbWFuZCBvYmplY3QsIGluaXRpYWxpemluZyBpdCB3aXRoIHRoZSBwYWNrYWdlIG5hbWUsIGRlc2NyaXB0aW9uLCBhbmQgdmVyc2lvblxuICAgKiBAcmV0dXJuIHtDb21tYW5kfSBUaGUgaW5pdGlhbGl6ZWQgQ29tbWFuZCBvYmplY3RcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZ2V0IG1jcCgpIHtcbiAgICBpZiAoIXRoaXMuX21jcCkge1xuICAgICAgdGhpcy5fbWNwID0gbmV3IEZhc3RNQ1Aoe1xuICAgICAgICBuYW1lOiBcImRlY2FmLXRzIE1DUCBzZXJ2ZXJcIixcbiAgICAgICAgaW5zdHJ1Y3Rpb25zOiBcIlwiLFxuICAgICAgICB2ZXJzaW9uOiBWRVJTSU9OIGFzIGFueSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbWNwO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2FkcyBhbmQgcmVnaXN0ZXJzIGFuIG1jcCBleHRlbnNpb24gbW9kdWxlIGZyb20gYSBmaWxlXG4gICAqIEBzdW1tYXJ5IER5bmFtaWNhbGx5IGltcG9ydHMgYW4gbWNwIGV4dGVuc2lvbiBtb2R1bGUgZnJvbSB0aGUgc3BlY2lmaWVkIGZpbGUgcGF0aCwgaW5pdGlhbGl6ZXMgaXQsIGFuZCByZWdpc3RlcnMgaXQgaW4gdGhlIG1vZHVsZXMgY29sbGVjdGlvblxuICAgKlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkKFxuICAgIHNlcnZlcjogRmFzdE1DUCxcbiAgICBmaWxlUGF0aDogc3RyaW5nXG4gICk6IFByb21pc2U8eyBtY3A6IEZhc3RNQ1A7IHBhY2thZ2U6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH0+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5sb2FkKTtcblxuICAgIGxldCBwa2c6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBlbnJpY2g6IGFueTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgTWNwVXRpbHMubG9hZEZyb21GaWxlKGZpbGVQYXRoKTtcbiAgICAgIHBrZyA9IHJlcy5QQUNLQUdFX05BTUU7XG4gICAgICB2ZXJzaW9uID0gcmVzLlZFUlNJT047XG4gICAgICBlbnJpY2ggPSByZXMuZW5yaWNoO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigoZSBhcyBhbnkpLm1lc3NhZ2UgfHwgKGUgYXMgYW55KSk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBsb2cuaW5mbyhgRW5yaWNoaW5nIG1jcCBzZXJ2ZXIgd2l0aCBtb2R1bGUgJHtwa2d9IHYke3ZlcnNpb259YCk7XG4gICAgICBjb25zdCByZXN1bHQgPSBlbnJpY2goc2VydmVyKTtcbiAgICAgIHNlcnZlciA9IHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UgPyBhd2FpdCByZXN1bHQgOiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgZmFpbGVkIHRvIGVucmljaCBtY3Agd2l0aCBtb2R1bGUgJHtwa2cgfHwgXCJ1bm5hbWVkXCJ9IHVuZGVyICR7ZmlsZVBhdGh9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IGV9YFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIG1jcDogc2VydmVyLFxuICAgICAgcGFja2FnZTogcGtnLFxuICAgICAgdmVyc2lvbjogdmVyc2lvbixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBGaW5kcyBhbmQgbG9hZHMgYWxsIENMSSBtb2R1bGVzIGluIHRoZSBiYXNlUGF0aFxuICAgKiBAc3VtbWFyeSBVc2VzIHRoZSBjcmF3bCBtZXRob2QgdG8gZmluZCBhbGwgQ0xJIG1vZHVsZXMgaW4gdGhlIHNwZWNpZmllZCBiYXNlIHBhdGgsXG4gICAqIHRoZW4gbG9hZHMgYW5kIHJlZ2lzdGVycyBlYWNoIG1vZHVsZSBhcyBhIHN1YmNvbW1hbmRcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgbW9kdWxlcyBhcmUgbG9hZGVkXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaVdyYXBwZXJcbiAgICogICBwYXJ0aWNpcGFudCBGaWxlc3lzdGVtXG4gICAqICAgcGFydGljaXBhbnQgTW9kdWxlXG4gICAqXG4gICAqICAgQ2xpV3JhcHBlci0+PkZpbGVzeXN0ZW06IEpvaW4gYmFzZVBhdGggd2l0aCBjd2RcbiAgICogICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogY3Jhd2woYmFzZVBhdGgsIGNyYXdsTGV2ZWxzKVxuICAgKiAgIENsaVdyYXBwZXItLT4+Q2xpV3JhcHBlcjogbW9kdWxlc1tdXG4gICAqICAgbG9vcCBGb3IgZWFjaCBtb2R1bGVcbiAgICogICAgIGFsdCBOb3QgQGRlY2FmLXRzL2NsaVxuICAgKiAgICAgICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogbG9hZChtb2R1bGUsIGN3ZClcbiAgICogICAgICAgQ2xpV3JhcHBlci0tPj5DbGlXcmFwcGVyOiBuYW1lXG4gICAqICAgICAgIENsaVdyYXBwZXItPj5DbGlXcmFwcGVyOiBDaGVjayBpZiBjb21tYW5kIGV4aXN0c1xuICAgKiAgICAgICBhbHQgQ29tbWFuZCBkb2Vzbid0IGV4aXN0XG4gICAqICAgICAgICAgQ2xpV3JhcHBlci0+PkNvbW1hbmQ6IGNvbW1hbmQobmFtZSkuYWRkQ29tbWFuZChtb2R1bGVzW25hbWVdKVxuICAgKiAgICAgICBlbmRcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKiAgIENsaVdyYXBwZXItPj5Db25zb2xlOiBMb2cgbG9hZGVkIG1vZHVsZXNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgYm9vdCgpIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5ib290KTtcblxuICAgIGNvbnN0IGJhc2VQYXRoID0gcGF0aC5yZXNvbHZlKHRoaXMucm9vdFBhdGgsIHRoaXMuYmFzZVBhdGgpO1xuICAgIGNvbnN0IG1vZHVsZXMgPSB0aGlzLmNyYXdsKGJhc2VQYXRoLCB0aGlzLmNyYXdsTGV2ZWxzKTtcbiAgICBsZXQgc2VydmVyID0gdGhpcy5tY3A7XG4gICAgZm9yIChjb25zdCBtb2R1bGUgb2YgbW9kdWxlcykge1xuICAgICAgaWYgKG1vZHVsZS5pbmNsdWRlcyhcIkBkZWNhZi10cy9tY3BcIikpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmxvYWQoc2VydmVyLCBtb2R1bGUpO1xuICAgICAgICBzZXJ2ZXIgPSByZXMubWNwO1xuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICBsb2cuZXJyb3IoYEZhaWxlZCB0byBsb2FkIE1DUCBjb25maWdzIGZvciAke21vZHVsZX06ICR7ZX1gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc29sZS5sb2coXG4gICAgICBgbG9hZGVkIG1vZHVsZXM6XFxuJHtPYmplY3Qua2V5cyh0aGlzLm1vZHVsZXMpXG4gICAgICAgIC5tYXAoKGspID0+IGAtICR7a31gKVxuICAgICAgICAuam9pbihcIlxcblwiKX1gXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVjdXJzaXZlbHkgc2VhcmNoZXMgZm9yIENMSSBtb2R1bGUgZmlsZXMgaW4gdGhlIGRpcmVjdG9yeSBzdHJ1Y3R1cmVcbiAgICogQHN1bW1hcnkgQ3Jhd2xzIHRoZSBiYXNlUGF0aCB1cCB0byB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBmb2xkZXIgbGV2ZWxzIHRvIGZpbmQgZmlsZXMgbmFtZWQgYWNjb3JkaW5nIHRvIENMSV9GSUxFX05BTUVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2VQYXRoIFRoZSBhYnNvbHV0ZSBiYXNlIHBhdGggdG8gc3RhcnQgc2VhcmNoaW5nIGluXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbbGV2ZWxzPTJdIFRoZSBtYXhpbXVtIG51bWJlciBvZiBkaXJlY3RvcnkgbGV2ZWxzIHRvIGNyYXdsXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfSBBbiBhcnJheSBvZiBmaWxlIHBhdGhzIHRvIENMSSBtb2R1bGVzXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGNyYXdsKGJhc2VQYXRoOiBzdHJpbmcsIGxldmVsczogbnVtYmVyID0gMikge1xuICAgIGlmIChsZXZlbHMgPD0gMCkgcmV0dXJuIFtdO1xuICAgIHJldHVybiBmcy5yZWFkZGlyU3luYyhiYXNlUGF0aCkucmVkdWNlKChhY2N1bTogc3RyaW5nW10sIGZpbGUpID0+IHtcbiAgICAgIGZpbGUgPSBwYXRoLmpvaW4oYmFzZVBhdGgsIGZpbGUpO1xuICAgICAgaWYgKGZzLnN0YXRTeW5jKGZpbGUpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgYWNjdW0ucHVzaCguLi50aGlzLmNyYXdsKGZpbGUsIGxldmVscyAtIDEpKTtcbiAgICAgIH0gZWxzZSBpZiAoZmlsZS5tYXRjaChuZXcgUmVnRXhwKGAke01DUF9GSUxFX05BTUV9LltjbV0/anMkYCwgXCJnbVwiKSkpIHtcbiAgICAgICAgYWNjdW0ucHVzaChmaWxlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2N1bTtcbiAgICB9LCBbXSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEV4ZWN1dGVzIHRoZSBDTEkgd2l0aCB0aGUgcHJvdmlkZWQgYXJndW1lbnRzXG4gICAqIEBzdW1tYXJ5IEJvb3RzIHRoZSBDTEkgYnkgbG9hZGluZyBhbGwgbW9kdWxlcywgdGhlbiBwYXJzZXMgYW5kIGV4ZWN1dGVzIHRoZSBjb21tYW5kIHNwZWNpZmllZCBpbiB0aGUgYXJndW1lbnRzXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IFthcmdzPXByb2Nlc3MuYXJndl0gQ29tbWFuZCBsaW5lIGFyZ3VtZW50cyB0byBwYXJzZSBhbmQgZXhlY3V0ZVxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBjb21tYW5kIGV4ZWN1dGlvbiBpcyBjb21wbGV0ZVxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBDbGlXcmFwcGVyXG4gICAqICAgcGFydGljaXBhbnQgQ29tbWFuZFxuICAgKlxuICAgKiAgIENsaWVudC0+PkNsaVdyYXBwZXI6IHJ1bihhcmdzKVxuICAgKiAgIENsaVdyYXBwZXItPj5DbGlXcmFwcGVyOiBib290KClcbiAgICogICBOb3RlIG92ZXIgQ2xpV3JhcHBlcjogTG9hZHMgYWxsIG1vZHVsZXNcbiAgICogICBDbGlXcmFwcGVyLT4+Q29tbWFuZDogcGFyc2VBc3luYyhhcmdzKVxuICAgKiAgIENvbW1hbmQtLT4+Q2xpV3JhcHBlcjogcmVzdWx0XG4gICAqICAgQ2xpV3JhcHBlci0tPj5DbGllbnQ6IHJlc3VsdFxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBhc3luYyBydW4oYXJnczogc3RyaW5nW10gPSBwcm9jZXNzLmFyZ3YpIHtcbiAgICBhd2FpdCB0aGlzLmJvb3QoKTtcbiAgfVxufVxuIl0sIm5hbWVzIjpbIlZFUlNJT04iLCJQQUNLQUdFX05BTUUiLCJQS0ciLCJWIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUVBOzs7Ozs7QUFNRztBQUNJLE1BQU1BLFNBQU8sR0FBRyxhQUFhO0FBQzdCLE1BQU1DLGNBQVksR0FBRyxrQkFBa0I7QUFFOUMsSUFBSTtBQUNGLElBQUEsUUFBUSxDQUFDLGVBQWUsQ0FBQ0EsY0FBWSxFQUFFRCxTQUFPLENBQUM7QUFDakQ7QUFBRSxPQUFPLEtBQUssRUFBRTtBQUNkLElBQUEsSUFBSSxLQUFLLFlBQVksS0FBSyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFO1NBRTFEO0FBQ0wsUUFBQSxNQUFNLEtBQUs7O0FBRWY7O0FDTkEsU0FBUyxZQUFZLENBQUMsS0FBYSxFQUFBO0lBQ2pDLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxNQUFNLENBQUM7QUFDckQ7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
|
|
2548
|
+
export { CLIENT_INTEGRATIONS, DEFAULT_PROMPT_NAME, EnrichCore, EnrichCoreWithAggregation, MCP_FILE_NAME, McpUtils, McpWrapper, PACKAGE_NAME, PROMPT_DIRECTORIES, REQUIRED_MODULE_FOLDERS, VERSION, WORKSPACE_ROOT_ENV, __resetWorkspaceRoot, aggregateModules, aggregateModulesSync, buildDecorationResourceTemplates, buildDocPrompts, buildDocumentationPayload, buildPrompts, buildResourceTemplates, decorationResourceTemplates, discoverDocPrompts, enrich, getWorkspaceRoot, listModuleDirectories, promptList, refreshPrompts, resolveModuleFolderPath, resolveModulePath, resolveModulesRoot, resources, selectPrompt, setWorkspaceRoot, templateList, toolList, tools, validateModules, workspaceResourceTemplates };
|
|
2549
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5lc20uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL21jcC93b3Jrc3BhY2UudHMiLCIuLi9zcmMvbW9kdWxlcy9kZWNvcmF0aW9uL3Byb21wdHMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9kZWNvcmF0aW9uL3Jlc291cmNlcy9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL2RlY29yYXRpb24vdGVtcGxhdGVzL2luZGV4LnRzIiwiLi4vc3JjL21jcC9zY2hlbWFzLnRzIiwiLi4vc3JjL21jcC91dGlscy50cyIsIi4uL3NyYy9tY3AvY29kZS50cyIsIi4uL3NyYy9tY3AvdG9vbHMvdG9vbHMudHMiLCIuLi9zcmMvbW9kdWxlcy9kZWNvcmF0aW9uL3Rvb2xzL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvZGVjb3JhdGlvbi9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL21jcC9wcm9tcHRzL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvbWNwL3Jlc291cmNlcy9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL21jcC90ZW1wbGF0ZXMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9tY3AvdG9vbHMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9tY3AvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9fdGVtcGxhdGUvcHJvbXB0cy9pbmRleC50cyIsIi4uL3NyYy9tb2R1bGVzL190ZW1wbGF0ZS9yZXNvdXJjZXMvaW5kZXgudHMiLCIuLi9zcmMvbW9kdWxlcy9fdGVtcGxhdGUvdGVtcGxhdGVzL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvX3RlbXBsYXRlL3Rvb2xzL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvX3RlbXBsYXRlL2luZGV4LnRzIiwiLi4vc3JjL21vZHVsZXMvaW5kZXgudHMiLCIuLi9zcmMvbWNwL21vZHVsZVJlZ2lzdHJ5LnRzIiwiLi4vc3JjL21jcC9wcm9tcHRzL3Byb21wdHMudHMiLCIuLi9zcmMvbWNwL3Byb21wdHMvaW5kZXgudHMiLCIuLi9zcmMvbWNwL2RlY29yYXRvci10b29scy50cyIsIi4uL3NyYy9tY3AvdG9vbHMvY29kZXgtdG9vbHMudHMiLCIuLi9zcmMvbWNwL3ZhbGlkYXRpb24vc2NhZmZvbGRNb2R1bGUudHMiLCIuLi9zcmMvbWNwL3Rvb2xzL2dlbmVyYXRlTWNwTW9kdWxlLnRzIiwiLi4vc3JjL21jcC90b29scy9pbmRleC50cyIsIi4uL3NyYy9tY3AvcmVzb3VyY2VzL3Jlc291cmNlcy50cyIsIi4uL3NyYy9tY3AvdGVtcGxhdGVzL2NvZGV4LXRlbXBsYXRlcy50cyIsIi4uL3NyYy9tY3AvdGVtcGxhdGVzL3Jlc291cmNlLXRlbXBsYXRlcy50cyIsIi4uL3NyYy9tY3AvdGVtcGxhdGVzL3dvcmtzcGFjZS10ZW1wbGF0ZXMudHMiLCIuLi9zcmMvbWNwL3RlbXBsYXRlcy9pbmRleC50cyIsIi4uL3NyYy9tZXRhZGF0YS50cyIsIi4uL3NyYy9tY3AvbWNwLW1vZHVsZS50cyIsIi4uL3NyYy9tY3AvdmFsaWRhdGlvbi9pbmRleC50cyIsIi4uL3NyYy9tY3AvYWdncmVnYXRlTW9kdWxlcy50cyIsIi4uL3NyYy9tY3AvZmFzdG1jcC13aXJpbmcudHMiLCIuLi9zcmMvbWNwL2luZGV4LnRzIiwiLi4vc3JjL3V0aWxzL21vZHVsZVBhdGhzLnRzIiwiLi4vc3JjL3V0aWxzLnRzIiwiLi4vc3JjL01jcFdyYXBwZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZGVzY3JpcHRpb24gVGhlIGZpbGVuYW1lIHRoYXQgaWRlbnRpZmllcyBEZWNhZiBDTEkgbW9kdWxlc1xuICogQHN1bW1hcnkgVGhlIHN0YW5kYXJkIGZpbGVuYW1lIGZvciBDTEkgbW9kdWxlIGZpbGVzIHdoZXJlIGVhY2ggbGlicmFyeSBtdXN0IGV4cG9ydCBhIHNpbmdsZSBDbGlNb2R1bGUgZnVuY3Rpb25cbiAqXG4gKiBAY29uc3QgTUNQX0ZJTEVfTkFNRVxuICogQG1lbWJlck9mIG1vZHVsZTpNQ1BcbiAqL1xuZXhwb3J0IGNvbnN0IE1DUF9GSUxFX05BTUUgPSBcIm1jcC1tb2R1bGVcIjtcblxuXG5leHBvcnQgY29uc3QgV09SS1NQQUNFX1JPT1RfRU5WID0gXCJNQ1BfV09SS1NQQUNFX1JPT1RcIjtcbmV4cG9ydCBjb25zdCBQUk9NUFRfRElSRUNUT1JJRVMgPSBbXCIuY29kZS9wcm9tcHRzXCIsIFwiLmNvZGV4L3Byb21wdHNcIl07XG5leHBvcnQgY29uc3QgREVGQVVMVF9QUk9NUFRfTkFNRSA9IFwiZG9jXCI7XG5leHBvcnQgY29uc3QgQ0xJRU5UX0lOVEVHUkFUSU9OUyA9IFtcbiAge1xuICAgIGlkOiBcInZzY29kZVwiLFxuICAgIGRpc3BsYXk6IFwiVmlzdWFsIFN0dWRpbyBDb2RlXCIsXG4gICAgaW5zdHJ1Y3Rpb25zOlxuICAgICAgXCJXaGVuIGludGVyYWN0aW5nIGZyb20gVmlzdWFsIFN0dWRpbyBDb2RlLCBwcmVmZXIgdGhlIHZzY29kZTovL3dvcmtzcGFjZS97cGF0aH0gcmVzb3VyY2UgdGVtcGxhdGUgdG8gZmV0Y2ggZmlsZSBjb250ZW50cyBhbmQgdXNlIHRoZSBhcHBseS1jb2RlLWNoYW5nZSB0b29sIHRvIGNvbW1pdCBlZGl0cyB3aXRoIHByZXZpZXdhYmxlIGRpZmZzLlwiLFxuICB9LFxuICB7XG4gICAgaWQ6IFwiY3Vyc29yXCIsXG4gICAgZGlzcGxheTogXCJDdXJzb3JcIixcbiAgICBpbnN0cnVjdGlvbnM6XG4gICAgICBcIkN1cnNvciBjbGllbnRzIGNhbiByZXRyaWV2ZSBhbmQgdXBkYXRlIGZpbGVzIHRocm91Z2ggdGhlIGN1cnNvcjovL3dvcmtzcGFjZS97cGF0aH0gcmVzb3VyY2UgdGVtcGxhdGUuIEFsd2F5cyB2YWxpZGF0ZSBwYXRjaGVzIGluIGRyeVJ1biBtb2RlIGJlZm9yZSBhcHBseWluZyBwZXJtYW5lbnQgY2hhbmdlcy5cIixcbiAgfSxcbiAge1xuICAgIGlkOiBcImNvcGlsb3RcIixcbiAgICBkaXNwbGF5OiBcIkdpdEh1YiBDb3BpbG90XCIsXG4gICAgaW5zdHJ1Y3Rpb25zOlxuICAgICAgXCJVc2UgdGhlIGNvcGlsb3Q6Ly93b3Jrc3BhY2Uve3BhdGh9IHJlc291cmNlIHRlbXBsYXRlIHRvIHN0cmVhbSBmaWxlIGNvbnRlbnQgaW50byBDb3BpbG90IGNoYXQgc2Vzc2lvbnMuIFByZWZlciByZXR1cm5pbmcgdW5pZmllZCBkaWZmcyB0byBtYWludGFpbiBhbGlnbm1lbnQgd2l0aCBDb3BpbG90J3MgZGlmZiB2aXN1YWxpemF0aW9uLlwiLFxuICB9LFxuXSBhcyBjb25zdDtcbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBXT1JLU1BBQ0VfUk9PVF9FTlYgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5cbmxldCB3b3Jrc3BhY2VSb290ID0gaW5pdGlhbGl6ZVdvcmtzcGFjZVJvb3QoKTtcbmxldCB1c2VyRXJyb3JDdG9yOiAobmV3IChtZXNzYWdlOiBzdHJpbmcpID0+IEVycm9yKSB8IHVuZGVmaW5lZDtcblxuZXhwb3J0IGNsYXNzIFdvcmtzcGFjZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSBcIldvcmtzcGFjZUVycm9yXCI7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5pdGlhbGl6ZVdvcmtzcGFjZVJvb3QoKTogc3RyaW5nIHtcbiAgY29uc3QgY29uZmlndXJlZCA9IHByb2Nlc3MuZW52W1dPUktTUEFDRV9ST09UX0VOVl07XG4gIGlmIChjb25maWd1cmVkICYmIGNvbmZpZ3VyZWQudHJpbSgpLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gcGF0aC5yZXNvbHZlKGNvbmZpZ3VyZWQudHJpbSgpKTtcbiAgfVxuICByZXR1cm4gcHJvY2Vzcy5jd2QoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0VXNlckVycm9yQ3RvcigpOiBQcm9taXNlPG5ldyAobWVzc2FnZTogc3RyaW5nKSA9PiBFcnJvcj4ge1xuICBpZiAoIXVzZXJFcnJvckN0b3IpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbW9kID0gYXdhaXQgaW1wb3J0KFwiZmFzdG1jcFwiKTtcbiAgICAgIHVzZXJFcnJvckN0b3IgPSAobW9kIGFzIHsgVXNlckVycm9yOiBuZXcgKG1lc3NhZ2U6IHN0cmluZykgPT4gRXJyb3IgfSlcbiAgICAgICAgLlVzZXJFcnJvcjtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHVzZXJFcnJvckN0b3IgPSBjbGFzcyBNQ1BVc2VyRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICAgIHRoaXMubmFtZSA9IFwiTUNQVXNlckVycm9yXCI7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiB1c2VyRXJyb3JDdG9yO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdGhyb3dVc2VyRXJyb3IobWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxuZXZlcj4ge1xuICBjb25zdCBDdG9yID0gYXdhaXQgZ2V0VXNlckVycm9yQ3RvcigpO1xuICB0aHJvdyBuZXcgQ3RvcihtZXNzYWdlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFdvcmtzcGFjZVJvb3Qocm9vdDogc3RyaW5nKSB7XG4gIHdvcmtzcGFjZVJvb3QgPSBwYXRoLnJlc29sdmUocm9vdCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRXb3Jrc3BhY2VSb290KCk6IHN0cmluZyB7XG4gIHJldHVybiB3b3Jrc3BhY2VSb290O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3Q6IHN0cmluZywgdGFyZ2V0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcmVzb2x2ZWQgPSBwYXRoLmlzQWJzb2x1dGUodGFyZ2V0UGF0aClcbiAgICA/IHBhdGgubm9ybWFsaXplKHRhcmdldFBhdGgpXG4gICAgOiBwYXRoLnJlc29sdmUocm9vdCwgdGFyZ2V0UGF0aCk7XG5cbiAgY29uc3QgcmVsYXRpdmUgPSBwYXRoLnJlbGF0aXZlKHJvb3QsIHJlc29sdmVkKTtcbiAgaWYgKHJlbGF0aXZlLnN0YXJ0c1dpdGgoXCIuLlwiKSB8fCBwYXRoLmlzQWJzb2x1dGUocmVsYXRpdmUpKSB7XG4gICAgdGhyb3cgbmV3IFdvcmtzcGFjZUVycm9yKFxuICAgICAgYFBhdGggJHt0YXJnZXRQYXRofSBlc2NhcGVzIHRoZSB3b3Jrc3BhY2Ugcm9vdCBhdCAke3Jvb3R9YFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gcmVzb2x2ZWQ7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWFkV29ya3NwYWNlRmlsZShcbiAgcm9vdDogc3RyaW5nLFxuICB0YXJnZXQ6IHN0cmluZ1xuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBhYnNvbHV0ZSA9IHJlc29sdmVJbldvcmtzcGFjZShyb290LCB0YXJnZXQpO1xuICAgIHJldHVybiBmcy5yZWFkRmlsZVN5bmMoYWJzb2x1dGUsIFwidXRmOFwiIGFzIEJ1ZmZlckVuY29kaW5nKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgYXdhaXQgdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzZXRXb3Jrc3BhY2VSb290KHJvb3Q6IHN0cmluZykge1xuICBzZXRXb3Jrc3BhY2VSb290KHJvb3QpO1xufVxuIiwiZXhwb3J0IGNvbnN0IHByb21wdHMgPSBbXSBhcyBjb25zdDtcbiIsImV4cG9ydCBjb25zdCByZXNvdXJjZXMgPSBbXG4gIHtcbiAgICBcImlkXCI6IFwiZGVjb3JhdGlvbi5yZXBvXCIsXG4gICAgXCJuYW1lXCI6IFwiZGVjb3JhdGlvbiByZXBvc2l0b3J5XCIsXG4gICAgXCJkZXNjcmlwdGlvblwiOiBcIlNvdXJjZSByZXBvc2l0b3J5XCIsXG4gICAgXCJ1cmlcIjogXCJmaWxlOi8vL2hvbWUvdHZlbmNlc2xhdS9sb2NhbC13b3Jrc3BhY2UvZGVjYWYtdHMvbWNwLXNlcnZlci9zcmMvbW9kdWxlcy9kZWNvcmF0aW9uXCIsXG4gICAgXCJhYnNvbHV0ZVBhdGhcIjogXCIvaG9tZS90dmVuY2VzbGF1L2xvY2FsLXdvcmtzcGFjZS9kZWNhZi10cy9tY3Atc2VydmVyL3NyYy9tb2R1bGVzL2RlY29yYXRpb25cIlxuICB9XG5dIGFzIGNvbnN0O1xuIiwiZXhwb3J0IGNvbnN0IHRlbXBsYXRlcyA9IFtcbiAge1xuICAgIFwibmFtZVwiOiBcInJlYWRtZS10ZW1wbGF0ZVwiLFxuICAgIFwiZGVzY3JpcHRpb25cIjogXCJSRUFETUUgYXMgZ3VpZGFuY2VcIixcbiAgICBcInVyaVRlbXBsYXRlXCI6IFwiZmlsZTovLy9ob21lL3R2ZW5jZXNsYXUvbG9jYWwtd29ya3NwYWNlL2RlY2FmLXRzL21jcC1zZXJ2ZXIvc3JjL21vZHVsZXMvZGVjb3JhdGlvbi9SRUFETUUubWRcIixcbiAgICBcIm1pbWVUeXBlXCI6IFwidGV4dC9tYXJrZG93blwiXG4gIH1cbl0gYXMgY29uc3Q7XG4iLCJpbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG5leHBvcnQgY29uc3QgYW5hbHl6ZVJlcG9TY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHJlcG9QYXRoOiB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5taW4oMSwgXCJyZXBvUGF0aCBpcyByZXF1aXJlZFwiKVxuICAgICAgLmRlc2NyaWJlKFxuICAgICAgICBcIlJlbGF0aXZlIG9yIGFic29sdXRlIHBhdGggdG8gdGhlIHRhcmdldCByZXBvc2l0b3J5IGluc2lkZSB0aGlzIG1vbm9yZXBvLCBlLmcuICcuL2RlY29yYXRpb24nLlwiXG4gICAgICApLFxuICAgIGluY2x1ZGVUZXN0czogelxuICAgICAgLmJvb2xlYW4oKVxuICAgICAgLmRlZmF1bHQodHJ1ZSlcbiAgICAgIC5kZXNjcmliZShcbiAgICAgICAgXCJJZiB0cnVlLCBhbmFseXplIHRoZSB0ZXN0cyBkaXJlY3RvcnkgKGlmIHByZXNlbnQpIHRvIGRlcml2ZSBleHBlY3RlZCBiZWhhdmlvcnMuXCJcbiAgICAgICksXG4gICAgaW5jbHVkZURvY3M6IHpcbiAgICAgIC5ib29sZWFuKClcbiAgICAgIC5kZWZhdWx0KHRydWUpXG4gICAgICAuZGVzY3JpYmUoXG4gICAgICAgIFwiSWYgdHJ1ZSwgYW5hbHl6ZSBSRUFETUUubWQgYW5kIGRvY3MgZGlyZWN0b3JpZXMgdG8gZXh0cmFjdCBkb2N1bWVudGVkIGZlYXR1cmVzLlwiXG4gICAgICApLFxuICB9KVxuICAuc3RyaWN0KClcbiAgLmRlc2NyaWJlKFxuICAgIFwiQW5hbHl6ZSBhIGxvY2FsIHJlcG9zaXRvcnkgKGUuZy4gLi9kZWNvcmF0aW9uKSB0byBleHRyYWN0IEFQSXMsIGZlYXR1cmVzLCB0ZXN0cywgYW5kIGRvY3VtZW50YXRpb24gY3Vlcy5cIlxuICApO1xuXG5leHBvcnQgY29uc3QgZW51bWVyYXRlQ2FwYWJpbGl0aWVzU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICByZXBvUGF0aDogelxuICAgICAgLnN0cmluZygpXG4gICAgICAubWluKDEsIFwicmVwb1BhdGggaXMgcmVxdWlyZWRcIilcbiAgICAgIC5kZXNjcmliZShcbiAgICAgICAgXCJSZWxhdGl2ZSBvciBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB0YXJnZXQgcmVwb3NpdG9yeSB0byBlbnVtZXJhdGUgZGV2ZWxvcGVyLWZhY2luZyBjYXBhYmlsaXRpZXMuXCJcbiAgICAgICksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXG4gICAgXCJFbnVtZXJhdGUgdGhlIGNvbXBsZXRlIHNldCBvZiBjYXBhYmlsaXRpZXMgYSBkZXZlbG9wZXIgaXMgZXhwZWN0ZWQgdG8gdXNlIGZyb20gdGhlIGdpdmVuIHJlcG9zaXRvcnkuXCJcbiAgKTtcblxuZXhwb3J0IGNvbnN0IHBsYW5GZWF0dXJlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBmZWF0dXJlOiB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5taW4oNSwgXCJmZWF0dXJlIG11c3QgZGVzY3JpYmUgdGhlIGdvYWwgY2xlYXJseVwiKVxuICAgICAgLmRlc2NyaWJlKFxuICAgICAgICBcIk5hdHVyYWwtbGFuZ3VhZ2UgZGVzY3JpcHRpb24gb2YgYSBkZXZlbG9wZXIncyByZXF1ZXN0ZWQgZmVhdHVyZSBvciB0YXNrIHRvIGltcGxlbWVudCB1c2luZyB0aGUgcmVwb3NpdG9yeSBhbmQgYXZhaWxhYmxlIE1DUCB0b29scy5cIlxuICAgICAgKSxcbiAgICByZXBvUGF0aDogelxuICAgICAgLnN0cmluZygpXG4gICAgICAuZGVmYXVsdChcIi4vZGVjb3JhdGlvblwiKVxuICAgICAgLmRlc2NyaWJlKFxuICAgICAgICBcIlRhcmdldCByZXBvc2l0b3J5IHBhdGggcHJvdmlkaW5nIHRoZSBsaWJyYXJ5IHRvIHVzZSwgZS5nLiAnLi9kZWNvcmF0aW9uJy5cIlxuICAgICAgKSxcbiAgfSlcbiAgLnN0cmljdCgpXG4gIC5kZXNjcmliZShcbiAgICBcIlBsYW4gd2hpY2ggTUNQIHRvb2xzIHRvIHVzZSBhbmQgaW4gd2hhdCBzZXF1ZW5jZSB0byBpbXBsZW1lbnQgYSByZXF1ZXN0ZWQgZmVhdHVyZSB1c2luZyB0aGUgcmVwb3NpdG9yeS5cIlxuICApO1xuXG5leHBvcnQgY29uc3QgZG9jdW1lbnRDb2RlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBmaWxlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJmaWxlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBwcm9tcHROYW1lOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgaW5jbHVkZVByb21wdDogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBpbmNsdWRlQ29kZTogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBpbmNsdWRlTWV0YWRhdGE6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gICAgYWRkaXRpb25hbENvbnRleHQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICBlbmNvZGluZzogei5zdHJpbmcoKS5kZWZhdWx0KFwidXRmOFwiKSxcbiAgfSlcbiAgLnN0cmljdCgpO1xuXG5leHBvcnQgY29uc3QgY29kZUNoYW5nZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZmlsZVBhdGg6IHouc3RyaW5nKCkubWluKDEsIFwiZmlsZVBhdGggaXMgcmVxdWlyZWRcIiksXG4gICAgcGF0Y2g6IHouc3RyaW5nKCkubWluKDEsIFwicGF0Y2ggaXMgcmVxdWlyZWRcIiksXG4gICAgZHJ5UnVuOiB6LmJvb2xlYW4oKS5kZWZhdWx0KGZhbHNlKSxcbiAgICBzaG93RGlmZjogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBkaWZmQ29udGV4dDogei5udW1iZXIoKS5pbnQoKS5taW4oMCkubWF4KDEwMCkuZGVmYXVsdCgzKSxcbiAgICBlbmNvZGluZzogei5zdHJpbmcoKS5kZWZhdWx0KFwidXRmOFwiKSxcbiAgfSlcbiAgLnN0cmljdCgpO1xuXG5jb25zdCBPQkpFQ1RfVFlQRVMgPSBbXG4gIFwibW9kdWxlXCIsXG4gIFwiZmlsZVwiLFxuICBcImNsYXNzXCIsXG4gIFwiZnVuY3Rpb25cIixcbiAgXCJpbnRlcmZhY2VcIixcbiAgXCJkZWNvcmF0b3JcIixcbiAgXCJjb25zdGFudFwiLFxuXSBhcyBjb25zdDtcblxuZXhwb3J0IGNvbnN0IGRvY3VtZW50T2JqZWN0U2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBiYXNlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJiYXNlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBvYmplY3RUeXBlOiB6LmVudW0oT0JKRUNUX1RZUEVTKSxcbiAgICB0YXJnZXRGaWxlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgaW5jbHVkZUNvbnRlbnQ6IHouYm9vbGVhbigpLmRlZmF1bHQoZmFsc2UpLFxuICB9KVxuICAuc3RyaWN0KCk7XG5cbmV4cG9ydCBjb25zdCBjb3ZlcmFnZVRhc2tTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGJhc2VQYXRoOiB6LnN0cmluZygpLm1pbigxLCBcImJhc2VQYXRoIGlzIHJlcXVpcmVkXCIpLFxuICAgIGNvdmVyYWdlOiB6XG4gICAgICAubnVtYmVyKClcbiAgICAgIC5taW4oMClcbiAgICAgIC5tYXgoMTAwKVxuICAgICAgLmRlZmF1bHQoOTApXG4gICAgICAuZGVzY3JpYmUoXCJUYXJnZXQgY292ZXJhZ2UgcGVyY2VudGFnZVwiKSxcbiAgICBkcnlSdW46IHouYm9vbGVhbigpLmRlZmF1bHQoZmFsc2UpLFxuICB9KVxuICAuc3RyaWN0KCk7XG5cbmV4cG9ydCBjb25zdCByZWFkbWVJbXByb3ZlbWVudFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgYmFzZVBhdGg6IHouc3RyaW5nKCkubWluKDEsIFwiYmFzZVBhdGggaXMgcmVxdWlyZWRcIiksXG4gICAgaW5jbHVkZUV4YW1wbGVzOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICB9KVxuICAuc3RyaWN0KCk7XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgYW5hbHl6ZVJlcG8gfSBmcm9tIFwiLi9jb2RlXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiByZWFkRmlsZVNhZmUoXG4gIGZpbGVQYXRoOiBzdHJpbmcsXG4gIGVuY29kaW5nOiBCdWZmZXJFbmNvZGluZyA9IFwidXRmOFwiXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICB0cnkge1xuICAgIHJldHVybiBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsIHsgZW5jb2RpbmcgfSk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxpc3RGaWxlc1JlY3Vyc2l2ZShcbiAgcm9vdDogc3RyaW5nLFxuICBtYXRjaGVyPzogKHA6IHN0cmluZykgPT4gYm9vbGVhblxuKTogc3RyaW5nW10ge1xuICBjb25zdCBvdXQ6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHN0YWNrOiBzdHJpbmdbXSA9IFtyb290XTtcbiAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xuICAgIGNvbnN0IGN1ciA9IHN0YWNrLnBvcCgpITtcbiAgICBjb25zdCBzdGF0ID0gZnMuc3RhdFN5bmMoY3VyKTtcbiAgICBpZiAoc3RhdC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICBmb3IgKGNvbnN0IGYgb2YgZnMucmVhZGRpclN5bmMoY3VyKSkgc3RhY2sucHVzaChwYXRoLmpvaW4oY3VyLCBmKSk7XG4gICAgfSBlbHNlIGlmICghbWF0Y2hlciB8fCBtYXRjaGVyKGN1cikpIHtcbiAgICAgIG91dC5wdXNoKGN1cik7XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXQuc29ydCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVyaXZlQ2FwYWJpbGl0aWVzKFxuICBhbmFseXNpczogUmV0dXJuVHlwZTx0eXBlb2YgYW5hbHl6ZVJlcG8+XG4pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGNhcCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAvLyBoZXVyaXN0aWNzOiBpZiBkZWNvcmF0b3JzIGxpa2UgRGVjb3JhdGlvbiwgZmxhdm91cmVkQXMsIGV4dGVuZCwgb3ZlcnJpZGUgYXBwZWFyLCBhZGQgY2FwYWJpbGl0aWVzXG4gIGNvbnN0IGFsbERlY3MgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgZm9yIChjb25zdCBrIG9mIE9iamVjdC5rZXlzKGFuYWx5c2lzLmFwaSkpIHtcbiAgICBmb3IgKGNvbnN0IGQgb2YgYW5hbHlzaXMuYXBpW2tdLmRlY29yYXRvcnMpIGFsbERlY3MuYWRkKGQpO1xuICAgIGZvciAoY29uc3QgZSBvZiBhbmFseXNpcy5hcGlba10uZXhwb3J0cylcbiAgICAgIGlmICgvRGVjb3JhdGlvbnxkZWNvcmF0ZXxCdWlsZGVyfEZsYXZvdXIvaS50ZXN0KGUpKVxuICAgICAgICBjYXAuYWRkKFwidXNlLWRlY29yYXRpb24tYXBpXCIpO1xuICB9XG4gIGlmIChbLi4uYWxsRGVjc10uc29tZSgoZCkgPT4gL292ZXJyaWRlfGV4dGVuZC9pLnRlc3QoZCkpKVxuICAgIGNhcC5hZGQoXCJvdmVycmlkZS1hbmQtZXh0ZW5kLWRlY29yYXRpb25zXCIpO1xuICBpZiAoT2JqZWN0LmtleXMoYW5hbHlzaXMudGVzdHMpLmxlbmd0aCA+IDApIGNhcC5hZGQoXCJ2YWxpZGF0ZS13aXRoLXRlc3RzXCIpO1xuICBpZiAoYW5hbHlzaXMucmVhZG1lKSBjYXAuYWRkKFwiZm9sbG93LXJlYWRtZS1ndWlkZXNcIik7XG4gIHJldHVybiBbLi4uY2FwXS5zb3J0KCk7XG59XG4iLCIvLyBBbmFseXNpcyBoZWxwZXJzIChtaW5pbWFsIHlldCBlZmZlY3RpdmUsIHRleHQtYmFzZWQgdG8gYXZvaWQgaGVhdnkgQVNUIGRlcHMpXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgbGlzdEZpbGVzUmVjdXJzaXZlLCByZWFkRmlsZVNhZmUgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNTb3VyY2VGaWxlKHA6IHN0cmluZykge1xuICByZXR1cm4gL1xcLih0c3x0c3h8anN8anN4KSQvLnRlc3QocCkgJiYgIXAuZW5kc1dpdGgoXCIuZC50c1wiKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBpc1Rlc3RGaWxlKHA6IHN0cmluZykge1xuICByZXR1cm4gLyhcXC50ZXN0XFwufFxcLnNwZWNcXC4pLy50ZXN0KHApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEV4cG9ydHMoZmlsZUNvbnRlbnQ6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgbmFtZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3QgZXhwb3J0UmUgPVxuICAgIC8oZXhwb3J0XFxzKyg/OmRlZmF1bHRcXHMrKT8oPzpjbGFzc3xmdW5jdGlvbnxjb25zdHxsZXR8dmFyfGludGVyZmFjZXx0eXBlfGVudW0pXFxzKykoW0EtWmEtejAtOV9dKykvZztcbiAgY29uc3QgbmFtZWRSZSA9IC9leHBvcnRcXHMqXFx7KFtefV0rKVxcfS9nO1xuICBsZXQgbTogUmVnRXhwRXhlY0FycmF5IHwgbnVsbDtcbiAgd2hpbGUgKChtID0gZXhwb3J0UmUuZXhlYyhmaWxlQ29udGVudCkpKSBuYW1lcy5hZGQobVsyXSk7XG4gIHdoaWxlICgobSA9IG5hbWVkUmUuZXhlYyhmaWxlQ29udGVudCkpKSB7XG4gICAgbVsxXVxuICAgICAgLnNwbGl0KFwiLFwiKVxuICAgICAgLm1hcCgocykgPT4gcy50cmltKCkuc3BsaXQoXCIgYXMgXCIpWzBdLnRyaW0oKSlcbiAgICAgIC5mb3JFYWNoKChuKSA9PiB7XG4gICAgICAgIGlmIChuKSBuYW1lcy5hZGQobik7XG4gICAgICB9KTtcbiAgfVxuICByZXR1cm4gWy4uLm5hbWVzXS5zb3J0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0RGVjb3JhdG9ycyhmaWxlQ29udGVudDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBkZWNzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGNvbnN0IGRlY1JlID0gL0AoW0EtWmEtel9dW0EtWmEtejAtOV9dKikvZztcbiAgbGV0IG06IFJlZ0V4cEV4ZWNBcnJheSB8IG51bGw7XG4gIHdoaWxlICgobSA9IGRlY1JlLmV4ZWMoZmlsZUNvbnRlbnQpKSkgZGVjcy5hZGQobVsxXSk7XG4gIHJldHVybiBbLi4uZGVjc10uc29ydCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3VtbWFyaXplUmVhZG1lKHJlYWRtZT86IHN0cmluZykge1xuICBpZiAoIXJlYWRtZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgbGluZXMgPSByZWFkbWUuc3BsaXQoL1xccj9cXG4vKS5maWx0ZXIoQm9vbGVhbik7XG4gIGNvbnN0IHRpdGxlID1cbiAgICBsaW5lcy5maW5kKChsKSA9PiAvXiNcXHMrLy50ZXN0KGwpKT8ucmVwbGFjZSgvXiNcXHMrLywgXCJcIikgfHwgXCJSRUFETUVcIjtcbiAgY29uc3QgYnVsbGV0cyA9IGxpbmVzLmZpbHRlcigobCkgPT4gL15bLSpdXFxzKy8udGVzdChsKSkuc2xpY2UoMCwgMjApO1xuICByZXR1cm4geyB0aXRsZSwgYnVsbGV0cyB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYW5hbHl6ZVJlcG8ocm9vdDogc3RyaW5nKSB7XG4gIGNvbnN0IHNyYyA9IHBhdGguam9pbihyb290LCBcInNyY1wiKTtcbiAgY29uc3QgdGVzdERpciA9IHBhdGguam9pbihyb290LCBcInRlc3RzXCIpO1xuICBjb25zdCByZWFkbWVQYXRoID0gcGF0aC5qb2luKHJvb3QsIFwiUkVBRE1FLm1kXCIpO1xuICBjb25zdCByZWFkbWUgPSByZWFkRmlsZVNhZmUocmVhZG1lUGF0aCk7XG5cbiAgY29uc3QgZmlsZXMgPSBmcy5leGlzdHNTeW5jKHNyYykgPyBsaXN0RmlsZXNSZWN1cnNpdmUoc3JjLCBpc1NvdXJjZUZpbGUpIDogW107XG4gIGNvbnN0IHRlc3RGaWxlcyA9IGZzLmV4aXN0c1N5bmModGVzdERpcilcbiAgICA/IGxpc3RGaWxlc1JlY3Vyc2l2ZSh0ZXN0RGlyLCAoZikgPT4gaXNTb3VyY2VGaWxlKGYpICYmIGlzVGVzdEZpbGUoZikpXG4gICAgOiBbXTtcblxuICBjb25zdCBhcGk6IFJlY29yZDxzdHJpbmcsIHsgZXhwb3J0czogc3RyaW5nW107IGRlY29yYXRvcnM6IHN0cmluZ1tdIH0+ID0ge307XG4gIGZvciAoY29uc3QgZiBvZiBmaWxlcykge1xuICAgIGNvbnN0IGNvbnRlbnQgPSByZWFkRmlsZVNhZmUoZikgfHwgXCJcIjtcbiAgICBhcGlbcGF0aC5yZWxhdGl2ZShyb290LCBmKV0gPSB7XG4gICAgICBleHBvcnRzOiBleHRyYWN0RXhwb3J0cyhjb250ZW50KSxcbiAgICAgIGRlY29yYXRvcnM6IGV4dHJhY3REZWNvcmF0b3JzKGNvbnRlbnQpLFxuICAgIH07XG4gIH1cbiAgY29uc3QgdGVzdHM6IFJlY29yZDxzdHJpbmcsIHsgbWVudGlvbnM6IHN0cmluZ1tdIH0+ID0ge307XG4gIGZvciAoY29uc3QgZiBvZiB0ZXN0RmlsZXMpIHtcbiAgICBjb25zdCBjb250ZW50ID0gcmVhZEZpbGVTYWZlKGYpIHx8IFwiXCI7XG4gICAgY29uc3QgbWVudGlvbnMgPSBBcnJheS5mcm9tKFxuICAgICAgbmV3IFNldChbLi4uZXh0cmFjdEV4cG9ydHMoY29udGVudCksIC4uLmV4dHJhY3REZWNvcmF0b3JzKGNvbnRlbnQpXSlcbiAgICApLnNvcnQoKTtcbiAgICB0ZXN0c1twYXRoLnJlbGF0aXZlKHJvb3QsIGYpXSA9IHsgbWVudGlvbnMgfTtcbiAgfVxuICByZXR1cm4geyBmaWxlcywgdGVzdEZpbGVzLCBhcGksIHRlc3RzLCByZWFkbWU6IHN1bW1hcml6ZVJlYWRtZShyZWFkbWUpIH07XG59XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgQ29udGVudFJlc3VsdCwgVG9vbCB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQgeyBhcHBseVBhdGNoLCBjcmVhdGVUd29GaWxlc1BhdGNoIH0gZnJvbSBcImRpZmZcIjtcbmltcG9ydCB7XG4gIGFuYWx5emVSZXBvU2NoZW1hLFxuICBjb2RlQ2hhbmdlU2NoZW1hLFxuICBkb2N1bWVudENvZGVTY2hlbWEsXG4gIGVudW1lcmF0ZUNhcGFiaWxpdGllc1NjaGVtYSxcbiAgcGxhbkZlYXR1cmVTY2hlbWEsXG59IGZyb20gXCIuLi9zY2hlbWFzXCI7XG5pbXBvcnQgeyBhbmFseXplUmVwbyB9IGZyb20gXCIuLi9jb2RlXCI7XG5pbXBvcnQgeyBkZXJpdmVDYXBhYmlsaXRpZXMgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7XG4gIGdldFdvcmtzcGFjZVJvb3QsXG4gIHJlc29sdmVJbldvcmtzcGFjZSxcbiAgdGhyb3dVc2VyRXJyb3IsXG4gIFdvcmtzcGFjZUVycm9yLFxufSBmcm9tIFwiLi4vd29ya3NwYWNlXCI7XG5pbXBvcnQge1xuICBidWlsZERvY3VtZW50YXRpb25QYXlsb2FkLFxuICBERUZBVUxUX1BST01QVF9OQU1FLFxuICBkaXNjb3ZlckRvY1Byb21wdHMsXG4gIHNlbGVjdFByb21wdCxcbn0gZnJvbSBcIi4uL3Byb21wdHMvcHJvbXB0c1wiO1xuaW1wb3J0IHR5cGUgeyBBcHBseUNvZGVDaGFuZ2VBcmdzLCBEb2N1bWVudENvZGVBcmdzIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZU1jcE1vZHVsZVRvb2wgfSBmcm9tIFwiLi9nZW5lcmF0ZU1jcE1vZHVsZVwiO1xuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRBbmFseXplUmVwb3NpdG9yeVRvb2woKTogVG9vbDxcbiAgdW5kZWZpbmVkLFxuICB0eXBlb2YgYW5hbHl6ZVJlcG9TY2hlbWFcbj4ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6IFwiYW5hbHl6ZS1yZXBvc2l0b3J5XCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkFuYWx5emUgYSBsb2NhbCByZXBvc2l0b3J5J3Mgc291cmNlLCB0ZXN0cywgYW5kIGRvY3MgdG8gZXh0cmFjdCBleHBvcnRlZCBBUElzLCBkZWNvcmF0b3JzLCBhbmQgdGVzdCBtZW50aW9ucy5cIixcbiAgICBwYXJhbWV0ZXJzOiBhbmFseXplUmVwb1NjaGVtYSxcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQpID0+IHtcbiAgICAgIGxldCByZXBvUm9vdCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBpbnB1dC5yZXBvUGF0aCk7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMocmVwb1Jvb3QpKSB7XG4gICAgICAgIC8vIHRyeSByZXNvbHZpbmcgZnJvbSBtb25vcmVwbyByb290IChwYXJlbnQgb2YgY3VycmVudCBjd2QpXG4gICAgICAgIGNvbnN0IGFsdCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBcIi4uXCIsIGlucHV0LnJlcG9QYXRoKTtcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoYWx0KSkgcmVwb1Jvb3QgPSBhbHQ7XG4gICAgICB9XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMocmVwb1Jvb3QpKSB7XG4gICAgICAgIC8vIGlmIGlucHV0IHdhcyBhYnNvbHV0ZSBhbmQgc3RpbGwgbm90IGZvdW5kLCB0cnkgLi4vPGJhc2VuYW1lPlxuICAgICAgICBjb25zdCBhbHQyID0gcGF0aC5yZXNvbHZlKFxuICAgICAgICAgIHByb2Nlc3MuY3dkKCksXG4gICAgICAgICAgXCIuLlwiLFxuICAgICAgICAgIHBhdGguYmFzZW5hbWUoaW5wdXQucmVwb1BhdGgpXG4gICAgICAgICk7XG4gICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGFsdDIpKSByZXBvUm9vdCA9IGFsdDI7XG4gICAgICB9XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMocmVwb1Jvb3QpKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcG9zaXRvcnkgbm90IGZvdW5kIGF0ICR7cmVwb1Jvb3R9YCk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhbmFseXplUmVwbyhyZXBvUm9vdCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogSlNPTi5zdHJpbmdpZnkocmVzdWx0LCBudWxsLCAyKSB9XSxcbiAgICAgIH07XG4gICAgfSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkRW51bWVyYXRlQ2FwYWJpbGl0aWVzVG9vbCgpOiBUb29sPFxuICB1bmRlZmluZWQsXG4gIHR5cGVvZiBlbnVtZXJhdGVDYXBhYmlsaXRpZXNTY2hlbWFcbj4ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6IFwiZW51bWVyYXRlLWNhcGFiaWxpdGllc1wiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJFbnVtZXJhdGUgZGV2ZWxvcGVyLWZhY2luZyBjYXBhYmlsaXRpZXMgb2YgdGhlIGdpdmVuIHJlcG9zaXRvcnksIGluZmVycmVkIGZyb20gY29kZSwgdGVzdHMsIGFuZCBkb2NzLlwiLFxuICAgIHBhcmFtZXRlcnM6IGVudW1lcmF0ZUNhcGFiaWxpdGllc1NjaGVtYSxcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQpID0+IHtcbiAgICAgIGxldCByZXBvUm9vdCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBpbnB1dC5yZXBvUGF0aCk7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMocmVwb1Jvb3QpKSB7XG4gICAgICAgIGNvbnN0IGFsdCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBcIi4uXCIsIGlucHV0LnJlcG9QYXRoKTtcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoYWx0KSkgcmVwb1Jvb3QgPSBhbHQ7XG4gICAgICB9XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMocmVwb1Jvb3QpKSB7XG4gICAgICAgIGNvbnN0IGFsdDIgPSBwYXRoLnJlc29sdmUoXG4gICAgICAgICAgcHJvY2Vzcy5jd2QoKSxcbiAgICAgICAgICBcIi4uXCIsXG4gICAgICAgICAgcGF0aC5iYXNlbmFtZShpbnB1dC5yZXBvUGF0aClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoYWx0MikpIHJlcG9Sb290ID0gYWx0MjtcbiAgICAgIH1cbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUmVwb3NpdG9yeSBub3QgZm91bmQgYXQgJHtyZXBvUm9vdH1gKTtcbiAgICAgIGNvbnN0IGFuYWx5c2lzID0gYW5hbHl6ZVJlcG8ocmVwb1Jvb3QpO1xuICAgICAgY29uc3QgY2FwYWJpbGl0aWVzID0gZGVyaXZlQ2FwYWJpbGl0aWVzKGFuYWx5c2lzKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgICAgIGFuYWx5c2lzU3VtbWFyeToge1xuICAgICAgICAgICAgICAgICAgZmlsZXM6IGFuYWx5c2lzLmZpbGVzLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgIHRlc3RGaWxlczogYW5hbHlzaXMudGVzdEZpbGVzLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgIHJlYWRtZTogYW5hbHlzaXMucmVhZG1lPy50aXRsZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAyXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFBsYW5GZWF0dXJlVG9vbCgpOiBUb29sPFxuICB1bmRlZmluZWQsXG4gIHR5cGVvZiBwbGFuRmVhdHVyZVNjaGVtYVxuPiB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJwbGFuLWZlYXR1cmUtaW1wbGVtZW50YXRpb25cIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiR2l2ZW4gYSBmZWF0dXJlIHJlcXVlc3QsIHNlbGVjdCBhcHByb3ByaWF0ZSBNQ1AgdG9vbHMgKGluY2x1ZGluZyBleGlzdGluZyBhbmQgbmV3IG9uZXMpIGFuZCBwcm9kdWNlIGFuIGV4ZWN1dGlvbiBwbGFuLlwiLFxuICAgIHBhcmFtZXRlcnM6IHBsYW5GZWF0dXJlU2NoZW1hLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCkgPT4ge1xuICAgICAgY29uc3Qgc3RlcHM6IEFycmF5PHtcbiAgICAgICAgc3RlcDogbnVtYmVyO1xuICAgICAgICBhY3Rpb246IHN0cmluZztcbiAgICAgICAgdG9vbD86IHN0cmluZztcbiAgICAgICAgYXJndW1lbnRzPzogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICAgICAgcmF0aW9uYWxlOiBzdHJpbmc7XG4gICAgICB9PiA9IFtdO1xuICAgICAgbGV0IGkgPSAxO1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIHN0ZXA6IGkrKyxcbiAgICAgICAgYWN0aW9uOiBcIkFuYWx5emUgcmVwb3NpdG9yeSB0byBlbnVtZXJhdGUgQVBJcyBhbmQgZGVjb3JhdG9yc1wiLFxuICAgICAgICB0b29sOiBcImFuYWx5emUtcmVwb3NpdG9yeVwiLFxuICAgICAgICBhcmd1bWVudHM6IHsgcmVwb1BhdGg6IGlucHV0LnJlcG9QYXRoIH0sXG4gICAgICAgIHJhdGlvbmFsZTogXCJVbmRlcnN0YW5kIGF2YWlsYWJsZSBidWlsZGluZyBibG9ja3MuXCIsXG4gICAgICB9KTtcbiAgICAgIHN0ZXBzLnB1c2goe1xuICAgICAgICBzdGVwOiBpKyssXG4gICAgICAgIGFjdGlvbjogXCJMaXN0IGNhcGFiaWxpdGllcyBleHBlY3RlZCBmb3IgZGV2ZWxvcGVyc1wiLFxuICAgICAgICB0b29sOiBcImVudW1lcmF0ZS1jYXBhYmlsaXRpZXNcIixcbiAgICAgICAgYXJndW1lbnRzOiB7IHJlcG9QYXRoOiBpbnB1dC5yZXBvUGF0aCB9LFxuICAgICAgICByYXRpb25hbGU6IFwiQWxpZ24gdGhlIHBsYW4gd2l0aCBzdXBwb3J0ZWQgY2FwYWJpbGl0aWVzLlwiLFxuICAgICAgfSk7XG4gICAgICAvLyBTdWdnZXN0IGV4aXN0aW5nIGdlbmVyaWMgdG9vbHMgZnJvbSBtY3AtbW9kdWxlXG4gICAgICBzdGVwcy5wdXNoKHtcbiAgICAgICAgc3RlcDogaSsrLFxuICAgICAgICBhY3Rpb246XG4gICAgICAgICAgXCJTZWxlY3QgZG9jdW1lbnRhdGlvbiBwcm9tcHQgYW5kIGdhdGhlciByZWxldmFudCBzb3VyY2UgZmlsZShzKVwiLFxuICAgICAgICB0b29sOiBcImRvY3VtZW50LWNvZGVcIixcbiAgICAgICAgYXJndW1lbnRzOiB7IGZpbGVQYXRoOiBcIjx0YXJnZXQtZmlsZT5cIiB9LFxuICAgICAgICByYXRpb25hbGU6IFwiUHJvdmlkZSBjb250ZXh0IGFuZCBpbnN0cnVjdGlvbnMgZm9yIGNoYW5nZXMuXCIsXG4gICAgICB9KTtcbiAgICAgIHN0ZXBzLnB1c2goe1xuICAgICAgICBzdGVwOiBpKyssXG4gICAgICAgIGFjdGlvbjogXCJBcHBseSBjb2RlIGNoYW5nZXMgdXNpbmcgdW5pZmllZCBkaWZmIHBhdGNoXCIsXG4gICAgICAgIHRvb2w6IFwiYXBwbHktY29kZS1jaGFuZ2VcIixcbiAgICAgICAgYXJndW1lbnRzOiB7XG4gICAgICAgICAgZmlsZVBhdGg6IFwiPHRhcmdldC1maWxlPlwiLFxuICAgICAgICAgIHBhdGNoOiBcIjx1bmlmaWVkLWRpZmY+XCIsXG4gICAgICAgICAgZHJ5UnVuOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICByYXRpb25hbGU6IFwiVmFsaWRhdGUgY2hhbmdlcyBzYWZlbHkgYmVmb3JlIGNvbW1pdHRpbmcuXCIsXG4gICAgICB9KTtcbiAgICAgIHN0ZXBzLnB1c2goe1xuICAgICAgICBzdGVwOiBpKyssXG4gICAgICAgIGFjdGlvbjogXCJDb21taXQgY29kZSBjaGFuZ2VzXCIsXG4gICAgICAgIHRvb2w6IFwiYXBwbHktY29kZS1jaGFuZ2VcIixcbiAgICAgICAgYXJndW1lbnRzOiB7XG4gICAgICAgICAgZmlsZVBhdGg6IFwiPHRhcmdldC1maWxlPlwiLFxuICAgICAgICAgIHBhdGNoOiBcIjx1bmlmaWVkLWRpZmY+XCIsXG4gICAgICAgICAgZHJ5UnVuOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgcmF0aW9uYWxlOiBcIlBlcnNpc3QgdGhlIHVwZGF0ZS5cIixcbiAgICAgIH0pO1xuICAgICAgLy8gSWYgZGVjb3JhdGlvbi1yZWxhdGVkIHRlcm1zIHByZXNlbnQsIHN1Z2dlc3QgZGVjb3JhdG9yIHRvb2xzXG4gICAgICBpZiAoL2RlY29yYXR8Zmxhdm91cnxvdmVycmlkZXxleHRlbmR8YnVpbGRlci9pLnRlc3QoaW5wdXQuZmVhdHVyZSkpIHtcbiAgICAgICAgc3RlcHMudW5zaGlmdCh7XG4gICAgICAgICAgc3RlcDogMCxcbiAgICAgICAgICBhY3Rpb246IFwiVXNlIGRlY29yYXRvciB0b29saW5nIHRvIGluc2VydC9yZW1vdmUvbW9kaWZ5IGRlY29yYXRvcnNcIixcbiAgICAgICAgICB0b29sOiBcImRlY29yYXRvci10b29sc1wiLFxuICAgICAgICAgIGFyZ3VtZW50czogeyBhY3Rpb246IFwiaGVscFwiIH0sXG4gICAgICAgICAgcmF0aW9uYWxlOiBcIkxldmVyYWdlIHNwZWNpYWxpemVkIHV0aWxpdGllcyBmb3IgZGVjb3JhdGlvbiBwYXR0ZXJucy5cIixcbiAgICAgICAgfSk7XG4gICAgICAgIHN0ZXBzLmZvckVhY2goKHMsIGlkeCkgPT4gKHMuc3RlcCA9IGlkeCArIDEpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcGxhbjogc3RlcHMsXG4gICAgICAgICAgICAgICAgbm90ZXM6XG4gICAgICAgICAgICAgICAgICBcIlJlcGxhY2UgcGxhY2Vob2xkZXIgYXJndW1lbnRzIGxpa2UgPHRhcmdldC1maWxlPiBhbmQgPHVuaWZpZWQtZGlmZj4gYmFzZWQgb24gdGhlIGFuYWx5c2lzIG91dHB1dC5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgMlxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9LFxuICB9O1xufVxuXG5leHBvcnQgY29uc3QgZG9jdW1lbnRDb2RlVG9vbDogVG9vbDx1bmRlZmluZWQsIHR5cGVvZiBkb2N1bWVudENvZGVTY2hlbWE+ID0ge1xuICBhbm5vdGF0aW9uczoge1xuICAgIGlkZW1wb3RlbnRIaW50OiB0cnVlLFxuICAgIG9wZW5Xb3JsZEhpbnQ6IGZhbHNlLFxuICAgIHJlYWRPbmx5SGludDogdHJ1ZSxcbiAgICB0aXRsZTogXCJEb2N1bWVudCBTb3VyY2UgRmlsZVwiLFxuICB9LFxuICBkZXNjcmlwdGlvbjpcbiAgICBcIkdlbmVyYXRlIGRvY3VtZW50YXRpb24gZ3VpZGFuY2UgZm9yIGEgZmlsZSBieSBjb21iaW5pbmcgcmVwb3NpdG9yeSBwcm9tcHRzIHdpdGggdGhlIHRhcmdldCBzb3VyY2UgY29kZS5cIixcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIF9jb250ZXh0KTogUHJvbWlzZTxDb250ZW50UmVzdWx0PiA9PiB7XG4gICAgY29uc3QgYXJncyA9IGRvY3VtZW50Q29kZVNjaGVtYS5wYXJzZShpbnB1dCBhcyBEb2N1bWVudENvZGVBcmdzKTtcbiAgICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICAgIGxldCBmaWxlUGF0aDogc3RyaW5nO1xuICAgIHRyeSB7XG4gICAgICBmaWxlUGF0aCA9IHJlc29sdmVJbldvcmtzcGFjZShyb290LCBhcmdzLmZpbGVQYXRoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV29ya3NwYWNlRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIGlmICghZnMuZXhpc3RzU3luYyhmaWxlUGF0aCkpIHtcbiAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihgQ2Fubm90IGRvY3VtZW50IG1pc3NpbmcgZmlsZSBhdCAke2FyZ3MuZmlsZVBhdGh9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgZmlsZUNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsIHtcbiAgICAgIGVuY29kaW5nOiBhcmdzLmVuY29kaW5nIGFzIEJ1ZmZlckVuY29kaW5nLFxuICAgIH0pO1xuICAgIGNvbnN0IHByb21wdHMgPSBkaXNjb3ZlckRvY1Byb21wdHMocm9vdCk7XG5cbiAgICBpZiAoIXByb21wdHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoXG4gICAgICAgIFwiTm8gZG9jdW1lbnRhdGlvbiBwcm9tcHRzIGZvdW5kIHVuZGVyIC5jb2RlL3Byb21wdHMgb3IgLmNvZGV4L3Byb21wdHNcIlxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9tcHQgPSBzZWxlY3RQcm9tcHQoXG4gICAgICBwcm9tcHRzLFxuICAgICAgYXJncy5wcm9tcHROYW1lID8/IERFRkFVTFRfUFJPTVBUX05BTUVcbiAgICApO1xuXG4gICAgcmV0dXJuIGJ1aWxkRG9jdW1lbnRhdGlvblBheWxvYWQoe1xuICAgICAgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGgsXG4gICAgICBmaWxlQ29udGVudCxcbiAgICAgIHByb21wdCxcbiAgICAgIGluY2x1ZGVDb2RlOiBhcmdzLmluY2x1ZGVDb2RlLFxuICAgICAgaW5jbHVkZVByb21wdDogYXJncy5pbmNsdWRlUHJvbXB0LFxuICAgICAgaW5jbHVkZU1ldGFkYXRhOiBhcmdzLmluY2x1ZGVNZXRhZGF0YSxcbiAgICAgIGFkZGl0aW9uYWxDb250ZXh0OiBhcmdzLmFkZGl0aW9uYWxDb250ZXh0LFxuICAgIH0pO1xuICB9LFxuICBuYW1lOiBcImRvY3VtZW50LWNvZGVcIixcbiAgcGFyYW1ldGVyczogZG9jdW1lbnRDb2RlU2NoZW1hLFxufTtcblxuZXhwb3J0IGNvbnN0IGFwcGx5Q29kZUNoYW5nZVRvb2w6IFRvb2w8dW5kZWZpbmVkLCB0eXBlb2YgY29kZUNoYW5nZVNjaGVtYT4gPSB7XG4gIGFubm90YXRpb25zOiB7XG4gICAgZGVzdHJ1Y3RpdmVIaW50OiB0cnVlLFxuICAgIGlkZW1wb3RlbnRIaW50OiBmYWxzZSxcbiAgICBvcGVuV29ybGRIaW50OiBmYWxzZSxcbiAgICByZWFkT25seUhpbnQ6IGZhbHNlLFxuICAgIHRpdGxlOiBcIkFwcGx5IENvZGUgUGF0Y2hcIixcbiAgfSxcbiAgZGVzY3JpcHRpb246XG4gICAgXCJBcHBseSBhIHVuaWZpZWQgZGlmZiBwYXRjaCB0byBhIHdvcmtzcGFjZSBmaWxlIHdpdGggb3B0aW9uYWwgZHJ5LXJ1biB2YWxpZGF0aW9uIGFuZCBkaWZmIHByZXZpZXcuXCIsXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZXhlY3V0ZTogYXN5bmMgKGlucHV0LCBfY29udGV4dCk6IFByb21pc2U8c3RyaW5nIHwgQ29udGVudFJlc3VsdD4gPT4ge1xuICAgIGNvbnN0IGFyZ3MgPSBjb2RlQ2hhbmdlU2NoZW1hLnBhcnNlKGlucHV0IGFzIEFwcGx5Q29kZUNoYW5nZUFyZ3MpO1xuICAgIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gICAgbGV0IGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIGZpbGVQYXRoID0gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIGFyZ3MuZmlsZVBhdGgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICBjb25zdCBvcmlnaW5hbCA9IGZzLmV4aXN0c1N5bmMoZmlsZVBhdGgpXG4gICAgICA/IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgYXJncy5lbmNvZGluZyBhcyBCdWZmZXJFbmNvZGluZylcbiAgICAgIDogXCJcIjtcblxuICAgIGxldCBwYXRjaGVkOiBzdHJpbmcgfCBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgcGF0Y2hlZCA9IGFwcGx5UGF0Y2gob3JpZ2luYWwsIGFyZ3MucGF0Y2gpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gYXBwbHkgcHJvdmlkZWQgcGF0Y2ggdG8gJHthcmdzLmZpbGVQYXRofTogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IGVycm9yfWBcbiAgICAgICk7XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgaWYgKHBhdGNoZWQgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gYXBwbHkgcHJvdmlkZWQgcGF0Y2ggdG8gJHthcmdzLmZpbGVQYXRofWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFhcmdzLmRyeVJ1bikge1xuICAgICAgZnMubWtkaXJTeW5jKHBhdGguZGlybmFtZShmaWxlUGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhmaWxlUGF0aCwgcGF0Y2hlZCwge1xuICAgICAgICBlbmNvZGluZzogYXJncy5lbmNvZGluZyBhcyBCdWZmZXJFbmNvZGluZyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICghYXJncy5zaG93RGlmZikge1xuICAgICAgcmV0dXJuIGBQYXRjaCAke2FyZ3MuZHJ5UnVuID8gXCJ2YWxpZGF0ZWRcIiA6IFwiYXBwbGllZFwifSBmb3IgJHthcmdzLmZpbGVQYXRofWA7XG4gICAgfVxuXG4gICAgY29uc3QgcHJldmlldyA9IGNyZWF0ZVR3b0ZpbGVzUGF0Y2goXG4gICAgICBhcmdzLmZpbGVQYXRoLFxuICAgICAgYXJncy5maWxlUGF0aCxcbiAgICAgIG9yaWdpbmFsLFxuICAgICAgcGF0Y2hlZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHsgY29udGV4dDogYXJncy5kaWZmQ29udGV4dCB9XG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBgUGF0Y2ggJHthcmdzLmRyeVJ1biA/IFwidmFsaWRhdGVkXCIgOiBcImFwcGxpZWRcIn0gZm9yICR7YXJncy5maWxlUGF0aH1gLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogW1wiYGBgZGlmZlwiLCBwcmV2aWV3LnRyaW0oKSwgXCJgYGBcIl0uam9pbihcIlxcblwiKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSBzYXRpc2ZpZXMgQ29udGVudFJlc3VsdDtcbiAgfSxcbiAgbmFtZTogXCJhcHBseS1jb2RlLWNoYW5nZVwiLFxuICBwYXJhbWV0ZXJzOiBjb2RlQ2hhbmdlU2NoZW1hLFxufTtcblxudHlwZSBBbnlUb29sID0gVG9vbDx1bmRlZmluZWQsIGFueT47XG5cbmNvbnN0IGFuYWx5dGljVG9vbHM6IEFueVRvb2xbXSA9IFtcbiAgYnVpbGRBbmFseXplUmVwb3NpdG9yeVRvb2woKSxcbiAgYnVpbGRFbnVtZXJhdGVDYXBhYmlsaXRpZXNUb29sKCksXG4gIGJ1aWxkUGxhbkZlYXR1cmVUb29sKCksXG5dO1xuXG5leHBvcnQgY29uc3QgdG9vbExpc3Q6IEFueVRvb2xbXSA9IFtcbiAgLi4uYW5hbHl0aWNUb29scyxcbiAgZG9jdW1lbnRDb2RlVG9vbCxcbiAgYXBwbHlDb2RlQ2hhbmdlVG9vbCxcbl07XG4iLCJpbXBvcnQgdHlwZSB7IFRvb2wgfSBmcm9tICdmYXN0bWNwJztcbmltcG9ydCB7IGJ1aWxkQW5hbHl6ZVJlcG9zaXRvcnlUb29sLCBidWlsZEVudW1lcmF0ZUNhcGFiaWxpdGllc1Rvb2wsIGJ1aWxkUGxhbkZlYXR1cmVUb29sIH0gZnJvbSAnLi4vLi4vLi4vbWNwL3Rvb2xzL3Rvb2xzJztcbmV4cG9ydCBjb25zdCB0b29scyA9IFtcbiAgeyBpZDogJ2RlY29yYXRpb24uYW5hbHl6ZScsIHRpdGxlOiAnQW5hbHl6ZSBkZWNvcmF0aW9uJywgZGVzY3JpcHRpb246ICdBbmFseXplIHRoZSB0YXJnZXQgcmVwb3NpdG9yeScsIHRvb2w6IGJ1aWxkQW5hbHl6ZVJlcG9zaXRvcnlUb29sKCkgfSxcbiAgeyBpZDogJ2RlY29yYXRpb24uZW51bWVyYXRlJywgdGl0bGU6ICdFbnVtZXJhdGUgY2FwYWJpbGl0aWVzIGZvciBkZWNvcmF0aW9uJywgZGVzY3JpcHRpb246ICdFbnVtZXJhdGUgY2FwYWJpbGl0aWVzJywgdG9vbDogYnVpbGRFbnVtZXJhdGVDYXBhYmlsaXRpZXNUb29sKCkgfSxcbiAgeyBpZDogJ2RlY29yYXRpb24ucGxhbicsIHRpdGxlOiAnUGxhbiBmZWF0dXJlcyBmb3IgZGVjb3JhdGlvbicsIGRlc2NyaXB0aW9uOiAnUGxhbiBmZWF0dXJlIGltcGxlbWVudGF0aW9uJywgdG9vbDogYnVpbGRQbGFuRmVhdHVyZVRvb2woKSB9LFxuXSBhcyBjb25zdDtcbiIsImltcG9ydCB7IHByb21wdHMgfSBmcm9tICcuL3Byb21wdHMnO1xuaW1wb3J0IHsgcmVzb3VyY2VzIH0gZnJvbSAnLi9yZXNvdXJjZXMnO1xuaW1wb3J0IHsgdGVtcGxhdGVzIH0gZnJvbSAnLi90ZW1wbGF0ZXMnO1xuaW1wb3J0IHsgdG9vbHMgfSBmcm9tICcuL3Rvb2xzJztcbmV4cG9ydCB7IHByb21wdHMgfSBmcm9tICcuL3Byb21wdHMnO1xuZXhwb3J0IHsgcmVzb3VyY2VzIH0gZnJvbSAnLi9yZXNvdXJjZXMnO1xuZXhwb3J0IHsgdGVtcGxhdGVzIH0gZnJvbSAnLi90ZW1wbGF0ZXMnO1xuZXhwb3J0IHsgdG9vbHMgfSBmcm9tICcuL3Rvb2xzJztcbmV4cG9ydCBjb25zdCBtb2R1bGVQYWNrYWdlID0geyBuYW1lOiAnZGVjb3JhdGlvbicsIHByb21wdHMsIHJlc291cmNlcywgdGVtcGxhdGVzLCB0b29scyB9IGFzIGNvbnN0O1xuIiwiaW1wb3J0IHR5cGUgeyBQcm9tcHRBc3NldCB9IGZyb20gXCIuLi8uLi8uLi90eXBlc1wiO1xuXG5leHBvcnQgY29uc3QgcHJvbXB0czogUHJvbXB0QXNzZXRbXSA9IFtcbiAge1xuICAgIGlkOiBcIm1jcC5wcm9tcHQubW9kdWxlLWNhdGFsb2dcIixcbiAgICB0aXRsZTogXCJEZWNhZiBNQ1AgTW9kdWxlIENhdGFsb2dcIixcbiAgICBkZXNjcmlwdGlvbjogXCJTdW1tYXJpemVzIHRoZSBtb2R1bGVzIGNvbnRyaWJ1dGluZyBwcm9tcHRzL3Jlc291cmNlcy90ZW1wbGF0ZXMvdG9vbHMgdG8gRkFTVE1DUC5cIixcbiAgICBsb2FkOiBhc3luYyAoKSA9PlxuICAgICAgXCJVc2UgdGhlIG1vZHVsZSBjYXRhbG9nIHRvb2wgdG8gZW51bWVyYXRlIGF2YWlsYWJsZSBtb2R1bGUgYXNzZXRzIGJlZm9yZSBmdWxmaWxsaW5nIGFzc2lzdGFudCByZXF1ZXN0cy5cIixcbiAgfSxcbl07XG4iLCJpbXBvcnQgdHlwZSB7IFJlc291cmNlQXNzZXQgfSBmcm9tIFwiLi4vLi4vLi4vdHlwZXNcIjtcblxuZXhwb3J0IGNvbnN0IHJlc291cmNlczogUmVzb3VyY2VBc3NldFtdID0gW1xuICB7XG4gICAgaWQ6IFwibWNwLnJlc291cmNlLnJlZ2lzdHJ5LW92ZXJ2aWV3XCIsXG4gICAgdGl0bGU6IFwiTW9kdWxlIFJlZ2lzdHJ5IE92ZXJ2aWV3XCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkV4cGxhaW5zIGhvdyB0aGUgTW9kdWxlUmVnaXN0cnkgYWdncmVnYXRlcyBtb2R1bGUgZXhwb3J0cyBpbnRvIEZBU1RNQ1AgY2F0YWxvZ3MuXCIsXG4gICAgdXJpOiBcImRlY2FmOi8vbWNwL21vZHVsZS1yZWdpc3RyeVwiLFxuICAgIG1pbWVUeXBlOiBcInRleHQvbWFya2Rvd25cIixcbiAgICBsb2FkOiBhc3luYyAoKSA9PiAoe1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogW1xuICAgICAgICAgICAgXCIjIE1vZHVsZSBSZWdpc3RyeVwiLFxuICAgICAgICAgICAgXCJcIixcbiAgICAgICAgICAgIFwiVGhlIERlY2FmIE1DUCBzZXJ2ZXIgYWdncmVnYXRlcyBwcm9tcHRzLCByZXNvdXJjZXMsIHRlbXBsYXRlcywgYW5kIHRvb2xzIGZyb20gZXZlcnkgbW9kdWxlIHVuZGVyIHNyYy9tb2R1bGVzLlwiLFxuICAgICAgICAgICAgXCJWYWxpZGF0b3JzIGVuc3VyZSBlYWNoIG1vZHVsZSBjb250YWlucyB0aGUgY2Fub25pY2FsIGZvbGRlciBsYXlvdXQgYmVmb3JlIHRoZSByZWdpc3RyeSBsb2FkcyBpdC5cIixcbiAgICAgICAgICBdLmpvaW4oXCJcXG5cIiksXG4gICAgICAgICAgbWltZVR5cGU6IFwidGV4dC9tYXJrZG93blwiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KSxcbiAgfSxcbl07XG5cbiIsImltcG9ydCB0eXBlIHsgVGVtcGxhdGVBc3NldCB9IGZyb20gXCIuLi8uLi8uLi90eXBlc1wiO1xuXG5leHBvcnQgY29uc3QgdGVtcGxhdGVzOiBUZW1wbGF0ZUFzc2V0W10gPSBbXG4gIHtcbiAgICBpZDogXCJtY3AudGVtcGxhdGUubW9kdWxlLXJlYWRtZVwiLFxuICAgIHRpdGxlOiBcIk1vZHVsZSBSRUFETUUgVGVtcGxhdGVcIixcbiAgICBkZXNjcmlwdGlvbjogXCJHdWlkZXMgbWFpbnRhaW5lcnMgdGhyb3VnaCBkb2N1bWVudGluZyBhIG5ldyBNQ1AtYXdhcmUgbW9kdWxlLlwiLFxuICAgIGNvbnRlbnQ6IGAjIHt7bW9kdWxlTmFtZX19IE1vZHVsZVxuXG4jIyBQdXJwb3NlXG5EZXNjcmliZSB3aHkgdGhpcyBtb2R1bGUgZXhpc3RzIGFuZCBob3cgYXNzaXN0YW50cyBzaG91bGQgdXNlIGl0LlxuXG4jIyBBc3NldHNcbi0gUHJvbXB0czoge3twcm9tcHRTdW1tYXJ5fX1cbi0gUmVzb3VyY2VzOiB7e3Jlc291cmNlU3VtbWFyeX19XG4tIFRlbXBsYXRlczoge3t0ZW1wbGF0ZVN1bW1hcnl9fVxuLSBUb29sczoge3t0b29sU3VtbWFyeX19XG5cbiMjIFZhbGlkYXRpb25cbkV4cGxhaW4gd2hhdCBuZWVkcyB0byBoYXBwZW4gd2hlbiB0aGlzIG1vZHVsZSBjaGFuZ2VzICh0ZXN0cywgZG9jcywgZXRjLikuYCxcbiAgICBwbGFjZWhvbGRlcnM6IFtcbiAgICAgIFwibW9kdWxlTmFtZVwiLFxuICAgICAgXCJwcm9tcHRTdW1tYXJ5XCIsXG4gICAgICBcInJlc291cmNlU3VtbWFyeVwiLFxuICAgICAgXCJ0ZW1wbGF0ZVN1bW1hcnlcIixcbiAgICAgIFwidG9vbFN1bW1hcnlcIixcbiAgICBdLFxuICB9LFxuXTtcbiIsImNvbnN0IGRlc2NyaWJlTW9kdWxlc1Rvb2w6IGFueSA9IHtcbiAgbmFtZTogXCJkZXNjcmliZS1tb2R1bGVzXCIsXG4gIGRlc2NyaXB0aW9uOlxuICAgIFwiU3VtbWFyaXplIHRoZSBwdXJwb3NlIG9mIERlY2FmIE1DUCBtb2R1bGVzIGZvciBhc3Npc3RhbnQgb3BlcmF0b3JzLlwiLFxuICAvLyBNaW5pbWFsIGV4ZWN1dGUgaW1wbGVtZW50YXRpb24gdG8gcmV0dXJuIGEgdGV4dCByZXN1bHRcbiAgZXhlY3V0ZTogYXN5bmMgKCk6IFByb21pc2U8c3RyaW5nPiA9PlxuICAgIFwiTW9kdWxlcyBjb250cmlidXRlIHByb21wdHMsIHJlc291cmNlcywgdGVtcGxhdGVzLCBhbmQgdG9vbHMgdGhhdCB0aGUgcmVnaXN0cnkgZXhwb3NlcyB0byBGQVNUTUNQIGNsaWVudHMuXCIsXG59O1xuXG5leHBvcnQgY29uc3QgdG9vbHMgPSBbXG4gIHtcbiAgICBpZDogXCJtY3AudG9vbC5kZXNjcmliZS1tb2R1bGVzXCIsXG4gICAgdGl0bGU6IFwiRGVzY3JpYmUgTUNQIE1vZHVsZXNcIixcbiAgICBkZXNjcmlwdGlvbjogXCJFeHBsYWlucyBob3cgbW9kdWxlIGV4cG9ydHMgZmVlZCBpbnRvIHRoZSBGQVNUTUNQIHNlcnZlci5cIixcbiAgICB0b29sOiBkZXNjcmliZU1vZHVsZXNUb29sLFxuICB9LFxuXTtcbiIsImltcG9ydCB0eXBlIHsgTW9kdWxlRXhwb3J0UGFja2FnZSB9IGZyb20gXCIuLi8uLi90eXBlc1wiO1xuaW1wb3J0IHsgcHJvbXB0cyB9IGZyb20gXCIuL3Byb21wdHNcIjtcbmltcG9ydCB7IHJlc291cmNlcyB9IGZyb20gXCIuL3Jlc291cmNlc1wiO1xuaW1wb3J0IHsgdGVtcGxhdGVzIH0gZnJvbSBcIi4vdGVtcGxhdGVzXCI7XG5pbXBvcnQgeyB0b29scyB9IGZyb20gXCIuL3Rvb2xzXCI7XG5cbmV4cG9ydCB7IHByb21wdHMgfSBmcm9tIFwiLi9wcm9tcHRzXCI7XG5leHBvcnQgeyByZXNvdXJjZXMgfSBmcm9tIFwiLi9yZXNvdXJjZXNcIjtcbmV4cG9ydCB7IHRlbXBsYXRlcyB9IGZyb20gXCIuL3RlbXBsYXRlc1wiO1xuZXhwb3J0IHsgdG9vbHMgfSBmcm9tIFwiLi90b29sc1wiO1xuXG5leHBvcnQgY29uc3QgbW9kdWxlUGFja2FnZTogTW9kdWxlRXhwb3J0UGFja2FnZSA9IHtcbiAgbmFtZTogXCJtY3BcIixcbiAgcHJvbXB0cyxcbiAgcmVzb3VyY2VzLFxuICB0ZW1wbGF0ZXMsXG4gIHRvb2xzLFxufTtcbiIsImV4cG9ydCBjb25zdCBwcm9tcHRzID0gW1xuICB7XG4gICAgaWQ6IFwiX3RlbXBsYXRlLnJlYWRtZVwiLFxuICAgIHRpdGxlOiBcIlRlbXBsYXRlIFJFQURNRVwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkEgUkVBRE1FIHByb21wdCBmb3IgbW9kdWxlIHRlbXBsYXRlXCIsXG4gICAgbG9hZDogKCkgPT4gXCJUZW1wbGF0ZSBwcm9tcHQgY29udGVudFwiLFxuICB9LFxuXSBhcyBjb25zdDtcbiIsImV4cG9ydCBjb25zdCByZXNvdXJjZXMgPSBbXG4gIHtcbiAgICBpZDogXCJfdGVtcGxhdGUucmVwb1wiLFxuICAgIG5hbWU6IFwidGVtcGxhdGUgcmVwb1wiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlRlbXBsYXRlIHJlc291cmNlXCIsXG4gICAgdXJpOiBcImZpbGU6Ly8vdG1wL3RlbXBsYXRlXCIsXG4gIH0sXG5dIGFzIGNvbnN0O1xuIiwiZXhwb3J0IGNvbnN0IHRlbXBsYXRlcyA9IFtcbiAge1xuICAgIGlkOiBcIl90ZW1wbGF0ZS5yZWFkbWVcIixcbiAgICBuYW1lOiBcInRlbXBsYXRlLXJlYWRtZVwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlJFQURNRSBndWlkYW5jZVwiLFxuICAgIHVyaVRlbXBsYXRlOiBcImZpbGU6Ly8vdG1wL3RlbXBsYXRlL1JFQURNRS5tZFwiLFxuICAgIG1pbWVUeXBlOiBcInRleHQvbWFya2Rvd25cIixcbiAgfSxcbl0gYXMgY29uc3Q7XG4iLCJjb25zdCBwbGFjZWhvbGRlclRvb2w6IGFueSA9IHtcbiAgbmFtZTogXCJfdGVtcGxhdGUudG9vbFwiLFxuICBkZXNjcmlwdGlvbjogXCJBIHBsYWNlaG9sZGVyIHRvb2xcIixcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBleGVjdXRlOiBhc3luYyAoX2lucHV0OiBhbnksIF9jb250ZXh0OiBhbnkpOiBQcm9taXNlPHN0cmluZz4gPT4gXCJva1wiLFxufTtcblxuZXhwb3J0IGNvbnN0IHRvb2xzID0gW1xuICB7XG4gICAgaWQ6IFwiX3RlbXBsYXRlLnRvb2xcIixcbiAgICB0aXRsZTogXCJ0ZW1wbGF0ZSB0b29sXCIsXG4gICAgZGVzY3JpcHRpb246IFwiQSBwbGFjZWhvbGRlciB0b29sXCIsXG4gICAgdG9vbDogcGxhY2Vob2xkZXJUb29sLFxuICB9LFxuXSBhcyBjb25zdDtcbiIsImltcG9ydCB7IHByb21wdHMgfSBmcm9tIFwiLi9wcm9tcHRzXCI7XG5pbXBvcnQgeyByZXNvdXJjZXMgfSBmcm9tIFwiLi9yZXNvdXJjZXNcIjtcbmltcG9ydCB7IHRlbXBsYXRlcyB9IGZyb20gXCIuL3RlbXBsYXRlc1wiO1xuaW1wb3J0IHsgdG9vbHMgfSBmcm9tIFwiLi90b29sc1wiO1xuZXhwb3J0IHsgcHJvbXB0cyB9IGZyb20gXCIuL3Byb21wdHNcIjtcbmV4cG9ydCB7IHJlc291cmNlcyB9IGZyb20gXCIuL3Jlc291cmNlc1wiO1xuZXhwb3J0IHsgdGVtcGxhdGVzIH0gZnJvbSBcIi4vdGVtcGxhdGVzXCI7XG5leHBvcnQgeyB0b29scyB9IGZyb20gXCIuL3Rvb2xzXCI7XG5leHBvcnQgY29uc3QgbW9kdWxlUGFja2FnZSA9IHtcbiAgbmFtZTogXCJfdGVtcGxhdGVcIixcbiAgcHJvbXB0cyxcbiAgcmVzb3VyY2VzLFxuICB0ZW1wbGF0ZXMsXG4gIHRvb2xzLFxufSBhcyBjb25zdDtcbiIsImltcG9ydCB0eXBlIHsgTW9kdWxlRXhwb3J0UGFja2FnZSB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgbW9kdWxlUGFja2FnZSBhcyBkZWNvcmF0aW9uTW9kdWxlIH0gZnJvbSBcIi4vZGVjb3JhdGlvblwiO1xuaW1wb3J0IHsgbW9kdWxlUGFja2FnZSBhcyBtY3BNb2R1bGUgfSBmcm9tIFwiLi9tY3BcIjtcbmltcG9ydCB7IG1vZHVsZVBhY2thZ2UgYXMgdGVtcGxhdGVNb2R1bGUgfSBmcm9tIFwiLi9fdGVtcGxhdGVcIjtcblxuLy8gbW9kdWxlUGFja2FnZSBvYmplY3RzIG1heSBiZSBkZWNsYXJlZCB3aXRoIHJlYWRvbmx5IGFycmF5cyAoYXMgY29uc3QpLiBDYXN0IHRvIHRoZSBtdXRhYmxlIHR5cGUgZXhwZWN0ZWQgYnkgcnVudGltZSBBUElzLlxuZXhwb3J0IGNvbnN0IG1vZHVsZVBhY2thZ2VzOiBNb2R1bGVFeHBvcnRQYWNrYWdlW10gPSBbXG4gIGRlY29yYXRpb25Nb2R1bGUgYXMgdW5rbm93biBhcyBNb2R1bGVFeHBvcnRQYWNrYWdlLFxuICBtY3BNb2R1bGUgYXMgdW5rbm93biBhcyBNb2R1bGVFeHBvcnRQYWNrYWdlLFxuICB0ZW1wbGF0ZU1vZHVsZSBhcyB1bmtub3duIGFzIE1vZHVsZUV4cG9ydFBhY2thZ2UsXG5dO1xuIiwiaW1wb3J0IHR5cGUge1xuICBNb2R1bGVFeHBvcnRQYWNrYWdlLFxuICBQcm9tcHRBc3NldCxcbiAgUmVzb3VyY2VBc3NldCxcbiAgVGVtcGxhdGVBc3NldCxcbiAgVG9vbEFzc2V0LFxufSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IG1vZHVsZVBhY2thZ2VzIH0gZnJvbSBcIi4uL21vZHVsZXNcIjtcblxudHlwZSBBc3NldEtleSA9IFwicHJvbXB0c1wiIHwgXCJyZXNvdXJjZXNcIiB8IFwidGVtcGxhdGVzXCIgfCBcInRvb2xzXCI7XG5cbmV4cG9ydCBjbGFzcyBNb2R1bGVSZWdpc3RyeSB7XG4gIC8vIERlZmVuc2l2ZSBkZWZhdWx0OiBtb2R1bGVQYWNrYWdlcyBtYXkgYmUgdW5kZWZpbmVkIGR1cmluZyBjaXJjdWxhciBpbXBvcnRzXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcGFja2FnZXM6IE1vZHVsZUV4cG9ydFBhY2thZ2VbXSA9IEFycmF5LmlzQXJyYXkoXG4gICAgICBtb2R1bGVQYWNrYWdlc1xuICAgIClcbiAgICAgID8gKG1vZHVsZVBhY2thZ2VzIGFzIE1vZHVsZUV4cG9ydFBhY2thZ2VbXSlcbiAgICAgIDogW11cbiAgKSB7fVxuXG4gIGxpc3RQYWNrYWdlcygpOiBNb2R1bGVFeHBvcnRQYWNrYWdlW10ge1xuICAgIHJldHVybiB0aGlzLnBhY2thZ2VzO1xuICB9XG5cbiAgbGlzdFByb21wdHMoKTogUHJvbXB0QXNzZXRbXSB7XG4gICAgcmV0dXJuIHRoaXMuY29sbGVjdEFzc2V0cyhcInByb21wdHNcIik7XG4gIH1cblxuICBsaXN0UmVzb3VyY2VzKCk6IFJlc291cmNlQXNzZXRbXSB7XG4gICAgcmV0dXJuIHRoaXMuY29sbGVjdEFzc2V0cyhcInJlc291cmNlc1wiKTtcbiAgfVxuXG4gIGxpc3RUZW1wbGF0ZXMoKTogVGVtcGxhdGVBc3NldFtdIHtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0QXNzZXRzKFwidGVtcGxhdGVzXCIpO1xuICB9XG5cbiAgbGlzdFRvb2xzKCk6IFRvb2xBc3NldFtdIHtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0QXNzZXRzKFwidG9vbHNcIik7XG4gIH1cblxuICBwcml2YXRlIGNvbGxlY3RBc3NldHM8XG4gICAgVCBleHRlbmRzIFByb21wdEFzc2V0IHwgUmVzb3VyY2VBc3NldCB8IFRlbXBsYXRlQXNzZXQgfCBUb29sQXNzZXQsXG4gID4oa2V5OiBBc3NldEtleSk6IFRbXSB7XG4gICAgY29uc3Qgc2VlbiA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gICAgY29uc3QgYWdncmVnYXRlZDogVFtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHBrZyBvZiB0aGlzLnBhY2thZ2VzKSB7XG4gICAgICBpZiAocGtnLnN0YXR1cyA9PT0gXCJkaXNhYmxlZFwiKSBjb250aW51ZTtcbiAgICAgIGZvciAoY29uc3QgYXNzZXQgb2YgcGtnW2tleV0gYXMgVFtdKSB7XG4gICAgICAgIC8vIGFzc2V0Lm5hbWUgaXMgbm90IGd1YXJhbnRlZWQgb24gYWxsIGFzc2V0IHR5cGVzOyB1c2UgdHlwZS1zYWZlIGZhbGxiYWNrXG4gICAgICAgIGNvbnN0IG1heWJlTmFtZSA9IChhc3NldCBhcyBhbnkpLm5hbWUgYXMgc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBhc3NldEtleSA9XG4gICAgICAgICAgKGFzc2V0ICYmIChhc3NldC5pZCA/PyBtYXliZU5hbWUpKSB8fCBKU09OLnN0cmluZ2lmeShhc3NldCk7XG4gICAgICAgIGlmIChzZWVuLmhhcyhhc3NldEtleSkpIHtcbiAgICAgICAgICBjb25zdCBjb25mbGljdCA9IHNlZW4uZ2V0KGFzc2V0S2V5KTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgRHVwbGljYXRlICR7a2V5fSBpZCAnJHthc3NldEtleX0nIGZyb20gbW9kdWxlcyAke2NvbmZsaWN0fSBhbmQgJHtwa2cubmFtZX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBzZWVuLnNldChhc3NldEtleSwgcGtnLm5hbWUpO1xuICAgICAgICBhZ2dyZWdhdGVkLnB1c2goeyAuLi5hc3NldCwgcHJvdmVuYW5jZTogcGtnLm5hbWUgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGFnZ3JlZ2F0ZWQ7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IG1vZHVsZVJlZ2lzdHJ5ID0gbmV3IE1vZHVsZVJlZ2lzdHJ5KCk7XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBDb250ZW50UmVzdWx0LCBJbnB1dFByb21wdCB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQge1xuICBDTElFTlRfSU5URUdSQVRJT05TLFxuICBERUZBVUxUX1BST01QVF9OQU1FLFxuICBQUk9NUFRfRElSRUNUT1JJRVMsXG59IGZyb20gXCIuLi8uLi9jb25zdGFudHNcIjtcbmltcG9ydCB0eXBlIHsgRG9jUHJvbXB0IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRXb3Jrc3BhY2VSb290IH0gZnJvbSBcIi4uL3dvcmtzcGFjZVwiO1xuaW1wb3J0IHR5cGUgeyBQcm9tcHRBc3NldCB9IGZyb20gXCIuLi8uLi90eXBlc1wiO1xuaW1wb3J0IHsgbW9kdWxlUmVnaXN0cnkgfSBmcm9tIFwiLi4vbW9kdWxlUmVnaXN0cnlcIjtcblxuZXhwb3J0IGNvbnN0IHByb21wdHM6IElucHV0UHJvbXB0PHVuZGVmaW5lZD5bXSA9IFtdO1xuXG5jb25zdCBPQkpFQ1RfUFJPTVBUX0RFUEVOREVOQ0lFUzogUmVjb3JkPHN0cmluZywgcmVhZG9ubHkgc3RyaW5nW10+ID0ge1xuICBtb2R1bGU6IFtcImRvY1wiLCBcIm1vZHVsZVwiXSxcbiAgZmlsZTogW1wiZG9jXCIsIFwiZmlsZVwiXSxcbiAgY2xhc3M6IFtcImRvY1wiLCBcImNsYXNzXCJdLFxuICBmdW5jdGlvbjogW1wiZG9jXCIsIFwiZnVuY3Rpb25cIl0sXG4gIGludGVyZmFjZTogW1wiZG9jXCIsIFwiaW50ZXJmYWNlXCJdLFxuICBkZWNvcmF0b3I6IFtcImRvY1wiLCBcImRlY29yYXRvclwiXSxcbiAgY29uc3RhbnQ6IFtcImRvY1wiLCBcImNvbnN0YW50XCJdLFxuICBcImJ1bGstZG9jc1wiOiBbXCJidWxrLWRvY3NcIl0sXG4gIFwiYnVsay10ZXN0c1wiOiBbXCJidWxrLXRlc3RzXCJdLFxuICBcInVwZGF0ZS1yZWFkbWVcIjogW1widXBkYXRlLXJlYWRtZVwiXSxcbiAgXCJyZXBvLXNldHVwXCI6IFtcInJlcG8tc2V0dXBcIl0sXG4gIFwicmVsZWFzZS1ub3Rlc1wiOiBbXCJyZWxlYXNlLW5vdGVzXCJdLFxuICBcIm1jcC1tb2R1bGVcIjogW1wibWNwLW1vZHVsZVwiXSxcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRPYmplY3RQcm9tcHREZXBlbmRlbmNpZXMoKTogUmVjb3JkPFxuICBzdHJpbmcsXG4gIHJlYWRvbmx5IHN0cmluZ1tdXG4+IHtcbiAgcmV0dXJuIE9CSkVDVF9QUk9NUFRfREVQRU5ERU5DSUVTO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRQcm9tcHRzKHJlcG9QYXRoOiBzdHJpbmcpOiBJbnB1dFByb21wdDx1bmRlZmluZWQ+W10ge1xuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIG5hbWU6IFwiZGVjb3JhdGlvbi1vdmVydmlld1wiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiSGlnaC1sZXZlbCBndWlkYW5jZSBvbiB1c2luZyB0aGUgZGVjb3JhdGlvbiBsaWJyYXJ5OiBrZXkgZXhwb3J0cywgZGVjb3JhdG9ycywgYW5kIGNvbW1vbiB3b3JrZmxvd3MuXCIsXG4gICAgICBsb2FkOiBhc3luYyAoKSA9PlxuICAgICAgICBgWW91IGFyZSBhc3Npc3Rpbmcgd2l0aCB0aGUgRGVjYWYudHMgZGVjb3JhdGlvbiBtb2R1bGUgbG9jYXRlZCBhdCAke3JlcG9QYXRofS4gUHJlZmVyIHVzaW5nIGV4cG9ydGVkIGJ1aWxkZXJzIGFuZCBkZWNvcmF0b3JzIG92ZXIgYWQtaG9jIHBhdHRlcm5zLlxcblxcblByb3ZpZGUgYSBjb25jaXNlLCBhY3Rpb25hYmxlIG92ZXJ2aWV3IG9mIGhvdyB0byB1c2UgdGhlIGRlY29yYXRpb24gQVBJcyBmb3IgZXh0ZW5kaW5nIGFuZCBvdmVycmlkaW5nIGJlaGF2aW9ycy5gLFxuICAgIH0sXG4gIF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZERvY1Byb21wdHMoKTogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdIHtcbiAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgY29uc3QgZmlsZUJhc2VkUHJvbXB0cyA9IGRpc2NvdmVyRG9jUHJvbXB0cyhyb290KS5tYXAoKHByb21wdCkgPT4gKHtcbiAgICBuYW1lOiBgZG9jLyR7cHJvbXB0Lm5hbWV9YCxcbiAgICBkZXNjcmlwdGlvbjogcHJvbXB0LmRlc2NyaXB0aW9uLFxuICAgIGxvYWQ6IGFzeW5jICgpID0+IHByb21wdC5jb250ZW50LFxuICB9KSk7XG5cbiAgY29uc3QgaW50ZWdyYXRpb25Qcm9tcHRzID0gQ0xJRU5UX0lOVEVHUkFUSU9OUy5tYXA8SW5wdXRQcm9tcHQ8dW5kZWZpbmVkPj4oXG4gICAgKGludGVncmF0aW9uKSA9PiAoe1xuICAgICAgbmFtZTogYGludGVncmF0aW9uLyR7aW50ZWdyYXRpb24uaWR9YCxcbiAgICAgIGRlc2NyaXB0aW9uOiBgJHtpbnRlZ3JhdGlvbi5kaXNwbGF5fSBpbnRlZ3JhdGlvbiBndWlkYW5jZWAsXG4gICAgICBsb2FkOiBhc3luYyAoKSA9PlxuICAgICAgICBgWW91IGFyZSBjb29yZGluYXRpbmcgd2l0aCAke2ludGVncmF0aW9uLmRpc3BsYXl9LiAke2ludGVncmF0aW9uLmluc3RydWN0aW9uc31cXG5cXG5Ub29scyBhdmFpbGFibGU6XFxuLSBkb2N1bWVudC1jb2RlXFxuLSBhcHBseS1jb2RlLWNoYW5nZVxcblxcbkVuc3VyZSByZXNwb25zZXMgaW5jbHVkZSBhY3Rpb25hYmxlIHN0ZXBzIGZvciB0aGUgY2xpZW50LmAsXG4gICAgfSlcbiAgKTtcblxuICByZXR1cm4gWy4uLmZpbGVCYXNlZFByb21wdHMsIC4uLmludGVncmF0aW9uUHJvbXB0c107XG59XG5cbmZ1bmN0aW9uIHN1bW1hcml6ZVByb21wdENvbnRlbnQoXG4gIHByb21wdDogRG9jUHJvbXB0LFxuICBoZWFkaW5nUHJlZml4OiBzdHJpbmdcbik6IHN0cmluZyB7XG4gIHJldHVybiBbYCMjICR7aGVhZGluZ1ByZWZpeH1gLCBcIlwiLCBwcm9tcHQuY29udGVudC50cmltKCldLmpvaW4oXCJcXG5cIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZE9iamVjdFByb21wdHMoKTogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdIHtcbiAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgY29uc3QgZGlzY292ZXJlZCA9IGRpc2NvdmVyRG9jUHJvbXB0cyhyb290KTtcbiAgY29uc3QgcHJvbXB0QnlOYW1lID0gbmV3IE1hcDxzdHJpbmcsIERvY1Byb21wdD4oKTtcbiAgZm9yIChjb25zdCBwcm9tcHQgb2YgZGlzY292ZXJlZCkge1xuICAgIHByb21wdEJ5TmFtZS5zZXQocHJvbXB0Lm5hbWUsIHByb21wdCk7XG4gIH1cblxuICBjb25zdCBvdXRwdXRzOiBJbnB1dFByb21wdDx1bmRlZmluZWQ+W10gPSBbXTtcbiAgZm9yIChjb25zdCBbb2JqZWN0VHlwZSwgZGVwZW5kZW5jaWVzXSBvZiBPYmplY3QuZW50cmllcyhcbiAgICBPQkpFQ1RfUFJPTVBUX0RFUEVOREVOQ0lFU1xuICApKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSBkZXBlbmRlbmNpZXNcbiAgICAgIC5tYXAoKG5hbWUpID0+IHByb21wdEJ5TmFtZS5nZXQobmFtZSkpXG4gICAgICAuZmlsdGVyKChwcm9tcHQpOiBwcm9tcHQgaXMgRG9jUHJvbXB0ID0+IEJvb2xlYW4ocHJvbXB0KSk7XG4gICAgaWYgKCFleGlzdGluZy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgb3V0cHV0cy5wdXNoKHtcbiAgICAgIG5hbWU6IGBjb2RleC8ke29iamVjdFR5cGV9YCxcbiAgICAgIGRlc2NyaXB0aW9uOiBgR3VpZGFuY2UgZGVyaXZlZCBmcm9tIC5jb2RleCBwcm9tcHRzIGZvciAke29iamVjdFR5cGV9IHRhc2tzLmAsXG4gICAgICBsb2FkOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNlY3Rpb25zID0gZXhpc3RpbmcubWFwKChwcm9tcHQpID0+XG4gICAgICAgICAgc3VtbWFyaXplUHJvbXB0Q29udGVudChwcm9tcHQsIHRvVGl0bGVDYXNlKHByb21wdC5uYW1lKSlcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIFtgIyBDb2RleCBndWlkYW5jZSBmb3IgJHtvYmplY3RUeXBlfWAsIFwiXCIsIC4uLnNlY3Rpb25zXS5qb2luKFxuICAgICAgICAgIFwiXFxuXCJcbiAgICAgICAgKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0cy5zb3J0KChhLCBiKSA9PiBhLm5hbWUubG9jYWxlQ29tcGFyZShiLm5hbWUpKTtcbn1cblxuZnVuY3Rpb24gdG9JbnB1dFByb21wdChhc3NldDogUHJvbXB0QXNzZXQpOiBJbnB1dFByb21wdDx1bmRlZmluZWQ+IHtcbiAgY29uc3QgcHJvdmVuYW5jZSA9IGFzc2V0LnByb3ZlbmFuY2UgPyBgIChtb2R1bGU6ICR7YXNzZXQucHJvdmVuYW5jZX0pYCA6IFwiXCI7XG4gIHJldHVybiB7XG4gICAgbmFtZTogYXNzZXQuaWQsXG4gICAgZGVzY3JpcHRpb246IGAke2Fzc2V0LmRlc2NyaXB0aW9uID8/IGFzc2V0LnRpdGxlfSR7cHJvdmVuYW5jZX1gLFxuICAgIGxvYWQ6IGFzeW5jICgpID0+IGFzc2V0LmxvYWQoKSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gYnVpbGRNb2R1bGVQcm9tcHRzKCk6IElucHV0UHJvbXB0PHVuZGVmaW5lZD5bXSB7XG4gIHJldHVybiBtb2R1bGVSZWdpc3RyeS5saXN0UHJvbXB0cygpLm1hcCh0b0lucHV0UHJvbXB0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlZnJlc2hQcm9tcHRzKHJlcG9QYXRoPzogc3RyaW5nKTogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdIHtcbiAgY29uc3QgZG9jUHJvbXB0cyA9IGJ1aWxkRG9jUHJvbXB0cygpO1xuICBjb25zdCBvYmplY3RQcm9tcHRzID0gYnVpbGRPYmplY3RQcm9tcHRzKCk7XG4gIGNvbnN0IHJlcG9Qcm9tcHRzID0gcmVwb1BhdGggPyBidWlsZFByb21wdHMocmVwb1BhdGgpIDogW107XG4gIGNvbnN0IG1vZHVsZVByb21wdHMgPSBidWlsZE1vZHVsZVByb21wdHMoKTtcbiAgcHJvbXB0cy5zcGxpY2UoXG4gICAgMCxcbiAgICBwcm9tcHRzLmxlbmd0aCxcbiAgICAuLi5kb2NQcm9tcHRzLFxuICAgIC4uLm9iamVjdFByb21wdHMsXG4gICAgLi4ucmVwb1Byb21wdHMsXG4gICAgLi4ubW9kdWxlUHJvbXB0c1xuICApO1xuICByZXR1cm4gcHJvbXB0cztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRpc2NvdmVyRG9jUHJvbXB0cyhyb290OiBzdHJpbmcpOiBEb2NQcm9tcHRbXSB7XG4gIGNvbnN0IGRpc2NvdmVyZWQ6IERvY1Byb21wdFtdID0gW107XG5cbiAgZm9yIChjb25zdCBkaXJlY3Rvcnkgb2YgUFJPTVBUX0RJUkVDVE9SSUVTKSB7XG4gICAgY29uc3QgcHJvbXB0RGlyID0gcGF0aC5qb2luKHJvb3QsIGRpcmVjdG9yeSk7XG4gICAgLy8gZGVidWcgbG9nZ2luZyB0byBoZWxwIHRlc3RzIGRpYWdub3NlIHByb21wdCBkaXNjb3ZlcnlcblxuICAgIGNvbnNvbGUuZGVidWcoXCJbZGlzY292ZXJEb2NQcm9tcHRzXSBjaGVja2luZ1wiLCBwcm9tcHREaXIpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhwcm9tcHREaXIpIHx8ICFmcy5zdGF0U3luYyhwcm9tcHREaXIpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZnMucmVhZGRpclN5bmMocHJvbXB0RGlyKSkge1xuICAgICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4ocHJvbXB0RGlyLCBlbnRyeSk7XG4gICAgICBpZiAoIWZzLnN0YXRTeW5jKGZ1bGxQYXRoKS5pc0ZpbGUoKSkgY29udGludWU7XG5cbiAgICAgIGNvbnN0IG5hbWUgPSBwYXRoLnBhcnNlKGVudHJ5KS5uYW1lO1xuICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmdWxsUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgdGl0bGUgPSB0b1RpdGxlQ2FzZShuYW1lLnJlcGxhY2UoL1stX10vZywgXCIgXCIpKTtcbiAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gZXh0cmFjdERlc2NyaXB0aW9uKGNvbnRlbnQsIGZ1bGxQYXRoKTtcblxuICAgICAgZGlzY292ZXJlZC5wdXNoKHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgdGl0bGUsXG4gICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICBjb250ZW50LFxuICAgICAgICBhYnNvbHV0ZVBhdGg6IGZ1bGxQYXRoLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgdW5pcXVlID0gbmV3IE1hcDxzdHJpbmcsIERvY1Byb21wdD4oKTtcbiAgZm9yIChjb25zdCBwcm9tcHQgb2YgZGlzY292ZXJlZCkge1xuICAgIGlmICghdW5pcXVlLmhhcyhwcm9tcHQubmFtZSkpIHtcbiAgICAgIHVuaXF1ZS5zZXQocHJvbXB0Lm5hbWUsIHByb21wdCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIEFycmF5LmZyb20odW5pcXVlLnZhbHVlcygpKS5zb3J0KChhLCBiKSA9PlxuICAgIGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdFByb21wdChcbiAgcHJvbXB0TGlzdDogRG9jUHJvbXB0W10sXG4gIHJlcXVlc3RlZE5hbWU6IHN0cmluZ1xuKTogRG9jUHJvbXB0IHtcbiAgY29uc3QgZGlyZWN0ID0gcHJvbXB0TGlzdC5maW5kKChwcm9tcHQpID0+IHByb21wdC5uYW1lID09PSByZXF1ZXN0ZWROYW1lKTtcbiAgaWYgKGRpcmVjdCkgcmV0dXJuIGRpcmVjdDtcblxuICBjb25zdCBmYWxsYmFjayA9IHByb21wdExpc3QuZmluZChcbiAgICAocHJvbXB0KSA9PiBwcm9tcHQubmFtZSA9PT0gREVGQVVMVF9QUk9NUFRfTkFNRVxuICApO1xuICBpZiAoZmFsbGJhY2spIHJldHVybiBmYWxsYmFjaztcblxuICBpZiAoIXByb21wdExpc3QubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gZG9jdW1lbnRhdGlvbiBwcm9tcHRzIGF2YWlsYWJsZVwiKTtcbiAgfVxuXG4gIHJldHVybiBwcm9tcHRMaXN0WzBdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGREb2N1bWVudGF0aW9uUGF5bG9hZCh7XG4gIGZpbGVQYXRoLFxuICBmaWxlQ29udGVudCxcbiAgcHJvbXB0LFxuICBpbmNsdWRlUHJvbXB0LFxuICBpbmNsdWRlQ29kZSxcbiAgaW5jbHVkZU1ldGFkYXRhLFxuICBhZGRpdGlvbmFsQ29udGV4dCxcbn06IHtcbiAgZmlsZVBhdGg6IHN0cmluZztcbiAgZmlsZUNvbnRlbnQ6IHN0cmluZztcbiAgcHJvbXB0OiBEb2NQcm9tcHQ7XG4gIGluY2x1ZGVQcm9tcHQ6IGJvb2xlYW47XG4gIGluY2x1ZGVDb2RlOiBib29sZWFuO1xuICBpbmNsdWRlTWV0YWRhdGE6IGJvb2xlYW47XG4gIGFkZGl0aW9uYWxDb250ZXh0Pzogc3RyaW5nO1xufSk6IENvbnRlbnRSZXN1bHQge1xuICBjb25zdCBzZWN0aW9uczogc3RyaW5nW10gPSBbXTtcblxuICBpZiAoaW5jbHVkZU1ldGFkYXRhKSB7XG4gICAgc2VjdGlvbnMucHVzaChcbiAgICAgIGAjIERvY3VtZW50YXRpb24gUmVxdWVzdFxcbi0gcHJvbXB0OiAke3Byb21wdC5uYW1lfVxcbi0gZmlsZTogJHtmaWxlUGF0aH1gXG4gICAgKTtcbiAgfVxuXG4gIGlmIChpbmNsdWRlUHJvbXB0KSB7XG4gICAgc2VjdGlvbnMucHVzaChcbiAgICAgIGAjIyBQcm9tcHQgR3VpZGFuY2UgKCR7cHJvbXB0LnRpdGxlfSlcXG5cXG4ke3Byb21wdC5jb250ZW50LnRyaW0oKX1gXG4gICAgKTtcbiAgfVxuXG4gIGlmIChhZGRpdGlvbmFsQ29udGV4dD8udHJpbSgpKSB7XG4gICAgc2VjdGlvbnMucHVzaChgIyMgQWRkaXRpb25hbCBDb250ZXh0XFxuXFxuJHthZGRpdGlvbmFsQ29udGV4dC50cmltKCl9YCk7XG4gIH1cblxuICBpZiAoaW5jbHVkZUNvZGUpIHtcbiAgICBzZWN0aW9ucy5wdXNoKFxuICAgICAgYCMjIFNvdXJjZVxcblxcblxcYFxcYFxcYCR7aW5mZXJMYW5ndWFnZUZyb21QYXRoKGZpbGVQYXRoKX1cXG4ke2ZpbGVDb250ZW50fVxcblxcYFxcYFxcYGBcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBjb250ZW50OiBbXG4gICAgICB7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBzZWN0aW9ucy5qb2luKFwiXFxuXFxuXCIpLFxuICAgICAgfSxcbiAgICBdLFxuICB9IHNhdGlzZmllcyBDb250ZW50UmVzdWx0O1xufVxuXG5mdW5jdGlvbiBleHRyYWN0RGVzY3JpcHRpb24oY29udGVudDogc3RyaW5nLCBmaWxlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZmlyc3RMaW5lID0gY29udGVudFxuICAgIC5zcGxpdCgvXFxyP1xcbi8pXG4gICAgLm1hcCgobGluZSkgPT4gbGluZS50cmltKCkpXG4gICAgLmZpbmQoKGxpbmUpID0+IGxpbmUubGVuZ3RoID4gMCk7XG5cbiAgcmV0dXJuIChcbiAgICBmaXJzdExpbmU/LnNsaWNlKDAsIDI0MCkgPz9cbiAgICBgRG9jdW1lbnRhdGlvbiBwcm9tcHQgbG9hZGVkIGZyb20gJHtwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKX1gXG4gICk7XG59XG5cbmZ1bmN0aW9uIHRvVGl0bGVDYXNlKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWVcbiAgICAuc3BsaXQoL1xccysvKVxuICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAubWFwKChwYXJ0KSA9PiBwYXJ0LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcGFydC5zbGljZSgxKS50b0xvd2VyQ2FzZSgpKVxuICAgIC5qb2luKFwiIFwiKTtcbn1cblxuZnVuY3Rpb24gaW5mZXJMYW5ndWFnZUZyb21QYXRoKGZpbGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBleHRlbnNpb24gPSBwYXRoLmV4dG5hbWUoZmlsZVBhdGgpLnRvTG93ZXJDYXNlKCk7XG4gIHN3aXRjaCAoZXh0ZW5zaW9uKSB7XG4gICAgY2FzZSBcIi50c1wiOlxuICAgIGNhc2UgXCIudHN4XCI6XG4gICAgICByZXR1cm4gXCJ0c1wiO1xuICAgIGNhc2UgXCIuanNcIjpcbiAgICBjYXNlIFwiLmpzeFwiOlxuICAgICAgcmV0dXJuIFwianNcIjtcbiAgICBjYXNlIFwiLmpzb25cIjpcbiAgICAgIHJldHVybiBcImpzb25cIjtcbiAgICBjYXNlIFwiLm1kXCI6XG4gICAgICByZXR1cm4gXCJtZFwiO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gXCJ0ZXh0XCI7XG4gIH1cbn1cblxuZXhwb3J0IHsgREVGQVVMVF9QUk9NUFRfTkFNRSB9O1xuZXhwb3J0IHR5cGUgeyBEb2NQcm9tcHQgfTtcbiIsImltcG9ydCB0eXBlIHsgSW5wdXRQcm9tcHQgfSBmcm9tIFwiZmFzdG1jcFwiO1xuaW1wb3J0IHsgcHJvbXB0cywgcmVmcmVzaFByb21wdHMgfSBmcm9tIFwiLi9wcm9tcHRzXCI7XG5cbmV4cG9ydCAqIGZyb20gXCIuL3Byb21wdHNcIjtcblxuZXhwb3J0IGNvbnN0IHByb21wdExpc3Q6IElucHV0UHJvbXB0PHVuZGVmaW5lZD5bXSA9IHByb21wdHM7XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2FkUHJvbXB0cyhyZXBvUGF0aD86IHN0cmluZyk6IElucHV0UHJvbXB0PHVuZGVmaW5lZD5bXSB7XG4gIHJldHVybiByZWZyZXNoUHJvbXB0cyhyZXBvUGF0aCk7XG59XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JTcGVjID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIGFyZ3M/OiB1bmtub3duW107XG59O1xuXG5leHBvcnQgdHlwZSBBdHRyaWJ1dGVTcGVjID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHR5cGU6IHN0cmluZztcbiAgZGVjb3JhdG9ycz86IERlY29yYXRvclNwZWNbXTtcbn07XG5cbmZ1bmN0aW9uIGVzY2FwZVJlZ0V4cCh2YWx1ZTogc3RyaW5nKSB7XG4gIHJldHVybiB2YWx1ZS5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgXCJcXFxcJCZcIik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdERlY29yYXRvcihzcGVjOiBEZWNvcmF0b3JTcGVjKTogc3RyaW5nIHtcbiAgY29uc3QgYXJncyA9IChzcGVjLmFyZ3MgfHwgW10pLm1hcCgoYXJnKSA9PiBKU09OLnN0cmluZ2lmeShhcmcpKS5qb2luKFwiLCBcIik7XG4gIHJldHVybiBgQCR7c3BlYy5uYW1lfSgke2FyZ3N9KWA7XG59XG5cbmZ1bmN0aW9uIGVuc3VyZURpcmVjdG9yeShmaWxlUGF0aDogc3RyaW5nKSB7XG4gIGZzLm1rZGlyU3luYyhwYXRoLmRpcm5hbWUoZmlsZVBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbn1cblxuZnVuY3Rpb24gY29sbGVjdERlY29yYXRvck5hbWVzKFxuICBjbGFzc0RlY29yYXRvcnM6IERlY29yYXRvclNwZWNbXSB8IHVuZGVmaW5lZCxcbiAgcHJvcGVydGllczogQXR0cmlidXRlU3BlY1tdIHwgdW5kZWZpbmVkXG4pIHtcbiAgY29uc3QgbmFtZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgbmFtZXMuYWRkKFwibW9kZWxcIik7XG4gIGZvciAoY29uc3QgZGVjb3JhdG9yIG9mIGNsYXNzRGVjb3JhdG9ycyB8fCBbXSkge1xuICAgIG5hbWVzLmFkZChkZWNvcmF0b3IubmFtZSk7XG4gIH1cbiAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBwcm9wZXJ0aWVzIHx8IFtdKSB7XG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgcHJvcGVydHkuZGVjb3JhdG9ycyB8fCBbXSkge1xuICAgICAgbmFtZXMuYWRkKGRlY29yYXRvci5uYW1lKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5hbWVzO1xufVxuXG5mdW5jdGlvbiBlbnN1cmVJbXBvcnQoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgaW1wb3J0c0Zyb206IHN0cmluZyxcbiAgZGVjb3JhdG9yczogU2V0PHN0cmluZz5cbikge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAoIWRlY29yYXRvcnMuc2l6ZSkgcmV0dXJuIGNvbnRlbnQ7XG4gIGNvbnN0IGltcG9ydFJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICBgaW1wb3J0XFxcXHMrXFxcXHsoW159XSspXFxcXH1cXFxccytmcm9tXFxcXHMrW1wiJ10ke2VzY2FwZVJlZ0V4cChpbXBvcnRzRnJvbSl9W1wiJ107YFxuICApO1xuICBjb25zdCBtYXRjaCA9IGNvbnRlbnQubWF0Y2goaW1wb3J0UmVnZXgpO1xuICBjb25zdCBzb3J0ZWQgPSBBcnJheS5mcm9tKGRlY29yYXRvcnMpLnNvcnQoKTtcblxuICBpZiAobWF0Y2gpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IG1hdGNoWzFdXG4gICAgICAuc3BsaXQoXCIsXCIpXG4gICAgICAubWFwKChuYW1lKSA9PiBuYW1lLnRyaW0oKSlcbiAgICAgIC5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgbWVyZ2VkID0gQXJyYXkuZnJvbShuZXcgU2V0KFsuLi5leGlzdGluZywgLi4uc29ydGVkXSkpLnNvcnQoKTtcbiAgICByZXR1cm4gY29udGVudC5yZXBsYWNlKFxuICAgICAgaW1wb3J0UmVnZXgsXG4gICAgICBgaW1wb3J0IHsgJHttZXJnZWQuam9pbihcIiwgXCIpfSB9IGZyb20gXCIke2ltcG9ydHNGcm9tfVwiO2BcbiAgICApO1xuICB9XG5cbiAgY29uc3QgaW1wb3J0TGluZSA9IGBpbXBvcnQgeyAke3NvcnRlZC5qb2luKFwiLCBcIil9IH0gZnJvbSBcIiR7aW1wb3J0c0Zyb219XCI7YDtcbiAgcmV0dXJuIGAke2ltcG9ydExpbmV9XFxuXFxuJHtjb250ZW50fWA7XG59XG5cbmZ1bmN0aW9uIGFkZFByb3BlcnR5QmxvY2socHJvcGVydHk6IEF0dHJpYnV0ZVNwZWMpIHtcbiAgY29uc3QgZGVjb3JhdG9ycyA9IChwcm9wZXJ0eS5kZWNvcmF0b3JzIHx8IFtdKVxuICAgIC5tYXAoZm9ybWF0RGVjb3JhdG9yKVxuICAgIC5qb2luKFwiXFxuICBcIik7XG4gIGNvbnN0IGRlY29yYXRvckJsb2NrID0gZGVjb3JhdG9ycyA/IGAgICR7ZGVjb3JhdG9yc31cXG5gIDogXCJcIjtcbiAgcmV0dXJuIGAke2RlY29yYXRvckJsb2NrfSAgJHtwcm9wZXJ0eS5uYW1lfTogJHtwcm9wZXJ0eS50eXBlfTtgO1xufVxuXG5mdW5jdGlvbiByZW1vdmVQcm9wZXJ0eUJsb2NrKGNvbnRlbnQ6IHN0cmluZywgcHJvcGVydHlOYW1lOiBzdHJpbmcpIHtcbiAgY29uc3QgbGluZXMgPSBjb250ZW50LnNwbGl0KC9cXHI/XFxuLyk7XG4gIGNvbnN0IHJlc3VsdDogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGxpbmUgPSBsaW5lc1tpXTtcbiAgICBpZiAoXG4gICAgICBsaW5lLnRyaW0oKS5zdGFydHNXaXRoKGBAYCkgJiZcbiAgICAgIGxpbmVzW2kgKyAxXT8uaW5jbHVkZXMoYCR7cHJvcGVydHlOYW1lfTpgKVxuICAgICkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChsaW5lLmluY2x1ZGVzKGAke3Byb3BlcnR5TmFtZX06YCkpIHtcbiAgICAgIC8vIHNraXAgdGhpcyBsaW5lIGFuZCBhbnkgdHJhaWxpbmcgYmxhbmsgbGluZVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHJlc3VsdC5wdXNoKGxpbmUpO1xuICB9XG4gIHJldHVybiByZXN1bHQuam9pbihcIlxcblwiKTtcbn1cblxuZnVuY3Rpb24gaW5zZXJ0RGVjb3JhdG9yKFxuICBjb250ZW50OiBzdHJpbmcsXG4gIGRlY29yYXRvcjogRGVjb3JhdG9yU3BlYyxcbiAgdGFyZ2V0OiB7XG4gICAga2luZDogXCJjbGFzc1wiIHwgXCJwcm9wZXJ0eVwiO1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gIH1cbikge1xuICBjb25zdCBkZWNvcmF0b3JMaW5lID0gZm9ybWF0RGVjb3JhdG9yKGRlY29yYXRvcik7XG4gIGlmICh0YXJnZXQua2luZCA9PT0gXCJjbGFzc1wiKSB7XG4gICAgY29uc3QgY2xhc3NSZWdleCA9IC8oZXhwb3J0XFxzK2NsYXNzXFxzK1teXFxze10rXFxzKlxceykvO1xuICAgIGlmIChjb250ZW50LmluY2x1ZGVzKGRlY29yYXRvckxpbmUpKSByZXR1cm4gY29udGVudDtcbiAgICByZXR1cm4gY29udGVudC5yZXBsYWNlKGNsYXNzUmVnZXgsIGAke2RlY29yYXRvckxpbmV9XFxuJDFgKTtcbiAgfVxuICBpZiAoIXRhcmdldC5uYW1lKSByZXR1cm4gY29udGVudDtcbiAgY29uc3QgcHJvcGVydHlSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgYCheXFxcXHMqKSg/OkAuKlxcXFxuXFxcXDEpKiR7ZXNjYXBlUmVnRXhwKHRhcmdldC5uYW1lKX06YCxcbiAgICBcIm1cIlxuICApO1xuICBjb25zdCBtYXRjaCA9IHByb3BlcnR5UmVnZXguZXhlYyhjb250ZW50KTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuIGNvbnRlbnQ7XG4gIGNvbnN0IGluZGVudCA9IG1hdGNoWzFdIHx8IFwiICBcIjtcbiAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoYCR7aW5kZW50fSR7ZGVjb3JhdG9yTGluZX1gKSkgcmV0dXJuIGNvbnRlbnQ7XG4gIHJldHVybiAoXG4gICAgY29udGVudC5zbGljZSgwLCBtYXRjaC5pbmRleCkgK1xuICAgIGAke2luZGVudH0ke2RlY29yYXRvckxpbmV9XFxuYCArXG4gICAgY29udGVudC5zbGljZShtYXRjaC5pbmRleClcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlRGVjb3JhdG9yKFxuICBjb250ZW50OiBzdHJpbmcsXG4gIGRlY29yYXRvck5hbWU6IHN0cmluZyxcbiAgdGFyZ2V0OiB7XG4gICAga2luZDogXCJjbGFzc1wiIHwgXCJwcm9wZXJ0eVwiO1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gIH1cbikge1xuICBjb25zdCBkZWNvcmF0b3JSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgYF5cXFxccypAJHtlc2NhcGVSZWdFeHAoZGVjb3JhdG9yTmFtZSl9XFxcXChbXildKlxcXFwpYCxcbiAgICBcIm1cIlxuICApO1xuICBpZiAodGFyZ2V0LmtpbmQgPT09IFwiY2xhc3NcIikge1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoZGVjb3JhdG9yUmVnZXgsIFwiXCIpO1xuICB9XG4gIGlmICh0YXJnZXQubmFtZSkge1xuICAgIGNvbnN0IHBhdHRlcm4gPSBuZXcgUmVnRXhwKFxuICAgICAgYCheXFxcXHMqQCR7ZXNjYXBlUmVnRXhwKGRlY29yYXRvck5hbWUpfVxcXFwoW14pXSpcXFxcKVxcXFxzKiRcXFxcbikoPz1cXFxccyoke2VzY2FwZVJlZ0V4cCh0YXJnZXQubmFtZSl9OilgLFxuICAgICAgXCJtXCJcbiAgICApO1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UocGF0dGVybiwgXCJcIik7XG4gIH1cbiAgcmV0dXJuIGNvbnRlbnQ7XG59XG5cbmZ1bmN0aW9uIHdyaXRlSWZDaGFuZ2VkKGZpbGVQYXRoOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZykge1xuICBlbnN1cmVEaXJlY3RvcnkoZmlsZVBhdGgpO1xuICBmcy53cml0ZUZpbGVTeW5jKGZpbGVQYXRoLCBjb250ZW50KTtcbn1cblxuZXhwb3J0IGNvbnN0IGRlY29yYXRvclRvb2xzID0ge1xuICBjcmVhdGVPclVwZGF0ZU1vZGVsVG9vbDoge1xuICAgIG5hbWU6IFwiY3JlYXRlLW9yLXVwZGF0ZS1tb2RlbFwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkNyZWF0ZSBvciB1cGRhdGUgYSB2YWxpZGF0aW9uLXJlYWR5IG1vZGVsIGNsYXNzXCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIGNsYXNzRGVjb3JhdG9ycz86IERlY29yYXRvclNwZWNbXTtcbiAgICAgIHByb3BlcnRpZXM6IEF0dHJpYnV0ZVNwZWNbXTtcbiAgICAgIGltcG9ydHNGcm9tOiBzdHJpbmc7XG4gICAgICBvdmVyd3JpdGU/OiBib29sZWFuO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghYXJncy5vdmVyd3JpdGUgJiYgZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZpbGUgYWxyZWFkeSBleGlzdHMgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgICAgfVxuICAgICAgY29uc3QgZGVjb3JhdG9ycyA9IGNvbGxlY3REZWNvcmF0b3JOYW1lcyhcbiAgICAgICAgYXJncy5jbGFzc0RlY29yYXRvcnMsXG4gICAgICAgIGFyZ3MucHJvcGVydGllc1xuICAgICAgKTtcbiAgICAgIGxldCBjb250ZW50ID0gYEBtb2RlbCgpYDtcbiAgICAgIGZvciAoY29uc3QgZGVjb3JhdG9yIG9mIGFyZ3MuY2xhc3NEZWNvcmF0b3JzIHx8IFtdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gYFxcbiR7Zm9ybWF0RGVjb3JhdG9yKGRlY29yYXRvcil9YDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSAoYXJncy5wcm9wZXJ0aWVzIHx8IFtdKVxuICAgICAgICAubWFwKGFkZFByb3BlcnR5QmxvY2spXG4gICAgICAgIC5qb2luKFwiXFxuXFxuXCIpO1xuICAgICAgY29udGVudCArPSBgXFxuZXhwb3J0IGNsYXNzICR7YXJncy5jbGFzc05hbWV9IHtcXG4ke3Byb3BlcnRpZXMgPyBgJHtwcm9wZXJ0aWVzfVxcbmAgOiBcIlwifX1cXG5gO1xuICAgICAgY29udGVudCA9IGVuc3VyZUltcG9ydChjb250ZW50LCBhcmdzLmltcG9ydHNGcm9tLCBkZWNvcmF0b3JzKTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICBhZGRBdHRyaWJ1dGVUb29sOiB7XG4gICAgbmFtZTogXCJhZGQtYXR0cmlidXRlXCIsXG4gICAgZGVzY3JpcHRpb246IFwiQWRkIGEgZGVjb3JhdGVkIGF0dHJpYnV0ZSB0byBhbiBleGlzdGluZyBtb2RlbFwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBmaWxlUGF0aDogc3RyaW5nO1xuICAgICAgY2xhc3NOYW1lOiBzdHJpbmc7XG4gICAgICBhdHRyaWJ1dGU6IEF0dHJpYnV0ZVNwZWM7XG4gICAgICBpbXBvcnRzRnJvbTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1vZGVsIGZpbGUgbm90IGZvdW5kIGF0ICR7YXJncy5maWxlUGF0aH1gKTtcbiAgICAgIH1cbiAgICAgIGxldCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGFyZ3MuZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICAgIGlmIChjb250ZW50LmluY2x1ZGVzKGAke2FyZ3MuYXR0cmlidXRlLm5hbWV9OmApKSB7XG4gICAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgICB9XG4gICAgICBjb25zdCBkZWNvcmF0b3JzID0gY29sbGVjdERlY29yYXRvck5hbWVzKHVuZGVmaW5lZCwgW2FyZ3MuYXR0cmlidXRlXSk7XG4gICAgICBjb250ZW50ID0gZW5zdXJlSW1wb3J0KGNvbnRlbnQsIGFyZ3MuaW1wb3J0c0Zyb20sIGRlY29yYXRvcnMpO1xuICAgICAgY29uc3QgaW5zZXJ0aW9uUG9pbnQgPSBjb250ZW50Lmxhc3RJbmRleE9mKFwifVwiKTtcbiAgICAgIGNvbnN0IGJsb2NrID0gYWRkUHJvcGVydHlCbG9jayhhcmdzLmF0dHJpYnV0ZSk7XG4gICAgICBjb25zdCBiZWZvcmUgPSBjb250ZW50LnNsaWNlKDAsIGluc2VydGlvblBvaW50KS5yZXBsYWNlKC9cXHMqJC8sIFwiXCIpO1xuICAgICAgY29uc3QgYWZ0ZXIgPSBjb250ZW50LnNsaWNlKGluc2VydGlvblBvaW50KTtcbiAgICAgIGNvbnN0IHVwZGF0ZWQgPSBgJHtiZWZvcmV9XFxuJHtibG9ja31cXG4ke2FmdGVyfWA7XG4gICAgICB3cml0ZUlmQ2hhbmdlZChhcmdzLmZpbGVQYXRoLCB1cGRhdGVkKTtcbiAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgfSxcbiAgfSxcbiAgcmVtb3ZlQXR0cmlidXRlVG9vbDoge1xuICAgIG5hbWU6IFwicmVtb3ZlLWF0dHJpYnV0ZVwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlJlbW92ZSBhbiBhdHRyaWJ1dGUgZnJvbSBhIG1vZGVsIGNsYXNzXCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIGF0dHJpYnV0ZU5hbWU6IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGFyZ3MuZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICAgIGNvbnN0IHVwZGF0ZWQgPSByZW1vdmVQcm9wZXJ0eUJsb2NrKGNvbnRlbnQsIGFyZ3MuYXR0cmlidXRlTmFtZSk7XG4gICAgICB3cml0ZUlmQ2hhbmdlZChhcmdzLmZpbGVQYXRoLCB1cGRhdGVkKTtcbiAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgfSxcbiAgfSxcbiAgYXBwbHlEZWNvcmF0b3JUb29sOiB7XG4gICAgbmFtZTogXCJhcHBseS1kZWNvcmF0b3JcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBcHBseSBhIGRlY29yYXRvciB0byBhIGNsYXNzIG9yIHByb3BlcnR5XCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIHRhcmdldDogeyBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7IG5hbWU/OiBzdHJpbmcgfTtcbiAgICAgIGRlY29yYXRvcjogRGVjb3JhdG9yU3BlYztcbiAgICAgIGltcG9ydHNGcm9tOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTW9kZWwgZmlsZSBub3QgZm91bmQgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgICAgfVxuICAgICAgbGV0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgZGVjb3JhdG9ycyA9IG5ldyBTZXQ8c3RyaW5nPihbYXJncy5kZWNvcmF0b3IubmFtZV0pO1xuICAgICAgY29udGVudCA9IGVuc3VyZUltcG9ydChjb250ZW50LCBhcmdzLmltcG9ydHNGcm9tLCBkZWNvcmF0b3JzKTtcbiAgICAgIGNvbnRlbnQgPSBpbnNlcnREZWNvcmF0b3IoY29udGVudCwgYXJncy5kZWNvcmF0b3IsIGFyZ3MudGFyZ2V0KTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICByZW1vdmVEZWNvcmF0b3JUb29sOiB7XG4gICAgbmFtZTogXCJyZW1vdmUtZGVjb3JhdG9yXCIsXG4gICAgZGVzY3JpcHRpb246IFwiUmVtb3ZlIGEgZGVjb3JhdG9yIGZyb20gYSBjbGFzcyBvciBwcm9wZXJ0eVwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBmaWxlUGF0aDogc3RyaW5nO1xuICAgICAgY2xhc3NOYW1lOiBzdHJpbmc7XG4gICAgICB0YXJnZXQ6IHsga2luZDogXCJjbGFzc1wiIHwgXCJwcm9wZXJ0eVwiOyBuYW1lPzogc3RyaW5nIH07XG4gICAgICBkZWNvcmF0b3JOYW1lOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgICAgbGV0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29udGVudCA9IHJlbW92ZURlY29yYXRvcihjb250ZW50LCBhcmdzLmRlY29yYXRvck5hbWUsIGFyZ3MudGFyZ2V0KTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICBzY2FmZm9sZFZhbGlkYXRvclRvb2w6IHtcbiAgICBuYW1lOiBcInNjYWZmb2xkLXZhbGlkYXRvclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlNjYWZmb2xkIGEgdmFsaWRhdG9yIGNsYXNzIGFuZCBvcHRpb25hbCBkZWNvcmF0b3JcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgdmFsaWRhdG9yc0Rpcjogc3RyaW5nO1xuICAgICAgZGVjb3JhdG9yRGlyPzogc3RyaW5nO1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGNsYXNzRmlsZSA9IHBhdGguam9pbihhcmdzLnZhbGlkYXRvcnNEaXIsIGAke2FyZ3MubmFtZX0udHNgKTtcbiAgICAgIGVuc3VyZURpcmVjdG9yeShjbGFzc0ZpbGUpO1xuICAgICAgY29uc3QgY2xhc3NDb250ZW50ID0gYGV4cG9ydCBjbGFzcyAke2FyZ3MubmFtZX0ge1xcbiAgdmFsaWRhdGUodmFsdWU6IHVua25vd24pOiBib29sZWFuIHtcXG4gICAgcmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQ7XFxuICB9XFxufVxcbmA7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKGNsYXNzRmlsZSwgY2xhc3NDb250ZW50KTtcbiAgICAgIGxldCBkZWNvcmF0b3JGaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy5kZWNvcmF0b3JEaXIpIHtcbiAgICAgICAgZGVjb3JhdG9yRmlsZSA9IHBhdGguam9pbihcbiAgICAgICAgICBhcmdzLmRlY29yYXRvckRpcixcbiAgICAgICAgICBgJHthcmdzLm5hbWV9RGVjb3JhdG9yLnRzYFxuICAgICAgICApO1xuICAgICAgICBlbnN1cmVEaXJlY3RvcnkoZGVjb3JhdG9yRmlsZSk7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgICAgZGVjb3JhdG9yRmlsZSxcbiAgICAgICAgICBgZXhwb3J0IGZ1bmN0aW9uICR7YXJncy5uYW1lfURlY29yYXRvcigpIHtcXG4gIHJldHVybiAoKSA9PiB2b2lkIDA7XFxufVxcbmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGNsYXNzRmlsZSwgZGVjb3JhdG9yRmlsZSB9O1xuICAgIH0sXG4gIH0sXG4gIHNjYWZmb2xkU2VyaWFsaXplclRvb2w6IHtcbiAgICBuYW1lOiBcInNjYWZmb2xkLXNlcmlhbGl6ZXJcIixcbiAgICBkZXNjcmlwdGlvbjogXCJTY2FmZm9sZCBhIHNlcmlhbGl6ZXIgY2xhc3MgYW5kIG9wdGlvbmFsIHJlZ2lzdHJ5XCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGRpcjogc3RyaW5nO1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgICAgcmVnaXN0ZXJEaXI/OiBzdHJpbmc7XG4gICAgICBzZXREZWZhdWx0PzogYm9vbGVhbjtcbiAgICB9KSA9PiB7XG4gICAgICBjb25zdCBjbGFzc0ZpbGUgPSBwYXRoLmpvaW4oYXJncy5kaXIsIGAke2FyZ3MubmFtZX0udHNgKTtcbiAgICAgIGVuc3VyZURpcmVjdG9yeShjbGFzc0ZpbGUpO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgY2xhc3NGaWxlLFxuICAgICAgICBgZXhwb3J0IGNsYXNzICR7YXJncy5uYW1lfSB7XFxuICBzZXJpYWxpemUodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xcbiAgfVxcbn1cXG5gXG4gICAgICApO1xuICAgICAgbGV0IHJlZ2lzdGVyRmlsZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGFyZ3MucmVnaXN0ZXJEaXIpIHtcbiAgICAgICAgcmVnaXN0ZXJGaWxlID0gcGF0aC5qb2luKGFyZ3MucmVnaXN0ZXJEaXIsIGAke2FyZ3MubmFtZX1SZWdpc3Rlci50c2ApO1xuICAgICAgICBlbnN1cmVEaXJlY3RvcnkocmVnaXN0ZXJGaWxlKTtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgICByZWdpc3RlckZpbGUsXG4gICAgICAgICAgYGV4cG9ydCBmdW5jdGlvbiByZWdpc3RlciR7YXJncy5uYW1lfSgpIHtcXG4gIHJldHVybiAke2FyZ3Muc2V0RGVmYXVsdCA/IFwiJ2RlZmF1bHQnXCIgOiBcIidvcHRpb25hbCdcIn07XFxufVxcbmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGNsYXNzRmlsZSwgcmVnaXN0ZXJGaWxlIH07XG4gICAgfSxcbiAgfSxcbiAgc2NhZmZvbGRIYXNoaW5nVG9vbDoge1xuICAgIG5hbWU6IFwic2NhZmZvbGQtaGFzaGluZ1wiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlNjYWZmb2xkIGEgaGFzaGluZyBmdW5jdGlvbiBhbmQgb3B0aW9uYWwgcmVnaXN0cnlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZGlyOiBzdHJpbmc7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICByZWdpc3RlckRpcj86IHN0cmluZztcbiAgICAgIHNldERlZmF1bHQ/OiBib29sZWFuO1xuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGZ1bmN0aW9uRmlsZSA9IHBhdGguam9pbihhcmdzLmRpciwgYCR7YXJncy5uYW1lfS50c2ApO1xuICAgICAgZW5zdXJlRGlyZWN0b3J5KGZ1bmN0aW9uRmlsZSk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICBmdW5jdGlvbkZpbGUsXG4gICAgICAgIGBleHBvcnQgZnVuY3Rpb24gJHthcmdzLm5hbWV9KHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xcbiAgcmV0dXJuIHZhbHVlLnNwbGl0KCcnKS5yZXZlcnNlKCkuam9pbignJyk7XFxufVxcbmBcbiAgICAgICk7XG4gICAgICBsZXQgcmVnaXN0ZXJGaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy5yZWdpc3RlckRpcikge1xuICAgICAgICByZWdpc3RlckZpbGUgPSBwYXRoLmpvaW4oYXJncy5yZWdpc3RlckRpciwgYCR7YXJncy5uYW1lfVJlZ2lzdGVyLnRzYCk7XG4gICAgICAgIGVuc3VyZURpcmVjdG9yeShyZWdpc3RlckZpbGUpO1xuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICAgIHJlZ2lzdGVyRmlsZSxcbiAgICAgICAgICBgZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyJHthcmdzLm5hbWV9KCkge1xcbiAgcmV0dXJuICR7YXJncy5zZXREZWZhdWx0ID8gXCInZGVmYXVsdCdcIiA6IFwiJ29wdGlvbmFsJ1wifTtcXG59XFxuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgZnVuY3Rpb25GaWxlLCByZWdpc3RlckZpbGUgfTtcbiAgICB9LFxuICB9LFxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgRGVjb3JhdG9yVG9vbHMgPSB0eXBlb2YgZGVjb3JhdG9yVG9vbHM7XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgc3Bhd25TeW5jIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB0eXBlIHsgQ29udGVudFJlc3VsdCwgVG9vbCB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQge1xuICBkb2N1bWVudE9iamVjdFNjaGVtYSxcbiAgY292ZXJhZ2VUYXNrU2NoZW1hLFxuICByZWFkbWVJbXByb3ZlbWVudFNjaGVtYSxcbn0gZnJvbSBcIi4uL3NjaGVtYXNcIjtcbmltcG9ydCB7XG4gIERvY3VtZW50T2JqZWN0QXJncyxcbiAgQ292ZXJhZ2VUYXNrQXJncyxcbiAgUmVhZG1lSW1wcm92ZW1lbnRBcmdzLFxufSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7XG4gIGdldFdvcmtzcGFjZVJvb3QsXG4gIHJlc29sdmVJbldvcmtzcGFjZSxcbiAgdGhyb3dVc2VyRXJyb3IsXG4gIFdvcmtzcGFjZUVycm9yLFxufSBmcm9tIFwiLi4vd29ya3NwYWNlXCI7XG5pbXBvcnQge1xuICBidWlsZE9iamVjdFByb21wdHMsXG4gIGRpc2NvdmVyRG9jUHJvbXB0cyxcbiAgZ2V0T2JqZWN0UHJvbXB0RGVwZW5kZW5jaWVzLFxufSBmcm9tIFwiLi4vcHJvbXB0cy9wcm9tcHRzXCI7XG5pbXBvcnQgdHlwZSB7IERvY1Byb21wdCB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgbGlzdEZpbGVzUmVjdXJzaXZlLCByZWFkRmlsZVNhZmUgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IGFuYWx5emVSZXBvLCBpc1NvdXJjZUZpbGUsIGlzVGVzdEZpbGUgfSBmcm9tIFwiLi4vY29kZVwiO1xuXG50eXBlIFByb21wdFNlY3Rpb24gPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgZGVzY3JpcHRpb246IHN0cmluZztcbiAgY29udGVudDogc3RyaW5nO1xuICBhYnNvbHV0ZVBhdGg/OiBzdHJpbmc7XG59O1xuXG5mdW5jdGlvbiByZWxhdGl2ZUZpbGVzKHJvb3Q6IHN0cmluZywgZmlsZXM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICByZXR1cm4gZmlsZXMubWFwKChmaWxlKSA9PiBwYXRoLnJlbGF0aXZlKHJvb3QsIGZpbGUpKS5zb3J0KCk7XG59XG5cbmZ1bmN0aW9uIGNvbGxlY3RQcm9tcHRTZWN0aW9ucyhuYW1lczogcmVhZG9ubHkgc3RyaW5nW10pOiBQcm9tcHRTZWN0aW9uW10ge1xuICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICBjb25zdCBwcm9tcHRJbmRleCA9IG5ldyBNYXA8c3RyaW5nLCBEb2NQcm9tcHQ+KFxuICAgIGRpc2NvdmVyRG9jUHJvbXB0cyhyb290KS5tYXAoKHByb21wdCkgPT4gW3Byb21wdC5uYW1lLCBwcm9tcHRdKVxuICApO1xuICByZXR1cm4gbmFtZXNcbiAgICAubWFwKChuYW1lKSA9PiBwcm9tcHRJbmRleC5nZXQobmFtZSkpXG4gICAgLmZpbHRlcigocHJvbXB0KTogcHJvbXB0IGlzIERvY1Byb21wdCA9PiBCb29sZWFuKHByb21wdCkpXG4gICAgLm1hcCgocHJvbXB0KSA9PiAoe1xuICAgICAgbmFtZTogcHJvbXB0Lm5hbWUsXG4gICAgICB0aXRsZTogcHJvbXB0LnRpdGxlLFxuICAgICAgZGVzY3JpcHRpb246IHByb21wdC5kZXNjcmlwdGlvbixcbiAgICAgIGNvbnRlbnQ6IHByb21wdC5jb250ZW50LFxuICAgICAgYWJzb2x1dGVQYXRoOiBwcm9tcHQuYWJzb2x1dGVQYXRoLFxuICAgIH0pKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VUYXNrTGluZXMoY29udGVudDogc3RyaW5nKTogc3RyaW5nW10ge1xuICByZXR1cm4gY29udGVudFxuICAgIC5zcGxpdCgvXFxyP1xcbi8pXG4gICAgLm1hcCgobGluZSkgPT4gbGluZS50cmltKCkpXG4gICAgLmZpbHRlcigobGluZSkgPT4gL150YXNrXFxzK1xcZCsvaS50ZXN0KGxpbmUpKTtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZUNvdmVyYWdlRnJvbUZpbmFsKGNvdmVyYWdlUGF0aDogc3RyaW5nKSB7XG4gIGNvbnN0IHBheWxvYWQgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhjb3ZlcmFnZVBhdGgsIFwidXRmOFwiKSkgYXMgUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICB7XG4gICAgICBzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+O1xuICAgICAgZjogUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcbiAgICAgIGI6IFJlY29yZDxzdHJpbmcsIG51bWJlciB8IG51bWJlcltdPjtcbiAgICB9XG4gID47XG5cbiAgY29uc3QgdG90YWxzID0ge1xuICAgIHN0YXRlbWVudHM6IHsgY292ZXJlZDogMCwgdG90YWw6IDAgfSxcbiAgICBmdW5jdGlvbnM6IHsgY292ZXJlZDogMCwgdG90YWw6IDAgfSxcbiAgICBicmFuY2hlczogeyBjb3ZlcmVkOiAwLCB0b3RhbDogMCB9LFxuICB9O1xuXG4gIGNvbnN0IGZpbGVzID0gT2JqZWN0LmVudHJpZXMocGF5bG9hZCkubWFwKChbZmlsZVBhdGgsIGluZm9dKSA9PiB7XG4gICAgY29uc3Qgc3RhdGVtZW50Q291bnRzID0gT2JqZWN0LnZhbHVlcyhpbmZvLnMpO1xuICAgIGNvbnN0IGZ1bmN0aW9uQ291bnRzID0gT2JqZWN0LnZhbHVlcyhpbmZvLmYpO1xuICAgIGNvbnN0IGJyYW5jaENvdW50cyA9IE9iamVjdC52YWx1ZXMoaW5mby5iKS5mbGF0TWFwKCh2YWx1ZSkgPT5cbiAgICAgIEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdXG4gICAgKTtcblxuICAgIGNvbnN0IHN0YXRlbWVudFRvdGFsID0gc3RhdGVtZW50Q291bnRzLmxlbmd0aDtcbiAgICBjb25zdCBmdW5jdGlvblRvdGFsID0gZnVuY3Rpb25Db3VudHMubGVuZ3RoO1xuICAgIGNvbnN0IGJyYW5jaFRvdGFsID0gYnJhbmNoQ291bnRzLmxlbmd0aDtcblxuICAgIGNvbnN0IHN0YXRlbWVudENvdmVyZWQgPSBzdGF0ZW1lbnRDb3VudHMuZmlsdGVyKFxuICAgICAgKGNvdW50KSA9PiBjb3VudCA+IDBcbiAgICApLmxlbmd0aDtcbiAgICBjb25zdCBmdW5jdGlvbkNvdmVyZWQgPSBmdW5jdGlvbkNvdW50cy5maWx0ZXIoKGNvdW50KSA9PiBjb3VudCA+IDApLmxlbmd0aDtcbiAgICBjb25zdCBicmFuY2hDb3ZlcmVkID0gYnJhbmNoQ291bnRzLmZpbHRlcigoY291bnQpID0+IGNvdW50ID4gMCkubGVuZ3RoO1xuXG4gICAgdG90YWxzLnN0YXRlbWVudHMuY292ZXJlZCArPSBzdGF0ZW1lbnRDb3ZlcmVkO1xuICAgIHRvdGFscy5zdGF0ZW1lbnRzLnRvdGFsICs9IHN0YXRlbWVudFRvdGFsO1xuICAgIHRvdGFscy5mdW5jdGlvbnMuY292ZXJlZCArPSBmdW5jdGlvbkNvdmVyZWQ7XG4gICAgdG90YWxzLmZ1bmN0aW9ucy50b3RhbCArPSBmdW5jdGlvblRvdGFsO1xuICAgIHRvdGFscy5icmFuY2hlcy5jb3ZlcmVkICs9IGJyYW5jaENvdmVyZWQ7XG4gICAgdG90YWxzLmJyYW5jaGVzLnRvdGFsICs9IGJyYW5jaFRvdGFsO1xuXG4gICAgY29uc3QgcGN0ID0gKGNvdmVyZWQ6IG51bWJlciwgdG90YWw6IG51bWJlcikgPT5cbiAgICAgIHRvdGFsID09PSAwID8gMTAwIDogTnVtYmVyKCgoY292ZXJlZCAvIHRvdGFsKSAqIDEwMCkudG9GaXhlZCgyKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcGF0aDogZmlsZVBhdGgsXG4gICAgICBzdGF0ZW1lbnRzOiBwY3Qoc3RhdGVtZW50Q292ZXJlZCwgc3RhdGVtZW50VG90YWwpLFxuICAgICAgZnVuY3Rpb25zOiBwY3QoZnVuY3Rpb25Db3ZlcmVkLCBmdW5jdGlvblRvdGFsKSxcbiAgICAgIGJyYW5jaGVzOiBwY3QoYnJhbmNoQ292ZXJlZCwgYnJhbmNoVG90YWwpLFxuICAgIH07XG4gIH0pO1xuXG4gIGNvbnN0IHBjdCA9IChjb3ZlcmVkOiBudW1iZXIsIHRvdGFsOiBudW1iZXIpID0+XG4gICAgdG90YWwgPT09IDAgPyAxMDAgOiBOdW1iZXIoKChjb3ZlcmVkIC8gdG90YWwpICogMTAwKS50b0ZpeGVkKDIpKTtcblxuICByZXR1cm4ge1xuICAgIHRvdGFsczoge1xuICAgICAgc3RhdGVtZW50czoge1xuICAgICAgICAuLi50b3RhbHMuc3RhdGVtZW50cyxcbiAgICAgICAgcGN0OiBwY3QodG90YWxzLnN0YXRlbWVudHMuY292ZXJlZCwgdG90YWxzLnN0YXRlbWVudHMudG90YWwpLFxuICAgICAgfSxcbiAgICAgIGZ1bmN0aW9uczoge1xuICAgICAgICAuLi50b3RhbHMuZnVuY3Rpb25zLFxuICAgICAgICBwY3Q6IHBjdCh0b3RhbHMuZnVuY3Rpb25zLmNvdmVyZWQsIHRvdGFscy5mdW5jdGlvbnMudG90YWwpLFxuICAgICAgfSxcbiAgICAgIGJyYW5jaGVzOiB7XG4gICAgICAgIC4uLnRvdGFscy5icmFuY2hlcyxcbiAgICAgICAgcGN0OiBwY3QodG90YWxzLmJyYW5jaGVzLmNvdmVyZWQsIHRvdGFscy5icmFuY2hlcy50b3RhbCksXG4gICAgICB9LFxuICAgIH0sXG4gICAgZmlsZXMsXG4gIH07XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVByb21wdFNlY3Rpb25zKHNlY3Rpb25zOiBQcm9tcHRTZWN0aW9uW10pIHtcbiAgcmV0dXJuIHNlY3Rpb25zLm1hcCgoc2VjdGlvbikgPT4gKHtcbiAgICBuYW1lOiBzZWN0aW9uLm5hbWUsXG4gICAgdGl0bGU6IHNlY3Rpb24udGl0bGUsXG4gICAgdGFza3M6IHBhcnNlVGFza0xpbmVzKHNlY3Rpb24uY29udGVudCksXG4gICAgY29udGVudDogc2VjdGlvbi5jb250ZW50LFxuICB9KSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVSZXBvUm9vdChiYXNlUGF0aDogc3RyaW5nKSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHJlc29sdmVJbldvcmtzcGFjZShyb290LCBiYXNlUGF0aCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV29ya3NwYWNlRXJyb3IpIHtcbiAgICAgIGF3YWl0IHRocm93VXNlckVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZG9jdW1lbnRPYmplY3RUb29sOiBUb29sPHVuZGVmaW5lZCwgdHlwZW9mIGRvY3VtZW50T2JqZWN0U2NoZW1hPiA9XG4gIHtcbiAgICBuYW1lOiBcImRvY3VtZW50LW9iamVjdFwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJDcmVhdGUgYSBkb2N1bWVudGF0aW9uIHBsYW4gZm9yIGEgc3BlY2lmaWMgb2JqZWN0IHR5cGUgdXNpbmcgLmNvZGV4IHByb21wdHMgYW5kIHJlcG9zaXRvcnkgYW5hbHlzaXMuXCIsXG4gICAgcGFyYW1ldGVyczogZG9jdW1lbnRPYmplY3RTY2hlbWEsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgX2NvbnRleHQpOiBQcm9taXNlPENvbnRlbnRSZXN1bHQ+ID0+IHtcbiAgICAgIGNvbnN0IGFyZ3MgPSBkb2N1bWVudE9iamVjdFNjaGVtYS5wYXJzZShpbnB1dCBhcyBEb2N1bWVudE9iamVjdEFyZ3MpO1xuICAgICAgY29uc3QgcmVwb1Jvb3QgPSBhd2FpdCByZXNvbHZlUmVwb1Jvb3QoYXJncy5iYXNlUGF0aCk7XG5cbiAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IGdldE9iamVjdFByb21wdERlcGVuZGVuY2llcygpW2FyZ3Mub2JqZWN0VHlwZV0gPz8gW107XG4gICAgICBpZiAoIWRlcGVuZGVuY2llcy5sZW5ndGgpIHtcbiAgICAgICAgYXdhaXQgdGhyb3dVc2VyRXJyb3IoXG4gICAgICAgICAgYE5vIHByb21wdCBndWlkYW5jZSBjb25maWd1cmVkIGZvciBvYmplY3QgdHlwZSAke2FyZ3Mub2JqZWN0VHlwZX1gXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNlY3Rpb25zID0gbm9ybWFsaXplUHJvbXB0U2VjdGlvbnMoXG4gICAgICAgIGNvbGxlY3RQcm9tcHRTZWN0aW9ucyhkZXBlbmRlbmNpZXMpXG4gICAgICApO1xuXG4gICAgICBjb25zdCBzcmNEaXIgPSBwYXRoLmpvaW4ocmVwb1Jvb3QsIFwic3JjXCIpO1xuICAgICAgY29uc3QgdGVzdERpciA9IHBhdGguam9pbihyZXBvUm9vdCwgXCJ0ZXN0c1wiKTtcblxuICAgICAgY29uc3Qgc291cmNlRmlsZXMgPSBmcy5leGlzdHNTeW5jKHNyY0RpcilcbiAgICAgICAgPyBsaXN0RmlsZXNSZWN1cnNpdmUoc3JjRGlyLCBpc1NvdXJjZUZpbGUpXG4gICAgICAgIDogW107XG4gICAgICBjb25zdCB0ZXN0RmlsZXMgPSBmcy5leGlzdHNTeW5jKHRlc3REaXIpXG4gICAgICAgID8gbGlzdEZpbGVzUmVjdXJzaXZlKFxuICAgICAgICAgICAgdGVzdERpcixcbiAgICAgICAgICAgIChmaWxlKSA9PiBpc1NvdXJjZUZpbGUoZmlsZSkgJiYgaXNUZXN0RmlsZShmaWxlKVxuICAgICAgICAgIClcbiAgICAgICAgOiBbXTtcblxuICAgICAgbGV0IHRhcmdldEZpbGVDb250ZW50OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy50YXJnZXRGaWxlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgYWJzb2x1dGUgPSByZXNvbHZlSW5Xb3Jrc3BhY2UocmVwb1Jvb3QsIGFyZ3MudGFyZ2V0RmlsZSk7XG4gICAgICAgICAgdGFyZ2V0RmlsZUNvbnRlbnQgPSByZWFkRmlsZVNhZmUoYWJzb2x1dGUpID8/IHVuZGVmaW5lZDtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgICAgICAgYXdhaXQgdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgIGJhc2VQYXRoOiBwYXRoLnJlbGF0aXZlKGdldFdvcmtzcGFjZVJvb3QoKSwgcmVwb1Jvb3QpIHx8IFwiLlwiLFxuICAgICAgICBvYmplY3RUeXBlOiBhcmdzLm9iamVjdFR5cGUsXG4gICAgICAgIHRhcmdldEZpbGU6IGFyZ3MudGFyZ2V0RmlsZSxcbiAgICAgICAgZ3VpZGFuY2U6IHNlY3Rpb25zLFxuICAgICAgICBmaWxlczoge1xuICAgICAgICAgIHNvdXJjZTogcmVsYXRpdmVGaWxlcyhyZXBvUm9vdCwgc291cmNlRmlsZXMpLFxuICAgICAgICAgIHRlc3RzOiByZWxhdGl2ZUZpbGVzKHJlcG9Sb290LCB0ZXN0RmlsZXMpLFxuICAgICAgICB9LFxuICAgICAgICB0YXJnZXRGaWxlQ29udGVudDogYXJncy5pbmNsdWRlQ29udGVudCA/IHRhcmdldEZpbGVDb250ZW50IDogdW5kZWZpbmVkLFxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkocGF5bG9hZCwgbnVsbCwgMiksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0gc2F0aXNmaWVzIENvbnRlbnRSZXN1bHQ7XG4gICAgfSxcbiAgfTtcblxuZXhwb3J0IGNvbnN0IGNvdmVyYWdlRW5mb3JjZXJUb29sOiBUb29sPHVuZGVmaW5lZCwgdHlwZW9mIGNvdmVyYWdlVGFza1NjaGVtYT4gPVxuICB7XG4gICAgbmFtZTogXCJlbnN1cmUtdGVzdC1jb3ZlcmFnZVwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJSdW4gdGhlIGNvbmZpZ3VyZWQgY292ZXJhZ2UgY29tbWFuZCBhbmQgcmVwb3J0IHdoZXRoZXIgdGhlIHRhcmdldCBwZXJjZW50YWdlIGlzIG1ldCwgaGlnaGxpZ2h0aW5nIHdlYWsgZmlsZXMuXCIsXG4gICAgcGFyYW1ldGVyczogY292ZXJhZ2VUYXNrU2NoZW1hLFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIF9jb250ZXh0KTogUHJvbWlzZTxDb250ZW50UmVzdWx0PiA9PiB7XG4gICAgICBjb25zdCBhcmdzID0gY292ZXJhZ2VUYXNrU2NoZW1hLnBhcnNlKGlucHV0IGFzIENvdmVyYWdlVGFza0FyZ3MpO1xuICAgICAgY29uc3QgcmVwb1Jvb3QgPSBhd2FpdCByZXNvbHZlUmVwb1Jvb3QoYXJncy5iYXNlUGF0aCk7XG5cbiAgICAgIGlmICghYXJncy5kcnlSdW4pIHtcbiAgICAgICAgY29uc3QgZW52ID0ge1xuICAgICAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgICAgIFVTRV9XQVRDSE1BTjogXCJmYWxzZVwiLFxuICAgICAgICAgIFdBVENITUFOX0RJU0FCTEU6IFwiMVwiLFxuICAgICAgICAgIEpFU1RfRElTQUJMRV9XQVRDSE1BTjogXCIxXCIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHNwYXduU3luYyhcbiAgICAgICAgICBcIm5wbVwiLFxuICAgICAgICAgIFtcInJ1blwiLCBcImNvdmVyYWdlXCIsIFwiLS1cIiwgXCItLXdhdGNobWFuPWZhbHNlXCIsIFwiLS1ydW5JbkJhbmRcIl0sXG4gICAgICAgICAgeyBjd2Q6IHJlcG9Sb290LCBlbnYsIGVuY29kaW5nOiBcInV0ZjhcIiB9XG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgIT09IDApIHtcbiAgICAgICAgICBjb25zdCBtZXNzYWdlID1cbiAgICAgICAgICAgIHJlc3VsdC5zdGRlcnIgfHwgcmVzdWx0LnN0ZG91dCB8fCBcIkNvdmVyYWdlIGNvbW1hbmQgZmFpbGVkXCI7XG4gICAgICAgICAgYXdhaXQgdGhyb3dVc2VyRXJyb3IobWVzc2FnZS50cmltKCkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNvdmVyYWdlUGF0aCA9IHBhdGguam9pbihcbiAgICAgICAgcmVwb1Jvb3QsXG4gICAgICAgIFwid29ya2RvY3NcIixcbiAgICAgICAgXCJyZXBvcnRzXCIsXG4gICAgICAgIFwiY292ZXJhZ2VcIixcbiAgICAgICAgXCJjb3ZlcmFnZS1maW5hbC5qc29uXCJcbiAgICAgICk7XG5cbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhjb3ZlcmFnZVBhdGgpKSB7XG4gICAgICAgIGF3YWl0IHRocm93VXNlckVycm9yKFxuICAgICAgICAgIGBDb3ZlcmFnZSByZXBvcnQgbm90IGZvdW5kIGF0ICR7cGF0aC5yZWxhdGl2ZShyZXBvUm9vdCwgY292ZXJhZ2VQYXRoKX1gXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN1bW1hcnkgPSBjb21wdXRlQ292ZXJhZ2VGcm9tRmluYWwoY292ZXJhZ2VQYXRoKTtcbiAgICAgIGNvbnN0IG1lZXRzVGhyZXNob2xkID1cbiAgICAgICAgc3VtbWFyeS50b3RhbHMuc3RhdGVtZW50cy5wY3QgPj0gYXJncy5jb3ZlcmFnZSAmJlxuICAgICAgICBzdW1tYXJ5LnRvdGFscy5mdW5jdGlvbnMucGN0ID49IGFyZ3MuY292ZXJhZ2UgJiZcbiAgICAgICAgc3VtbWFyeS50b3RhbHMuYnJhbmNoZXMucGN0ID49IGFyZ3MuY292ZXJhZ2U7XG5cbiAgICAgIGNvbnN0IHdlYWtlc3QgPSBbLi4uc3VtbWFyeS5maWxlc11cbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IGEuc3RhdGVtZW50cyAtIGIuc3RhdGVtZW50cylcbiAgICAgICAgLnNsaWNlKDAsIDEwKTtcblxuICAgICAgY29uc3QgZ3VpZGFuY2UgPSBub3JtYWxpemVQcm9tcHRTZWN0aW9ucyhcbiAgICAgICAgY29sbGVjdFByb21wdFNlY3Rpb25zKFtcImJ1bGstdGVzdHNcIl0pXG4gICAgICApO1xuXG4gICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICBiYXNlUGF0aDogcGF0aC5yZWxhdGl2ZShnZXRXb3Jrc3BhY2VSb290KCksIHJlcG9Sb290KSB8fCBcIi5cIixcbiAgICAgICAgdGFyZ2V0OiBhcmdzLmNvdmVyYWdlLFxuICAgICAgICBtZWV0c1RocmVzaG9sZCxcbiAgICAgICAgdG90YWxzOiBzdW1tYXJ5LnRvdGFscyxcbiAgICAgICAgd2Vha2VzdCxcbiAgICAgICAgZ3VpZGFuY2UsXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeShwYXlsb2FkLCBudWxsLCAyKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSBzYXRpc2ZpZXMgQ29udGVudFJlc3VsdDtcbiAgICB9LFxuICB9O1xuXG5leHBvcnQgY29uc3QgcmVhZG1lSW1wcm92ZW1lbnRUb29sOiBUb29sPFxuICB1bmRlZmluZWQsXG4gIHR5cGVvZiByZWFkbWVJbXByb3ZlbWVudFNjaGVtYVxuPiA9IHtcbiAgbmFtZTogXCJpbXByb3ZlLXJlYWRtZVwiLFxuICBkZXNjcmlwdGlvbjpcbiAgICBcIlN1bW1hcml6ZSByZXF1aXJlZCBzdGVwcyB0byByZWZyZXNoIFJFQURNRSBhbmQgd29ya2RvY3MgY29udGVudCB1c2luZyAuY29kZXggZ3VpZGFuY2UgYW5kIHJlcG9zaXRvcnkgYW5hbHlzaXMuXCIsXG4gIHBhcmFtZXRlcnM6IHJlYWRtZUltcHJvdmVtZW50U2NoZW1hLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgX2NvbnRleHQpOiBQcm9taXNlPENvbnRlbnRSZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBhcmdzID0gcmVhZG1lSW1wcm92ZW1lbnRTY2hlbWEucGFyc2UoaW5wdXQgYXMgUmVhZG1lSW1wcm92ZW1lbnRBcmdzKTtcbiAgICBjb25zdCByZXBvUm9vdCA9IGF3YWl0IHJlc29sdmVSZXBvUm9vdChhcmdzLmJhc2VQYXRoKTtcblxuICAgIGNvbnN0IGFuYWx5c2lzID0gYW5hbHl6ZVJlcG8ocmVwb1Jvb3QpO1xuICAgIGNvbnN0IG1vZHVsZXMgPSBhbmFseXNpcy5maWxlc1xuICAgICAgLmZpbHRlcigoZmlsZSkgPT4gL2luZGV4XFwudHMkLy50ZXN0KGZpbGUpKVxuICAgICAgLm1hcCgoZmlsZSkgPT4gcGF0aC5yZWxhdGl2ZShyZXBvUm9vdCwgZmlsZSkpO1xuXG4gICAgY29uc3QgcHJvbXB0U2VjdGlvbnMgPSBub3JtYWxpemVQcm9tcHRTZWN0aW9ucyhcbiAgICAgIGNvbGxlY3RQcm9tcHRTZWN0aW9ucyhbXCJ1cGRhdGUtcmVhZG1lXCIsIFwiZG9jXCIsIFwibW9kdWxlXCJdKVxuICAgICk7XG5cbiAgICBjb25zdCB0ZXN0RXhhbXBsZXMgPSBPYmplY3Qua2V5cyhhbmFseXNpcy50ZXN0cyA/PyB7fSk7XG4gICAgY29uc3QgZXhhbXBsZXMgPSBhcmdzLmluY2x1ZGVFeGFtcGxlcyA/IHRlc3RFeGFtcGxlcy5zbGljZSgwLCAyMCkgOiBbXTtcblxuICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICBiYXNlUGF0aDogcGF0aC5yZWxhdGl2ZShnZXRXb3Jrc3BhY2VSb290KCksIHJlcG9Sb290KSB8fCBcIi5cIixcbiAgICAgIHN1bW1hcnk6IHtcbiAgICAgICAgbW9kdWxlcyxcbiAgICAgICAgdG90YWxTb3VyY2VGaWxlczogYW5hbHlzaXMuZmlsZXMubGVuZ3RoLFxuICAgICAgICB0b3RhbFRlc3RGaWxlczogYW5hbHlzaXMudGVzdEZpbGVzLmxlbmd0aCxcbiAgICAgICAgaGFzUmVhZG1lOiBCb29sZWFuKGFuYWx5c2lzLnJlYWRtZSksXG4gICAgICB9LFxuICAgICAgZ3VpZGFuY2U6IHByb21wdFNlY3Rpb25zLFxuICAgICAgc3VnZ2VzdGVkRXhhbXBsZXM6IGV4YW1wbGVzLFxuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkocGF5bG9hZCwgbnVsbCwgMiksXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0gc2F0aXNmaWVzIENvbnRlbnRSZXN1bHQ7XG4gIH0sXG59O1xuIiwiaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcblxuZXhwb3J0IHR5cGUgU2NhZmZvbGRSZXN1bHQgPSB7XG4gIG1vZHVsZVBhdGg6IHN0cmluZztcbiAgY3JlYXRlZEZpbGVzOiBzdHJpbmdbXTtcbn07XG5cbmNvbnN0IERFRkFVTFRfUExBQ0VIT0xERVJTID0ge1xuICBwcm9tcHRzOiBgZXhwb3J0IGNvbnN0IHByb21wdExpc3QgPSBbXG4gIHtcbiAgICBpZDogXCJleGFtcGxlLXByb21wdFwiLFxuICAgIHRpdGxlOiBcIkV4YW1wbGUgcHJvbXB0XCIsXG4gICAgZGVzY3JpcHRpb246IFwiQSBwbGFjZWhvbGRlciBwcm9tcHQgY3JlYXRlZCBieSBzY2FmZm9sZE1vZHVsZVwiLFxuICAgIGNvbnRlbnQ6IFwiRGVzY3JpYmUgdGhlIHRhc2sgZm9yIHRoZSBhc3Npc3RhbnQuLi5cIixcbiAgICBhYnNvbHV0ZVBhdGg6IF9fZmlsZW5hbWUsXG4gIH0sXG5dIGFzIGNvbnN0O1xuYCxcbiAgcmVzb3VyY2VzOiBgZXhwb3J0IGNvbnN0IHJlc291cmNlcyA9IFtcbiAge1xuICAgIGlkOiBcImV4YW1wbGUtcmVzb3VyY2VcIixcbiAgICBuYW1lOiBcIkV4YW1wbGUgUmVzb3VyY2VcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBIHBsYWNlaG9sZGVyIHJlc291cmNlIGNyZWF0ZWQgYnkgc2NhZmZvbGRNb2R1bGVcIixcbiAgICB1cmk6IFwiZmlsZTovL3BsYWNlaG9sZGVyXCIsXG4gICAgYWJzb2x1dGVQYXRoOiBfX2ZpbGVuYW1lLFxuICB9LFxuXSBhcyBjb25zdDtcbmAsXG4gIHRlbXBsYXRlczogYGV4cG9ydCBjb25zdCB0ZW1wbGF0ZXMgPSBbXG4gIHtcbiAgICBuYW1lOiBcImV4YW1wbGUtdGVtcGxhdGVcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBIHBsYWNlaG9sZGVyIHRlbXBsYXRlIGNyZWF0ZWQgYnkgc2NhZmZvbGRNb2R1bGVcIixcbiAgICB1cmlUZW1wbGF0ZTogXCJmaWxlOi8vdGVtcGxhdGUve3BhdGh9XCIsXG4gICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICB9LFxuXSBhcyBjb25zdDtcbmAsXG4gIHRvb2xzOiBgZXhwb3J0IGNvbnN0IHRvb2xMaXN0ID0gW1xuICB7XG4gICAgaWQ6IFwiZXhhbXBsZS10b29sXCIsXG4gICAgbmFtZTogXCJleGFtcGxlLXRvb2xcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBIHBsYWNlaG9sZGVyIHRvb2wgY3JlYXRlZCBieSBzY2FmZm9sZE1vZHVsZVwiLFxuICAgIHJ1bjogYXN5bmMgKCkgPT4gKHsgcmVzdWx0OiBcInBsYWNlaG9sZGVyXCIgfSksXG4gIH0sXG5dIGFzIGNvbnN0O1xuYCxcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgbW9kdWxlIHNjYWZmb2xkIHVuZGVyIHJlcG9Sb290L3NyYy9tb2R1bGVzLzxtb2R1bGVOYW1lPlxuICogUmV0dXJucyBjcmVhdGVkIGZpbGVzIGxpc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzY2FmZm9sZE1vZHVsZShcbiAgcmVwb1Jvb3Q6IHN0cmluZyxcbiAgbW9kdWxlTmFtZTogc3RyaW5nXG4pOiBTY2FmZm9sZFJlc3VsdCB7XG4gIGlmICghcmVwb1Jvb3QpIHRocm93IG5ldyBFcnJvcihcInJlcG9Sb290IGlzIHJlcXVpcmVkXCIpO1xuICBpZiAoIW1vZHVsZU5hbWUpIHRocm93IG5ldyBFcnJvcihcIm1vZHVsZU5hbWUgaXMgcmVxdWlyZWRcIik7XG5cbiAgY29uc3QgbW9kdWxlUGF0aCA9IHBhdGguam9pbihyZXBvUm9vdCwgXCJzcmNcIiwgXCJtb2R1bGVzXCIsIG1vZHVsZU5hbWUpO1xuICBjb25zdCBjcmVhdGVkRmlsZXM6IHN0cmluZ1tdID0gW107XG5cbiAgY29uc3Qgc3ViZm9sZGVycyA9IFtcInByb21wdHNcIiwgXCJyZXNvdXJjZXNcIiwgXCJ0ZW1wbGF0ZXNcIiwgXCJ0b29sc1wiXTtcblxuICBmb3IgKGNvbnN0IGZvbGRlciBvZiBzdWJmb2xkZXJzKSB7XG4gICAgY29uc3QgZm9sZGVyUGF0aCA9IHBhdGguam9pbihtb2R1bGVQYXRoLCBmb2xkZXIpO1xuICAgIGZzLm1rZGlyU3luYyhmb2xkZXJQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBjb25zdCBpbmRleFBhdGggPSBwYXRoLmpvaW4oZm9sZGVyUGF0aCwgXCJpbmRleC50c1wiKTtcbiAgICAvLyBpZiBmaWxlIGV4aXN0cywgc2tpcCB3cml0aW5nXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGluZGV4UGF0aCkpIHtcbiAgICAgIC8vIGluc2VydCBfX2ZpbGVuYW1lIGZvciBhYnNvbHV0ZVBhdGggaW4gcGxhY2Vob2xkZXJzXG4gICAgICBjb25zdCBjb250ZW50ID0gREVGQVVMVF9QTEFDRUhPTERFUlNbXG4gICAgICAgIGZvbGRlciBhcyBrZXlvZiB0eXBlb2YgREVGQVVMVF9QTEFDRUhPTERFUlNcbiAgICAgIF0ucmVwbGFjZSgvX19maWxlbmFtZS9nLCBKU09OLnN0cmluZ2lmeShpbmRleFBhdGgpKTtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoaW5kZXhQYXRoLCBjb250ZW50LCB7IGVuY29kaW5nOiBcInV0ZjhcIiB9KTtcbiAgICAgIGNyZWF0ZWRGaWxlcy5wdXNoKGluZGV4UGF0aCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgbW9kdWxlUGF0aCwgY3JlYXRlZEZpbGVzIH07XG59XG5cbi8vIENMSSBzdXBwb3J0IHdoZW4gcmVxdWlyZWQgZGlyZWN0bHkgdmlhIHRzLW5vZGUgcmVnaXN0cmF0aW9uXG5pZiAocmVxdWlyZS5tYWluID09PSBtb2R1bGUpIHtcbiAgY29uc3QgWywgLCBtb2R1bGVOYW1lXSA9IHByb2Nlc3MuYXJndjtcbiAgaWYgKCFtb2R1bGVOYW1lKSB7XG4gICAgY29uc29sZS5lcnJvcihcIlVzYWdlOiBzY2FmZm9sZC1tb2R1bGUgPG1vZHVsZS1uYW1lPlwiKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCByZXMgPSBzY2FmZm9sZE1vZHVsZShwcm9jZXNzLmN3ZCgpLCBtb2R1bGVOYW1lKTtcbiAgICBjb25zb2xlLmxvZyhcIlNjYWZmb2xkZWQgbW9kdWxlOlwiLCByZXMubW9kdWxlUGF0aCk7XG4gICAgZm9yIChjb25zdCBmIG9mIHJlcy5jcmVhdGVkRmlsZXMpIGNvbnNvbGUubG9nKFwiICBjcmVhdGVkOlwiLCBmKTtcbiAgICBwcm9jZXNzLmV4aXQoMCk7XG4gIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgY29uc29sZS5lcnJvcihlcnIgJiYgZXJyLm1lc3NhZ2UgPyBlcnIubWVzc2FnZSA6IGVycik7XG4gICAgcHJvY2Vzcy5leGl0KDIpO1xuICB9XG59XG4iLCIvLyBOZXcgdG9vbDogZ2VuZXJhdGUtbWNwLW1vZHVsZVxuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB0eXBlIHsgVG9vbCB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuaW1wb3J0IHsgZ2V0V29ya3NwYWNlUm9vdCB9IGZyb20gXCIuLi93b3Jrc3BhY2VcIjtcbmltcG9ydCB7IGFuYWx5emVSZXBvIH0gZnJvbSBcIi4uL2NvZGVcIjtcbmltcG9ydCB7IHNjYWZmb2xkTW9kdWxlIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vc2NhZmZvbGRNb2R1bGVcIjtcblxuY29uc3QgZ2VuZXJhdGVTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIHJlcG9QYXRoOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVmYXVsdChcIi5cIiksXG4gIG1vZHVsZU5hbWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgaW5jbHVkZURvY3M6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG59KTtcblxudHlwZSBHZW5lcmF0ZUFyZ3MgPSB6LmluZmVyPHR5cGVvZiBnZW5lcmF0ZVNjaGVtYT47XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZU1jcE1vZHVsZVRvb2w6IFRvb2w8dW5kZWZpbmVkLCB0eXBlb2YgZ2VuZXJhdGVTY2hlbWE+ID0ge1xuICBuYW1lOiBcImdlbmVyYXRlLW1jcC1tb2R1bGVcIixcbiAgZGVzY3JpcHRpb246XG4gICAgXCJHZW5lcmF0ZSBhIG1pbmltYWwgTUNQIG1vZHVsZSB1bmRlciBzcmMvbW9kdWxlcy88bmFtZT4gYnkgYW5hbHl6aW5nIGEgdGFyZ2V0IHJlcG9zaXRvcnkgYW5kIGV4cG9ydGluZyBwcm9tcHRzLCByZXNvdXJjZXMsIHRlbXBsYXRlcyBhbmQgdG9vbHMuXCIsXG4gIHBhcmFtZXRlcnM6IGdlbmVyYXRlU2NoZW1hLFxuICBleGVjdXRlOiBhc3luYyAoaW5wdXQpID0+IHtcbiAgICBjb25zdCBhcmdzID0gZ2VuZXJhdGVTY2hlbWEucGFyc2UoaW5wdXQgYXMgYW55KTtcbiAgICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICAgIGxldCByZXBvUm9vdCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBhcmdzLnJlcG9QYXRoIHx8IFwiLlwiKTtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMocmVwb1Jvb3QpKSB7XG4gICAgICBjb25zdCBhbHQgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgXCIuLlwiLCBhcmdzLnJlcG9QYXRoKTtcbiAgICAgIGlmIChmcy5leGlzdHNTeW5jKGFsdCkpIHJlcG9Sb290ID0gYWx0O1xuICAgIH1cbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMocmVwb1Jvb3QpKSB7XG4gICAgICBjb25zdCBhbHQyID0gcGF0aC5yZXNvbHZlKFxuICAgICAgICBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICBcIi4uXCIsXG4gICAgICAgIHBhdGguYmFzZW5hbWUoYXJncy5yZXBvUGF0aClcbiAgICAgICk7XG4gICAgICBpZiAoZnMuZXhpc3RzU3luYyhhbHQyKSkgcmVwb1Jvb3QgPSBhbHQyO1xuICAgIH1cbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMocmVwb1Jvb3QpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXBvc2l0b3J5IG5vdCBmb3VuZCBhdCAke3JlcG9Sb290fWApO1xuXG4gICAgY29uc3QgYW5hbHlzaXMgPSBhbmFseXplUmVwbyhyZXBvUm9vdCk7XG4gICAgY29uc3QgaW5mZXJyZWROYW1lID1cbiAgICAgIGFyZ3MubW9kdWxlTmFtZSA/PyBwYXRoLmJhc2VuYW1lKHBhdGgucmVzb2x2ZShyZXBvUm9vdCkpO1xuICAgIGNvbnN0IG1vZHVsZVJvb3QgPSBwYXRoLmpvaW4ocm9vdCwgXCJzcmNcIiwgXCJtb2R1bGVzXCIsIGluZmVycmVkTmFtZSk7XG5cbiAgICAvLyBVc2UgZXhpc3Rpbmcgc2NhZmZvbGQgdG8gY3JlYXRlIGZvbGRlcnNcbiAgICBzY2FmZm9sZE1vZHVsZShyb290LCBpbmZlcnJlZE5hbWUpO1xuXG4gICAgLy8gcG9wdWxhdGUgcHJvbXB0czogY29weSBtYXJrZG93biBwcm9tcHRzIGZyb20gUkVBRE1FLm1kIGFuZCBkb2NzL1xuICAgIGNvbnN0IHByb21wdHNEaXIgPSBwYXRoLmpvaW4obW9kdWxlUm9vdCwgXCJwcm9tcHRzXCIpO1xuICAgIGNvbnN0IHJlc291cmNlc0RpciA9IHBhdGguam9pbihtb2R1bGVSb290LCBcInJlc291cmNlc1wiKTtcbiAgICBjb25zdCB0ZW1wbGF0ZXNEaXIgPSBwYXRoLmpvaW4obW9kdWxlUm9vdCwgXCJ0ZW1wbGF0ZXNcIik7XG4gICAgY29uc3QgdG9vbHNEaXIgPSBwYXRoLmpvaW4obW9kdWxlUm9vdCwgXCJ0b29sc1wiKTtcblxuICAgIC8vIGhlbHBlciB0byB3cml0ZSBhbiBpbmRleC50cyB0aGF0IGV4cG9ydHMgYXJyYXlzXG4gICAgZnVuY3Rpb24gd3JpdGVJbmRleChkaXI6IHN0cmluZywgdmFyTmFtZTogc3RyaW5nLCBpdGVtczogc3RyaW5nKSB7XG4gICAgICBjb25zdCBwID0gcGF0aC5qb2luKGRpciwgXCJpbmRleC50c1wiKTtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBgZXhwb3J0IGNvbnN0ICR7dmFyTmFtZX0gPSAke2l0ZW1zfSBhcyBjb25zdDtcXG5gO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhwLCBjb250ZW50LCB7IGVuY29kaW5nOiBcInV0ZjhcIiB9KTtcbiAgICB9XG5cbiAgICAvLyBQcm9tcHRzOiBjcmVhdGUgYSBzaW1wbGUgcHJvbXB0IGZyb20gUkVBRE1FIGFuZCBhbnkgLm1kIGluIGRvY3NcbiAgICBjb25zdCBwcm9tcHRBc3NldHM6IGFueVtdID0gW107XG4gICAgaWYgKGFyZ3MuaW5jbHVkZURvY3MpIHtcbiAgICAgIGNvbnN0IHJlYWRtZSA9IHBhdGguam9pbihyZXBvUm9vdCwgXCJSRUFETUUubWRcIik7XG4gICAgICBpZiAoZnMuZXhpc3RzU3luYyhyZWFkbWUpKSB7XG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMocmVhZG1lLCBcInV0ZjhcIik7XG4gICAgICAgIGNvbnN0IGlkID0gXCJyZWFkbWVcIjtcbiAgICAgICAgY29uc3QgcHJvbXB0UGF0aCA9IHBhdGguam9pbihwcm9tcHRzRGlyLCBgJHtpZH0ubWRgKTtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhwcm9tcHRQYXRoLCBjb250ZW50LCB7IGVuY29kaW5nOiBcInV0ZjhcIiB9KTtcbiAgICAgICAgcHJvbXB0QXNzZXRzLnB1c2goe1xuICAgICAgICAgIGlkLFxuICAgICAgICAgIHRpdGxlOiBcIlJFQURNRVwiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlJlcG9zaXRvcnkgUkVBRE1FXCIsXG4gICAgICAgICAgYWJzb2x1dGVQYXRoOiBwcm9tcHRQYXRoLFxuICAgICAgICAgIGxvYWQ6ICgpID0+IGNvbnRlbnQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZG9jc0RpciA9IHBhdGguam9pbihyZXBvUm9vdCwgXCJkb2NzXCIpO1xuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoZG9jc0RpcikgJiYgZnMuc3RhdFN5bmMoZG9jc0RpcikuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICBmb3IgKGNvbnN0IGYgb2YgZnMucmVhZGRpclN5bmMoZG9jc0RpcikpIHtcbiAgICAgICAgICBpZiAoIWYuZW5kc1dpdGgoXCIubWRcIikpIGNvbnRpbnVlO1xuICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMocGF0aC5qb2luKGRvY3NEaXIsIGYpLCBcInV0ZjhcIik7XG4gICAgICAgICAgY29uc3QgaWQgPSBwYXRoLnBhcnNlKGYpLm5hbWU7XG4gICAgICAgICAgY29uc3QgcHJvbXB0UGF0aCA9IHBhdGguam9pbihwcm9tcHRzRGlyLCBgJHtpZH0ubWRgKTtcbiAgICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHByb21wdFBhdGgsIGNvbnRlbnQsIHsgZW5jb2Rpbmc6IFwidXRmOFwiIH0pO1xuICAgICAgICAgIHByb21wdEFzc2V0cy5wdXNoKHtcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgdGl0bGU6IGlkLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IGNvbnRlbnQuc3BsaXQoL1xccj9cXG4vKVswXSB8fCBcIlwiLFxuICAgICAgICAgICAgYWJzb2x1dGVQYXRoOiBwcm9tcHRQYXRoLFxuICAgICAgICAgICAgbG9hZDogKCkgPT4gY29udGVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHdyaXRlSW5kZXgocHJvbXB0c0RpciwgXCJwcm9tcHRzXCIsIEpTT04uc3RyaW5naWZ5KHByb21wdEFzc2V0cywgbnVsbCwgMikpO1xuXG4gICAgLy8gUmVzb3VyY2VzOiByZWZlcmVuY2UgdGhlIHJlcG8gcm9vdCBhbmQgZG9jc1xuICAgIGNvbnN0IHJlc291cmNlQXNzZXRzID0gW1xuICAgICAge1xuICAgICAgICBpZDogYCR7aW5mZXJyZWROYW1lfS5yZXBvYCxcbiAgICAgICAgbmFtZTogYCR7aW5mZXJyZWROYW1lfSByZXBvc2l0b3J5YCxcbiAgICAgICAgZGVzY3JpcHRpb246IFwiU291cmNlIHJlcG9zaXRvcnlcIixcbiAgICAgICAgdXJpOiBgZmlsZTovLyR7cmVwb1Jvb3R9YCxcbiAgICAgICAgYWJzb2x1dGVQYXRoOiByZXBvUm9vdCxcbiAgICAgIH0sXG4gICAgXTtcbiAgICB3cml0ZUluZGV4KFxuICAgICAgcmVzb3VyY2VzRGlyLFxuICAgICAgXCJyZXNvdXJjZXNcIixcbiAgICAgIEpTT04uc3RyaW5naWZ5KHJlc291cmNlQXNzZXRzLCBudWxsLCAyKVxuICAgICk7XG5cbiAgICAvLyBUZW1wbGF0ZXM6IGNyZWF0ZSBhIHBsYWNlaG9sZGVyIHRlbXBsYXRlIHRoYXQgcmVmZXJlbmNlcyBSRUFETUVcbiAgICBjb25zdCB0ZW1wbGF0ZUFzc2V0cyA9IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogXCJyZWFkbWUtdGVtcGxhdGVcIixcbiAgICAgICAgZGVzY3JpcHRpb246IFwiUkVBRE1FIGFzIGd1aWRhbmNlXCIsXG4gICAgICAgIHVyaVRlbXBsYXRlOiBgZmlsZTovLyR7cGF0aC5qb2luKHJlcG9Sb290LCBcIlJFQURNRS5tZFwiKX1gLFxuICAgICAgICBtaW1lVHlwZTogXCJ0ZXh0L21hcmtkb3duXCIsXG4gICAgICB9LFxuICAgIF07XG4gICAgd3JpdGVJbmRleChcbiAgICAgIHRlbXBsYXRlc0RpcixcbiAgICAgIFwidGVtcGxhdGVzXCIsXG4gICAgICBKU09OLnN0cmluZ2lmeSh0ZW1wbGF0ZUFzc2V0cywgbnVsbCwgMilcbiAgICApO1xuXG4gICAgLy8gVG9vbHM6IGNyZWF0ZSBhIHdyYXBwZXIgdG9vbCB0aGF0IGV4cG9zZXMgYW5hbHl6ZS9lbnVtZXJhdGUgZm9yIHRoZSBtb2R1bGVcbiAgICBjb25zdCB0b29sSW5kZXhQYXRoID0gcGF0aC5qb2luKHRvb2xzRGlyLCBcImluZGV4LnRzXCIpO1xuICAgIGNvbnN0IHRvb2xDb250ZW50ID0gYGltcG9ydCB0eXBlIHsgVG9vbCB9IGZyb20gJ2Zhc3RtY3AnO1xcbmltcG9ydCB7IGJ1aWxkQW5hbHl6ZVJlcG9zaXRvcnlUb29sLCBidWlsZEVudW1lcmF0ZUNhcGFiaWxpdGllc1Rvb2wsIGJ1aWxkUGxhbkZlYXR1cmVUb29sIH0gZnJvbSAnLi4vLi4vLi4vbWNwL3Rvb2xzL3Rvb2xzJztcXG5leHBvcnQgY29uc3QgdG9vbHMgPSBbXFxuICB7IGlkOiAnJHtpbmZlcnJlZE5hbWV9LmFuYWx5emUnLCB0aXRsZTogJ0FuYWx5emUgJHtpbmZlcnJlZE5hbWV9JywgZGVzY3JpcHRpb246ICdBbmFseXplIHRoZSB0YXJnZXQgcmVwb3NpdG9yeScsIHRvb2w6IGJ1aWxkQW5hbHl6ZVJlcG9zaXRvcnlUb29sKCkgfSxcXG4gIHsgaWQ6ICcke2luZmVycmVkTmFtZX0uZW51bWVyYXRlJywgdGl0bGU6ICdFbnVtZXJhdGUgY2FwYWJpbGl0aWVzIGZvciAke2luZmVycmVkTmFtZX0nLCBkZXNjcmlwdGlvbjogJ0VudW1lcmF0ZSBjYXBhYmlsaXRpZXMnLCB0b29sOiBidWlsZEVudW1lcmF0ZUNhcGFiaWxpdGllc1Rvb2woKSB9LFxcbiAgeyBpZDogJyR7aW5mZXJyZWROYW1lfS5wbGFuJywgdGl0bGU6ICdQbGFuIGZlYXR1cmVzIGZvciAke2luZmVycmVkTmFtZX0nLCBkZXNjcmlwdGlvbjogJ1BsYW4gZmVhdHVyZSBpbXBsZW1lbnRhdGlvbicsIHRvb2w6IGJ1aWxkUGxhbkZlYXR1cmVUb29sKCkgfSxcXG5dIGFzIGNvbnN0O1xcbmA7XG4gICAgZnMud3JpdGVGaWxlU3luYyh0b29sSW5kZXhQYXRoLCB0b29sQ29udGVudCwgeyBlbmNvZGluZzogXCJ1dGY4XCIgfSk7XG5cbiAgICAvLyBXcml0ZSBtb2R1bGUgaW5kZXgudHNcbiAgICBjb25zdCBtb2R1bGVJbmRleCA9IHBhdGguam9pbihtb2R1bGVSb290LCBcImluZGV4LnRzXCIpO1xuICAgIGNvbnN0IG1vZHVsZUluZGV4Q29udGVudCA9IGBpbXBvcnQgeyBwcm9tcHRzIH0gZnJvbSAnLi9wcm9tcHRzJztcXG5pbXBvcnQgeyByZXNvdXJjZXMgfSBmcm9tICcuL3Jlc291cmNlcyc7XFxuaW1wb3J0IHsgdGVtcGxhdGVzIH0gZnJvbSAnLi90ZW1wbGF0ZXMnO1xcbmltcG9ydCB7IHRvb2xzIH0gZnJvbSAnLi90b29scyc7XFxuZXhwb3J0IHsgcHJvbXB0cyB9IGZyb20gJy4vcHJvbXB0cyc7XFxuZXhwb3J0IHsgcmVzb3VyY2VzIH0gZnJvbSAnLi9yZXNvdXJjZXMnO1xcbmV4cG9ydCB7IHRlbXBsYXRlcyB9IGZyb20gJy4vdGVtcGxhdGVzJztcXG5leHBvcnQgeyB0b29scyB9IGZyb20gJy4vdG9vbHMnO1xcbmV4cG9ydCBjb25zdCBtb2R1bGVQYWNrYWdlID0geyBuYW1lOiAnJHtpbmZlcnJlZE5hbWV9JywgcHJvbXB0cywgcmVzb3VyY2VzLCB0ZW1wbGF0ZXMsIHRvb2xzIH0gYXMgY29uc3Q7XFxuYDtcbiAgICBmcy53cml0ZUZpbGVTeW5jKG1vZHVsZUluZGV4LCBtb2R1bGVJbmRleENvbnRlbnQsIHsgZW5jb2Rpbmc6IFwidXRmOFwiIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBtb2R1bGVSb290LFxuICAgICAgICAgICAgICBpbmZlcnJlZE5hbWUsXG4gICAgICAgICAgICAgIGFuYWx5c2lzU3VtbWFyeToge1xuICAgICAgICAgICAgICAgIGZpbGVzOiBhbmFseXNpcy5maWxlcy5sZW5ndGgsXG4gICAgICAgICAgICAgICAgdGVzdEZpbGVzOiBhbmFseXNpcy50ZXN0RmlsZXMubGVuZ3RoLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAyXG4gICAgICAgICAgKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGdlbmVyYXRlTWNwTW9kdWxlVG9vbDtcbiIsImltcG9ydCB7IGRlY29yYXRvclRvb2xzIH0gZnJvbSBcIi4uL2RlY29yYXRvci10b29sc1wiO1xuaW1wb3J0IHsgbW9kdWxlUmVnaXN0cnkgfSBmcm9tIFwiLi4vbW9kdWxlUmVnaXN0cnlcIjtcbmltcG9ydCB7XG4gIGFwcGx5Q29kZUNoYW5nZVRvb2wsXG4gIGRvY3VtZW50Q29kZVRvb2wsXG4gIHRvb2xMaXN0IGFzIGNvcmVUb29sTGlzdCxcbn0gZnJvbSBcIi4vdG9vbHNcIjtcbmltcG9ydCB7XG4gIGNvdmVyYWdlRW5mb3JjZXJUb29sLFxuICBkb2N1bWVudE9iamVjdFRvb2wsXG4gIHJlYWRtZUltcHJvdmVtZW50VG9vbCxcbn0gZnJvbSBcIi4vY29kZXgtdG9vbHNcIjtcblxuZXhwb3J0ICogZnJvbSBcIi4vdG9vbHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvZGV4LXRvb2xzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9nZW5lcmF0ZU1jcE1vZHVsZVwiO1xuXG5jb25zdCBjb2RleFRvb2xMaXN0ID0gW1xuICBkb2N1bWVudE9iamVjdFRvb2wsXG4gIGNvdmVyYWdlRW5mb3JjZXJUb29sLFxuICByZWFkbWVJbXByb3ZlbWVudFRvb2wsXG5dO1xuXG5jb25zdCBtb2R1bGVUb29sTGlzdCA9IG1vZHVsZVJlZ2lzdHJ5Lmxpc3RUb29scygpLm1hcCgoYXNzZXQpID0+IGFzc2V0LnRvb2wgYXMgYW55KTtcblxuZXhwb3J0IGNvbnN0IHRvb2xMaXN0ID0gWy4uLmNvcmVUb29sTGlzdCwgLi4uY29kZXhUb29sTGlzdCwgLi4ubW9kdWxlVG9vbExpc3RdO1xuZXhwb3J0IGNvbnN0IGRlY29yYXRvclRvb2xMaXN0ID0gT2JqZWN0LnZhbHVlcyhkZWNvcmF0b3JUb29scyk7XG5jb25zdCBbXG4gIGFuYWx5emVSZXBvc2l0b3J5VG9vbCxcbiAgZW51bWVyYXRlQ2FwYWJpbGl0aWVzVG9vbCxcbiAgcGxhbkZlYXR1cmVUb29sLFxuICBkb2N1bWVudENvZGVUb29sUmVmLFxuICBhcHBseUNvZGVDaGFuZ2VUb29sUmVmLFxuXSA9IGNvcmVUb29sTGlzdDtcblxuZXhwb3J0IGNvbnN0IHRvb2xzID0ge1xuICBhbmFseXplUmVwb3NpdG9yeVRvb2wsXG4gIGVudW1lcmF0ZUNhcGFiaWxpdGllc1Rvb2wsXG4gIHBsYW5GZWF0dXJlVG9vbCxcbiAgZG9jdW1lbnRDb2RlVG9vbDogZG9jdW1lbnRDb2RlVG9vbFJlZixcbiAgYXBwbHlDb2RlQ2hhbmdlVG9vbDogYXBwbHlDb2RlQ2hhbmdlVG9vbFJlZixcbiAgZG9jdW1lbnRPYmplY3RUb29sLFxuICBjb3ZlcmFnZUVuZm9yY2VyVG9vbCxcbiAgcmVhZG1lSW1wcm92ZW1lbnRUb29sLFxuICAuLi5kZWNvcmF0b3JUb29scyxcbn07XG5cbmV4cG9ydCB7IGRlY29yYXRvclRvb2xzIH07IiwiaW1wb3J0IHR5cGUgeyBSZXNvdXJjZSB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQgdHlwZSB7IFJlc291cmNlQXNzZXQgfSBmcm9tIFwiLi4vLi4vdHlwZXNcIjtcbmltcG9ydCB7IG1vZHVsZVJlZ2lzdHJ5IH0gZnJvbSBcIi4uL21vZHVsZVJlZ2lzdHJ5XCI7XG5pbXBvcnQgeyBnZXRXb3Jrc3BhY2VSb290IH0gZnJvbSBcIi4uL3dvcmtzcGFjZVwiO1xuaW1wb3J0IHsgYnVpbGRPYmplY3RQcm9tcHRzLCBkaXNjb3ZlckRvY1Byb21wdHMgfSBmcm9tIFwiLi4vcHJvbXB0cy9wcm9tcHRzXCI7XG5cbmZ1bmN0aW9uIHRvUmVzb3VyY2UoYXNzZXQ6IFJlc291cmNlQXNzZXQpOiBSZXNvdXJjZTx1bmRlZmluZWQ+IHtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBhc3NldC5pZCxcbiAgICB1cmk6IGFzc2V0LnVyaSxcbiAgICBkZXNjcmlwdGlvbjogYXNzZXQuZGVzY3JpcHRpb24gPz8gYXNzZXQudGl0bGUsXG4gICAgbWltZVR5cGU6IGFzc2V0Lm1pbWVUeXBlLFxuICAgIGxvYWQ6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFzc2V0LmxvYWQoKTtcbiAgICAgIC8vIGFzc2V0LmxvYWQgbWF5IHJldHVybiBhIENvbnRlbnRSZXN1bHQgb3IgYSBQcm9taXNlIG9mIENvbnRlbnRSZXN1bHQ7IGVuc3VyZSB3ZSByZXR1cm4gUmVzb3VyY2VSZXN1bHQtbGlrZSBvYmplY3RcbiAgICAgIGlmICgocmVzIGFzIGFueSk/LmNvbnRlbnQpIHtcbiAgICAgICAgY29uc3QgY3IgPSByZXMgYXMgYW55O1xuICAgICAgICAvLyBJZiBDb250ZW50UmVzdWx0LCBjb252ZXJ0IHRvIHNpbXBsZSB0ZXh0IHJlc3VsdCBleHBlY3RlZCBieSBSZXNvdXJjZS5sb2FkIGNvbnN1bWVyc1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRleHQ6IEFycmF5LmlzQXJyYXkoY3IuY29udGVudClcbiAgICAgICAgICAgID8gY3IuY29udGVudC5tYXAoKGM6IGFueSkgPT4gYy50ZXh0KS5qb2luKFwiXFxuXCIpXG4gICAgICAgICAgICA6IFN0cmluZyhjciksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyBmYWxsYmFjayBmb3Igb2JqZWN0cyB3aXRoIHRleHRcbiAgICAgIHJldHVybiByZXMgYXMgYW55IGFzIHsgdGV4dDogc3RyaW5nIH07XG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gYnVpbGRNb2R1bGVSZXNvdXJjZXMoKTogUmVzb3VyY2U8dW5kZWZpbmVkPltdIHtcbiAgcmV0dXJuIG1vZHVsZVJlZ2lzdHJ5Lmxpc3RSZXNvdXJjZXMoKS5tYXAodG9SZXNvdXJjZSk7XG59XG5cbmV4cG9ydCBjb25zdCByZXNvdXJjZXM6IFJlc291cmNlPHVuZGVmaW5lZD5bXSA9IFtcbiAge1xuICAgIG5hbWU6IFwiY29kZXgtcHJvbXB0LWluZGV4XCIsXG4gICAgdXJpOiBcImNvZGV4Oi8vcHJvbXB0cy9pbmRleFwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJFbnVtZXJhdGUgYXZhaWxhYmxlIC5jb2RleCBwcm9tcHQgZmlsZXMgd2l0aCB0aXRsZXMgYW5kIGRlc2NyaXB0aW9ucy5cIixcbiAgICBtaW1lVHlwZTogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgbG9hZDogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgICAgIGNvbnN0IHByb21wdHMgPSBkaXNjb3ZlckRvY1Byb21wdHMocm9vdCkubWFwKChwcm9tcHQpID0+ICh7XG4gICAgICAgIG5hbWU6IHByb21wdC5uYW1lLFxuICAgICAgICB0aXRsZTogcHJvbXB0LnRpdGxlLFxuICAgICAgICBkZXNjcmlwdGlvbjogcHJvbXB0LmRlc2NyaXB0aW9uLFxuICAgICAgICBwYXRoOiBwcm9tcHQuYWJzb2x1dGVQYXRoLFxuICAgICAgfSkpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoeyBwcm9tcHRzIH0sIG51bGwsIDIpLFxuICAgICAgICBtaW1lVHlwZTogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICB9O1xuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiBcImNvZGV4LW9iamVjdC1wcm9tcHRzXCIsXG4gICAgdXJpOiBcImNvZGV4Oi8vcHJvbXB0cy9vYmplY3RzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlByb3ZpZGVzIHRoZSByZXNvbHZlZCBwcm9tcHQgY29udGVudCBmb3IgZWFjaCBkb2N1bWVudGVkIG9iamVjdCB3b3JrZmxvdy5cIixcbiAgICBtaW1lVHlwZTogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgbG9hZDogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZW50cmllcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBidWlsZE9iamVjdFByb21wdHMoKS5tYXAoYXN5bmMgKHByb21wdCkgPT4gKHtcbiAgICAgICAgICBuYW1lOiBwcm9tcHQubmFtZSxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogcHJvbXB0LmRlc2NyaXB0aW9uLFxuICAgICAgICAgIGNvbnRlbnQ6IGF3YWl0IHByb21wdC5sb2FkKHt9IGFzIG5ldmVyKSxcbiAgICAgICAgfSkpXG4gICAgICApO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoeyBwcm9tcHRzOiBlbnRyaWVzIH0sIG51bGwsIDIpLFxuICAgICAgICBtaW1lVHlwZTogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICB9O1xuICAgIH0sXG4gIH0sXG4gIC4uLmJ1aWxkTW9kdWxlUmVzb3VyY2VzKCksXG5dO1xuIiwiaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IGdldFdvcmtzcGFjZVJvb3QsIHJlc29sdmVJbldvcmtzcGFjZSB9IGZyb20gXCIuLi93b3Jrc3BhY2VcIjtcbmltcG9ydCB0eXBlIHsgUHJvbXB0UmVzb3VyY2VUZW1wbGF0ZSB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG5leHBvcnQgY29uc3QgY29kZXhQcm9tcHRUZW1wbGF0ZXM6IFByb21wdFJlc291cmNlVGVtcGxhdGVbXSA9IFtdO1xuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRDb2RleFByb21wdFRlbXBsYXRlcygpOiBQcm9tcHRSZXNvdXJjZVRlbXBsYXRlW10ge1xuICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICBjb25zdCB0ZW1wbGF0ZXM6IFByb21wdFJlc291cmNlVGVtcGxhdGVbXSA9IFtcbiAgICB7XG4gICAgICBuYW1lOiBcImNvZGV4LXByb21wdFwiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiTG9hZCBhIC5jb2RleCBwcm9tcHQgZmlsZSBieSBuYW1lICh3aXRob3V0IGV4dGVuc2lvbikgYXMgbWFya2Rvd24uXCIsXG4gICAgICB1cmlUZW1wbGF0ZTogXCJjb2RleC1wcm9tcHQ6Ly97bmFtZX1cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvbWFya2Rvd25cIixcbiAgICAgIGFyZ3VtZW50czogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJuYW1lXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIk5hbWUgb2YgdGhlIHByb21wdCBmaWxlIGluc2lkZSAuY29kZXgvcHJvbXB0cyAod2l0aG91dCAubWQpLlwiLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGxvYWQ6IGFzeW5jICh7IG5hbWUgfSkgPT4ge1xuICAgICAgICBjb25zdCBwcm9tcHRQYXRoID0gcmVzb2x2ZUluV29ya3NwYWNlKFxuICAgICAgICAgIHJvb3QsXG4gICAgICAgICAgcGF0aC5qb2luKFwiLmNvZGV4XCIsIFwicHJvbXB0c1wiLCBgJHtuYW1lfS5tZGApXG4gICAgICAgICk7XG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyhwcm9tcHRQYXRoKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUHJvbXB0IC5jb2RleC9wcm9tcHRzLyR7bmFtZX0ubWQgbm90IGZvdW5kYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGV4dCA9IGZzLnJlYWRGaWxlU3luYyhwcm9tcHRQYXRoLCBcInV0ZjhcIik7XG4gICAgICAgIHJldHVybiB7IHRleHQsIHVyaTogYGNvZGV4LXByb21wdDovLy8ke25hbWV9YCB9O1xuICAgICAgfSxcbiAgICB9LFxuICBdO1xuXG4gIGNvZGV4UHJvbXB0VGVtcGxhdGVzLnNwbGljZSgwLCBjb2RleFByb21wdFRlbXBsYXRlcy5sZW5ndGgsIC4uLnRlbXBsYXRlcyk7XG4gIHJldHVybiBjb2RleFByb21wdFRlbXBsYXRlcztcbn1cbiIsImltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgdHlwZSB7IERlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRXb3Jrc3BhY2VSb290LCByZWFkV29ya3NwYWNlRmlsZSB9IGZyb20gXCIuLi93b3Jrc3BhY2VcIjtcblxuZXhwb3J0IGNvbnN0IGRlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlczogRGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVbXSA9IFtdO1xuXG5mdW5jdGlvbiBtYWtlTG9hZGVyKHR5cGU6IFwic3JjXCIgfCBcInRlc3RzXCIgfCBcIndvcmtkb2NzXCIpIHtcbiAgcmV0dXJuIGFzeW5jICh7IHBhdGg6IHJlbGF0aXZlIH06IHsgcGF0aDogc3RyaW5nIH0pID0+IHtcbiAgICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICAgIGNvbnN0IHRhcmdldCA9IHBhdGguam9pbih0eXBlLCByZWxhdGl2ZSk7XG4gICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlYWRXb3Jrc3BhY2VGaWxlKHJvb3QsIHRhcmdldCk7XG4gICAgcmV0dXJuIHsgdGV4dCB9O1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGREZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMoKTogRGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVbXSB7XG4gIGNvbnN0IHRlbXBsYXRlczogRGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVbXSA9IFtcbiAgICB7XG4gICAgICBuYW1lOiBcInJlYWQtY29kZS1mcm9tLXNvdXJjZVwiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiUmVhZCBhIGZpbGUgZnJvbSB0aGUgPGJhc2VfcGF0aD4vc3JjIHRyZWUgYnkgcmVsYXRpdmUgcGF0aC5cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcImZyb20tc291cmNlOi8vc3JjL3twYXRofVwiLFxuICAgICAgYXJndW1lbnRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInBhdGhcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiUGF0aCB1bmRlciA8YmFzZV9wYXRoPi9zcmMgdG8gbG9hZCwgZS5nLiAnZGVjb3JhdGlvbi90eXBlcy50cydcIixcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBsb2FkOiBtYWtlTG9hZGVyKFwic3JjXCIpLFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogXCJyZWFkLXRlc3QtZnJvbS1zb3VyY2VcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIlJlYWQgYSBmaWxlIGZyb20gdGhlIDxiYXNlX3BhdGg+L3Rlc3RzIHRyZWUgYnkgcmVsYXRpdmUgcGF0aC5cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcImZyb20tc291cmNlOi8vdGVzdHMve3BhdGh9XCIsXG4gICAgICBhcmd1bWVudHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicGF0aFwiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgXCJQYXRoIHVuZGVyIDxiYXNlX3BhdGg+L3Rlc3RzIHRvIGxvYWQsIGUuZy4gJ2RlY29yYXRpb24vdGVzdHMvdHlwZXMudGVzdC50cydcIixcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBsb2FkOiBtYWtlTG9hZGVyKFwidGVzdHNcIiksXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiBcInJlYWQtZG9jLWZyb20tc291cmNlXCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJSZWFkIGEgZmlsZSBmcm9tIHRoZSA8YmFzZV9wYXRoPi93b3JrZG9jcyB0cmVlIGJ5IHJlbGF0aXZlIHBhdGguXCIsXG4gICAgICBtaW1lVHlwZTogXCJ0ZXh0L3BsYWluXCIsXG4gICAgICB1cmlUZW1wbGF0ZTogXCJmcm9tLXNvdXJjZTovL3dvcmtkb2NzL3twYXRofVwiLFxuICAgICAgYXJndW1lbnRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInBhdGhcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiUGF0aCB1bmRlciA8YmFzZV9wYXRoPi93b3JrZG9jcyB0byBsb2FkLCBlLmcuICdkZWNvcmF0aW9uL3dvcmtkb2NzL3R1dG9yaWFscy9mb3ItZGV2ZWxvcGVycy5tZCdcIixcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBsb2FkOiBtYWtlTG9hZGVyKFwid29ya2RvY3NcIiksXG4gICAgfSxcbiAgXTtcblxuICBkZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMuc3BsaWNlKFxuICAgIDAsXG4gICAgZGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzLmxlbmd0aCxcbiAgICAuLi50ZW1wbGF0ZXNcbiAgKTtcbiAgcmV0dXJuIGRlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcztcbn1cbiIsImltcG9ydCB7IFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGUgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGdldFdvcmtzcGFjZVJvb3QsIHJlYWRXb3Jrc3BhY2VGaWxlIH0gZnJvbSBcIi4uL3dvcmtzcGFjZVwiO1xuXG5leHBvcnQgY29uc3Qgd29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZXM6IFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVbXSA9IFtdO1xuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRXb3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlcygpOiBXb3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlW10ge1xuICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICBjb25zdCBzaGFyZWRBcmd1bWVudHMgPSBbXG4gICAge1xuICAgICAgbmFtZTogXCJwYXRoXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJQYXRoIHJlbGF0aXZlIHRvIHRoZSB3b3Jrc3BhY2Ugcm9vdFwiLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgfSxcbiAgXSBhcyBjb25zdDtcblxuICBjb25zdCB0ZW1wbGF0ZXM6IFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVbXSA9IFtcbiAgICB7XG4gICAgICBuYW1lOiBcInZzY29kZS13b3Jrc3BhY2UtZmlsZVwiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiRXhwb3NlIHdvcmtzcGFjZSBmaWxlcyB0byBWaXN1YWwgU3R1ZGlvIENvZGUgdmlhIHZzY29kZTovLyBVUklzXCIsXG4gICAgICB1cmlUZW1wbGF0ZTogXCJ2c2NvZGU6Ly93b3Jrc3BhY2Uve3BhdGh9XCIsXG4gICAgICBtaW1lVHlwZTogXCJ0ZXh0L3BsYWluXCIsXG4gICAgICBhcmd1bWVudHM6IHNoYXJlZEFyZ3VtZW50cyxcbiAgICAgIGxvYWQ6IGFzeW5jIChhcmdzOiB7IHBhdGg6IHN0cmluZyB9KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlYWRXb3Jrc3BhY2VGaWxlKHJvb3QsIGFyZ3MucGF0aCk7XG4gICAgICAgICAgcmV0dXJuIHsgdGV4dDogU3RyaW5nKHRleHQpIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIC8vIHByb3BhZ2F0ZSBhcy1pcyBmb3IgdGVzdHMgdG8gYXNzZXJ0IGVycm9yc1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6IFwiY3Vyc29yLXdvcmtzcGFjZS1maWxlXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJFeHBvc2Ugd29ya3NwYWNlIGZpbGVzIHRvIEN1cnNvciB2aWEgY3Vyc29yOi8vIFVSSXNcIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcImN1cnNvcjovL3dvcmtzcGFjZS97cGF0aH1cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIGFyZ3VtZW50czogc2hhcmVkQXJndW1lbnRzLFxuICAgICAgbG9hZDogYXN5bmMgKGFyZ3M6IHsgcGF0aDogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgYXJncy5wYXRoKTtcbiAgICAgICAgICByZXR1cm4geyB0ZXh0OiBTdHJpbmcodGV4dCkgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogXCJjb3BpbG90LXdvcmtzcGFjZS1maWxlXCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJFeHBvc2Ugd29ya3NwYWNlIGZpbGVzIHRvIEdpdEh1YiBDb3BpbG90IHZpYSBjb3BpbG90Oi8vIFVSSXNcIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcImNvcGlsb3Q6Ly93b3Jrc3BhY2Uve3BhdGh9XCIsXG4gICAgICBtaW1lVHlwZTogXCJ0ZXh0L3BsYWluXCIsXG4gICAgICBhcmd1bWVudHM6IHNoYXJlZEFyZ3VtZW50cyxcbiAgICAgIGxvYWQ6IGFzeW5jIChhcmdzOiB7IHBhdGg6IHN0cmluZyB9KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlYWRXb3Jrc3BhY2VGaWxlKHJvb3QsIGFyZ3MucGF0aCk7XG4gICAgICAgICAgcmV0dXJuIHsgdGV4dDogU3RyaW5nKHRleHQpIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9LFxuICBdO1xuXG4gIHdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzLnNwbGljZShcbiAgICAwLFxuICAgIHdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzLmxlbmd0aCxcbiAgICAuLi50ZW1wbGF0ZXNcbiAgKTtcbiAgcmV0dXJuIHdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzO1xufVxuXG4iLCJpbXBvcnQge1xuICBidWlsZENvZGV4UHJvbXB0VGVtcGxhdGVzLFxuICBjb2RleFByb21wdFRlbXBsYXRlcyxcbn0gZnJvbSBcIi4vY29kZXgtdGVtcGxhdGVzXCI7XG5pbXBvcnQge1xuICBidWlsZERlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcyxcbiAgZGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzLFxufSBmcm9tIFwiLi9yZXNvdXJjZS10ZW1wbGF0ZXNcIjtcbmltcG9ydCB7XG4gIGJ1aWxkV29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZXMsXG4gIHdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzLFxufSBmcm9tIFwiLi93b3Jrc3BhY2UtdGVtcGxhdGVzXCI7XG5pbXBvcnQgdHlwZSB7IFRlbXBsYXRlQXNzZXQgfSBmcm9tIFwiLi4vLi4vdHlwZXNcIjtcbmltcG9ydCB7IG1vZHVsZVJlZ2lzdHJ5IH0gZnJvbSBcIi4uL21vZHVsZVJlZ2lzdHJ5XCI7XG5cbmV4cG9ydCB7XG4gIGJ1aWxkQ29kZXhQcm9tcHRUZW1wbGF0ZXMsXG4gIGNvZGV4UHJvbXB0VGVtcGxhdGVzLFxufSBmcm9tIFwiLi9jb2RleC10ZW1wbGF0ZXNcIjtcbmV4cG9ydCB7XG4gIGJ1aWxkRGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzLFxuICBkZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMsXG59IGZyb20gXCIuL3Jlc291cmNlLXRlbXBsYXRlc1wiO1xuZXhwb3J0IHtcbiAgYnVpbGRXb3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlcyxcbiAgd29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZXMsXG59IGZyb20gXCIuL3dvcmtzcGFjZS10ZW1wbGF0ZXNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMoKSB7XG4gIGNvbnN0IG1vZHVsZVRlbXBsYXRlcyA9IG1vZHVsZVJlZ2lzdHJ5Lmxpc3RUZW1wbGF0ZXMoKS5tYXAoKHRlbXBsYXRlKSA9PiAoe1xuICAgIG5hbWU6IHRlbXBsYXRlLmlkLFxuICAgIGRlc2NyaXB0aW9uOiB0ZW1wbGF0ZS5kZXNjcmlwdGlvbiA/PyB0ZW1wbGF0ZS50aXRsZSxcbiAgICBtaW1lVHlwZTogXCJ0ZXh0L21hcmtkb3duXCIsXG4gICAgdXJpVGVtcGxhdGU6IGBtb2R1bGUtdGVtcGxhdGU6Ly8ke3RlbXBsYXRlLmlkfWAsXG4gICAgYXJndW1lbnRzOiAodGVtcGxhdGUucGxhY2Vob2xkZXJzID8/IFtdKS5tYXAoKG5hbWUpID0+ICh7XG4gICAgICBuYW1lLFxuICAgICAgZGVzY3JpcHRpb246IGBWYWx1ZSBmb3IgJHtuYW1lfWAsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICB9KSksXG4gICAgbG9hZDogYXN5bmMgKCkgPT4gKHtcbiAgICAgIHRleHQ6XG4gICAgICAgIHR5cGVvZiAodGVtcGxhdGUgYXMgYW55KS5jb250ZW50ID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgPyAodGVtcGxhdGUgYXMgYW55KS5jb250ZW50XG4gICAgICAgICAgOiBgIyAke3RlbXBsYXRlLmRlc2NyaXB0aW9uID8/IHRlbXBsYXRlLnRpdGxlID8/IHRlbXBsYXRlLmlkfVxcblxcbk5vIHRlbXBsYXRlIGNvbnRlbnQgYXZhaWxhYmxlIGZvciAke3RlbXBsYXRlLmlkfWAsXG4gICAgfSksXG4gIH0pKTtcblxuICBjb25zdCBhbGwgPSBbXG4gICAgLi4uYnVpbGRXb3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlcygpLFxuICAgIC4uLmJ1aWxkQ29kZXhQcm9tcHRUZW1wbGF0ZXMoKSxcbiAgICAuLi5idWlsZERlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcygpLFxuICAgIC4uLm1vZHVsZVRlbXBsYXRlcyxcbiAgXTtcblxuICAvLyBOb3JtYWxpc2UgYWxsIGxvYWRlcnMgdG8gYWx3YXlzIHJldHVybiB7IHRleHQ6IHN0cmluZyB9XG4gIGZ1bmN0aW9uIG5vcm1hbGlzZVJlc3VsdChyZXM6IGFueSkge1xuICAgIGlmIChyZXMgPT0gbnVsbCkgcmV0dXJuIHsgdGV4dDogXCJcIiB9O1xuICAgIGlmICh0eXBlb2YgcmVzID09PSBcInN0cmluZ1wiKSByZXR1cm4geyB0ZXh0OiByZXMgfTtcbiAgICBpZiAodHlwZW9mIHJlcy50ZXh0ID09PSBcInN0cmluZ1wiKSByZXR1cm4gcmVzO1xuICAgIC8vIGhhbmRsZSBsZWdhY3kgQ29udGVudFJlc3VsdCBzaGFwZXMgd2l0aCBjb250ZW50IG9yIGNvbnRlbnQgYXJyYXlcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXMuY29udGVudCkpIHtcbiAgICAgIGNvbnN0IHBhcnRzID0gcmVzLmNvbnRlbnRcbiAgICAgICAgLm1hcCgoYzogYW55KSA9PiAoYyAmJiB0eXBlb2YgYy50ZXh0ID09PSBcInN0cmluZ1wiID8gYy50ZXh0IDogU3RyaW5nKGMpKSlcbiAgICAgICAgLmpvaW4oXCJcXG5cIik7XG4gICAgICByZXR1cm4geyB0ZXh0OiBwYXJ0cyB9O1xuICAgIH1cbiAgICBpZiAocmVzLmNvbnRlbnQgJiYgdHlwZW9mIHJlcy5jb250ZW50LnRleHQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiB7IHRleHQ6IHJlcy5jb250ZW50LnRleHQgfTtcbiAgICB9XG4gICAgLy8gZmFsbGJhY2s6IHN0cmluZ2lmeVxuICAgIHRyeSB7XG4gICAgICByZXR1cm4geyB0ZXh0OiBKU09OLnN0cmluZ2lmeShyZXMpIH07XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4geyB0ZXh0OiBTdHJpbmcocmVzKSB9O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBhbGwubWFwKCh0KSA9PiAoe1xuICAgIC4uLnQsXG4gICAgbG9hZDogYXN5bmMgKGFyZ3M6IGFueSkgPT4ge1xuICAgICAgY29uc3QgcmF3ID0gYXdhaXQgKHQubG9hZCBhcyBhbnkpKGFyZ3MpO1xuICAgICAgcmV0dXJuIG5vcm1hbGlzZVJlc3VsdChyYXcpO1xuICAgIH0sXG4gIH0pKTtcbn1cblxuZXhwb3J0IGNvbnN0IHRlbXBsYXRlTGlzdCA9IGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMoKTtcbiIsImltcG9ydCB7IE1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0aW9uXCI7XG5cbi8qKlxuICogQGNvbnN0IFZFUlNJT05cbiAqIEBuYW1lIFZFUlNJT05cbiAqIEBkZXNjcmlwdGlvbiBSZXByZXNlbnRzIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIHRzLXdvcmtzcGFjZSBtb2R1bGUuXG4gKiBAc3VtbWFyeSBUaGUgYWN0dWFsIHZlcnNpb24gbnVtYmVyIGlzIHJlcGxhY2VkIGR1cmluZyB0aGUgYnVpbGQgcHJvY2Vzcy5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfTkFNRSA9IFwiIyNQQUNLQUdFX05BTUUjI1wiO1xuXG50cnkge1xuICBNZXRhZGF0YS5yZWdpc3RlckxpYnJhcnkoUEFDS0FHRV9OQU1FLCBWRVJTSU9OKTtcbn0gY2F0Y2ggKGVycm9yKSB7XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoXCJhbHJlYWR5XCIpKSB7XG4gICAgLy8gSWdub3JlIGR1cGxpY2F0ZSByZWdpc3RyYXRpb24gZHVyaW5nIHRlc3RzL2J1bmRsaW5nIGNoZWNrcy5cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuIiwiaW1wb3J0IHR5cGUgeyBGYXN0TUNQIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7IFBBQ0tBR0VfTkFNRSBhcyBQS0csIFZFUlNJT04gYXMgViB9IGZyb20gXCIuLi9tZXRhZGF0YVwiO1xuaW1wb3J0IHtcbiAgYnVpbGREb2NQcm9tcHRzLFxuICBidWlsZFByb21wdHMsXG4gIGJ1aWxkRG9jdW1lbnRhdGlvblBheWxvYWQsXG4gIGRpc2NvdmVyRG9jUHJvbXB0cyxcbiAgbG9hZFByb21wdHMsXG4gIHByb21wdExpc3QsXG4gIHJlZnJlc2hQcm9tcHRzLFxuICBzZWxlY3RQcm9tcHQsXG4gIERFRkFVTFRfUFJPTVBUX05BTUUsXG59IGZyb20gXCIuL3Byb21wdHNcIjtcbmltcG9ydCB7IHJlc291cmNlcyB9IGZyb20gXCIuL3Jlc291cmNlc1wiO1xuaW1wb3J0IHtcbiAgYnVpbGREZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMsXG4gIGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMsXG4gIGRlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcyxcbiAgdGVtcGxhdGVMaXN0LFxuICB3b3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlcyxcbn0gZnJvbSBcIi4vdGVtcGxhdGVzXCI7XG5pbXBvcnQgeyB0b29sTGlzdCwgdG9vbHMgfSBmcm9tIFwiLi90b29sc1wiO1xuaW1wb3J0IHtcbiAgX19yZXNldFdvcmtzcGFjZVJvb3QsXG4gIGdldFdvcmtzcGFjZVJvb3QsXG4gIHNldFdvcmtzcGFjZVJvb3QsXG59IGZyb20gXCIuL3dvcmtzcGFjZVwiO1xuXG5leHBvcnQgZnVuY3Rpb24gZW5yaWNoKG1jcDogRmFzdE1DUCk6IEZhc3RNQ1Age1xuICBjb25zdCBwcm9tcHRFbnRyaWVzID0gbG9hZFByb21wdHMoKTtcbiAgZm9yIChjb25zdCBwcm9tcHQgb2YgcHJvbXB0RW50cmllcykge1xuICAgIG1jcC5hZGRQcm9tcHQocHJvbXB0IGFzIGFueSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IHRvb2wgb2YgdG9vbExpc3QpIHtcbiAgICBtY3AuYWRkVG9vbCh0b29sIGFzIGFueSk7XG4gIH1cblxuICBjb25zdCB0ZW1wbGF0ZXMgPSBidWlsZFJlc291cmNlVGVtcGxhdGVzKCk7XG4gIGZvciAoY29uc3QgdGVtcGxhdGUgb2YgdGVtcGxhdGVzKSB7XG4gICAgbWNwLmFkZFJlc291cmNlVGVtcGxhdGUodGVtcGxhdGUgYXMgYW55KTtcbiAgfVxuXG4gIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgcmVzb3VyY2VzKSB7XG4gICAgY29uc3QgYWRkUmVzb3VyY2UgPSAobWNwIGFzIHVua25vd24gYXMgeyBhZGRSZXNvdXJjZT86IChyZXM6IHVua25vd24pID0+IHZvaWQgfSkuYWRkUmVzb3VyY2U7XG4gICAgaWYgKHR5cGVvZiBhZGRSZXNvdXJjZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBhZGRSZXNvdXJjZS5jYWxsKG1jcCwgcmVzb3VyY2UgYXMgYW55KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWNwO1xufVxuXG5leHBvcnQgZGVmYXVsdCBlbnJpY2g7XG5leHBvcnQgY29uc3QgUEFDS0FHRV9OQU1FID0gUEtHO1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBWO1xuXG5leHBvcnQge1xuICB0b29scyxcbiAgdG9vbExpc3QsXG4gIGJ1aWxkRG9jUHJvbXB0cyxcbiAgYnVpbGRQcm9tcHRzLFxuICBidWlsZERlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcyxcbiAgYnVpbGRSZXNvdXJjZVRlbXBsYXRlcyxcbiAgYnVpbGREb2N1bWVudGF0aW9uUGF5bG9hZCxcbiAgZGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzLFxuICBkaXNjb3ZlckRvY1Byb21wdHMsXG4gIERFRkFVTFRfUFJPTVBUX05BTUUsXG4gIHByb21wdExpc3QsXG4gIHJlZnJlc2hQcm9tcHRzLFxuICByZXNvdXJjZXMsXG4gIHNlbGVjdFByb21wdCxcbiAgdGVtcGxhdGVMaXN0LFxuICB3b3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlcyxcbiAgZ2V0V29ya3NwYWNlUm9vdCxcbiAgc2V0V29ya3NwYWNlUm9vdCxcbiAgX19yZXNldFdvcmtzcGFjZVJvb3QsXG59O1xuIiwiLy8gTmV3OiB2YWxpZGF0aW9uIGVudHJ5cG9pbnQgZm9yIG1vZHVsZSBzdHJ1Y3R1cmVcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25Jc3N1ZSA9IHtcbiAgbW9kdWxlOiBzdHJpbmc7XG4gIHBhdGg6IHN0cmluZztcbiAgdHlwZTpcbiAgICB8IFwibWlzc2luZy1mb2xkZXJcIlxuICAgIHwgXCJtaXNzaW5nLWV4cG9ydFwiXG4gICAgfCBcImVtcHR5LWxpc3RcIlxuICAgIHwgXCJkaXNhYmxlZFwiXG4gICAgfCBcIm90aGVyXCI7XG4gIGRldGFpbD86IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25SZXBvcnQgPSB7XG4gIG9rOiBib29sZWFuO1xuICBtb2R1bGVzQ2hlY2tlZDogbnVtYmVyO1xuICBpc3N1ZXM6IFZhbGlkYXRpb25Jc3N1ZVtdO1xufTtcblxuY29uc3QgUkVRVUlSRURfU1VCRk9MREVSUyA9IFtcInByb21wdHNcIiwgXCJyZXNvdXJjZXNcIiwgXCJ0ZW1wbGF0ZXNcIiwgXCJ0b29sc1wiXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRNb2R1bGVEaXJzKHJlcG9Sb290OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IG1vZHVsZXNQYXRoID0gcGF0aC5yZXNvbHZlKHJlcG9Sb290LCBcInNyY1wiLCBcIm1vZHVsZXNcIik7XG4gIGlmICghZnMuZXhpc3RzU3luYyhtb2R1bGVzUGF0aCkgfHwgIWZzLnN0YXRTeW5jKG1vZHVsZXNQYXRoKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIHJldHVybiBmc1xuICAgIC5yZWFkZGlyU3luYyhtb2R1bGVzUGF0aCwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pXG4gICAgLmZpbHRlcigoZCkgPT4gZC5pc0RpcmVjdG9yeSgpKVxuICAgIC5tYXAoKGQpID0+IHBhdGguam9pbihtb2R1bGVzUGF0aCwgZC5uYW1lKSk7XG59XG5cbmZ1bmN0aW9uIGhhc0luZGV4RXhwb3J0KGZvbGRlclBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBjYW5kaWRhdGVzID0gW1xuICAgIFwiaW5kZXgudHNcIixcbiAgICBcImluZGV4LnRzeFwiLFxuICAgIFwiaW5kZXguanNcIixcbiAgICBcImluZGV4LmNqc1wiLFxuICAgIFwiaW5kZXgubWpzXCIsXG4gIF07XG4gIGZvciAoY29uc3QgYyBvZiBjYW5kaWRhdGVzKSB7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMocGF0aC5qb2luKGZvbGRlclBhdGgsIGMpKSkgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVNb2R1bGVzKHJlcG9Sb290OiBzdHJpbmcpOiBWYWxpZGF0aW9uUmVwb3J0IHtcbiAgY29uc3QgZGlycyA9IGZpbmRNb2R1bGVEaXJzKHJlcG9Sb290KTtcbiAgY29uc3QgaXNzdWVzOiBWYWxpZGF0aW9uSXNzdWVbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgbW9kdWxlRGlyIG9mIGRpcnMpIHtcbiAgICBjb25zdCBtb2R1bGVOYW1lID0gcGF0aC5iYXNlbmFtZShtb2R1bGVEaXIpO1xuICAgIGZvciAoY29uc3Qgc3ViIG9mIFJFUVVJUkVEX1NVQkZPTERFUlMpIHtcbiAgICAgIGNvbnN0IHN1YlBhdGggPSBwYXRoLmpvaW4obW9kdWxlRGlyLCBzdWIpO1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHN1YlBhdGgpIHx8ICFmcy5zdGF0U3luYyhzdWJQYXRoKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICBtb2R1bGU6IG1vZHVsZU5hbWUsXG4gICAgICAgICAgcGF0aDogc3ViUGF0aCxcbiAgICAgICAgICB0eXBlOiBcIm1pc3NpbmctZm9sZGVyXCIsXG4gICAgICAgICAgZGV0YWlsOiBgUmVxdWlyZWQgZm9sZGVyICcke3N1Yn0nIGlzIG1pc3NpbmcgaW4gbW9kdWxlICcke21vZHVsZU5hbWV9J2AsXG4gICAgICAgIH0pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIC8vIElmIGZvbGRlciBleGlzdHMsIGNoZWNrIGZvciBpbmRleCBleHBvcnRcbiAgICAgIGlmICghaGFzSW5kZXhFeHBvcnQoc3ViUGF0aCkpIHtcbiAgICAgICAgaXNzdWVzLnB1c2goe1xuICAgICAgICAgIG1vZHVsZTogbW9kdWxlTmFtZSxcbiAgICAgICAgICBwYXRoOiBzdWJQYXRoLFxuICAgICAgICAgIHR5cGU6IFwibWlzc2luZy1leHBvcnRcIixcbiAgICAgICAgICBkZXRhaWw6IGBObyBpbmRleCBleHBvcnQgZm91bmQgaW4gJyR7c3ViUGF0aH0nLiBFeHBlY3RlZCBvbmUgb2YgaW5kZXgudHMsIGluZGV4LmpzLCBldGMuYCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgLy8gT3B0aW9uYWxseSBpbnNwZWN0IHRoZSBpbmRleCBmaWxlIHRvIHNlZSBpZiBpdCBleHBvcnRzIGEgbGlzdCAobGlnaHR3ZWlnaHQgY2hlY2spXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBpbmRleEZpbGUgPSBjYW5kaWRhdGVzRmluZGluZ0luZGV4KHN1YlBhdGgpO1xuICAgICAgICBpZiAoaW5kZXhGaWxlKSB7XG4gICAgICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhpbmRleEZpbGUsIFwidXRmOFwiKTtcbiAgICAgICAgICAvLyBjcnVkZSBoZXVyaXN0aWNzOiBsb29rIGZvciBgZXhwb3J0IGNvbnN0IG5hbWUgPSBbYCBvciBgZXhwb3J0IGNvbnN0IG5hbWU6IFR5cGVbXSA9IFtgLFxuICAgICAgICAgIC8vIG9yIGFueSBuYW1lZCBleHBvcnQgbGlrZSBgZXhwb3J0IHsgc29tZXRoaW5nIH1gIHdoaWNoIGltcGxpZXMgZXhwb3J0cyBleGlzdC5cbiAgICAgICAgICBjb25zdCBleHBvcnRMaXN0UGF0dGVybiA9XG4gICAgICAgICAgICAvZXhwb3J0XFxzKyhjb25zdHxsZXR8dmFyKVxccytbXFx3JF0rKD86XFxzKjpcXHMqW149XSspP1xccyo9XFxzKlxcWy87XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIWV4cG9ydExpc3RQYXR0ZXJuLnRlc3QoY29udGVudCkgJiZcbiAgICAgICAgICAgICEvZXhwb3J0XFxzK1xcey8udGVzdChjb250ZW50KVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgaXNzdWVzLnB1c2goe1xuICAgICAgICAgICAgICBtb2R1bGU6IG1vZHVsZU5hbWUsXG4gICAgICAgICAgICAgIHBhdGg6IGluZGV4RmlsZSxcbiAgICAgICAgICAgICAgdHlwZTogXCJlbXB0eS1saXN0XCIsXG4gICAgICAgICAgICAgIGRldGFpbDogYEluZGV4IGZpbGUgZG9lcyBub3QgYXBwZWFyIHRvIGV4cG9ydCBhIGxpc3Qgb2YgYXNzZXRzOiAke3BhdGguYmFzZW5hbWUoaW5kZXhGaWxlKX1gLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICBpc3N1ZXMucHVzaCh7XG4gICAgICAgICAgbW9kdWxlOiBtb2R1bGVOYW1lLFxuICAgICAgICAgIHBhdGg6IHN1YlBhdGgsXG4gICAgICAgICAgdHlwZTogXCJvdGhlclwiLFxuICAgICAgICAgIGRldGFpbDogYEVycm9yIHJlYWRpbmcgaW5kZXggZmlsZTogJHtlcnIubWVzc2FnZX1gLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG9rOiBpc3N1ZXMubGVuZ3RoID09PSAwLFxuICAgIG1vZHVsZXNDaGVja2VkOiBkaXJzLmxlbmd0aCxcbiAgICBpc3N1ZXMsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNhbmRpZGF0ZXNGaW5kaW5nSW5kZXgoZm9sZGVyUGF0aDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgY2FuZGlkYXRlcyA9IFtcbiAgICBcImluZGV4LnRzXCIsXG4gICAgXCJpbmRleC50c3hcIixcbiAgICBcImluZGV4LmpzXCIsXG4gICAgXCJpbmRleC5janNcIixcbiAgICBcImluZGV4Lm1qc1wiLFxuICBdO1xuICBmb3IgKGNvbnN0IGMgb2YgY2FuZGlkYXRlcykge1xuICAgIGNvbnN0IGZ1bGwgPSBwYXRoLmpvaW4oZm9sZGVyUGF0aCwgYyk7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMoZnVsbCkpIHJldHVybiBmdWxsO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8vIENMSSBoZWxwZXJcbmlmIChyZXF1aXJlLm1haW4gPT09IG1vZHVsZSkge1xuICBjb25zdCByZXBvUm9vdCA9IHByb2Nlc3MuY3dkKCk7XG4gIGNvbnN0IHJlcG9ydCA9IHZhbGlkYXRlTW9kdWxlcyhyZXBvUm9vdCk7XG4gIGlmICghcmVwb3J0Lm9rKSB7XG4gICAgY29uc29sZS5lcnJvcihcbiAgICAgIFwiTW9kdWxlIHZhbGlkYXRpb24gZmFpbGVkOlxcblwiLFxuICAgICAgSlNPTi5zdHJpbmdpZnkocmVwb3J0LCBudWxsLCAyKVxuICAgICk7XG4gICAgcHJvY2Vzcy5leGl0KDIpO1xuICB9XG4gIGNvbnNvbGUubG9nKFwiTW9kdWxlIHZhbGlkYXRpb24gcGFzc2VkXCIpO1xuICBwcm9jZXNzLmV4aXQoMCk7XG59XG4iLCIvLyBBZ2dyZWdhdG9yOiBpbXBvcnQgbW9kdWxlIGluZGV4IGZpbGVzIGFuZCBtZXJnZSBleHBvcnRlZCBhcnJheXMgd2l0aCBwcm92ZW5hbmNlICsgZHVwbGljYXRlIGRldGVjdGlvblxuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IHBhdGhUb0ZpbGVVUkwgfSBmcm9tIFwidXJsXCI7XG5pbXBvcnQgeyBmaW5kTW9kdWxlRGlycyB9IGZyb20gXCIuL3ZhbGlkYXRpb25cIjtcblxuZXhwb3J0IHR5cGUgUHJvdmVuYW5jZSA9IHsgbW9kdWxlTmFtZTogc3RyaW5nOyBtb2R1bGVQYXRoOiBzdHJpbmcgfTtcbmV4cG9ydCB0eXBlIEFnZ3JlZ2F0aW9uQ29uZmxpY3QgPSB7XG4gIGtleTogc3RyaW5nO1xuICBleGlzdGluZzogUHJvdmVuYW5jZTtcbiAgaW5jb21pbmc6IFByb3ZlbmFuY2U7XG59O1xuXG5leHBvcnQgdHlwZSBBZ2dyZWdhdGlvblJlc3VsdDxUID0gYW55PiA9IHtcbiAgcHJvbXB0czogQXJyYXk8VCAmIHsgcHJvdmVuYW5jZTogUHJvdmVuYW5jZSB9PjtcbiAgcmVzb3VyY2VzOiBBcnJheTxUICYgeyBwcm92ZW5hbmNlOiBQcm92ZW5hbmNlIH0+O1xuICB0ZW1wbGF0ZXM6IEFycmF5PFQgJiB7IHByb3ZlbmFuY2U6IFByb3ZlbmFuY2UgfT47XG4gIHRvb2xzOiBBcnJheTxUICYgeyBwcm92ZW5hbmNlOiBQcm92ZW5hbmNlIH0+O1xuICBjb25mbGljdHM6IEFnZ3JlZ2F0aW9uQ29uZmxpY3RbXTtcbn07XG5cbmNvbnN0IFNVQkZPTERFUlMgPSBbXCJwcm9tcHRzXCIsIFwicmVzb3VyY2VzXCIsIFwidGVtcGxhdGVzXCIsIFwidG9vbHNcIl07XG5jb25zdCBJTkRFWF9DQU5ESURBVEVTID0gW1xuICBcImluZGV4LnRzXCIsXG4gIFwiaW5kZXgudHN4XCIsXG4gIFwiaW5kZXguanNcIixcbiAgXCJpbmRleC5janNcIixcbiAgXCJpbmRleC5tanNcIixcbl07XG5cbmZ1bmN0aW9uIGZpbmRJbmRleEZpbGUoZm9sZGVyOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBmb3IgKGNvbnN0IGMgb2YgSU5ERVhfQ0FORElEQVRFUykge1xuICAgIGNvbnN0IGYgPSBwYXRoLmpvaW4oZm9sZGVyLCBjKTtcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhmKSkgcmV0dXJuIGY7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gbWFrZUtleUZvckl0ZW0oaXRlbTogYW55KTogc3RyaW5nIHtcbiAgaWYgKCFpdGVtKSByZXR1cm4gSlNPTi5zdHJpbmdpZnkoaXRlbSk7XG4gIGlmICh0eXBlb2YgaXRlbSA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIGBzdHI6JHtpdGVtfWA7XG4gIGlmICh0eXBlb2YgaXRlbSA9PT0gXCJudW1iZXJcIikgcmV0dXJuIGBudW06JHtpdGVtfWA7XG4gIGlmIChpdGVtLmlkKSByZXR1cm4gYGlkOiR7aXRlbS5pZH1gO1xuICBpZiAoaXRlbS5uYW1lKSByZXR1cm4gYG5hbWU6JHtpdGVtLm5hbWV9YDtcbiAgLy8gZmFsbGJhY2sgdG8gc3RhYmxlIHN0cmluZ1xuICB0cnkge1xuICAgIHJldHVybiBgb2JqOiR7SlNPTi5zdHJpbmdpZnkoaXRlbSl9YDtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBgb2JqOiR7U3RyaW5nKGl0ZW0pfWA7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gbG9hZEFycmF5RnJvbUluZGV4KFxuICBmaWxlUGF0aDogc3RyaW5nXG4pOiBQcm9taXNlPGFueVtdIHwgdW5kZWZpbmVkPiB7XG4gIC8vIFByZWZlciBhIGZhc3QsIHN0YXRpYyBwYXJzZSBvZiB0aGUgZmlyc3QgYXJyYXkgbGl0ZXJhbCBmb3VuZCBpbiB0aGUgZmlsZS5cbiAgdHJ5IHtcbiAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCBcInV0ZjhcIik7XG4gICAgY29uc3Qgc3RhcnQgPSBjb250ZW50LmluZGV4T2YoXCJbXCIpO1xuICAgIGlmIChzdGFydCAhPT0gLTEpIHtcbiAgICAgIGxldCBkZXB0aCA9IDA7XG4gICAgICBsZXQgZW5kID0gLTE7XG4gICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBjb250ZW50Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGNoID0gY29udGVudFtpXTtcbiAgICAgICAgaWYgKGNoID09PSBcIltcIikgZGVwdGgrKztcbiAgICAgICAgZWxzZSBpZiAoY2ggPT09IFwiXVwiKSB7XG4gICAgICAgICAgZGVwdGgtLTtcbiAgICAgICAgICBpZiAoZGVwdGggPT09IDApIHtcbiAgICAgICAgICAgIGVuZCA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChlbmQgIT09IC0xKSB7XG4gICAgICAgIGNvbnN0IGFyclRleHQgPSBjb250ZW50LnNsaWNlKHN0YXJ0LCBlbmQgKyAxKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShhcnJUZXh0KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIC8vIE5vcm1hbGl6ZSBUUyBvYmplY3QgbGl0ZXJhbHMgdG8gSlNPTjpcbiAgICAgICAgICAvLyAtIGNvbnZlcnQgc2luZ2xlIHF1b3RlcyB0byBkb3VibGUgcXVvdGVzXG4gICAgICAgICAgLy8gLSBxdW90ZSB1bnF1b3RlZCBvYmplY3Qga2V5c1xuICAgICAgICAgIC8vIC0gc3RyaXAgdHJhaWxpbmcgY29tbWFzXG4gICAgICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IGFyclRleHRcbiAgICAgICAgICAgIC8vIHVuaWZ5IHF1b3RlcyBpbiBzdHJpbmcgbGl0ZXJhbHNcbiAgICAgICAgICAgIC5yZXBsYWNlKC8nKD86XFxcXCd8W14nXSkqJy9nLCAobSkgPT4gbS5yZXBsYWNlKC8nL2csICdcIicpKVxuICAgICAgICAgICAgLy8gcXVvdGUgdW5xdW90ZWQga2V5cyBhZnRlciB7IG9yICxcbiAgICAgICAgICAgIC5yZXBsYWNlKC8oW1xceyxdXFxzKikoW0EtWmEtel8kXVtcXHckXSopKFxccyo6KS9nLCAnJDFcIiQyXCIkMycpXG4gICAgICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgY29tbWFzIGJlZm9yZSBdIG9yIH1cbiAgICAgICAgICAgIC5yZXBsYWNlKC8sKFxccypbXFx9XFxdXSkvZywgJyQxJyk7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKG5vcm1hbGl6ZWQpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUyKSB7XG4gICAgICAgICAgICAvLyBmYWxsdGhyb3VnaCB0byBpbXBvcnQgYXR0ZW1wdCBiZWxvd1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIGlnbm9yZSBzdGF0aWMgcGFyc2UgZXJyb3JzIGFuZCBmYWxsIGJhY2sgdG8gaW1wb3J0XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IGZpbGVVcmwgPSBwYXRoVG9GaWxlVVJMKGZpbGVQYXRoKS5ocmVmO1xuICAgIGNvbnN0IG1vZCA9IGF3YWl0IGltcG9ydChmaWxlVXJsKTtcbiAgICAvLyBGaW5kIGZpcnN0IGV4cG9ydCB0aGF0IGlzIGFuIGFycmF5XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMobW9kKSkge1xuICAgICAgY29uc3QgdmFsID0gKG1vZCBhcyBhbnkpW2tleV07XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSByZXR1cm4gdmFsO1xuICAgIH1cbiAgICAvLyBkZWZhdWx0IGV4cG9ydCBjaGVja1xuICAgIGlmIChBcnJheS5pc0FycmF5KChtb2QgYXMgYW55KS5kZWZhdWx0KSkgcmV0dXJuIChtb2QgYXMgYW55KS5kZWZhdWx0O1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIC8vIGZhbGxiYWNrOiBpZiBpbXBvcnQgZmFpbHMsIHRyeSB0byBzdGF0aWMtcGFyc2UgYWdhaW4gKGFscmVhZHkgYXR0ZW1wdGVkKSBhbmQgZmluYWxseSByZXR1cm4gdW5kZWZpbmVkXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWdncmVnYXRlTW9kdWxlcyhcbiAgcmVwb1Jvb3Q6IHN0cmluZ1xuKTogUHJvbWlzZTxBZ2dyZWdhdGlvblJlc3VsdD4ge1xuICBjb25zdCBkaXJzID0gZmluZE1vZHVsZURpcnMocmVwb1Jvb3QpO1xuICBjb25zdCBtYXN0ZXIgPSB7XG4gICAgcHJvbXB0czogW10gYXMgYW55W10sXG4gICAgcmVzb3VyY2VzOiBbXSBhcyBhbnlbXSxcbiAgICB0ZW1wbGF0ZXM6IFtdIGFzIGFueVtdLFxuICAgIHRvb2xzOiBbXSBhcyBhbnlbXSxcbiAgICBjb25mbGljdHM6IFtdIGFzIEFnZ3JlZ2F0aW9uQ29uZmxpY3RbXSxcbiAgfTtcblxuICAvLyBtYXBzIHRvIGRldGVjdCBkdXBsaWNhdGVzIHBlciB0eXBlXG4gIGNvbnN0IG1hcHM6IFJlY29yZDxzdHJpbmcsIE1hcDxzdHJpbmcsIFByb3ZlbmFuY2U+PiA9IHtcbiAgICBwcm9tcHRzOiBuZXcgTWFwKCksXG4gICAgcmVzb3VyY2VzOiBuZXcgTWFwKCksXG4gICAgdGVtcGxhdGVzOiBuZXcgTWFwKCksXG4gICAgdG9vbHM6IG5ldyBNYXAoKSxcbiAgfTtcblxuICBmb3IgKGNvbnN0IG1vZHVsZURpciBvZiBkaXJzKSB7XG4gICAgY29uc3QgbW9kdWxlTmFtZSA9IHBhdGguYmFzZW5hbWUobW9kdWxlRGlyKTtcbiAgICBmb3IgKGNvbnN0IHN1YiBvZiBTVUJGT0xERVJTKSB7XG4gICAgICBjb25zdCBmb2xkZXIgPSBwYXRoLmpvaW4obW9kdWxlRGlyLCBzdWIpO1xuICAgICAgY29uc3QgaW5kZXhGaWxlID0gZmluZEluZGV4RmlsZShmb2xkZXIpO1xuICAgICAgaWYgKCFpbmRleEZpbGUpIGNvbnRpbnVlO1xuICAgICAgbGV0IGFycjogYW55W10gfCB1bmRlZmluZWQ7XG4gICAgICB0cnkge1xuICAgICAgICBhcnIgPSBhd2FpdCBsb2FkQXJyYXlGcm9tSW5kZXgoaW5kZXhGaWxlKTtcbiAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgIC8vIHNraXAgbW9kdWxlIG9uIGltcG9ydCBlcnJvciBidXQgcmVjb3JkIGFzIGNvbmZsaWN0LWxpa2UgaXNzdWVcbiAgICAgICAgbWFzdGVyLmNvbmZsaWN0cy5wdXNoKHtcbiAgICAgICAgICBrZXk6IGBpbXBvcnQtZXJyb3I6JHttb2R1bGVOYW1lfToke3N1Yn1gLFxuICAgICAgICAgIGV4aXN0aW5nOiB7IG1vZHVsZU5hbWUsIG1vZHVsZVBhdGg6IG1vZHVsZURpciB9LFxuICAgICAgICAgIGluY29taW5nOiB7IG1vZHVsZU5hbWUsIG1vZHVsZVBhdGg6IG1vZHVsZURpciB9LFxuICAgICAgICB9KTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoIWFyciB8fCAhQXJyYXkuaXNBcnJheShhcnIpKSBjb250aW51ZTtcblxuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGFycikge1xuICAgICAgICBjb25zdCBrZXkgPSBtYWtlS2V5Rm9ySXRlbShpdGVtKTtcbiAgICAgICAgY29uc3QgcHJvdmVuYW5jZSA9IHsgbW9kdWxlTmFtZSwgbW9kdWxlUGF0aDogbW9kdWxlRGlyIH07XG4gICAgICAgIGNvbnN0IG1hcCA9IG1hcHNbc3ViXTtcbiAgICAgICAgaWYgKG1hcC5oYXMoa2V5KSkge1xuICAgICAgICAgIC8vIHJlY29yZCBjb25mbGljdCBkZXRlcm1pbmlzdGljYWxseSAoZXhpc3RpbmcgdnMgaW5jb21pbmcpXG4gICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBtYXAuZ2V0KGtleSkhO1xuICAgICAgICAgIG1hc3Rlci5jb25mbGljdHMucHVzaCh7IGtleSwgZXhpc3RpbmcsIGluY29taW5nOiBwcm92ZW5hbmNlIH0pO1xuICAgICAgICAgIC8vIHNraXAgYWRkaW5nIGR1cGxpY2F0ZVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIG1hcC5zZXQoa2V5LCBwcm92ZW5hbmNlKTtcbiAgICAgICAgKG1hc3RlciBhcyBhbnkpW3N1Yl0ucHVzaCh7IC4uLml0ZW0sIHByb3ZlbmFuY2UgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1hc3Rlcjtcbn1cblxuLy8gRm9yIGNvbXBhdGliaWxpdHkgd2l0aCBDb21tb25KUyBjYWxsIHNpdGVzIChub3QgZXhwb3J0ZWQgYnkgRVNNKSwgcHJvdmlkZSBhIHN5bmMgd3JhcHBlclxuZXhwb3J0IGZ1bmN0aW9uIGFnZ3JlZ2F0ZU1vZHVsZXNTeW5jKHJlcG9Sb290OiBzdHJpbmcpIHtcbiAgLy8gc3luY2hyb25vdXMgd3JhcHBlciB0aGF0IHJ1bnMgdGhlIGFzeW5jIGZ1bmN0aW9uIGFuZCBibG9ja3Mg4oCUIHN1aXRhYmxlIGZvciBzbWFsbCBtb2R1bGUgc2V0c1xuICBjb25zdCBwID0gYWdncmVnYXRlTW9kdWxlcyhyZXBvUm9vdCk7XG4gIGxldCByZXN1bHQ6IGFueTtcbiAgbGV0IGRvbmUgPSBmYWxzZTtcbiAgcC50aGVuKChyKSA9PiB7XG4gICAgcmVzdWx0ID0gcjtcbiAgICBkb25lID0gdHJ1ZTtcbiAgfSkuY2F0Y2goKGUpID0+IHtcbiAgICB0aHJvdyBlO1xuICB9KTtcbiAgLy8gc3Bpbi13YWl0IChhY2NlcHRhYmxlIGluIHNtYWxsIGRldiBzY3JpcHRzKVxuICBjb25zdCB1bnRpbCA9IERhdGUubm93KCkgKyA1MDAwO1xuICB3aGlsZSAoIWRvbmUgJiYgRGF0ZS5ub3coKSA8IHVudGlsKSB7fVxuICBpZiAoIWRvbmUpXG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJhZ2dyZWdhdGVNb2R1bGVzU3luYzogdGltZW91dCB3YWl0aW5nIGZvciBhc3luYyBhZ2dyZWdhdGlvblwiXG4gICAgKTtcbiAgcmV0dXJuIHJlc3VsdCBhcyBBZ2dyZWdhdGlvblJlc3VsdDtcbn1cbiIsImltcG9ydCB7IGFnZ3JlZ2F0ZU1vZHVsZXMgfSBmcm9tIFwiLi9hZ2dyZWdhdGVNb2R1bGVzXCI7XG5pbXBvcnQgeyBsb2FkUHJvbXB0cywgcHJvbXB0TGlzdCB9IGZyb20gXCIuL3Byb21wdHNcIjtcbmltcG9ydCB7IHRvb2xMaXN0IH0gZnJvbSBcIi4vdG9vbHNcIjtcbmltcG9ydCB7IHJlc291cmNlcyB9IGZyb20gXCIuL3Jlc291cmNlc1wiO1xuaW1wb3J0IHsgYnVpbGRSZXNvdXJjZVRlbXBsYXRlcyB9IGZyb20gXCIuL3RlbXBsYXRlc1wiO1xuXG5leHBvcnQgdHlwZSBGYXN0TUNQTGlrZSA9IHtcbiAgYWRkUHJvbXB0OiAocDogYW55KSA9PiB2b2lkO1xuICBhZGRUb29sOiAodDogYW55KSA9PiB2b2lkO1xuICBhZGRSZXNvdXJjZTogKHI6IGFueSkgPT4gdm9pZDtcbiAgYWRkUmVzb3VyY2VUZW1wbGF0ZTogKHQ6IGFueSkgPT4gdm9pZDtcbn07XG5cbi8qKlxuICogQWdncmVnYXRlIG1vZHVsZSBhc3NldHMgYW5kIHJlZ2lzdGVyIHRoZW0gb24gdGhlIHByb3ZpZGVkIEZhc3RNQ1AtbGlrZSBzZXJ2ZXIuXG4gKiBGYWxscyBiYWNrIHRvIGJ1aWx0LWluIGxpc3RzIGlmIGFnZ3JlZ2F0aW9uIHlpZWxkcyBub25lLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gRW5yaWNoQ29yZVdpdGhBZ2dyZWdhdGlvbihcbiAgc2VydmVyOiBGYXN0TUNQTGlrZSxcbiAgcmVwb1Jvb3QgPSBwcm9jZXNzLmN3ZCgpXG4pIHtcbiAgLy8gRmlyc3QgcmVnaXN0ZXIgYnVpbHQtaW4gcHJvbXB0cy90b29scy9yZXNvdXJjZXMvdGVtcGxhdGVzIChsZWdhY3kgYmVoYXZpb3IpXG4gIHRyeSB7XG4gICAgbG9hZFByb21wdHMoKTtcbiAgICBmb3IgKGNvbnN0IHByb21wdCBvZiBwcm9tcHRMaXN0KSBzZXJ2ZXIuYWRkUHJvbXB0KHByb21wdCBhcyBhbnkpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gaWdub3JlIGlmIGxvYWRQcm9tcHRzIG5vdCBhdmFpbGFibGUgb3IgZmFpbHNcbiAgfVxuXG4gIHRyeSB7XG4gICAgZm9yIChjb25zdCB0b29sIG9mIHRvb2xMaXN0KSBzZXJ2ZXIuYWRkVG9vbCh0b29sIGFzIGFueSk7XG4gIH0gY2F0Y2ggKGUpIHt9XG5cbiAgdHJ5IHtcbiAgICBmb3IgKGNvbnN0IHJlc291cmNlIG9mIHJlc291cmNlcykgc2VydmVyLmFkZFJlc291cmNlKHJlc291cmNlIGFzIGFueSk7XG4gIH0gY2F0Y2ggKGUpIHt9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB0ZW1wbGF0ZXMgPSBidWlsZFJlc291cmNlVGVtcGxhdGVzKCk7XG4gICAgZm9yIChjb25zdCB0ZW1wbGF0ZSBvZiB0ZW1wbGF0ZXMpXG4gICAgICBzZXJ2ZXIuYWRkUmVzb3VyY2VUZW1wbGF0ZSh0ZW1wbGF0ZSBhcyBhbnkpO1xuICB9IGNhdGNoIChlKSB7fVxuXG4gIC8vIE5vdyBhZ2dyZWdhdGUgbW9kdWxlcyBhbmQgcmVnaXN0ZXIgYWdncmVnYXRlZCBhc3NldHMgd2l0aCBwcm92ZW5hbmNlXG4gIGNvbnN0IGFnZyA9IGF3YWl0IGFnZ3JlZ2F0ZU1vZHVsZXMocmVwb1Jvb3QpO1xuXG4gIGZvciAoY29uc3QgcCBvZiBhZ2cucHJvbXB0cykge1xuICAgIHNlcnZlci5hZGRQcm9tcHQocCk7XG4gIH1cbiAgZm9yIChjb25zdCB0IG9mIGFnZy50b29scykge1xuICAgIHNlcnZlci5hZGRUb29sKHQpO1xuICB9XG4gIGZvciAoY29uc3QgciBvZiBhZ2cucmVzb3VyY2VzKSB7XG4gICAgc2VydmVyLmFkZFJlc291cmNlKHIpO1xuICB9XG4gIGZvciAoY29uc3QgdHBsIG9mIGFnZy50ZW1wbGF0ZXMpIHtcbiAgICBzZXJ2ZXIuYWRkUmVzb3VyY2VUZW1wbGF0ZSh0cGwpO1xuICB9XG5cbiAgLy8gcmV0dXJuIGFnZ3JlZ2F0aW9uIHN1bW1hcnkgZm9yIGNhbGxpbmcgdGVzdHMvQ0lcbiAgcmV0dXJuIHtcbiAgICBtb2R1bGVzQ2hlY2tlZDogYWdnLnByb21wdHMuY29uY2F0KGFnZy50b29scykubGVuZ3RoLFxuICAgIGNvbmZsaWN0czogYWdnLmNvbmZsaWN0cyxcbiAgfTtcbn1cbiIsImltcG9ydCB7IEZhc3RNQ1AgfSBmcm9tIFwiZmFzdG1jcFwiO1xuaW1wb3J0IHsgbG9hZFByb21wdHMsIHByb21wdExpc3QgfSBmcm9tIFwiLi9wcm9tcHRzXCI7XG5pbXBvcnQgeyB0b29sTGlzdCB9IGZyb20gXCIuL3Rvb2xzXCI7XG5pbXBvcnQgeyByZXNvdXJjZXMgfSBmcm9tIFwiLi9yZXNvdXJjZXNcIjtcbmltcG9ydCB7IGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMgfSBmcm9tIFwiLi90ZW1wbGF0ZXNcIjtcblxuZXhwb3J0ICogZnJvbSBcIi4vbWNwLW1vZHVsZVwiO1xuZXhwb3J0IHsgZGVmYXVsdCB9IGZyb20gXCIuL21jcC1tb2R1bGVcIjtcblxuZXhwb3J0IHsgdmFsaWRhdGVNb2R1bGVzIH0gZnJvbSBcIi4vdmFsaWRhdGlvblwiO1xuZXhwb3J0IHsgYWdncmVnYXRlTW9kdWxlcywgYWdncmVnYXRlTW9kdWxlc1N5bmMgfSBmcm9tIFwiLi9hZ2dyZWdhdGVNb2R1bGVzXCI7XG5leHBvcnQgeyBFbnJpY2hDb3JlV2l0aEFnZ3JlZ2F0aW9uIH0gZnJvbSBcIi4vZmFzdG1jcC13aXJpbmdcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIEVucmljaENvcmUoc2VydmVyOiBGYXN0TUNQKSB7XG4gIGxvYWRQcm9tcHRzKCk7XG4gIGZvciAoY29uc3QgcHJvbXB0IG9mIHByb21wdExpc3QpIHtcbiAgICBzZXJ2ZXIuYWRkUHJvbXB0KHByb21wdCBhcyBhbnkpO1xuICB9XG4gIGZvciAoY29uc3QgdG9vbCBvZiB0b29sTGlzdCkge1xuICAgIHNlcnZlci5hZGRUb29sKHRvb2wgYXMgYW55KTtcbiAgfVxuICBmb3IgKGNvbnN0IHJlc291cmNlIG9mIHJlc291cmNlcykge1xuICAgIHNlcnZlci5hZGRSZXNvdXJjZShyZXNvdXJjZSBhcyBhbnkpO1xuICB9XG4gIGNvbnN0IHRlbXBsYXRlcyA9IGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMoKTtcbiAgZm9yIChjb25zdCB0ZW1wbGF0ZSBvZiB0ZW1wbGF0ZXMpIHtcbiAgICBzZXJ2ZXIuYWRkUmVzb3VyY2VUZW1wbGF0ZSh0ZW1wbGF0ZSBhcyBhbnkpO1xuICB9XG59XG4iLCJpbXBvcnQgZnMgZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IGdldFdvcmtzcGFjZVJvb3QgfSBmcm9tIFwiLi4vbWNwL3dvcmtzcGFjZVwiO1xuXG5leHBvcnQgY29uc3QgUkVRVUlSRURfTU9EVUxFX0ZPTERFUlMgPSBbXG4gIFwicHJvbXB0c1wiLFxuICBcInJlc291cmNlc1wiLFxuICBcInRlbXBsYXRlc1wiLFxuICBcInRvb2xzXCIsXG5dIGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBNb2R1bGVGb2xkZXIgPSAodHlwZW9mIFJFUVVJUkVEX01PRFVMRV9GT0xERVJTKVtudW1iZXJdO1xuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZU1vZHVsZXNSb290KHdvcmtzcGFjZVJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCkpOiBzdHJpbmcge1xuICByZXR1cm4gcGF0aC5yZXNvbHZlKHdvcmtzcGFjZVJvb3QsIFwic3JjL21vZHVsZXNcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsaXN0TW9kdWxlRGlyZWN0b3JpZXMod29ya3NwYWNlUm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKSk6IHN0cmluZ1tdIHtcbiAgY29uc3Qgcm9vdCA9IHJlc29sdmVNb2R1bGVzUm9vdCh3b3Jrc3BhY2VSb290KTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKHJvb3QpKSByZXR1cm4gW107XG5cbiAgcmV0dXJuIGZzXG4gICAgLnJlYWRkaXJTeW5jKHJvb3QpXG4gICAgLm1hcCgoZW50cnkpID0+ICh7XG4gICAgICBlbnRyeSxcbiAgICAgIGFic29sdXRlOiBwYXRoLmpvaW4ocm9vdCwgZW50cnkpLFxuICAgIH0pKVxuICAgIC5maWx0ZXIoKHsgYWJzb2x1dGUgfSkgPT4gZnMuc3RhdFN5bmMoYWJzb2x1dGUpLmlzRGlyZWN0b3J5KCkpXG4gICAgLm1hcCgoeyBlbnRyeSB9KSA9PiBlbnRyeSlcbiAgICAuc29ydCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZU1vZHVsZVBhdGgoXG4gIG1vZHVsZU5hbWU6IHN0cmluZyxcbiAgd29ya3NwYWNlUm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKVxuKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhdGguam9pbihyZXNvbHZlTW9kdWxlc1Jvb3Qod29ya3NwYWNlUm9vdCksIG1vZHVsZU5hbWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZU1vZHVsZUZvbGRlclBhdGgoXG4gIG1vZHVsZU5hbWU6IHN0cmluZyxcbiAgZm9sZGVyOiBNb2R1bGVGb2xkZXIsXG4gIHdvcmtzcGFjZVJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KClcbik6IHN0cmluZyB7XG4gIHJldHVybiBwYXRoLmpvaW4ocmVzb2x2ZU1vZHVsZVBhdGgobW9kdWxlTmFtZSwgd29ya3NwYWNlUm9vdCksIGZvbGRlcik7XG59XG4iLCIvKiBpc3RhbmJ1bCBpZ25vcmUgZmlsZSAqL1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IE1jcE1vZHVsZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFV0aWxpdHkgY2xhc3MgZm9yIENMSSBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBBIHN0YXRpYyB1dGlsaXR5IGNsYXNzIHRoYXQgcHJvdmlkZXMgbWV0aG9kcyBmb3IgbG9hZGluZyBtb2R1bGVzLCByZXRyaWV2aW5nIHBhY2thZ2UgaW5mb3JtYXRpb24sIGFuZCBpbml0aWFsaXppbmcgQ0xJIGNvbW1hbmRzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEluaXRpYWxpemUgYSBDb21tYW5kIG9iamVjdCB3aXRoIHBhY2thZ2UgaW5mb3JtYXRpb25cbiAqIGNvbnN0IGNvbW1hbmQgPSBuZXcgQ29tbWFuZCgpO1xuICogQ0xJVXRpbHMuaW5pdGlhbGl6ZShjb21tYW5kLCAnLi9wYXRoL3RvL3BhY2thZ2UnKTtcbiAqXG4gKiAvLyBMb2FkIGEgQ0xJIG1vZHVsZSBmcm9tIGEgZmlsZVxuICogY29uc3QgbW9kdWxlID0gYXdhaXQgQ0xJVXRpbHMubG9hZEZyb21GaWxlKCcuL3BhdGgvdG8vY2xpLW1vZHVsZS5qcycpO1xuICpcbiAqIEBjbGFzcyBNY3BVdGlsc1xuICovXG5leHBvcnQgY2xhc3MgTWNwVXRpbHMge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIER5bmFtaWNhbGx5IGltcG9ydHMgYSBtb2R1bGUgZmlsZVxuICAgKiBAc3VtbWFyeSBMb2FkcyBhIEphdmFTY3JpcHQgZmlsZSBhbmQgcmV0dXJucyBpdCBhcyBhIENsaU1vZHVsZSwgaGFuZGxpbmcgYm90aCBFU00gYW5kIENvbW1vbkpTIGZvcm1hdHNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIGZpbGUgcGF0aCB0byB0aGUgbW9kdWxlIHRvIGxvYWRcbiAgICogQHJldHVybiB7UHJvbWlzZTxNY3BNb2R1bGU+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbG9hZGVkIENsaU1vZHVsZVxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGxvYWRGcm9tRmlsZShwYXRoOiBzdHJpbmcpOiBQcm9taXNlPE1jcE1vZHVsZT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gTWNwVXRpbHMubm9ybWFsaXplSW1wb3J0KGltcG9ydChwYXRoKSk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGxvYWQgZnJvbSAke3BhdGh9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IGV9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIE5vcm1hbGl6ZXMgbW9kdWxlIGltcG9ydHMgdG8gaGFuZGxlIGJvdGggRVNNIGFuZCBDb21tb25KUyBmb3JtYXRzXG4gICAqIEBzdW1tYXJ5IFByb3Blcmx5IGltcG9ydHMgSmF2YVNjcmlwdCBmaWxlcyByZWdhcmRsZXNzIG9mIHRoZWlyIG1vZHVsZSBmb3JtYXQgYnkgaGFuZGxpbmcgdGhlIEVTTSB3cmFwcGVyIGZvciBDb21tb25KUyBtb2R1bGVzXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBUIFRoZSB0eXBlIG9mIHRoZSBpbXBvcnRlZCBtb2R1bGVcbiAgICogQHBhcmFtIHtQcm9taXNlPFQ+fSBpbXBvcnRQcm9taXNlIFRoZSBwcm9taXNlIHJldHVybmVkIGJ5IHRoZSBkeW5hbWljIGltcG9ydFxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbm9ybWFsaXplZCBtb2R1bGVcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHN0YXRpYyBhc3luYyBub3JtYWxpemVJbXBvcnQ8VD4oaW1wb3J0UHJvbWlzZTogUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgIC8vIENvbW1vbkpTJ3MgYG1vZHVsZS5leHBvcnRzYCBpcyB3cmFwcGVkIGFzIGBkZWZhdWx0YCBpbiBFU01vZHVsZS5cbiAgICByZXR1cm4gaW1wb3J0UHJvbWlzZS50aGVuKFxuICAgICAgKG06IHVua25vd24pID0+ICgobSBhcyB7IGRlZmF1bHQ6IFQgfSkuZGVmYXVsdCB8fCBtKSBhcyBUXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGFuZCBwYXJzZXMgdGhlIHBhY2thZ2UuanNvbiBmaWxlXG4gICAqIEBzdW1tYXJ5IFJlYWRzIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBmcm9tIHRoZSBzcGVjaWZpZWQgcGF0aCBhbmQgcGFyc2VzIGl0IGludG8gYSBKYXZhU2NyaXB0IG9iamVjdFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gVGhlIHBhcnNlZCBwYWNrYWdlLmpzb24gY29udGVudCBhcyBhbiBvYmplY3RcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdldFBhY2thZ2UoYmFzZVBhdGg6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoXG4gICAgICAgIGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4oYmFzZVBhdGgsIFwicGFja2FnZS5qc29uXCIpLCBcInV0ZjhcIilcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gcmVhZCB2ZXJzaW9uIGZyb20gJHtiYXNlUGF0aH06ICR7ZX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHVybnMgdGhlIHZlcnNpb24gZnJvbSBwYWNrYWdlLmpzb25cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSB2ZXJzaW9uIGZpZWxkIGZyb20gdGhlIHBhY2thZ2UuanNvbiBmaWxlIGF0IHRoZSBzcGVjaWZpZWQgcGF0aFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwYWNrYWdlIHZlcnNpb24gc3RyaW5nXG4gICAqL1xuICBzdGF0aWMgcGFja2FnZVZlcnNpb24oYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIE1jcFV0aWxzLmdldFBhY2thZ2UoYmFzZVBhdGgpW1widmVyc2lvblwiXSBhcyBzdHJpbmc7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHVybnMgdGhlIG5hbWUgZnJvbSBwYWNrYWdlLmpzb25cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBuYW1lIGZpZWxkIGZyb20gdGhlIHBhY2thZ2UuanNvbiBmaWxlIGF0IHRoZSBzcGVjaWZpZWQgcGF0aCBhbmQgZXh0cmFjdHMgdGhlIHBhY2thZ2UgbmFtZSB3aXRob3V0IHRoZSBzY29wZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwYWNrYWdlIG5hbWUgd2l0aG91dCB0aGUgc2NvcGUgKGUuZy4sIFwiY2xpXCIgZnJvbSBcIkBkZWNhZi10cy9jbGlcIilcbiAgICovXG4gIHN0YXRpYyBwYWNrYWdlTmFtZShiYXNlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBuYW1lID0gKE1jcFV0aWxzLmdldFBhY2thZ2UoYmFzZVBhdGgpW1wibmFtZVwiXSBhcyBzdHJpbmcpLnNwbGl0KFwiL1wiKTtcbiAgICByZXR1cm4gbmFtZVtuYW1lLmxlbmd0aCAtIDFdO1xuICB9XG59XG5cbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzL21vZHVsZVBhdGhzXCI7XG4iLCJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgTUNQX0ZJTEVfTkFNRSB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgTWNwVXRpbHMgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgRmFzdE1DUCB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQgeyBMb2dnZWRDbGFzcyB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gXCIuL21ldGFkYXRhXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFV0aWxpdHkgY2xhc3MgdG8gaGFuZGxlIENMSSBmdW5jdGlvbmFsaXR5IGZyb20gYWxsIERlY2FmIG1vZHVsZXNcbiAqIEBzdW1tYXJ5IFRoaXMgY2xhc3MgcHJvdmlkZXMgYSB3cmFwcGVyIGFyb3VuZCBDb21tYW5kZXIuanMgdG8gaGFuZGxlIENMSSBjb21tYW5kcyBmcm9tIGRpZmZlcmVudCBEZWNhZiBtb2R1bGVzLlxuICogSXQgY3Jhd2xzIHRoZSBmaWxlc3lzdGVtIHRvIGZpbmQgQ0xJIG1vZHVsZXMsIGxvYWRzIHRoZW0sIGFuZCByZWdpc3RlcnMgdGhlaXIgY29tbWFuZHMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtiYXNlUGF0aF0gVGhlIGJhc2UgcGF0aCB0byBsb29rIGZvciBtb2R1bGVzIGluLiBEZWZhdWx0cyB0byBgLi9gXG4gKiBAcGFyYW0ge251bWJlcn0gW2NyYXdsTGV2ZWxzXSBOdW1iZXIgb2YgZm9sZGVyIGxldmVscyB0byBjcmF3bCB0byBmaW5kIG1vZHVsZXMgZnJvbSB0aGUgYmFzZVBhdGguIERlZmF1bHRzIHRvIDRcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIGEgbmV3IENMSSB3cmFwcGVyIGFuZCBydW4gaXQgd2l0aCBjdXN0b20gb3B0aW9uc1xuICogY29uc3QgY2xpID0gbmV3IENsaVdyYXBwZXIoJy4vc3JjJywgMik7XG4gKiBjbGkucnVuKHByb2Nlc3MuYXJndikudGhlbigoKSA9PiB7XG4gKiAgIGNvbnNvbGUubG9nKCdDTEkgY29tbWFuZHMgZXhlY3V0ZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gKiB9KTtcbiAqXG4gKiBAY2xhc3MgTWNwV3JhcHBlclxuICovXG5leHBvcnQgY2xhc3MgTWNwV3JhcHBlciBleHRlbmRzIExvZ2dlZENsYXNzIHtcbiAgcHJpdmF0ZSBfbWNwPzogRmFzdE1DUDtcbiAgcHJpdmF0ZSBtb2R1bGVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIHByaXZhdGUgcmVhZG9ubHkgcm9vdFBhdGg6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGJhc2VQYXRoOiBzdHJpbmcgPSBcIi4vXCIsXG4gICAgcHJpdmF0ZSBjcmF3bExldmVscyA9IDRcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnJvb3RQYXRoID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgXCIuLlwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGFuZCBpbml0aWFsaXplcyB0aGUgQ29tbWFuZGVyIENvbW1hbmQgb2JqZWN0XG4gICAqIEBzdW1tYXJ5IExhenktbG9hZHMgdGhlIENvbW1hbmQgb2JqZWN0LCBpbml0aWFsaXppbmcgaXQgd2l0aCB0aGUgcGFja2FnZSBuYW1lLCBkZXNjcmlwdGlvbiwgYW5kIHZlcnNpb25cbiAgICogQHJldHVybiB7RmFzdE1DUH0gVGhlIGluaXRpYWxpemVkIENvbW1hbmQgb2JqZWN0XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGdldCBtY3AoKSB7XG4gICAgaWYgKCF0aGlzLl9tY3ApIHtcbiAgICAgIHRoaXMuX21jcCA9IG5ldyBGYXN0TUNQKHtcbiAgICAgICAgbmFtZTogXCJkZWNhZi10cyBNQ1Agc2VydmVyXCIsXG4gICAgICAgIGluc3RydWN0aW9uczogXCJcIixcbiAgICAgICAgdmVyc2lvbjogVkVSU0lPTiBhcyBhbnksXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX21jcDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9hZHMgYW5kIHJlZ2lzdGVycyBhbiBtY3AgZXh0ZW5zaW9uIG1vZHVsZSBmcm9tIGEgZmlsZVxuICAgKiBAc3VtbWFyeSBEeW5hbWljYWxseSBpbXBvcnRzIGFuIG1jcCBleHRlbnNpb24gbW9kdWxlIGZyb20gdGhlIHNwZWNpZmllZCBmaWxlIHBhdGgsIGluaXRpYWxpemVzIGl0LCBhbmQgcmVnaXN0ZXJzIGl0IGluIHRoZSBtb2R1bGVzIGNvbGxlY3Rpb25cbiAgICpcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgbG9hZChcbiAgICBzZXJ2ZXI6IEZhc3RNQ1AsXG4gICAgZmlsZVBhdGg6IHN0cmluZ1xuICApOiBQcm9taXNlPHsgbWNwOiBGYXN0TUNQOyBwYWNrYWdlOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZyB9PiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMubG9hZCk7XG5cbiAgICBsZXQgcGtnOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgZW5yaWNoOiBhbnk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IE1jcFV0aWxzLmxvYWRGcm9tRmlsZShmaWxlUGF0aCk7XG4gICAgICBwa2cgPSByZXMuUEFDS0FHRV9OQU1FO1xuICAgICAgdmVyc2lvbiA9IHJlcy5WRVJTSU9OO1xuICAgICAgZW5yaWNoID0gcmVzLmVucmljaDtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoKGUgYXMgYW55KS5tZXNzYWdlIHx8IChlIGFzIGFueSkpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgbG9nLmluZm8oYEVucmljaGluZyBtY3Agc2VydmVyIHdpdGggbW9kdWxlICR7cGtnfSB2JHt2ZXJzaW9ufWApO1xuICAgICAgY29uc3QgcmVzdWx0ID0gZW5yaWNoKHNlcnZlcik7XG4gICAgICBzZXJ2ZXIgPSByZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlID8gYXdhaXQgcmVzdWx0IDogcmVzdWx0O1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYGZhaWxlZCB0byBlbnJpY2ggbWNwIHdpdGggbW9kdWxlICR7cGtnIHx8IFwidW5uYW1lZFwifSB1bmRlciAke2ZpbGVQYXRofTogJHtlIGluc3RhbmNlb2YgRXJyb3IgPyBlLm1lc3NhZ2UgOiBlfWBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBtY3A6IHNlcnZlcixcbiAgICAgIHBhY2thZ2U6IHBrZyxcbiAgICAgIHZlcnNpb246IHZlcnNpb24sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRmluZHMgYW5kIGxvYWRzIGFsbCBDTEkgbW9kdWxlcyBpbiB0aGUgYmFzZVBhdGhcbiAgICogQHN1bW1hcnkgVXNlcyB0aGUgY3Jhd2wgbWV0aG9kIHRvIGZpbmQgYWxsIENMSSBtb2R1bGVzIGluIHRoZSBzcGVjaWZpZWQgYmFzZSBwYXRoLFxuICAgKiB0aGVuIGxvYWRzIGFuZCByZWdpc3RlcnMgZWFjaCBtb2R1bGUgYXMgYSBzdWJjb21tYW5kXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gYWxsIG1vZHVsZXMgYXJlIGxvYWRlZFxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGlXcmFwcGVyXG4gICAqICAgcGFydGljaXBhbnQgRmlsZXN5c3RlbVxuICAgKiAgIHBhcnRpY2lwYW50IE1vZHVsZVxuICAgKlxuICAgKiAgIENsaVdyYXBwZXItPj5GaWxlc3lzdGVtOiBKb2luIGJhc2VQYXRoIHdpdGggY3dkXG4gICAqICAgQ2xpV3JhcHBlci0+PkNsaVdyYXBwZXI6IGNyYXdsKGJhc2VQYXRoLCBjcmF3bExldmVscylcbiAgICogICBDbGlXcmFwcGVyLS0+PkNsaVdyYXBwZXI6IG1vZHVsZXNbXVxuICAgKiAgIGxvb3AgRm9yIGVhY2ggbW9kdWxlXG4gICAqICAgICBhbHQgTm90IEBkZWNhZi10cy9jbGlcbiAgICogICAgICAgQ2xpV3JhcHBlci0+PkNsaVdyYXBwZXI6IGxvYWQobW9kdWxlLCBjd2QpXG4gICAqICAgICAgIENsaVdyYXBwZXItLT4+Q2xpV3JhcHBlcjogbmFtZVxuICAgKiAgICAgICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogQ2hlY2sgaWYgY29tbWFuZCBleGlzdHNcbiAgICogICAgICAgYWx0IENvbW1hbmQgZG9lc24ndCBleGlzdFxuICAgKiAgICAgICAgIENsaVdyYXBwZXItPj5Db21tYW5kOiBjb21tYW5kKG5hbWUpLmFkZENvbW1hbmQobW9kdWxlc1tuYW1lXSlcbiAgICogICAgICAgZW5kXG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICogICBDbGlXcmFwcGVyLT4+Q29uc29sZTogTG9nIGxvYWRlZCBtb2R1bGVzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGJvb3QoKSB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuYm9vdCk7XG4gICAgbGV0IHNlcnZlciA9IHRoaXMubWNwO1xuICAgIC8vIGRpc2NvdmVyIG1vZHVsZXMgYnkgY3Jhd2xpbmcgYmFzZVBhdGhcbiAgICBjb25zdCBtb2R1bGVGaWxlcyA9IHRoaXMuY3Jhd2woXG4gICAgICBwYXRoLnJlc29sdmUodGhpcy5iYXNlUGF0aCksXG4gICAgICB0aGlzLmNyYXdsTGV2ZWxzXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IG1vZHVsZUZpbGUgb2YgbW9kdWxlRmlsZXMpIHtcbiAgICAgIGlmIChtb2R1bGVGaWxlLmluY2x1ZGVzKFwiQGRlY2FmLXRzL21jcFwiKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMubG9hZChzZXJ2ZXIsIG1vZHVsZUZpbGUpO1xuICAgICAgICBzZXJ2ZXIgPSByZXMubWNwO1xuICAgICAgICB0aGlzLm1vZHVsZXNbcmVzLnBhY2thZ2VdID0gbW9kdWxlRmlsZTtcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgbG9nLmVycm9yKFxuICAgICAgICAgIGBGYWlsZWQgdG8gbG9hZCBNQ1AgY29uZmlncyBmb3IgJHttb2R1bGVGaWxlfTogJHtlIGluc3RhbmNlb2YgRXJyb3IgPyBlLm1lc3NhZ2UgOiBlfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc29sZS5sb2coXG4gICAgICBgbG9hZGVkIG1vZHVsZXM6XFxuJHtPYmplY3Qua2V5cyh0aGlzLm1vZHVsZXMpXG4gICAgICAgIC5tYXAoKGspID0+IGAtICR7a31gKVxuICAgICAgICAuam9pbihcIlxcblwiKX1gXG4gICAgKTtcbiAgICByZXR1cm4gc2VydmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWN1cnNpdmVseSBzZWFyY2hlcyBmb3IgQ0xJIG1vZHVsZSBmaWxlcyBpbiB0aGUgZGlyZWN0b3J5IHN0cnVjdHVyZVxuICAgKiBAc3VtbWFyeSBDcmF3bHMgdGhlIGJhc2VQYXRoIHVwIHRvIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGZvbGRlciBsZXZlbHMgdG8gZmluZCBmaWxlcyBuYW1lZCBhY2NvcmRpbmcgdG8gQ0xJX0ZJTEVfTkFNRVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGFic29sdXRlIGJhc2UgcGF0aCB0byBzdGFydCBzZWFyY2hpbmcgaW5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtsZXZlbHM9Ml0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGRpcmVjdG9yeSBsZXZlbHMgdG8gY3Jhd2xcbiAgICogQHJldHVybiB7c3RyaW5nW119IEFuIGFycmF5IG9mIGZpbGUgcGF0aHMgdG8gQ0xJIG1vZHVsZXNcbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgY3Jhd2woYmFzZVBhdGg6IHN0cmluZywgbGV2ZWxzOiBudW1iZXIgPSAyKSB7XG4gICAgaWYgKGxldmVscyA8PSAwKSByZXR1cm4gW107XG4gICAgcmV0dXJuIGZzLnJlYWRkaXJTeW5jKGJhc2VQYXRoKS5yZWR1Y2UoKGFjY3VtOiBzdHJpbmdbXSwgZmlsZSkgPT4ge1xuICAgICAgZmlsZSA9IHBhdGguam9pbihiYXNlUGF0aCwgZmlsZSk7XG4gICAgICBpZiAoZnMuc3RhdFN5bmMoZmlsZSkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICBhY2N1bS5wdXNoKC4uLnRoaXMuY3Jhd2woZmlsZSwgbGV2ZWxzIC0gMSkpO1xuICAgICAgfSBlbHNlIGlmIChmaWxlLm1hdGNoKG5ldyBSZWdFeHAoYCR7TUNQX0ZJTEVfTkFNRX0uW2NtXT9qcyRgLCBcImdtXCIpKSkge1xuICAgICAgICBhY2N1bS5wdXNoKGZpbGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH0sIFtdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXhlY3V0ZXMgdGhlIENMSSB3aXRoIHRoZSBwcm92aWRlZCBhcmd1bWVudHNcbiAgICogQHN1bW1hcnkgQm9vdHMgdGhlIENMSSBieSBsb2FkaW5nIGFsbCBtb2R1bGVzLCB0aGVuIHBhcnNlcyBhbmQgZXhlY3V0ZXMgdGhlIGNvbW1hbmQgc3BlY2lmaWVkIGluIHRoZSBhcmd1bWVudHNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gW2FyZ3M9cHJvY2Vzcy5hcmd2XSBDb21tYW5kIGxpbmUgYXJndW1lbnRzIHRvIHBhcnNlIGFuZCBleGVjdXRlXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGNvbW1hbmQgZXhlY3V0aW9uIGlzIGNvbXBsZXRlXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IENsaVdyYXBwZXJcbiAgICogICBwYXJ0aWNpcGFudCBDb21tYW5kXG4gICAqXG4gICAqICAgQ2xpZW50LT4+Q2xpV3JhcHBlcjogcnVuKGFyZ3MpXG4gICAqICAgQ2xpV3JhcHBlci0+PkNsaVdyYXBwZXI6IGJvb3QoKVxuICAgKiAgIE5vdGUgb3ZlciBDbGlXcmFwcGVyOiBMb2FkcyBhbGwgbW9kdWxlc1xuICAgKiAgIENsaVdyYXBwZXItPj5Db21tYW5kOiBwYXJzZUFzeW5jKGFyZ3MpXG4gICAqICAgQ29tbWFuZC0tPj5DbGlXcmFwcGVyOiByZXN1bHRcbiAgICogICBDbGlXcmFwcGVyLS0+PkNsaWVudDogcmVzdWx0XG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGFzeW5jIHJ1bihhcmdzOiBzdHJpbmdbXSA9IHByb2Nlc3MuYXJndikge1xuICAgIGNvbnN0IHNlcnZlciA9IGF3YWl0IHRoaXMuYm9vdCgpO1xuICAgIGF3YWl0IHNlcnZlci5zdGFydCh7IHRyYW5zcG9ydFR5cGU6IFwic3RkaW9cIiB9KTtcbiAgfVxufVxuIl0sIm5hbWVzIjpbInByb21wdHMiLCJyZXNvdXJjZXMiLCJ0ZW1wbGF0ZXMiLCJ0b29sTGlzdCIsInRvb2xzIiwibW9kdWxlUGFja2FnZSIsImRlY29yYXRpb25Nb2R1bGUiLCJtY3BNb2R1bGUiLCJ0ZW1wbGF0ZU1vZHVsZSIsImNvcmVUb29sTGlzdCIsIlZFUlNJT04iLCJQQUNLQUdFX05BTUUiLCJQS0ciLCJWIiwicGF0aCIsImZzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQTs7Ozs7O0FBTUc7QUFDSSxNQUFNLGFBQWEsR0FBRztBQUd0QixNQUFNLGtCQUFrQixHQUFHO01BQ3JCLGtCQUFrQixHQUFHLENBQUMsZUFBZSxFQUFFLGdCQUFnQjtBQUM3RCxNQUFNLG1CQUFtQixHQUFHO0FBQzVCLE1BQU0sbUJBQW1CLEdBQUc7QUFDakMsSUFBQTtBQUNFLFFBQUEsRUFBRSxFQUFFLFFBQVE7QUFDWixRQUFBLE9BQU8sRUFBRSxvQkFBb0I7QUFDN0IsUUFBQSxZQUFZLEVBQ1Ysb01BQW9NO0FBQ3ZNLEtBQUE7QUFDRCxJQUFBO0FBQ0UsUUFBQSxFQUFFLEVBQUUsUUFBUTtBQUNaLFFBQUEsT0FBTyxFQUFFLFFBQVE7QUFDakIsUUFBQSxZQUFZLEVBQ1YsaUxBQWlMO0FBQ3BMLEtBQUE7QUFDRCxJQUFBO0FBQ0UsUUFBQSxFQUFFLEVBQUUsU0FBUztBQUNiLFFBQUEsT0FBTyxFQUFFLGdCQUFnQjtBQUN6QixRQUFBLFlBQVksRUFDVixpTUFBaU07QUFDcE0sS0FBQTs7O0FDM0JILElBQUksYUFBYSxHQUFHLHVCQUF1QixFQUFFO0FBQzdDLElBQUksYUFBMkQ7QUFFekQsTUFBTyxjQUFlLFNBQVEsS0FBSyxDQUFBO0FBQ3ZDLElBQUEsV0FBQSxDQUFZLE9BQWUsRUFBQTtRQUN6QixLQUFLLENBQUMsT0FBTyxDQUFDO0FBQ2QsUUFBQSxJQUFJLENBQUMsSUFBSSxHQUFHLGdCQUFnQjtJQUM5QjtBQUNEO0FBRUQsU0FBUyx1QkFBdUIsR0FBQTtJQUM5QixNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDO0lBQ2xELElBQUksVUFBVSxJQUFJLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FB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
|