@workflow/next 5.0.0-beta.2 → 5.0.0-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder-deferred.d.ts.map +1 -1
- package/dist/builder-deferred.js +416 -501
- package/dist/builder-eager.d.ts.map +1 -1
- package/dist/builder-eager.js +60 -76
- package/dist/builder.d.ts +1 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +4 -4
- package/dist/environment-flag.d.ts +2 -0
- package/dist/environment-flag.d.ts.map +1 -0
- package/dist/environment-flag.js +15 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +267 -10
- package/dist/loader.d.ts +6 -0
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +59 -60
- package/dist/runtime.js +1 -1
- package/dist/socket-server.d.ts +20 -0
- package/dist/socket-server.d.ts.map +1 -1
- package/dist/socket-server.js +29 -2
- package/docs/api-reference/with-workflow.mdx +34 -2
- package/docs/next.mdx +5 -3
- package/package.json +4 -5
- package/dist/builder-deferred.js.map +0 -1
- package/dist/builder-eager.js.map +0 -1
- package/dist/builder.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/loader.js.map +0 -1
- package/dist/runtime.js.map +0 -1
- package/dist/socket-server.js.map +0 -1
- package/dist/step-copy-utils.d.ts +0 -19
- package/dist/step-copy-utils.d.ts.map +0 -1
- package/dist/step-copy-utils.js +0 -101
- package/dist/step-copy-utils.js.map +0 -1
package/dist/builder-deferred.js
CHANGED
|
@@ -7,13 +7,13 @@ exports.getNextBuilderDeferred = getNextBuilderDeferred;
|
|
|
7
7
|
const node_crypto_1 = require("node:crypto");
|
|
8
8
|
const node_fs_1 = require("node:fs");
|
|
9
9
|
const promises_1 = require("node:fs/promises");
|
|
10
|
+
const node_module_1 = require("node:module");
|
|
10
11
|
const node_os_1 = __importDefault(require("node:os"));
|
|
11
12
|
const node_path_1 = require("node:path");
|
|
12
|
-
const enhanced_resolve_1 = __importDefault(require("enhanced-resolve"));
|
|
13
13
|
const socket_server_js_1 = require("./socket-server.js");
|
|
14
|
-
const step_copy_utils_js_1 = require("./step-copy-utils.js");
|
|
15
14
|
const ROUTE_STUB_FILE_MARKER = 'WORKFLOW_ROUTE_STUB_FILE';
|
|
16
15
|
const ROUTE_STUB_MARKER_SCAN_BYTES = 4 * 1024;
|
|
16
|
+
const DEV_WORKFLOW_CODE_FILENAME = '__workflow_code.txt';
|
|
17
17
|
let CachedNextBuilderDeferred;
|
|
18
18
|
// Create the deferred Next builder dynamically by extending the ESM BaseBuilder.
|
|
19
19
|
// Exported as getNextBuilderDeferred() to allow CommonJS modules to import from
|
|
@@ -22,46 +22,15 @@ async function getNextBuilderDeferred() {
|
|
|
22
22
|
if (CachedNextBuilderDeferred) {
|
|
23
23
|
return CachedNextBuilderDeferred;
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
// V2: STEP_QUEUE_TRIGGER and enhanced-resolve infrastructure
|
|
26
|
+
// were removed because the V2 combined handler eliminates the separate step
|
|
27
|
+
// route/topic. The step copy import rewriting (getRelativeImportSpecifier,
|
|
28
|
+
// getStepCopyFileName, rewriteRelativeImportsForCopiedStep) from main was also
|
|
29
|
+
// removed — V2 doesn't use step copies. If step copy support is needed, it
|
|
30
|
+
// should land as a complete feature set.
|
|
31
|
+
const { BaseBuilder: BaseBuilderClass, WORKFLOW_QUEUE_TRIGGER, createWorkflowEntrypointOptionsCode, detectWorkflowPatterns, applySwcTransform, getImportPath, resolveWorkflowAliasRelativePath,
|
|
26
32
|
// biome-ignore lint/security/noGlobalEval: Need to use eval here to avoid TypeScript from transpiling the import statement into `require()`
|
|
27
33
|
} = (await eval('import("@workflow/builders")'));
|
|
28
|
-
// Shared resolve options matching the configuration used by the SWC
|
|
29
|
-
// esbuild plugin (swc-esbuild-plugin.ts) for consistent resolution
|
|
30
|
-
// semantics across the toolchain.
|
|
31
|
-
const NODE_RESOLVE_OPTIONS = {
|
|
32
|
-
dependencyType: 'commonjs',
|
|
33
|
-
modules: ['node_modules'],
|
|
34
|
-
exportsFields: ['exports'],
|
|
35
|
-
importsFields: ['imports'],
|
|
36
|
-
conditionNames: ['node', 'require'],
|
|
37
|
-
descriptionFiles: ['package.json'],
|
|
38
|
-
extensions: [
|
|
39
|
-
'.ts',
|
|
40
|
-
'.tsx',
|
|
41
|
-
'.mts',
|
|
42
|
-
'.cts',
|
|
43
|
-
'.cjs',
|
|
44
|
-
'.mjs',
|
|
45
|
-
'.js',
|
|
46
|
-
'.jsx',
|
|
47
|
-
'.json',
|
|
48
|
-
'.node',
|
|
49
|
-
],
|
|
50
|
-
enforceExtensions: false,
|
|
51
|
-
symlinks: true,
|
|
52
|
-
mainFields: ['main'],
|
|
53
|
-
mainFiles: ['index'],
|
|
54
|
-
roots: [],
|
|
55
|
-
fullySpecified: false,
|
|
56
|
-
preferRelative: false,
|
|
57
|
-
preferAbsolute: false,
|
|
58
|
-
restrictions: [],
|
|
59
|
-
};
|
|
60
|
-
const NODE_ESM_RESOLVE_OPTIONS = {
|
|
61
|
-
...NODE_RESOLVE_OPTIONS,
|
|
62
|
-
dependencyType: 'esm',
|
|
63
|
-
conditionNames: ['node', 'import'],
|
|
64
|
-
};
|
|
65
34
|
class NextDeferredBuilder extends BaseBuilderClass {
|
|
66
35
|
socketIO;
|
|
67
36
|
discoveredWorkflowFiles = new Set();
|
|
@@ -73,11 +42,6 @@ async function getNextBuilderDeferred() {
|
|
|
73
42
|
cacheWriteTimer = null;
|
|
74
43
|
deferredRebuildTimer = null;
|
|
75
44
|
lastDeferredBuildSignature = null;
|
|
76
|
-
// Lazily initialized resolvers for bare specifier rewriting.
|
|
77
|
-
// Cached to avoid re-creating on every import rewrite.
|
|
78
|
-
esmSyncResolver;
|
|
79
|
-
cjsSyncResolver;
|
|
80
|
-
manifestStepResolveBaseDirs = null;
|
|
81
45
|
async build() {
|
|
82
46
|
const outputDir = await this.findAppDirectory();
|
|
83
47
|
await this.initializeDiscoveryState();
|
|
@@ -141,6 +105,14 @@ async function getNextBuilderDeferred() {
|
|
|
141
105
|
}
|
|
142
106
|
}
|
|
143
107
|
this.lastDeferredBuildSignature = buildSignature;
|
|
108
|
+
if (!this.config.watch) {
|
|
109
|
+
// Production builds can persist newly discovered deferred-entry files to
|
|
110
|
+
// the cache after the first pass completes. Reload that cache before we
|
|
111
|
+
// decide whether the input signature stabilized so staged tarball builds
|
|
112
|
+
// can immediately replay with the expanded step set.
|
|
113
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
114
|
+
await this.loadWorkflowsCache();
|
|
115
|
+
}
|
|
144
116
|
const postBuildInputFiles = this.getCurrentInputFiles(implicitStepFiles);
|
|
145
117
|
const postBuildSignature = await this.createDeferredBuildSignature(postBuildInputFiles);
|
|
146
118
|
if (postBuildSignature === buildSignature) {
|
|
@@ -157,15 +129,11 @@ async function getNextBuilderDeferred() {
|
|
|
157
129
|
const outputDir = await this.findAppDirectory();
|
|
158
130
|
const generatedRouteFiles = [
|
|
159
131
|
(0, node_path_1.join)(outputDir, '.well-known/workflow/v1/flow/route.js'),
|
|
160
|
-
(0, node_path_1.join)(outputDir, '.well-known/workflow/v1/step/route.js'),
|
|
161
132
|
(0, node_path_1.join)(outputDir, '.well-known/workflow/v1/webhook/[token]/route.js'),
|
|
162
133
|
];
|
|
163
134
|
for (const routeFilePath of generatedRouteFiles) {
|
|
164
135
|
const routeState = await this.getGeneratedRouteState(routeFilePath);
|
|
165
|
-
if (routeState === 'missing') {
|
|
166
|
-
return true;
|
|
167
|
-
}
|
|
168
|
-
if (routeState === 'stub') {
|
|
136
|
+
if (routeState === 'missing' || routeState === 'stub') {
|
|
169
137
|
return true;
|
|
170
138
|
}
|
|
171
139
|
}
|
|
@@ -383,18 +351,17 @@ async function getNextBuilderDeferred() {
|
|
|
383
351
|
...this.discoveredSerdeFiles,
|
|
384
352
|
...trackedDiscoveredEntries.discoveredSerdeFiles,
|
|
385
353
|
])).sort();
|
|
386
|
-
const discoveredStepFiles = await this.filterExistingFiles(discoveredStepFileCandidates);
|
|
387
354
|
const discoveredWorkflowFiles = await this.filterExistingFiles(discoveredWorkflowFileCandidates);
|
|
355
|
+
const existingStepFileCandidates = await this.filterExistingFiles(discoveredStepFileCandidates);
|
|
356
|
+
const discoveredStepFiles = await this.collectTransitiveStepFiles({
|
|
357
|
+
entryFiles: [...existingStepFileCandidates, ...discoveredWorkflowFiles],
|
|
358
|
+
stepFiles: existingStepFileCandidates,
|
|
359
|
+
});
|
|
388
360
|
const existingSerdeFileCandidates = await this.filterExistingFiles(discoveredSerdeFileCandidates);
|
|
389
361
|
const discoveredSerdeFiles = await this.collectTransitiveSerdeFiles({
|
|
390
362
|
entryFiles: [...discoveredStepFiles, ...discoveredWorkflowFiles],
|
|
391
363
|
serdeFiles: existingSerdeFileCandidates,
|
|
392
364
|
});
|
|
393
|
-
const discoveredEntries = {
|
|
394
|
-
discoveredSteps: new Set(discoveredStepFiles),
|
|
395
|
-
discoveredWorkflows: new Set(discoveredWorkflowFiles),
|
|
396
|
-
discoveredSerdeFiles: new Set(discoveredSerdeFiles),
|
|
397
|
-
};
|
|
398
365
|
const existingInputFiles = await this.filterExistingFiles(inputFiles);
|
|
399
366
|
const buildInputFiles = Array.from(new Set([
|
|
400
367
|
...existingInputFiles,
|
|
@@ -402,38 +369,32 @@ async function getNextBuilderDeferred() {
|
|
|
402
369
|
...discoveredWorkflowFiles,
|
|
403
370
|
...discoveredSerdeFiles,
|
|
404
371
|
])).sort();
|
|
372
|
+
const discoveredEntries = {
|
|
373
|
+
discoveredSteps: new Set(discoveredStepFiles),
|
|
374
|
+
discoveredWorkflows: new Set(discoveredWorkflowFiles),
|
|
375
|
+
discoveredSerdeFiles: new Set(discoveredSerdeFiles),
|
|
376
|
+
};
|
|
405
377
|
// Ensure output directories exist
|
|
406
378
|
await (0, promises_1.mkdir)(workflowGeneratedDir, { recursive: true });
|
|
407
379
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, '.gitignore'), '*');
|
|
408
380
|
const tsconfigPath = await this.findTsConfigPath();
|
|
409
|
-
const
|
|
381
|
+
const flowRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'flow');
|
|
382
|
+
await (0, promises_1.mkdir)(flowRouteDir, { recursive: true });
|
|
383
|
+
const combinedResult = await this.createDeferredFlowRoute({
|
|
410
384
|
inputFiles: buildInputFiles,
|
|
411
|
-
|
|
385
|
+
flowOutfile: (0, node_path_1.join)(flowRouteDir, tempRouteFileName),
|
|
412
386
|
tsconfigPath,
|
|
413
|
-
routeFileName: tempRouteFileName,
|
|
414
387
|
discoveredEntries,
|
|
415
|
-
};
|
|
416
|
-
const workflowsBundle = await this.buildWorkflowsFunction(options);
|
|
417
|
-
const { manifest: stepsManifest } = await this.buildStepsFunction({
|
|
418
|
-
...options,
|
|
419
|
-
additionalStepSourceManifest: workflowsBundle?.manifest,
|
|
420
388
|
});
|
|
421
389
|
await this.buildWebhookRoute({
|
|
422
390
|
workflowGeneratedDir,
|
|
423
391
|
routeFileName: tempRouteFileName,
|
|
424
392
|
});
|
|
425
393
|
await this.refreshTrackedDependencyFiles(workflowGeneratedDir, tempRouteFileName);
|
|
426
|
-
// Merge manifests from both bundles
|
|
427
394
|
const manifest = {
|
|
428
|
-
steps: { ...
|
|
429
|
-
workflows: {
|
|
430
|
-
|
|
431
|
-
...workflowsBundle?.manifest?.workflows,
|
|
432
|
-
},
|
|
433
|
-
classes: {
|
|
434
|
-
...stepsManifest.classes,
|
|
435
|
-
...workflowsBundle?.manifest?.classes,
|
|
436
|
-
},
|
|
395
|
+
steps: { ...combinedResult?.manifest?.steps },
|
|
396
|
+
workflows: { ...combinedResult?.manifest?.workflows },
|
|
397
|
+
classes: { ...combinedResult?.manifest?.classes },
|
|
437
398
|
};
|
|
438
399
|
const manifestFilePath = (0, node_path_1.join)(workflowGeneratedDir, 'manifest.json');
|
|
439
400
|
const manifestBuildPath = (0, node_path_1.join)(manifestBuildDir, 'manifest.json');
|
|
@@ -452,19 +413,197 @@ async function getNextBuilderDeferred() {
|
|
|
452
413
|
await (0, promises_1.rm)(manifestFilePath, { force: true });
|
|
453
414
|
}
|
|
454
415
|
await this.writeFunctionsConfig(outputDir);
|
|
416
|
+
// V2: Combined route (flow) — step registrations already at final path
|
|
455
417
|
await this.copyFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, `flow/${tempRouteFileName}`), (0, node_path_1.join)(workflowGeneratedDir, 'flow/route.js'));
|
|
456
|
-
await this.copyFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, `step/${tempRouteFileName}`), (0, node_path_1.join)(workflowGeneratedDir, 'step/route.js'));
|
|
457
418
|
await this.copyFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, `webhook/[token]/${tempRouteFileName}`), (0, node_path_1.join)(workflowGeneratedDir, 'webhook/[token]/route.js'));
|
|
458
419
|
// Expose manifest as a static file when WORKFLOW_PUBLIC_MANIFEST=1.
|
|
459
420
|
// Next.js serves files from public/ at the root URL.
|
|
460
421
|
if (this.shouldExposePublicManifest && manifestJson) {
|
|
461
422
|
const publicManifestDir = (0, node_path_1.join)(this.config.workingDir, 'public/.well-known/workflow/v1');
|
|
462
423
|
await (0, promises_1.mkdir)(publicManifestDir, { recursive: true });
|
|
424
|
+
if (process.env.VERCEL_DEPLOYMENT_ID === undefined) {
|
|
425
|
+
await this.writeFileIfChanged((0, node_path_1.join)(publicManifestDir, '.gitignore'), '*');
|
|
426
|
+
}
|
|
463
427
|
await this.copyFileIfChanged(manifestFilePath, (0, node_path_1.join)(publicManifestDir, 'manifest.json'));
|
|
464
428
|
}
|
|
465
429
|
// Notify deferred entry loaders waiting on route.js stubs.
|
|
466
430
|
this.socketIO?.emit('build-complete');
|
|
467
431
|
}
|
|
432
|
+
async createDeferredFlowRoute({ inputFiles, flowOutfile, tsconfigPath, discoveredEntries, }) {
|
|
433
|
+
const workflowResult = await this.createWorkflowsBundle({
|
|
434
|
+
inputFiles,
|
|
435
|
+
outfile: `${flowOutfile}.__wf_tmp.js`,
|
|
436
|
+
format: 'esm',
|
|
437
|
+
bundleFinalOutput: false,
|
|
438
|
+
tsconfigPath,
|
|
439
|
+
discoveredEntries,
|
|
440
|
+
});
|
|
441
|
+
const workflowVMCode = workflowResult.interimBundleText;
|
|
442
|
+
if (!workflowVMCode) {
|
|
443
|
+
throw new Error('createWorkflowsBundle did not return interimBundleText');
|
|
444
|
+
}
|
|
445
|
+
try {
|
|
446
|
+
await (0, promises_1.rm)(`${flowOutfile}.__wf_tmp.js`, { force: true });
|
|
447
|
+
}
|
|
448
|
+
catch {
|
|
449
|
+
// Ignore cleanup errors.
|
|
450
|
+
}
|
|
451
|
+
const stepAndSerdeFiles = Array.from(new Set([
|
|
452
|
+
...discoveredEntries.discoveredSteps,
|
|
453
|
+
...discoveredEntries.discoveredSerdeFiles,
|
|
454
|
+
])).sort();
|
|
455
|
+
const stepImports = await this.createDeferredStepSideEffectImports(stepAndSerdeFiles, (0, node_path_1.dirname)(flowOutfile));
|
|
456
|
+
const stepManifest = await this.createDeferredStepManifest(stepAndSerdeFiles);
|
|
457
|
+
const escapedVMCode = workflowVMCode.replace(/[\\`$]/g, '\\$&');
|
|
458
|
+
const workflowEntrypointOptionsCode = createWorkflowEntrypointOptionsCode();
|
|
459
|
+
let routeCode;
|
|
460
|
+
if (this.config.watch) {
|
|
461
|
+
const workflowCodePath = (0, node_path_1.join)((0, node_path_1.dirname)(flowOutfile), DEV_WORKFLOW_CODE_FILENAME);
|
|
462
|
+
await this.writeFileIfChanged(workflowCodePath, workflowVMCode);
|
|
463
|
+
routeCode = `// biome-ignore-all lint: generated file
|
|
464
|
+
/* eslint-disable */
|
|
465
|
+
import 'workflow/internal/builtins';
|
|
466
|
+
${stepImports}
|
|
467
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
468
|
+
import { workflowEntrypoint } from 'workflow/runtime';
|
|
469
|
+
|
|
470
|
+
const workflowCodePath = ${JSON.stringify(workflowCodePath)};
|
|
471
|
+
let cachedWorkflowHandler;
|
|
472
|
+
let cachedWorkflowCodeSignature;
|
|
473
|
+
|
|
474
|
+
async function getWorkflowHandler() {
|
|
475
|
+
const workflowCodeStats = await stat(workflowCodePath);
|
|
476
|
+
const workflowCodeSignature = \`\${workflowCodeStats.size}:\${workflowCodeStats.mtimeMs}\`;
|
|
477
|
+
if (!cachedWorkflowHandler || cachedWorkflowCodeSignature !== workflowCodeSignature) {
|
|
478
|
+
const workflowCode = await readFile(workflowCodePath, 'utf8');
|
|
479
|
+
cachedWorkflowHandler = workflowEntrypoint(workflowCode${workflowEntrypointOptionsCode});
|
|
480
|
+
cachedWorkflowCodeSignature = workflowCodeSignature;
|
|
481
|
+
}
|
|
482
|
+
return cachedWorkflowHandler;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export async function POST(req) {
|
|
486
|
+
return (await getWorkflowHandler())(req);
|
|
487
|
+
}`;
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
routeCode = `// biome-ignore-all lint: generated file
|
|
491
|
+
/* eslint-disable */
|
|
492
|
+
import 'workflow/internal/builtins';
|
|
493
|
+
${stepImports}
|
|
494
|
+
import { workflowEntrypoint } from 'workflow/runtime';
|
|
495
|
+
|
|
496
|
+
const workflowCode = \`${escapedVMCode}\`;
|
|
497
|
+
|
|
498
|
+
export const POST = workflowEntrypoint(workflowCode${workflowEntrypointOptionsCode});`;
|
|
499
|
+
}
|
|
500
|
+
await this.writeFileIfChanged(flowOutfile, routeCode);
|
|
501
|
+
return {
|
|
502
|
+
manifest: {
|
|
503
|
+
...stepManifest,
|
|
504
|
+
workflows: {
|
|
505
|
+
...stepManifest.workflows,
|
|
506
|
+
...workflowResult.manifest.workflows,
|
|
507
|
+
},
|
|
508
|
+
classes: {
|
|
509
|
+
...stepManifest.classes,
|
|
510
|
+
...workflowResult.manifest.classes,
|
|
511
|
+
},
|
|
512
|
+
},
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
async createDeferredStepSideEffectImports(files, routeDir) {
|
|
516
|
+
const importSpecifiers = await Promise.all(files.map((file) => this.getDeferredRouteImportSpecifier(file, routeDir)));
|
|
517
|
+
return importSpecifiers
|
|
518
|
+
.map((specifier) => `import ${JSON.stringify(specifier)};`)
|
|
519
|
+
.join('\n');
|
|
520
|
+
}
|
|
521
|
+
async getDeferredRouteImportSpecifier(file, routeDir) {
|
|
522
|
+
const { importPath, isPackage } = getImportPath(file, this.config.workingDir);
|
|
523
|
+
if (isPackage) {
|
|
524
|
+
return importPath;
|
|
525
|
+
}
|
|
526
|
+
const absolutePath = await this.resolveDeferredRouteImportFilePath((0, node_path_1.resolve)(this.config.workingDir, importPath));
|
|
527
|
+
let relativePath = (0, node_path_1.relative)(routeDir, absolutePath).replace(/\\/g, '/');
|
|
528
|
+
if (!relativePath.startsWith('./') && !relativePath.startsWith('../')) {
|
|
529
|
+
relativePath = `./${relativePath}`;
|
|
530
|
+
}
|
|
531
|
+
return relativePath;
|
|
532
|
+
}
|
|
533
|
+
async resolveDeferredRouteImportFilePath(filePath) {
|
|
534
|
+
const packageDistPath = this.resolvePackageSourceDistFilePathForRouteImport(filePath);
|
|
535
|
+
if (packageDistPath) {
|
|
536
|
+
return packageDistPath;
|
|
537
|
+
}
|
|
538
|
+
return filePath;
|
|
539
|
+
}
|
|
540
|
+
resolvePackageSourceDistFilePathForRouteImport(filePath) {
|
|
541
|
+
const relativeToWorkingDir = (0, node_path_1.relative)(this.config.workingDir, filePath);
|
|
542
|
+
if (!relativeToWorkingDir.startsWith('..') &&
|
|
543
|
+
!(0, node_path_1.isAbsolute)(relativeToWorkingDir)) {
|
|
544
|
+
return null;
|
|
545
|
+
}
|
|
546
|
+
const packageRoot = this.findPackageRootForRouteImportSource(filePath);
|
|
547
|
+
if (!packageRoot) {
|
|
548
|
+
return null;
|
|
549
|
+
}
|
|
550
|
+
const relativeToPackageRoot = (0, node_path_1.relative)(packageRoot, filePath).replace(/\\/g, '/');
|
|
551
|
+
const srcPrefix = 'src/';
|
|
552
|
+
if (!relativeToPackageRoot.startsWith(srcPrefix)) {
|
|
553
|
+
return null;
|
|
554
|
+
}
|
|
555
|
+
const extension = (0, node_path_1.extname)(relativeToPackageRoot);
|
|
556
|
+
const outputExtension = extension === '.mts' ? '.mjs' : extension === '.cts' ? '.cjs' : '.js';
|
|
557
|
+
const withoutExtension = relativeToPackageRoot.slice(srcPrefix.length, relativeToPackageRoot.length - extension.length);
|
|
558
|
+
const distPath = (0, node_path_1.join)(packageRoot, 'dist', `${withoutExtension}${outputExtension}`);
|
|
559
|
+
return (0, node_fs_1.existsSync)(distPath) ? distPath : null;
|
|
560
|
+
}
|
|
561
|
+
findPackageRootForRouteImportSource(filePath) {
|
|
562
|
+
let currentDir = (0, node_path_1.dirname)(filePath);
|
|
563
|
+
while (true) {
|
|
564
|
+
if ((0, node_fs_1.existsSync)((0, node_path_1.join)(currentDir, 'package.json'))) {
|
|
565
|
+
return currentDir;
|
|
566
|
+
}
|
|
567
|
+
const parentDir = (0, node_path_1.dirname)(currentDir);
|
|
568
|
+
if (parentDir === currentDir) {
|
|
569
|
+
return null;
|
|
570
|
+
}
|
|
571
|
+
currentDir = parentDir;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
async createDeferredStepManifest(files) {
|
|
575
|
+
const manifest = {};
|
|
576
|
+
const manifestFiles = Array.from(new Set([
|
|
577
|
+
...files,
|
|
578
|
+
...(await this.resolveBuiltInStepFilesForManifest()),
|
|
579
|
+
])).sort();
|
|
580
|
+
for (const file of manifestFiles) {
|
|
581
|
+
const source = await (0, promises_1.readFile)(file, 'utf8').catch(() => undefined);
|
|
582
|
+
if (!source) {
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
585
|
+
const relativeFilepath = await this.getRelativeFilenameForSwc(file);
|
|
586
|
+
const { workflowManifest } = await applySwcTransform(relativeFilepath, source, 'step', file, this.transformProjectRoot, this.moduleSpecifierRoot);
|
|
587
|
+
this.mergeWorkflowManifest(manifest, workflowManifest);
|
|
588
|
+
}
|
|
589
|
+
return manifest;
|
|
590
|
+
}
|
|
591
|
+
async resolveBuiltInStepFilesForManifest() {
|
|
592
|
+
try {
|
|
593
|
+
const workflowRequire = (0, node_module_1.createRequire)((0, node_path_1.join)(this.config.workingDir, 'package.json'));
|
|
594
|
+
return [
|
|
595
|
+
this.normalizeDiscoveredFilePath(workflowRequire.resolve('workflow/internal/builtins')),
|
|
596
|
+
];
|
|
597
|
+
}
|
|
598
|
+
catch {
|
|
599
|
+
return [];
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
mergeWorkflowManifest(target, source) {
|
|
603
|
+
target.workflows = Object.assign(target.workflows || {}, source.workflows);
|
|
604
|
+
target.steps = Object.assign(target.steps || {}, source.steps);
|
|
605
|
+
target.classes = Object.assign(target.classes || {}, source.classes);
|
|
606
|
+
}
|
|
468
607
|
async cleanupGeneratedArtifactsOnBoot(outputDir) {
|
|
469
608
|
const workflowGeneratedDir = (0, node_path_1.join)(outputDir, '.well-known/workflow/v1');
|
|
470
609
|
const flowRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'flow');
|
|
@@ -474,17 +613,18 @@ async function getNextBuilderDeferred() {
|
|
|
474
613
|
(0, node_path_1.join)(flowRouteDir, 'route.js.temp'),
|
|
475
614
|
(0, node_path_1.join)(flowRouteDir, 'route.js.temp.debug.json'),
|
|
476
615
|
(0, node_path_1.join)(flowRouteDir, 'route.js.debug.json'),
|
|
477
|
-
(0, node_path_1.join)(
|
|
478
|
-
(0, node_path_1.join)(
|
|
479
|
-
(0, node_path_1.join)(
|
|
480
|
-
|
|
616
|
+
(0, node_path_1.join)(flowRouteDir, DEV_WORKFLOW_CODE_FILENAME),
|
|
617
|
+
(0, node_path_1.join)(flowRouteDir, '__step_registrations.route.js.temp'),
|
|
618
|
+
(0, node_path_1.join)(flowRouteDir, '__step_registrations.route.js.temp.debug.json'),
|
|
619
|
+
// V2: clean up stale V1 step route directory
|
|
620
|
+
stepRouteDir,
|
|
481
621
|
(0, node_path_1.join)(webhookRouteDir, 'route.js.temp'),
|
|
482
622
|
(0, node_path_1.join)(workflowGeneratedDir, 'manifest.json'),
|
|
483
623
|
];
|
|
484
|
-
await Promise.all(staleArtifactPaths.map((stalePath) => (0, promises_1.rm)(stalePath, { recursive: true, force: true })));
|
|
485
624
|
await Promise.all([
|
|
625
|
+
...staleArtifactPaths.map((stalePath) => (0, promises_1.rm)(stalePath, { recursive: true, force: true })),
|
|
626
|
+
(0, socket_server_js_1.cleanupStaleSocketInfoFiles)((0, node_path_1.join)(this.config.workingDir, this.getDistDir())),
|
|
486
627
|
this.removeStaleDeferredTempFiles(flowRouteDir),
|
|
487
|
-
this.removeStaleDeferredTempFiles(stepRouteDir),
|
|
488
628
|
this.removeStaleDeferredTempFiles(webhookRouteDir),
|
|
489
629
|
]);
|
|
490
630
|
}
|
|
@@ -545,7 +685,11 @@ async function getNextBuilderDeferred() {
|
|
|
545
685
|
if (hasCacheTrackingChange) {
|
|
546
686
|
this.scheduleWorkflowsCacheWrite();
|
|
547
687
|
}
|
|
548
|
-
if (
|
|
688
|
+
if (hasWorkflow ||
|
|
689
|
+
hasStep ||
|
|
690
|
+
hasSerde ||
|
|
691
|
+
hasCacheTrackingChange ||
|
|
692
|
+
wasTrackedDependency) {
|
|
549
693
|
this.scheduleDeferredRebuild();
|
|
550
694
|
}
|
|
551
695
|
},
|
|
@@ -571,41 +715,52 @@ async function getNextBuilderDeferred() {
|
|
|
571
715
|
return (0, node_path_1.join)(this.config.workingDir, this.getDistDir(), 'cache', 'workflows.json');
|
|
572
716
|
}
|
|
573
717
|
getSocketInfoFilePath() {
|
|
574
|
-
return (0, node_path_1.join)(this.config.workingDir, this.getDistDir(),
|
|
718
|
+
return (0, node_path_1.join)(this.config.workingDir, this.getDistDir(), socket_server_js_1.SOCKET_INFO_FILENAME);
|
|
575
719
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
720
|
+
findPackageJsonPath(filePath) {
|
|
721
|
+
let currentDir = (0, node_path_1.dirname)(filePath);
|
|
722
|
+
let previousDir = '';
|
|
723
|
+
while (currentDir !== previousDir) {
|
|
724
|
+
const packageJsonPath = (0, node_path_1.join)(currentDir, 'package.json');
|
|
725
|
+
if ((0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
726
|
+
return packageJsonPath;
|
|
727
|
+
}
|
|
728
|
+
previousDir = currentDir;
|
|
729
|
+
currentDir = (0, node_path_1.dirname)(currentDir);
|
|
730
|
+
}
|
|
731
|
+
return null;
|
|
732
|
+
}
|
|
733
|
+
shouldPreferSourceBackedPackagePath(filePath) {
|
|
734
|
+
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
735
|
+
// Only prefer source for workspace packages (not in node_modules).
|
|
736
|
+
// For tarball-installed packages, using source-backed paths causes
|
|
737
|
+
// esbuild to bundle the full source tree (including world.ts with
|
|
738
|
+
// process.cwd()) instead of externalizing properly.
|
|
739
|
+
if (normalizedPath.includes('/packages/') &&
|
|
740
|
+
!normalizedPath.includes('/node_modules/')) {
|
|
741
|
+
return true;
|
|
742
|
+
}
|
|
743
|
+
if (!normalizedPath.includes('/node_modules/')) {
|
|
744
|
+
return false;
|
|
745
|
+
}
|
|
746
|
+
const packageJsonPath = this.findPackageJsonPath(filePath);
|
|
747
|
+
if (!packageJsonPath) {
|
|
748
|
+
return false;
|
|
749
|
+
}
|
|
580
750
|
try {
|
|
581
|
-
|
|
751
|
+
const packageJson = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, 'utf-8'));
|
|
752
|
+
return (packageJson.name === 'workflow' ||
|
|
753
|
+
(typeof packageJson.name === 'string' &&
|
|
754
|
+
packageJson.name.startsWith('@workflow/')));
|
|
582
755
|
}
|
|
583
756
|
catch {
|
|
584
|
-
return
|
|
757
|
+
return false;
|
|
585
758
|
}
|
|
586
759
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
const resolveBaseDirs = new Set();
|
|
592
|
-
const addResolveBaseDir = (baseDir) => {
|
|
593
|
-
resolveBaseDirs.add(this.normalizeDiscoveredFilePath(baseDir));
|
|
594
|
-
};
|
|
595
|
-
if (this.config.projectRoot) {
|
|
596
|
-
addResolveBaseDir(this.config.projectRoot);
|
|
597
|
-
}
|
|
598
|
-
let currentResolveDir = this.config.workingDir;
|
|
599
|
-
while (currentResolveDir) {
|
|
600
|
-
addResolveBaseDir(currentResolveDir);
|
|
601
|
-
const parentResolveDir = (0, node_path_1.dirname)(currentResolveDir);
|
|
602
|
-
if (parentResolveDir === currentResolveDir) {
|
|
603
|
-
break;
|
|
604
|
-
}
|
|
605
|
-
currentResolveDir = parentResolveDir;
|
|
606
|
-
}
|
|
607
|
-
this.manifestStepResolveBaseDirs = Array.from(resolveBaseDirs);
|
|
608
|
-
return this.manifestStepResolveBaseDirs;
|
|
760
|
+
normalizeDiscoveredFilePath(filePath) {
|
|
761
|
+
return (0, node_path_1.isAbsolute)(filePath)
|
|
762
|
+
? filePath
|
|
763
|
+
: (0, node_path_1.resolve)(this.config.workingDir, filePath);
|
|
609
764
|
}
|
|
610
765
|
async filterExistingFiles(filePaths) {
|
|
611
766
|
const normalizedFilePaths = Array.from(new Set(filePaths.map((filePath) => this.normalizeDiscoveredFilePath(filePath)))).sort();
|
|
@@ -687,9 +842,62 @@ async function getNextBuilderDeferred() {
|
|
|
687
842
|
}
|
|
688
843
|
const baseDirectory = (0, node_path_1.dirname)(bundleFilePath);
|
|
689
844
|
const localSourceFiles = new Set();
|
|
690
|
-
|
|
845
|
+
// Extract inline base64 sourcemaps via string scanning. A previous
|
|
846
|
+
// implementation used `bundleContents.matchAll(/...[A-Za-z0-9+/=]+.../g)`
|
|
847
|
+
// which overflows V8's regex stack
|
|
848
|
+
// (`RangeError: Maximum call stack size exceeded at RegExpStringIterator.next`)
|
|
849
|
+
// on bundles with large inline sourcemaps — V8's irregexp uses
|
|
850
|
+
// recursion for greedy character-class quantifiers and certain long
|
|
851
|
+
// base64 inputs exhaust the call stack.
|
|
852
|
+
const sourceMapPrefix = '//# sourceMappingURL=data:application/json';
|
|
853
|
+
const base64Marker = ';base64,';
|
|
854
|
+
const sourceMapMatches = [];
|
|
855
|
+
let scanFrom = 0;
|
|
856
|
+
while (scanFrom < bundleContents.length) {
|
|
857
|
+
const prefixIdx = bundleContents.indexOf(sourceMapPrefix, scanFrom);
|
|
858
|
+
if (prefixIdx === -1)
|
|
859
|
+
break;
|
|
860
|
+
const base64Start = bundleContents.indexOf(base64Marker, prefixIdx + sourceMapPrefix.length);
|
|
861
|
+
if (base64Start === -1) {
|
|
862
|
+
scanFrom = prefixIdx + sourceMapPrefix.length;
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
865
|
+
// Bail if a comma appears before `;base64,` — that means this
|
|
866
|
+
// wasn't a `data:application/json[;params];base64,...` URL after
|
|
867
|
+
// all (the comma would terminate the data URL parameters).
|
|
868
|
+
const commaBefore = bundleContents.indexOf(',', prefixIdx);
|
|
869
|
+
if (commaBefore !== -1 && commaBefore < base64Start) {
|
|
870
|
+
scanFrom = base64Start;
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
const valueStart = base64Start + base64Marker.length;
|
|
874
|
+
// Base64 payload terminates at first non-base64 char (newline,
|
|
875
|
+
// closing `*/`, etc.). Scanning a small alphabet by char is far
|
|
876
|
+
// cheaper than backtracking a regex over a multi-MB capture.
|
|
877
|
+
let valueEnd = valueStart;
|
|
878
|
+
while (valueEnd < bundleContents.length) {
|
|
879
|
+
const code = bundleContents.charCodeAt(valueEnd);
|
|
880
|
+
// A-Z 0x41-0x5A, a-z 0x61-0x7A, 0-9 0x30-0x39, '+' 0x2B,
|
|
881
|
+
// '/' 0x2F, '=' 0x3D
|
|
882
|
+
if (!((code >= 0x41 && code <= 0x5a) ||
|
|
883
|
+
(code >= 0x61 && code <= 0x7a) ||
|
|
884
|
+
(code >= 0x30 && code <= 0x39) ||
|
|
885
|
+
code === 0x2b ||
|
|
886
|
+
code === 0x2f ||
|
|
887
|
+
code === 0x3d)) {
|
|
888
|
+
break;
|
|
889
|
+
}
|
|
890
|
+
valueEnd++;
|
|
891
|
+
}
|
|
892
|
+
if (valueEnd > valueStart) {
|
|
893
|
+
sourceMapMatches.push({
|
|
894
|
+
base64Value: bundleContents.slice(valueStart, valueEnd),
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
scanFrom = valueEnd;
|
|
898
|
+
}
|
|
691
899
|
for (const match of sourceMapMatches) {
|
|
692
|
-
const base64Value = match
|
|
900
|
+
const base64Value = match.base64Value;
|
|
693
901
|
if (!base64Value) {
|
|
694
902
|
continue;
|
|
695
903
|
}
|
|
@@ -725,9 +933,12 @@ async function getNextBuilderDeferred() {
|
|
|
725
933
|
}
|
|
726
934
|
const normalizedSourcePath = this.normalizeDiscoveredFilePath(resolvedSourcePath);
|
|
727
935
|
const normalizedSourcePathForCheck = normalizedSourcePath.replace(/\\/g, '/');
|
|
936
|
+
const isSourceBackedPackagePath = this.shouldPreferSourceBackedPackagePath(normalizedSourcePath);
|
|
728
937
|
if (normalizedSourcePathForCheck.includes('/.well-known/workflow/') ||
|
|
729
|
-
|
|
730
|
-
|
|
938
|
+
(!isSourceBackedPackagePath &&
|
|
939
|
+
normalizedSourcePathForCheck.includes('/node_modules/')) ||
|
|
940
|
+
(!isSourceBackedPackagePath &&
|
|
941
|
+
normalizedSourcePathForCheck.includes('/.pnpm/')) ||
|
|
731
942
|
normalizedSourcePathForCheck.includes('/.next/') ||
|
|
732
943
|
normalizedSourcePathForCheck.endsWith('/virtual-entry.js')) {
|
|
733
944
|
continue;
|
|
@@ -749,9 +960,6 @@ async function getNextBuilderDeferred() {
|
|
|
749
960
|
}, 50);
|
|
750
961
|
}
|
|
751
962
|
scheduleDeferredRebuild() {
|
|
752
|
-
if (!this.config.watch) {
|
|
753
|
-
return;
|
|
754
|
-
}
|
|
755
963
|
if (this.deferredRebuildTimer) {
|
|
756
964
|
clearTimeout(this.deferredRebuildTimer);
|
|
757
965
|
}
|
|
@@ -826,35 +1034,61 @@ async function getNextBuilderDeferred() {
|
|
|
826
1034
|
].join('\n');
|
|
827
1035
|
const workflowGeneratedDir = (0, node_path_1.join)(outputDir, '.well-known/workflow/v1');
|
|
828
1036
|
await (0, promises_1.mkdir)((0, node_path_1.join)(workflowGeneratedDir, 'flow'), { recursive: true });
|
|
829
|
-
await (0, promises_1.mkdir)((0, node_path_1.join)(workflowGeneratedDir, 'step'), { recursive: true });
|
|
830
1037
|
await (0, promises_1.mkdir)((0, node_path_1.join)(workflowGeneratedDir, 'webhook/[token]'), {
|
|
831
1038
|
recursive: true,
|
|
832
1039
|
});
|
|
833
1040
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, '.gitignore'), '*');
|
|
834
|
-
//
|
|
835
|
-
//
|
|
1041
|
+
// V2: Only flow + webhook stubs needed (no separate step route).
|
|
1042
|
+
// Stubs are replaced by generated output once discovery finishes.
|
|
836
1043
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, 'flow/route.js'), routeStubContent);
|
|
837
|
-
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, 'step/route.js'), routeStubContent);
|
|
838
1044
|
await this.writeFileIfChanged((0, node_path_1.join)(workflowGeneratedDir, 'webhook/[token]/route.js'), routeStubContent);
|
|
839
1045
|
}
|
|
1046
|
+
async getInputFiles() {
|
|
1047
|
+
// Read Next.js's app-paths-manifest.json from a previous build to
|
|
1048
|
+
// determine which files are actual route entrypoints. This avoids
|
|
1049
|
+
// predicting Next.js conventions with regexes and instead reads
|
|
1050
|
+
// from Next.js's own output.
|
|
1051
|
+
const nextDir = (0, node_path_1.join)(this.config.workingDir, '.next');
|
|
1052
|
+
const manifestPath = (0, node_path_1.join)(nextDir, 'app-paths-manifest.json');
|
|
1053
|
+
try {
|
|
1054
|
+
const manifestContent = (0, node_fs_1.readFileSync)(manifestPath, 'utf-8');
|
|
1055
|
+
const manifest = JSON.parse(manifestContent);
|
|
1056
|
+
// The manifest maps route paths to their source files.
|
|
1057
|
+
// Extract the source file paths and resolve them.
|
|
1058
|
+
const manifestFiles = new Set();
|
|
1059
|
+
for (const sourcePath of Object.values(manifest)) {
|
|
1060
|
+
const resolved = (0, node_path_1.resolve)(nextDir, 'server', sourcePath);
|
|
1061
|
+
// The manifest points to built output; find the source file
|
|
1062
|
+
// by matching against the base builder's full file list.
|
|
1063
|
+
manifestFiles.add(resolved);
|
|
1064
|
+
}
|
|
1065
|
+
// Use the manifest route paths to filter the input files.
|
|
1066
|
+
// A file is included if it matches a known route segment from
|
|
1067
|
+
// the manifest (e.g., app/api/route contains 'app/api/route').
|
|
1068
|
+
const inputFiles = await super.getInputFiles();
|
|
1069
|
+
const routeSegments = Object.keys(manifest).map((route) => route.replace(/^\//, '').replace(/\/route$/, ''));
|
|
1070
|
+
return inputFiles.filter((item) => routeSegments.some((segment) => item.includes(segment)));
|
|
1071
|
+
}
|
|
1072
|
+
catch {
|
|
1073
|
+
// No manifest from a previous build — fall back to the base
|
|
1074
|
+
// builder's full file scan. This is safe but slower; subsequent
|
|
1075
|
+
// builds will use the manifest.
|
|
1076
|
+
return super.getInputFiles();
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
840
1079
|
async writeFunctionsConfig(outputDir) {
|
|
841
1080
|
// we don't run this in development mode as it's not needed
|
|
842
1081
|
if (process.env.NODE_ENV === 'development') {
|
|
843
1082
|
return;
|
|
844
1083
|
}
|
|
1084
|
+
// V2: Single combined trigger handles both workflow and step execution
|
|
845
1085
|
const generatedConfig = {
|
|
846
1086
|
version: '0',
|
|
847
|
-
steps: {
|
|
848
|
-
maxDuration: 'max',
|
|
849
|
-
experimentalTriggers: [STEP_QUEUE_TRIGGER],
|
|
850
|
-
},
|
|
851
1087
|
workflows: {
|
|
852
1088
|
maxDuration: 'max',
|
|
853
1089
|
experimentalTriggers: [WORKFLOW_QUEUE_TRIGGER],
|
|
854
1090
|
},
|
|
855
1091
|
};
|
|
856
|
-
// We write this file to the generated directory for
|
|
857
|
-
// the Next.js builder to consume
|
|
858
1092
|
await this.writeFileIfChanged((0, node_path_1.join)(outputDir, '.well-known/workflow/v1/config.json'), JSON.stringify(generatedConfig, null, 2));
|
|
859
1093
|
}
|
|
860
1094
|
async writeFileIfChanged(filePath, contents) {
|
|
@@ -901,16 +1135,26 @@ async function getNextBuilderDeferred() {
|
|
|
901
1135
|
// Manifest may not exist (e.g. manifest generation failed); ignore.
|
|
902
1136
|
}
|
|
903
1137
|
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1138
|
+
extractRelativeImportSpecifiers(source) {
|
|
1139
|
+
return this.extractImportSpecifiers(source).filter((specifier) => specifier.startsWith('.'));
|
|
1140
|
+
}
|
|
1141
|
+
extractImportSpecifiers(source) {
|
|
1142
|
+
const relativeSpecifiers = new Set();
|
|
1143
|
+
const importPatterns = [
|
|
1144
|
+
/from\s+['"]([^'"]+)['"]/g,
|
|
1145
|
+
/import\s+['"]([^'"]+)['"]/g,
|
|
1146
|
+
/import\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
1147
|
+
/require\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
1148
|
+
];
|
|
1149
|
+
for (const importPattern of importPatterns) {
|
|
1150
|
+
for (const match of source.matchAll(importPattern)) {
|
|
1151
|
+
const specifier = match[1];
|
|
1152
|
+
if (specifier) {
|
|
1153
|
+
relativeSpecifiers.add(specifier);
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
913
1156
|
}
|
|
1157
|
+
return Array.from(relativeSpecifiers);
|
|
914
1158
|
}
|
|
915
1159
|
async getRelativeFilenameForSwc(filePath) {
|
|
916
1160
|
const workingDir = this.config.workingDir;
|
|
@@ -948,98 +1192,7 @@ async function getNextBuilderDeferred() {
|
|
|
948
1192
|
}
|
|
949
1193
|
return relativeFilename;
|
|
950
1194
|
}
|
|
951
|
-
|
|
952
|
-
let relativePath = (0, node_path_1.relative)((0, node_path_1.dirname)(fromFilePath), toFilePath).replace(/\\/g, '/');
|
|
953
|
-
if (!relativePath.startsWith('.')) {
|
|
954
|
-
relativePath = `./${relativePath}`;
|
|
955
|
-
}
|
|
956
|
-
return relativePath;
|
|
957
|
-
}
|
|
958
|
-
getStepCopyFileName(filePath) {
|
|
959
|
-
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
960
|
-
const hash = (0, node_crypto_1.createHash)('sha256').update(normalizedPath).digest('hex');
|
|
961
|
-
const extension = (0, node_path_1.extname)(normalizedPath);
|
|
962
|
-
return `${hash.slice(0, 16)}${extension || '.js'}`;
|
|
963
|
-
}
|
|
964
|
-
rewriteCopiedStepImportSpecifier(specifier, sourceFilePath, copiedFilePath, copiedStepFileBySourcePath) {
|
|
965
|
-
if (!specifier.startsWith('.')) {
|
|
966
|
-
// Bare specifiers (e.g. '@workflow/serde') that are transitive
|
|
967
|
-
// dependencies of SDK packages can't be resolved by the bundler
|
|
968
|
-
// from the copied file's location (__workflow_step_files__/ inside
|
|
969
|
-
// the app dir) because the app doesn't directly depend on them.
|
|
970
|
-
//
|
|
971
|
-
// Only rewrite when the specifier can't be resolved from the app
|
|
972
|
-
// directory. If the package is a direct dependency of the app,
|
|
973
|
-
// the bare specifier will resolve normally and should be left as-is.
|
|
974
|
-
const appResolvable = this.resolveBareCopiedStepSpecifier(specifier, copiedFilePath);
|
|
975
|
-
if (!appResolvable) {
|
|
976
|
-
const resolved = this.resolveBareCopiedStepSpecifier(specifier, sourceFilePath);
|
|
977
|
-
if (!resolved)
|
|
978
|
-
return specifier;
|
|
979
|
-
let rewrittenPath = (0, node_path_1.relative)((0, node_path_1.dirname)(copiedFilePath), resolved).replace(/\\/g, '/');
|
|
980
|
-
if (!rewrittenPath.startsWith('.')) {
|
|
981
|
-
rewrittenPath = `./${rewrittenPath}`;
|
|
982
|
-
}
|
|
983
|
-
return rewrittenPath;
|
|
984
|
-
}
|
|
985
|
-
return specifier;
|
|
986
|
-
}
|
|
987
|
-
const specifierMatch = specifier.match(/^([^?#]+)(.*)$/);
|
|
988
|
-
const importPath = specifierMatch?.[1] ?? specifier;
|
|
989
|
-
const suffix = specifierMatch?.[2] ?? '';
|
|
990
|
-
const absoluteTargetPath = (0, node_path_1.resolve)((0, node_path_1.dirname)(sourceFilePath), importPath);
|
|
991
|
-
const resolvedTargetPath = this.resolveCopiedStepImportTargetPath(absoluteTargetPath);
|
|
992
|
-
const normalizedTargetPath = resolvedTargetPath.replace(/\\/g, '/');
|
|
993
|
-
const copiedTargetPath = copiedStepFileBySourcePath.get(normalizedTargetPath) ||
|
|
994
|
-
(() => {
|
|
995
|
-
try {
|
|
996
|
-
const realTargetPath = (0, node_fs_1.realpathSync)(resolvedTargetPath).replace(/\\/g, '/');
|
|
997
|
-
return copiedStepFileBySourcePath.get(realTargetPath);
|
|
998
|
-
}
|
|
999
|
-
catch {
|
|
1000
|
-
return undefined;
|
|
1001
|
-
}
|
|
1002
|
-
})();
|
|
1003
|
-
let rewrittenPath = (0, node_path_1.relative)((0, node_path_1.dirname)(copiedFilePath), copiedTargetPath || resolvedTargetPath).replace(/\\/g, '/');
|
|
1004
|
-
if (!rewrittenPath.startsWith('.')) {
|
|
1005
|
-
rewrittenPath = `./${rewrittenPath}`;
|
|
1006
|
-
}
|
|
1007
|
-
return `${rewrittenPath}${suffix}`;
|
|
1008
|
-
}
|
|
1009
|
-
/**
|
|
1010
|
-
* Resolves a bare specifier (e.g. '@workflow/serde', 'workflow') to an
|
|
1011
|
-
* absolute file path using ESM-compatible resolution semantics via
|
|
1012
|
-
* `enhanced-resolve`. Tries ESM conditions first (`node`, `import`),
|
|
1013
|
-
* falling back to CJS resolution if ESM fails.
|
|
1014
|
-
*/
|
|
1015
|
-
resolveBareCopiedStepSpecifier(specifier, sourceFilePath) {
|
|
1016
|
-
if (!this.esmSyncResolver) {
|
|
1017
|
-
this.esmSyncResolver = enhanced_resolve_1.default.create.sync(NODE_ESM_RESOLVE_OPTIONS);
|
|
1018
|
-
}
|
|
1019
|
-
if (!this.cjsSyncResolver) {
|
|
1020
|
-
this.cjsSyncResolver =
|
|
1021
|
-
enhanced_resolve_1.default.create.sync(NODE_RESOLVE_OPTIONS);
|
|
1022
|
-
}
|
|
1023
|
-
const context = (0, node_path_1.dirname)(sourceFilePath);
|
|
1024
|
-
try {
|
|
1025
|
-
const resolved = this.esmSyncResolver(context, specifier);
|
|
1026
|
-
if (resolved)
|
|
1027
|
-
return resolved;
|
|
1028
|
-
}
|
|
1029
|
-
catch {
|
|
1030
|
-
// ESM resolution failed, try CJS
|
|
1031
|
-
}
|
|
1032
|
-
try {
|
|
1033
|
-
const resolved = this.cjsSyncResolver(context, specifier);
|
|
1034
|
-
if (resolved)
|
|
1035
|
-
return resolved;
|
|
1036
|
-
}
|
|
1037
|
-
catch {
|
|
1038
|
-
// CJS resolution also failed
|
|
1039
|
-
}
|
|
1040
|
-
return undefined;
|
|
1041
|
-
}
|
|
1042
|
-
resolveCopiedStepImportTargetPath(targetPath) {
|
|
1195
|
+
resolveImportTargetWithExtensionFallbacks(targetPath) {
|
|
1043
1196
|
if ((0, node_fs_1.existsSync)(targetPath)) {
|
|
1044
1197
|
return targetPath;
|
|
1045
1198
|
}
|
|
@@ -1069,51 +1222,38 @@ async function getNextBuilderDeferred() {
|
|
|
1069
1222
|
}
|
|
1070
1223
|
return targetPath;
|
|
1071
1224
|
}
|
|
1072
|
-
rewriteRelativeImportsForCopiedStep(source, sourceFilePath, copiedFilePath, copiedStepFileBySourcePath) {
|
|
1073
|
-
const rewriteSpecifier = (specifier) => this.rewriteCopiedStepImportSpecifier(specifier, sourceFilePath, copiedFilePath, copiedStepFileBySourcePath);
|
|
1074
|
-
const rewritePattern = (currentSource, pattern) => currentSource.replace(pattern, (_match, prefix, specifier, suffix) => `${prefix}${rewriteSpecifier(specifier)}${suffix}`);
|
|
1075
|
-
let rewrittenSource = source;
|
|
1076
|
-
rewrittenSource = rewritePattern(rewrittenSource, /(from\s+['"])([^'"]+)(['"])/g);
|
|
1077
|
-
rewrittenSource = rewritePattern(rewrittenSource, /(import\s+['"])([^'"]+)(['"])/g);
|
|
1078
|
-
rewrittenSource = rewritePattern(rewrittenSource, /(import\(\s*['"])([^'"]+)(['"]\s*\))/g);
|
|
1079
|
-
rewrittenSource = rewritePattern(rewrittenSource, /(require\(\s*['"])([^'"]+)(['"]\s*\))/g);
|
|
1080
|
-
return rewrittenSource;
|
|
1081
|
-
}
|
|
1082
|
-
extractRelativeImportSpecifiers(source) {
|
|
1083
|
-
const relativeSpecifiers = new Set();
|
|
1084
|
-
const importPatterns = [
|
|
1085
|
-
/from\s+['"]([^'"]+)['"]/g,
|
|
1086
|
-
/import\s+['"]([^'"]+)['"]/g,
|
|
1087
|
-
/import\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
1088
|
-
/require\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
1089
|
-
];
|
|
1090
|
-
for (const importPattern of importPatterns) {
|
|
1091
|
-
for (const match of source.matchAll(importPattern)) {
|
|
1092
|
-
const specifier = match[1];
|
|
1093
|
-
if (specifier?.startsWith('.')) {
|
|
1094
|
-
relativeSpecifiers.add(specifier);
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
return Array.from(relativeSpecifiers);
|
|
1099
|
-
}
|
|
1100
|
-
isGeneratedWorkflowArtifact(filePath) {
|
|
1101
|
-
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
1102
|
-
return (normalizedPath.includes('/.well-known/workflow/') ||
|
|
1103
|
-
normalizedPath.includes('/.next/'));
|
|
1104
|
-
}
|
|
1105
1225
|
shouldSkipTransitiveStepFile(filePath) {
|
|
1106
1226
|
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
normalizedPath.includes('/.
|
|
1227
|
+
const isSourceBackedPackagePath = this.shouldPreferSourceBackedPackagePath(filePath);
|
|
1228
|
+
return (normalizedPath.includes('/.well-known/workflow/') ||
|
|
1229
|
+
normalizedPath.includes('/.next/') ||
|
|
1230
|
+
(!isSourceBackedPackagePath &&
|
|
1231
|
+
(normalizedPath.includes('/node_modules/') ||
|
|
1232
|
+
normalizedPath.includes('/.pnpm/'))));
|
|
1110
1233
|
}
|
|
1111
1234
|
async resolveTransitiveStepImportTargetPath(sourceFilePath, specifier) {
|
|
1112
1235
|
const specifierMatch = specifier.match(/^([^?#]+)(.*)$/);
|
|
1113
1236
|
const importPath = specifierMatch?.[1] ?? specifier;
|
|
1237
|
+
if (!importPath.startsWith('.')) {
|
|
1238
|
+
if (importPath !== 'workflow' && !importPath.startsWith('@workflow/')) {
|
|
1239
|
+
return null;
|
|
1240
|
+
}
|
|
1241
|
+
try {
|
|
1242
|
+
const resolvedPath = (0, node_module_1.createRequire)(sourceFilePath).resolve(importPath);
|
|
1243
|
+
const normalizedResolvedPath = this.normalizeDiscoveredFilePath(resolvedPath);
|
|
1244
|
+
if (this.shouldSkipTransitiveStepFile(normalizedResolvedPath)) {
|
|
1245
|
+
return null;
|
|
1246
|
+
}
|
|
1247
|
+
const fileStats = await (0, promises_1.stat)(normalizedResolvedPath);
|
|
1248
|
+
return fileStats.isFile() ? normalizedResolvedPath : null;
|
|
1249
|
+
}
|
|
1250
|
+
catch {
|
|
1251
|
+
return null;
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1114
1254
|
const absoluteTargetPath = (0, node_path_1.resolve)((0, node_path_1.dirname)(sourceFilePath), importPath);
|
|
1115
1255
|
const candidatePaths = new Set([
|
|
1116
|
-
this.
|
|
1256
|
+
this.resolveImportTargetWithExtensionFallbacks(absoluteTargetPath),
|
|
1117
1257
|
]);
|
|
1118
1258
|
if (!(0, node_path_1.extname)(absoluteTargetPath)) {
|
|
1119
1259
|
const extensionCandidates = [
|
|
@@ -1132,7 +1272,7 @@ async function getNextBuilderDeferred() {
|
|
|
1132
1272
|
}
|
|
1133
1273
|
}
|
|
1134
1274
|
for (const candidatePath of candidatePaths) {
|
|
1135
|
-
const resolvedPath = this.
|
|
1275
|
+
const resolvedPath = this.resolveImportTargetWithExtensionFallbacks(candidatePath);
|
|
1136
1276
|
const normalizedResolvedPath = this.normalizeDiscoveredFilePath(resolvedPath);
|
|
1137
1277
|
if (this.shouldSkipTransitiveStepFile(normalizedResolvedPath)) {
|
|
1138
1278
|
continue;
|
|
@@ -1149,13 +1289,11 @@ async function getNextBuilderDeferred() {
|
|
|
1149
1289
|
}
|
|
1150
1290
|
return null;
|
|
1151
1291
|
}
|
|
1152
|
-
async collectTransitiveStepFiles({
|
|
1153
|
-
const
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
const discoveredStepFiles = new Set();
|
|
1158
|
-
const queuedFiles = [...normalizedSeedFiles];
|
|
1292
|
+
async collectTransitiveStepFiles({ entryFiles, stepFiles, }) {
|
|
1293
|
+
const normalizedEntryFiles = Array.from(new Set(entryFiles.map((entryFile) => this.normalizeDiscoveredFilePath(entryFile)))).sort();
|
|
1294
|
+
const normalizedStepSeedFiles = Array.from(new Set(stepFiles.map((stepFile) => this.normalizeDiscoveredFilePath(stepFile)))).sort();
|
|
1295
|
+
const discoveredStepFiles = new Set(normalizedStepSeedFiles);
|
|
1296
|
+
const queuedFiles = Array.from(new Set([...normalizedEntryFiles, ...normalizedStepSeedFiles]));
|
|
1159
1297
|
const visitedFiles = new Set();
|
|
1160
1298
|
const sourceCache = new Map();
|
|
1161
1299
|
const patternCache = new Map();
|
|
@@ -1196,12 +1334,8 @@ async function getNextBuilderDeferred() {
|
|
|
1196
1334
|
if (currentSource === null) {
|
|
1197
1335
|
continue;
|
|
1198
1336
|
}
|
|
1199
|
-
const
|
|
1200
|
-
|
|
1201
|
-
discoveredStepFiles.add(currentFile);
|
|
1202
|
-
}
|
|
1203
|
-
const relativeImportSpecifiers = this.extractRelativeImportSpecifiers(currentSource);
|
|
1204
|
-
for (const specifier of relativeImportSpecifiers) {
|
|
1337
|
+
const importSpecifiers = this.extractImportSpecifiers(currentSource);
|
|
1338
|
+
for (const specifier of importSpecifiers) {
|
|
1205
1339
|
const resolvedImportPath = await this.resolveTransitiveStepImportTargetPath(currentFile, specifier);
|
|
1206
1340
|
if (!resolvedImportPath) {
|
|
1207
1341
|
continue;
|
|
@@ -1298,7 +1432,7 @@ async function getNextBuilderDeferred() {
|
|
|
1298
1432
|
return;
|
|
1299
1433
|
try {
|
|
1300
1434
|
const relativeFilename = await this.getRelativeFilenameForSwc(filePath);
|
|
1301
|
-
const { workflowManifest } = await applySwcTransform(relativeFilename, source, 'detect', filePath, projectRoot);
|
|
1435
|
+
const { workflowManifest } = await applySwcTransform(relativeFilename, source, 'detect', filePath, projectRoot, this.moduleSpecifierRoot);
|
|
1302
1436
|
// Only include files that actually define serde classes
|
|
1303
1437
|
const hasClasses = workflowManifest.classes &&
|
|
1304
1438
|
Object.values(workflowManifest.classes).some((entries) => Object.keys(entries).length > 0);
|
|
@@ -1313,225 +1447,6 @@ async function getNextBuilderDeferred() {
|
|
|
1313
1447
|
}));
|
|
1314
1448
|
return verifiedSerdeFiles.sort();
|
|
1315
1449
|
}
|
|
1316
|
-
async createResponseBuiltinsStepFile({ stepsRouteDir, }) {
|
|
1317
|
-
const copiedStepsDir = (0, node_path_1.join)(stepsRouteDir, step_copy_utils_js_1.DEFERRED_STEP_COPY_DIR_NAME);
|
|
1318
|
-
await (0, promises_1.mkdir)(copiedStepsDir, { recursive: true });
|
|
1319
|
-
const responseBuiltinsFilePath = (0, node_path_1.join)(copiedStepsDir, 'workflow-response-builtins.ts');
|
|
1320
|
-
const source = [
|
|
1321
|
-
'export async function __builtin_response_array_buffer(this: Request | Response) {',
|
|
1322
|
-
" 'use step';",
|
|
1323
|
-
' return this.arrayBuffer();',
|
|
1324
|
-
'}',
|
|
1325
|
-
'',
|
|
1326
|
-
'export async function __builtin_response_json(this: Request | Response) {',
|
|
1327
|
-
" 'use step';",
|
|
1328
|
-
' return this.json();',
|
|
1329
|
-
'}',
|
|
1330
|
-
'',
|
|
1331
|
-
'export async function __builtin_response_text(this: Request | Response) {',
|
|
1332
|
-
" 'use step';",
|
|
1333
|
-
' return this.text();',
|
|
1334
|
-
'}',
|
|
1335
|
-
].join('\n');
|
|
1336
|
-
const sourceMapComment = (0, step_copy_utils_js_1.createDeferredStepCopyInlineSourceMapComment)({
|
|
1337
|
-
sourcePath: responseBuiltinsFilePath,
|
|
1338
|
-
sourceContent: source,
|
|
1339
|
-
});
|
|
1340
|
-
await this.writeFileIfChanged(responseBuiltinsFilePath, `${source}\n${sourceMapComment}\n`);
|
|
1341
|
-
return responseBuiltinsFilePath;
|
|
1342
|
-
}
|
|
1343
|
-
async copyDiscoveredStepFiles({ stepFiles, stepsRouteDir, preserveFileNames = [], }) {
|
|
1344
|
-
const copiedStepsDir = (0, node_path_1.join)(stepsRouteDir, step_copy_utils_js_1.DEFERRED_STEP_COPY_DIR_NAME);
|
|
1345
|
-
await (0, promises_1.mkdir)(copiedStepsDir, { recursive: true });
|
|
1346
|
-
const normalizedStepFiles = Array.from(new Set(stepFiles.map((stepFile) => this.normalizeDiscoveredFilePath(stepFile)))).sort();
|
|
1347
|
-
const copiedStepFileBySourcePath = new Map();
|
|
1348
|
-
const expectedFileNames = new Set(preserveFileNames);
|
|
1349
|
-
const copiedStepFiles = [];
|
|
1350
|
-
for (const normalizedStepFile of normalizedStepFiles) {
|
|
1351
|
-
const copiedFileName = this.getStepCopyFileName(normalizedStepFile);
|
|
1352
|
-
const copiedFilePath = (0, node_path_1.join)(copiedStepsDir, copiedFileName);
|
|
1353
|
-
const normalizedPathKey = normalizedStepFile.replace(/\\/g, '/');
|
|
1354
|
-
copiedStepFileBySourcePath.set(normalizedPathKey, copiedFilePath);
|
|
1355
|
-
try {
|
|
1356
|
-
const realPathKey = (0, node_fs_1.realpathSync)(normalizedStepFile).replace(/\\/g, '/');
|
|
1357
|
-
copiedStepFileBySourcePath.set(realPathKey, copiedFilePath);
|
|
1358
|
-
}
|
|
1359
|
-
catch {
|
|
1360
|
-
// Keep best-effort mapping when source cannot be realpath-resolved.
|
|
1361
|
-
}
|
|
1362
|
-
expectedFileNames.add(copiedFileName);
|
|
1363
|
-
copiedStepFiles.push(copiedFilePath);
|
|
1364
|
-
}
|
|
1365
|
-
for (const normalizedStepFile of normalizedStepFiles) {
|
|
1366
|
-
const source = await (0, promises_1.readFile)(normalizedStepFile, 'utf-8');
|
|
1367
|
-
const copiedFilePath = copiedStepFileBySourcePath.get(normalizedStepFile.replace(/\\/g, '/'));
|
|
1368
|
-
if (!copiedFilePath) {
|
|
1369
|
-
continue;
|
|
1370
|
-
}
|
|
1371
|
-
const rewrittenSource = this.rewriteRelativeImportsForCopiedStep(source, normalizedStepFile, copiedFilePath, copiedStepFileBySourcePath);
|
|
1372
|
-
const metadataComment = (0, step_copy_utils_js_1.createDeferredStepSourceMetadataComment)({
|
|
1373
|
-
relativeFilename: await this.getRelativeFilenameForSwc(normalizedStepFile),
|
|
1374
|
-
absolutePath: normalizedStepFile.replace(/\\/g, '/'),
|
|
1375
|
-
});
|
|
1376
|
-
const sourceMapComment = (0, step_copy_utils_js_1.createDeferredStepCopyInlineSourceMapComment)({
|
|
1377
|
-
sourcePath: normalizedStepFile,
|
|
1378
|
-
sourceContent: source,
|
|
1379
|
-
generatedContent: rewrittenSource,
|
|
1380
|
-
});
|
|
1381
|
-
const copiedSource = `${metadataComment}\n${rewrittenSource}\n${sourceMapComment}`;
|
|
1382
|
-
await this.writeFileIfChanged(copiedFilePath, copiedSource);
|
|
1383
|
-
}
|
|
1384
|
-
const existingEntries = await (0, promises_1.readdir)(copiedStepsDir, {
|
|
1385
|
-
withFileTypes: true,
|
|
1386
|
-
}).catch(() => []);
|
|
1387
|
-
await Promise.all(existingEntries
|
|
1388
|
-
.filter((entry) => !expectedFileNames.has(entry.name))
|
|
1389
|
-
.map((entry) => (0, promises_1.rm)((0, node_path_1.join)(copiedStepsDir, entry.name), {
|
|
1390
|
-
recursive: true,
|
|
1391
|
-
force: true,
|
|
1392
|
-
})));
|
|
1393
|
-
return copiedStepFiles;
|
|
1394
|
-
}
|
|
1395
|
-
async createDeferredStepsManifest({ stepFiles, workflowFiles, serdeOnlyFiles, }) {
|
|
1396
|
-
const workflowManifest = {};
|
|
1397
|
-
const filesForStepTransform = Array.from(new Set([...stepFiles, ...serdeOnlyFiles])).sort();
|
|
1398
|
-
await Promise.all(filesForStepTransform.map(async (stepFile) => {
|
|
1399
|
-
const source = await (0, promises_1.readFile)(stepFile, 'utf-8');
|
|
1400
|
-
const relativeFilename = await this.getRelativeFilenameForSwc(stepFile);
|
|
1401
|
-
const { workflowManifest: fileManifest } = await applySwcTransform(relativeFilename, source, 'step', stepFile, this.config.projectRoot || this.config.workingDir);
|
|
1402
|
-
this.mergeWorkflowManifest(workflowManifest, fileManifest);
|
|
1403
|
-
}));
|
|
1404
|
-
const stepFileSet = new Set(stepFiles);
|
|
1405
|
-
const workflowOnlyFiles = workflowFiles
|
|
1406
|
-
.filter((workflowFile) => !stepFileSet.has(workflowFile))
|
|
1407
|
-
.sort();
|
|
1408
|
-
await Promise.all(workflowOnlyFiles.map(async (workflowFile) => {
|
|
1409
|
-
try {
|
|
1410
|
-
const source = await (0, promises_1.readFile)(workflowFile, 'utf-8');
|
|
1411
|
-
const relativeFilename = await this.getRelativeFilenameForSwc(workflowFile);
|
|
1412
|
-
const { workflowManifest: fileManifest } = await applySwcTransform(relativeFilename, source, 'workflow', workflowFile, this.config.projectRoot || this.config.workingDir);
|
|
1413
|
-
this.mergeWorkflowManifest(workflowManifest, {
|
|
1414
|
-
workflows: fileManifest.workflows,
|
|
1415
|
-
classes: fileManifest.classes,
|
|
1416
|
-
});
|
|
1417
|
-
}
|
|
1418
|
-
catch (error) {
|
|
1419
|
-
console.log(`Warning: Failed to extract workflow metadata from ${workflowFile}:`, error instanceof Error ? error.message : String(error));
|
|
1420
|
-
}
|
|
1421
|
-
}));
|
|
1422
|
-
return workflowManifest;
|
|
1423
|
-
}
|
|
1424
|
-
async collectManifestStepSourceFiles(manifest) {
|
|
1425
|
-
const manifestStepEntries = Object.keys(manifest.steps || {});
|
|
1426
|
-
if (manifestStepEntries.length === 0) {
|
|
1427
|
-
return [];
|
|
1428
|
-
}
|
|
1429
|
-
const resolveBaseDirs = this.getManifestStepResolveBaseDirs();
|
|
1430
|
-
const candidateFiles = manifestStepEntries
|
|
1431
|
-
.flatMap((stepEntry) => {
|
|
1432
|
-
if ((0, node_path_1.isAbsolute)(stepEntry)) {
|
|
1433
|
-
return [this.normalizeDiscoveredFilePath(stepEntry)];
|
|
1434
|
-
}
|
|
1435
|
-
return resolveBaseDirs.map((baseDir) => this.normalizeDiscoveredFilePath((0, node_path_1.resolve)(baseDir, stepEntry)));
|
|
1436
|
-
})
|
|
1437
|
-
.filter((candidateFile) => !this.isGeneratedWorkflowArtifact(candidateFile));
|
|
1438
|
-
const existingCandidates = await this.filterExistingFiles(candidateFiles);
|
|
1439
|
-
return Array.from(new Set(existingCandidates)).sort();
|
|
1440
|
-
}
|
|
1441
|
-
async buildStepsFunction({ workflowGeneratedDir, routeFileName = 'route.js', discoveredEntries, additionalStepSourceManifest, }) {
|
|
1442
|
-
const stepsRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'step');
|
|
1443
|
-
await (0, promises_1.mkdir)(stepsRouteDir, { recursive: true });
|
|
1444
|
-
const discovered = discoveredEntries;
|
|
1445
|
-
const workflowFiles = [...discovered.discoveredWorkflows].sort();
|
|
1446
|
-
const stepFiles = await this.collectTransitiveStepFiles({
|
|
1447
|
-
stepFiles: [...discovered.discoveredSteps].sort(),
|
|
1448
|
-
// Workflow transforms can inline step IDs and remove runtime imports,
|
|
1449
|
-
// so seed transitive traversal with workflow files too.
|
|
1450
|
-
seedFiles: workflowFiles,
|
|
1451
|
-
});
|
|
1452
|
-
const serdeFiles = [...discovered.discoveredSerdeFiles].sort();
|
|
1453
|
-
const stepFileSet = new Set(stepFiles);
|
|
1454
|
-
const serdeOnlyFiles = serdeFiles.filter((file) => !stepFileSet.has(file));
|
|
1455
|
-
const additionalManifestStepFiles = additionalStepSourceManifest
|
|
1456
|
-
? await this.collectManifestStepSourceFiles(additionalStepSourceManifest)
|
|
1457
|
-
: [];
|
|
1458
|
-
const stepFilesWithManifestSources = Array.from(new Set([...stepFiles, ...additionalManifestStepFiles])).sort();
|
|
1459
|
-
const responseBuiltinsStepFilePath = await this.createResponseBuiltinsStepFile({
|
|
1460
|
-
stepsRouteDir,
|
|
1461
|
-
});
|
|
1462
|
-
const manifestStepFiles = Array.from(new Set([...stepFilesWithManifestSources, responseBuiltinsStepFilePath])).sort();
|
|
1463
|
-
const manifest = await this.createDeferredStepsManifest({
|
|
1464
|
-
stepFiles: manifestStepFiles,
|
|
1465
|
-
workflowFiles,
|
|
1466
|
-
serdeOnlyFiles,
|
|
1467
|
-
});
|
|
1468
|
-
const manifestDiscoveredStepFiles = await this.collectManifestStepSourceFiles(manifest);
|
|
1469
|
-
// Copy all discovered step sources so they are transformed in step mode.
|
|
1470
|
-
// Importing raw node_modules files directly can bypass loader transforms,
|
|
1471
|
-
// which prevents step registrars from being emitted.
|
|
1472
|
-
const copiedStepSourceFiles = Array.from(new Set([
|
|
1473
|
-
...stepFilesWithManifestSources,
|
|
1474
|
-
...manifestDiscoveredStepFiles,
|
|
1475
|
-
])).sort();
|
|
1476
|
-
const copiedDiscoveredStepFiles = await this.copyDiscoveredStepFiles({
|
|
1477
|
-
stepFiles: copiedStepSourceFiles,
|
|
1478
|
-
stepsRouteDir,
|
|
1479
|
-
preserveFileNames: [(0, node_path_1.basename)(responseBuiltinsStepFilePath)],
|
|
1480
|
-
});
|
|
1481
|
-
const copiedStepFiles = [
|
|
1482
|
-
responseBuiltinsStepFilePath,
|
|
1483
|
-
...copiedDiscoveredStepFiles,
|
|
1484
|
-
];
|
|
1485
|
-
const stepRouteFile = (0, node_path_1.join)(stepsRouteDir, routeFileName);
|
|
1486
|
-
const copiedStepImports = copiedStepFiles
|
|
1487
|
-
.map((copiedStepFile) => {
|
|
1488
|
-
const importSpecifier = this.getRelativeImportSpecifier(stepRouteFile, copiedStepFile);
|
|
1489
|
-
return `import '${importSpecifier}';`;
|
|
1490
|
-
})
|
|
1491
|
-
.join('\n');
|
|
1492
|
-
const serdeImports = serdeOnlyFiles
|
|
1493
|
-
.map((serdeFile) => {
|
|
1494
|
-
const normalizedSerdeFile = this.normalizeDiscoveredFilePath(serdeFile);
|
|
1495
|
-
const { importPath, isPackage } = getImportPath(normalizedSerdeFile, this.config.workingDir);
|
|
1496
|
-
if (isPackage) {
|
|
1497
|
-
return `import '${importPath}';`;
|
|
1498
|
-
}
|
|
1499
|
-
const importSpecifier = this.getRelativeImportSpecifier(stepRouteFile, normalizedSerdeFile);
|
|
1500
|
-
return `import '${importSpecifier}';`;
|
|
1501
|
-
})
|
|
1502
|
-
.join('\n');
|
|
1503
|
-
const routeContents = [
|
|
1504
|
-
'// biome-ignore-all lint: generated file',
|
|
1505
|
-
'/* eslint-disable */',
|
|
1506
|
-
copiedStepImports,
|
|
1507
|
-
serdeImports
|
|
1508
|
-
? `// Serde files for cross-context class registration\n${serdeImports}`
|
|
1509
|
-
: '',
|
|
1510
|
-
"export { stepEntrypoint as POST } from 'workflow/runtime';",
|
|
1511
|
-
]
|
|
1512
|
-
.filter(Boolean)
|
|
1513
|
-
.join('\n');
|
|
1514
|
-
await this.writeFileIfChanged(stepRouteFile, routeContents);
|
|
1515
|
-
return {
|
|
1516
|
-
context: undefined,
|
|
1517
|
-
manifest,
|
|
1518
|
-
};
|
|
1519
|
-
}
|
|
1520
|
-
async buildWorkflowsFunction({ inputFiles, workflowGeneratedDir, tsconfigPath, routeFileName = 'route.js', discoveredEntries, }) {
|
|
1521
|
-
const workflowsRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'flow');
|
|
1522
|
-
await (0, promises_1.mkdir)(workflowsRouteDir, { recursive: true });
|
|
1523
|
-
return await this.createWorkflowsBundle({
|
|
1524
|
-
format: 'esm',
|
|
1525
|
-
outfile: (0, node_path_1.join)(workflowsRouteDir, routeFileName),
|
|
1526
|
-
bundleFinalOutput: false,
|
|
1527
|
-
// Deferred builds do not reuse the interim esbuild context. Dispose it
|
|
1528
|
-
// after each pass to avoid leaking contexts during watch-mode rebuilds.
|
|
1529
|
-
keepInterimBundleContext: false,
|
|
1530
|
-
inputFiles,
|
|
1531
|
-
tsconfigPath,
|
|
1532
|
-
discoveredEntries,
|
|
1533
|
-
});
|
|
1534
|
-
}
|
|
1535
1450
|
async buildWebhookRoute({ workflowGeneratedDir, routeFileName = 'route.js', }) {
|
|
1536
1451
|
const webhookRouteFile = (0, node_path_1.join)(workflowGeneratedDir, `webhook/[token]/${routeFileName}`);
|
|
1537
1452
|
await this.createWebhookBundle({
|
|
@@ -1586,4 +1501,4 @@ async function getNextBuilderDeferred() {
|
|
|
1586
1501
|
CachedNextBuilderDeferred = NextDeferredBuilder;
|
|
1587
1502
|
return NextDeferredBuilder;
|
|
1588
1503
|
}
|
|
1589
|
-
//# sourceMappingURL=builder-deferred.js.map
|
|
1504
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci1kZWZlcnJlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9idWlsZGVyLWRlZmVycmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBeUNBLHdEQWlpRUM7QUExa0VELDZDQUF5QztBQUN6QyxxQ0FBOEQ7QUFDOUQsK0NBUzBCO0FBQzFCLDZDQUE0QztBQUM1QyxzREFBeUI7QUFDekIseUNBUW1CO0FBRW5CLHlEQU00QjtBQUU1QixNQUFNLHNCQUFzQixHQUFHLDBCQUEwQixDQUFDO0FBQzFELE1BQU0sNEJBQTRCLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUM5QyxNQUFNLDBCQUEwQixHQUFHLHFCQUFxQixDQUFDO0FBRXpELElBQUkseUJBQThCLENBQUM7QUFFbkMsaUZBQWlGO0FBQ2pGLGdGQUFnRjtBQUNoRixvRUFBb0U7QUFDN0QsS0FBSyxVQUFVLHNCQUFzQjtJQUMxQyxJQUFJLHlCQUF5QixFQUFFLENBQUM7UUFDOUIsT0FBTyx5QkFBeUIsQ0FBQztJQUNuQyxDQUFDO0lBRUQsNkRBQTZEO0lBQzdELDRFQUE0RTtJQUM1RSwyRUFBMkU7SUFDM0UsK0VBQStFO0lBQy9FLDJFQUEyRTtJQUMzRSx5Q0FBeUM7SUFDekMsTUFBTSxFQUNKLFdBQVcsRUFBRSxnQkFBZ0IsRUFDN0Isc0JBQXNCLEVBQ3RCLG1DQUFtQyxFQUNuQyxzQkFBc0IsRUFDdEIsaUJBQWlCLEVBQ2pCLGFBQWEsRUFDYixnQ0FBZ0M7SUFDaEMsNElBQTRJO01BQzdJLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FDYiw4QkFBOEIsQ0FDL0IsQ0FBd0MsQ0FBQztJQUUxQyxNQUFNLG1CQUFvQixTQUFRLGdCQUFnQjtRQUN4QyxRQUFRLENBQVk7UUFDWCx1QkFBdUIsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBQzVDLG1CQUFtQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDeEMsb0JBQW9CLEdBQUcsSUFBSSxHQUFHLEVBQVUs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QUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7d0JBQ2hFLE1BQU0sQ0FBQyxDQUFDO29CQUNWLENBQUM7b0JBQ0QsT0FBTyxLQUFLLENBQUM7Z0JBQ2YsQ0FBQztZQUNILENBQUMsQ0FBQztZQUVGLGdDQUFnQztZQUNoQyxJQUFJLE1BQU0sV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7Z0JBQzlCLE9BQU8sTUFBTSxDQUFDO1lBQ2hCLENBQUM7WUFFRCxvQ0FBb0M7WUFDcEMsSUFBSSxNQUFNLFdBQVcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUNqQyxPQUFPLFNBQVMsQ0FBQztZQUNuQixDQUFDO1lBRUQsa0ZBQWtGO1lBQ2xGLElBQUksTUFBTSxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDaEMsK0NBQStDO2dCQUMvQyxNQUFNLElBQUEsZ0JBQUssRUFBQyxNQUFNLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDekMsT0FBTyxNQUFNLENBQUM7WUFDaEIsQ0FBQztZQUVELElBQUksTUFBTSxXQUFXLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztnQkFDbkMsdURBQXVEO2dCQUN2RCxNQUFNLElBQUEsZ0JBQUssRUFBQyxTQUFTLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDNUMsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztZQUVELE1BQU0sSUFBSSxLQUFLLENBQ2IscUhBQXFILENBQ3RILENBQUM7UUFDSixDQUFDO0tBQ0Y7SUFFRCx5QkFBeUIsR0FBRyxtQkFBbUIsQ0FBQztJQUNoRCxPQUFPLG1CQUFtQixDQUFDO0FBQzdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHsgY29uc3RhbnRzLCBleGlzdHNTeW5jLCByZWFkRmlsZVN5bmMgfSBmcm9tICdub2RlOmZzJztcbmltcG9ydCB7XG4gIGFjY2VzcyxcbiAgbWtkaXIsXG4gIG9wZW4sXG4gIHJlYWRkaXIsXG4gIHJlYWRGaWxlLFxuICBybSxcbiAgc3RhdCxcbiAgd3JpdGVGaWxlLFxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tICdub2RlOm1vZHVsZSc7XG5pbXBvcnQgb3MgZnJvbSAnbm9kZTpvcyc7XG5pbXBvcnQge1xuICBiYXNlbmFtZSxcbiAgZGlybmFtZSxcbiAgZXh0bmFtZSxcbiAgaXNBYnNvbHV0ZSxcbiAgam9pbixcbiAgcmVsYXRpdmUsXG4gIHJlc29sdmUsXG59IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgdHlwZSB7IFdvcmtmbG93TWFuaWZlc3QgfSBmcm9tICdAd29ya2Zsb3cvYnVpbGRlcnMnO1xuaW1wb3J0IHtcbiAgY2xlYW51cFN0YWxlU29ja2V0SW5mb0ZpbGVzLFxuICBjcmVhdGVTb2NrZXRTZXJ2ZXIsXG4gIFNPQ0tFVF9JTkZPX0ZJTEVOQU1FLFxuICB0eXBlIFNvY2tldElPLFxuICB0eXBlIFNvY2tldFNlcnZlckNvbmZpZyxcbn0gZnJvbSAnLi9zb2NrZXQtc2VydmVyLmpzJztcblxuY29uc3QgUk9VVEVfU1RVQl9GSUxFX01BUktFUiA9ICdXT1JLRkxPV19ST1VURV9TVFVCX0ZJTEUnO1xuY29uc3QgUk9VVEVfU1RVQl9NQVJLRVJfU0NBTl9CWVRFUyA9IDQgKiAxMDI0O1xuY29uc3QgREVWX1dPUktGTE9XX0NPREVfRklMRU5BTUUgPSAnX193b3JrZmxvd19jb2RlLnR4dCc7XG5cbmxldCBDYWNoZWROZXh0QnVpbGRlckRlZmVycmVkOiBhbnk7XG5cbi8vIENyZWF0ZSB0aGUgZGVmZXJyZWQgTmV4dCBidWlsZGVyIGR5bmFtaWNhbGx5IGJ5IGV4dGVuZGluZyB0aGUgRVNNIEJhc2VCdWlsZGVyLlxuLy8gRXhwb3J0ZWQgYXMgZ2V0TmV4dEJ1aWxkZXJEZWZlcnJlZCgpIHRvIGFsbG93IENvbW1vbkpTIG1vZHVsZXMgdG8gaW1wb3J0IGZyb21cbi8vIHRoZSBFU00gQHdvcmtmbG93L2J1aWxkZXJzIHBhY2thZ2UgdmlhIGR5bmFtaWMgaW1wb3J0IGF0IHJ1bnRpbWUuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0TmV4dEJ1aWxkZXJEZWZlcnJlZCgpIHtcbiAgaWYgKENhY2hlZE5leHRCdWlsZGVyRGVmZXJyZWQpIHtcbiAgICByZXR1cm4gQ2FjaGVkTmV4dEJ1aWxkZXJEZWZlcnJlZDtcbiAgfVxuXG4gIC8vIFYyOiBTVEVQX1FVRVVFX1RSSUdHRVIgYW5kIGVuaGFuY2VkLXJlc29sdmUgaW5mcmFzdHJ1Y3R1cmVcbiAgLy8gd2VyZSByZW1vdmVkIGJlY2F1c2UgdGhlIFYyIGNvbWJpbmVkIGhhbmRsZXIgZWxpbWluYXRlcyB0aGUgc2VwYXJhdGUgc3RlcFxuICAvLyByb3V0ZS90b3BpYy4gVGhlIHN0ZXAgY29weSBpbXBvcnQgcmV3cml0aW5nIChnZXRSZWxhdGl2ZUltcG9ydFNwZWNpZmllcixcbiAgLy8gZ2V0U3RlcENvcHlGaWxlTmFtZSwgcmV3cml0ZVJlbGF0aXZlSW1wb3J0c0ZvckNvcGllZFN0ZXApIGZyb20gbWFpbiB3YXMgYWxzb1xuICAvLyByZW1vdmVkIOKAlCBWMiBkb2Vzbid0IHVzZSBzdGVwIGNvcGllcy4gSWYgc3RlcCBjb3B5IHN1cHBvcnQgaXMgbmVlZGVkLCBpdFxuICAvLyBzaG91bGQgbGFuZCBhcyBhIGNvbXBsZXRlIGZlYXR1cmUgc2V0LlxuICBjb25zdCB7XG4gICAgQmFzZUJ1aWxkZXI6IEJhc2VCdWlsZGVyQ2xhc3MsXG4gICAgV09SS0ZMT1dfUVVFVUVfVFJJR0dFUixcbiAgICBjcmVhdGVXb3JrZmxvd0VudHJ5cG9pbnRPcHRpb25zQ29kZSxcbiAgICBkZXRlY3RXb3JrZmxvd1BhdHRlcm5zLFxuICAgIGFwcGx5U3djVHJhbnNmb3JtLFxuICAgIGdldEltcG9ydFBhdGgsXG4gICAgcmVzb2x2ZVdvcmtmbG93QWxpYXNSZWxhdGl2ZVBhdGgsXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc2VjdXJpdHkvbm9HbG9iYWxFdmFsOiBOZWVkIHRvIHVzZSBldmFsIGhlcmUgdG8gYXZvaWQgVHlwZVNjcmlwdCBmcm9tIHRyYW5zcGlsaW5nIHRoZSBpbXBvcnQgc3RhdGVtZW50IGludG8gYHJlcXVpcmUoKWBcbiAgfSA9IChhd2FpdCBldmFsKFxuICAgICdpbXBvcnQoXCJAd29ya2Zsb3cvYnVpbGRlcnNcIiknXG4gICkpIGFzIHR5cGVvZiBpbXBvcnQoJ0B3b3JrZmxvdy9idWlsZGVycycpO1xuXG4gIGNsYXNzIE5leHREZWZlcnJlZEJ1aWxkZXIgZXh0ZW5kcyBCYXNlQnVpbGRlckNsYXNzIHtcbiAgICBwcml2YXRlIHNvY2tldElPPzogU29ja2V0SU87XG4gICAgcHJpdmF0ZSByZWFkb25seSBkaXNjb3ZlcmVkV29ya2Zsb3dGaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZGlzY292ZXJlZFN0ZXBGaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZGlzY292ZXJlZFNlcmRlRmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBwcml2YXRlIHRyYWNrZWREZXBlbmRlbmN5RmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBwcml2YXRlIGRlZmVycmVkQnVpbGRRdWV1ZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIHByaXZhdGUgY2FjaGVJbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgY2FjaGVXcml0ZVRpbWVyOiBOb2RlSlMuVGltZW91dCB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgZGVmZXJyZWRSZWJ1aWxkVGltZXI6IE5vZGVKUy5UaW1lb3V0IHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBsYXN0RGVmZXJyZWRCdWlsZFNpZ25hdHVyZTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgICBhc3luYyBidWlsZCgpIHtcbiAgICAgIGNvbnN0IG91dHB1dERpciA9IGF3YWl0IHRoaXMuZmluZEFwcERpcmVjdG9yeSgpO1xuXG4gICAgICBhd2FpdCB0aGlzLmluaXRpYWxpemVEaXNjb3ZlcnlTdGF0ZSgpO1xuICAgICAgYXdhaXQgdGhpcy5jbGVhbnVwR2VuZXJhdGVkQXJ0aWZhY3RzT25Cb290KG91dHB1dERpcik7XG5cbiAgICAgIGF3YWl0IHRoaXMud3JpdGVTdHViRmlsZXMob3V0cHV0RGlyKTtcbiAgICAgIGF3YWl0IHRoaXMuY3JlYXRlRGlzY292ZXJ5U29ja2V0U2VydmVyKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25CZWZvcmVEZWZlcnJlZEVudHJpZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBhd2FpdCB0aGlzLmluaXRpYWxpemVEaXNjb3ZlcnlTdGF0ZSgpO1xuICAgICAgYXdhaXQgdGhpcy52YWxpZGF0ZURpc2NvdmVyZWRFbnRyeUZpbGVzKCk7XG4gICAgICBjb25zdCBpbXBsaWNpdFN0ZXBGaWxlcyA9IGF3YWl0IHRoaXMucmVzb2x2ZUltcGxpY2l0U3RlcEZpbGVzKCk7XG5cbiAgICAgIGNvbnN0IHBlbmRpbmdCdWlsZCA9IHRoaXMuZGVmZXJyZWRCdWlsZFF1ZXVlLnRoZW4oKCkgPT5cbiAgICAgICAgdGhpcy5idWlsZERlZmVycmVkRW50cmllc1VudGlsU3RhYmxlKGltcGxpY2l0U3RlcEZpbGVzKVxuICAgICAgKTtcblxuICAgICAgLy8gS2VlcCB0aGUgcXVldWUgY2hhaW4gYWxpdmUgZXZlbiB3aGVuIHRoZSBjdXJyZW50IGJ1aWxkIGZhaWxzIHNvIGZ1dHVyZVxuICAgICAgLy8gY2FsbGJhY2tzIGNhbiBlbnF1ZXVlIGFub3RoZXIgYXR0ZW1wdCB3aXRob3V0IHRyaWdnZXJpbmcgdW5oYW5kbGVkXG4gICAgICAvLyByZWplY3Rpb24gd2FybmluZ3MuXG4gICAgICB0aGlzLmRlZmVycmVkQnVpbGRRdWV1ZSA9IHBlbmRpbmdCdWlsZC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIC8vIEVycm9yIGlzIHN1cmZhY2VkIHRocm91Z2ggYHBlbmRpbmdCdWlsZGAgYmVsb3cuXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgcGVuZGluZ0J1aWxkO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q3VycmVudElucHV0RmlsZXMoaW1wbGljaXRTdGVwRmlsZXM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICAgICAgcmV0dXJuIEFycmF5LmZyb20oXG4gICAgICAgIG5ldyBTZXQoW1xuICAgICAgICAgIC4uLnRoaXMuZGlzY292ZXJlZFdvcmtmbG93RmlsZXMsXG4gICAgICAgICAgLi4udGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLFxuICAgICAgICAgIC4uLnRoaXMuZGlzY292ZXJlZFNlcmRlRmlsZXMsXG4gICAgICAgICAgLi4uaW1wbGljaXRTdGVwRmlsZXMsXG4gICAgICAgIF0pXG4gICAgICApLnNvcnQoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGJ1aWxkRGVmZXJyZWRFbnRyaWVzVW50aWxTdGFibGUoXG4gICAgICBpbXBsaWNpdFN0ZXBGaWxlczogc3RyaW5nW11cbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIC8vIEEgc3VjY2Vzc2Z1bCBidWlsZCBjYW4gZGlzY292ZXIgYWRkaXRpb25hbCB0cmFuc2l0aXZlIGRlcGVuZGVuY3kgZmlsZXNcbiAgICAgIC8vICh2aWEgc291cmNlIG1hcHMpLCB3aGljaCBjaGFuZ2VzIHRoZSBzaWduYXR1cmUgYW5kIG1heSByZXF1aXJlIG9uZSBtb3JlXG4gICAgICAvLyBidWlsZCBwYXNzIHRvIGluY2x1ZGUgbmV3bHkgZGlzY292ZXJlZCBzZXJkZSBmaWxlcy5cbiAgICAgIGNvbnN0IG1heEJ1aWxkUGFzc2VzID0gMztcblxuICAgICAgZm9yIChsZXQgYnVpbGRQYXNzID0gMDsgYnVpbGRQYXNzIDwgbWF4QnVpbGRQYXNzZXM7IGJ1aWxkUGFzcysrKSB7XG4gICAgICAgIGNvbnN0IGlucHV0RmlsZXMgPSB0aGlzLmdldEN1cnJlbnRJbnB1dEZpbGVzKGltcGxpY2l0U3RlcEZpbGVzKTtcbiAgICAgICAgY29uc3QgYnVpbGRTaWduYXR1cmUgPVxuICAgICAgICAgIGF3YWl0IHRoaXMuY3JlYXRlRGVmZXJyZWRCdWlsZFNpZ25hdHVyZShpbnB1dEZpbGVzKTtcbiAgICAgICAgY29uc3Qgc2hvdWxkRm9yY2VCdWlsZEZvckdlbmVyYXRlZFJvdXRlcyA9XG4gICAgICAgICAgYXdhaXQgdGhpcy5zaG91bGRGb3JjZUJ1aWxkRm9yR2VuZXJhdGVkUm91dGVzKCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBidWlsZFNpZ25hdHVyZSA9PT0gdGhpcy5sYXN0RGVmZXJyZWRCdWlsZFNpZ25hdHVyZSAmJlxuICAgICAgICAgICFzaG91bGRGb3JjZUJ1aWxkRm9yR2VuZXJhdGVkUm91dGVzXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5idWlsZERpc2NvdmVyZWRGaWxlcyhpbnB1dEZpbGVzLCBpbXBsaWNpdFN0ZXBGaWxlcyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgaWYgKHRoaXMuY29uZmlnLndhdGNoKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnZhbGlkYXRlRGlzY292ZXJlZEVudHJ5RmlsZXMoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlY292ZXJlZElucHV0RmlsZXMgPVxuICAgICAgICAgICAgICB0aGlzLmdldEN1cnJlbnRJbnB1dEZpbGVzKGltcGxpY2l0U3RlcEZpbGVzKTtcbiAgICAgICAgICAgIGNvbnN0IHJlY292ZXJlZFNpZ25hdHVyZSA9XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuY3JlYXRlRGVmZXJyZWRCdWlsZFNpZ25hdHVyZShyZWNvdmVyZWRJbnB1dEZpbGVzKTtcbiAgICAgICAgICAgIGlmIChyZWNvdmVyZWRTaWduYXR1cmUgIT09IGJ1aWxkU2lnbmF0dXJlKSB7XG4gICAgICAgICAgICAgIC8vIEEgZmlsZSB3YXMgYWRkZWQvcmVtb3ZlZCB3aGlsZSB0aGlzIGJ1aWxkIHdhcyBydW5uaW5nOyByZXRyeVxuICAgICAgICAgICAgICAvLyBpbW1lZGlhdGVseSB3aXRoIHRoZSByZWZyZXNoZWQgZGlzY292ZXJlZC1lbnRyeSBzdGF0ZS5cbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICdbd29ya2Zsb3ddIERlZmVycmVkIGVudHJpZXMgYnVpbGQgZmFpbGVkLiBXaWxsIHJldHJ5IG9ubHkgYWZ0ZXIgaW5wdXRzIGNoYW5nZS4nLFxuICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMubGFzdERlZmVycmVkQnVpbGRTaWduYXR1cmUgPSBidWlsZFNpZ25hdHVyZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMubGFzdERlZmVycmVkQnVpbGRTaWduYXR1cmUgPSBidWlsZFNpZ25hdHVyZTtcblxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLndhdGNoKSB7XG4gICAgICAgICAgLy8gUHJvZHVjdGlvbiBidWlsZHMgY2FuIHBlcnNpc3QgbmV3bHkgZGlzY292ZXJlZCBkZWZlcnJlZC1lbnRyeSBmaWxlcyB0b1xuICAgICAgICAgIC8vIHRoZSBjYWNoZSBhZnRlciB0aGUgZmlyc3QgcGFzcyBjb21wbGV0ZXMuIFJlbG9hZCB0aGF0IGNhY2hlIGJlZm9yZSB3ZVxuICAgICAgICAgIC8vIGRlY2lkZSB3aGV0aGVyIHRoZSBpbnB1dCBzaWduYXR1cmUgc3RhYmlsaXplZCBzbyBzdGFnZWQgdGFyYmFsbCBidWlsZHNcbiAgICAgICAgICAvLyBjYW4gaW1tZWRpYXRlbHkgcmVwbGF5IHdpdGggdGhlIGV4cGFuZGVkIHN0ZXAgc2V0LlxuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDI1MCkpO1xuICAgICAgICAgIGF3YWl0IHRoaXMubG9hZFdvcmtmbG93c0NhY2hlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwb3N0QnVpbGRJbnB1dEZpbGVzID1cbiAgICAgICAgICB0aGlzLmdldEN1cnJlbnRJbnB1dEZpbGVzKGltcGxpY2l0U3RlcEZpbGVzKTtcbiAgICAgICAgY29uc3QgcG9zdEJ1aWxkU2lnbmF0dXJlID1cbiAgICAgICAgICBhd2FpdCB0aGlzLmNyZWF0ZURlZmVycmVkQnVpbGRTaWduYXR1cmUocG9zdEJ1aWxkSW5wdXRGaWxlcyk7XG4gICAgICAgIGlmIChwb3N0QnVpbGRTaWduYXR1cmUgPT09IGJ1aWxkU2lnbmF0dXJlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgJ1t3b3JrZmxvd10gRGVmZXJyZWQgZW50cmllcyBidWlsZCBzaWduYXR1cmUgZGlkIG5vdCBzdGFiaWxpemUgYWZ0ZXIgMyBwYXNzZXMuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlc29sdmVJbXBsaWNpdFN0ZXBGaWxlcygpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICBjb25zdCB3b3JrZmxvd1N0ZGxpYlBhdGggPSB0aGlzLnJlc29sdmVXb3JrZmxvd1N0ZGxpYlN0ZXBGaWxlUGF0aCgpO1xuICAgICAgcmV0dXJuIHdvcmtmbG93U3RkbGliUGF0aCA/IFt3b3JrZmxvd1N0ZGxpYlBhdGhdIDogW107XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBzaG91bGRGb3JjZUJ1aWxkRm9yR2VuZXJhdGVkUm91dGVzKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgY29uc3Qgb3V0cHV0RGlyID0gYXdhaXQgdGhpcy5maW5kQXBwRGlyZWN0b3J5KCk7XG4gICAgICBjb25zdCBnZW5lcmF0ZWRSb3V0ZUZpbGVzID0gW1xuICAgICAgICBqb2luKG91dHB1dERpciwgJy53ZWxsLWtub3duL3dvcmtmbG93L3YxL2Zsb3cvcm91dGUuanMnKSxcbiAgICAgICAgam9pbihvdXRwdXREaXIsICcud2VsbC1rbm93bi93b3JrZmxvdy92MS93ZWJob29rL1t0b2tlbl0vcm91dGUuanMnKSxcbiAgICAgIF07XG5cbiAgICAgIGZvciAoY29uc3Qgcm91dGVGaWxlUGF0aCBvZiBnZW5lcmF0ZWRSb3V0ZUZpbGVzKSB7XG4gICAgICAgIGNvbnN0IHJvdXRlU3RhdGUgPSBhd2FpdCB0aGlzLmdldEdlbmVyYXRlZFJvdXRlU3RhdGUocm91dGVGaWxlUGF0aCk7XG4gICAgICAgIGlmIChyb3V0ZVN0YXRlID09PSAnbWlzc2luZycgfHwgcm91dGVTdGF0ZSA9PT0gJ3N0dWInKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZ2V0R2VuZXJhdGVkUm91dGVTdGF0ZShcbiAgICAgIHJvdXRlRmlsZVBhdGg6IHN0cmluZ1xuICAgICk6IFByb21pc2U8J21pc3NpbmcnIHwgJ3N0dWInIHwgJ2dlbmVyYXRlZCc+IHtcbiAgICAgIGxldCByb3V0ZVN0YXRzOiBBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIHN0YXQ+PjtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJvdXRlU3RhdHMgPSBhd2FpdCBzdGF0KHJvdXRlRmlsZVBhdGgpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiAnbWlzc2luZyc7XG4gICAgICB9XG4gICAgICBpZiAoIXJvdXRlU3RhdHMuaXNGaWxlKCkpIHtcbiAgICAgICAgcmV0dXJuICdtaXNzaW5nJztcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgcm91dGVGaWxlSGFuZGxlID0gYXdhaXQgb3Blbihyb3V0ZUZpbGVQYXRoLCAncicpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IG1hcmtlclNjYW5CdWZmZXIgPSBCdWZmZXIuYWxsb2MoUk9VVEVfU1RVQl9NQVJLRVJfU0NBTl9CWVRFUyk7XG4gICAgICAgICAgY29uc3QgeyBieXRlc1JlYWQgfSA9IGF3YWl0IHJvdXRlRmlsZUhhbmRsZS5yZWFkKFxuICAgICAgICAgICAgbWFya2VyU2NhbkJ1ZmZlcixcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICBST1VURV9TVFVCX01BUktFUl9TQ0FOX0JZVEVTLFxuICAgICAgICAgICAgMFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgbWFya2VyU2NhblNvdXJjZSA9IG1hcmtlclNjYW5CdWZmZXIudG9TdHJpbmcoXG4gICAgICAgICAgICAndXRmOCcsXG4gICAgICAgICAgICAwLFxuICAgICAgICAgICAgYnl0ZXNSZWFkXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gbWFya2VyU2NhblNvdXJjZS5pbmNsdWRlcyhST1VURV9TVFVCX0ZJTEVfTUFSS0VSKVxuICAgICAgICAgICAgPyAnc3R1YidcbiAgICAgICAgICAgIDogJ2dlbmVyYXRlZCc7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgYXdhaXQgcm91dGVGaWxlSGFuZGxlLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gJ21pc3NpbmcnO1xuICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVzb2x2ZVdvcmtmbG93U3RkbGliU3RlcEZpbGVQYXRoKCk6IHN0cmluZyB8IG51bGwge1xuICAgICAgbGV0IHdvcmtmbG93Q2pzRW50cnk6IHN0cmluZztcbiAgICAgIHRyeSB7XG4gICAgICAgIHdvcmtmbG93Q2pzRW50cnkgPSByZXF1aXJlLnJlc29sdmUoJ3dvcmtmbG93Jywge1xuICAgICAgICAgIHBhdGhzOiBbdGhpcy5jb25maWcud29ya2luZ0Rpcl0sXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB3b3JrZmxvd0Rpc3REaXIgPSBkaXJuYW1lKHdvcmtmbG93Q2pzRW50cnkpO1xuICAgICAgY29uc3Qgd29ya2Zsb3dTdGRsaWJQYXRoID0gdGhpcy5ub3JtYWxpemVEaXNjb3ZlcmVkRmlsZVBhdGgoXG4gICAgICAgIGpvaW4od29ya2Zsb3dEaXN0RGlyLCAnc3RkbGliLmpzJylcbiAgICAgICk7XG4gICAgICByZXR1cm4gZXhpc3RzU3luYyh3b3JrZmxvd1N0ZGxpYlBhdGgpID8gd29ya2Zsb3dTdGRsaWJQYXRoIDogbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlY29uY2lsZURpc2NvdmVyZWRFbnRyaWVzKHtcbiAgICAgIHdvcmtmbG93Q2FuZGlkYXRlcyxcbiAgICAgIHN0ZXBDYW5kaWRhdGVzLFxuICAgICAgc2VyZGVDYW5kaWRhdGVzLFxuICAgICAgdmFsaWRhdGVQYXR0ZXJucyxcbiAgICB9OiB7XG4gICAgICB3b3JrZmxvd0NhbmRpZGF0ZXM6IEl0ZXJhYmxlPHN0cmluZz47XG4gICAgICBzdGVwQ2FuZGlkYXRlczogSXRlcmFibGU8c3RyaW5nPjtcbiAgICAgIHNlcmRlQ2FuZGlkYXRlcz86IEl0ZXJhYmxlPHN0cmluZz47XG4gICAgICB2YWxpZGF0ZVBhdHRlcm5zOiBib29sZWFuO1xuICAgIH0pOiBQcm9taXNlPHtcbiAgICAgIHdvcmtmbG93RmlsZXM6IFNldDxzdHJpbmc+O1xuICAgICAgc3RlcEZpbGVzOiBTZXQ8c3RyaW5nPjtcbiAgICAgIHNlcmRlRmlsZXM6IFNldDxzdHJpbmc+O1xuICAgIH0+IHtcbiAgICAgIGNvbnN0IGNhbmRpZGF0ZXNCeUZpbGUgPSBuZXcgTWFwPFxuICAgICAgICBzdHJpbmcsXG4gICAgICAgIHtcbiAgICAgICAgICBoYXNXb3JrZmxvd0NhbmRpZGF0ZTogYm9vbGVhbjtcbiAgICAgICAgICBoYXNTdGVwQ2FuZGlkYXRlOiBib29sZWFuO1xuICAgICAgICAgIGhhc1NlcmRlQ2FuZGlkYXRlOiBib29sZWFuO1xuICAgICAgICB9XG4gICAgICA+KCk7XG5cbiAgICAgIGZvciAoY29uc3QgZmlsZVBhdGggb2Ygd29ya2Zsb3dDYW5kaWRhdGVzKSB7XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gdGhpcy5ub3JtYWxpemVEaXNjb3ZlcmVkRmlsZVBhdGgoZmlsZVBhdGgpO1xuICAgICAgICBjb25zdCBleGlzdGluZyA9IGNhbmRpZGF0ZXNCeUZpbGUuZ2V0KG5vcm1hbGl6ZWRQYXRoKTtcbiAgICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgICAgZXhpc3RpbmcuaGFzV29ya2Zsb3dDYW5kaWRhdGUgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNhbmRpZGF0ZXNCeUZpbGUuc2V0KG5vcm1hbGl6ZWRQYXRoLCB7XG4gICAgICAgICAgICBoYXNXb3JrZmxvd0NhbmRpZGF0ZTogdHJ1ZSxcbiAgICAgICAgICAgIGhhc1N0ZXBDYW5kaWRhdGU6IGZhbHNlLFxuICAgICAgICAgICAgaGFzU2VyZGVDYW5kaWRhdGU6IGZhbHNlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgZmlsZVBhdGggb2Ygc3RlcENhbmRpZGF0ZXMpIHtcbiAgICAgICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChmaWxlUGF0aCk7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nID0gY2FuZGlkYXRlc0J5RmlsZS5nZXQobm9ybWFsaXplZFBhdGgpO1xuICAgICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgICBleGlzdGluZy5oYXNTdGVwQ2FuZGlkYXRlID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYW5kaWRhdGVzQnlGaWxlLnNldChub3JtYWxpemVkUGF0aCwge1xuICAgICAgICAgICAgaGFzV29ya2Zsb3dDYW5kaWRhdGU6IGZhbHNlLFxuICAgICAgICAgICAgaGFzU3RlcENhbmRpZGF0ZTogdHJ1ZSxcbiAgICAgICAgICAgIGhhc1NlcmRlQ2FuZGlkYXRlOiBmYWxzZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoc2VyZGVDYW5kaWRhdGVzKSB7XG4gICAgICAgIGZvciAoY29uc3QgZmlsZVBhdGggb2Ygc2VyZGVDYW5kaWRhdGVzKSB7XG4gICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChmaWxlUGF0aCk7XG4gICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBjYW5kaWRhdGVzQnlGaWxlLmdldChub3JtYWxpemVkUGF0aCk7XG4gICAgICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgICAgICBleGlzdGluZy5oYXNTZXJkZUNhbmRpZGF0ZSA9IHRydWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhbmRpZGF0ZXNCeUZpbGUuc2V0KG5vcm1hbGl6ZWRQYXRoLCB7XG4gICAgICAgICAgICAgIGhhc1dvcmtmbG93Q2FuZGlkYXRlOiBmYWxzZSxcbiAgICAgICAgICAgICAgaGFzU3RlcENhbmRpZGF0ZTogZmFsc2UsXG4gICAgICAgICAgICAgIGhhc1NlcmRlQ2FuZGlkYXRlOiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbGVFbnRyaWVzID0gQXJyYXkuZnJvbShjYW5kaWRhdGVzQnlGaWxlLmVudHJpZXMoKSkuc29ydChcbiAgICAgICAgKFthXSwgW2JdKSA9PiBhLmxvY2FsZUNvbXBhcmUoYilcbiAgICAgICk7XG4gICAgICBjb25zdCB2YWxpZGF0ZWRFbnRyaWVzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIGZpbGVFbnRyaWVzLm1hcChhc3luYyAoW2ZpbGVQYXRoLCBjYW5kaWRhdGVzXSkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlU3RhdHMgPSBhd2FpdCBzdGF0KGZpbGVQYXRoKTtcbiAgICAgICAgICAgIGlmICghZmlsZVN0YXRzLmlzRmlsZSgpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXZhbGlkYXRlUGF0dGVybnMpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmaWxlUGF0aCxcbiAgICAgICAgICAgICAgICBoYXNVc2VXb3JrZmxvdzogY2FuZGlkYXRlcy5oYXNXb3JrZmxvd0NhbmRpZGF0ZSxcbiAgICAgICAgICAgICAgICBoYXNVc2VTdGVwOiBjYW5kaWRhdGVzLmhhc1N0ZXBDYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgaGFzU2VyZGU6IGNhbmRpZGF0ZXMuaGFzU2VyZGVDYW5kaWRhdGUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoLCAndXRmLTgnKTtcbiAgICAgICAgICAgIGNvbnN0IHBhdHRlcm5zID0gZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucyhzb3VyY2UpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgZmlsZVBhdGgsXG4gICAgICAgICAgICAgIGhhc1VzZVdvcmtmbG93OiBwYXR0ZXJucy5oYXNVc2VXb3JrZmxvdyxcbiAgICAgICAgICAgICAgaGFzVXNlU3RlcDogcGF0dGVybnMuaGFzVXNlU3RlcCxcbiAgICAgICAgICAgICAgaGFzU2VyZGU6IHBhdHRlcm5zLmhhc1NlcmRlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHdvcmtmbG93RmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgIGNvbnN0IHN0ZXBGaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgY29uc3Qgc2VyZGVGaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB2YWxpZGF0ZWRFbnRyaWVzKSB7XG4gICAgICAgIGlmICghZW50cnkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZW50cnkuaGFzVXNlV29ya2Zsb3cpIHtcbiAgICAgICAgICB3b3JrZmxvd0ZpbGVzLmFkZChlbnRyeS5maWxlUGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVudHJ5Lmhhc1VzZVN0ZXApIHtcbiAgICAgICAgICBzdGVwRmlsZXMuYWRkKGVudHJ5LmZpbGVQYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZW50cnkuaGFzU2VyZGUpIHtcbiAgICAgICAgICBzZXJkZUZpbGVzLmFkZChlbnRyeS5maWxlUGF0aCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHsgd29ya2Zsb3dGaWxlcywgc3RlcEZpbGVzLCBzZXJkZUZpbGVzIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyB2YWxpZGF0ZURpc2NvdmVyZWRFbnRyeUZpbGVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgY29uc3Qgd29ya2Zsb3dDYW5kaWRhdGVzID0gbmV3IFNldCh0aGlzLmRpc2NvdmVyZWRXb3JrZmxvd0ZpbGVzKTtcbiAgICAgIGNvbnN0IHN0ZXBDYW5kaWRhdGVzID0gbmV3IFNldCh0aGlzLmRpc2NvdmVyZWRTdGVwRmlsZXMpO1xuICAgICAgY29uc3Qgc2VyZGVDYW5kaWRhdGVzID0gbmV3IFNldCh0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzKTtcbiAgICAgIGNvbnN0IHsgd29ya2Zsb3dGaWxlcywgc3RlcEZpbGVzLCBzZXJkZUZpbGVzIH0gPVxuICAgICAgICBhd2FpdCB0aGlzLnJlY29uY2lsZURpc2NvdmVyZWRFbnRyaWVzKHtcbiAgICAgICAgICB3b3JrZmxvd0NhbmRpZGF0ZXMsXG4gICAgICAgICAgc3RlcENhbmRpZGF0ZXMsXG4gICAgICAgICAgc2VyZGVDYW5kaWRhdGVzLFxuICAgICAgICAgIHZhbGlkYXRlUGF0dGVybnM6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAvLyBSZWNvbmNpbGUgdmFsaWRhdGVkIGVudHJpZXMgYWdhaW5zdCB0aGUgc25hcHNob3Qgd2Ugc3RhcnRlZCB3aXRoIHNvXG4gICAgICAvLyBmaWxlIGRpc2NvdmVyaWVzIHRoYXQgYXJyaXZlIGR1cmluZyB2YWxpZGF0aW9uIGFyZSBwcmVzZXJ2ZWQuXG4gICAgICBsZXQgd29ya2Zsb3dzQ2hhbmdlZCA9IGZhbHNlO1xuICAgICAgbGV0IHN0ZXBzQ2hhbmdlZCA9IGZhbHNlO1xuICAgICAgbGV0IHNlcmRlQ2hhbmdlZCA9IGZhbHNlO1xuXG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHdvcmtmbG93Q2FuZGlkYXRlcykge1xuICAgICAgICBpZiAoIXdvcmtmbG93RmlsZXMuaGFzKGZpbGVQYXRoKSkge1xuICAgICAgICAgIHdvcmtmbG93c0NoYW5nZWQgPVxuICAgICAgICAgICAgdGhpcy5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlcy5kZWxldGUoZmlsZVBhdGgpIHx8IHdvcmtmbG93c0NoYW5nZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgZmlsZVBhdGggb2Ygd29ya2Zsb3dGaWxlcykge1xuICAgICAgICBpZiAoIXRoaXMuZGlzY292ZXJlZFdvcmtmbG93RmlsZXMuaGFzKGZpbGVQYXRoKSkge1xuICAgICAgICAgIHRoaXMuZGlzY292ZXJlZFdvcmtmbG93RmlsZXMuYWRkKGZpbGVQYXRoKTtcbiAgICAgICAgICB3b3JrZmxvd3NDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHN0ZXBDYW5kaWRhdGVzKSB7XG4gICAgICAgIGlmICghc3RlcEZpbGVzLmhhcyhmaWxlUGF0aCkpIHtcbiAgICAgICAgICBzdGVwc0NoYW5nZWQgPVxuICAgICAgICAgICAgdGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLmRlbGV0ZShmaWxlUGF0aCkgfHwgc3RlcHNDaGFuZ2VkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHN0ZXBGaWxlcykge1xuICAgICAgICBpZiAoIXRoaXMuZGlzY292ZXJlZFN0ZXBGaWxlcy5oYXMoZmlsZVBhdGgpKSB7XG4gICAgICAgICAgdGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLmFkZChmaWxlUGF0aCk7XG4gICAgICAgICAgc3RlcHNDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHNlcmRlQ2FuZGlkYXRlcykge1xuICAgICAgICBpZiAoIXNlcmRlRmlsZXMuaGFzKGZpbGVQYXRoKSkge1xuICAgICAgICAgIHNlcmRlQ2hhbmdlZCA9XG4gICAgICAgICAgICB0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLmRlbGV0ZShmaWxlUGF0aCkgfHwgc2VyZGVDaGFuZ2VkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHNlcmRlRmlsZXMpIHtcbiAgICAgICAgaWYgKCF0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLmhhcyhmaWxlUGF0aCkpIHtcbiAgICAgICAgICB0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLmFkZChmaWxlUGF0aCk7XG4gICAgICAgICAgc2VyZGVDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAod29ya2Zsb3dzQ2hhbmdlZCB8fCBzdGVwc0NoYW5nZWQpIHtcbiAgICAgICAgdGhpcy5zY2hlZHVsZVdvcmtmbG93c0NhY2hlV3JpdGUoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGJ1aWxkRGlzY292ZXJlZEZpbGVzKFxuICAgICAgaW5wdXRGaWxlczogc3RyaW5nW10sXG4gICAgICBpbXBsaWNpdFN0ZXBGaWxlczogc3RyaW5nW11cbiAgICApIHtcbiAgICAgIGNvbnN0IG91dHB1dERpciA9IGF3YWl0IHRoaXMuZmluZEFwcERpcmVjdG9yeSgpO1xuICAgICAgY29uc3Qgd29ya2Zsb3dHZW5lcmF0ZWREaXIgPSBqb2luKG91dHB1dERpciwgJy53ZWxsLWtub3duL3dvcmtmbG93L3YxJyk7XG4gICAgICBjb25zdCBjYWNoZURpciA9IGpvaW4odGhpcy5jb25maWcud29ya2luZ0RpciwgdGhpcy5nZXREaXN0RGlyKCksICdjYWNoZScpO1xuICAgICAgYXdhaXQgbWtkaXIoY2FjaGVEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgY29uc3QgbWFuaWZlc3RCdWlsZERpciA9IGpvaW4oY2FjaGVEaXIsICd3b3JrZmxvdy1nZW5lcmF0ZWQtbWFuaWZlc3QnKTtcbiAgICAgIGNvbnN0IHRlbXBSb3V0ZUZpbGVOYW1lID0gJ3JvdXRlLmpzLnRlbXAnO1xuICAgICAgY29uc3QgdHJhY2tlZERpc2NvdmVyZWRFbnRyaWVzID1cbiAgICAgICAgYXdhaXQgdGhpcy5jb2xsZWN0VHJhY2tlZERpc2NvdmVyZWRFbnRyaWVzKCk7XG4gICAgICBjb25zdCBkaXNjb3ZlcmVkU3RlcEZpbGVDYW5kaWRhdGVzID0gQXJyYXkuZnJvbShcbiAgICAgICAgbmV3IFNldChbXG4gICAgICAgICAgLi4udGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLFxuICAgICAgICAgIC4uLnRyYWNrZWREaXNjb3ZlcmVkRW50cmllcy5kaXNjb3ZlcmVkU3RlcHMsXG4gICAgICAgICAgLi4uaW1wbGljaXRTdGVwRmlsZXMsXG4gICAgICAgIF0pXG4gICAgICApLnNvcnQoKTtcbiAgICAgIGNvbnN0IGRpc2NvdmVyZWRXb3JrZmxvd0ZpbGVDYW5kaWRhdGVzID0gQXJyYXkuZnJvbShcbiAgICAgICAgbmV3IFNldChbXG4gICAgICAgICAgLi4udGhpcy5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlcyxcbiAgICAgICAgICAuLi50cmFja2VkRGlzY292ZXJlZEVudHJpZXMuZGlzY292ZXJlZFdvcmtmbG93cyxcbiAgICAgICAgXSlcbiAgICAgICkuc29ydCgpO1xuICAgICAgY29uc3QgZGlzY292ZXJlZFNlcmRlRmlsZUNhbmRpZGF0ZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFtcbiAgICAgICAgICAuLi50aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLFxuICAgICAgICAgIC4uLnRyYWNrZWREaXNjb3ZlcmVkRW50cmllcy5kaXNjb3ZlcmVkU2VyZGVGaWxlcyxcbiAgICAgICAgXSlcbiAgICAgICkuc29ydCgpO1xuICAgICAgY29uc3QgZGlzY292ZXJlZFdvcmtmbG93RmlsZXMgPSBhd2FpdCB0aGlzLmZpbHRlckV4aXN0aW5nRmlsZXMoXG4gICAgICAgIGRpc2NvdmVyZWRXb3JrZmxvd0ZpbGVDYW5kaWRhdGVzXG4gICAgICApO1xuICAgICAgY29uc3QgZXhpc3RpbmdTdGVwRmlsZUNhbmRpZGF0ZXMgPSBhd2FpdCB0aGlzLmZpbHRlckV4aXN0aW5nRmlsZXMoXG4gICAgICAgIGRpc2NvdmVyZWRTdGVwRmlsZUNhbmRpZGF0ZXNcbiAgICAgICk7XG4gICAgICBjb25zdCBkaXNjb3ZlcmVkU3RlcEZpbGVzID0gYXdhaXQgdGhpcy5jb2xsZWN0VHJhbnNpdGl2ZVN0ZXBGaWxlcyh7XG4gICAgICAgIGVudHJ5RmlsZXM6IFsuLi5leGlzdGluZ1N0ZXBGaWxlQ2FuZGlkYXRlcywgLi4uZGlzY292ZXJlZFdvcmtmbG93RmlsZXNdLFxuICAgICAgICBzdGVwRmlsZXM6IGV4aXN0aW5nU3RlcEZpbGVDYW5kaWRhdGVzLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBleGlzdGluZ1NlcmRlRmlsZUNhbmRpZGF0ZXMgPSBhd2FpdCB0aGlzLmZpbHRlckV4aXN0aW5nRmlsZXMoXG4gICAgICAgIGRpc2NvdmVyZWRTZXJkZUZpbGVDYW5kaWRhdGVzXG4gICAgICApO1xuICAgICAgY29uc3QgZGlzY292ZXJlZFNlcmRlRmlsZXMgPSBhd2FpdCB0aGlzLmNvbGxlY3RUcmFuc2l0aXZlU2VyZGVGaWxlcyh7XG4gICAgICAgIGVudHJ5RmlsZXM6IFsuLi5kaXNjb3ZlcmVkU3RlcEZpbGVzLCAuLi5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlc10sXG4gICAgICAgIHNlcmRlRmlsZXM6IGV4aXN0aW5nU2VyZGVGaWxlQ2FuZGlkYXRlcyxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZXhpc3RpbmdJbnB1dEZpbGVzID0gYXdhaXQgdGhpcy5maWx0ZXJFeGlzdGluZ0ZpbGVzKGlucHV0RmlsZXMpO1xuICAgICAgY29uc3QgYnVpbGRJbnB1dEZpbGVzID0gQXJyYXkuZnJvbShcbiAgICAgICAgbmV3IFNldChbXG4gICAgICAgICAgLi4uZXhpc3RpbmdJbnB1dEZpbGVzLFxuICAgICAgICAgIC4uLmRpc2NvdmVyZWRTdGVwRmlsZXMsXG4gICAgICAgICAgLi4uZGlzY292ZXJlZFdvcmtmbG93RmlsZXMsXG4gICAgICAgICAgLi4uZGlzY292ZXJlZFNlcmRlRmlsZXMsXG4gICAgICAgIF0pXG4gICAgICApLnNvcnQoKTtcbiAgICAgIGNvbnN0IGRpc2NvdmVyZWRFbnRyaWVzID0ge1xuICAgICAgICBkaXNjb3ZlcmVkU3RlcHM6IG5ldyBTZXQoZGlzY292ZXJlZFN0ZXBGaWxlcyksXG4gICAgICAgIGRpc2NvdmVyZWRXb3JrZmxvd3M6IG5ldyBTZXQoZGlzY292ZXJlZFdvcmtmbG93RmlsZXMpLFxuICAgICAgICBkaXNjb3ZlcmVkU2VyZGVGaWxlczogbmV3IFNldChkaXNjb3ZlcmVkU2VyZGVGaWxlcyksXG4gICAgICB9O1xuXG4gICAgICAvLyBFbnN1cmUgb3V0cHV0IGRpcmVjdG9yaWVzIGV4aXN0XG4gICAgICBhd2FpdCBta2Rpcih3b3JrZmxvd0dlbmVyYXRlZERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgICAgIGF3YWl0IHRoaXMud3JpdGVGaWxlSWZDaGFuZ2VkKFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnLmdpdGlnbm9yZScpLFxuICAgICAgICAnKidcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHRzY29uZmlnUGF0aCA9IGF3YWl0IHRoaXMuZmluZFRzQ29uZmlnUGF0aCgpO1xuXG4gICAgICBjb25zdCBmbG93Um91dGVEaXIgPSBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnZmxvdycpO1xuICAgICAgYXdhaXQgbWtkaXIoZmxvd1JvdXRlRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICAgICAgY29uc3QgY29tYmluZWRSZXN1bHQgPSBhd2FpdCB0aGlzLmNyZWF0ZURlZmVycmVkRmxvd1JvdXRlKHtcbiAgICAgICAgaW5wdXRGaWxlczogYnVpbGRJbnB1dEZpbGVzLFxuICAgICAgICBmbG93T3V0ZmlsZTogam9pbihmbG93Um91dGVEaXIsIHRlbXBSb3V0ZUZpbGVOYW1lKSxcbiAgICAgICAgdHNjb25maWdQYXRoLFxuICAgICAgICBkaXNjb3ZlcmVkRW50cmllcyxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgdGhpcy5idWlsZFdlYmhvb2tSb3V0ZSh7XG4gICAgICAgIHdvcmtmbG93R2VuZXJhdGVkRGlyLFxuICAgICAgICByb3V0ZUZpbGVOYW1lOiB0ZW1wUm91dGVGaWxlTmFtZSxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgdGhpcy5yZWZyZXNoVHJhY2tlZERlcGVuZGVuY3lGaWxlcyhcbiAgICAgICAgd29ya2Zsb3dHZW5lcmF0ZWREaXIsXG4gICAgICAgIHRlbXBSb3V0ZUZpbGVOYW1lXG4gICAgICApO1xuXG4gICAgICBjb25zdCBtYW5pZmVzdCA9IHtcbiAgICAgICAgc3RlcHM6IHsgLi4uY29tYmluZWRSZXN1bHQ/Lm1hbmlmZXN0Py5zdGVwcyB9LFxuICAgICAgICB3b3JrZmxvd3M6IHsgLi4uY29tYmluZWRSZXN1bHQ/Lm1hbmlmZXN0Py53b3JrZmxvd3MgfSxcbiAgICAgICAgY2xhc3NlczogeyAuLi5jb21iaW5lZFJlc3VsdD8ubWFuaWZlc3Q/LmNsYXNzZXMgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmlmZXN0RmlsZVBhdGggPSBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnbWFuaWZlc3QuanNvbicpO1xuICAgICAgY29uc3QgbWFuaWZlc3RCdWlsZFBhdGggPSBqb2luKG1hbmlmZXN0QnVpbGREaXIsICdtYW5pZmVzdC5qc29uJyk7XG4gICAgICBjb25zdCB3b3JrZmxvd0J1bmRsZVBhdGggPSBqb2luKFxuICAgICAgICB3b3JrZmxvd0dlbmVyYXRlZERpcixcbiAgICAgICAgYGZsb3cvJHt0ZW1wUm91dGVGaWxlTmFtZX1gXG4gICAgICApO1xuICAgICAgY29uc3QgbWFuaWZlc3RKc29uID0gYXdhaXQgdGhpcy5jcmVhdGVNYW5pZmVzdCh7XG4gICAgICAgIHdvcmtmbG93QnVuZGxlUGF0aCxcbiAgICAgICAgbWFuaWZlc3REaXI6IG1hbmlmZXN0QnVpbGREaXIsXG4gICAgICAgIG1hbmlmZXN0LFxuICAgICAgfSk7XG4gICAgICBpZiAobWFuaWZlc3RKc29uKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmV3cml0ZUpzb25GaWxlV2l0aFN0YWJsZUtleU9yZGVyKG1hbmlmZXN0QnVpbGRQYXRoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5jb3B5RmlsZUlmQ2hhbmdlZChtYW5pZmVzdEJ1aWxkUGF0aCwgbWFuaWZlc3RGaWxlUGF0aCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCBybShtYW5pZmVzdEJ1aWxkUGF0aCwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICAgICAgYXdhaXQgcm0obWFuaWZlc3RGaWxlUGF0aCwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgdGhpcy53cml0ZUZ1bmN0aW9uc0NvbmZpZyhvdXRwdXREaXIpO1xuXG4gICAgICAvLyBWMjogQ29tYmluZWQgcm91dGUgKGZsb3cpIOKAlCBzdGVwIHJlZ2lzdHJhdGlvbnMgYWxyZWFkeSBhdCBmaW5hbCBwYXRoXG4gICAgICBhd2FpdCB0aGlzLmNvcHlGaWxlSWZDaGFuZ2VkKFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCBgZmxvdy8ke3RlbXBSb3V0ZUZpbGVOYW1lfWApLFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnZmxvdy9yb3V0ZS5qcycpXG4gICAgICApO1xuICAgICAgYXdhaXQgdGhpcy5jb3B5RmlsZUlmQ2hhbmdlZChcbiAgICAgICAgam9pbih3b3JrZmxvd0dlbmVyYXRlZERpciwgYHdlYmhvb2svW3Rva2VuXS8ke3RlbXBSb3V0ZUZpbGVOYW1lfWApLFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnd2ViaG9vay9bdG9rZW5dL3JvdXRlLmpzJylcbiAgICAgICk7XG5cbiAgICAgIC8vIEV4cG9zZSBtYW5pZmVzdCBhcyBhIHN0YXRpYyBmaWxlIHdoZW4gV09SS0ZMT1dfUFVCTElDX01BTklGRVNUPTEuXG4gICAgICAvLyBOZXh0LmpzIHNlcnZlcyBmaWxlcyBmcm9tIHB1YmxpYy8gYXQgdGhlIHJvb3QgVVJMLlxuICAgICAgaWYgKHRoaXMuc2hvdWxkRXhwb3NlUHVibGljTWFuaWZlc3QgJiYgbWFuaWZlc3RKc29uKSB7XG4gICAgICAgIGNvbnN0IHB1YmxpY01hbmlmZXN0RGlyID0gam9pbihcbiAgICAgICAgICB0aGlzLmNvbmZpZy53b3JraW5nRGlyLFxuICAgICAgICAgICdwdWJsaWMvLndlbGwta25vd24vd29ya2Zsb3cvdjEnXG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IG1rZGlyKHB1YmxpY01hbmlmZXN0RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52LlZFUkNFTF9ERVBMT1lNRU5UX0lEID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLndyaXRlRmlsZUlmQ2hhbmdlZChcbiAgICAgICAgICAgIGpvaW4ocHVibGljTWFuaWZlc3REaXIsICcuZ2l0aWdub3JlJyksXG4gICAgICAgICAgICAnKidcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuY29weUZpbGVJZkNoYW5nZWQoXG4gICAgICAgICAgbWFuaWZlc3RGaWxlUGF0aCxcbiAgICAgICAgICBqb2luKHB1YmxpY01hbmlmZXN0RGlyLCAnbWFuaWZlc3QuanNvbicpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIE5vdGlmeSBkZWZlcnJlZCBlbnRyeSBsb2FkZXJzIHdhaXRpbmcgb24gcm91dGUuanMgc3R1YnMuXG4gICAgICB0aGlzLnNvY2tldElPPy5lbWl0KCdidWlsZC1jb21wbGV0ZScpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgY3JlYXRlRGVmZXJyZWRGbG93Um91dGUoe1xuICAgICAgaW5wdXRGaWxlcyxcbiAgICAgIGZsb3dPdXRmaWxlLFxuICAgICAgdHNjb25maWdQYXRoLFxuICAgICAgZGlzY292ZXJlZEVudHJpZXMsXG4gICAgfToge1xuICAgICAgaW5wdXRGaWxlczogc3RyaW5nW107XG4gICAgICBmbG93T3V0ZmlsZTogc3RyaW5nO1xuICAgICAgdHNjb25maWdQYXRoPzogc3RyaW5nO1xuICAgICAgZGlzY292ZXJlZEVudHJpZXM6IHtcbiAgICAgICAgZGlzY292ZXJlZFN0ZXBzOiBTZXQ8c3RyaW5nPjtcbiAgICAgICAgZGlzY292ZXJlZFdvcmtmbG93czogU2V0PHN0cmluZz47XG4gICAgICAgIGRpc2NvdmVyZWRTZXJkZUZpbGVzOiBTZXQ8c3RyaW5nPjtcbiAgICAgIH07XG4gICAgfSk6IFByb21pc2U8eyBtYW5pZmVzdDogV29ya2Zsb3dNYW5pZmVzdCB9PiB7XG4gICAgICBjb25zdCB3b3JrZmxvd1Jlc3VsdCA9IGF3YWl0IHRoaXMuY3JlYXRlV29ya2Zsb3dzQnVuZGxlKHtcbiAgICAgICAgaW5wdXRGaWxlcyxcbiAgICAgICAgb3V0ZmlsZTogYCR7Zmxvd091dGZpbGV9Ll9fd2ZfdG1wLmpzYCxcbiAgICAgICAgZm9ybWF0OiAnZXNtJyxcbiAgICAgICAgYnVuZGxlRmluYWxPdXRwdXQ6IGZhbHNlLFxuICAgICAgICB0c2NvbmZpZ1BhdGgsXG4gICAgICAgIGRpc2NvdmVyZWRFbnRyaWVzLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHdvcmtmbG93Vk1Db2RlID0gd29ya2Zsb3dSZXN1bHQuaW50ZXJpbUJ1bmRsZVRleHQ7XG4gICAgICBpZiAoIXdvcmtmbG93Vk1Db2RlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnY3JlYXRlV29ya2Zsb3dzQnVuZGxlIGRpZCBub3QgcmV0dXJuIGludGVyaW1CdW5kbGVUZXh0J1xuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBybShgJHtmbG93T3V0ZmlsZX0uX193Zl90bXAuanNgLCB7IGZvcmNlOiB0cnVlIH0pO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIElnbm9yZSBjbGVhbnVwIGVycm9ycy5cbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RlcEFuZFNlcmRlRmlsZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFtcbiAgICAgICAgICAuLi5kaXNjb3ZlcmVkRW50cmllcy5kaXNjb3ZlcmVkU3RlcHMsXG4gICAgICAgICAgLi4uZGlzY292ZXJlZEVudHJpZXMuZGlzY292ZXJlZFNlcmRlRmlsZXMsXG4gICAgICAgIF0pXG4gICAgICApLnNvcnQoKTtcbiAgICAgIGNvbnN0IHN0ZXBJbXBvcnRzID0gYXdhaXQgdGhpcy5jcmVhdGVEZWZlcnJlZFN0ZXBTaWRlRWZmZWN0SW1wb3J0cyhcbiAgICAgICAgc3RlcEFuZFNlcmRlRmlsZXMsXG4gICAgICAgIGRpcm5hbWUoZmxvd091dGZpbGUpXG4gICAgICApO1xuICAgICAgY29uc3Qgc3RlcE1hbmlmZXN0ID1cbiAgICAgICAgYXdhaXQgdGhpcy5jcmVhdGVEZWZlcnJlZFN0ZXBNYW5pZmVzdChzdGVwQW5kU2VyZGVGaWxlcyk7XG4gICAgICBjb25zdCBlc2NhcGVkVk1Db2RlID0gd29ya2Zsb3dWTUNvZGUucmVwbGFjZSgvW1xcXFxgJF0vZywgJ1xcXFwkJicpO1xuICAgICAgY29uc3Qgd29ya2Zsb3dFbnRyeXBvaW50T3B0aW9uc0NvZGUgPVxuICAgICAgICBjcmVhdGVXb3JrZmxvd0VudHJ5cG9pbnRPcHRpb25zQ29kZSgpO1xuICAgICAgbGV0IHJvdXRlQ29kZTogc3RyaW5nO1xuXG4gICAgICBpZiAodGhpcy5jb25maWcud2F0Y2gpIHtcbiAgICAgICAgY29uc3Qgd29ya2Zsb3dDb2RlUGF0aCA9IGpvaW4oXG4gICAgICAgICAgZGlybmFtZShmbG93T3V0ZmlsZSksXG4gICAgICAgICAgREVWX1dPUktGTE9XX0NPREVfRklMRU5BTUVcbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgdGhpcy53cml0ZUZpbGVJZkNoYW5nZWQod29ya2Zsb3dDb2RlUGF0aCwgd29ya2Zsb3dWTUNvZGUpO1xuICAgICAgICByb3V0ZUNvZGUgPSBgLy8gYmlvbWUtaWdub3JlLWFsbCBsaW50OiBnZW5lcmF0ZWQgZmlsZVxuLyogZXNsaW50LWRpc2FibGUgKi9cbmltcG9ydCAnd29ya2Zsb3cvaW50ZXJuYWwvYnVpbHRpbnMnO1xuJHtzdGVwSW1wb3J0c31cbmltcG9ydCB7IHJlYWRGaWxlLCBzdGF0IH0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyB3b3JrZmxvd0VudHJ5cG9pbnQgfSBmcm9tICd3b3JrZmxvdy9ydW50aW1lJztcblxuY29uc3Qgd29ya2Zsb3dDb2RlUGF0aCA9ICR7SlNPTi5zdHJpbmdpZnkod29ya2Zsb3dDb2RlUGF0aCl9O1xubGV0IGNhY2hlZFdvcmtmbG93SGFuZGxlcjtcbmxldCBjYWNoZWRXb3JrZmxvd0NvZGVTaWduYXR1cmU7XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFdvcmtmbG93SGFuZGxlcigpIHtcbiAgY29uc3Qgd29ya2Zsb3dDb2RlU3RhdHMgPSBhd2FpdCBzdGF0KHdvcmtmbG93Q29kZVBhdGgpO1xuICBjb25zdCB3b3JrZmxvd0NvZGVTaWduYXR1cmUgPSBcXGBcXCR7d29ya2Zsb3dDb2RlU3RhdHMuc2l6ZX06XFwke3dvcmtmbG93Q29kZVN0YXRzLm10aW1lTXN9XFxgO1xuICBpZiAoIWNhY2hlZFdvcmtmbG93SGFuZGxlciB8fCBjYWNoZWRXb3JrZmxvd0NvZGVTaWduYXR1cmUgIT09IHdvcmtmbG93Q29kZVNpZ25hdHVyZSkge1xuICAgIGNvbnN0IHdvcmtmbG93Q29kZSA9IGF3YWl0IHJlYWRGaWxlKHdvcmtmbG93Q29kZVBhdGgsICd1dGY4Jyk7XG4gICAgY2FjaGVkV29ya2Zsb3dIYW5kbGVyID0gd29ya2Zsb3dFbnRyeXBvaW50KHdvcmtmbG93Q29kZSR7d29ya2Zsb3dFbnRyeXBvaW50T3B0aW9uc0NvZGV9KTtcbiAgICBjYWNoZWRXb3JrZmxvd0NvZGVTaWduYXR1cmUgPSB3b3JrZmxvd0NvZGVTaWduYXR1cmU7XG4gIH1cbiAgcmV0dXJuIGNhY2hlZFdvcmtmbG93SGFuZGxlcjtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIFBPU1QocmVxKSB7XG4gIHJldHVybiAoYXdhaXQgZ2V0V29ya2Zsb3dIYW5kbGVyKCkpKHJlcSk7XG59YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJvdXRlQ29kZSA9IGAvLyBiaW9tZS1pZ25vcmUtYWxsIGxpbnQ6IGdlbmVyYXRlZCBmaWxlXG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xuaW1wb3J0ICd3b3JrZmxvdy9pbnRlcm5hbC9idWlsdGlucyc7XG4ke3N0ZXBJbXBvcnRzfVxuaW1wb3J0IHsgd29ya2Zsb3dFbnRyeXBvaW50IH0gZnJvbSAnd29ya2Zsb3cvcnVudGltZSc7XG5cbmNvbnN0IHdvcmtmbG93Q29kZSA9IFxcYCR7ZXNjYXBlZFZNQ29kZX1cXGA7XG5cbmV4cG9ydCBjb25zdCBQT1NUID0gd29ya2Zsb3dFbnRyeXBvaW50KHdvcmtmbG93Q29kZSR7d29ya2Zsb3dFbnRyeXBvaW50T3B0aW9uc0NvZGV9KTtgO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCB0aGlzLndyaXRlRmlsZUlmQ2hhbmdlZChmbG93T3V0ZmlsZSwgcm91dGVDb2RlKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbWFuaWZlc3Q6IHtcbiAgICAgICAgICAuLi5zdGVwTWFuaWZlc3QsXG4gICAgICAgICAgd29ya2Zsb3dzOiB7XG4gICAgICAgICAgICAuLi5zdGVwTWFuaWZlc3Qud29ya2Zsb3dzLFxuICAgICAgICAgICAgLi4ud29ya2Zsb3dSZXN1bHQubWFuaWZlc3Qud29ya2Zsb3dzLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgY2xhc3Nlczoge1xuICAgICAgICAgICAgLi4uc3RlcE1hbmlmZXN0LmNsYXNzZXMsXG4gICAgICAgICAgICAuLi53b3JrZmxvd1Jlc3VsdC5tYW5pZmVzdC5jbGFzc2VzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgY3JlYXRlRGVmZXJyZWRTdGVwU2lkZUVmZmVjdEltcG9ydHMoXG4gICAgICBmaWxlczogc3RyaW5nW10sXG4gICAgICByb3V0ZURpcjogc3RyaW5nXG4gICAgKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgIGNvbnN0IGltcG9ydFNwZWNpZmllcnMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgZmlsZXMubWFwKChmaWxlKSA9PlxuICAgICAgICAgIHRoaXMuZ2V0RGVmZXJyZWRSb3V0ZUltcG9ydFNwZWNpZmllcihmaWxlLCByb3V0ZURpcilcbiAgICAgICAgKVxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIGltcG9ydFNwZWNpZmllcnNcbiAgICAgICAgLm1hcCgoc3BlY2lmaWVyKSA9PiBgaW1wb3J0ICR7SlNPTi5zdHJpbmdpZnkoc3BlY2lmaWVyKX07YClcbiAgICAgICAgLmpvaW4oJ1xcbicpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZ2V0RGVmZXJyZWRSb3V0ZUltcG9ydFNwZWNpZmllcihcbiAgICAgIGZpbGU6IHN0cmluZyxcbiAgICAgIHJvdXRlRGlyOiBzdHJpbmdcbiAgICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgY29uc3QgeyBpbXBvcnRQYXRoLCBpc1BhY2thZ2UgfSA9IGdldEltcG9ydFBhdGgoXG4gICAgICAgIGZpbGUsXG4gICAgICAgIHRoaXMuY29uZmlnLndvcmtpbmdEaXJcbiAgICAgICk7XG5cbiAgICAgIGlmIChpc1BhY2thZ2UpIHtcbiAgICAgICAgcmV0dXJuIGltcG9ydFBhdGg7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IGF3YWl0IHRoaXMucmVzb2x2ZURlZmVycmVkUm91dGVJbXBvcnRGaWxlUGF0aChcbiAgICAgICAgcmVzb2x2ZSh0aGlzLmNvbmZpZy53b3JraW5nRGlyLCBpbXBvcnRQYXRoKVxuICAgICAgKTtcbiAgICAgIGxldCByZWxhdGl2ZVBhdGggPSByZWxhdGl2ZShyb3V0ZURpciwgYWJzb2x1dGVQYXRoKS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gICAgICBpZiAoIXJlbGF0aXZlUGF0aC5zdGFydHNXaXRoKCcuLycpICYmICFyZWxhdGl2ZVBhdGguc3RhcnRzV2l0aCgnLi4vJykpIHtcbiAgICAgICAgcmVsYXRpdmVQYXRoID0gYC4vJHtyZWxhdGl2ZVBhdGh9YDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZWxhdGl2ZVBhdGg7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZXNvbHZlRGVmZXJyZWRSb3V0ZUltcG9ydEZpbGVQYXRoKFxuICAgICAgZmlsZVBhdGg6IHN0cmluZ1xuICAgICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICBjb25zdCBwYWNrYWdlRGlzdFBhdGggPVxuICAgICAgICB0aGlzLnJlc29sdmVQYWNrYWdlU291cmNlRGlzdEZpbGVQYXRoRm9yUm91dGVJbXBvcnQoZmlsZVBhdGgpO1xuICAgICAgaWYgKHBhY2thZ2VEaXN0UGF0aCkge1xuICAgICAgICByZXR1cm4gcGFja2FnZURpc3RQYXRoO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmlsZVBhdGg7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZXNvbHZlUGFja2FnZVNvdXJjZURpc3RGaWxlUGF0aEZvclJvdXRlSW1wb3J0KFxuICAgICAgZmlsZVBhdGg6IHN0cmluZ1xuICAgICk6IHN0cmluZyB8IG51bGwge1xuICAgICAgY29uc3QgcmVsYXRpdmVUb1dvcmtpbmdEaXIgPSByZWxhdGl2ZSh0aGlzLmNvbmZpZy53b3JraW5nRGlyLCBmaWxlUGF0aCk7XG4gICAgICBpZiAoXG4gICAgICAgICFyZWxhdGl2ZVRvV29ya2luZ0Rpci5zdGFydHNXaXRoKCcuLicpICYmXG4gICAgICAgICFpc0Fic29sdXRlKHJlbGF0aXZlVG9Xb3JraW5nRGlyKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYWNrYWdlUm9vdCA9IHRoaXMuZmluZFBhY2thZ2VSb290Rm9yUm91dGVJbXBvcnRTb3VyY2UoZmlsZVBhdGgpO1xuICAgICAgaWYgKCFwYWNrYWdlUm9vdCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVsYXRpdmVUb1BhY2thZ2VSb290ID0gcmVsYXRpdmUocGFja2FnZVJvb3QsIGZpbGVQYXRoKS5yZXBsYWNlKFxuICAgICAgICAvXFxcXC9nLFxuICAgICAgICAnLydcbiAgICAgICk7XG4gICAgICBjb25zdCBzcmNQcmVmaXggPSAnc3JjLyc7XG4gICAgICBpZiAoIXJlbGF0aXZlVG9QYWNrYWdlUm9vdC5zdGFydHNXaXRoKHNyY1ByZWZpeCkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGV4dG5hbWUocmVsYXRpdmVUb1BhY2thZ2VSb290KTtcbiAgICAgIGNvbnN0IG91dHB1dEV4dGVuc2lvbiA9XG4gICAgICAgIGV4dGVuc2lvbiA9PT0gJy5tdHMnID8gJy5tanMnIDogZXh0ZW5zaW9uID09PSAnLmN0cycgPyAnLmNqcycgOiAnLmpzJztcbiAgICAgIGNvbnN0IHdpdGhvdXRFeHRlbnNpb24gPSByZWxhdGl2ZVRvUGFja2FnZVJvb3Quc2xpY2UoXG4gICAgICAgIHNyY1ByZWZpeC5sZW5ndGgsXG4gICAgICAgIHJlbGF0aXZlVG9QYWNrYWdlUm9vdC5sZW5ndGggLSBleHRlbnNpb24ubGVuZ3RoXG4gICAgICApO1xuICAgICAgY29uc3QgZGlzdFBhdGggPSBqb2luKFxuICAgICAgICBwYWNrYWdlUm9vdCxcbiAgICAgICAgJ2Rpc3QnLFxuICAgICAgICBgJHt3aXRob3V0RXh0ZW5zaW9ufSR7b3V0cHV0RXh0ZW5zaW9ufWBcbiAgICAgICk7XG5cbiAgICAgIHJldHVybiBleGlzdHNTeW5jKGRpc3RQYXRoKSA/IGRpc3RQYXRoIDogbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGZpbmRQYWNrYWdlUm9vdEZvclJvdXRlSW1wb3J0U291cmNlKFxuICAgICAgZmlsZVBhdGg6IHN0cmluZ1xuICAgICk6IHN0cmluZyB8IG51bGwge1xuICAgICAgbGV0IGN1cnJlbnREaXIgPSBkaXJuYW1lKGZpbGVQYXRoKTtcblxuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaWYgKGV4aXN0c1N5bmMoam9pbihjdXJyZW50RGlyLCAncGFja2FnZS5qc29uJykpKSB7XG4gICAgICAgICAgcmV0dXJuIGN1cnJlbnREaXI7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXJlbnREaXIgPSBkaXJuYW1lKGN1cnJlbnREaXIpO1xuICAgICAgICBpZiAocGFyZW50RGlyID09PSBjdXJyZW50RGlyKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudERpciA9IHBhcmVudERpcjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNyZWF0ZURlZmVycmVkU3RlcE1hbmlmZXN0KFxuICAgICAgZmlsZXM6IHN0cmluZ1tdXG4gICAgKTogUHJvbWlzZTxXb3JrZmxvd01hbmlmZXN0PiB7XG4gICAgICBjb25zdCBtYW5pZmVzdDogV29ya2Zsb3dNYW5pZmVzdCA9IHt9O1xuICAgICAgY29uc3QgbWFuaWZlc3RGaWxlcyA9IEFycmF5LmZyb20oXG4gICAgICAgIG5ldyBTZXQoW1xuICAgICAgICAgIC4uLmZpbGVzLFxuICAgICAgICAgIC4uLihhd2FpdCB0aGlzLnJlc29sdmVCdWlsdEluU3RlcEZpbGVzRm9yTWFuaWZlc3QoKSksXG4gICAgICAgIF0pXG4gICAgICApLnNvcnQoKTtcblxuICAgICAgZm9yIChjb25zdCBmaWxlIG9mIG1hbmlmZXN0RmlsZXMpIHtcbiAgICAgICAgY29uc3Qgc291cmNlID0gYXdhaXQgcmVhZEZpbGUoZmlsZSwgJ3V0ZjgnKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgICAgICBpZiAoIXNvdXJjZSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVsYXRpdmVGaWxlcGF0aCA9IGF3YWl0IHRoaXMuZ2V0UmVsYXRpdmVGaWxlbmFtZUZvclN3YyhmaWxlKTtcbiAgICAgICAgY29uc3QgeyB3b3JrZmxvd01hbmlmZXN0IH0gPSBhd2FpdCBhcHBseVN3Y1RyYW5zZm9ybShcbiAgICAgICAgICByZWxhdGl2ZUZpbGVwYXRoLFxuICAgICAgICAgIHNvdXJjZSxcbiAgICAgICAgICAnc3RlcCcsXG4gICAgICAgICAgZmlsZSxcbiAgICAgICAgICB0aGlzLnRyYW5zZm9ybVByb2plY3RSb290LFxuICAgICAgICAgIHRoaXMubW9kdWxlU3BlY2lmaWVyUm9vdFxuICAgICAgICApO1xuICAgICAgICB0aGlzLm1lcmdlV29ya2Zsb3dNYW5pZmVzdChtYW5pZmVzdCwgd29ya2Zsb3dNYW5pZmVzdCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBtYW5pZmVzdDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlc29sdmVCdWlsdEluU3RlcEZpbGVzRm9yTWFuaWZlc3QoKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgd29ya2Zsb3dSZXF1aXJlID0gY3JlYXRlUmVxdWlyZShcbiAgICAgICAgICBqb2luKHRoaXMuY29uZmlnLndvcmtpbmdEaXIsICdwYWNrYWdlLmpzb24nKVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIHRoaXMubm9ybWFsaXplRGlzY292ZXJlZEZpbGVQYXRoKFxuICAgICAgICAgICAgd29ya2Zsb3dSZXF1aXJlLnJlc29sdmUoJ3dvcmtmbG93L2ludGVybmFsL2J1aWx0aW5zJylcbiAgICAgICAgICApLFxuICAgICAgICBdO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG1lcmdlV29ya2Zsb3dNYW5pZmVzdChcbiAgICAgIHRhcmdldDogV29ya2Zsb3dNYW5pZmVzdCxcbiAgICAgIHNvdXJjZTogV29ya2Zsb3dNYW5pZmVzdFxuICAgICk6IHZvaWQge1xuICAgICAgdGFyZ2V0LndvcmtmbG93cyA9IE9iamVjdC5hc3NpZ24oXG4gICAgICAgIHRhcmdldC53b3JrZmxvd3MgfHwge30sXG4gICAgICAgIHNvdXJjZS53b3JrZmxvd3NcbiAgICAgICk7XG4gICAgICB0YXJnZXQuc3RlcHMgPSBPYmplY3QuYXNzaWduKHRhcmdldC5zdGVwcyB8fCB7fSwgc291cmNlLnN0ZXBzKTtcbiAgICAgIHRhcmdldC5jbGFzc2VzID0gT2JqZWN0LmFzc2lnbih0YXJnZXQuY2xhc3NlcyB8fCB7fSwgc291cmNlLmNsYXNzZXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgY2xlYW51cEdlbmVyYXRlZEFydGlmYWN0c09uQm9vdChcbiAgICAgIG91dHB1dERpcjogc3RyaW5nXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCB3b3JrZmxvd0dlbmVyYXRlZERpciA9IGpvaW4ob3V0cHV0RGlyLCAnLndlbGwta25vd24vd29ya2Zsb3cvdjEnKTtcbiAgICAgIGNvbnN0IGZsb3dSb3V0ZURpciA9IGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICdmbG93Jyk7XG4gICAgICBjb25zdCBzdGVwUm91dGVEaXIgPSBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnc3RlcCcpO1xuICAgICAgY29uc3Qgd2ViaG9va1JvdXRlRGlyID0gam9pbih3b3JrZmxvd0dlbmVyYXRlZERpciwgJ3dlYmhvb2svW3Rva2VuXScpO1xuXG4gICAgICBjb25zdCBzdGFsZUFydGlmYWN0UGF0aHMgPSBbXG4gICAgICAgIGpvaW4oZmxvd1JvdXRlRGlyLCAncm91dGUuanMudGVtcCcpLFxuICAgICAgICBqb2luKGZsb3dSb3V0ZURpciwgJ3JvdXRlLmpzLnRlbXAuZGVidWcuanNvbicpLFxuICAgICAgICBqb2luKGZsb3dSb3V0ZURpciwgJ3JvdXRlLmpzLmRlYnVnLmpzb24nKSxcbiAgICAgICAgam9pbihmbG93Um91dGVEaXIsIERFVl9XT1JLRkxPV19DT0RFX0ZJTEVOQU1FKSxcbiAgICAgICAgam9pbihmbG93Um91dGVEaXIsICdfX3N0ZXBfcmVnaXN0cmF0aW9ucy5yb3V0ZS5qcy50ZW1wJyksXG4gICAgICAgIGpvaW4oZmxvd1JvdXRlRGlyLCAnX19zdGVwX3JlZ2lzdHJhdGlvbnMucm91dGUuanMudGVtcC5kZWJ1Zy5qc29uJyksXG4gICAgICAgIC8vIFYyOiBjbGVhbiB1cCBzdGFsZSBWMSBzdGVwIHJvdXRlIGRpcmVjdG9yeVxuICAgICAgICBzdGVwUm91dGVEaXIsXG4gICAgICAgIGpvaW4od2ViaG9va1JvdXRlRGlyLCAncm91dGUuanMudGVtcCcpLFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnbWFuaWZlc3QuanNvbicpLFxuICAgICAgXTtcblxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICAuLi5zdGFsZUFydGlmYWN0UGF0aHMubWFwKChzdGFsZVBhdGgpID0+XG4gICAgICAgICAgcm0oc3RhbGVQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSlcbiAgICAgICAgKSxcbiAgICAgICAgY2xlYW51cFN0YWxlU29ja2V0SW5mb0ZpbGVzKFxuICAgICAgICAgIGpvaW4odGhpcy5jb25maWcud29ya2luZ0RpciwgdGhpcy5nZXREaXN0RGlyKCkpXG4gICAgICAgICksXG4gICAgICAgIHRoaXMucmVtb3ZlU3RhbGVEZWZlcnJlZFRlbXBGaWxlcyhmbG93Um91dGVEaXIpLFxuICAgICAgICB0aGlzLnJlbW92ZVN0YWxlRGVmZXJyZWRUZW1wRmlsZXMod2ViaG9va1JvdXRlRGlyKSxcbiAgICAgIF0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVtb3ZlU3RhbGVEZWZlcnJlZFRlbXBGaWxlcyhcbiAgICAgIHJvdXRlRGlyOiBzdHJpbmdcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGNvbnN0IHJvdXRlRW50cmllcyA9IGF3YWl0IHJlYWRkaXIocm91dGVEaXIsIHtcbiAgICAgICAgd2l0aEZpbGVUeXBlczogdHJ1ZSxcbiAgICAgIH0pLmNhdGNoKCgpID0+IFtdKTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICByb3V0ZUVudHJpZXNcbiAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgKGVudHJ5KSA9PlxuICAgICAgICAgICAgICBlbnRyeS5pc0ZpbGUoKSAmJlxuICAgICAgICAgICAgICBlbnRyeS5uYW1lLnN0YXJ0c1dpdGgoJ3JvdXRlLmpzLicpICYmXG4gICAgICAgICAgICAgIGVudHJ5Lm5hbWUuZW5kc1dpdGgoJy50bXAnKVxuICAgICAgICAgIClcbiAgICAgICAgICAubWFwKChlbnRyeSkgPT5cbiAgICAgICAgICAgIHJtKGpvaW4ocm91dGVEaXIsIGVudHJ5Lm5hbWUpLCB7XG4gICAgICAgICAgICAgIGZvcmNlOiB0cnVlLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApXG4gICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgY3JlYXRlRGlzY292ZXJ5U29ja2V0U2VydmVyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgaWYgKHRoaXMuc29ja2V0SU8gfHwgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfU09DS0VUX1BPUlQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBwcm9jZXNzLmVudi5XT1JLRkxPV19TT0NLRVRfSU5GT19QQVRIID0gdGhpcy5nZXRTb2NrZXRJbmZvRmlsZVBhdGgoKTtcbiAgICAgIGNvbnN0IGNvbmZpZzogU29ja2V0U2VydmVyQ29uZmlnID0ge1xuICAgICAgICBpc0RldlNlcnZlcjogQm9vbGVhbih0aGlzLmNvbmZpZy53YXRjaCksXG4gICAgICAgIHNvY2tldEluZm9GaWxlUGF0aDogdGhpcy5nZXRTb2NrZXRJbmZvRmlsZVBhdGgoKSxcbiAgICAgICAgb25GaWxlRGlzY292ZXJlZDogKFxuICAgICAgICAgIGZpbGVQYXRoOiBzdHJpbmcsXG4gICAgICAgICAgaGFzV29ya2Zsb3c6IGJvb2xlYW4sXG4gICAgICAgICAgaGFzU3RlcDogYm9vbGVhbixcbiAgICAgICAgICBoYXNTZXJkZTogYm9vbGVhblxuICAgICAgICApID0+IHtcbiAgICAgICAgICBjb25zdCBub3JtYWxpemVkRmlsZVBhdGggPSB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChmaWxlUGF0aCk7XG4gICAgICAgICAgbGV0IGhhc0NhY2hlVHJhY2tpbmdDaGFuZ2UgPSBmYWxzZTtcbiAgICAgICAgICBjb25zdCB3YXNUcmFja2VkRGVwZW5kZW5jeSA9XG4gICAgICAgICAgICB0aGlzLnRyYWNrZWREZXBlbmRlbmN5RmlsZXMuaGFzKG5vcm1hbGl6ZWRGaWxlUGF0aCk7XG5cbiAgICAgICAgICBpZiAoaGFzV29ya2Zsb3cpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlcy5oYXMobm9ybWFsaXplZEZpbGVQYXRoKSkge1xuICAgICAgICAgICAgICB0aGlzLmRpc2NvdmVyZWRXb3JrZmxvd0ZpbGVzLmFkZChub3JtYWxpemVkRmlsZVBhdGgpO1xuICAgICAgICAgICAgICBoYXNDYWNoZVRyYWNraW5nQ2hhbmdlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgd2FzRGVsZXRlZCA9XG4gICAgICAgICAgICAgIHRoaXMuZGlzY292ZXJlZFdvcmtmbG93RmlsZXMuZGVsZXRlKG5vcm1hbGl6ZWRGaWxlUGF0aCk7XG4gICAgICAgICAgICBoYXNDYWNoZVRyYWNraW5nQ2hhbmdlID0gd2FzRGVsZXRlZCB8fCBoYXNDYWNoZVRyYWNraW5nQ2hhbmdlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChoYXNTdGVwKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzY292ZXJlZFN0ZXBGaWxlcy5oYXMobm9ybWFsaXplZEZpbGVQYXRoKSkge1xuICAgICAgICAgICAgICB0aGlzLmRpc2NvdmVyZWRTdGVwRmlsZXMuYWRkKG5vcm1hbGl6ZWRGaWxlUGF0aCk7XG4gICAgICAgICAgICAgIGhhc0NhY2hlVHJhY2tpbmdDaGFuZ2UgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB3YXNEZWxldGVkID1cbiAgICAgICAgICAgICAgdGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLmRlbGV0ZShub3JtYWxpemVkRmlsZVBhdGgpO1xuICAgICAgICAgICAgaGFzQ2FjaGVUcmFja2luZ0NoYW5nZSA9IHdhc0RlbGV0ZWQgfHwgaGFzQ2FjaGVUcmFja2luZ0NoYW5nZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaGFzU2VyZGUpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNjb3ZlcmVkU2VyZGVGaWxlcy5oYXMobm9ybWFsaXplZEZpbGVQYXRoKSkge1xuICAgICAgICAgICAgICBoYXNDYWNoZVRyYWNraW5nQ2hhbmdlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZGlzY292ZXJlZFNlcmRlRmlsZXMuYWRkKG5vcm1hbGl6ZWRGaWxlUGF0aCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHdhc0RlbGV0ZWQgPVxuICAgICAgICAgICAgICB0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLmRlbGV0ZShub3JtYWxpemVkRmlsZVBhdGgpO1xuICAgICAgICAgICAgaGFzQ2FjaGVUcmFja2luZ0NoYW5nZSA9IHdhc0RlbGV0ZWQgfHwgaGFzQ2FjaGVUcmFja2luZ0NoYW5nZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaGFzQ2FjaGVUcmFja2luZ0NoYW5nZSkge1xuICAgICAgICAgICAgdGhpcy5zY2hlZHVsZVdvcmtmbG93c0NhY2hlV3JpdGUoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBoYXNXb3JrZmxvdyB8fFxuICAgICAgICAgICAgaGFzU3RlcCB8fFxuICAgICAgICAgICAgaGFzU2VyZGUgfHxcbiAgICAgICAgICAgIGhhc0NhY2hlVHJhY2tpbmdDaGFuZ2UgfHxcbiAgICAgICAgICAgIHdhc1RyYWNrZWREZXBlbmRlbmN5XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLnNjaGVkdWxlRGVmZXJyZWRSZWJ1aWxkKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBvblRyaWdnZXJCdWlsZDogKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2NoZWR1bGVEZWZlcnJlZFJlYnVpbGQoKTtcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuc29ja2V0SU8gPSBhd2FpdCBjcmVhdGVTb2NrZXRTZXJ2ZXIoY29uZmlnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGluaXRpYWxpemVEaXNjb3ZlcnlTdGF0ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGlmICh0aGlzLmNhY2hlSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCB0aGlzLmxvYWRXb3JrZmxvd3NDYWNoZSgpO1xuICAgICAgLy8gRGVmZXJyZWQgbW9kZSBtdXN0IG5vdCBydW4gZWFnZXIgaW5wdXQtZ3JhcGggZGlzY292ZXJ5OyBlbnRyaWVzIGFyZVxuICAgICAgLy8gZGlzY292ZXJlZCB2aWEgbG9hZGVyLT5zb2NrZXQgbm90aWZpY2F0aW9ucyBkdXJpbmcgTmV4dCdzIGJ1aWxkLlxuICAgICAgdGhpcy5jYWNoZUluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERpc3REaXIoKTogc3RyaW5nIHtcbiAgICAgIHJldHVybiAodGhpcy5jb25maWcgYXMgeyBkaXN0RGlyPzogc3RyaW5nIH0pLmRpc3REaXIgfHwgJy5uZXh0JztcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFdvcmtmbG93c0NhY2hlRmlsZVBhdGgoKTogc3RyaW5nIHtcbiAgICAgIHJldHVybiBqb2luKFxuICAgICAgICB0aGlzLmNvbmZpZy53b3JraW5nRGlyLFxuICAgICAgICB0aGlzLmdldERpc3REaXIoKSxcbiAgICAgICAgJ2NhY2hlJyxcbiAgICAgICAgJ3dvcmtmbG93cy5qc29uJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFNvY2tldEluZm9GaWxlUGF0aCgpOiBzdHJpbmcge1xuICAgICAgcmV0dXJuIGpvaW4oXG4gICAgICAgIHRoaXMuY29uZmlnLndvcmtpbmdEaXIsXG4gICAgICAgIHRoaXMuZ2V0RGlzdERpcigpLFxuICAgICAgICBTT0NLRVRfSU5GT19GSUxFTkFNRVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGZpbmRQYWNrYWdlSnNvblBhdGgoZmlsZVBhdGg6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgICAgbGV0IGN1cnJlbnREaXIgPSBkaXJuYW1lKGZpbGVQYXRoKTtcbiAgICAgIGxldCBwcmV2aW91c0RpciA9ICcnO1xuXG4gICAgICB3aGlsZSAoY3VycmVudERpciAhPT0gcHJldmlvdXNEaXIpIHtcbiAgICAgICAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gam9pbihjdXJyZW50RGlyLCAncGFja2FnZS5qc29uJyk7XG4gICAgICAgIGlmIChleGlzdHNTeW5jKHBhY2thZ2VKc29uUGF0aCkpIHtcbiAgICAgICAgICByZXR1cm4gcGFja2FnZUpzb25QYXRoO1xuICAgICAgICB9XG4gICAgICAgIHByZXZpb3VzRGlyID0gY3VycmVudERpcjtcbiAgICAgICAgY3VycmVudERpciA9IGRpcm5hbWUoY3VycmVudERpcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2hvdWxkUHJlZmVyU291cmNlQmFja2VkUGFja2FnZVBhdGgoZmlsZVBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSBmaWxlUGF0aC5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gICAgICAvLyBPbmx5IHByZWZlciBzb3VyY2UgZm9yIHdvcmtzcGFjZSBwYWNrYWdlcyAobm90IGluIG5vZGVfbW9kdWxlcykuXG4gICAgICAvLyBGb3IgdGFyYmFsbC1pbnN0YWxsZWQgcGFja2FnZXMsIHVzaW5nIHNvdXJjZS1iYWNrZWQgcGF0aHMgY2F1c2VzXG4gICAgICAvLyBlc2J1aWxkIHRvIGJ1bmRsZSB0aGUgZnVsbCBzb3VyY2UgdHJlZSAoaW5jbHVkaW5nIHdvcmxkLnRzIHdpdGhcbiAgICAgIC8vIHByb2Nlc3MuY3dkKCkpIGluc3RlYWQgb2YgZXh0ZXJuYWxpemluZyBwcm9wZXJseS5cbiAgICAgIGlmIChcbiAgICAgICAgbm9ybWFsaXplZFBhdGguaW5jbHVkZXMoJy9wYWNrYWdlcy8nKSAmJlxuICAgICAgICAhbm9ybWFsaXplZFBhdGguaW5jbHVkZXMoJy9ub2RlX21vZHVsZXMvJylcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFub3JtYWxpemVkUGF0aC5pbmNsdWRlcygnL25vZGVfbW9kdWxlcy8nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhY2thZ2VKc29uUGF0aCA9IHRoaXMuZmluZFBhY2thZ2VKc29uUGF0aChmaWxlUGF0aCk7XG4gICAgICBpZiAoIXBhY2thZ2VKc29uUGF0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHBhY2thZ2VKc29uID0gSlNPTi5wYXJzZShcbiAgICAgICAgICByZWFkRmlsZVN5bmMocGFja2FnZUpzb25QYXRoLCAndXRmLTgnKVxuICAgICAgICApIGFzIHsgbmFtZT86IHVua25vd24gfTtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBwYWNrYWdlSnNvbi5uYW1lID09PSAnd29ya2Zsb3cnIHx8XG4gICAgICAgICAgKHR5cGVvZiBwYWNrYWdlSnNvbi5uYW1lID09PSAnc3RyaW5nJyAmJlxuICAgICAgICAgICAgcGFja2FnZUpzb24ubmFtZS5zdGFydHNXaXRoKCdAd29ya2Zsb3cvJykpXG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgbm9ybWFsaXplRGlzY292ZXJlZEZpbGVQYXRoKGZpbGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgcmV0dXJuIGlzQWJzb2x1dGUoZmlsZVBhdGgpXG4gICAgICAgID8gZmlsZVBhdGhcbiAgICAgICAgOiByZXNvbHZlKHRoaXMuY29uZmlnLndvcmtpbmdEaXIsIGZpbGVQYXRoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGZpbHRlckV4aXN0aW5nRmlsZXMoZmlsZVBhdGhzOiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRGaWxlUGF0aHMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFxuICAgICAgICAgIGZpbGVQYXRocy5tYXAoKGZpbGVQYXRoKSA9PlxuICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVEaXNjb3ZlcmVkRmlsZVBhdGgoZmlsZVBhdGgpXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICApLnNvcnQoKTtcblxuICAgICAgY29uc3QgZXhpc3RpbmdGaWxlcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBub3JtYWxpemVkRmlsZVBhdGhzLm1hcChhc3luYyAoZmlsZVBhdGgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZmlsZVN0YXRzID0gYXdhaXQgc3RhdChmaWxlUGF0aCk7XG4gICAgICAgICAgICByZXR1cm4gZmlsZVN0YXRzLmlzRmlsZSgpID8gZmlsZVBhdGggOiBudWxsO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIGV4aXN0aW5nRmlsZXMuZmlsdGVyKChmaWxlUGF0aCk6IGZpbGVQYXRoIGlzIHN0cmluZyA9PlxuICAgICAgICBCb29sZWFuKGZpbGVQYXRoKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNyZWF0ZURlZmVycmVkQnVpbGRTaWduYXR1cmUoXG4gICAgICBpbnB1dEZpbGVzOiBzdHJpbmdbXVxuICAgICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICBjb25zdCBub3JtYWxpemVkRmlsZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFtcbiAgICAgICAgICAuLi5pbnB1dEZpbGVzLm1hcCgoZmlsZVBhdGgpID0+XG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChmaWxlUGF0aClcbiAgICAgICAgICApLFxuICAgICAgICAgIC4uLnRoaXMudHJhY2tlZERlcGVuZGVuY3lGaWxlcyxcbiAgICAgICAgXSlcbiAgICAgICkuc29ydCgpO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmVQYXJ0cyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBub3JtYWxpemVkRmlsZXMubWFwKGFzeW5jIChmaWxlUGF0aCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlU3RhdHMgPSBhd2FpdCBzdGF0KGZpbGVQYXRoKTtcbiAgICAgICAgICAgIHJldHVybiBgJHtmaWxlUGF0aH06JHtmaWxlU3RhdHMuc2l6ZX06JHtNYXRoLnRydW5jKGZpbGVTdGF0cy5tdGltZU1zKX1gO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgcmV0dXJuIGAke2ZpbGVQYXRofTptaXNzaW5nYDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICApO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmVIYXNoID0gY3JlYXRlSGFzaCgnc2hhMjU2Jyk7XG4gICAgICBmb3IgKGNvbnN0IHNpZ25hdHVyZVBhcnQgb2Ygc2lnbmF0dXJlUGFydHMpIHtcbiAgICAgICAgc2lnbmF0dXJlSGFzaC51cGRhdGUoc2lnbmF0dXJlUGFydCk7XG4gICAgICAgIHNpZ25hdHVyZUhhc2gudXBkYXRlKCdcXG4nKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNpZ25hdHVyZUhhc2guZGlnZXN0KCdoZXgnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNvbGxlY3RUcmFja2VkRGlzY292ZXJlZEVudHJpZXMoKTogUHJvbWlzZTx7XG4gICAgICBkaXNjb3ZlcmVkU3RlcHM6IHN0cmluZ1tdO1xuICAgICAgZGlzY292ZXJlZFdvcmtmbG93czogc3RyaW5nW107XG4gICAgICBkaXNjb3ZlcmVkU2VyZGVGaWxlczogc3RyaW5nW107XG4gICAgfT4ge1xuICAgICAgaWYgKHRoaXMudHJhY2tlZERlcGVuZGVuY3lGaWxlcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGlzY292ZXJlZFN0ZXBzOiBbXSxcbiAgICAgICAgICBkaXNjb3ZlcmVkV29ya2Zsb3dzOiBbXSxcbiAgICAgICAgICBkaXNjb3ZlcmVkU2VyZGVGaWxlczogW10sXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgd29ya2Zsb3dGaWxlcywgc3RlcEZpbGVzLCBzZXJkZUZpbGVzIH0gPVxuICAgICAgICBhd2FpdCB0aGlzLnJlY29uY2lsZURpc2NvdmVyZWRFbnRyaWVzKHtcbiAgICAgICAgICB3b3JrZmxvd0NhbmRpZGF0ZXM6IHRoaXMudHJhY2tlZERlcGVuZGVuY3lGaWxlcyxcbiAgICAgICAgICBzdGVwQ2FuZGlkYXRlczogdGhpcy50cmFja2VkRGVwZW5kZW5jeUZpbGVzLFxuICAgICAgICAgIHNlcmRlQ2FuZGlkYXRlczogdGhpcy50cmFja2VkRGVwZW5kZW5jeUZpbGVzLFxuICAgICAgICAgIHZhbGlkYXRlUGF0dGVybnM6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkaXNjb3ZlcmVkU3RlcHM6IEFycmF5LmZyb20oc3RlcEZpbGVzKS5zb3J0KCksXG4gICAgICAgIGRpc2NvdmVyZWRXb3JrZmxvd3M6IEFycmF5LmZyb20od29ya2Zsb3dGaWxlcykuc29ydCgpLFxuICAgICAgICBkaXNjb3ZlcmVkU2VyZGVGaWxlczogQXJyYXkuZnJvbShzZXJkZUZpbGVzKS5zb3J0KCksXG4gICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVmcmVzaFRyYWNrZWREZXBlbmRlbmN5RmlsZXMoXG4gICAgICB3b3JrZmxvd0dlbmVyYXRlZERpcjogc3RyaW5nLFxuICAgICAgcm91dGVGaWxlTmFtZTogc3RyaW5nXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCBidW5kbGVGaWxlcyA9IFtcbiAgICAgICAgam9pbih3b3JrZmxvd0dlbmVyYXRlZERpciwgYHN0ZXAvJHtyb3V0ZUZpbGVOYW1lfWApLFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCBgZmxvdy8ke3JvdXRlRmlsZU5hbWV9YCksXG4gICAgICBdO1xuICAgICAgY29uc3QgdHJhY2tlZEZpbGVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICAgIGZvciAoY29uc3QgYnVuZGxlRmlsZSBvZiBidW5kbGVGaWxlcykge1xuICAgICAgICBjb25zdCBidW5kbGVTb3VyY2VzID0gYXdhaXQgdGhpcy5leHRyYWN0QnVuZGxlU291cmNlRmlsZXMoYnVuZGxlRmlsZSk7XG4gICAgICAgIGZvciAoY29uc3Qgc291cmNlRmlsZSBvZiBidW5kbGVTb3VyY2VzKSB7XG4gICAgICAgICAgdHJhY2tlZEZpbGVzLmFkZChzb3VyY2VGaWxlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodHJhY2tlZEZpbGVzLnNpemUgPiAwKSB7XG4gICAgICAgIHRoaXMudHJhY2tlZERlcGVuZGVuY3lGaWxlcyA9IHRyYWNrZWRGaWxlcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGV4dHJhY3RCdW5kbGVTb3VyY2VGaWxlcyhcbiAgICAgIGJ1bmRsZUZpbGVQYXRoOiBzdHJpbmdcbiAgICApOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICBsZXQgYnVuZGxlQ29udGVudHM6IHN0cmluZztcbiAgICAgIHRyeSB7XG4gICAgICAgIGJ1bmRsZUNvbnRlbnRzID0gYXdhaXQgcmVhZEZpbGUoYnVuZGxlRmlsZVBhdGgsICd1dGYtOCcpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmFzZURpcmVjdG9yeSA9IGRpcm5hbWUoYnVuZGxlRmlsZVBhdGgpO1xuICAgICAgY29uc3QgbG9jYWxTb3VyY2VGaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgICAvLyBFeHRyYWN0IGlubGluZSBiYXNlNjQgc291cmNlbWFwcyB2aWEgc3RyaW5nIHNjYW5uaW5nLiBBIHByZXZpb3VzXG4gICAgICAvLyBpbXBsZW1lbnRhdGlvbiB1c2VkIGBidW5kbGVDb250ZW50cy5tYXRjaEFsbCgvLi4uW0EtWmEtejAtOSsvPV0rLi4uL2cpYFxuICAgICAgLy8gd2hpY2ggb3ZlcmZsb3dzIFY4J3MgcmVnZXggc3RhY2tcbiAgICAgIC8vIChgUmFuZ2VFcnJvcjogTWF4aW11bSBjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWQgYXQgUmVnRXhwU3RyaW5nSXRlcmF0b3IubmV4dGApXG4gICAgICAvLyBvbiBidW5kbGVzIHdpdGggbGFyZ2UgaW5saW5lIHNvdXJjZW1hcHMg4oCUIFY4J3MgaXJyZWdleHAgdXNlc1xuICAgICAgLy8gcmVjdXJzaW9uIGZvciBncmVlZHkgY2hhcmFjdGVyLWNsYXNzIHF1YW50aWZpZXJzIGFuZCBjZXJ0YWluIGxvbmdcbiAgICAgIC8vIGJhc2U2NCBpbnB1dHMgZXhoYXVzdCB0aGUgY2FsbCBzdGFjay5cbiAgICAgIGNvbnN0IHNvdXJjZU1hcFByZWZpeCA9ICcvLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb24nO1xuICAgICAgY29uc3QgYmFzZTY0TWFya2VyID0gJztiYXNlNjQsJztcbiAgICAgIGNvbnN0IHNvdXJjZU1hcE1hdGNoZXM6IEFycmF5PHsgYmFzZTY0VmFsdWU6IHN0cmluZyB9PiA9IFtdO1xuICAgICAgbGV0IHNjYW5Gcm9tID0gMDtcbiAgICAgIHdoaWxlIChzY2FuRnJvbSA8IGJ1bmRsZUNvbnRlbnRzLmxlbmd0aCkge1xuICAgICAgICBjb25zdCBwcmVmaXhJZHggPSBidW5kbGVDb250ZW50cy5pbmRleE9mKHNvdXJjZU1hcFByZWZpeCwgc2NhbkZyb20pO1xuICAgICAgICBpZiAocHJlZml4SWR4ID09PSAtMSkgYnJlYWs7XG4gICAgICAgIGNvbnN0IGJhc2U2NFN0YXJ0ID0gYnVuZGxlQ29udGVudHMuaW5kZXhPZihcbiAgICAgICAgICBiYXNlNjRNYXJrZXIsXG4gICAgICAgICAgcHJlZml4SWR4ICsgc291cmNlTWFwUHJlZml4Lmxlbmd0aFxuICAgICAgICApO1xuICAgICAgICBpZiAoYmFzZTY0U3RhcnQgPT09IC0xKSB7XG4gICAgICAgICAgc2NhbkZyb20gPSBwcmVmaXhJZHggKyBzb3VyY2VNYXBQcmVmaXgubGVuZ3RoO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJhaWwgaWYgYSBjb21tYSBhcHBlYXJzIGJlZm9yZSBgO2Jhc2U2NCxgIOKAlCB0aGF0IG1lYW5zIHRoaXNcbiAgICAgICAgLy8gd2Fzbid0IGEgYGRhdGE6YXBwbGljYXRpb24vanNvbls7cGFyYW1zXTtiYXNlNjQsLi4uYCBVUkwgYWZ0ZXJcbiAgICAgICAgLy8gYWxsICh0aGUgY29tbWEgd291bGQgdGVybWluYXRlIHRoZSBkYXRhIFVSTCBwYXJhbWV0ZXJzKS5cbiAgICAgICAgY29uc3QgY29tbWFCZWZvcmUgPSBidW5kbGVDb250ZW50cy5pbmRleE9mKCcsJywgcHJlZml4SWR4KTtcbiAgICAgICAgaWYgKGNvbW1hQmVmb3JlICE9PSAtMSAmJiBjb21tYUJlZm9yZSA8IGJhc2U2NFN0YXJ0KSB7XG4gICAgICAgICAgc2NhbkZyb20gPSBiYXNlNjRTdGFydDtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2YWx1ZVN0YXJ0ID0gYmFzZTY0U3RhcnQgKyBiYXNlNjRNYXJrZXIubGVuZ3RoO1xuICAgICAgICAvLyBCYXNlNjQgcGF5bG9hZCB0ZXJtaW5hdGVzIGF0IGZpcnN0IG5vbi1iYXNlNjQgY2hhciAobmV3bGluZSxcbiAgICAgICAgLy8gY2xvc2luZyBgKi9gLCBldGMuKS4gU2Nhbm5pbmcgYSBzbWFsbCBhbHBoYWJldCBieSBjaGFyIGlzIGZhclxuICAgICAgICAvLyBjaGVhcGVyIHRoYW4gYmFja3RyYWNraW5nIGEgcmVnZXggb3ZlciBhIG11bHRpLU1CIGNhcHR1cmUuXG4gICAgICAgIGxldCB2YWx1ZUVuZCA9IHZhbHVlU3RhcnQ7XG4gICAgICAgIHdoaWxlICh2YWx1ZUVuZCA8IGJ1bmRsZUNvbnRlbnRzLmxlbmd0aCkge1xuICAgICAgICAgIGNvbnN0IGNvZGUgPSBidW5kbGVDb250ZW50cy5jaGFyQ29kZUF0KHZhbHVlRW5kKTtcbiAgICAgICAgICAvLyBBLVogMHg0MS0weDVBLCBhLXogMHg2MS0weDdBLCAwLTkgMHgzMC0weDM5LCAnKycgMHgyQixcbiAgICAgICAgICAvLyAnLycgMHgyRiwgJz0nIDB4M0RcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhKFxuICAgICAgICAgICAgICAoY29kZSA+PSAweDQxICYmIGNvZGUgPD0gMHg1YSkgfHxcbiAgICAgICAgICAgICAgKGNvZGUgPj0gMHg2MSAmJiBjb2RlIDw9IDB4N2EpIHx8XG4gICAgICAgICAgICAgIChjb2RlID49IDB4MzAgJiYgY29kZSA8PSAweDM5KSB8fFxuICAgICAgICAgICAgICBjb2RlID09PSAweDJiIHx8XG4gICAgICAgICAgICAgIGNvZGUgPT09IDB4MmYgfHxcbiAgICAgICAgICAgICAgY29kZSA9PT0gMHgzZFxuICAgICAgICAgICAgKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhbHVlRW5kKys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlRW5kID4gdmFsdWVTdGFydCkge1xuICAgICAgICAgIHNvdXJjZU1hcE1hdGNoZXMucHVzaCh7XG4gICAgICAgICAgICBiYXNlNjRWYWx1ZTogYnVuZGxlQ29udGVudHMuc2xpY2UodmFsdWVTdGFydCwgdmFsdWVFbmQpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHNjYW5Gcm9tID0gdmFsdWVFbmQ7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2Ygc291cmNlTWFwTWF0Y2hlcykge1xuICAgICAgICBjb25zdCBiYXNlNjRWYWx1ZSA9IG1hdGNoLmJhc2U2NFZhbHVlO1xuICAgICAgICBpZiAoIWJhc2U2NFZhbHVlKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc291cmNlTWFwOiB7IHNvdXJjZVJvb3Q/OiB1bmtub3duOyBzb3VyY2VzPzogdW5rbm93biB9O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHNvdXJjZU1hcCA9IEpTT04ucGFyc2UoXG4gICAgICAgICAgICBCdWZmZXIuZnJvbShiYXNlNjRWYWx1ZSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCd1dGYtOCcpXG4gICAgICAgICAgKSBhcyB7IHNvdXJjZVJvb3Q/OiB1bmtub3duOyBzb3VyY2VzPzogdW5rbm93biB9O1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNvdXJjZVJvb3QgPVxuICAgICAgICAgIHR5cGVvZiBzb3VyY2VNYXAuc291cmNlUm9vdCA9PT0gJ3N0cmluZycgPyBzb3VyY2VNYXAuc291cmNlUm9vdCA6ICcnO1xuICAgICAgICBjb25zdCBzb3VyY2VzID0gQXJyYXkuaXNBcnJheShzb3VyY2VNYXAuc291cmNlcylcbiAgICAgICAgICA/IHNvdXJjZU1hcC5zb3VyY2VzLmZpbHRlcihcbiAgICAgICAgICAgICAgKHNvdXJjZSk6IHNvdXJjZSBpcyBzdHJpbmcgPT4gdHlwZW9mIHNvdXJjZSA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgICBpZiAoc291cmNlLnN0YXJ0c1dpdGgoJ3dlYnBhY2s6Ly8nKSB8fCBzb3VyY2Uuc3RhcnRzV2l0aCgnPCcpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsZXQgcmVzb2x2ZWRTb3VyY2VQYXRoOiBzdHJpbmc7XG4gICAgICAgICAgaWYgKHNvdXJjZS5zdGFydHNXaXRoKCdmaWxlOi8vJykpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHJlc29sdmVkU291cmNlUGF0aCA9IGRlY29kZVVSSUNvbXBvbmVudChuZXcgVVJMKHNvdXJjZSkucGF0aG5hbWUpO1xuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoaXNBYnNvbHV0ZShzb3VyY2UpKSB7XG4gICAgICAgICAgICByZXNvbHZlZFNvdXJjZVBhdGggPSBzb3VyY2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmVkU291cmNlUGF0aCA9IHJlc29sdmUoYmFzZURpcmVjdG9yeSwgc291cmNlUm9vdCwgc291cmNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBub3JtYWxpemVkU291cmNlUGF0aCA9XG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChyZXNvbHZlZFNvdXJjZVBhdGgpO1xuICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRTb3VyY2VQYXRoRm9yQ2hlY2sgPSBub3JtYWxpemVkU291cmNlUGF0aC5yZXBsYWNlKFxuICAgICAgICAgICAgL1xcXFwvZyxcbiAgICAgICAgICAgICcvJ1xuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgaXNTb3VyY2VCYWNrZWRQYWNrYWdlUGF0aCA9XG4gICAgICAgICAgICB0aGlzLnNob3VsZFByZWZlclNvdXJjZUJhY2tlZFBhY2thZ2VQYXRoKG5vcm1hbGl6ZWRTb3VyY2VQYXRoKTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBub3JtYWxpemVkU291cmNlUGF0aEZvckNoZWNrLmluY2x1ZGVzKCcvLndlbGwta25vd24vd29ya2Zsb3cvJykgfHxcbiAgICAgICAgICAgICghaXNTb3VyY2VCYWNrZWRQYWNrYWdlUGF0aCAmJlxuICAgICAgICAgICAgICBub3JtYWxpemVkU291cmNlUGF0aEZvckNoZWNrLmluY2x1ZGVzKCcvbm9kZV9tb2R1bGVzLycpKSB8fFxuICAgICAgICAgICAgKCFpc1NvdXJjZUJhY2tlZFBhY2thZ2VQYXRoICYmXG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWRTb3VyY2VQYXRoRm9yQ2hlY2suaW5jbHVkZXMoJy8ucG5wbS8nKSkgfHxcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRTb3VyY2VQYXRoRm9yQ2hlY2suaW5jbHVkZXMoJy8ubmV4dC8nKSB8fFxuICAgICAgICAgICAgbm9ybWFsaXplZFNvdXJjZVBhdGhGb3JDaGVjay5lbmRzV2l0aCgnL3ZpcnR1YWwtZW50cnkuanMnKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbG9jYWxTb3VyY2VGaWxlcy5hZGQobm9ybWFsaXplZFNvdXJjZVBhdGgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBBcnJheS5mcm9tKGxvY2FsU291cmNlRmlsZXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2NoZWR1bGVXb3JrZmxvd3NDYWNoZVdyaXRlKCk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuY2FjaGVXcml0ZVRpbWVyKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmNhY2hlV3JpdGVUaW1lcik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY2FjaGVXcml0ZVRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuY2FjaGVXcml0ZVRpbWVyID0gbnVsbDtcbiAgICAgICAgdm9pZCB0aGlzLndyaXRlV29ya2Zsb3dzQ2FjaGUoKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byB3cml0ZSB3b3JrZmxvdyBkaXNjb3ZlcnkgY2FjaGUnLCBlcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfSwgNTApO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2NoZWR1bGVEZWZlcnJlZFJlYnVpbGQoKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy5kZWZlcnJlZFJlYnVpbGRUaW1lcikge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5kZWZlcnJlZFJlYnVpbGRUaW1lcik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZGVmZXJyZWRSZWJ1aWxkVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5kZWZlcnJlZFJlYnVpbGRUaW1lciA9IG51bGw7XG4gICAgICAgIHZvaWQgdGhpcy5vbkJlZm9yZURlZmVycmVkRW50cmllcygpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICdbd29ya2Zsb3ddIERlZmVycmVkIHJlYnVpbGQgYWZ0ZXIgc291cmNlIHVwZGF0ZSBmYWlsZWQuJyxcbiAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9LCA3NSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZWFkV29ya2Zsb3dzQ2FjaGUoKTogUHJvbWlzZTx7XG4gICAgICB3b3JrZmxvd0ZpbGVzOiBzdHJpbmdbXTtcbiAgICAgIHN0ZXBGaWxlczogc3RyaW5nW107XG4gICAgfSB8IG51bGw+IHtcbiAgICAgIGNvbnN0IGNhY2hlRmlsZVBhdGggPSB0aGlzLmdldFdvcmtmbG93c0NhY2hlRmlsZVBhdGgoKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY2FjaGVDb250ZW50cyA9IGF3YWl0IHJlYWRGaWxlKGNhY2hlRmlsZVBhdGgsICd1dGYtOCcpO1xuICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGNhY2hlQ29udGVudHMpIGFzIHtcbiAgICAgICAgICB3b3JrZmxvd0ZpbGVzPzogdW5rbm93bjtcbiAgICAgICAgICBzdGVwRmlsZXM/OiB1bmtub3duO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHdvcmtmbG93RmlsZXMgPSBBcnJheS5pc0FycmF5KHBhcnNlZC53b3JrZmxvd0ZpbGVzKVxuICAgICAgICAgID8gcGFyc2VkLndvcmtmbG93RmlsZXMuZmlsdGVyKFxuICAgICAgICAgICAgICAoaXRlbSk6IGl0ZW0gaXMgc3RyaW5nID0+IHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgKVxuICAgICAgICAgIDogW107XG4gICAgICAgIGNvbnN0IHN0ZXBGaWxlcyA9IEFycmF5LmlzQXJyYXkocGFyc2VkLnN0ZXBGaWxlcylcbiAgICAgICAgICA/IHBhcnNlZC5zdGVwRmlsZXMuZmlsdGVyKFxuICAgICAgICAgICAgICAoaXRlbSk6IGl0ZW0gaXMgc3RyaW5nID0+IHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgKVxuICAgICAgICAgIDogW107XG5cbiAgICAgICAgcmV0dXJuIHsgd29ya2Zsb3dGaWxlcywgc3RlcEZpbGVzIH07XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBsb2FkV29ya2Zsb3dzQ2FjaGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCBjYWNoZWREYXRhID0gYXdhaXQgdGhpcy5yZWFkV29ya2Zsb3dzQ2FjaGUoKTtcbiAgICAgIGlmICghY2FjaGVkRGF0YSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCB7IHdvcmtmbG93RmlsZXMsIHN0ZXBGaWxlcywgc2VyZGVGaWxlcyB9ID1cbiAgICAgICAgYXdhaXQgdGhpcy5yZWNvbmNpbGVEaXNjb3ZlcmVkRW50cmllcyh7XG4gICAgICAgICAgd29ya2Zsb3dDYW5kaWRhdGVzOiBjYWNoZWREYXRhLndvcmtmbG93RmlsZXMsXG4gICAgICAgICAgc3RlcENhbmRpZGF0ZXM6IGNhY2hlZERhdGEuc3RlcEZpbGVzLFxuICAgICAgICAgIHNlcmRlQ2FuZGlkYXRlczogdGhpcy5kaXNjb3ZlcmVkU2VyZGVGaWxlcyxcbiAgICAgICAgICB2YWxpZGF0ZVBhdHRlcm5zOiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgdGhpcy5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlcy5jbGVhcigpO1xuICAgICAgdGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLmNsZWFyKCk7XG4gICAgICB0aGlzLmRpc2NvdmVyZWRTZXJkZUZpbGVzLmNsZWFyKCk7XG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHdvcmtmbG93RmlsZXMpIHtcbiAgICAgICAgdGhpcy5kaXNjb3ZlcmVkV29ya2Zsb3dGaWxlcy5hZGQoZmlsZVBhdGgpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBmaWxlUGF0aCBvZiBzdGVwRmlsZXMpIHtcbiAgICAgICAgdGhpcy5kaXNjb3ZlcmVkU3RlcEZpbGVzLmFkZChmaWxlUGF0aCk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHNlcmRlRmlsZXMpIHtcbiAgICAgICAgdGhpcy5kaXNjb3ZlcmVkU2VyZGVGaWxlcy5hZGQoZmlsZVBhdGgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgd3JpdGVXb3JrZmxvd3NDYWNoZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGNvbnN0IGNhY2hlRmlsZVBhdGggPSB0aGlzLmdldFdvcmtmbG93c0NhY2hlRmlsZVBhdGgoKTtcbiAgICAgIGNvbnN0IGNhY2hlRGlyID0gam9pbih0aGlzLmNvbmZpZy53b3JraW5nRGlyLCB0aGlzLmdldERpc3REaXIoKSwgJ2NhY2hlJyk7XG4gICAgICBhd2FpdCBta2RpcihjYWNoZURpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgICAgIGNvbnN0IGNhY2hlRGF0YSA9IHtcbiAgICAgICAgd29ya2Zsb3dGaWxlczogQXJyYXkuZnJvbSh0aGlzLmRpc2NvdmVyZWRXb3JrZmxvd0ZpbGVzKS5zb3J0KCksXG4gICAgICAgIHN0ZXBGaWxlczogQXJyYXkuZnJvbSh0aGlzLmRpc2NvdmVyZWRTdGVwRmlsZXMpLnNvcnQoKSxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdyaXRlRmlsZShjYWNoZUZpbGVQYXRoLCBKU09OLnN0cmluZ2lmeShjYWNoZURhdGEsIG51bGwsIDIpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHdyaXRlU3R1YkZpbGVzKG91dHB1dERpcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAvLyBUdXJib3BhY2sgY3VycmVudGx5IGhhcyBhIHdvcmtlci1jb25jdXJyZW5jeSBsaW1pdGF0aW9uIGZvciBwZW5kaW5nXG4gICAgICAvLyB2aXJ0dWFsIGVudHJpZXMuIFdhcm4gaWYgcGFyYWxsZWxpc20gaXMgdG9vIGxvdyB0byByZWxpYWJseSBkaXNjb3Zlci5cbiAgICAgIGNvbnN0IHBhcmFsbGVsaXNtQ291bnQgPSBvcy5hdmFpbGFibGVQYXJhbGxlbGlzbSgpO1xuICAgICAgaWYgKHByb2Nlc3MuZW52LlRVUkJPUEFDSyAmJiBwYXJhbGxlbGlzbUNvdW50IDwgNCkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYEF2YWlsYWJsZSBwYXJhbGxlbGlzbSBvZiAke3BhcmFsbGVsaXNtQ291bnR9IGlzIGxlc3MgdGhhbiBuZWVkZWQgNC4gVGhpcyBjYW4gY2F1c2Ugd29ya2Zsb3dzL3N0ZXBzIHRvIGZhaWwgdG8gZGlzY292ZXIgcHJvcGVybHkgaW4gdHVyYm9wYWNrYFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByb3V0ZVN0dWJDb250ZW50ID0gW1xuICAgICAgICBgLy8gJHtST1VURV9TVFVCX0ZJTEVfTUFSS0VSfWAsXG4gICAgICAgICdleHBvcnQgY29uc3QgX193b3JrZmxvd1JvdXRlU3R1YiA9IHRydWU7JyxcbiAgICAgIF0uam9pbignXFxuJyk7XG4gICAgICBjb25zdCB3b3JrZmxvd0dlbmVyYXRlZERpciA9IGpvaW4ob3V0cHV0RGlyLCAnLndlbGwta25vd24vd29ya2Zsb3cvdjEnKTtcblxuICAgICAgYXdhaXQgbWtkaXIoam9pbih3b3JrZmxvd0dlbmVyYXRlZERpciwgJ2Zsb3cnKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICBhd2FpdCBta2Rpcihqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnd2ViaG9vay9bdG9rZW5dJyksIHtcbiAgICAgICAgcmVjdXJzaXZlOiB0cnVlLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHRoaXMud3JpdGVGaWxlSWZDaGFuZ2VkKFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnLmdpdGlnbm9yZScpLFxuICAgICAgICAnKidcbiAgICAgICk7XG5cbiAgICAgIC8vIFYyOiBPbmx5IGZsb3cgKyB3ZWJob29rIHN0dWJzIG5lZWRlZCAobm8gc2VwYXJhdGUgc3RlcCByb3V0ZSkuXG4gICAgICAvLyBTdHVicyBhcmUgcmVwbGFjZWQgYnkgZ2VuZXJhdGVkIG91dHB1dCBvbmNlIGRpc2NvdmVyeSBmaW5pc2hlcy5cbiAgICAgIGF3YWl0IHRoaXMud3JpdGVGaWxlSWZDaGFuZ2VkKFxuICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnZmxvdy9yb3V0ZS5qcycpLFxuICAgICAgICByb3V0ZVN0dWJDb250ZW50XG4gICAgICApO1xuICAgICAgYXdhaXQgdGhpcy53cml0ZUZpbGVJZkNoYW5nZWQoXG4gICAgICAgIGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICd3ZWJob29rL1t0b2tlbl0vcm91dGUuanMnKSxcbiAgICAgICAgcm91dGVTdHViQ29udGVudFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgYXN5bmMgZ2V0SW5wdXRGaWxlcygpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICAvLyBSZWFkIE5leHQuanMncyBhcHAtcGF0aHMtbWFuaWZlc3QuanNvbiBmcm9tIGEgcHJldmlvdXMgYnVpbGQgdG9cbiAgICAgIC8vIGRldGVybWluZSB3aGljaCBmaWxlcyBhcmUgYWN0dWFsIHJvdXRlIGVudHJ5cG9pbnRzLiBUaGlzIGF2b2lkc1xuICAgICAgLy8gcHJlZGljdGluZyBOZXh0LmpzIGNvbnZlbnRpb25zIHdpdGggcmVnZXhlcyBhbmQgaW5zdGVhZCByZWFkc1xuICAgICAgLy8gZnJvbSBOZXh0LmpzJ3Mgb3duIG91dHB1dC5cbiAgICAgIGNvbnN0IG5leHREaXIgPSBqb2luKHRoaXMuY29uZmlnLndvcmtpbmdEaXIsICcubmV4dCcpO1xuICAgICAgY29uc3QgbWFuaWZlc3RQYXRoID0gam9pbihuZXh0RGlyLCAnYXBwLXBhdGhzLW1hbmlmZXN0Lmpzb24nKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG1hbmlmZXN0Q29udGVudCA9IHJlYWRGaWxlU3luYyhtYW5pZmVzdFBhdGgsICd1dGYtOCcpO1xuICAgICAgICBjb25zdCBtYW5pZmVzdCA9IEpTT04ucGFyc2UobWFuaWZlc3RDb250ZW50KSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAgICAgICAvLyBUaGUgbWFuaWZlc3QgbWFwcyByb3V0ZSBwYXRocyB0byB0aGVpciBzb3VyY2UgZmlsZXMuXG4gICAgICAgIC8vIEV4dHJhY3QgdGhlIHNvdXJjZSBmaWxlIHBhdGhzIGFuZCByZXNvbHZlIHRoZW0uXG4gICAgICAgIGNvbnN0IG1hbmlmZXN0RmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2VQYXRoIG9mIE9iamVjdC52YWx1ZXMobWFuaWZlc3QpKSB7XG4gICAgICAgICAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlKG5leHREaXIsICdzZXJ2ZXInLCBzb3VyY2VQYXRoKTtcbiAgICAgICAgICAvLyBUaGUgbWFuaWZlc3QgcG9pbnRzIHRvIGJ1aWx0IG91dHB1dDsgZmluZCB0aGUgc291cmNlIGZpbGVcbiAgICAgICAgICAvLyBieSBtYXRjaGluZyBhZ2FpbnN0IHRoZSBiYXNlIGJ1aWxkZXIncyBmdWxsIGZpbGUgbGlzdC5cbiAgICAgICAgICBtYW5pZmVzdEZpbGVzLmFkZChyZXNvbHZlZCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVc2UgdGhlIG1hbmlmZXN0IHJvdXRlIHBhdGhzIHRvIGZpbHRlciB0aGUgaW5wdXQgZmlsZXMuXG4gICAgICAgIC8vIEEgZmlsZSBpcyBpbmNsdWRlZCBpZiBpdCBtYXRjaGVzIGEga25vd24gcm91dGUgc2VnbWVudCBmcm9tXG4gICAgICAgIC8vIHRoZSBtYW5pZmVzdCAoZS5nLiwgYXBwL2FwaS9yb3V0ZSBjb250YWlucyAnYXBwL2FwaS9yb3V0ZScpLlxuICAgICAgICBjb25zdCBpbnB1dEZpbGVzID0gYXdhaXQgc3VwZXIuZ2V0SW5wdXRGaWxlcygpO1xuICAgICAgICBjb25zdCByb3V0ZVNlZ21lbnRzID0gT2JqZWN0LmtleXMobWFuaWZlc3QpLm1hcCgocm91dGUpID0+XG4gICAgICAgICAgcm91dGUucmVwbGFjZSgvXlxcLy8sICcnKS5yZXBsYWNlKC9cXC9yb3V0ZSQvLCAnJylcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGlucHV0RmlsZXMuZmlsdGVyKChpdGVtKSA9PlxuICAgICAgICAgIHJvdXRlU2VnbWVudHMuc29tZSgoc2VnbWVudCkgPT4gaXRlbS5pbmNsdWRlcyhzZWdtZW50KSlcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBObyBtYW5pZmVzdCBmcm9tIGEgcHJldmlvdXMgYnVpbGQg4oCUIGZhbGwgYmFjayB0byB0aGUgYmFzZVxuICAgICAgICAvLyBidWlsZGVyJ3MgZnVsbCBmaWxlIHNjYW4uIFRoaXMgaXMgc2FmZSBidXQgc2xvd2VyOyBzdWJzZXF1ZW50XG4gICAgICAgIC8vIGJ1aWxkcyB3aWxsIHVzZSB0aGUgbWFuaWZlc3QuXG4gICAgICAgIHJldHVybiBzdXBlci5nZXRJbnB1dEZpbGVzKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyB3cml0ZUZ1bmN0aW9uc0NvbmZpZyhvdXRwdXREaXI6IHN0cmluZykge1xuICAgICAgLy8gd2UgZG9uJ3QgcnVuIHRoaXMgaW4gZGV2ZWxvcG1lbnQgbW9kZSBhcyBpdCdzIG5vdCBuZWVkZWRcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ2RldmVsb3BtZW50Jykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyBWMjogU2luZ2xlIGNvbWJpbmVkIHRyaWdnZXIgaGFuZGxlcyBib3RoIHdvcmtmbG93IGFuZCBzdGVwIGV4ZWN1dGlvblxuICAgICAgY29uc3QgZ2VuZXJhdGVkQ29uZmlnID0ge1xuICAgICAgICB2ZXJzaW9uOiAnMCcsXG4gICAgICAgIHdvcmtmbG93czoge1xuICAgICAgICAgIG1heER1cmF0aW9uOiAnbWF4JyxcbiAgICAgICAgICBleHBlcmltZW50YWxUcmlnZ2VyczogW1dPUktGTE9XX1FVRVVFX1RSSUdHRVJdLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgdGhpcy53cml0ZUZpbGVJZkNoYW5nZWQoXG4gICAgICAgIGpvaW4ob3V0cHV0RGlyLCAnLndlbGwta25vd24vd29ya2Zsb3cvdjEvY29uZmlnLmpzb24nKSxcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoZ2VuZXJhdGVkQ29uZmlnLCBudWxsLCAyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHdyaXRlRmlsZUlmQ2hhbmdlZChcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmcsXG4gICAgICBjb250ZW50czogc3RyaW5nIHwgQnVmZmVyXG4gICAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICBjb25zdCBuZXh0QnVmZmVyID0gQnVmZmVyLmlzQnVmZmVyKGNvbnRlbnRzKVxuICAgICAgICA/IGNvbnRlbnRzXG4gICAgICAgIDogQnVmZmVyLmZyb20oY29udGVudHMpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBjdXJyZW50QnVmZmVyID0gYXdhaXQgcmVhZEZpbGUoZmlsZVBhdGgpO1xuICAgICAgICBpZiAoY3VycmVudEJ1ZmZlci5lcXVhbHMobmV4dEJ1ZmZlcikpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBGaWxlIGRvZXMgbm90IGV4aXN0IHlldCBvciBjYW5ub3QgYmUgcmVhZDsgd3JpdGUgYSBmcmVzaCBjb3B5LlxuICAgICAgfVxuXG4gICAgICBhd2FpdCBta2RpcihkaXJuYW1lKGZpbGVQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICBhd2FpdCB3cml0ZUZpbGUoZmlsZVBhdGgsIG5leHRCdWZmZXIpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBjb3B5RmlsZUlmQ2hhbmdlZChcbiAgICAgIHNvdXJjZVBhdGg6IHN0cmluZyxcbiAgICAgIGRlc3RpbmF0aW9uUGF0aDogc3RyaW5nXG4gICAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICBjb25zdCBzb3VyY2VDb250ZW50cyA9IGF3YWl0IHJlYWRGaWxlKHNvdXJjZVBhdGgpO1xuICAgICAgcmV0dXJuIHRoaXMud3JpdGVGaWxlSWZDaGFuZ2VkKGRlc3RpbmF0aW9uUGF0aCwgc291cmNlQ29udGVudHMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgc29ydEpzb25WYWx1ZSh2YWx1ZTogdW5rbm93bik6IHVua25vd24ge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZS5tYXAoKGl0ZW0pID0+IHRoaXMuc29ydEpzb25WYWx1ZShpdGVtKSk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBjb25zdCBzb3J0ZWRFbnRyaWVzID0gT2JqZWN0LmVudHJpZXModmFsdWUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pXG4gICAgICAgICAgLnNvcnQoKFthXSwgW2JdKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXG4gICAgICAgICAgLm1hcCgoW2tleSwgZW50cnlWYWx1ZV0pID0+IFtrZXksIHRoaXMuc29ydEpzb25WYWx1ZShlbnRyeVZhbHVlKV0pO1xuICAgICAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKHNvcnRlZEVudHJpZXMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmV3cml0ZUpzb25GaWxlV2l0aFN0YWJsZUtleU9yZGVyKFxuICAgICAgZmlsZVBhdGg6IHN0cmluZ1xuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY29udGVudHMgPSBhd2FpdCByZWFkRmlsZShmaWxlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoY29udGVudHMpIGFzIHVua25vd247XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSB0aGlzLnNvcnRKc29uVmFsdWUocGFyc2VkKTtcbiAgICAgICAgYXdhaXQgdGhpcy53cml0ZUZpbGVJZkNoYW5nZWQoXG4gICAgICAgICAgZmlsZVBhdGgsXG4gICAgICAgICAgYCR7SlNPTi5zdHJpbmdpZnkobm9ybWFsaXplZCwgbnVsbCwgMil9XFxuYFxuICAgICAgICApO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIE1hbmlmZXN0IG1heSBub3QgZXhpc3QgKGUuZy4gbWFuaWZlc3QgZ2VuZXJhdGlvbiBmYWlsZWQpOyBpZ25vcmUuXG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBleHRyYWN0UmVsYXRpdmVJbXBvcnRTcGVjaWZpZXJzKHNvdXJjZTogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgICAgcmV0dXJuIHRoaXMuZXh0cmFjdEltcG9ydFNwZWNpZmllcnMoc291cmNlKS5maWx0ZXIoKHNwZWNpZmllcikgPT5cbiAgICAgICAgc3BlY2lmaWVyLnN0YXJ0c1dpdGgoJy4nKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGV4dHJhY3RJbXBvcnRTcGVjaWZpZXJzKHNvdXJjZTogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgICAgY29uc3QgcmVsYXRpdmVTcGVjaWZpZXJzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgICBjb25zdCBpbXBvcnRQYXR0ZXJucyA9IFtcbiAgICAgICAgL2Zyb21cXHMrWydcIl0oW14nXCJdKylbJ1wiXS9nLFxuICAgICAgICAvaW1wb3J0XFxzK1snXCJdKFteJ1wiXSspWydcIl0vZyxcbiAgICAgICAgL2ltcG9ydFxcKFxccypbJ1wiXShbXidcIl0rKVsnXCJdXFxzKlxcKS9nLFxuICAgICAgICAvcmVxdWlyZVxcKFxccypbJ1wiXShbXidcIl0rKVsnXCJdXFxzKlxcKS9nLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBpbXBvcnRQYXR0ZXJuIG9mIGltcG9ydFBhdHRlcm5zKSB7XG4gICAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2Ygc291cmNlLm1hdGNoQWxsKGltcG9ydFBhdHRlcm4pKSB7XG4gICAgICAgICAgY29uc3Qgc3BlY2lmaWVyID0gbWF0Y2hbMV07XG4gICAgICAgICAgaWYgKHNwZWNpZmllcikge1xuICAgICAgICAgICAgcmVsYXRpdmVTcGVjaWZpZXJzLmFkZChzcGVjaWZpZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gQXJyYXkuZnJvbShyZWxhdGl2ZVNwZWNpZmllcnMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZ2V0UmVsYXRpdmVGaWxlbmFtZUZvclN3YyhmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgIGNvbnN0IHdvcmtpbmdEaXIgPSB0aGlzLmNvbmZpZy53b3JraW5nRGlyO1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFdvcmtpbmdEaXIgPSB3b3JraW5nRGlyXG4gICAgICAgIC5yZXBsYWNlKC9cXFxcL2csICcvJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyQvLCAnJyk7XG4gICAgICBjb25zdCBub3JtYWxpemVkRmlsZXBhdGggPSBmaWxlUGF0aC5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG5cbiAgICAgIC8vIFdpbmRvd3MgZml4OiBVc2UgY2FzZS1pbnNlbnNpdGl2ZSBjb21wYXJpc29uIHRvIHdvcmsgYXJvdW5kIGRyaXZlIGxldHRlciBjYXNpbmcgaXNzdWVzLlxuICAgICAgY29uc3QgbG93ZXJXZCA9IG5vcm1hbGl6ZWRXb3JraW5nRGlyLnRvTG93ZXJDYXNlKCk7XG4gICAgICBjb25zdCBsb3dlclBhdGggPSBub3JtYWxpemVkRmlsZXBhdGgudG9Mb3dlckNhc2UoKTtcblxuICAgICAgbGV0IHJlbGF0aXZlRmlsZW5hbWU6IHN0cmluZztcbiAgICAgIGlmIChsb3dlclBhdGguc3RhcnRzV2l0aChgJHtsb3dlcldkfS9gKSkge1xuICAgICAgICByZWxhdGl2ZUZpbGVuYW1lID0gbm9ybWFsaXplZEZpbGVwYXRoLnN1YnN0cmluZyhcbiAgICAgICAgICBub3JtYWxpemVkV29ya2luZ0Rpci5sZW5ndGggKyAxXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKGxvd2VyUGF0aCA9PT0gbG93ZXJXZCkge1xuICAgICAgICByZWxhdGl2ZUZpbGVuYW1lID0gJy4nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVsYXRpdmVGaWxlbmFtZSA9IHJlbGF0aXZlKHdvcmtpbmdEaXIsIGZpbGVQYXRoKS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gICAgICAgIGlmIChyZWxhdGl2ZUZpbGVuYW1lLnN0YXJ0c1dpdGgoJy4uLycpKSB7XG4gICAgICAgICAgY29uc3QgYWxpYXNlZFJlbGF0aXZlUGF0aCA9IGF3YWl0IHJlc29sdmVXb3JrZmxvd0FsaWFzUmVsYXRpdmVQYXRoKFxuICAgICAgICAgICAgZmlsZVBhdGgsXG4gICAgICAgICAgICB3b3JraW5nRGlyXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoYWxpYXNlZFJlbGF0aXZlUGF0aCkge1xuICAgICAgICAgICAgcmVsYXRpdmVGaWxlbmFtZSA9IGFsaWFzZWRSZWxhdGl2ZVBhdGg7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlbGF0aXZlRmlsZW5hbWUgPSByZWxhdGl2ZUZpbGVuYW1lXG4gICAgICAgICAgICAgIC5zcGxpdCgnLycpXG4gICAgICAgICAgICAgIC5maWx0ZXIoKHBhcnQpID0+IHBhcnQgIT09ICcuLicpXG4gICAgICAgICAgICAgIC5qb2luKCcvJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChyZWxhdGl2ZUZpbGVuYW1lLmluY2x1ZGVzKCc6JykgfHwgcmVsYXRpdmVGaWxlbmFtZS5zdGFydHNXaXRoKCcvJykpIHtcbiAgICAgICAgcmVsYXRpdmVGaWxlbmFtZSA9IGJhc2VuYW1lKG5vcm1hbGl6ZWRGaWxlcGF0aCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZWxhdGl2ZUZpbGVuYW1lO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVzb2x2ZUltcG9ydFRhcmdldFdpdGhFeHRlbnNpb25GYWxsYmFja3MoXG4gICAgICB0YXJnZXRQYXRoOiBzdHJpbmdcbiAgICApOiBzdHJpbmcge1xuICAgICAgaWYgKGV4aXN0c1N5bmModGFyZ2V0UGF0aCkpIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldFBhdGg7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4dGVuc2lvbk1hdGNoID0gdGFyZ2V0UGF0aC5tYXRjaCgvKFxcLlteLi9cXFxcXSspJC8pO1xuICAgICAgY29uc3QgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uTWF0Y2g/LlsxXT8udG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmICghZXh0ZW5zaW9uKSB7XG4gICAgICAgIHJldHVybiB0YXJnZXRQYXRoO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBleHRlbnNpb25GYWxsYmFja3MgPVxuICAgICAgICBleHRlbnNpb24gPT09ICcuanMnXG4gICAgICAgICAgPyBbJy50cycsICcudHN4JywgJy5tdHMnLCAnLmN0cyddXG4gICAgICAgICAgOiBleHRlbnNpb24gPT09ICcubWpzJ1xuICAgICAgICAgICAgPyBbJy5tdHMnXVxuICAgICAgICAgICAgOiBleHRlbnNpb24gPT09ICcuY2pzJ1xuICAgICAgICAgICAgICA/IFsnLmN0cyddXG4gICAgICAgICAgICAgIDogZXh0ZW5zaW9uID09PSAnLmpzeCdcbiAgICAgICAgICAgICAgICA/IFsnLnRzeCddXG4gICAgICAgICAgICAgICAgOiBbXTtcblxuICAgICAgaWYgKGV4dGVuc2lvbkZhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldFBhdGg7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRhcmdldFdpdGhvdXRFeHRlbnNpb24gPSB0YXJnZXRQYXRoLnNsaWNlKDAsIC1leHRlbnNpb24ubGVuZ3RoKTtcbiAgICAgIGZvciAoY29uc3QgZmFsbGJhY2tFeHRlbnNpb24gb2YgZXh0ZW5zaW9uRmFsbGJhY2tzKSB7XG4gICAgICAgIGNvbnN0IGZhbGxiYWNrUGF0aCA9IGAke3RhcmdldFdpdGhvdXRFeHRlbnNpb259JHtmYWxsYmFja0V4dGVuc2lvbn1gO1xuICAgICAgICBpZiAoZXhpc3RzU3luYyhmYWxsYmFja1BhdGgpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbGxiYWNrUGF0aDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGFyZ2V0UGF0aDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNob3VsZFNraXBUcmFuc2l0aXZlU3RlcEZpbGUoZmlsZVBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSBmaWxlUGF0aC5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gICAgICBjb25zdCBpc1NvdXJjZUJhY2tlZFBhY2thZ2VQYXRoID1cbiAgICAgICAgdGhpcy5zaG91bGRQcmVmZXJTb3VyY2VCYWNrZWRQYWNrYWdlUGF0aChmaWxlUGF0aCk7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBub3JtYWxpemVkUGF0aC5pbmNsdWRlcygnLy53ZWxsLWtub3duL3dvcmtmbG93LycpIHx8XG4gICAgICAgIG5vcm1hbGl6ZWRQYXRoLmluY2x1ZGVzKCcvLm5leHQvJykgfHxcbiAgICAgICAgKCFpc1NvdXJjZUJhY2tlZFBhY2thZ2VQYXRoICYmXG4gICAgICAgICAgKG5vcm1hbGl6ZWRQYXRoLmluY2x1ZGVzKCcvbm9kZV9tb2R1bGVzLycpIHx8XG4gICAgICAgICAgICBub3JtYWxpemVkUGF0aC5pbmNsdWRlcygnLy5wbnBtLycpKSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZXNvbHZlVHJhbnNpdGl2ZVN0ZXBJbXBvcnRUYXJnZXRQYXRoKFxuICAgICAgc291cmNlRmlsZVBhdGg6IHN0cmluZyxcbiAgICAgIHNwZWNpZmllcjogc3RyaW5nXG4gICAgKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgICBjb25zdCBzcGVjaWZpZXJNYXRjaCA9IHNwZWNpZmllci5tYXRjaCgvXihbXj8jXSspKC4qKSQvKTtcbiAgICAgIGNvbnN0IGltcG9ydFBhdGggPSBzcGVjaWZpZXJNYXRjaD8uWzFdID8/IHNwZWNpZmllcjtcblxuICAgICAgaWYgKCFpbXBvcnRQYXRoLnN0YXJ0c1dpdGgoJy4nKSkge1xuICAgICAgICBpZiAoaW1wb3J0UGF0aCAhPT0gJ3dvcmtmbG93JyAmJiAhaW1wb3J0UGF0aC5zdGFydHNXaXRoKCdAd29ya2Zsb3cvJykpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzb2x2ZWRQYXRoID1cbiAgICAgICAgICAgIGNyZWF0ZVJlcXVpcmUoc291cmNlRmlsZVBhdGgpLnJlc29sdmUoaW1wb3J0UGF0aCk7XG4gICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFJlc29sdmVkUGF0aCA9XG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChyZXNvbHZlZFBhdGgpO1xuICAgICAgICAgIGlmICh0aGlzLnNob3VsZFNraXBUcmFuc2l0aXZlU3RlcEZpbGUobm9ybWFsaXplZFJlc29sdmVkUGF0aCkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGZpbGVTdGF0cyA9IGF3YWl0IHN0YXQobm9ybWFsaXplZFJlc29sdmVkUGF0aCk7XG4gICAgICAgICAgcmV0dXJuIGZpbGVTdGF0cy5pc0ZpbGUoKSA/IG5vcm1hbGl6ZWRSZXNvbHZlZFBhdGggOiBudWxsO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBhYnNvbHV0ZVRhcmdldFBhdGggPSByZXNvbHZlKGRpcm5hbWUoc291cmNlRmlsZVBhdGgpLCBpbXBvcnRQYXRoKTtcblxuICAgICAgY29uc3QgY2FuZGlkYXRlUGF0aHMgPSBuZXcgU2V0PHN0cmluZz4oW1xuICAgICAgICB0aGlzLnJlc29sdmVJbXBvcnRUYXJnZXRXaXRoRXh0ZW5zaW9uRmFsbGJhY2tzKGFic29sdXRlVGFyZ2V0UGF0aCksXG4gICAgICBdKTtcblxuICAgICAgaWYgKCFleHRuYW1lKGFic29sdXRlVGFyZ2V0UGF0aCkpIHtcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uQ2FuZGlkYXRlcyA9IFtcbiAgICAgICAgICAnLnRzJyxcbiAgICAgICAgICAnLnRzeCcsXG4gICAgICAgICAgJy5tdHMnLFxuICAgICAgICAgICcuY3RzJyxcbiAgICAgICAgICAnLmpzJyxcbiAgICAgICAgICAnLmpzeCcsXG4gICAgICAgICAgJy5tanMnLFxuICAgICAgICAgICcuY2pzJyxcbiAgICAgICAgXTtcbiAgICAgICAgZm9yIChjb25zdCBleHRlbnNpb25DYW5kaWRhdGUgb2YgZXh0ZW5zaW9uQ2FuZGlkYXRlcykge1xuICAgICAgICAgIGNhbmRpZGF0ZVBhdGhzLmFkZChgJHthYnNvbHV0ZVRhcmdldFBhdGh9JHtleHRlbnNpb25DYW5kaWRhdGV9YCk7XG4gICAgICAgICAgY2FuZGlkYXRlUGF0aHMuYWRkKFxuICAgICAgICAgICAgam9pbihhYnNvbHV0ZVRhcmdldFBhdGgsIGBpbmRleCR7ZXh0ZW5zaW9uQ2FuZGlkYXRlfWApXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGNhbmRpZGF0ZVBhdGggb2YgY2FuZGlkYXRlUGF0aHMpIHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZWRQYXRoID1cbiAgICAgICAgICB0aGlzLnJlc29sdmVJbXBvcnRUYXJnZXRXaXRoRXh0ZW5zaW9uRmFsbGJhY2tzKGNhbmRpZGF0ZVBhdGgpO1xuICAgICAgICBjb25zdCBub3JtYWxpemVkUmVzb2x2ZWRQYXRoID1cbiAgICAgICAgICB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChyZXNvbHZlZFBhdGgpO1xuXG4gICAgICAgIGlmICh0aGlzLnNob3VsZFNraXBUcmFuc2l0aXZlU3RlcEZpbGUobm9ybWFsaXplZFJlc29sdmVkUGF0aCkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZmlsZVN0YXRzID0gYXdhaXQgc3RhdChub3JtYWxpemVkUmVzb2x2ZWRQYXRoKTtcbiAgICAgICAgICBpZiAoZmlsZVN0YXRzLmlzRmlsZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplZFJlc29sdmVkUGF0aDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIC8vIFRyeSB0aGUgbmV4dCBjYW5kaWRhdGUgcGF0aC5cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNvbGxlY3RUcmFuc2l0aXZlU3RlcEZpbGVzKHtcbiAgICAgIGVudHJ5RmlsZXMsXG4gICAgICBzdGVwRmlsZXMsXG4gICAgfToge1xuICAgICAgZW50cnlGaWxlczogc3RyaW5nW107XG4gICAgICBzdGVwRmlsZXM6IHN0cmluZ1tdO1xuICAgIH0pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICBjb25zdCBub3JtYWxpemVkRW50cnlGaWxlcyA9IEFycmF5LmZyb20oXG4gICAgICAgIG5ldyBTZXQoXG4gICAgICAgICAgZW50cnlGaWxlcy5tYXAoKGVudHJ5RmlsZSkgPT5cbiAgICAgICAgICAgIHRoaXMubm9ybWFsaXplRGlzY292ZXJlZEZpbGVQYXRoKGVudHJ5RmlsZSlcbiAgICAgICAgICApXG4gICAgICAgIClcbiAgICAgICkuc29ydCgpO1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFN0ZXBTZWVkRmlsZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFxuICAgICAgICAgIHN0ZXBGaWxlcy5tYXAoKHN0ZXBGaWxlKSA9PlxuICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVEaXNjb3ZlcmVkRmlsZVBhdGgoc3RlcEZpbGUpXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICApLnNvcnQoKTtcbiAgICAgIGNvbnN0IGRpc2NvdmVyZWRTdGVwRmlsZXMgPSBuZXcgU2V0PHN0cmluZz4obm9ybWFsaXplZFN0ZXBTZWVkRmlsZXMpO1xuICAgICAgY29uc3QgcXVldWVkRmlsZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFsuLi5ub3JtYWxpemVkRW50cnlGaWxlcywgLi4ubm9ybWFsaXplZFN0ZXBTZWVkRmlsZXNdKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IHZpc2l0ZWRGaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nIHwgbnVsbD4oKTtcbiAgICAgIGNvbnN0IHBhdHRlcm5DYWNoZSA9IG5ldyBNYXA8XG4gICAgICAgIHN0cmluZyxcbiAgICAgICAgUmV0dXJuVHlwZTx0eXBlb2YgZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucz4gfCBudWxsXG4gICAgICA+KCk7XG5cbiAgICAgIGNvbnN0IGdldFNvdXJjZSA9IGFzeW5jIChmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiA9PiB7XG4gICAgICAgIGlmIChzb3VyY2VDYWNoZS5oYXMoZmlsZVBhdGgpKSB7XG4gICAgICAgICAgcmV0dXJuIHNvdXJjZUNhY2hlLmdldChmaWxlUGF0aCkgPz8gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoLCAndXRmLTgnKTtcbiAgICAgICAgICBzb3VyY2VDYWNoZS5zZXQoZmlsZVBhdGgsIHNvdXJjZSk7XG4gICAgICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgc291cmNlQ2FjaGUuc2V0KGZpbGVQYXRoLCBudWxsKTtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3QgZ2V0UGF0dGVybnMgPSBhc3luYyAoXG4gICAgICAgIGZpbGVQYXRoOiBzdHJpbmdcbiAgICAgICk6IFByb21pc2U8UmV0dXJuVHlwZTx0eXBlb2YgZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucz4gfCBudWxsPiA9PiB7XG4gICAgICAgIGlmIChwYXR0ZXJuQ2FjaGUuaGFzKGZpbGVQYXRoKSkge1xuICAgICAgICAgIHJldHVybiBwYXR0ZXJuQ2FjaGUuZ2V0KGZpbGVQYXRoKSA/PyBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNvdXJjZSA9IGF3YWl0IGdldFNvdXJjZShmaWxlUGF0aCk7XG4gICAgICAgIGlmIChzb3VyY2UgPT09IG51bGwpIHtcbiAgICAgICAgICBwYXR0ZXJuQ2FjaGUuc2V0KGZpbGVQYXRoLCBudWxsKTtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXR0ZXJucyA9IGRldGVjdFdvcmtmbG93UGF0dGVybnMoc291cmNlKTtcbiAgICAgICAgcGF0dGVybkNhY2hlLnNldChmaWxlUGF0aCwgcGF0dGVybnMpO1xuICAgICAgICByZXR1cm4gcGF0dGVybnM7XG4gICAgICB9O1xuXG4gICAgICB3aGlsZSAocXVldWVkRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBjdXJyZW50RmlsZSA9IHF1ZXVlZEZpbGVzLnBvcCgpO1xuICAgICAgICBpZiAoIWN1cnJlbnRGaWxlIHx8IHZpc2l0ZWRGaWxlcy5oYXMoY3VycmVudEZpbGUpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmlzaXRlZEZpbGVzLmFkZChjdXJyZW50RmlsZSk7XG5cbiAgICAgICAgY29uc3QgY3VycmVudFNvdXJjZSA9IGF3YWl0IGdldFNvdXJjZShjdXJyZW50RmlsZSk7XG4gICAgICAgIGlmIChjdXJyZW50U291cmNlID09PSBudWxsKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbXBvcnRTcGVjaWZpZXJzID0gdGhpcy5leHRyYWN0SW1wb3J0U3BlY2lmaWVycyhjdXJyZW50U291cmNlKTtcbiAgICAgICAgZm9yIChjb25zdCBzcGVjaWZpZXIgb2YgaW1wb3J0U3BlY2lmaWVycykge1xuICAgICAgICAgIGNvbnN0IHJlc29sdmVkSW1wb3J0UGF0aCA9XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlc29sdmVUcmFuc2l0aXZlU3RlcEltcG9ydFRhcmdldFBhdGgoXG4gICAgICAgICAgICAgIGN1cnJlbnRGaWxlLFxuICAgICAgICAgICAgICBzcGVjaWZpZXJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKCFyZXNvbHZlZEltcG9ydFBhdGgpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghdmlzaXRlZEZpbGVzLmhhcyhyZXNvbHZlZEltcG9ydFBhdGgpKSB7XG4gICAgICAgICAgICBxdWV1ZWRGaWxlcy5wdXNoKHJlc29sdmVkSW1wb3J0UGF0aCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgaW1wb3J0UGF0dGVybnMgPSBhd2FpdCBnZXRQYXR0ZXJucyhyZXNvbHZlZEltcG9ydFBhdGgpO1xuICAgICAgICAgIGlmIChpbXBvcnRQYXR0ZXJucz8uaGFzVXNlU3RlcCkge1xuICAgICAgICAgICAgZGlzY292ZXJlZFN0ZXBGaWxlcy5hZGQocmVzb2x2ZWRJbXBvcnRQYXRoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEFycmF5LmZyb20oZGlzY292ZXJlZFN0ZXBGaWxlcykuc29ydCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgY29sbGVjdFRyYW5zaXRpdmVTZXJkZUZpbGVzKHtcbiAgICAgIGVudHJ5RmlsZXMsXG4gICAgICBzZXJkZUZpbGVzLFxuICAgIH06IHtcbiAgICAgIGVudHJ5RmlsZXM6IHN0cmluZ1tdO1xuICAgICAgc2VyZGVGaWxlczogc3RyaW5nW107XG4gICAgfSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRFbnRyeUZpbGVzID0gQXJyYXkuZnJvbShcbiAgICAgICAgbmV3IFNldChcbiAgICAgICAgICBlbnRyeUZpbGVzLm1hcCgoZW50cnlGaWxlKSA9PlxuICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVEaXNjb3ZlcmVkRmlsZVBhdGgoZW50cnlGaWxlKVxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgKS5zb3J0KCk7XG4gICAgICBjb25zdCBub3JtYWxpemVkU2VyZGVTZWVkRmlsZXMgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFxuICAgICAgICAgIHNlcmRlRmlsZXMubWFwKChzZXJkZUZpbGUpID0+XG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZURpc2NvdmVyZWRGaWxlUGF0aChzZXJkZUZpbGUpXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICApLnNvcnQoKTtcbiAgICAgIC8vIEludGVudGlvbmFsbHkgcmUtdmFsaWRhdGUgc2VyZGUgc2VlZHMgYWdhaW5zdCBzb3VyY2UgcGF0dGVybnMuXG4gICAgICAvLyBUaGlzIGtlZXBzIHByZXZpb3VzbHkgZGlzY292ZXJlZC9tYW51YWwgc2VlZCBlbnRyaWVzIGZyb20gc3RpY2tpbmcgd2hlblxuICAgICAgLy8gZmlsZXMgbm8gbG9uZ2VyIG1hdGNoIHNlcmRlIHBhdHRlcm5zLlxuICAgICAgY29uc3QgZGlzY292ZXJlZFNlcmRlRmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgIGNvbnN0IHF1ZXVlZEZpbGVzID0gQXJyYXkuZnJvbShcbiAgICAgICAgbmV3IFNldChbLi4ubm9ybWFsaXplZEVudHJ5RmlsZXMsIC4uLm5vcm1hbGl6ZWRTZXJkZVNlZWRGaWxlc10pXG4gICAgICApO1xuICAgICAgY29uc3QgdmlzaXRlZEZpbGVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgICBjb25zdCBzb3VyY2VDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmcgfCBudWxsPigpO1xuICAgICAgY29uc3QgcGF0dGVybkNhY2hlID0gbmV3IE1hcDxcbiAgICAgICAgc3RyaW5nLFxuICAgICAgICBSZXR1cm5UeXBlPHR5cGVvZiBkZXRlY3RXb3JrZmxvd1BhdHRlcm5zPiB8IG51bGxcbiAgICAgID4oKTtcblxuICAgICAgY29uc3QgZ2V0U291cmNlID0gYXN5bmMgKGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+ID0+IHtcbiAgICAgICAgaWYgKHNvdXJjZUNhY2hlLmhhcyhmaWxlUGF0aCkpIHtcbiAgICAgICAgICByZXR1cm4gc291cmNlQ2FjaGUuZ2V0KGZpbGVQYXRoKSA/PyBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qgc291cmNlID0gYXdhaXQgcmVhZEZpbGUoZmlsZVBhdGgsICd1dGYtOCcpO1xuICAgICAgICAgIHNvdXJjZUNhY2hlLnNldChmaWxlUGF0aCwgc291cmNlKTtcbiAgICAgICAgICByZXR1cm4gc291cmNlO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICBzb3VyY2VDYWNoZS5zZXQoZmlsZVBhdGgsIG51bGwpO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBnZXRQYXR0ZXJucyA9IGFzeW5jIChcbiAgICAgICAgZmlsZVBhdGg6IHN0cmluZ1xuICAgICAgKTogUHJvbWlzZTxSZXR1cm5UeXBlPHR5cGVvZiBkZXRlY3RXb3JrZmxvd1BhdHRlcm5zPiB8IG51bGw+ID0+IHtcbiAgICAgICAgaWYgKHBhdHRlcm5DYWNoZS5oYXMoZmlsZVBhdGgpKSB7XG4gICAgICAgICAgcmV0dXJuIHBhdHRlcm5DYWNoZS5nZXQoZmlsZVBhdGgpID8/IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc291cmNlID0gYXdhaXQgZ2V0U291cmNlKGZpbGVQYXRoKTtcbiAgICAgICAgaWYgKHNvdXJjZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHBhdHRlcm5DYWNoZS5zZXQoZmlsZVBhdGgsIG51bGwpO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhdHRlcm5zID0gZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucyhzb3VyY2UpO1xuICAgICAgICBwYXR0ZXJuQ2FjaGUuc2V0KGZpbGVQYXRoLCBwYXR0ZXJucyk7XG4gICAgICAgIHJldHVybiBwYXR0ZXJucztcbiAgICAgIH07XG5cbiAgICAgIGZvciAoY29uc3Qgc2VyZGVTZWVkRmlsZSBvZiBub3JtYWxpemVkU2VyZGVTZWVkRmlsZXMpIHtcbiAgICAgICAgY29uc3Qgc2VlZFBhdHRlcm5zID0gYXdhaXQgZ2V0UGF0dGVybnMoc2VyZGVTZWVkRmlsZSk7XG4gICAgICAgIGlmIChzZWVkUGF0dGVybnM/Lmhhc1NlcmRlKSB7XG4gICAgICAgICAgZGlzY292ZXJlZFNlcmRlRmlsZXMuYWRkKHNlcmRlU2VlZEZpbGUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHdoaWxlIChxdWV1ZWRGaWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRGaWxlID0gcXVldWVkRmlsZXMucG9wKCk7XG4gICAgICAgIGlmICghY3VycmVudEZpbGUgfHwgdmlzaXRlZEZpbGVzLmhhcyhjdXJyZW50RmlsZSkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB2aXNpdGVkRmlsZXMuYWRkKGN1cnJlbnRGaWxlKTtcblxuICAgICAgICBjb25zdCBjdXJyZW50U291cmNlID0gYXdhaXQgZ2V0U291cmNlKGN1cnJlbnRGaWxlKTtcbiAgICAgICAgaWYgKGN1cnJlbnRTb3VyY2UgPT09IG51bGwpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlbGF0aXZlSW1wb3J0U3BlY2lmaWVycyA9XG4gICAgICAgICAgdGhpcy5leHRyYWN0UmVsYXRpdmVJbXBvcnRTcGVjaWZpZXJzKGN1cnJlbnRTb3VyY2UpO1xuICAgICAgICBmb3IgKGNvbnN0IHNwZWNpZmllciBvZiByZWxhdGl2ZUltcG9ydFNwZWNpZmllcnMpIHtcbiAgICAgICAgICBjb25zdCByZXNvbHZlZEltcG9ydFBhdGggPVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZXNvbHZlVHJhbnNpdGl2ZVN0ZXBJbXBvcnRUYXJnZXRQYXRoKFxuICAgICAgICAgICAgICBjdXJyZW50RmlsZSxcbiAgICAgICAgICAgICAgc3BlY2lmaWVyXG4gICAgICAgICAgICApO1xuICAgICAgICAgIGlmICghcmVzb2x2ZWRJbXBvcnRQYXRoKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXZpc2l0ZWRGaWxlcy5oYXMocmVzb2x2ZWRJbXBvcnRQYXRoKSkge1xuICAgICAgICAgICAgcXVldWVkRmlsZXMucHVzaChyZXNvbHZlZEltcG9ydFBhdGgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGltcG9ydFBhdHRlcm5zID0gYXdhaXQgZ2V0UGF0dGVybnMocmVzb2x2ZWRJbXBvcnRQYXRoKTtcbiAgICAgICAgICBpZiAoaW1wb3J0UGF0dGVybnM/Lmhhc1NlcmRlKSB7XG4gICAgICAgICAgICBkaXNjb3ZlcmVkU2VyZGVGaWxlcy5hZGQocmVzb2x2ZWRJbXBvcnRQYXRoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQVNULWxldmVsIHZlcmlmaWNhdGlvbjogcnVuIFNXQyBkZXRlY3QgbW9kZSBvbiByZWdleC1tYXRjaGVkIGNhbmRpZGF0ZXNcbiAgICAgIC8vIHRvIGNvbmZpcm0gdGhleSBhY3R1YWxseSBkZWZpbmUgc2VyZGUgY2xhc3Nlcy4gVGhpcyBwcmV2ZW50cyBTREsgaW50ZXJuYWxcbiAgICAgIC8vIGZpbGVzICh3aGljaCBtYXRjaCBzZXJkZSByZWdleCBwYXR0ZXJucyBidXQgZGVmaW5lIG5vIGNsYXNzZXMpIGZyb20gYmVpbmdcbiAgICAgIC8vIGJ1bmRsZWQgaW50byB0aGUgd29ya2Zsb3cgc2FuZGJveC5cbiAgICAgIGNvbnN0IHByb2plY3RSb290ID0gdGhpcy5jb25maWcucHJvamVjdFJvb3QgfHwgdGhpcy5jb25maWcud29ya2luZ0RpcjtcbiAgICAgIGNvbnN0IHZlcmlmaWVkU2VyZGVGaWxlczogc3RyaW5nW10gPSBbXTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBBcnJheS5mcm9tKGRpc2NvdmVyZWRTZXJkZUZpbGVzKS5tYXAoYXN5bmMgKGZpbGVQYXRoKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc291cmNlID0gYXdhaXQgZ2V0U291cmNlKGZpbGVQYXRoKTtcbiAgICAgICAgICBpZiAoIXNvdXJjZSkgcmV0dXJuO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZWxhdGl2ZUZpbGVuYW1lID1cbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5nZXRSZWxhdGl2ZUZpbGVuYW1lRm9yU3djKGZpbGVQYXRoKTtcbiAgICAgICAgICAgIGNvbnN0IHsgd29ya2Zsb3dNYW5pZmVzdCB9ID0gYXdhaXQgYXBwbHlTd2NUcmFuc2Zvcm0oXG4gICAgICAgICAgICAgIHJlbGF0aXZlRmlsZW5hbWUsXG4gICAgICAgICAgICAgIHNvdXJjZSxcbiAgICAgICAgICAgICAgJ2RldGVjdCcsXG4gICAgICAgICAgICAgIGZpbGVQYXRoLFxuICAgICAgICAgICAgICBwcm9qZWN0Um9vdCxcbiAgICAgICAgICAgICAgdGhpcy5tb2R1bGVTcGVjaWZpZXJSb290XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgLy8gT25seSBpbmNsdWRlIGZpbGVzIHRoYXQgYWN0dWFsbHkgZGVmaW5lIHNlcmRlIGNsYXNzZXNcbiAgICAgICAgICAgIGNvbnN0IGhhc0NsYXNzZXMgPVxuICAgICAgICAgICAgICB3b3JrZmxvd01hbmlmZXN0LmNsYXNzZXMgJiZcbiAgICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyh3b3JrZmxvd01hbmlmZXN0LmNsYXNzZXMpLnNvbWUoXG4gICAgICAgICAgICAgICAgKGVudHJpZXMpID0+IE9iamVjdC5rZXlzKGVudHJpZXMpLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChoYXNDbGFzc2VzKSB7XG4gICAgICAgICAgICAgIHZlcmlmaWVkU2VyZGVGaWxlcy5wdXNoKGZpbGVQYXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIElmIGRldGVjdCBmYWlscywgaW5jbHVkZSB0aGUgZmlsZSB0byBiZSBzYWZlXG4gICAgICAgICAgICB2ZXJpZmllZFNlcmRlRmlsZXMucHVzaChmaWxlUGF0aCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIHZlcmlmaWVkU2VyZGVGaWxlcy5zb3J0KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBidWlsZFdlYmhvb2tSb3V0ZSh7XG4gICAgICB3b3JrZmxvd0dlbmVyYXRlZERpcixcbiAgICAgIHJvdXRlRmlsZU5hbWUgPSAncm91dGUuanMnLFxuICAgIH06IHtcbiAgICAgIHdvcmtmbG93R2VuZXJhdGVkRGlyOiBzdHJpbmc7XG4gICAgICByb3V0ZUZpbGVOYW1lPzogc3RyaW5nO1xuICAgIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGNvbnN0IHdlYmhvb2tSb3V0ZUZpbGUgPSBqb2luKFxuICAgICAgICB3b3JrZmxvd0dlbmVyYXRlZERpcixcbiAgICAgICAgYHdlYmhvb2svW3Rva2VuXS8ke3JvdXRlRmlsZU5hbWV9YFxuICAgICAgKTtcbiAgICAgIGF3YWl0IHRoaXMuY3JlYXRlV2ViaG9va0J1bmRsZSh7XG4gICAgICAgIG91dGZpbGU6IHdlYmhvb2tSb3V0ZUZpbGUsXG4gICAgICAgIGJ1bmRsZTogZmFsc2UsIC8vIE5leHQuanMgZG9lc24ndCBuZWVkIGJ1bmRsaW5nXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGZpbmRBcHBEaXJlY3RvcnkoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgIGNvbnN0IGFwcERpciA9IHJlc29sdmUodGhpcy5jb25maWcud29ya2luZ0RpciwgJ2FwcCcpO1xuICAgICAgY29uc3Qgc3JjQXBwRGlyID0gcmVzb2x2ZSh0aGlzLmNvbmZpZy53b3JraW5nRGlyLCAnc3JjL2FwcCcpO1xuICAgICAgY29uc3QgcGFnZXNEaXIgPSByZXNvbHZlKHRoaXMuY29uZmlnLndvcmtpbmdEaXIsICdwYWdlcycpO1xuICAgICAgY29uc3Qgc3JjUGFnZXNEaXIgPSByZXNvbHZlKHRoaXMuY29uZmlnLndvcmtpbmdEaXIsICdzcmMvcGFnZXMnKTtcblxuICAgICAgLy8gSGVscGVyIHRvIGNoZWNrIGlmIGEgcGF0aCBleGlzdHMgYW5kIGlzIGEgZGlyZWN0b3J5XG4gICAgICBjb25zdCBpc0RpcmVjdG9yeSA9IGFzeW5jIChwYXRoOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+ID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBhY2Nlc3MocGF0aCwgY29uc3RhbnRzLkZfT0spO1xuICAgICAgICAgIGNvbnN0IHN0YXRzID0gYXdhaXQgc3RhdChwYXRoKTtcbiAgICAgICAgICBpZiAoIXN0YXRzLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUGF0aCBleGlzdHMgYnV0IGlzIG5vdCBhIGRpcmVjdG9yeTogJHtwYXRofWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3IgJiYgZS5tZXNzYWdlLmluY2x1ZGVzKCdub3QgYSBkaXJlY3RvcnknKSkge1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICAvLyBDaGVjayBpZiBhcHAgZGlyZWN0b3J5IGV4aXN0c1xuICAgICAgaWYgKGF3YWl0IGlzRGlyZWN0b3J5KGFwcERpcikpIHtcbiAgICAgICAgcmV0dXJuIGFwcERpcjtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgaWYgc3JjL2FwcCBkaXJlY3RvcnkgZXhpc3RzXG4gICAgICBpZiAoYXdhaXQgaXNEaXJlY3Rvcnkoc3JjQXBwRGlyKSkge1xuICAgICAgICByZXR1cm4gc3JjQXBwRGlyO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiBubyBhcHAgZGlyZWN0b3J5IGV4aXN0cywgY2hlY2sgZm9yIHBhZ2VzIGRpcmVjdG9yeSBhbmQgY3JlYXRlIGFwcCBuZXh0IHRvIGl0XG4gICAgICBpZiAoYXdhaXQgaXNEaXJlY3RvcnkocGFnZXNEaXIpKSB7XG4gICAgICAgIC8vIENyZWF0ZSBhcHAgZGlyZWN0b3J5IG5leHQgdG8gcGFnZXMgZGlyZWN0b3J5XG4gICAgICAgIGF3YWl0IG1rZGlyKGFwcERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgIHJldHVybiBhcHBEaXI7XG4gICAgICB9XG5cbiAgICAgIGlmIChhd2FpdCBpc0RpcmVjdG9yeShzcmNQYWdlc0RpcikpIHtcbiAgICAgICAgLy8gQ3JlYXRlIHNyYy9hcHAgZGlyZWN0b3J5IG5leHQgdG8gc3JjL3BhZ2VzIGRpcmVjdG9yeVxuICAgICAgICBhd2FpdCBta2RpcihzcmNBcHBEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICByZXR1cm4gc3JjQXBwRGlyO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdDb3VsZCBub3QgZmluZCBOZXh0LmpzIGFwcCBvciBwYWdlcyBkaXJlY3RvcnkuIEV4cGVjdGVkIG9uZSBvZjogXCJhcHBcIiwgXCJzcmMvYXBwXCIsIFwicGFnZXNcIiwgb3IgXCJzcmMvcGFnZXNcIiB0byBleGlzdC4nXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIENhY2hlZE5leHRCdWlsZGVyRGVmZXJyZWQgPSBOZXh0RGVmZXJyZWRCdWlsZGVyO1xuICByZXR1cm4gTmV4dERlZmVycmVkQnVpbGRlcjtcbn1cbiJdfQ==
|