@nlabs/lex 1.49.4 → 1.50.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/.swcrc +35 -0
- package/README.md +43 -59
- package/__mocks__/chalk.js +19 -17
- package/config.json +32 -8
- package/examples/lex.config.js +110 -10
- package/index.cjs +1 -5
- package/lex.config.js +34 -7
- package/lib/Button.stories.js +99 -0
- package/lib/LexConfig.d.ts +60 -22
- package/lib/LexConfig.js +285 -244
- package/lib/commands/ai/ai.js +287 -288
- package/lib/commands/ai/index.js +8 -7
- package/lib/commands/build/build.d.ts +2 -2
- package/lib/commands/build/build.js +349 -458
- package/lib/commands/clean/clean.js +45 -33
- package/lib/commands/compile/compile.js +214 -227
- package/lib/commands/config/config.js +46 -42
- package/lib/commands/copy/copy.js +36 -35
- package/lib/commands/create/create.js +200 -121
- package/lib/commands/dev/dev.d.ts +2 -0
- package/lib/commands/dev/dev.js +259 -263
- package/lib/commands/init/init.js +108 -88
- package/lib/commands/link/link.js +18 -14
- package/lib/commands/lint/lint.js +735 -742
- package/lib/commands/migrate/migrate.js +49 -36
- package/lib/commands/publish/publish.js +116 -96
- package/lib/commands/serverless/serverless.js +611 -585
- package/lib/commands/storybook/storybook.js +242 -238
- package/lib/commands/test/test.d.ts +1 -1
- package/lib/commands/test/test.js +382 -394
- package/lib/commands/update/update.js +141 -120
- package/lib/commands/upgrade/upgrade.js +51 -44
- package/lib/commands/versions/versions.d.ts +1 -1
- package/lib/commands/versions/versions.js +36 -38
- package/lib/create/changelog.js +136 -125
- package/lib/index.js +40 -38
- package/lib/lex.js +95 -68
- package/lib/storybook/index.js +6 -1
- package/lib/test-react/index.js +7 -84
- package/lib/types.d.ts +1 -1
- package/lib/types.js +7 -1
- package/lib/utils/aiService.js +240 -227
- package/lib/utils/app.js +274 -273
- package/lib/utils/deepMerge.js +37 -23
- package/lib/utils/file.js +218 -215
- package/lib/utils/log.js +29 -27
- package/lib/utils/reactShim.js +7 -85
- package/lib/utils/translations.js +91 -65
- package/package.json +63 -64
- package/templates/typescript/DataLayer.js.txt +218 -0
- package/templates/typescript/DataLayer.test.js.txt +268 -0
- package/templates/typescript/DataLayer.test.ts.txt +269 -0
- package/templates/typescript/DataLayer.ts.txt +227 -0
- package/webpack.config.js +53 -26
- package/lib/commands/lint/autofix.d.ts +0 -2
|
@@ -1,399 +1,390 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2018-Present, Nitrogen Labs, Inc.
|
|
3
|
+
* Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
|
|
4
|
+
*/ import { execa } from 'execa';
|
|
5
|
+
import { existsSync, readFileSync } from 'fs';
|
|
6
|
+
import { sync as globSync } from 'glob';
|
|
7
|
+
import { resolve as pathResolve } from 'path';
|
|
8
|
+
import { LexConfig, getTypeScriptConfigPath } from '../../LexConfig.js';
|
|
9
|
+
import { createSpinner } from '../../utils/app.js';
|
|
10
|
+
import { resolveBinaryPath } from '../../utils/file.js';
|
|
11
|
+
import { log } from '../../utils/log.js';
|
|
12
|
+
import { aiFunction } from '../ai/ai.js';
|
|
13
|
+
const detectESM = (cwd)=>{
|
|
14
|
+
const packageJsonPath = pathResolve(cwd, 'package.json');
|
|
15
|
+
if (existsSync(packageJsonPath)) {
|
|
16
|
+
try {
|
|
17
|
+
const packageJsonContent = readFileSync(packageJsonPath, 'utf8');
|
|
18
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
19
|
+
return packageJson.type === 'module';
|
|
20
|
+
} catch (_error) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
19
23
|
}
|
|
20
|
-
|
|
21
|
-
return false;
|
|
24
|
+
return false;
|
|
22
25
|
};
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return [testPathPattern];
|
|
26
|
+
const defaultExit = (code)=>{
|
|
27
|
+
if (process.env.JEST_WORKER_ID || process.env.NODE_ENV === 'test') {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
process.exit(code);
|
|
29
31
|
};
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
32
|
+
export const getTestFilePatterns = (testPathPattern)=>{
|
|
33
|
+
const defaultPatterns = [
|
|
34
|
+
'**/*.test.*',
|
|
35
|
+
'**/*.spec.*',
|
|
36
|
+
'**/*.integration.*'
|
|
37
|
+
];
|
|
38
|
+
if (!testPathPattern) {
|
|
39
|
+
return defaultPatterns;
|
|
40
|
+
}
|
|
41
|
+
return [
|
|
42
|
+
testPathPattern
|
|
43
|
+
];
|
|
43
44
|
};
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
const findUncoveredSourceFiles = ()=>{
|
|
46
|
+
const sourceFiles = globSync('src/**/*.{ts,tsx,js,jsx}', {
|
|
47
|
+
cwd: process.cwd(),
|
|
48
|
+
ignore: [
|
|
49
|
+
'**/node_modules/**',
|
|
50
|
+
'**/dist/**',
|
|
51
|
+
'**/lib/**',
|
|
52
|
+
'**/*.test.*',
|
|
53
|
+
'**/*.spec.*'
|
|
54
|
+
]
|
|
55
|
+
});
|
|
56
|
+
const testFiles = globSync('**/*.{test,spec}.{ts,tsx,js,jsx}', {
|
|
57
|
+
cwd: process.cwd(),
|
|
58
|
+
ignore: [
|
|
59
|
+
'**/node_modules/**',
|
|
60
|
+
'**/dist/**',
|
|
61
|
+
'**/lib/**'
|
|
62
|
+
]
|
|
63
|
+
});
|
|
64
|
+
return sourceFiles.filter((sourceFile)=>{
|
|
65
|
+
const baseName = sourceFile.replace(/\.[^/.]+$/, '');
|
|
66
|
+
return !testFiles.some((testFile)=>testFile.includes(baseName));
|
|
67
|
+
});
|
|
54
68
|
};
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
aiAnalyze = false,
|
|
59
|
-
aiDebug = false,
|
|
60
|
-
aiGenerate = false,
|
|
61
|
-
bail,
|
|
62
|
-
changedFilesWithAncestor,
|
|
63
|
-
changedSince,
|
|
64
|
-
ci,
|
|
65
|
-
cliName = "Lex",
|
|
66
|
-
collectCoverageFrom,
|
|
67
|
-
colors,
|
|
68
|
-
config,
|
|
69
|
-
debug = false,
|
|
70
|
-
debugTests = false,
|
|
71
|
-
detectOpenHandles,
|
|
72
|
-
env,
|
|
73
|
-
errorOnDeprecated,
|
|
74
|
-
expand,
|
|
75
|
-
forceExit,
|
|
76
|
-
generate = false,
|
|
77
|
-
json,
|
|
78
|
-
lastCommit,
|
|
79
|
-
listTests,
|
|
80
|
-
logHeapUsage,
|
|
81
|
-
maxWorkers,
|
|
82
|
-
noStackTrace,
|
|
83
|
-
notify,
|
|
84
|
-
onlyChanged,
|
|
85
|
-
outputFile,
|
|
86
|
-
passWithNoTests,
|
|
87
|
-
quiet,
|
|
88
|
-
removeCache,
|
|
89
|
-
runInBand,
|
|
90
|
-
setup,
|
|
91
|
-
showConfig,
|
|
92
|
-
silent,
|
|
93
|
-
testLocationInResults,
|
|
94
|
-
testNamePattern,
|
|
95
|
-
testPathPattern,
|
|
96
|
-
update,
|
|
97
|
-
useStderr,
|
|
98
|
-
verbose,
|
|
99
|
-
watch,
|
|
100
|
-
watchAll
|
|
101
|
-
} = options;
|
|
102
|
-
const useGenerate = generate || aiGenerate;
|
|
103
|
-
const useAnalyze = analyze || aiAnalyze;
|
|
104
|
-
const useDebug = debugTests || aiDebug;
|
|
105
|
-
log(`${cliName} testing...`, "info", quiet);
|
|
106
|
-
const spinner = createSpinner(quiet);
|
|
107
|
-
await LexConfig.parseConfig(options);
|
|
108
|
-
const { useTypescript } = LexConfig.config;
|
|
109
|
-
if (useTypescript) {
|
|
110
|
-
const testConfigPath = getTypeScriptConfigPath("tsconfig.test.json");
|
|
111
|
-
if (existsSync(testConfigPath)) {
|
|
112
|
-
log("Using tsconfig.test.json for testing...", "info", quiet);
|
|
113
|
-
} else {
|
|
114
|
-
LexConfig.checkTestTypescriptConfig();
|
|
69
|
+
const processTestResults = (outputFile)=>{
|
|
70
|
+
if (!outputFile) {
|
|
71
|
+
return null;
|
|
115
72
|
}
|
|
116
|
-
}
|
|
117
|
-
if (useGenerate) {
|
|
118
|
-
spinner.start("AI is analyzing code to generate test cases...");
|
|
119
73
|
try {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
task: "test"
|
|
133
|
-
});
|
|
134
|
-
spinner.succeed(`AI test generation suggestions provided for ${targetFile}`);
|
|
135
|
-
} else {
|
|
136
|
-
spinner.succeed("All source files appear to have corresponding test files");
|
|
137
|
-
}
|
|
138
|
-
} catch (aiError) {
|
|
139
|
-
spinner.fail("Could not generate AI test suggestions");
|
|
140
|
-
if (!quiet) {
|
|
141
|
-
console.error("AI test generation error:", aiError);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
const dirName = getDirName();
|
|
146
|
-
const projectJestBin = pathResolve(process.cwd(), "node_modules/.bin/jest");
|
|
147
|
-
let jestPath;
|
|
148
|
-
if (existsSync(projectJestBin)) {
|
|
149
|
-
jestPath = projectJestBin;
|
|
150
|
-
} else {
|
|
151
|
-
jestPath = resolveBinaryPath("jest");
|
|
152
|
-
}
|
|
153
|
-
if (!jestPath) {
|
|
154
|
-
log(`
|
|
155
|
-
${cliName} Error: Jest binary not found in Lex's node_modules or monorepo root`, "error", quiet);
|
|
156
|
-
log("Please reinstall Lex or check your installation.", "info", quiet);
|
|
157
|
-
return 1;
|
|
158
|
-
}
|
|
159
|
-
let jestConfigFile;
|
|
160
|
-
let projectJestConfig = null;
|
|
161
|
-
if (config) {
|
|
162
|
-
jestConfigFile = config;
|
|
163
|
-
} else {
|
|
164
|
-
const projectJestConfigPath = pathResolve(process.cwd(), "jest.config.js");
|
|
165
|
-
const projectJestConfigCjsPath = pathResolve(process.cwd(), "jest.config.cjs");
|
|
166
|
-
const projectJestConfigMjsPath = pathResolve(process.cwd(), "jest.config.mjs");
|
|
167
|
-
const projectJestConfigJsonPath = pathResolve(process.cwd(), "jest.config.json");
|
|
168
|
-
if (existsSync(projectJestConfigPath)) {
|
|
169
|
-
jestConfigFile = projectJestConfigPath;
|
|
170
|
-
if (debug) {
|
|
171
|
-
log(`Using project Jest config file: ${jestConfigFile}`, "info", quiet);
|
|
172
|
-
}
|
|
173
|
-
} else if (existsSync(projectJestConfigCjsPath)) {
|
|
174
|
-
jestConfigFile = projectJestConfigCjsPath;
|
|
175
|
-
if (debug) {
|
|
176
|
-
log(`Using project Jest config file (CJS): ${jestConfigFile}`, "info", quiet);
|
|
177
|
-
}
|
|
178
|
-
} else if (existsSync(projectJestConfigMjsPath)) {
|
|
179
|
-
jestConfigFile = projectJestConfigMjsPath;
|
|
180
|
-
if (debug) {
|
|
181
|
-
log(`Using project Jest config file (MJS): ${jestConfigFile}`, "info", quiet);
|
|
182
|
-
}
|
|
183
|
-
} else if (existsSync(projectJestConfigJsonPath)) {
|
|
184
|
-
jestConfigFile = projectJestConfigJsonPath;
|
|
185
|
-
if (debug) {
|
|
186
|
-
log(`Using project Jest config file (JSON): ${jestConfigFile}`, "info", quiet);
|
|
187
|
-
}
|
|
74
|
+
const content = readFileSync(outputFile, 'utf-8');
|
|
75
|
+
return JSON.parse(content);
|
|
76
|
+
} catch (_error) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
export const test = async (options, args, filesOrCallback, callbackParam)=>{
|
|
81
|
+
// Backward-compat argument normalization: allow callback as third param
|
|
82
|
+
let files;
|
|
83
|
+
let callback = defaultExit;
|
|
84
|
+
if (typeof filesOrCallback === 'function') {
|
|
85
|
+
callback = filesOrCallback;
|
|
188
86
|
} else {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
87
|
+
files = filesOrCallback;
|
|
88
|
+
callback = callbackParam || defaultExit;
|
|
89
|
+
}
|
|
90
|
+
const { analyze = false, aiAnalyze = false, aiDebug = false, aiGenerate = false, bail, changedFilesWithAncestor, changedSince, ci, cliName = 'Lex', collectCoverageFrom, colors, config, debug = false, debugTests = false, detectOpenHandles, env, errorOnDeprecated, expand, forceExit, generate = false, json, lastCommit, listTests, logHeapUsage, maxWorkers, noStackTrace, notify, onlyChanged, outputFile, passWithNoTests, quiet, removeCache, runInBand, setup, showConfig, silent, testLocationInResults, testNamePattern, testPathPattern, update, useStderr, verbose, watch, watchAll } = options;
|
|
91
|
+
const useGenerate = generate || aiGenerate;
|
|
92
|
+
const useAnalyze = analyze || aiAnalyze;
|
|
93
|
+
const useDebug = debugTests || aiDebug;
|
|
94
|
+
log(`${cliName} testing...`, 'info', quiet);
|
|
95
|
+
const spinner = createSpinner(quiet);
|
|
96
|
+
await LexConfig.parseConfig(options);
|
|
97
|
+
const { useTypescript } = LexConfig.config;
|
|
98
|
+
if (useTypescript) {
|
|
99
|
+
const testConfigPath = getTypeScriptConfigPath('tsconfig.test.json');
|
|
100
|
+
if (existsSync(testConfigPath)) {
|
|
101
|
+
log('Using tsconfig.test.json for testing...', 'info', quiet);
|
|
202
102
|
} else {
|
|
203
|
-
|
|
204
|
-
log(`Using Lex Jest config (no project Jest config found): ${jestConfigFile}`, "info", quiet);
|
|
205
|
-
}
|
|
103
|
+
LexConfig.checkTestTypescriptConfig();
|
|
206
104
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
105
|
+
}
|
|
106
|
+
if (useGenerate) {
|
|
107
|
+
spinner.start('AI is analyzing code to generate test cases...');
|
|
108
|
+
try {
|
|
109
|
+
const uncoveredFiles = findUncoveredSourceFiles();
|
|
110
|
+
if (uncoveredFiles.length > 0) {
|
|
111
|
+
const targetFile = uncoveredFiles[0];
|
|
112
|
+
await aiFunction({
|
|
113
|
+
context: true,
|
|
114
|
+
file: targetFile,
|
|
115
|
+
prompt: `Generate Jest unit tests for this file: ${targetFile}\n\n${readFileSync(targetFile, 'utf-8')}\n\nPlease create comprehensive tests that cover the main functionality. Include test fixtures and mocks where necessary.`,
|
|
116
|
+
quiet,
|
|
117
|
+
task: 'test'
|
|
118
|
+
});
|
|
119
|
+
spinner.succeed(`AI test generation suggestions provided for ${targetFile}`);
|
|
120
|
+
} else {
|
|
121
|
+
spinner.succeed('All source files appear to have corresponding test files');
|
|
122
|
+
}
|
|
123
|
+
} catch (aiError) {
|
|
124
|
+
spinner.fail('Could not generate AI test suggestions');
|
|
125
|
+
if (!quiet) {
|
|
126
|
+
// eslint-disable-next-line no-console
|
|
127
|
+
console.error('AI test generation error:', aiError);
|
|
128
|
+
}
|
|
210
129
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
jestOptions
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
130
|
+
}
|
|
131
|
+
const projectJestBin = pathResolve(process.cwd(), 'node_modules/.bin/jest');
|
|
132
|
+
let jestPath;
|
|
133
|
+
if (existsSync(projectJestBin)) {
|
|
134
|
+
jestPath = projectJestBin;
|
|
135
|
+
} else {
|
|
136
|
+
jestPath = resolveBinaryPath('jest');
|
|
137
|
+
}
|
|
138
|
+
if (!jestPath) {
|
|
139
|
+
log(`\n${cliName} Error: Jest binary not found in Lex's node_modules or monorepo root`, 'error', quiet);
|
|
140
|
+
log('Please reinstall Lex or check your installation.', 'info', quiet);
|
|
141
|
+
return 1;
|
|
142
|
+
}
|
|
143
|
+
let jestConfigFile;
|
|
144
|
+
let projectJestConfig = null;
|
|
145
|
+
if (config) {
|
|
146
|
+
jestConfigFile = config;
|
|
147
|
+
} else {
|
|
148
|
+
const projectJestConfigPath = pathResolve(process.cwd(), 'jest.config.js');
|
|
149
|
+
const projectJestConfigCjsPath = pathResolve(process.cwd(), 'jest.config.cjs');
|
|
150
|
+
const projectJestConfigMjsPath = pathResolve(process.cwd(), 'jest.config.mjs');
|
|
151
|
+
const projectJestConfigJsonPath = pathResolve(process.cwd(), 'jest.config.json');
|
|
152
|
+
if (existsSync(projectJestConfigPath)) {
|
|
153
|
+
jestConfigFile = projectJestConfigPath;
|
|
154
|
+
if (debug) {
|
|
155
|
+
log(`Using project Jest config file: ${jestConfigFile}`, 'info', quiet);
|
|
156
|
+
}
|
|
157
|
+
} else if (existsSync(projectJestConfigCjsPath)) {
|
|
158
|
+
jestConfigFile = projectJestConfigCjsPath;
|
|
159
|
+
if (debug) {
|
|
160
|
+
log(`Using project Jest config file (CJS): ${jestConfigFile}`, 'info', quiet);
|
|
161
|
+
}
|
|
162
|
+
} else if (existsSync(projectJestConfigMjsPath)) {
|
|
163
|
+
jestConfigFile = projectJestConfigMjsPath;
|
|
164
|
+
if (debug) {
|
|
165
|
+
log(`Using project Jest config file (MJS): ${jestConfigFile}`, 'info', quiet);
|
|
166
|
+
}
|
|
167
|
+
} else if (existsSync(projectJestConfigJsonPath)) {
|
|
168
|
+
jestConfigFile = projectJestConfigJsonPath;
|
|
169
|
+
if (debug) {
|
|
170
|
+
log(`Using project Jest config file (JSON): ${jestConfigFile}`, 'info', quiet);
|
|
171
|
+
}
|
|
172
|
+
} else {
|
|
173
|
+
// No Jest config file exists in the project
|
|
174
|
+
// Check if there's a Jest config in lex.config.cjs
|
|
175
|
+
projectJestConfig = LexConfig.config.jest;
|
|
176
|
+
const lexDir = LexConfig.getLexDir();
|
|
177
|
+
const lexJestConfig = pathResolve(lexDir, 'jest.config.mjs');
|
|
178
|
+
if (debug) {
|
|
179
|
+
log(`Looking for Jest config at: ${lexJestConfig}`, 'info', quiet);
|
|
180
|
+
log(`File exists: ${existsSync(lexJestConfig)}`, 'info', quiet);
|
|
181
|
+
}
|
|
182
|
+
if (existsSync(lexJestConfig)) {
|
|
183
|
+
jestConfigFile = lexJestConfig;
|
|
184
|
+
if (projectJestConfig && Object.keys(projectJestConfig).length > 0) {
|
|
185
|
+
if (debug) {
|
|
186
|
+
log(`Using Lex Jest config with project Jest config from lex.config.cjs: ${jestConfigFile}`, 'info', quiet);
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
if (debug) {
|
|
190
|
+
log(`Using Lex Jest config (no project Jest config found): ${jestConfigFile}`, 'info', quiet);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
if (debug) {
|
|
195
|
+
log('No Jest config found in project or Lex', 'warn', quiet);
|
|
196
|
+
}
|
|
197
|
+
jestConfigFile = '';
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const jestSetupFile = setup || pathResolve(process.cwd(), 'jest.setup.js');
|
|
202
|
+
const jestOptions = [
|
|
203
|
+
'--no-cache'
|
|
204
|
+
];
|
|
205
|
+
const isESM = detectESM(process.cwd());
|
|
206
|
+
let nodeOptions = process.env.NODE_OPTIONS || '';
|
|
207
|
+
if (isESM) {
|
|
208
|
+
if (!nodeOptions.includes('--experimental-vm-modules')) {
|
|
209
|
+
nodeOptions = `${nodeOptions} --experimental-vm-modules`.trim();
|
|
210
|
+
}
|
|
211
|
+
log('ESM project detected, using --experimental-vm-modules in NODE_OPTIONS', 'info', quiet);
|
|
212
|
+
}
|
|
213
|
+
if (jestConfigFile) {
|
|
214
|
+
jestOptions.push('--config', jestConfigFile);
|
|
215
|
+
}
|
|
216
|
+
if (bail) {
|
|
217
|
+
jestOptions.push('--bail');
|
|
218
|
+
}
|
|
219
|
+
if (changedFilesWithAncestor) {
|
|
220
|
+
jestOptions.push('--changedFilesWithAncestor');
|
|
221
|
+
}
|
|
222
|
+
if (changedSince) {
|
|
223
|
+
jestOptions.push('--changedSince');
|
|
224
|
+
}
|
|
225
|
+
if (ci) {
|
|
226
|
+
jestOptions.push('--ci');
|
|
227
|
+
}
|
|
228
|
+
if (collectCoverageFrom) {
|
|
229
|
+
jestOptions.push('--collectCoverageFrom', collectCoverageFrom);
|
|
230
|
+
}
|
|
231
|
+
if (colors) {
|
|
232
|
+
jestOptions.push('--colors');
|
|
233
|
+
}
|
|
234
|
+
if (debug) {
|
|
235
|
+
jestOptions.push('--debug');
|
|
236
|
+
}
|
|
237
|
+
if (detectOpenHandles) {
|
|
238
|
+
jestOptions.push('--detectOpenHandles');
|
|
239
|
+
}
|
|
240
|
+
if (env) {
|
|
241
|
+
jestOptions.push('--env');
|
|
242
|
+
}
|
|
243
|
+
if (errorOnDeprecated) {
|
|
244
|
+
jestOptions.push('--errorOnDeprecated');
|
|
245
|
+
}
|
|
246
|
+
if (expand) {
|
|
247
|
+
jestOptions.push('--expand');
|
|
248
|
+
}
|
|
249
|
+
if (forceExit) {
|
|
250
|
+
jestOptions.push('--forceExit');
|
|
251
|
+
}
|
|
252
|
+
if (json) {
|
|
253
|
+
jestOptions.push('--json');
|
|
254
|
+
}
|
|
255
|
+
if (lastCommit) {
|
|
256
|
+
jestOptions.push('--lastCommit');
|
|
257
|
+
}
|
|
258
|
+
if (listTests) {
|
|
259
|
+
jestOptions.push('--listTests');
|
|
260
|
+
}
|
|
261
|
+
if (logHeapUsage) {
|
|
262
|
+
jestOptions.push('--logHeapUsage');
|
|
263
|
+
}
|
|
264
|
+
if (maxWorkers) {
|
|
265
|
+
jestOptions.push('--maxWorkers', maxWorkers);
|
|
266
|
+
}
|
|
267
|
+
if (noStackTrace) {
|
|
268
|
+
jestOptions.push('--noStackTrace');
|
|
269
|
+
}
|
|
270
|
+
if (notify) {
|
|
271
|
+
jestOptions.push('--notify');
|
|
272
|
+
}
|
|
273
|
+
if (onlyChanged) {
|
|
274
|
+
jestOptions.push('--onlyChanged');
|
|
275
|
+
}
|
|
276
|
+
let tempOutputFile = outputFile;
|
|
277
|
+
if ((useAnalyze || useDebug) && !outputFile) {
|
|
278
|
+
tempOutputFile = '.lex-test-results.json';
|
|
279
|
+
jestOptions.push('--json', '--outputFile', tempOutputFile);
|
|
280
|
+
} else if (outputFile) {
|
|
281
|
+
jestOptions.push('--outputFile', outputFile);
|
|
282
|
+
}
|
|
283
|
+
if (passWithNoTests) {
|
|
284
|
+
jestOptions.push('--passWithNoTests');
|
|
285
|
+
}
|
|
286
|
+
if (runInBand) {
|
|
287
|
+
jestOptions.push('--runInBand');
|
|
288
|
+
}
|
|
289
|
+
if (showConfig) {
|
|
290
|
+
jestOptions.push('--showConfig');
|
|
291
|
+
}
|
|
292
|
+
if (silent) {
|
|
293
|
+
jestOptions.push('--silent');
|
|
294
|
+
}
|
|
295
|
+
if (testLocationInResults) {
|
|
296
|
+
jestOptions.push('--testLocationInResults');
|
|
297
|
+
}
|
|
298
|
+
if (testNamePattern) {
|
|
299
|
+
jestOptions.push('--testNamePattern', testNamePattern);
|
|
300
|
+
}
|
|
301
|
+
if (testPathPattern) {
|
|
302
|
+
jestOptions.push('--testPathPattern', testPathPattern);
|
|
303
|
+
}
|
|
304
|
+
if (useStderr) {
|
|
305
|
+
jestOptions.push('--useStderr');
|
|
306
|
+
}
|
|
307
|
+
if (verbose) {
|
|
308
|
+
jestOptions.push('--verbose');
|
|
309
|
+
}
|
|
310
|
+
if (watchAll) {
|
|
311
|
+
jestOptions.push('--watchAll');
|
|
312
|
+
}
|
|
313
|
+
if (removeCache) {
|
|
314
|
+
jestOptions.push('--no-cache');
|
|
315
|
+
}
|
|
316
|
+
if (jestSetupFile && existsSync(jestSetupFile)) {
|
|
317
|
+
jestOptions.push(`--setupFilesAfterEnv=${jestSetupFile}`);
|
|
318
|
+
}
|
|
319
|
+
if (update) {
|
|
320
|
+
jestOptions.push('--updateSnapshot');
|
|
321
|
+
}
|
|
322
|
+
if (watch) {
|
|
323
|
+
jestOptions.push('--watch', watch);
|
|
324
|
+
}
|
|
325
|
+
if (args) {
|
|
326
|
+
jestOptions.push(...args);
|
|
327
|
+
}
|
|
328
|
+
if (files && files.length > 0) {
|
|
329
|
+
jestOptions.push(...files);
|
|
330
|
+
}
|
|
331
|
+
if (debug) {
|
|
332
|
+
log(`Jest options: ${jestOptions.join(' ')}`, 'info', quiet);
|
|
333
|
+
log(`NODE_OPTIONS: ${nodeOptions}`, 'info', quiet);
|
|
334
|
+
}
|
|
335
|
+
try {
|
|
336
|
+
const env = {
|
|
337
|
+
...process.env,
|
|
338
|
+
NODE_OPTIONS: nodeOptions
|
|
339
|
+
};
|
|
340
|
+
await execa(jestPath, jestOptions, {
|
|
341
|
+
encoding: 'utf8',
|
|
342
|
+
env,
|
|
343
|
+
stdio: 'inherit'
|
|
344
|
+
});
|
|
345
|
+
spinner.succeed('Testing completed!');
|
|
346
|
+
if (useAnalyze) {
|
|
347
|
+
spinner.start('AI is analyzing test coverage and suggesting improvements...');
|
|
348
|
+
try {
|
|
349
|
+
const testResults = processTestResults(tempOutputFile);
|
|
350
|
+
const filePatterns = getTestFilePatterns(testPathPattern);
|
|
351
|
+
await aiFunction({
|
|
352
|
+
context: true,
|
|
353
|
+
prompt: `Analyze these Jest test results and suggest test coverage improvements:
|
|
362
354
|
|
|
363
355
|
${JSON.stringify(testResults, null, 2)}
|
|
364
356
|
|
|
365
|
-
Test patterns: ${filePatterns.join(
|
|
357
|
+
Test patterns: ${filePatterns.join(', ')}
|
|
366
358
|
|
|
367
359
|
Please provide:
|
|
368
360
|
1. Analysis of current coverage gaps
|
|
369
361
|
2. Suggestions for improving test cases
|
|
370
362
|
3. Recommendations for additional integration test scenarios
|
|
371
363
|
4. Best practices for increasing test effectiveness`,
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
364
|
+
quiet,
|
|
365
|
+
task: 'optimize'
|
|
366
|
+
});
|
|
367
|
+
spinner.succeed('AI test analysis complete');
|
|
368
|
+
} catch (aiError) {
|
|
369
|
+
spinner.fail('Could not generate AI test analysis');
|
|
370
|
+
if (!quiet) {
|
|
371
|
+
// eslint-disable-next-line no-console
|
|
372
|
+
console.error('AI analysis error:', aiError);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
381
375
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
await aiFunction({
|
|
395
|
-
context: true,
|
|
396
|
-
prompt: `Debug these failed Jest tests and suggest fixes:
|
|
376
|
+
callback(0);
|
|
377
|
+
return 0;
|
|
378
|
+
} catch (error) {
|
|
379
|
+
log(`\n${cliName} Error: Check for unit test errors and/or coverage.`, 'error', quiet);
|
|
380
|
+
spinner.fail('Testing failed!');
|
|
381
|
+
if (useDebug) {
|
|
382
|
+
spinner.start('AI is analyzing test failures...');
|
|
383
|
+
try {
|
|
384
|
+
const testResults = processTestResults(tempOutputFile);
|
|
385
|
+
await aiFunction({
|
|
386
|
+
context: true,
|
|
387
|
+
prompt: `Debug these failed Jest tests and suggest fixes:
|
|
397
388
|
|
|
398
389
|
${JSON.stringify(error.message, null, 2)}
|
|
399
390
|
|
|
@@ -404,25 +395,22 @@ Please provide:
|
|
|
404
395
|
2. Specific suggestions to fix each failing test
|
|
405
396
|
3. Any potential issues with test fixtures or mocks
|
|
406
397
|
4. Code examples for solutions`,
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
398
|
+
quiet,
|
|
399
|
+
task: 'help'
|
|
400
|
+
});
|
|
401
|
+
spinner.succeed('AI debugging assistance complete');
|
|
402
|
+
} catch (aiError) {
|
|
403
|
+
spinner.fail('Could not generate AI debugging assistance');
|
|
404
|
+
if (!quiet) {
|
|
405
|
+
// eslint-disable-next-line no-console
|
|
406
|
+
console.error('AI debugging error:', aiError);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
415
409
|
}
|
|
416
|
-
|
|
410
|
+
callback(1);
|
|
411
|
+
return 1;
|
|
417
412
|
}
|
|
418
|
-
callback(1);
|
|
419
|
-
return 1;
|
|
420
|
-
}
|
|
421
413
|
};
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
test_default as default,
|
|
425
|
-
getTestFilePatterns,
|
|
426
|
-
test
|
|
427
|
-
};
|
|
428
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL3Rlc3QvdGVzdC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhlY2F9IGZyb20gJ2V4ZWNhJztcbmltcG9ydCB7ZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jfSBmcm9tICdmcyc7XG5pbXBvcnQge3N5bmMgYXMgZ2xvYlN5bmN9IGZyb20gJ2dsb2InO1xuaW1wb3J0IHtyZXNvbHZlIGFzIHBhdGhSZXNvbHZlfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IHtMZXhDb25maWcsIGdldFR5cGVTY3JpcHRDb25maWdQYXRofSBmcm9tICcuLi8uLi9MZXhDb25maWcuanMnO1xuaW1wb3J0IHtjcmVhdGVTcGlubmVyfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtnZXREaXJOYW1lLCByZXNvbHZlQmluYXJ5UGF0aH0gZnJvbSAnLi4vLi4vdXRpbHMvZmlsZS5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJztcbmltcG9ydCB7YWlGdW5jdGlvbn0gZnJvbSAnLi4vYWkvYWkuanMnO1xuXG5jb25zdCBkZXRlY3RFU00gPSAoY3dkOiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gcGF0aFJlc29sdmUoY3dkLCAncGFja2FnZS5qc29uJyk7XG5cbiAgaWYoZXhpc3RzU3luYyhwYWNrYWdlSnNvblBhdGgpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhY2thZ2VKc29uQ29udGVudCA9IHJlYWRGaWxlU3luYyhwYWNrYWdlSnNvblBhdGgsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwYWNrYWdlSnNvbiA9IEpTT04ucGFyc2UocGFja2FnZUpzb25Db250ZW50KTtcbiAgICAgIHJldHVybiBwYWNrYWdlSnNvbi50eXBlID09PSAnbW9kdWxlJztcbiAgICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFRlc3RPcHRpb25zIHtcbiAgcmVhZG9ubHkgYW5hbHl6ZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGFpRGVidWc/OiBib29sZWFuO1xuICByZWFkb25seSBhaUdlbmVyYXRlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgYWlBbmFseXplPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgYmFpbD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNoYW5nZWRGaWxlc1dpdGhBbmNlc3Rvcj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNoYW5nZWRTaW5jZT86IHN0cmluZztcbiAgcmVhZG9ubHkgY2k/OiBib29sZWFuO1xuICByZWFkb25seSBjbGlOYW1lPzogc3RyaW5nO1xuICByZWFkb25seSBjb2xsZWN0Q292ZXJhZ2VGcm9tPzogc3RyaW5nO1xuICByZWFkb25seSBjb2xvcnM/OiBib29sZWFuO1xuICByZWFkb25seSBjb25maWc/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRlYnVnPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZGVidWdUZXN0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGRldGVjdE9wZW5IYW5kbGVzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZW52Pzogc3RyaW5nO1xuICByZWFkb25seSBlcnJvck9uRGVwcmVjYXRlZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGV4cGFuZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGZvcmNlRXhpdD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGdlbmVyYXRlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkganNvbj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGxhc3RDb21taXQ/OiBib29sZWFuO1xuICByZWFkb25seSBsaXN0VGVzdHM/OiBib29sZWFuO1xuICByZWFkb25seSBsb2dIZWFwVXNhZ2U/OiBib29sZWFuO1xuICByZWFkb25seSBtYXhXb3JrZXJzPzogc3RyaW5nO1xuICByZWFkb25seSBub1N0YWNrVHJhY2U/OiBib29sZWFuO1xuICByZWFkb25seSBub3RpZnk/OiBib29sZWFuO1xuICByZWFkb25seSBvbmx5Q2hhbmdlZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IG91dHB1dEZpbGU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHBhc3NXaXRoTm9UZXN0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHF1aWV0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcmVtb3ZlQ2FjaGU/OiBib29sZWFuO1xuICByZWFkb25seSBydW5JbkJhbmQ/OiBib29sZWFuO1xuICByZWFkb25seSBzZXR1cD86IHN0cmluZztcbiAgcmVhZG9ubHkgc2hvd0NvbmZpZz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHNpbGVudD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHRlc3RMb2NhdGlvbkluUmVzdWx0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHRlc3ROYW1lUGF0dGVybj86IHN0cmluZztcbiAgcmVhZG9ubHkgdGVzdFBhdGhQYXR0ZXJuPzogc3RyaW5nO1xuICByZWFkb25seSB1cGRhdGU/OiBib29sZWFuO1xuICByZWFkb25seSB1c2VTdGRlcnI/OiBib29sZWFuO1xuICByZWFkb25seSB2ZXJib3NlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgd2F0Y2g/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHdhdGNoQWxsPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IHR5cGUgVGVzdENhbGxiYWNrID0gdHlwZW9mIHByb2Nlc3MuZXhpdDtcblxuZXhwb3J0IGNvbnN0IGdldFRlc3RGaWxlUGF0dGVybnMgPSAodGVzdFBhdGhQYXR0ZXJuPzogc3RyaW5nKTogc3RyaW5nW10gPT4ge1xuICBjb25zdCBkZWZhdWx0UGF0dGVybnMgPSBbJyoqLyoudGVzdC4qJywgJyoqLyouc3BlYy4qJywgJyoqLyouaW50ZWdyYXRpb24uKiddO1xuXG4gIGlmKCF0ZXN0UGF0aFBhdHRlcm4pIHtcbiAgICByZXR1cm4gZGVmYXVsdFBhdHRlcm5zO1xuICB9XG5cbiAgcmV0dXJuIFt0ZXN0UGF0aFBhdHRlcm5dO1xufTtcblxuY29uc3QgZmluZFVuY292ZXJlZFNvdXJjZUZpbGVzID0gKCk6IHN0cmluZ1tdID0+IHtcbiAgY29uc3Qgc291cmNlRmlsZXMgPSBnbG9iU3luYygnc3JjLyoqLyoue3RzLHRzeCxqcyxqc3h9Jywge1xuICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgICBpZ25vcmU6IFsnKiovbm9kZV9tb2R1bGVzLyoqJywgJyoqL2Rpc3QvKionLCAnKiovbGliLyoqJywgJyoqLyoudGVzdC4qJywgJyoqLyouc3BlYy4qJ11cbiAgfSk7XG5cbiAgY29uc3QgdGVzdEZpbGVzID0gZ2xvYlN5bmMoJyoqLyoue3Rlc3Qsc3BlY30ue3RzLHRzeCxqcyxqc3h9Jywge1xuICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgICBpZ25vcmU6IFsnKiovbm9kZV9tb2R1bGVzLyoqJywgJyoqL2Rpc3QvKionLCAnKiovbGliLyoqJ11cbiAgfSk7XG5cbiAgcmV0dXJuIHNvdXJjZUZpbGVzLmZpbHRlcigoc291cmNlRmlsZSkgPT4ge1xuICAgIGNvbnN0IGJhc2VOYW1lID0gc291cmNlRmlsZS5yZXBsYWNlKC9cXC5bXi8uXSskLywgJycpO1xuICAgIHJldHVybiAhdGVzdEZpbGVzLnNvbWUoKHRlc3RGaWxlKSA9PiB0ZXN0RmlsZS5pbmNsdWRlcyhiYXNlTmFtZSkpO1xuICB9KTtcbn07XG5cbmNvbnN0IHByb2Nlc3NUZXN0UmVzdWx0cyA9IChvdXRwdXRGaWxlPzogc3RyaW5nKTogYW55ID0+IHtcbiAgaWYoIW91dHB1dEZpbGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhvdXRwdXRGaWxlLCAndXRmLTgnKTtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShjb250ZW50KTtcbiAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCB0ZXN0ID0gYXN5bmMgKFxuICBvcHRpb25zOiBUZXN0T3B0aW9ucyxcbiAgYXJnczogc3RyaW5nW10sXG4gIGNhbGxiYWNrOiBUZXN0Q2FsbGJhY2sgPSBwcm9jZXNzLmV4aXRcbik6IFByb21pc2U8bnVtYmVyPiA9PiB7XG4gIGNvbnN0IHtcbiAgICBhbmFseXplID0gZmFsc2UsXG4gICAgYWlBbmFseXplID0gZmFsc2UsXG4gICAgYWlEZWJ1ZyA9IGZhbHNlLFxuICAgIGFpR2VuZXJhdGUgPSBmYWxzZSxcbiAgICBiYWlsLFxuICAgIGNoYW5nZWRGaWxlc1dpdGhBbmNlc3RvcixcbiAgICBjaGFuZ2VkU2luY2UsXG4gICAgY2ksXG4gICAgY2xpTmFtZSA9ICdMZXgnLFxuICAgIGNvbGxlY3RDb3ZlcmFnZUZyb20sXG4gICAgY29sb3JzLFxuICAgIGNvbmZpZyxcbiAgICBkZWJ1ZyA9IGZhbHNlLFxuICAgIGRlYnVnVGVzdHMgPSBmYWxzZSxcbiAgICBkZXRlY3RPcGVuSGFuZGxlcyxcbiAgICBlbnYsXG4gICAgZXJyb3JPbkRlcHJlY2F0ZWQsXG4gICAgZXhwYW5kLFxuICAgIGZvcmNlRXhpdCxcbiAgICBnZW5lcmF0ZSA9IGZhbHNlLFxuICAgIGpzb24sXG4gICAgbGFzdENvbW1pdCxcbiAgICBsaXN0VGVzdHMsXG4gICAgbG9nSGVhcFVzYWdlLFxuICAgIG1heFdvcmtlcnMsXG4gICAgbm9TdGFja1RyYWNlLFxuICAgIG5vdGlmeSxcbiAgICBvbmx5Q2hhbmdlZCxcbiAgICBvdXRwdXRGaWxlLFxuICAgIHBhc3NXaXRoTm9UZXN0cyxcbiAgICBxdWlldCxcbiAgICByZW1vdmVDYWNoZSxcbiAgICBydW5JbkJhbmQsXG4gICAgc2V0dXAsXG4gICAgc2hvd0NvbmZpZyxcbiAgICBzaWxlbnQsXG4gICAgdGVzdExvY2F0aW9uSW5SZXN1bHRzLFxuICAgIHRlc3ROYW1lUGF0dGVybixcbiAgICB0ZXN0UGF0aFBhdHRlcm4sXG4gICAgdXBkYXRlLFxuICAgIHVzZVN0ZGVycixcbiAgICB2ZXJib3NlLFxuICAgIHdhdGNoLFxuICAgIHdhdGNoQWxsXG4gIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IHVzZUdlbmVyYXRlID0gZ2VuZXJhdGUgfHwgYWlHZW5lcmF0ZTtcbiAgY29uc3QgdXNlQW5hbHl6ZSA9IGFuYWx5emUgfHwgYWlBbmFseXplO1xuICBjb25zdCB1c2VEZWJ1ZyA9IGRlYnVnVGVzdHMgfHwgYWlEZWJ1ZztcblxuICBsb2coYCR7Y2xpTmFtZX0gdGVzdGluZy4uLmAsICdpbmZvJywgcXVpZXQpO1xuXG4gIGNvbnN0IHNwaW5uZXIgPSBjcmVhdGVTcGlubmVyKHF1aWV0KTtcblxuICBhd2FpdCBMZXhDb25maWcucGFyc2VDb25maWcob3B0aW9ucyk7XG5cbiAgY29uc3Qge3VzZVR5cGVzY3JpcHR9ID0gTGV4Q29uZmlnLmNvbmZpZztcblxuICBpZih1c2VUeXBlc2NyaXB0KSB7XG4gICAgY29uc3QgdGVzdENvbmZpZ1BhdGggPSBnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aCgndHNjb25maWcudGVzdC5qc29uJyk7XG4gICAgaWYoZXhpc3RzU3luYyh0ZXN0Q29uZmlnUGF0aCkpIHtcbiAgICAgIGxvZygnVXNpbmcgdHNjb25maWcudGVzdC5qc29uIGZvciB0ZXN0aW5nLi4uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIExleENvbmZpZy5jaGVja1Rlc3RUeXBlc2NyaXB0Q29uZmlnKCk7XG4gICAgfVxuICB9XG5cbiAgaWYodXNlR2VuZXJhdGUpIHtcbiAgICBzcGlubmVyLnN0YXJ0KCdBSSBpcyBhbmFseXppbmcgY29kZSB0byBnZW5lcmF0ZSB0ZXN0IGNhc2VzLi4uJyk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdW5jb3ZlcmVkRmlsZXMgPSBmaW5kVW5jb3ZlcmVkU291cmNlRmlsZXMoKTtcblxuICAgICAgaWYodW5jb3ZlcmVkRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCB0YXJnZXRGaWxlID0gdW5jb3ZlcmVkRmlsZXNbMF07XG5cbiAgICAgICAgYXdhaXQgYWlGdW5jdGlvbih7XG4gICAgICAgICAgY29udGV4dDogdHJ1ZSxcbiAgICAgICAgICBmaWxlOiB0YXJnZXRGaWxlLFxuICAgICAgICAgIHByb21wdDogYEdlbmVyYXRlIEplc3QgdW5pdCB0ZXN0cyBmb3IgdGhpcyBmaWxlOiAke3RhcmdldEZpbGV9XFxuXFxuJHtyZWFkRmlsZVN5bmModGFyZ2V0RmlsZSwgJ3V0Zi04Jyl9XFxuXFxuUGxlYXNlIGNyZWF0ZSBjb21wcmVoZW5zaXZlIHRlc3RzIHRoYXQgY292ZXIgdGhlIG1haW4gZnVuY3Rpb25hbGl0eS4gSW5jbHVkZSB0ZXN0IGZpeHR1cmVzIGFuZCBtb2NrcyB3aGVyZSBuZWNlc3NhcnkuYCxcbiAgICAgICAgICBxdWlldCxcbiAgICAgICAgICB0YXNrOiAndGVzdCdcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc3Bpbm5lci5zdWNjZWVkKGBBSSB0ZXN0IGdlbmVyYXRpb24gc3VnZ2VzdGlvbnMgcHJvdmlkZWQgZm9yICR7dGFyZ2V0RmlsZX1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNwaW5uZXIuc3VjY2VlZCgnQWxsIHNvdXJjZSBmaWxlcyBhcHBlYXIgdG8gaGF2ZSBjb3JyZXNwb25kaW5nIHRlc3QgZmlsZXMnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChhaUVycm9yKSB7XG4gICAgICBzcGlubmVyLmZhaWwoJ0NvdWxkIG5vdCBnZW5lcmF0ZSBBSSB0ZXN0IHN1Z2dlc3Rpb25zJyk7XG4gICAgICBpZighcXVpZXQpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgY29uc29sZS5lcnJvcignQUkgdGVzdCBnZW5lcmF0aW9uIGVycm9yOicsIGFpRXJyb3IpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGRpck5hbWUgPSBnZXREaXJOYW1lKCk7XG5cbiAgY29uc3QgcHJvamVjdEplc3RCaW4gPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnbm9kZV9tb2R1bGVzLy5iaW4vamVzdCcpO1xuICBsZXQgamVzdFBhdGg6IHN0cmluZztcblxuICBpZihleGlzdHNTeW5jKHByb2plY3RKZXN0QmluKSkge1xuICAgIGplc3RQYXRoID0gcHJvamVjdEplc3RCaW47XG4gIH0gZWxzZSB7XG4gICAgamVzdFBhdGggPSByZXNvbHZlQmluYXJ5UGF0aCgnamVzdCcpO1xuICB9XG5cbiAgaWYoIWplc3RQYXRoKSB7XG4gICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiBKZXN0IGJpbmFyeSBub3QgZm91bmQgaW4gTGV4J3Mgbm9kZV9tb2R1bGVzIG9yIG1vbm9yZXBvIHJvb3RgLCAnZXJyb3InLCBxdWlldCk7XG4gICAgbG9nKCdQbGVhc2UgcmVpbnN0YWxsIExleCBvciBjaGVjayB5b3VyIGluc3RhbGxhdGlvbi4nLCAnaW5mbycsIHF1aWV0KTtcbiAgICByZXR1cm4gMTtcbiAgfVxuXG4gIGxldCBqZXN0Q29uZmlnRmlsZTogc3RyaW5nO1xuICBsZXQgcHJvamVjdEplc3RDb25maWc6IGFueSA9IG51bGw7XG5cbiAgaWYoY29uZmlnKSB7XG4gICAgamVzdENvbmZpZ0ZpbGUgPSBjb25maWc7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgcHJvamVjdEplc3RDb25maWdQYXRoID0gcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ2plc3QuY29uZmlnLmpzJyk7XG4gICAgY29uc3QgcHJvamVjdEplc3RDb25maWdDanNQYXRoID0gcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ2plc3QuY29uZmlnLmNqcycpO1xuICAgIGNvbnN0IHByb2plY3RKZXN0Q29uZmlnTWpzUGF0aCA9IHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICdqZXN0LmNvbmZpZy5tanMnKTtcbiAgICBjb25zdCBwcm9qZWN0SmVzdENvbmZpZ0pzb25QYXRoID0gcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ2plc3QuY29uZmlnLmpzb24nKTtcblxuICAgIGlmKGV4aXN0c1N5bmMocHJvamVjdEplc3RDb25maWdQYXRoKSkge1xuICAgICAgamVzdENvbmZpZ0ZpbGUgPSBwcm9qZWN0SmVzdENvbmZpZ1BhdGg7XG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coYFVzaW5nIHByb2plY3QgSmVzdCBjb25maWcgZmlsZTogJHtqZXN0Q29uZmlnRmlsZX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYoZXhpc3RzU3luYyhwcm9qZWN0SmVzdENvbmZpZ0Nqc1BhdGgpKSB7XG4gICAgICBqZXN0Q29uZmlnRmlsZSA9IHByb2plY3RKZXN0Q29uZmlnQ2pzUGF0aDtcbiAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgIGxvZyhgVXNpbmcgcHJvamVjdCBKZXN0IGNvbmZpZyBmaWxlIChDSlMpOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZihleGlzdHNTeW5jKHByb2plY3RKZXN0Q29uZmlnTWpzUGF0aCkpIHtcbiAgICAgIGplc3RDb25maWdGaWxlID0gcHJvamVjdEplc3RDb25maWdNanNQYXRoO1xuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBVc2luZyBwcm9qZWN0IEplc3QgY29uZmlnIGZpbGUgKE1KUyk6ICR7amVzdENvbmZpZ0ZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmKGV4aXN0c1N5bmMocHJvamVjdEplc3RDb25maWdKc29uUGF0aCkpIHtcbiAgICAgIGplc3RDb25maWdGaWxlID0gcHJvamVjdEplc3RDb25maWdKc29uUGF0aDtcbiAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgIGxvZyhgVXNpbmcgcHJvamVjdCBKZXN0IGNvbmZpZyBmaWxlIChKU09OKTogJHtqZXN0Q29uZmlnRmlsZX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTm8gSmVzdCBjb25maWcgZmlsZSBleGlzdHMgaW4gdGhlIHByb2plY3RcbiAgICAgIC8vIENoZWNrIGlmIHRoZXJlJ3MgYSBKZXN0IGNvbmZpZyBpbiBsZXguY29uZmlnLmNqc1xuICAgICAgcHJvamVjdEplc3RDb25maWcgPSBMZXhDb25maWcuY29uZmlnLmplc3Q7XG5cbiAgICAgIGNvbnN0IGxleERpciA9IExleENvbmZpZy5nZXRMZXhEaXIoKTtcbiAgICAgIGNvbnN0IGxleEplc3RDb25maWcgPSBwYXRoUmVzb2x2ZShsZXhEaXIsICdqZXN0LmNvbmZpZy5tanMnKTtcblxuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBMb29raW5nIGZvciBKZXN0IGNvbmZpZyBhdDogJHtsZXhKZXN0Q29uZmlnfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICBsb2coYEZpbGUgZXhpc3RzOiAke2V4aXN0c1N5bmMobGV4SmVzdENvbmZpZyl9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIGlmKGV4aXN0c1N5bmMobGV4SmVzdENvbmZpZykpIHtcbiAgICAgICAgamVzdENvbmZpZ0ZpbGUgPSBsZXhKZXN0Q29uZmlnO1xuICAgICAgICBpZihwcm9qZWN0SmVzdENvbmZpZyAmJiBPYmplY3Qua2V5cyhwcm9qZWN0SmVzdENvbmZpZykubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgICAgICBsb2coYFVzaW5nIExleCBKZXN0IGNvbmZpZyB3aXRoIHByb2plY3QgSmVzdCBjb25maWcgZnJvbSBsZXguY29uZmlnLmNqczogJHtqZXN0Q29uZmlnRmlsZX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICAgIGxvZyhgVXNpbmcgTGV4IEplc3QgY29uZmlnIChubyBwcm9qZWN0IEplc3QgY29uZmlnIGZvdW5kKTogJHtqZXN0Q29uZmlnRmlsZX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgICAgbG9nKCdObyBKZXN0IGNvbmZpZyBmb3VuZCBpbiBwcm9qZWN0IG9yIExleCcsICd3YXJuJywgcXVpZXQpO1xuICAgICAgICB9XG4gICAgICAgIGplc3RDb25maWdGaWxlID0gJyc7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgamVzdFNldHVwRmlsZTogc3RyaW5nID0gc2V0dXAgfHwgcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ2plc3Quc2V0dXAuanMnKTtcbiAgY29uc3QgamVzdE9wdGlvbnM6IHN0cmluZ1tdID0gWyctLW5vLWNhY2hlJ107XG5cbiAgY29uc3QgaXNFU00gPSBkZXRlY3RFU00ocHJvY2Vzcy5jd2QoKSk7XG4gIGxldCBub2RlT3B0aW9ucyA9IHByb2Nlc3MuZW52Lk5PREVfT1BUSU9OUyB8fCAnJztcbiAgaWYoaXNFU00pIHtcbiAgICBpZighbm9kZU9wdGlvbnMuaW5jbHVkZXMoJy0tZXhwZXJpbWVudGFsLXZtLW1vZHVsZXMnKSkge1xuICAgICAgbm9kZU9wdGlvbnMgPSBgJHtub2RlT3B0aW9uc30gLS1leHBlcmltZW50YWwtdm0tbW9kdWxlc2AudHJpbSgpO1xuICAgIH1cbiAgICBsb2coJ0VTTSBwcm9qZWN0IGRldGVjdGVkLCB1c2luZyAtLWV4cGVyaW1lbnRhbC12bS1tb2R1bGVzIGluIE5PREVfT1BUSU9OUycsICdpbmZvJywgcXVpZXQpO1xuICB9XG5cbiAgaWYoamVzdENvbmZpZ0ZpbGUpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWNvbmZpZycsIGplc3RDb25maWdGaWxlKTtcbiAgfVxuXG4gIGlmKGJhaWwpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWJhaWwnKTtcbiAgfVxuXG4gIGlmKGNoYW5nZWRGaWxlc1dpdGhBbmNlc3Rvcikge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY2hhbmdlZEZpbGVzV2l0aEFuY2VzdG9yJyk7XG4gIH1cblxuICBpZihjaGFuZ2VkU2luY2UpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWNoYW5nZWRTaW5jZScpO1xuICB9XG5cbiAgaWYoY2kpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWNpJyk7XG4gIH1cblxuICBpZihjb2xsZWN0Q292ZXJhZ2VGcm9tKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1jb2xsZWN0Q292ZXJhZ2VGcm9tJywgY29sbGVjdENvdmVyYWdlRnJvbSk7XG4gIH1cblxuICBpZihjb2xvcnMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWNvbG9ycycpO1xuICB9XG5cbiAgaWYoZGVidWcpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWRlYnVnJyk7XG4gIH1cblxuICBpZihkZXRlY3RPcGVuSGFuZGxlcykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tZGV0ZWN0T3BlbkhhbmRsZXMnKTtcbiAgfVxuXG4gIGlmKGVudikge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tZW52Jyk7XG4gIH1cblxuICBpZihlcnJvck9uRGVwcmVjYXRlZCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tZXJyb3JPbkRlcHJlY2F0ZWQnKTtcbiAgfVxuXG4gIGlmKGV4cGFuZCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tZXhwYW5kJyk7XG4gIH1cblxuICBpZihmb3JjZUV4aXQpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWZvcmNlRXhpdCcpO1xuICB9XG5cbiAgaWYoanNvbikge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tanNvbicpO1xuICB9XG5cbiAgaWYobGFzdENvbW1pdCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tbGFzdENvbW1pdCcpO1xuICB9XG5cbiAgaWYobGlzdFRlc3RzKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1saXN0VGVzdHMnKTtcbiAgfVxuXG4gIGlmKGxvZ0hlYXBVc2FnZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tbG9nSGVhcFVzYWdlJyk7XG4gIH1cblxuICBpZihtYXhXb3JrZXJzKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1tYXhXb3JrZXJzJywgbWF4V29ya2Vycyk7XG4gIH1cblxuICBpZihub1N0YWNrVHJhY2UpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW5vU3RhY2tUcmFjZScpO1xuICB9XG5cbiAgaWYobm90aWZ5KSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1ub3RpZnknKTtcbiAgfVxuXG4gIGlmKG9ubHlDaGFuZ2VkKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1vbmx5Q2hhbmdlZCcpO1xuICB9XG5cbiAgbGV0IHRlbXBPdXRwdXRGaWxlID0gb3V0cHV0RmlsZTtcblxuICBpZigodXNlQW5hbHl6ZSB8fCB1c2VEZWJ1ZykgJiYgIW91dHB1dEZpbGUpIHtcbiAgICB0ZW1wT3V0cHV0RmlsZSA9ICcubGV4LXRlc3QtcmVzdWx0cy5qc29uJztcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWpzb24nLCAnLS1vdXRwdXRGaWxlJywgdGVtcE91dHB1dEZpbGUpO1xuICB9IGVsc2UgaWYob3V0cHV0RmlsZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tb3V0cHV0RmlsZScsIG91dHB1dEZpbGUpO1xuICB9XG5cbiAgaWYocGFzc1dpdGhOb1Rlc3RzKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1wYXNzV2l0aE5vVGVzdHMnKTtcbiAgfVxuXG4gIGlmKHJ1bkluQmFuZCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tcnVuSW5CYW5kJyk7XG4gIH1cblxuICBpZihzaG93Q29uZmlnKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1zaG93Q29uZmlnJyk7XG4gIH1cblxuICBpZihzaWxlbnQpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXNpbGVudCcpO1xuICB9XG5cbiAgaWYodGVzdExvY2F0aW9uSW5SZXN1bHRzKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS10ZXN0TG9jYXRpb25JblJlc3VsdHMnKTtcbiAgfVxuXG4gIGlmKHRlc3ROYW1lUGF0dGVybikge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tdGVzdE5hbWVQYXR0ZXJuJywgdGVzdE5hbWVQYXR0ZXJuKTtcbiAgfVxuXG4gIGlmKHRlc3RQYXRoUGF0dGVybikge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tdGVzdFBhdGhQYXR0ZXJuJywgdGVzdFBhdGhQYXR0ZXJuKTtcbiAgfVxuXG4gIGlmKHVzZVN0ZGVycikge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tdXNlU3RkZXJyJyk7XG4gIH1cblxuICBpZih2ZXJib3NlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS12ZXJib3NlJyk7XG4gIH1cblxuICBpZih3YXRjaEFsbCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0td2F0Y2hBbGwnKTtcbiAgfVxuXG4gIGlmKHJlbW92ZUNhY2hlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1uby1jYWNoZScpO1xuICB9XG5cbiAgaWYoamVzdFNldHVwRmlsZSAmJiBleGlzdHNTeW5jKGplc3RTZXR1cEZpbGUpKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaChgLS1zZXR1cEZpbGVzQWZ0ZXJFbnY9JHtqZXN0U2V0dXBGaWxlfWApO1xuICB9XG5cbiAgaWYodXBkYXRlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS11cGRhdGVTbmFwc2hvdCcpO1xuICB9XG5cbiAgaWYod2F0Y2gpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXdhdGNoJywgd2F0Y2gpO1xuICB9XG5cbiAgaWYoYXJncykge1xuICAgIGplc3RPcHRpb25zLnB1c2goLi4uYXJncyk7XG4gIH1cblxuICBpZihkZWJ1Zykge1xuICAgIGxvZyhgSmVzdCBvcHRpb25zOiAke2plc3RPcHRpb25zLmpvaW4oJyAnKX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICBsb2coYE5PREVfT1BUSU9OUzogJHtub2RlT3B0aW9uc31gLCAnaW5mbycsIHF1aWV0KTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgZW52OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgLi4ucHJvY2Vzcy5lbnYsXG4gICAgICBOT0RFX09QVElPTlM6IG5vZGVPcHRpb25zXG4gICAgfTtcblxuICAgIGF3YWl0IGV4ZWNhKGplc3RQYXRoLCBqZXN0T3B0aW9ucywge1xuICAgICAgZW5jb2Rpbmc6ICd1dGY4JyxcbiAgICAgIHN0ZGlvOiAnaW5oZXJpdCcsXG4gICAgICBlbnZcbiAgICB9KTtcblxuICAgIHNwaW5uZXIuc3VjY2VlZCgnVGVzdGluZyBjb21wbGV0ZWQhJyk7XG5cbiAgICBpZih1c2VBbmFseXplKSB7XG4gICAgICBzcGlubmVyLnN0YXJ0KCdBSSBpcyBhbmFseXppbmcgdGVzdCBjb3ZlcmFnZSBhbmQgc3VnZ2VzdGluZyBpbXByb3ZlbWVudHMuLi4nKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdGVzdFJlc3VsdHMgPSBwcm9jZXNzVGVzdFJlc3VsdHModGVtcE91dHB1dEZpbGUpO1xuICAgICAgICBjb25zdCBmaWxlUGF0dGVybnMgPSBnZXRUZXN0RmlsZVBhdHRlcm5zKHRlc3RQYXRoUGF0dGVybik7XG5cbiAgICAgICAgYXdhaXQgYWlGdW5jdGlvbih7XG4gICAgICAgICAgcHJvbXB0OiBgQW5hbHl6ZSB0aGVzZSBKZXN0IHRlc3QgcmVzdWx0cyBhbmQgc3VnZ2VzdCB0ZXN0IGNvdmVyYWdlIGltcHJvdmVtZW50czpcblxuJHtKU09OLnN0cmluZ2lmeSh0ZXN0UmVzdWx0cywgbnVsbCwgMil9XG5cblRlc3QgcGF0dGVybnM6ICR7ZmlsZVBhdHRlcm5zLmpvaW4oJywgJyl9XG5cblBsZWFzZSBwcm92aWRlOlxuMS4gQW5hbHlzaXMgb2YgY3VycmVudCBjb3ZlcmFnZSBnYXBzXG4yLiBTdWdnZXN0aW9ucyBmb3IgaW1wcm92aW5nIHRlc3QgY2FzZXNcbjMuIFJlY29tbWVuZGF0aW9ucyBmb3IgYWRkaXRpb25hbCBpbnRlZ3JhdGlvbiB0ZXN0IHNjZW5hcmlvc1xuNC4gQmVzdCBwcmFjdGljZXMgZm9yIGluY3JlYXNpbmcgdGVzdCBlZmZlY3RpdmVuZXNzYCxcbiAgICAgICAgICB0YXNrOiAnb3B0aW1pemUnLFxuICAgICAgICAgIGNvbnRleHQ6IHRydWUsXG4gICAgICAgICAgcXVpZXRcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc3Bpbm5lci5zdWNjZWVkKCdBSSB0ZXN0IGFuYWx5c2lzIGNvbXBsZXRlJyk7XG4gICAgICB9IGNhdGNoIChhaUVycm9yKSB7XG4gICAgICAgIHNwaW5uZXIuZmFpbCgnQ291bGQgbm90IGdlbmVyYXRlIEFJIHRlc3QgYW5hbHlzaXMnKTtcbiAgICAgICAgaWYoIXF1aWV0KSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdBSSBhbmFseXNpcyBlcnJvcjonLCBhaUVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNhbGxiYWNrKDApO1xuICAgIHJldHVybiAwO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogQ2hlY2sgZm9yIHVuaXQgdGVzdCBlcnJvcnMgYW5kL29yIGNvdmVyYWdlLmAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgIHNwaW5uZXIuZmFpbCgnVGVzdGluZyBmYWlsZWQhJyk7XG5cbiAgICBpZih1c2VEZWJ1Zykge1xuICAgICAgc3Bpbm5lci5zdGFydCgnQUkgaXMgYW5hbHl6aW5nIHRlc3QgZmFpbHVyZXMuLi4nKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdGVzdFJlc3VsdHMgPSBwcm9jZXNzVGVzdFJlc3VsdHModGVtcE91dHB1dEZpbGUpO1xuXG4gICAgICAgIGF3YWl0IGFpRnVuY3Rpb24oe1xuICAgICAgICAgIGNvbnRleHQ6IHRydWUsXG4gICAgICAgICAgcHJvbXB0OiBgRGVidWcgdGhlc2UgZmFpbGVkIEplc3QgdGVzdHMgYW5kIHN1Z2dlc3QgZml4ZXM6XG5cbiR7SlNPTi5zdHJpbmdpZnkoZXJyb3IubWVzc2FnZSwgbnVsbCwgMil9XG5cblRlc3QgcmVzdWx0czogJHtKU09OLnN0cmluZ2lmeSh0ZXN0UmVzdWx0cywgbnVsbCwgMil9XG5cblBsZWFzZSBwcm92aWRlOlxuMS4gQW5hbHlzaXMgb2Ygd2h5IHRoZSB0ZXN0cyBhcmUgZmFpbGluZ1xuMi4gU3BlY2lmaWMgc3VnZ2VzdGlvbnMgdG8gZml4IGVhY2ggZmFpbGluZyB0ZXN0XG4zLiBBbnkgcG90ZW50aWFsIGlzc3VlcyB3aXRoIHRlc3QgZml4dHVyZXMgb3IgbW9ja3NcbjQuIENvZGUgZXhhbXBsZXMgZm9yIHNvbHV0aW9uc2AsXG4gICAgICAgICAgcXVpZXQsXG4gICAgICAgICAgdGFzazogJ2hlbHAnXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNwaW5uZXIuc3VjY2VlZCgnQUkgZGVidWdnaW5nIGFzc2lzdGFuY2UgY29tcGxldGUnKTtcbiAgICAgIH0gY2F0Y2ggKGFpRXJyb3IpIHtcbiAgICAgICAgc3Bpbm5lci5mYWlsKCdDb3VsZCBub3QgZ2VuZXJhdGUgQUkgZGVidWdnaW5nIGFzc2lzdGFuY2UnKTtcbiAgICAgICAgaWYoIXF1aWV0KSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdBSSBkZWJ1Z2dpbmcgZXJyb3I6JywgYWlFcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjYWxsYmFjaygxKTtcbiAgICByZXR1cm4gMTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgdGVzdDsiXSwKICAibWFwcGluZ3MiOiAiQUFJQSxTQUFRLGFBQVk7QUFDcEIsU0FBUSxZQUFZLG9CQUFtQjtBQUN2QyxTQUFRLFFBQVEsZ0JBQWU7QUFDL0IsU0FBUSxXQUFXLG1CQUFrQjtBQUVyQyxTQUFRLFdBQVcsK0JBQThCO0FBQ2pELFNBQVEscUJBQW9CO0FBQzVCLFNBQVEsWUFBWSx5QkFBd0I7QUFDNUMsU0FBUSxXQUFVO0FBQ2xCLFNBQVEsa0JBQWlCO0FBRXpCLE1BQU0sWUFBWSxDQUFDLFFBQXlCO0FBQzFDLFFBQU0sa0JBQWtCLFlBQVksS0FBSyxjQUFjO0FBRXZELE1BQUcsV0FBVyxlQUFlLEdBQUc7QUFDOUIsUUFBSTtBQUNGLFlBQU0scUJBQXFCLGFBQWEsaUJBQWlCLE1BQU07QUFDL0QsWUFBTSxjQUFjLEtBQUssTUFBTSxrQkFBa0I7QUFDakQsYUFBTyxZQUFZLFNBQVM7QUFBQSxJQUM5QixTQUFTLFFBQVE7QUFDZixhQUFPO0FBQUEsSUFDVDtBQUFBLEVBQ0Y7QUFFQSxTQUFPO0FBQ1Q7QUFtRE8sTUFBTSxzQkFBc0IsQ0FBQyxvQkFBdUM7QUFDekUsUUFBTSxrQkFBa0IsQ0FBQyxlQUFlLGVBQWUsb0JBQW9CO0FBRTNFLE1BQUcsQ0FBQyxpQkFBaUI7QUFDbkIsV0FBTztBQUFBLEVBQ1Q7QUFFQSxTQUFPLENBQUMsZUFBZTtBQUN6QjtBQUVBLE1BQU0sMkJBQTJCLE1BQWdCO0FBQy9DLFFBQU0sY0FBYyxTQUFTLDRCQUE0QjtBQUFBLElBQ3ZELEtBQUssUUFBUSxJQUFJO0FBQUEsSUFDakIsUUFBUSxDQUFDLHNCQUFzQixjQUFjLGFBQWEsZUFBZSxhQUFhO0FBQUEsRUFDeEYsQ0FBQztBQUVELFFBQU0sWUFBWSxTQUFTLG9DQUFvQztBQUFBLElBQzdELEtBQUssUUFBUSxJQUFJO0FBQUEsSUFDakIsUUFBUSxDQUFDLHNCQUFzQixjQUFjLFdB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
|
|
414
|
+
export default test;
|
|
415
|
+
|
|
416
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy90ZXN0L3Rlc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhlY2F9IGZyb20gJ2V4ZWNhJztcbmltcG9ydCB7ZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jfSBmcm9tICdmcyc7XG5pbXBvcnQge3N5bmMgYXMgZ2xvYlN5bmN9IGZyb20gJ2dsb2InO1xuaW1wb3J0IHtyZXNvbHZlIGFzIHBhdGhSZXNvbHZlfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IHtMZXhDb25maWcsIGdldFR5cGVTY3JpcHRDb25maWdQYXRofSBmcm9tICcuLi8uLi9MZXhDb25maWcuanMnO1xuaW1wb3J0IHtjcmVhdGVTcGlubmVyfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtyZXNvbHZlQmluYXJ5UGF0aH0gZnJvbSAnLi4vLi4vdXRpbHMvZmlsZS5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJztcbmltcG9ydCB7YWlGdW5jdGlvbn0gZnJvbSAnLi4vYWkvYWkuanMnO1xuXG5jb25zdCBkZXRlY3RFU00gPSAoY3dkOiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gcGF0aFJlc29sdmUoY3dkLCAncGFja2FnZS5qc29uJyk7XG5cbiAgaWYoZXhpc3RzU3luYyhwYWNrYWdlSnNvblBhdGgpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhY2thZ2VKc29uQ29udGVudCA9IHJlYWRGaWxlU3luYyhwYWNrYWdlSnNvblBhdGgsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwYWNrYWdlSnNvbiA9IEpTT04ucGFyc2UocGFja2FnZUpzb25Db250ZW50KTtcbiAgICAgIHJldHVybiBwYWNrYWdlSnNvbi50eXBlID09PSAnbW9kdWxlJztcbiAgICB9IGNhdGNoKF9lcnJvcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVzdE9wdGlvbnMge1xuICByZWFkb25seSBhbmFseXplPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgYWlEZWJ1Zz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGFpR2VuZXJhdGU/OiBib29sZWFuO1xuICByZWFkb25seSBhaUFuYWx5emU/OiBib29sZWFuO1xuICByZWFkb25seSBiYWlsPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgY2hhbmdlZEZpbGVzV2l0aEFuY2VzdG9yPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgY2hhbmdlZFNpbmNlPzogc3RyaW5nO1xuICByZWFkb25seSBjaT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNsaU5hbWU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNvbGxlY3RDb3ZlcmFnZUZyb20/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNvbG9ycz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNvbmZpZz86IHN0cmluZztcbiAgcmVhZG9ubHkgZGVidWc/OiBib29sZWFuO1xuICByZWFkb25seSBkZWJ1Z1Rlc3RzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZGV0ZWN0T3BlbkhhbmRsZXM/OiBib29sZWFuO1xuICByZWFkb25seSBlbnY/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGVycm9yT25EZXByZWNhdGVkPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZXhwYW5kPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZm9yY2VFeGl0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZ2VuZXJhdGU/OiBib29sZWFuO1xuICByZWFkb25seSBqc29uPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbGFzdENvbW1pdD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGxpc3RUZXN0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGxvZ0hlYXBVc2FnZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IG1heFdvcmtlcnM/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IG5vU3RhY2tUcmFjZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IG5vdGlmeT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IG9ubHlDaGFuZ2VkPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgb3V0cHV0RmlsZT86IHN0cmluZztcbiAgcmVhZG9ubHkgcGFzc1dpdGhOb1Rlc3RzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcXVpZXQ/OiBib29sZWFuO1xuICByZWFkb25seSByZW1vdmVDYWNoZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHJ1bkluQmFuZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHNldHVwPzogc3RyaW5nO1xuICByZWFkb25seSBzaG93Q29uZmlnPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgc2lsZW50PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdGVzdExvY2F0aW9uSW5SZXN1bHRzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdGVzdE5hbWVQYXR0ZXJuPzogc3RyaW5nO1xuICByZWFkb25seSB0ZXN0UGF0aFBhdHRlcm4/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHVwZGF0ZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHVzZVN0ZGVycj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHZlcmJvc2U/OiBib29sZWFuO1xuICByZWFkb25seSB3YXRjaD86IHN0cmluZztcbiAgcmVhZG9ubHkgd2F0Y2hBbGw/OiBib29sZWFuO1xufVxuXG5leHBvcnQgdHlwZSBUZXN0Q2FsbGJhY2sgPSB0eXBlb2YgcHJvY2Vzcy5leGl0O1xuXG5jb25zdCBkZWZhdWx0RXhpdCA9ICgoY29kZT86IG51bWJlcikgPT4ge1xuICBpZihwcm9jZXNzLmVudi5KRVNUX1dPUktFUl9JRCB8fCBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Rlc3QnKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZCBhcyBuZXZlcjtcbiAgfVxuXG4gIHByb2Nlc3MuZXhpdChjb2RlKTtcbn0pIGFzIHR5cGVvZiBwcm9jZXNzLmV4aXQ7XG5cbmV4cG9ydCBjb25zdCBnZXRUZXN0RmlsZVBhdHRlcm5zID0gKHRlc3RQYXRoUGF0dGVybj86IHN0cmluZyk6IHN0cmluZ1tdID0+IHtcbiAgY29uc3QgZGVmYXVsdFBhdHRlcm5zID0gWycqKi8qLnRlc3QuKicsICcqKi8qLnNwZWMuKicsICcqKi8qLmludGVncmF0aW9uLionXTtcblxuICBpZighdGVzdFBhdGhQYXR0ZXJuKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRQYXR0ZXJucztcbiAgfVxuXG4gIHJldHVybiBbdGVzdFBhdGhQYXR0ZXJuXTtcbn07XG5cbmNvbnN0IGZpbmRVbmNvdmVyZWRTb3VyY2VGaWxlcyA9ICgpOiBzdHJpbmdbXSA9PiB7XG4gIGNvbnN0IHNvdXJjZUZpbGVzID0gZ2xvYlN5bmMoJ3NyYy8qKi8qLnt0cyx0c3gsanMsanN4fScsIHtcbiAgICBjd2Q6IHByb2Nlc3MuY3dkKCksXG4gICAgaWdub3JlOiBbJyoqL25vZGVfbW9kdWxlcy8qKicsICcqKi9kaXN0LyoqJywgJyoqL2xpYi8qKicsICcqKi8qLnRlc3QuKicsICcqKi8qLnNwZWMuKiddXG4gIH0pO1xuXG4gIGNvbnN0IHRlc3RGaWxlcyA9IGdsb2JTeW5jKCcqKi8qLnt0ZXN0LHNwZWN9Lnt0cyx0c3gsanMsanN4fScsIHtcbiAgICBjd2Q6IHByb2Nlc3MuY3dkKCksXG4gICAgaWdub3JlOiBbJyoqL25vZGVfbW9kdWxlcy8qKicsICcqKi9kaXN0LyoqJywgJyoqL2xpYi8qKiddXG4gIH0pO1xuXG4gIHJldHVybiBzb3VyY2VGaWxlcy5maWx0ZXIoKHNvdXJjZUZpbGUpID0+IHtcbiAgICBjb25zdCBiYXNlTmFtZSA9IHNvdXJjZUZpbGUucmVwbGFjZSgvXFwuW14vLl0rJC8sICcnKTtcbiAgICByZXR1cm4gIXRlc3RGaWxlcy5zb21lKCh0ZXN0RmlsZSkgPT4gdGVzdEZpbGUuaW5jbHVkZXMoYmFzZU5hbWUpKTtcbiAgfSk7XG59O1xuXG5jb25zdCBwcm9jZXNzVGVzdFJlc3VsdHMgPSAob3V0cHV0RmlsZT86IHN0cmluZyk6IGFueSA9PiB7XG4gIGlmKCFvdXRwdXRGaWxlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IGNvbnRlbnQgPSByZWFkRmlsZVN5bmMob3V0cHV0RmlsZSwgJ3V0Zi04Jyk7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoY29udGVudCk7XG4gIH0gY2F0Y2goX2Vycm9yKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCB0ZXN0ID0gYXN5bmMgKFxuICBvcHRpb25zOiBUZXN0T3B0aW9ucyxcbiAgYXJncz86IHN0cmluZ1tdLFxuICBmaWxlc09yQ2FsbGJhY2s/OiBzdHJpbmdbXSB8IFRlc3RDYWxsYmFjayxcbiAgY2FsbGJhY2tQYXJhbT86IFRlc3RDYWxsYmFja1xuKTogUHJvbWlzZTxudW1iZXI+ID0+IHtcbiAgLy8gQmFja3dhcmQtY29tcGF0IGFyZ3VtZW50IG5vcm1hbGl6YXRpb246IGFsbG93IGNhbGxiYWNrIGFzIHRoaXJkIHBhcmFtXG4gIGxldCBmaWxlczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG4gIGxldCBjYWxsYmFjazogVGVzdENhbGxiYWNrID0gZGVmYXVsdEV4aXQ7XG5cbiAgaWYodHlwZW9mIGZpbGVzT3JDYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gZmlsZXNPckNhbGxiYWNrIGFzIFRlc3RDYWxsYmFjaztcbiAgfSBlbHNlIHtcbiAgICBmaWxlcyA9IGZpbGVzT3JDYWxsYmFjayBhcyBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrUGFyYW0gfHwgZGVmYXVsdEV4aXQ7XG4gIH1cbiAgY29uc3Qge1xuICAgIGFuYWx5emUgPSBmYWxzZSxcbiAgICBhaUFuYWx5emUgPSBmYWxzZSxcbiAgICBhaURlYnVnID0gZmFsc2UsXG4gICAgYWlHZW5lcmF0ZSA9IGZhbHNlLFxuICAgIGJhaWwsXG4gICAgY2hhbmdlZEZpbGVzV2l0aEFuY2VzdG9yLFxuICAgIGNoYW5nZWRTaW5jZSxcbiAgICBjaSxcbiAgICBjbGlOYW1lID0gJ0xleCcsXG4gICAgY29sbGVjdENvdmVyYWdlRnJvbSxcbiAgICBjb2xvcnMsXG4gICAgY29uZmlnLFxuICAgIGRlYnVnID0gZmFsc2UsXG4gICAgZGVidWdUZXN0cyA9IGZhbHNlLFxuICAgIGRldGVjdE9wZW5IYW5kbGVzLFxuICAgIGVudixcbiAgICBlcnJvck9uRGVwcmVjYXRlZCxcbiAgICBleHBhbmQsXG4gICAgZm9yY2VFeGl0LFxuICAgIGdlbmVyYXRlID0gZmFsc2UsXG4gICAganNvbixcbiAgICBsYXN0Q29tbWl0LFxuICAgIGxpc3RUZXN0cyxcbiAgICBsb2dIZWFwVXNhZ2UsXG4gICAgbWF4V29ya2VycyxcbiAgICBub1N0YWNrVHJhY2UsXG4gICAgbm90aWZ5LFxuICAgIG9ubHlDaGFuZ2VkLFxuICAgIG91dHB1dEZpbGUsXG4gICAgcGFzc1dpdGhOb1Rlc3RzLFxuICAgIHF1aWV0LFxuICAgIHJlbW92ZUNhY2hlLFxuICAgIHJ1bkluQmFuZCxcbiAgICBzZXR1cCxcbiAgICBzaG93Q29uZmlnLFxuICAgIHNpbGVudCxcbiAgICB0ZXN0TG9jYXRpb25JblJlc3VsdHMsXG4gICAgdGVzdE5hbWVQYXR0ZXJuLFxuICAgIHRlc3RQYXRoUGF0dGVybixcbiAgICB1cGRhdGUsXG4gICAgdXNlU3RkZXJyLFxuICAgIHZlcmJvc2UsXG4gICAgd2F0Y2gsXG4gICAgd2F0Y2hBbGxcbiAgfSA9IG9wdGlvbnM7XG5cbiAgY29uc3QgdXNlR2VuZXJhdGUgPSBnZW5lcmF0ZSB8fCBhaUdlbmVyYXRlO1xuICBjb25zdCB1c2VBbmFseXplID0gYW5hbHl6ZSB8fCBhaUFuYWx5emU7XG4gIGNvbnN0IHVzZURlYnVnID0gZGVidWdUZXN0cyB8fCBhaURlYnVnO1xuXG4gIGxvZyhgJHtjbGlOYW1lfSB0ZXN0aW5nLi4uYCwgJ2luZm8nLCBxdWlldCk7XG5cbiAgY29uc3Qgc3Bpbm5lciA9IGNyZWF0ZVNwaW5uZXIocXVpZXQpO1xuXG4gIGF3YWl0IExleENvbmZpZy5wYXJzZUNvbmZpZyhvcHRpb25zKTtcblxuICBjb25zdCB7dXNlVHlwZXNjcmlwdH0gPSBMZXhDb25maWcuY29uZmlnO1xuXG4gIGlmKHVzZVR5cGVzY3JpcHQpIHtcbiAgICBjb25zdCB0ZXN0Q29uZmlnUGF0aCA9IGdldFR5cGVTY3JpcHRDb25maWdQYXRoKCd0c2NvbmZpZy50ZXN0Lmpzb24nKTtcbiAgICBpZihleGlzdHNTeW5jKHRlc3RDb25maWdQYXRoKSkge1xuICAgICAgbG9nKCdVc2luZyB0c2NvbmZpZy50ZXN0Lmpzb24gZm9yIHRlc3RpbmcuLi4nLCAnaW5mbycsIHF1aWV0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgTGV4Q29uZmlnLmNoZWNrVGVzdFR5cGVzY3JpcHRDb25maWcoKTtcbiAgICB9XG4gIH1cblxuICBpZih1c2VHZW5lcmF0ZSkge1xuICAgIHNwaW5uZXIuc3RhcnQoJ0FJIGlzIGFuYWx5emluZyBjb2RlIHRvIGdlbmVyYXRlIHRlc3QgY2FzZXMuLi4nKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB1bmNvdmVyZWRGaWxlcyA9IGZpbmRVbmNvdmVyZWRTb3VyY2VGaWxlcygpO1xuXG4gICAgICBpZih1bmNvdmVyZWRGaWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHRhcmdldEZpbGUgPSB1bmNvdmVyZWRGaWxlc1swXTtcblxuICAgICAgICBhd2FpdCBhaUZ1bmN0aW9uKHtcbiAgICAgICAgICBjb250ZXh0OiB0cnVlLFxuICAgICAgICAgIGZpbGU6IHRhcmdldEZpbGUsXG4gICAgICAgICAgcHJvbXB0OiBgR2VuZXJhdGUgSmVzdCB1bml0IHRlc3RzIGZvciB0aGlzIGZpbGU6ICR7dGFyZ2V0RmlsZX1cXG5cXG4ke3JlYWRGaWxlU3luYyh0YXJnZXRGaWxlLCAndXRmLTgnKX1cXG5cXG5QbGVhc2UgY3JlYXRlIGNvbXByZWhlbnNpdmUgdGVzdHMgdGhhdCBjb3ZlciB0aGUgbWFpbiBmdW5jdGlvbmFsaXR5LiBJbmNsdWRlIHRlc3QgZml4dHVyZXMgYW5kIG1vY2tzIHdoZXJlIG5lY2Vzc2FyeS5gLFxuICAgICAgICAgIHF1aWV0LFxuICAgICAgICAgIHRhc2s6ICd0ZXN0J1xuICAgICAgICB9KTtcblxuICAgICAgICBzcGlubmVyLnN1Y2NlZWQoYEFJIHRlc3QgZ2VuZXJhdGlvbiBzdWdnZXN0aW9ucyBwcm92aWRlZCBmb3IgJHt0YXJnZXRGaWxlfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3Bpbm5lci5zdWNjZWVkKCdBbGwgc291cmNlIGZpbGVzIGFwcGVhciB0byBoYXZlIGNvcnJlc3BvbmRpbmcgdGVzdCBmaWxlcycpO1xuICAgICAgfVxuICAgIH0gY2F0Y2goYWlFcnJvcikge1xuICAgICAgc3Bpbm5lci5mYWlsKCdDb3VsZCBub3QgZ2VuZXJhdGUgQUkgdGVzdCBzdWdnZXN0aW9ucycpO1xuICAgICAgaWYoIXF1aWV0KSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0FJIHRlc3QgZ2VuZXJhdGlvbiBlcnJvcjonLCBhaUVycm9yKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBwcm9qZWN0SmVzdEJpbiA9IHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICdub2RlX21vZHVsZXMvLmJpbi9qZXN0Jyk7XG4gIGxldCBqZXN0UGF0aDogc3RyaW5nO1xuXG4gIGlmKGV4aXN0c1N5bmMocHJvamVjdEplc3RCaW4pKSB7XG4gICAgamVzdFBhdGggPSBwcm9qZWN0SmVzdEJpbjtcbiAgfSBlbHNlIHtcbiAgICBqZXN0UGF0aCA9IHJlc29sdmVCaW5hcnlQYXRoKCdqZXN0Jyk7XG4gIH1cblxuICBpZighamVzdFBhdGgpIHtcbiAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IEplc3QgYmluYXJ5IG5vdCBmb3VuZCBpbiBMZXgncyBub2RlX21vZHVsZXMgb3IgbW9ub3JlcG8gcm9vdGAsICdlcnJvcicsIHF1aWV0KTtcbiAgICBsb2coJ1BsZWFzZSByZWluc3RhbGwgTGV4IG9yIGNoZWNrIHlvdXIgaW5zdGFsbGF0aW9uLicsICdpbmZvJywgcXVpZXQpO1xuICAgIHJldHVybiAxO1xuICB9XG5cbiAgbGV0IGplc3RDb25maWdGaWxlOiBzdHJpbmc7XG4gIGxldCBwcm9qZWN0SmVzdENvbmZpZzogYW55ID0gbnVsbDtcblxuICBpZihjb25maWcpIHtcbiAgICBqZXN0Q29uZmlnRmlsZSA9IGNvbmZpZztcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBwcm9qZWN0SmVzdENvbmZpZ1BhdGggPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5jb25maWcuanMnKTtcbiAgICBjb25zdCBwcm9qZWN0SmVzdENvbmZpZ0Nqc1BhdGggPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5jb25maWcuY2pzJyk7XG4gICAgY29uc3QgcHJvamVjdEplc3RDb25maWdNanNQYXRoID0gcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ2plc3QuY29uZmlnLm1qcycpO1xuICAgIGNvbnN0IHByb2plY3RKZXN0Q29uZmlnSnNvblBhdGggPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5jb25maWcuanNvbicpO1xuXG4gICAgaWYoZXhpc3RzU3luYyhwcm9qZWN0SmVzdENvbmZpZ1BhdGgpKSB7XG4gICAgICBqZXN0Q29uZmlnRmlsZSA9IHByb2plY3RKZXN0Q29uZmlnUGF0aDtcbiAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgIGxvZyhgVXNpbmcgcHJvamVjdCBKZXN0IGNvbmZpZyBmaWxlOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZihleGlzdHNTeW5jKHByb2plY3RKZXN0Q29uZmlnQ2pzUGF0aCkpIHtcbiAgICAgIGplc3RDb25maWdGaWxlID0gcHJvamVjdEplc3RDb25maWdDanNQYXRoO1xuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBVc2luZyBwcm9qZWN0IEplc3QgY29uZmlnIGZpbGUgKENKUyk6ICR7amVzdENvbmZpZ0ZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmKGV4aXN0c1N5bmMocHJvamVjdEplc3RDb25maWdNanNQYXRoKSkge1xuICAgICAgamVzdENvbmZpZ0ZpbGUgPSBwcm9qZWN0SmVzdENvbmZpZ01qc1BhdGg7XG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coYFVzaW5nIHByb2plY3QgSmVzdCBjb25maWcgZmlsZSAoTUpTKTogJHtqZXN0Q29uZmlnRmlsZX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYoZXhpc3RzU3luYyhwcm9qZWN0SmVzdENvbmZpZ0pzb25QYXRoKSkge1xuICAgICAgamVzdENvbmZpZ0ZpbGUgPSBwcm9qZWN0SmVzdENvbmZpZ0pzb25QYXRoO1xuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBVc2luZyBwcm9qZWN0IEplc3QgY29uZmlnIGZpbGUgKEpTT04pOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBObyBKZXN0IGNvbmZpZyBmaWxlIGV4aXN0cyBpbiB0aGUgcHJvamVjdFxuICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUncyBhIEplc3QgY29uZmlnIGluIGxleC5jb25maWcuY2pzXG4gICAgICBwcm9qZWN0SmVzdENvbmZpZyA9IExleENvbmZpZy5jb25maWcuamVzdDtcblxuICAgICAgY29uc3QgbGV4RGlyID0gTGV4Q29uZmlnLmdldExleERpcigpO1xuICAgICAgY29uc3QgbGV4SmVzdENvbmZpZyA9IHBhdGhSZXNvbHZlKGxleERpciwgJ2plc3QuY29uZmlnLm1qcycpO1xuXG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coYExvb2tpbmcgZm9yIEplc3QgY29uZmlnIGF0OiAke2xleEplc3RDb25maWd9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgIGxvZyhgRmlsZSBleGlzdHM6ICR7ZXhpc3RzU3luYyhsZXhKZXN0Q29uZmlnKX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIH1cblxuICAgICAgaWYoZXhpc3RzU3luYyhsZXhKZXN0Q29uZmlnKSkge1xuICAgICAgICBqZXN0Q29uZmlnRmlsZSA9IGxleEplc3RDb25maWc7XG4gICAgICAgIGlmKHByb2plY3RKZXN0Q29uZmlnICYmIE9iamVjdC5rZXlzKHByb2plY3RKZXN0Q29uZmlnKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICAgIGxvZyhgVXNpbmcgTGV4IEplc3QgY29uZmlnIHdpdGggcHJvamVjdCBKZXN0IGNvbmZpZyBmcm9tIGxleC5jb25maWcuY2pzOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgICAgbG9nKGBVc2luZyBMZXggSmVzdCBjb25maWcgKG5vIHByb2plY3QgSmVzdCBjb25maWcgZm91bmQpOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICBsb2coJ05vIEplc3QgY29uZmlnIGZvdW5kIGluIHByb2plY3Qgb3IgTGV4JywgJ3dhcm4nLCBxdWlldCk7XG4gICAgICAgIH1cbiAgICAgICAgamVzdENvbmZpZ0ZpbGUgPSAnJztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBqZXN0U2V0dXBGaWxlOiBzdHJpbmcgPSBzZXR1cCB8fCBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5zZXR1cC5qcycpO1xuICBjb25zdCBqZXN0T3B0aW9uczogc3RyaW5nW10gPSBbJy0tbm8tY2FjaGUnXTtcblxuICBjb25zdCBpc0VTTSA9IGRldGVjdEVTTShwcm9jZXNzLmN3ZCgpKTtcbiAgbGV0IG5vZGVPcHRpb25zID0gcHJvY2Vzcy5lbnYuTk9ERV9PUFRJT05TIHx8ICcnO1xuICBpZihpc0VTTSkge1xuICAgIGlmKCFub2RlT3B0aW9ucy5pbmNsdWRlcygnLS1leHBlcmltZW50YWwtdm0tbW9kdWxlcycpKSB7XG4gICAgICBub2RlT3B0aW9ucyA9IGAke25vZGVPcHRpb25zfSAtLWV4cGVyaW1lbnRhbC12bS1tb2R1bGVzYC50cmltKCk7XG4gICAgfVxuICAgIGxvZygnRVNNIHByb2plY3QgZGV0ZWN0ZWQsIHVzaW5nIC0tZXhwZXJpbWVudGFsLXZtLW1vZHVsZXMgaW4gTk9ERV9PUFRJT05TJywgJ2luZm8nLCBxdWlldCk7XG4gIH1cblxuICBpZihqZXN0Q29uZmlnRmlsZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY29uZmlnJywgamVzdENvbmZpZ0ZpbGUpO1xuICB9XG5cbiAgaWYoYmFpbCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tYmFpbCcpO1xuICB9XG5cbiAgaWYoY2hhbmdlZEZpbGVzV2l0aEFuY2VzdG9yKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1jaGFuZ2VkRmlsZXNXaXRoQW5jZXN0b3InKTtcbiAgfVxuXG4gIGlmKGNoYW5nZWRTaW5jZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY2hhbmdlZFNpbmNlJyk7XG4gIH1cblxuICBpZihjaSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY2knKTtcbiAgfVxuXG4gIGlmKGNvbGxlY3RDb3ZlcmFnZUZyb20pIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWNvbGxlY3RDb3ZlcmFnZUZyb20nLCBjb2xsZWN0Q292ZXJhZ2VGcm9tKTtcbiAgfVxuXG4gIGlmKGNvbG9ycykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY29sb3JzJyk7XG4gIH1cblxuICBpZihkZWJ1Zykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tZGVidWcnKTtcbiAgfVxuXG4gIGlmKGRldGVjdE9wZW5IYW5kbGVzKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1kZXRlY3RPcGVuSGFuZGxlcycpO1xuICB9XG5cbiAgaWYoZW52KSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1lbnYnKTtcbiAgfVxuXG4gIGlmKGVycm9yT25EZXByZWNhdGVkKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1lcnJvck9uRGVwcmVjYXRlZCcpO1xuICB9XG5cbiAgaWYoZXhwYW5kKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1leHBhbmQnKTtcbiAgfVxuXG4gIGlmKGZvcmNlRXhpdCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tZm9yY2VFeGl0Jyk7XG4gIH1cblxuICBpZihqc29uKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1qc29uJyk7XG4gIH1cblxuICBpZihsYXN0Q29tbWl0KSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1sYXN0Q29tbWl0Jyk7XG4gIH1cblxuICBpZihsaXN0VGVzdHMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWxpc3RUZXN0cycpO1xuICB9XG5cbiAgaWYobG9nSGVhcFVzYWdlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1sb2dIZWFwVXNhZ2UnKTtcbiAgfVxuXG4gIGlmKG1heFdvcmtlcnMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW1heFdvcmtlcnMnLCBtYXhXb3JrZXJzKTtcbiAgfVxuXG4gIGlmKG5vU3RhY2tUcmFjZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tbm9TdGFja1RyYWNlJyk7XG4gIH1cblxuICBpZihub3RpZnkpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW5vdGlmeScpO1xuICB9XG5cbiAgaWYob25seUNoYW5nZWQpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW9ubHlDaGFuZ2VkJyk7XG4gIH1cblxuICBsZXQgdGVtcE91dHB1dEZpbGUgPSBvdXRwdXRGaWxlO1xuXG4gIGlmKCh1c2VBbmFseXplIHx8IHVzZURlYnVnKSAmJiAhb3V0cHV0RmlsZSkge1xuICAgIHRlbXBPdXRwdXRGaWxlID0gJy5sZXgtdGVzdC1yZXN1bHRzLmpzb24nO1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tanNvbicsICctLW91dHB1dEZpbGUnLCB0ZW1wT3V0cHV0RmlsZSk7XG4gIH0gZWxzZSBpZihvdXRwdXRGaWxlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1vdXRwdXRGaWxlJywgb3V0cHV0RmlsZSk7XG4gIH1cblxuICBpZihwYXNzV2l0aE5vVGVzdHMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXBhc3NXaXRoTm9UZXN0cycpO1xuICB9XG5cbiAgaWYocnVuSW5CYW5kKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1ydW5JbkJhbmQnKTtcbiAgfVxuXG4gIGlmKHNob3dDb25maWcpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXNob3dDb25maWcnKTtcbiAgfVxuXG4gIGlmKHNpbGVudCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tc2lsZW50Jyk7XG4gIH1cblxuICBpZih0ZXN0TG9jYXRpb25JblJlc3VsdHMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXRlc3RMb2NhdGlvbkluUmVzdWx0cycpO1xuICB9XG5cbiAgaWYodGVzdE5hbWVQYXR0ZXJuKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS10ZXN0TmFtZVBhdHRlcm4nLCB0ZXN0TmFtZVBhdHRlcm4pO1xuICB9XG5cbiAgaWYodGVzdFBhdGhQYXR0ZXJuKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS10ZXN0UGF0aFBhdHRlcm4nLCB0ZXN0UGF0aFBhdHRlcm4pO1xuICB9XG5cbiAgaWYodXNlU3RkZXJyKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS11c2VTdGRlcnInKTtcbiAgfVxuXG4gIGlmKHZlcmJvc2UpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXZlcmJvc2UnKTtcbiAgfVxuXG4gIGlmKHdhdGNoQWxsKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS13YXRjaEFsbCcpO1xuICB9XG5cbiAgaWYocmVtb3ZlQ2FjaGUpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW5vLWNhY2hlJyk7XG4gIH1cblxuICBpZihqZXN0U2V0dXBGaWxlICYmIGV4aXN0c1N5bmMoamVzdFNldHVwRmlsZSkpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKGAtLXNldHVwRmlsZXNBZnRlckVudj0ke2plc3RTZXR1cEZpbGV9YCk7XG4gIH1cblxuICBpZih1cGRhdGUpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXVwZGF0ZVNuYXBzaG90Jyk7XG4gIH1cblxuICBpZih3YXRjaCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0td2F0Y2gnLCB3YXRjaCk7XG4gIH1cblxuICBpZihhcmdzKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCguLi5hcmdzKTtcbiAgfVxuXG4gIGlmKGZpbGVzICYmIGZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKC4uLmZpbGVzKTtcbiAgfVxuXG4gIGlmKGRlYnVnKSB7XG4gICAgbG9nKGBKZXN0IG9wdGlvbnM6ICR7amVzdE9wdGlvbnMuam9pbignICcpfWAsICdpbmZvJywgcXVpZXQpO1xuICAgIGxvZyhgTk9ERV9PUFRJT05TOiAke25vZGVPcHRpb25zfWAsICdpbmZvJywgcXVpZXQpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBlbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAuLi5wcm9jZXNzLmVudixcbiAgICAgIE5PREVfT1BUSU9OUzogbm9kZU9wdGlvbnNcbiAgICB9O1xuXG4gICAgYXdhaXQgZXhlY2EoamVzdFBhdGgsIGplc3RPcHRpb25zLCB7XG4gICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgZW52LFxuICAgICAgc3RkaW86ICdpbmhlcml0J1xuICAgIH0pO1xuXG4gICAgc3Bpbm5lci5zdWNjZWVkKCdUZXN0aW5nIGNvbXBsZXRlZCEnKTtcblxuICAgIGlmKHVzZUFuYWx5emUpIHtcbiAgICAgIHNwaW5uZXIuc3RhcnQoJ0FJIGlzIGFuYWx5emluZyB0ZXN0IGNvdmVyYWdlIGFuZCBzdWdnZXN0aW5nIGltcHJvdmVtZW50cy4uLicpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0ZXN0UmVzdWx0cyA9IHByb2Nlc3NUZXN0UmVzdWx0cyh0ZW1wT3V0cHV0RmlsZSk7XG4gICAgICAgIGNvbnN0IGZpbGVQYXR0ZXJucyA9IGdldFRlc3RGaWxlUGF0dGVybnModGVzdFBhdGhQYXR0ZXJuKTtcblxuICAgICAgICBhd2FpdCBhaUZ1bmN0aW9uKHtcbiAgICAgICAgICBjb250ZXh0OiB0cnVlLFxuICAgICAgICAgIHByb21wdDogYEFuYWx5emUgdGhlc2UgSmVzdCB0ZXN0IHJlc3VsdHMgYW5kIHN1Z2dlc3QgdGVzdCBjb3ZlcmFnZSBpbXByb3ZlbWVudHM6XG5cbiR7SlNPTi5zdHJpbmdpZnkodGVzdFJlc3VsdHMsIG51bGwsIDIpfVxuXG5UZXN0IHBhdHRlcm5zOiAke2ZpbGVQYXR0ZXJucy5qb2luKCcsICcpfVxuXG5QbGVhc2UgcHJvdmlkZTpcbjEuIEFuYWx5c2lzIG9mIGN1cnJlbnQgY292ZXJhZ2UgZ2Fwc1xuMi4gU3VnZ2VzdGlvbnMgZm9yIGltcHJvdmluZyB0ZXN0IGNhc2VzXG4zLiBSZWNvbW1lbmRhdGlvbnMgZm9yIGFkZGl0aW9uYWwgaW50ZWdyYXRpb24gdGVzdCBzY2VuYXJpb3NcbjQuIEJlc3QgcHJhY3RpY2VzIGZvciBpbmNyZWFzaW5nIHRlc3QgZWZmZWN0aXZlbmVzc2AsXG4gICAgICAgICAgcXVpZXQsXG4gICAgICAgICAgdGFzazogJ29wdGltaXplJ1xuICAgICAgICB9KTtcblxuICAgICAgICBzcGlubmVyLnN1Y2NlZWQoJ0FJIHRlc3QgYW5hbHlzaXMgY29tcGxldGUnKTtcbiAgICAgIH0gY2F0Y2goYWlFcnJvcikge1xuICAgICAgICBzcGlubmVyLmZhaWwoJ0NvdWxkIG5vdCBnZW5lcmF0ZSBBSSB0ZXN0IGFuYWx5c2lzJyk7XG4gICAgICAgIGlmKCFxdWlldCkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgY29uc29sZS5lcnJvcignQUkgYW5hbHlzaXMgZXJyb3I6JywgYWlFcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjYWxsYmFjaygwKTtcbiAgICByZXR1cm4gMDtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogQ2hlY2sgZm9yIHVuaXQgdGVzdCBlcnJvcnMgYW5kL29yIGNvdmVyYWdlLmAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgIHNwaW5uZXIuZmFpbCgnVGVzdGluZyBmYWlsZWQhJyk7XG5cbiAgICBpZih1c2VEZWJ1Zykge1xuICAgICAgc3Bpbm5lci5zdGFydCgnQUkgaXMgYW5hbHl6aW5nIHRlc3QgZmFpbHVyZXMuLi4nKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdGVzdFJlc3VsdHMgPSBwcm9jZXNzVGVzdFJlc3VsdHModGVtcE91dHB1dEZpbGUpO1xuXG4gICAgICAgIGF3YWl0IGFpRnVuY3Rpb24oe1xuICAgICAgICAgIGNvbnRleHQ6IHRydWUsXG4gICAgICAgICAgcHJvbXB0OiBgRGVidWcgdGhlc2UgZmFpbGVkIEplc3QgdGVzdHMgYW5kIHN1Z2dlc3QgZml4ZXM6XG5cbiR7SlNPTi5zdHJpbmdpZnkoZXJyb3IubWVzc2FnZSwgbnVsbCwgMil9XG5cblRlc3QgcmVzdWx0czogJHtKU09OLnN0cmluZ2lmeSh0ZXN0UmVzdWx0cywgbnVsbCwgMil9XG5cblBsZWFzZSBwcm92aWRlOlxuMS4gQW5hbHlzaXMgb2Ygd2h5IHRoZSB0ZXN0cyBhcmUgZmFpbGluZ1xuMi4gU3BlY2lmaWMgc3VnZ2VzdGlvbnMgdG8gZml4IGVhY2ggZmFpbGluZyB0ZXN0XG4zLiBBbnkgcG90ZW50aWFsIGlzc3VlcyB3aXRoIHRlc3QgZml4dHVyZXMgb3IgbW9ja3NcbjQuIENvZGUgZXhhbXBsZXMgZm9yIHNvbHV0aW9uc2AsXG4gICAgICAgICAgcXVpZXQsXG4gICAgICAgICAgdGFzazogJ2hlbHAnXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNwaW5uZXIuc3VjY2VlZCgnQUkgZGVidWdnaW5nIGFzc2lzdGFuY2UgY29tcGxldGUnKTtcbiAgICAgIH0gY2F0Y2goYWlFcnJvcikge1xuICAgICAgICBzcGlubmVyLmZhaWwoJ0NvdWxkIG5vdCBnZW5lcmF0ZSBBSSBkZWJ1Z2dpbmcgYXNzaXN0YW5jZScpO1xuICAgICAgICBpZighcXVpZXQpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0FJIGRlYnVnZ2luZyBlcnJvcjonLCBhaUVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNhbGxiYWNrKDEpO1xuICAgIHJldHVybiAxO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCB0ZXN0OyJdLCJuYW1lcyI6WyJleGVjYSIsImV4aXN0c1N5bmMiLCJyZWFkRmlsZVN5bmMiLCJzeW5jIiwiZ2xvYlN5bmMiLCJyZXNvbHZlIiwicGF0aFJlc29sdmUiLCJMZXhDb25maWciLCJnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aCIsImNyZWF0ZVNwaW5uZXIiLCJyZXNvbHZlQmluYXJ5UGF0aCIsImxvZyIsImFpRnVuY3Rpb24iLCJkZXRlY3RFU00iLCJjd2QiLCJwYWNrYWdlSnNvblBhdGgiLCJwYWNrYWdlSnNvbkNvbnRlbnQiLCJwYWNrYWdlSnNvbiIsIkpTT04iLCJwYXJzZSIsInR5cGUiLCJfZXJyb3IiLCJkZWZhdWx0RXhpdCIsImNvZGUiLCJwcm9jZXNzIiwiZW52IiwiSkVTVF9XT1JLRVJfSUQiLCJOT0RFX0VOViIsInVuZGVmaW5lZCIsImV4aXQiLCJnZXRUZXN0RmlsZVBhdHRlcm5zIiwidGVzdFBhdGhQYXR0ZXJuIiwiZGVmYXVsdFBhdHRlcm5zIiwiZmluZFVuY292ZXJlZFNvdXJjZUZpbGVzIiwic291cmNlRmlsZXMiLCJpZ25vcmUiLCJ0ZXN0RmlsZXMiLCJmaWx0ZXIiLCJzb3VyY2VGaWxlIiwiYmFzZU5hbWUiLCJyZXBsYWNlIiwic29tZSIsInRlc3RGaWxlIiwiaW5jbHVkZXMiLCJwcm9jZXNzVGVzdFJlc3VsdHMiLCJvdXRwdXRGaWxlIiwiY29udGVudCIsInRlc3QiLCJvcHRpb25zIiwiYXJncyIsImZpbGVzT3JDYWxsYmFjayIsImNhbGxiYWNrUGFyYW0iLCJmaWxlcyIsImNhbGxiYWNrIiwiYW5hbHl6ZSIsImFpQW5hbHl6ZSIsImFpRGVidWciLCJhaUdlbmVyYXRlIiwiYmFpbCIsImNoYW5nZWRGaWxlc1dpdGhBbmNlc3RvciIsImNoYW5nZWRTaW5jZSIsImNpIiwiY2xpTmFtZSIsImNvbGxlY3RDb3ZlcmFnZUZyb20iLCJjb2xvcnMiLCJjb25maWciLCJkZWJ1ZyIsImRlYnVnVGVzdHMiLCJkZXRlY3RPcGVuSGFuZGxlcyIsImVycm9yT25EZXByZWNhdGVkIiwiZXhwYW5kIiwiZm9yY2VFeGl0IiwiZ2VuZXJhdGUiLCJqc29uIiwibGFzdENvbW1pdCIsImxpc3RUZXN0cyIsImxvZ0hlYXBVc2FnZSIsIm1heFdvcmtlcnMiLCJub1N0YWNrVHJhY2UiLCJub3RpZnkiLCJvbmx5Q2hhbmdlZCIsInBhc3NXaXRoTm9UZXN0cyIsInF1aWV0IiwicmVtb3ZlQ2FjaGUiLCJydW5JbkJhbmQiLCJzZXR1cCIsInNob3dDb25maWciLCJzaWxlbnQiLCJ0ZXN0TG9jYXRpb25JblJlc3VsdHMiLCJ0ZXN0TmFtZVBhdHRlcm4iLCJ1cGRhdGUiLCJ1c2VTdGRlcnIiLCJ2ZXJib3NlIiwid2F0Y2giLCJ3YXRjaEFsbCIsInVzZUdlbmVyYXRlIiwidXNlQW5hbHl6ZSIsInVzZURlYnVnIiwic3Bpbm5lciIsInBhcnNlQ29uZmlnIiwidXNlVHlwZXNjcmlwdCIsInRlc3RDb25maWdQYXRoIiwiY2hlY2tUZXN0VHlwZXNjcmlwdENvbmZpZyIsInN0YXJ0IiwidW5jb3ZlcmVkRmlsZXMiLCJsZW5ndGgiLCJ0YXJnZXRGaWxlIiwiY29udGV4dCIsImZpbGUiLCJwcm9tcHQiLCJ0YXNrIiwic3VjY2VlZCIsImFpRXJyb3IiLCJmYWlsIiwiY29uc29sZSIsImVycm9yIiwicHJvamVjdEplc3RCaW4iLCJqZXN0UGF0aCIsImplc3RDb25maWdGaWxlIiwicHJvamVjdEplc3RDb25maWciLCJwcm9qZWN0SmVzdENvbmZpZ1BhdGgiLCJwcm9qZWN0SmVzdENvbmZpZ0Nqc1BhdGgiLCJwcm9qZWN0SmVzdENvbmZpZ01qc1BhdGgiLCJwcm9qZWN0SmVzdENvbmZpZ0pzb25QYXRoIiwiamVzdCIsImxleERpciIsImdldExleERpciIsImxleEplc3RDb25maWciLCJPYmplY3QiLCJrZXlzIiwiamVzdFNldHVwRmlsZSIsImplc3RPcHRpb25zIiwiaXNFU00iLCJub2RlT3B0aW9ucyIsIk5PREVfT1BUSU9OUyIsInRyaW0iLCJwdXNoIiwidGVtcE91dHB1dEZpbGUiLCJqb2luIiwiZW5jb2RpbmciLCJzdGRpbyIsInRlc3RSZXN1bHRzIiwiZmlsZVBhdHRlcm5zIiwic3RyaW5naWZ5IiwibWVzc2FnZSJdLCJtYXBwaW5ncyI6IkFBQUE7OztDQUdDLEdBQ0QsU0FBUUEsS0FBSyxRQUFPLFFBQVE7QUFDNUIsU0FBUUMsVUFBVSxFQUFFQyxZQUFZLFFBQU8sS0FBSztBQUM1QyxTQUFRQyxRQUFRQyxRQUFRLFFBQU8sT0FBTztBQUN0QyxTQUFRQyxXQUFXQyxXQUFX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
|