@nlabs/lex 1.48.7 → 1.49.1
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/.storybook/main.ts +9 -2
- package/.vscode/settings.json +1 -6
- package/README.md +249 -0
- package/eslint.config.mjs +24 -0
- package/examples/lex.config.js +18 -8
- package/examples/serverless-example/README.md +109 -0
- package/examples/serverless-example/dist/handlers/echo.js +15 -0
- package/examples/serverless-example/dist/handlers/graphql.js +137 -0
- package/examples/serverless-example/dist/handlers/hello.js +15 -0
- package/examples/serverless-example/dist/handlers/test.js +17 -0
- package/examples/serverless-example/dist/handlers/websocket.js +14 -0
- package/examples/serverless-example/lex.config.mjs +74 -0
- package/jest.config.mjs +13 -12
- package/{dist → lib}/LexConfig.d.ts +7 -6
- package/lib/LexConfig.js +268 -0
- package/lib/commands/ai/ai.js +303 -0
- package/{dist → lib}/commands/build/build.d.ts +3 -0
- package/lib/commands/build/build.js +494 -0
- package/{dist → lib}/commands/clean/clean.js +1 -1
- package/lib/commands/compile/compile.js +241 -0
- package/lib/commands/copy/copy.js +38 -0
- package/{dist → lib}/commands/create/create.js +1 -1
- package/{dist → lib}/commands/dev/dev.d.ts +2 -0
- package/lib/commands/dev/dev.js +286 -0
- package/{dist → lib}/commands/init/init.js +1 -1
- package/lib/commands/lint/lint.js +962 -0
- package/{dist → lib}/commands/migrate/migrate.js +1 -1
- package/lib/commands/publish/publish.js +104 -0
- package/lib/commands/serverless/serverless.d.ts +17 -0
- package/lib/commands/serverless/serverless.js +662 -0
- package/lib/commands/storybook/storybook.js +249 -0
- package/lib/commands/test/test.js +428 -0
- package/lib/commands/update/update.js +128 -0
- package/{dist → lib}/create/changelog.js +1 -1
- package/{dist → lib}/index.d.ts +1 -0
- package/{dist → lib}/index.js +2 -1
- package/lib/lex.js +73 -0
- package/lib/utils/aiService.d.ts +9 -0
- package/lib/utils/aiService.js +299 -0
- package/{dist → lib}/utils/app.d.ts +3 -0
- package/lib/utils/app.js +296 -0
- package/{dist → lib}/utils/file.d.ts +7 -3
- package/lib/utils/file.js +229 -0
- package/lib/utils/translations.d.ts +1 -0
- package/lib/utils/translations.js +74 -0
- package/package.json +60 -54
- package/postcss.config.js +5 -3
- package/tsconfig.build.json +2 -2
- package/webpack.config.js +229 -39
- package/dist/LexConfig.js +0 -287
- package/dist/commands/ai/ai.js +0 -303
- package/dist/commands/build/build.js +0 -404
- package/dist/commands/compile/compile.js +0 -234
- package/dist/commands/copy/copy.js +0 -38
- package/dist/commands/dev/dev.js +0 -74
- package/dist/commands/lint/lint.js +0 -993
- package/dist/commands/publish/publish.js +0 -104
- package/dist/commands/storybook/storybook.js +0 -249
- package/dist/commands/test/test.js +0 -429
- package/dist/commands/update/update.js +0 -132
- package/dist/lex.js +0 -70
- package/dist/utils/aiService.d.ts +0 -9
- package/dist/utils/aiService.js +0 -299
- package/dist/utils/app.js +0 -267
- package/dist/utils/file.js +0 -185
- package/emptyModule.js +0 -0
- package/eslint.config.js +0 -3
- /package/{dist → lib}/Button.stories.d.ts +0 -0
- /package/{dist → lib}/commands/ai/ai.d.ts +0 -0
- /package/{dist → lib}/commands/ai/index.d.ts +0 -0
- /package/{dist → lib}/commands/ai/index.js +0 -0
- /package/{dist → lib}/commands/clean/clean.d.ts +0 -0
- /package/{dist → lib}/commands/compile/compile.d.ts +0 -0
- /package/{dist → lib}/commands/config/config.d.ts +0 -0
- /package/{dist → lib}/commands/config/config.js +0 -0
- /package/{dist → lib}/commands/copy/copy.d.ts +0 -0
- /package/{dist → lib}/commands/create/create.d.ts +0 -0
- /package/{dist → lib}/commands/init/init.d.ts +0 -0
- /package/{dist → lib}/commands/link/link.d.ts +0 -0
- /package/{dist → lib}/commands/link/link.js +0 -0
- /package/{dist → lib}/commands/lint/autofix.d.ts +0 -0
- /package/{dist → lib}/commands/lint/lint.d.ts +0 -0
- /package/{dist → lib}/commands/migrate/migrate.d.ts +0 -0
- /package/{dist → lib}/commands/publish/publish.d.ts +0 -0
- /package/{dist → lib}/commands/storybook/storybook.d.ts +0 -0
- /package/{dist → lib}/commands/test/test.d.ts +0 -0
- /package/{dist → lib}/commands/update/update.d.ts +0 -0
- /package/{dist → lib}/commands/upgrade/upgrade.d.ts +0 -0
- /package/{dist → lib}/commands/upgrade/upgrade.js +0 -0
- /package/{dist → lib}/commands/versions/versions.d.ts +0 -0
- /package/{dist → lib}/commands/versions/versions.js +0 -0
- /package/{dist → lib}/create/changelog.d.ts +0 -0
- /package/{dist → lib}/lex.d.ts +0 -0
- /package/{dist → lib}/storybook/index.d.ts +0 -0
- /package/{dist → lib}/storybook/index.js +0 -0
- /package/{dist → lib}/test-react/index.d.ts +0 -0
- /package/{dist → lib}/test-react/index.js +0 -0
- /package/{dist → lib}/types.d.ts +0 -0
- /package/{dist → lib}/types.js +0 -0
- /package/{dist → lib}/utils/deepMerge.d.ts +0 -0
- /package/{dist → lib}/utils/deepMerge.js +0 -0
- /package/{dist → lib}/utils/log.d.ts +0 -0
- /package/{dist → lib}/utils/log.js +0 -0
- /package/{dist → lib}/utils/reactShim.d.ts +0 -0
- /package/{dist → lib}/utils/reactShim.js +0 -0
package/dist/LexConfig.js
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
-
import { dirname, extname as pathExtname, resolve as pathResolve } from "path";
|
|
3
|
-
import { URL } from "url";
|
|
4
|
-
import { getDirName, getLexPackageJsonPath, relativeFilePath } from "./utils/file.js";
|
|
5
|
-
import { log } from "./utils/log.js";
|
|
6
|
-
const cwd = process.cwd();
|
|
7
|
-
const defaultConfigValues = {
|
|
8
|
-
ai: {
|
|
9
|
-
provider: "none",
|
|
10
|
-
model: "gpt-4o",
|
|
11
|
-
maxTokens: 4e3,
|
|
12
|
-
temperature: 0.1
|
|
13
|
-
},
|
|
14
|
-
configFiles: [],
|
|
15
|
-
copyFiles: [],
|
|
16
|
-
entryHTML: "index.html",
|
|
17
|
-
entryJs: "index.js",
|
|
18
|
-
eslint: {},
|
|
19
|
-
esbuild: {
|
|
20
|
-
minify: true,
|
|
21
|
-
treeShaking: true,
|
|
22
|
-
drop: ["console", "debugger"],
|
|
23
|
-
pure: ["console.log", "console.warn", "console.error"],
|
|
24
|
-
legalComments: "none",
|
|
25
|
-
splitting: true,
|
|
26
|
-
metafile: false,
|
|
27
|
-
sourcemap: false
|
|
28
|
-
},
|
|
29
|
-
env: null,
|
|
30
|
-
jest: {},
|
|
31
|
-
outputFullPath: pathResolve(cwd, "./dist"),
|
|
32
|
-
outputHash: false,
|
|
33
|
-
outputPath: "./dist",
|
|
34
|
-
packageManager: "npm",
|
|
35
|
-
preset: "web",
|
|
36
|
-
sourceFullPath: pathResolve(cwd, "./src"),
|
|
37
|
-
sourcePath: "./src",
|
|
38
|
-
targetEnvironment: "web",
|
|
39
|
-
useGraphQl: false,
|
|
40
|
-
useTypescript: false,
|
|
41
|
-
webpack: {}
|
|
42
|
-
};
|
|
43
|
-
function findLexRoot(startDir) {
|
|
44
|
-
let dir = startDir;
|
|
45
|
-
while (dir !== "/" && dir !== ".") {
|
|
46
|
-
const pkgPath = pathResolve(dir, "package.json");
|
|
47
|
-
if (existsSync(pkgPath)) {
|
|
48
|
-
try {
|
|
49
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
50
|
-
if (pkg.name === "@nlabs/lex") {
|
|
51
|
-
return dir;
|
|
52
|
-
}
|
|
53
|
-
} catch {
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
const parent = dirname(dir);
|
|
57
|
-
if (parent === dir) {
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
dir = parent;
|
|
61
|
-
}
|
|
62
|
-
throw new Error("Could not find @nlabs/lex root");
|
|
63
|
-
}
|
|
64
|
-
function getTypeScriptConfigPath(configName) {
|
|
65
|
-
const cwd2 = process.cwd();
|
|
66
|
-
if (configName === "tsconfig.build.json") {
|
|
67
|
-
const projectBuildConfig = pathResolve(cwd2, "tsconfig.build.json");
|
|
68
|
-
if (existsSync(projectBuildConfig)) {
|
|
69
|
-
return projectBuildConfig;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (configName === "tsconfig.lint.json") {
|
|
73
|
-
const projectLintConfig = pathResolve(cwd2, "tsconfig.eslint.json");
|
|
74
|
-
if (existsSync(projectLintConfig)) {
|
|
75
|
-
return projectLintConfig;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
if (configName === "tsconfig.test.json") {
|
|
79
|
-
const projectTestConfig = pathResolve(cwd2, "tsconfig.test.json");
|
|
80
|
-
if (existsSync(projectTestConfig)) {
|
|
81
|
-
return projectTestConfig;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
const projectConfigPath = pathResolve(cwd2, configName);
|
|
85
|
-
if (existsSync(projectConfigPath)) {
|
|
86
|
-
return projectConfigPath;
|
|
87
|
-
}
|
|
88
|
-
const lexDir = LexConfig.getLexDir();
|
|
89
|
-
return pathResolve(lexDir, configName);
|
|
90
|
-
}
|
|
91
|
-
class LexConfig {
|
|
92
|
-
static config = {
|
|
93
|
-
...defaultConfigValues
|
|
94
|
-
};
|
|
95
|
-
static getLexDir() {
|
|
96
|
-
return dirname(getLexPackageJsonPath());
|
|
97
|
-
}
|
|
98
|
-
static set useTypescript(value) {
|
|
99
|
-
LexConfig.config.useTypescript = value;
|
|
100
|
-
const { sourceFullPath } = LexConfig.config;
|
|
101
|
-
const { entryJs } = LexConfig.config;
|
|
102
|
-
if (entryJs === "index.js" && value) {
|
|
103
|
-
const indexPath = pathResolve(cwd, sourceFullPath, "index.tsx");
|
|
104
|
-
const hasIndexTsx = existsSync(indexPath);
|
|
105
|
-
if (hasIndexTsx) {
|
|
106
|
-
LexConfig.config.entryJs = "index.tsx";
|
|
107
|
-
} else {
|
|
108
|
-
LexConfig.config.entryJs = "index.ts";
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
static updateConfig(updatedConfig) {
|
|
113
|
-
const { outputFullPath, outputPath, sourcePath, sourceFullPath, useTypescript, ai } = updatedConfig;
|
|
114
|
-
const cwd2 = process.cwd();
|
|
115
|
-
if (useTypescript !== void 0) {
|
|
116
|
-
LexConfig.useTypescript = useTypescript;
|
|
117
|
-
}
|
|
118
|
-
if (outputPath !== void 0 && outputFullPath === void 0) {
|
|
119
|
-
updatedConfig.outputFullPath = pathResolve(cwd2, outputPath);
|
|
120
|
-
}
|
|
121
|
-
if (sourcePath !== void 0 && sourceFullPath === void 0) {
|
|
122
|
-
updatedConfig.sourceFullPath = pathResolve(cwd2, sourcePath);
|
|
123
|
-
}
|
|
124
|
-
if (ai) {
|
|
125
|
-
LexConfig.config.ai = { ...LexConfig.config.ai, ...ai };
|
|
126
|
-
if (process.env.CURSOR_IDE === "true" && LexConfig.config.ai.provider === "none") {
|
|
127
|
-
LexConfig.config.ai.provider = "cursor";
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
LexConfig.config = { ...LexConfig.config, ...updatedConfig };
|
|
131
|
-
return LexConfig.config;
|
|
132
|
-
}
|
|
133
|
-
static addConfigParams(cmd, params) {
|
|
134
|
-
const nameProperty = "_name";
|
|
135
|
-
const { environment, outputPath, sourcePath, typescript } = cmd;
|
|
136
|
-
if (outputPath !== void 0) {
|
|
137
|
-
params.outputPath = outputPath;
|
|
138
|
-
params.outputFullPath = pathResolve(cwd, outputPath);
|
|
139
|
-
}
|
|
140
|
-
if (sourcePath !== void 0) {
|
|
141
|
-
params.sourcePath = sourcePath;
|
|
142
|
-
params.sourceFullPath = pathResolve(cwd, sourcePath);
|
|
143
|
-
}
|
|
144
|
-
if (typescript !== void 0) {
|
|
145
|
-
params.useTypescript = true;
|
|
146
|
-
}
|
|
147
|
-
if (environment !== void 0) {
|
|
148
|
-
params.targetEnvironment = environment === "web" ? "web" : "node";
|
|
149
|
-
}
|
|
150
|
-
process.env.LEX_CONFIG = JSON.stringify(
|
|
151
|
-
{
|
|
152
|
-
...LexConfig.updateConfig(params),
|
|
153
|
-
commandName: cmd[nameProperty],
|
|
154
|
-
isStatic: cmd.static
|
|
155
|
-
},
|
|
156
|
-
null,
|
|
157
|
-
0
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
static async parseConfig(cmd, isRoot = true) {
|
|
161
|
-
const { cliName = "Lex", lexConfig, lexConfigName, quiet, typescript, debug = false } = cmd;
|
|
162
|
-
const configFormats = ["js", "mjs", "cjs", "ts", "json"];
|
|
163
|
-
const configBaseName = lexConfigName || "lex.config";
|
|
164
|
-
let configPath = lexConfig || "";
|
|
165
|
-
let configExists = lexConfig ? existsSync(configPath) : false;
|
|
166
|
-
if (!configPath || !configExists) {
|
|
167
|
-
if (debug) {
|
|
168
|
-
log(`Searching for config files with base name: ${configBaseName}`, "info", quiet);
|
|
169
|
-
}
|
|
170
|
-
for (const format of configFormats) {
|
|
171
|
-
const potentialPath = isRoot ? pathResolve(cwd, `./${configBaseName}.${format}`) : relativeFilePath(`${configBaseName}.${format}`, cwd);
|
|
172
|
-
if (debug) {
|
|
173
|
-
log(`Checking for config file: ${potentialPath}`, "info", quiet);
|
|
174
|
-
}
|
|
175
|
-
if (existsSync(potentialPath)) {
|
|
176
|
-
configPath = potentialPath;
|
|
177
|
-
configExists = true;
|
|
178
|
-
break;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
if (configExists) {
|
|
183
|
-
log(`Using ${cliName} configuration file: ${configPath}`, "note", quiet);
|
|
184
|
-
const ext = pathExtname(configPath);
|
|
185
|
-
if (ext === ".json") {
|
|
186
|
-
const configContent = readFileSync(configPath, "utf8");
|
|
187
|
-
if (configContent) {
|
|
188
|
-
let configJson;
|
|
189
|
-
try {
|
|
190
|
-
configJson = JSON.parse(configContent)?.default || {};
|
|
191
|
-
} catch (error) {
|
|
192
|
-
log(`
|
|
193
|
-
${cliName} Error: Failed to parse JSON config: ${error.message}`, "error", quiet);
|
|
194
|
-
configJson = {};
|
|
195
|
-
}
|
|
196
|
-
LexConfig.addConfigParams(cmd, configJson);
|
|
197
|
-
} else {
|
|
198
|
-
log(`
|
|
199
|
-
${cliName} Error: Config file malformed, ${configPath}`, "error", quiet);
|
|
200
|
-
}
|
|
201
|
-
} else if ([".js", ".mjs", ".cjs", ".ts"].includes(ext)) {
|
|
202
|
-
try {
|
|
203
|
-
let lexCustomConfig;
|
|
204
|
-
if (ext === ".cjs") {
|
|
205
|
-
const fileUrl = new URL(`file:///${pathResolve(configPath)}`).href;
|
|
206
|
-
if (debug) {
|
|
207
|
-
log(`Loading CommonJS config from: ${fileUrl}`, "info", quiet);
|
|
208
|
-
}
|
|
209
|
-
lexCustomConfig = await import(fileUrl);
|
|
210
|
-
} else {
|
|
211
|
-
if (debug) {
|
|
212
|
-
log(`Loading ESM/TS config from: ${configPath}`, "info", quiet);
|
|
213
|
-
}
|
|
214
|
-
lexCustomConfig = await import(configPath);
|
|
215
|
-
}
|
|
216
|
-
const config = lexCustomConfig.default || lexCustomConfig;
|
|
217
|
-
if (debug) {
|
|
218
|
-
log(`Loaded config: ${JSON.stringify(config, null, 2)}`, "info", quiet);
|
|
219
|
-
}
|
|
220
|
-
if (!config) {
|
|
221
|
-
log(`
|
|
222
|
-
${cliName} Warning: Config file loaded but no configuration found`, "warn", quiet);
|
|
223
|
-
}
|
|
224
|
-
LexConfig.addConfigParams(cmd, config || {});
|
|
225
|
-
} catch (error) {
|
|
226
|
-
log(`
|
|
227
|
-
${cliName} Error: Failed to load config file: ${error.message}`, "error", quiet);
|
|
228
|
-
if (debug) {
|
|
229
|
-
console.error(error);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
} else {
|
|
233
|
-
log(`
|
|
234
|
-
${cliName} Error: Config file must be a JS, CJS, MJS, TS, or JSON file.`, "error", quiet);
|
|
235
|
-
}
|
|
236
|
-
} else {
|
|
237
|
-
if (debug) {
|
|
238
|
-
log("No config file found. Using default configuration.", "info", quiet);
|
|
239
|
-
}
|
|
240
|
-
LexConfig.useTypescript = !!typescript;
|
|
241
|
-
LexConfig.addConfigParams(cmd, LexConfig.config);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
static checkTypescriptConfig() {
|
|
245
|
-
const tsconfigPath = pathResolve(cwd, "./tsconfig.json");
|
|
246
|
-
if (!existsSync(tsconfigPath)) {
|
|
247
|
-
const dirName = getDirName();
|
|
248
|
-
writeFileSync(tsconfigPath, readFileSync(pathResolve(dirName, "../../../tsconfig.base.json")));
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
static checkCompileTypescriptConfig() {
|
|
252
|
-
const lexDir = LexConfig.getLexDir();
|
|
253
|
-
const tsconfigCompilePath = pathResolve(lexDir, "./tsconfig.build.json");
|
|
254
|
-
if (!existsSync(tsconfigCompilePath)) {
|
|
255
|
-
const templatePath = pathResolve(lexDir, "tsconfig.build.json");
|
|
256
|
-
if (existsSync(templatePath)) {
|
|
257
|
-
writeFileSync(tsconfigCompilePath, readFileSync(templatePath));
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
static checkLintTypescriptConfig() {
|
|
262
|
-
const lexDir = LexConfig.getLexDir();
|
|
263
|
-
const tsconfigLintPath = pathResolve(lexDir, "./tsconfig.lint.json");
|
|
264
|
-
if (!existsSync(tsconfigLintPath)) {
|
|
265
|
-
const templatePath = pathResolve(lexDir, "tsconfig.lint.json");
|
|
266
|
-
if (existsSync(templatePath)) {
|
|
267
|
-
writeFileSync(tsconfigLintPath, readFileSync(templatePath));
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
static checkTestTypescriptConfig() {
|
|
272
|
-
const lexDir = LexConfig.getLexDir();
|
|
273
|
-
const tsconfigTestPath = pathResolve(lexDir, "./tsconfig.test.json");
|
|
274
|
-
if (!existsSync(tsconfigTestPath)) {
|
|
275
|
-
const templatePath = pathResolve(lexDir, "tsconfig.test.json");
|
|
276
|
-
if (existsSync(templatePath)) {
|
|
277
|
-
writeFileSync(tsconfigTestPath, readFileSync(templatePath));
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
export {
|
|
283
|
-
LexConfig,
|
|
284
|
-
defaultConfigValues,
|
|
285
|
-
getTypeScriptConfigPath
|
|
286
|
-
};
|
|
287
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL0xleENvbmZpZy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jLCB3cml0ZUZpbGVTeW5jfSBmcm9tICdmcyc7XG5pbXBvcnQge2Rpcm5hbWUsIGV4dG5hbWUgYXMgcGF0aEV4dG5hbWUsIHJlc29sdmUgYXMgcGF0aFJlc29sdmV9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHtVUkx9IGZyb20gJ3VybCc7XG5cbmltcG9ydCB7Z2V0RGlyTmFtZSwgZ2V0TGV4UGFja2FnZUpzb25QYXRoLCByZWxhdGl2ZUZpbGVQYXRofSBmcm9tICcuL3V0aWxzL2ZpbGUuanMnO1xuaW1wb3J0IHtsb2d9IGZyb20gJy4vdXRpbHMvbG9nLmpzJztcblxuaW1wb3J0IHR5cGUge0xpbnRlcn0gZnJvbSAnZXNsaW50JztcblxuY29uc3QgY3dkOiBzdHJpbmcgPSBwcm9jZXNzLmN3ZCgpO1xuXG5leHBvcnQgaW50ZXJmYWNlIEVzYnVpbGRDb25maWcge1xuICBlbnRyeVBvaW50cz86IHN0cmluZ1tdO1xuICBvdXRkaXI/OiBzdHJpbmc7XG4gIHBsYXRmb3JtPzogJ25vZGUnIHwgJ2Jyb3dzZXInO1xuICB0YXJnZXQ/OiBzdHJpbmc7XG4gIGZvcm1hdD86ICdjanMnIHwgJ2VzbSc7XG4gIG1pbmlmeT86IGJvb2xlYW47XG4gIHRyZWVTaGFraW5nPzogYm9vbGVhbjtcbiAgZHJvcD86IHN0cmluZ1tdO1xuICBwdXJlPzogc3RyaW5nW107XG4gIGV4dGVybmFsPzogc3RyaW5nW107XG4gIHNwbGl0dGluZz86IGJvb2xlYW47XG4gIG1ldGFmaWxlPzogYm9vbGVhbjtcbiAgc291cmNlbWFwPzogYm9vbGVhbiB8ICdpbmxpbmUnIHwgJ2V4dGVybmFsJztcbiAgbGVnYWxDb21tZW50cz86ICdub25lJyB8ICdpbmxpbmUnIHwgJ2VvZicgfCAnbGlua2VkJyB8ICdzZXBhcmF0ZSc7XG4gIGJhbm5lcj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGZvb3Rlcj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGRlZmluZT86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIFtrZXk6IHN0cmluZ106IHVua25vd247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSmVzdENvbmZpZyB7XG4gIHJvb3RzPzogc3RyaW5nW107XG4gIHRlc3RFbnZpcm9ubWVudD86IHN0cmluZztcbiAgdHJhbnNmb3JtPzogUmVjb3JkPHN0cmluZywgW3N0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj5dPjtcbiAgdHJhbnNmb3JtSWdub3JlUGF0dGVybnM/OiBzdHJpbmdbXTtcbiAgbW9kdWxlTmFtZU1hcHBlcj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGV4dGVuc2lvbnNUb1RyZWF0QXNFc20/OiBzdHJpbmdbXTtcbiAgcHJlc2V0Pzogc3RyaW5nO1xuICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFdlYnBhY2tDb25maWcge1xuICBlbnRyeT86IHN0cmluZyB8IHN0cmluZ1tdO1xuICBvdXRwdXQ/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgbW9kdWxlPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIHBsdWdpbnM/OiB1bmtub3duW107XG4gIFtrZXk6IHN0cmluZ106IHVua25vd247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQUlDb25maWcge1xuICBwcm92aWRlcj86ICdjdXJzb3InIHwgJ2NvcGlsb3QnIHwgJ29wZW5haScgfCAnYW50aHJvcGljJyB8ICdub25lJztcbiAgYXBpS2V5Pzogc3RyaW5nO1xuICBtb2RlbD86IHN0cmluZztcbiAgbWF4VG9rZW5zPzogbnVtYmVyO1xuICB0ZW1wZXJhdHVyZT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFU0xpbnRDb25maWcge1xuICBleHRlbmRzPzogc3RyaW5nW107XG4gIHJ1bGVzPzogTGludGVyLlJ1bGVzUmVjb3JkO1xuICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExleENvbmZpZ1R5cGUge1xuICBhaT86IEFJQ29uZmlnO1xuICBjb25maWdGaWxlcz86IHN0cmluZ1tdO1xuICBjb3B5RmlsZXM/OiBzdHJpbmdbXTtcbiAgZW50cnlIVE1MPzogc3RyaW5nO1xuICBlbnRyeUpzPzogc3RyaW5nO1xuICBlbnY/OiBvYmplY3Q7XG4gIGVzYnVpbGQ/OiBFc2J1aWxkQ29uZmlnO1xuICBlc2xpbnQ/OiBFU0xpbnRDb25maWc7XG4gIGdpdFVybD86IHN0cmluZztcbiAgamVzdD86IEplc3RDb25maWc7XG4gIGxpYnJhcnlOYW1lPzogc3RyaW5nO1xuICBsaWJyYXJ5VGFyZ2V0Pzogc3RyaW5nO1xuICBvdXRwdXRGaWxlPzogc3RyaW5nO1xuICBvdXRwdXRGdWxsUGF0aD86IHN0cmluZztcbiAgb3V0cHV0SGFzaD86IGJvb2xlYW47XG4gIG91dHB1dFBhdGg/OiBzdHJpbmc7XG4gIHBhY2thZ2VNYW5hZ2VyPzogJ25wbScgfCAneWFybic7XG4gIHByZXNldD86ICd3ZWInIHwgJ25vZGUnIHwgJ2xhbWJkYScgfCAnbW9iaWxlJztcbiAgc291cmNlRnVsbFBhdGg/OiBzdHJpbmc7XG4gIHNvdXJjZVBhdGg/OiBzdHJpbmc7XG4gIHRhcmdldEVudmlyb25tZW50PzogJ25vZGUnIHwgJ3dlYic7XG4gIHVzZUdyYXBoUWw/OiBib29sZWFuO1xuICB1c2VUeXBlc2NyaXB0PzogYm9vbGVhbjtcbiAgd2VicGFjaz86IFdlYnBhY2tDb25maWc7XG59XG5cbmV4cG9ydCB0eXBlIENvbmZpZyA9IExleENvbmZpZ1R5cGU7XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0Q29uZmlnVmFsdWVzOiBMZXhDb25maWdUeXBlID0ge1xuICBhaToge1xuICAgIHByb3ZpZGVyOiAnbm9uZScsXG4gICAgbW9kZWw6ICdncHQtNG8nLFxuICAgIG1heFRva2VuczogNDAwMCxcbiAgICB0ZW1wZXJhdHVyZTogMC4xXG4gIH0sXG4gIGNvbmZpZ0ZpbGVzOiBbXSxcbiAgY29weUZpbGVzOiBbXSxcbiAgZW50cnlIVE1MOiAnaW5kZXguaHRtbCcsXG4gIGVudHJ5SnM6ICdpbmRleC5qcycsXG4gIGVzbGludDoge30sXG4gIGVzYnVpbGQ6IHtcbiAgICBtaW5pZnk6IHRydWUsXG4gICAgdHJlZVNoYWtpbmc6IHRydWUsXG4gICAgZHJvcDogWydjb25zb2xlJywgJ2RlYnVnZ2VyJ10sXG4gICAgcHVyZTogWydjb25zb2xlLmxvZycsICdjb25zb2xlLndhcm4nLCAnY29uc29sZS5lcnJvciddLFxuICAgIGxlZ2FsQ29tbWVudHM6ICdub25lJyxcbiAgICBzcGxpdHRpbmc6IHRydWUsXG4gICAgbWV0YWZpbGU6IGZhbHNlLFxuICAgIHNvdXJjZW1hcDogZmFsc2VcbiAgfSxcbiAgZW52OiBudWxsLFxuICBqZXN0OiB7fSxcbiAgb3V0cHV0RnVsbFBhdGg6IHBhdGhSZXNvbHZlKGN3ZCwgJy4vZGlzdCcpLFxuICBvdXRwdXRIYXNoOiBmYWxzZSxcbiAgb3V0cHV0UGF0aDogJy4vZGlzdCcsXG4gIHBhY2thZ2VNYW5hZ2VyOiAnbnBtJyxcbiAgcHJlc2V0OiAnd2ViJyxcbiAgc291cmNlRnVsbFBhdGg6IHBhdGhSZXNvbHZlKGN3ZCwgJy4vc3JjJyksXG4gIHNvdXJjZVBhdGg6ICcuL3NyYycsXG4gIHRhcmdldEVudmlyb25tZW50OiAnd2ViJyxcbiAgdXNlR3JhcGhRbDogZmFsc2UsXG4gIHVzZVR5cGVzY3JpcHQ6IGZhbHNlLFxuICB3ZWJwYWNrOiB7fVxufTtcblxuZnVuY3Rpb24gZmluZExleFJvb3Qoc3RhcnREaXI6IHN0cmluZyk6IHN0cmluZyB7XG4gIGxldCBkaXIgPSBzdGFydERpcjtcbiAgd2hpbGUoZGlyICE9PSAnLycgJiYgZGlyICE9PSAnLicpIHtcbiAgICBjb25zdCBwa2dQYXRoID0gcGF0aFJlc29sdmUoZGlyLCAncGFja2FnZS5qc29uJyk7XG4gICAgaWYoZXhpc3RzU3luYyhwa2dQYXRoKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGtnID0gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMocGtnUGF0aCwgJ3V0ZjgnKSk7XG4gICAgICAgIGlmKHBrZy5uYW1lID09PSAnQG5sYWJzL2xleCcpIHtcbiAgICAgICAgICByZXR1cm4gZGlyO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoe31cbiAgICB9XG4gICAgY29uc3QgcGFyZW50ID0gZGlybmFtZShkaXIpO1xuICAgIGlmKHBhcmVudCA9PT0gZGlyKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgZGlyID0gcGFyZW50O1xuICB9XG4gIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGZpbmQgQG5sYWJzL2xleCByb290Jyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aChjb25maWdOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBjd2QgPSBwcm9jZXNzLmN3ZCgpO1xuXG4gIGlmKGNvbmZpZ05hbWUgPT09ICd0c2NvbmZpZy5idWlsZC5qc29uJykge1xuICAgIGNvbnN0IHByb2plY3RCdWlsZENvbmZpZyA9IHBhdGhSZXNvbHZlKGN3ZCwgJ3RzY29uZmlnLmJ1aWxkLmpzb24nKTtcbiAgICBpZihleGlzdHNTeW5jKHByb2plY3RCdWlsZENvbmZpZykpIHtcbiAgICAgIHJldHVybiBwcm9qZWN0QnVpbGRDb25maWc7XG4gICAgfVxuICB9XG5cbiAgaWYoY29uZmlnTmFtZSA9PT0gJ3RzY29uZmlnLmxpbnQuanNvbicpIHtcbiAgICBjb25zdCBwcm9qZWN0TGludENvbmZpZyA9IHBhdGhSZXNvbHZlKGN3ZCwgJ3RzY29uZmlnLmVzbGludC5qc29uJyk7XG4gICAgaWYoZXhpc3RzU3luYyhwcm9qZWN0TGludENvbmZpZykpIHtcbiAgICAgIHJldHVybiBwcm9qZWN0TGludENvbmZpZztcbiAgICB9XG4gIH1cblxuICBpZihjb25maWdOYW1lID09PSAndHNjb25maWcudGVzdC5qc29uJykge1xuICAgIGNvbnN0IHByb2plY3RUZXN0Q29uZmlnID0gcGF0aFJlc29sdmUoY3dkLCAndHNjb25maWcudGVzdC5qc29uJyk7XG4gICAgaWYoZXhpc3RzU3luYyhwcm9qZWN0VGVzdENvbmZpZykpIHtcbiAgICAgIHJldHVybiBwcm9qZWN0VGVzdENvbmZpZztcbiAgICB9XG4gIH1cblxuICBjb25zdCBwcm9qZWN0Q29uZmlnUGF0aCA9IHBhdGhSZXNvbHZlKGN3ZCwgY29uZmlnTmFtZSk7XG4gIGlmKGV4aXN0c1N5bmMocHJvamVjdENvbmZpZ1BhdGgpKSB7XG4gICAgcmV0dXJuIHByb2plY3RDb25maWdQYXRoO1xuICB9XG5cbiAgY29uc3QgbGV4RGlyID0gTGV4Q29uZmlnLmdldExleERpcigpO1xuICByZXR1cm4gcGF0aFJlc29sdmUobGV4RGlyLCBjb25maWdOYW1lKTtcbn1cblxuZXhwb3J0IGNsYXNzIExleENvbmZpZyB7XG4gIHN0YXRpYyBjb25maWc6IExleENvbmZpZ1R5cGUgPSB7XG4gICAgLi4uZGVmYXVsdENvbmZpZ1ZhbHVlc1xuICB9O1xuXG4gIHN0YXRpYyBnZXRMZXhEaXIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZGlybmFtZShnZXRMZXhQYWNrYWdlSnNvblBhdGgoKSk7XG4gIH1cblxuICBzdGF0aWMgc2V0IHVzZVR5cGVzY3JpcHQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICBMZXhDb25maWcuY29uZmlnLnVzZVR5cGVzY3JpcHQgPSB2YWx1ZTtcbiAgICBjb25zdCB7c291cmNlRnVsbFBhdGh9ID0gTGV4Q29uZmlnLmNvbmZpZztcblxuICAgIGNvbnN0IHtlbnRyeUpzfSA9IExleENvbmZpZy5jb25maWc7XG5cbiAgICBpZihlbnRyeUpzID09PSAnaW5kZXguanMnICYmIHZhbHVlKSB7XG4gICAgICBjb25zdCBpbmRleFBhdGg6IHN0cmluZyA9IHBhdGhSZXNvbHZlKGN3ZCwgc291cmNlRnVsbFBhdGgsICdpbmRleC50c3gnKTtcbiAgICAgIGNvbnN0IGhhc0luZGV4VHN4OiBib29sZWFuID0gZXhpc3RzU3luYyhpbmRleFBhdGgpO1xuXG4gICAgICBpZihoYXNJbmRleFRzeCkge1xuICAgICAgICBMZXhDb25maWcuY29uZmlnLmVudHJ5SnMgPSAnaW5kZXgudHN4JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIExleENvbmZpZy5jb25maWcuZW50cnlKcyA9ICdpbmRleC50cyc7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHVwZGF0ZUNvbmZpZyh1cGRhdGVkQ29uZmlnOiBMZXhDb25maWdUeXBlKTogTGV4Q29uZmlnVHlwZSB7XG4gICAgY29uc3Qge291dHB1dEZ1bGxQYXRoLCBvdXRwdXRQYXRoLCBzb3VyY2VQYXRoLCBzb3VyY2VGdWxsUGF0aCwgdXNlVHlwZXNjcmlwdCwgYWl9ID0gdXBkYXRlZENvbmZpZztcbiAgICBjb25zdCBjd2Q6IHN0cmluZyA9IHByb2Nlc3MuY3dkKCk7XG5cbiAgICBpZih1c2VUeXBlc2NyaXB0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIExleENvbmZpZy51c2VUeXBlc2NyaXB0ID0gdXNlVHlwZXNjcmlwdDtcbiAgICB9XG5cbiAgICBpZihvdXRwdXRQYXRoICE9PSB1bmRlZmluZWQgJiYgb3V0cHV0RnVsbFBhdGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgdXBkYXRlZENvbmZpZy5vdXRwdXRGdWxsUGF0aCA9IHBhdGhSZXNvbHZlKGN3ZCwgb3V0cHV0UGF0aCk7XG4gICAgfVxuXG4gICAgaWYoc291cmNlUGF0aCAhPT0gdW5kZWZpbmVkICYmIHNvdXJjZUZ1bGxQYXRoID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHVwZGF0ZWRDb25maWcuc291cmNlRnVsbFBhdGggPSBwYXRoUmVzb2x2ZShjd2QsIHNvdXJjZVBhdGgpO1xuICAgIH1cblxuICAgIGlmKGFpKSB7XG4gICAgICBMZXhDb25maWcuY29uZmlnLmFpID0gey4uLkxleENvbmZpZy5jb25maWcuYWksIC4uLmFpfTtcblxuICAgICAgaWYocHJvY2Vzcy5lbnYuQ1VSU09SX0lERSA9PT0gJ3RydWUnICYmIExleENvbmZpZy5jb25maWcuYWkucHJvdmlkZXIgPT09ICdub25lJykge1xuICAgICAgICBMZXhDb25maWcuY29uZmlnLmFpLnByb3ZpZGVyID0gJ2N1cnNvcic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgTGV4Q29uZmlnLmNvbmZpZyA9IHsuLi5MZXhDb25maWcuY29uZmlnLCAuLi51cGRhdGVkQ29uZmlnfTtcblxuICAgIHJldHVybiBMZXhDb25maWcuY29uZmlnO1xuICB9XG5cbiAgc3RhdGljIGFkZENvbmZpZ1BhcmFtcyhjbWQsIHBhcmFtczogTGV4Q29uZmlnVHlwZSkge1xuICAgIGNvbnN0IG5hbWVQcm9wZXJ0eTogc3RyaW5nID0gJ19uYW1lJztcbiAgICBjb25zdCB7ZW52aXJvbm1lbnQsIG91dHB1dFBhdGgsIHNvdXJjZVBhdGgsIHR5cGVzY3JpcHR9ID0gY21kO1xuXG4gICAgaWYob3V0cHV0UGF0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYXJhbXMub3V0cHV0UGF0aCA9IG91dHB1dFBhdGg7XG4gICAgICBwYXJhbXMub3V0cHV0RnVsbFBhdGggPSBwYXRoUmVzb2x2ZShjd2QsIG91dHB1dFBhdGgpO1xuICAgIH1cblxuICAgIGlmKHNvdXJjZVBhdGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFyYW1zLnNvdXJjZVBhdGggPSBzb3VyY2VQYXRoO1xuICAgICAgcGFyYW1zLnNvdXJjZUZ1bGxQYXRoID0gcGF0aFJlc29sdmUoY3dkLCBzb3VyY2VQYXRoKTtcbiAgICB9XG5cbiAgICBpZih0eXBlc2NyaXB0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhcmFtcy51c2VUeXBlc2NyaXB0ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZihlbnZpcm9ubWVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYXJhbXMudGFyZ2V0RW52aXJvbm1lbnQgPSBlbnZpcm9ubWVudCA9PT0gJ3dlYicgPyAnd2ViJyA6ICdub2RlJztcbiAgICB9XG5cbiAgICBwcm9jZXNzLmVudi5MRVhfQ09ORklHID0gSlNPTi5zdHJpbmdpZnkoXG4gICAgICB7XG4gICAgICAgIC4uLkxleENvbmZpZy51cGRhdGVDb25maWcocGFyYW1zKSxcbiAgICAgICAgY29tbWFuZE5hbWU6IGNtZFtuYW1lUHJvcGVydHldLFxuICAgICAgICBpc1N0YXRpYzogY21kLnN0YXRpY1xuICAgICAgfSwgbnVsbCwgMFxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgcGFyc2VDb25maWcoY21kLCBpc1Jvb3Q6IGJvb2xlYW4gPSB0cnVlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qge2NsaU5hbWUgPSAnTGV4JywgbGV4Q29uZmlnLCBsZXhDb25maWdOYW1lLCBxdWlldCwgdHlwZXNjcmlwdCwgZGVidWcgPSBmYWxzZX0gPSBjbWQ7XG4gICAgY29uc3QgY29uZmlnRm9ybWF0cyA9IFsnanMnLCAnbWpzJywgJ2NqcycsICd0cycsICdqc29uJ107XG4gICAgY29uc3QgY29uZmlnQmFzZU5hbWU6IHN0cmluZyA9IGxleENvbmZpZ05hbWUgfHwgJ2xleC5jb25maWcnO1xuICAgIGxldCBjb25maWdQYXRoOiBzdHJpbmcgPSBsZXhDb25maWcgfHwgJyc7XG4gICAgbGV0IGNvbmZpZ0V4aXN0czogYm9vbGVhbiA9IGxleENvbmZpZyA/IGV4aXN0c1N5bmMoY29uZmlnUGF0aCkgOiBmYWxzZTtcblxuICAgIGlmKCFjb25maWdQYXRoIHx8ICFjb25maWdFeGlzdHMpIHtcbiAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgIGxvZyhgU2VhcmNoaW5nIGZvciBjb25maWcgZmlsZXMgd2l0aCBiYXNlIG5hbWU6ICR7Y29uZmlnQmFzZU5hbWV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIGZvcihjb25zdCBmb3JtYXQgb2YgY29uZmlnRm9ybWF0cykge1xuICAgICAgICBjb25zdCBwb3RlbnRpYWxQYXRoID0gaXNSb290XG4gICAgICAgICAgPyBwYXRoUmVzb2x2ZShjd2QsIGAuLyR7Y29uZmlnQmFzZU5hbWV9LiR7Zm9ybWF0fWApXG4gICAgICAgICAgOiByZWxhdGl2ZUZpbGVQYXRoKGAke2NvbmZpZ0Jhc2VOYW1lfS4ke2Zvcm1hdH1gLCBjd2QpO1xuXG4gICAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgICAgbG9nKGBDaGVja2luZyBmb3IgY29uZmlnIGZpbGU6ICR7cG90ZW50aWFsUGF0aH1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKGV4aXN0c1N5bmMocG90ZW50aWFsUGF0aCkpIHtcbiAgICAgICAgICBjb25maWdQYXRoID0gcG90ZW50aWFsUGF0aDtcbiAgICAgICAgICBjb25maWdFeGlzdHMgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYoY29uZmlnRXhpc3RzKSB7XG4gICAgICBsb2coYFVzaW5nICR7Y2xpTmFtZX0gY29uZmlndXJhdGlvbiBmaWxlOiAke2NvbmZpZ1BhdGh9YCwgJ25vdGUnLCBxdWlldCk7XG4gICAgICBjb25zdCBleHQ6IHN0cmluZyA9IHBhdGhFeHRuYW1lKGNvbmZpZ1BhdGgpO1xuXG4gICAgICBpZihleHQgPT09ICcuanNvbicpIHtcbiAgICAgICAgY29uc3QgY29uZmlnQ29udGVudDogc3RyaW5nID0gcmVhZEZpbGVTeW5jKGNvbmZpZ1BhdGgsICd1dGY4Jyk7XG5cbiAgICAgICAgaWYoY29uZmlnQ29udGVudCkge1xuICAgICAgICAgIGxldCBjb25maWdKc29uOiBMZXhDb25maWdUeXBlO1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbmZpZ0pzb24gPSBKU09OLnBhcnNlKGNvbmZpZ0NvbnRlbnQpPy5kZWZhdWx0IHx8IHt9O1xuICAgICAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogRmFpbGVkIHRvIHBhcnNlIEpTT04gY29uZmlnOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgICAgICAgICAgY29uZmlnSnNvbiA9IHt9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIExleENvbmZpZy5hZGRDb25maWdQYXJhbXMoY21kLCBjb25maWdKc29uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IENvbmZpZyBmaWxlIG1hbGZvcm1lZCwgJHtjb25maWdQYXRofWAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmKFsnLmpzJywgJy5tanMnLCAnLmNqcycsICcudHMnXS5pbmNsdWRlcyhleHQpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbGV0IGxleEN1c3RvbUNvbmZpZztcblxuICAgICAgICAgIGlmKGV4dCA9PT0gJy5janMnKSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlVXJsID0gbmV3IFVSTChgZmlsZTovLy8ke3BhdGhSZXNvbHZlKGNvbmZpZ1BhdGgpfWApLmhyZWY7XG5cbiAgICAgICAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgICAgICAgIGxvZyhgTG9hZGluZyBDb21tb25KUyBjb25maWcgZnJvbTogJHtmaWxlVXJsfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV4Q3VzdG9tQ29uZmlnID0gYXdhaXQgaW1wb3J0KGZpbGVVcmwpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgICAgICBsb2coYExvYWRpbmcgRVNNL1RTIGNvbmZpZyBmcm9tOiAke2NvbmZpZ1BhdGh9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxleEN1c3RvbUNvbmZpZyA9IGF3YWl0IGltcG9ydChjb25maWdQYXRoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBjb25maWcgPSBsZXhDdXN0b21Db25maWcuZGVmYXVsdCB8fCBsZXhDdXN0b21Db25maWc7XG5cbiAgICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgICAgbG9nKGBMb2FkZWQgY29uZmlnOiAke0pTT04uc3RyaW5naWZ5KGNvbmZpZywgbnVsbCwgMil9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYoIWNvbmZpZykge1xuICAgICAgICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IFdhcm5pbmc6IENvbmZpZyBmaWxlIGxvYWRlZCBidXQgbm8gY29uZmlndXJhdGlvbiBmb3VuZGAsICd3YXJuJywgcXVpZXQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIExleENvbmZpZy5hZGRDb25maWdQYXJhbXMoY21kLCBjb25maWcgfHwge30pO1xuICAgICAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiBGYWlsZWQgdG8gbG9hZCBjb25maWcgZmlsZTogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IENvbmZpZyBmaWxlIG11c3QgYmUgYSBKUywgQ0pTLCBNSlMsIFRTLCBvciBKU09OIGZpbGUuYCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coJ05vIGNvbmZpZyBmaWxlIGZvdW5kLiBVc2luZyBkZWZhdWx0IGNvbmZpZ3VyYXRpb24uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIExleENvbmZpZy51c2VUeXBlc2NyaXB0ID0gISF0eXBlc2NyaXB0O1xuICAgICAgTGV4Q29uZmlnLmFkZENvbmZpZ1BhcmFtcyhjbWQsIExleENvbmZpZy5jb25maWcpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBjaGVja1R5cGVzY3JpcHRDb25maWcoKSB7XG4gICAgY29uc3QgdHNjb25maWdQYXRoOiBzdHJpbmcgPSBwYXRoUmVzb2x2ZShjd2QsICcuL3RzY29uZmlnLmpzb24nKTtcblxuICAgIGlmKCFleGlzdHNTeW5jKHRzY29uZmlnUGF0aCkpIHtcbiAgICAgIGNvbnN0IGRpck5hbWUgPSBnZXREaXJOYW1lKCk7XG4gICAgICB3cml0ZUZpbGVTeW5jKHRzY29uZmlnUGF0aCwgcmVhZEZpbGVTeW5jKHBhdGhSZXNvbHZlKGRpck5hbWUsICcuLi8uLi8uLi90c2NvbmZpZy5iYXNlLmpzb24nKSkpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBjaGVja0NvbXBpbGVUeXBlc2NyaXB0Q29uZmlnKCkge1xuICAgIGNvbnN0IGxleERpciA9IExleENvbmZpZy5nZXRMZXhEaXIoKTtcbiAgICBjb25zdCB0c2NvbmZpZ0NvbXBpbGVQYXRoOiBzdHJpbmcgPSBwYXRoUmVzb2x2ZShsZXhEaXIsICcuL3RzY29uZmlnLmJ1aWxkLmpzb24nKTtcblxuICAgIGlmKCFleGlzdHNTeW5jKHRzY29uZmlnQ29tcGlsZVBhdGgpKSB7XG4gICAgICBjb25zdCB0ZW1wbGF0ZVBhdGggPSBwYXRoUmVzb2x2ZShsZXhEaXIsICd0c2NvbmZpZy5idWlsZC5qc29uJyk7XG4gICAgICBpZihleGlzdHNTeW5jKHRlbXBsYXRlUGF0aCkpIHtcbiAgICAgICAgd3JpdGVGaWxlU3luYyh0c2NvbmZpZ0NvbXBpbGVQYXRoLCByZWFkRmlsZVN5bmModGVtcGxhdGVQYXRoKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGNoZWNrTGludFR5cGVzY3JpcHRDb25maWcoKSB7XG4gICAgY29uc3QgbGV4RGlyID0gTGV4Q29uZmlnLmdldExleERpcigpO1xuICAgIGNvbnN0IHRzY29uZmlnTGludFBhdGg6IHN0cmluZyA9IHBhdGhSZXNvbHZlKGxleERpciwgJy4vdHNjb25maWcubGludC5qc29uJyk7XG5cbiAgICBpZighZXhpc3RzU3luYyh0c2NvbmZpZ0xpbnRQYXRoKSkge1xuICAgICAgY29uc3QgdGVtcGxhdGVQYXRoID0gcGF0aFJlc29sdmUobGV4RGlyLCAndHNjb25maWcubGludC5qc29uJyk7XG4gICAgICBpZihleGlzdHNTeW5jKHRlbXBsYXRlUGF0aCkpIHtcbiAgICAgICAgd3JpdGVGaWxlU3luYyh0c2NvbmZpZ0xpbnRQYXRoLCByZWFkRmlsZVN5bmModGVtcGxhdGVQYXRoKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGNoZWNrVGVzdFR5cGVzY3JpcHRDb25maWcoKSB7XG4gICAgY29uc3QgbGV4RGlyID0gTGV4Q29uZmlnLmdldExleERpcigpO1xuICAgIGNvbnN0IHRzY29uZmlnVGVzdFBhdGg6IHN0cmluZyA9IHBhdGhSZXNvbHZlKGxleERpciwgJy4vdHNjb25maWcudGVzdC5qc29uJyk7XG5cbiAgICBpZighZXhpc3RzU3luYyh0c2NvbmZpZ1Rlc3RQYXRoKSkge1xuICAgICAgY29uc3QgdGVtcGxhdGVQYXRoID0gcGF0aFJlc29sdmUobGV4RGlyLCAndHNjb25maWcudGVzdC5qc29uJyk7XG4gICAgICBpZihleGlzdHNTeW5jKHRlbXBsYXRlUGF0aCkpIHtcbiAgICAgICAgd3JpdGVGaWxlU3luYyh0c2NvbmZpZ1Rlc3RQYXRoLCByZWFkRmlsZVN5bmModGVtcGxhdGVQYXRoKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59Il0sCiAgIm1hcHBpbmdzIjogIkFBSUEsU0FBUSxZQUFZ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
|