@workflow/cli 5.0.0-beta.3 → 5.0.0-beta.31
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/base.d.ts.map +1 -1
- package/dist/base.js +8 -2
- package/dist/commands/build.js +1 -1
- package/dist/commands/cancel.d.ts.map +1 -1
- package/dist/commands/cancel.js +56 -10
- package/dist/commands/dev.js +1 -1
- package/dist/commands/health.js +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/inspect.d.ts +3 -0
- package/dist/commands/inspect.d.ts.map +1 -1
- package/dist/commands/inspect.js +37 -7
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +8 -3
- package/dist/commands/transform.js +1 -1
- package/dist/commands/validate.js +1 -1
- package/dist/commands/web.d.ts +1 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +9 -3
- package/dist/lib/config/log.js +1 -1
- package/dist/lib/config/types.d.ts +6 -1
- package/dist/lib/config/types.d.ts.map +1 -1
- package/dist/lib/config/types.js +1 -1
- package/dist/lib/config/workflow-config.js +1 -1
- package/dist/lib/inspect/auth.js +1 -1
- package/dist/lib/inspect/env.d.ts +1 -1
- package/dist/lib/inspect/env.js +2 -2
- package/dist/lib/inspect/errors.d.ts +3 -0
- package/dist/lib/inspect/errors.d.ts.map +1 -0
- package/dist/lib/inspect/errors.js +27 -0
- package/dist/lib/inspect/flags.d.ts +8 -0
- package/dist/lib/inspect/flags.d.ts.map +1 -1
- package/dist/lib/inspect/flags.js +15 -1
- package/dist/lib/inspect/hydration.d.ts +22 -0
- package/dist/lib/inspect/hydration.d.ts.map +1 -1
- package/dist/lib/inspect/hydration.js +102 -47
- package/dist/lib/inspect/hydration.test.d.ts +2 -0
- package/dist/lib/inspect/hydration.test.d.ts.map +1 -0
- package/dist/lib/inspect/hydration.test.js +23 -0
- package/dist/lib/inspect/output.d.ts +2 -2
- package/dist/lib/inspect/output.d.ts.map +1 -1
- package/dist/lib/inspect/output.js +255 -131
- package/dist/lib/inspect/output.test.js +403 -3
- package/dist/lib/inspect/pagination.d.ts +10 -1
- package/dist/lib/inspect/pagination.d.ts.map +1 -1
- package/dist/lib/inspect/pagination.js +20 -4
- package/dist/lib/inspect/run.d.ts.map +1 -1
- package/dist/lib/inspect/run.js +32 -9
- package/dist/lib/inspect/setup.d.ts.map +1 -1
- package/dist/lib/inspect/setup.js +42 -6
- package/dist/lib/inspect/stream.js +1 -1
- package/dist/lib/inspect/terminal-utils.js +1 -1
- package/dist/lib/inspect/time-window.d.ts +28 -0
- package/dist/lib/inspect/time-window.d.ts.map +1 -0
- package/dist/lib/inspect/time-window.js +61 -0
- package/dist/lib/inspect/time-window.test.d.ts +2 -0
- package/dist/lib/inspect/time-window.test.d.ts.map +1 -0
- package/dist/lib/inspect/time-window.test.js +58 -0
- package/dist/lib/inspect/vercel-api.d.ts +5 -2
- package/dist/lib/inspect/vercel-api.d.ts.map +1 -1
- package/dist/lib/inspect/vercel-api.js +12 -37
- package/dist/lib/inspect/vercel-api.test.d.ts +2 -0
- package/dist/lib/inspect/vercel-api.test.d.ts.map +1 -0
- package/dist/lib/inspect/vercel-api.test.js +21 -0
- package/dist/lib/inspect/vercel-link.js +1 -1
- package/dist/lib/inspect/web.d.ts +24 -0
- package/dist/lib/inspect/web.d.ts.map +1 -1
- package/dist/lib/inspect/web.js +47 -3
- package/dist/lib/update-check.js +1 -1
- package/package.json +14 -14
- package/dist/base.js.map +0 -1
- package/dist/commands/build.js.map +0 -1
- package/dist/commands/cancel.js.map +0 -1
- package/dist/commands/dev.js.map +0 -1
- package/dist/commands/health.js.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/inspect.js.map +0 -1
- package/dist/commands/start.js.map +0 -1
- package/dist/commands/transform.js.map +0 -1
- package/dist/commands/validate.js.map +0 -1
- package/dist/commands/web.js.map +0 -1
- package/dist/lib/config/log.js.map +0 -1
- package/dist/lib/config/types.js.map +0 -1
- package/dist/lib/config/workflow-config.js.map +0 -1
- package/dist/lib/inspect/auth.js.map +0 -1
- package/dist/lib/inspect/env.js.map +0 -1
- package/dist/lib/inspect/flags.js.map +0 -1
- package/dist/lib/inspect/hydration.js.map +0 -1
- package/dist/lib/inspect/output.js.map +0 -1
- package/dist/lib/inspect/output.test.js.map +0 -1
- package/dist/lib/inspect/pagination.js.map +0 -1
- package/dist/lib/inspect/run.js.map +0 -1
- package/dist/lib/inspect/setup.js.map +0 -1
- package/dist/lib/inspect/stream.js.map +0 -1
- package/dist/lib/inspect/terminal-utils.js.map +0 -1
- package/dist/lib/inspect/vercel-api.js.map +0 -1
- package/dist/lib/inspect/vercel-link.js.map +0 -1
- package/dist/lib/inspect/web.js.map +0 -1
- package/dist/lib/update-check.js.map +0 -1
|
@@ -2,11 +2,14 @@ import { importKey } from '@workflow/core/encryption';
|
|
|
2
2
|
import { getDeserializeStream, getExternalRevivers, } from '@workflow/core/serialization';
|
|
3
3
|
import { VERCEL_403_ERROR_MESSAGE } from '@workflow/errors';
|
|
4
4
|
import { parseStepName, parseWorkflowName } from '@workflow/utils/parse-name';
|
|
5
|
+
import { isWaitEventType, } from '@workflow/world';
|
|
5
6
|
import chalk from 'chalk';
|
|
6
7
|
import { formatDistance } from 'date-fns';
|
|
7
8
|
import Table from 'easy-table';
|
|
8
9
|
import { logger } from '../config/log.js';
|
|
10
|
+
import { getObservabilityUpgradeRequiredMessage, isObservabilityUpgradeRequiredError, } from './errors.js';
|
|
9
11
|
import { hydrateResourceIO, isEncryptedRef, isExpiredRef, } from './hydration.js';
|
|
12
|
+
import { resolveTimeWindow } from './time-window.js';
|
|
10
13
|
/**
|
|
11
14
|
* Create an EncryptionKeyResolver from a World instance.
|
|
12
15
|
* Returns null if decrypt is false — encrypted data will show as a placeholder.
|
|
@@ -31,7 +34,7 @@ function createResolver(world, decrypt) {
|
|
|
31
34
|
return cached;
|
|
32
35
|
};
|
|
33
36
|
}
|
|
34
|
-
import { setupListPagination } from './pagination.js';
|
|
37
|
+
import { setupListPagination, } from './pagination.js';
|
|
35
38
|
import { streamToConsole } from './stream.js';
|
|
36
39
|
import { formatISODate, formatStatus as formatStatusAbbrev, getDisplaySettings, getTerminalWidth, isCI, } from './terminal-utils.js';
|
|
37
40
|
const DEFAULT_PAGE_SIZE = 20;
|
|
@@ -84,6 +87,7 @@ const STATUS_COLORS = {
|
|
|
84
87
|
failed: chalk.red,
|
|
85
88
|
cancelled: chalk.strikethrough.yellow,
|
|
86
89
|
pending: chalk.blue,
|
|
90
|
+
waiting: chalk.blue,
|
|
87
91
|
};
|
|
88
92
|
const isStreamId = (value) => {
|
|
89
93
|
return typeof value === 'string' && value.startsWith('strm_');
|
|
@@ -96,6 +100,7 @@ const showStatusLegend = () => {
|
|
|
96
100
|
'failed',
|
|
97
101
|
'cancelled',
|
|
98
102
|
'pending',
|
|
103
|
+
'waiting',
|
|
99
104
|
];
|
|
100
105
|
const legendItems = statuses.map((status) => {
|
|
101
106
|
const colorFunc = STATUS_COLORS[status];
|
|
@@ -133,11 +138,23 @@ const extractErrorMessage = (err) => {
|
|
|
133
138
|
}
|
|
134
139
|
return undefined;
|
|
135
140
|
};
|
|
141
|
+
const getPageInfo = (result) => {
|
|
142
|
+
if (typeof result !== 'object' ||
|
|
143
|
+
result === null ||
|
|
144
|
+
!('pageInfo' in result)) {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
return result.pageInfo;
|
|
148
|
+
};
|
|
136
149
|
const handleApiError = (error, backend) => {
|
|
137
150
|
// First check for Vercel access errors
|
|
138
151
|
if (checkAndHandleVercelAccessError(error, backend)) {
|
|
139
152
|
return true;
|
|
140
153
|
}
|
|
154
|
+
if (isObservabilityUpgradeRequiredError(error)) {
|
|
155
|
+
logger.error(getObservabilityUpgradeRequiredMessage());
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
141
158
|
// Handle other HTTP errors
|
|
142
159
|
if (error && typeof error === 'object') {
|
|
143
160
|
const err = error;
|
|
@@ -166,6 +183,7 @@ const getStatusText = (status) => {
|
|
|
166
183
|
const statusTexts = {
|
|
167
184
|
400: 'Bad Request',
|
|
168
185
|
401: 'Unauthorized',
|
|
186
|
+
402: 'Payment Required',
|
|
169
187
|
403: 'Forbidden',
|
|
170
188
|
404: 'Not Found',
|
|
171
189
|
429: 'Too Many Requests',
|
|
@@ -229,7 +247,7 @@ export const formatTableValue = (prop, value, opts = {}, displaySettings, item)
|
|
|
229
247
|
}
|
|
230
248
|
if (prop === 'status') {
|
|
231
249
|
const status = value;
|
|
232
|
-
const colorFunc = STATUS_COLORS[status];
|
|
250
|
+
const colorFunc = STATUS_COLORS[status] ?? ((formatted) => formatted);
|
|
233
251
|
const formattedStatus = displaySettings?.abbreviateStatus
|
|
234
252
|
? formatStatusAbbrev(status, true)
|
|
235
253
|
: status;
|
|
@@ -305,6 +323,14 @@ const showJson = (data) => {
|
|
|
305
323
|
const json = JSON.stringify(data, null, 2);
|
|
306
324
|
process.stdout.write(`${json}\n`);
|
|
307
325
|
};
|
|
326
|
+
const showJsonPage = (page) => {
|
|
327
|
+
showJson({
|
|
328
|
+
data: page.data,
|
|
329
|
+
cursor: page.cursor,
|
|
330
|
+
hasMore: page.hasMore,
|
|
331
|
+
...(page.pageInfo ? { pageInfo: page.pageInfo } : {}),
|
|
332
|
+
});
|
|
333
|
+
};
|
|
308
334
|
/**
|
|
309
335
|
* In tables, we want to show a shorter timestamp, YYYY-MM-DD HH:MM:SS
|
|
310
336
|
*/
|
|
@@ -418,31 +444,81 @@ const inlineFormatIO = (io, topLevel = true) => {
|
|
|
418
444
|
}
|
|
419
445
|
return value;
|
|
420
446
|
};
|
|
447
|
+
/**
|
|
448
|
+
* List views surface metadata only. When the active backend exposes the
|
|
449
|
+
* optional `world.analytics` read namespace we read list pages from it
|
|
450
|
+
* (metadata-only — no payload resolution); otherwise we fall back to the
|
|
451
|
+
* runtime storage APIs with `resolveData: 'none'`.
|
|
452
|
+
*
|
|
453
|
+
* `--withData` forces the runtime path so payloads can be resolved into the
|
|
454
|
+
* table. It is deprecated for list views: view payloads per-resource with
|
|
455
|
+
* `workflow inspect <resource> <id>`.
|
|
456
|
+
*/
|
|
457
|
+
const warnWithDataDeprecatedForList = (singular) => {
|
|
458
|
+
logger.warn(`'--withData' is deprecated for list views and will be removed in a future release. Use 'workflow inspect ${singular} <id>' to view payloads for a single ${singular}.`);
|
|
459
|
+
};
|
|
421
460
|
export const listRuns = async (world, opts = {}) => {
|
|
422
461
|
const resolveKey = createResolver(world, opts?.decrypt ?? false);
|
|
423
462
|
if (opts.stepId || opts.runId) {
|
|
424
463
|
logger.warn('Filtering by step-id or run-id is not supported in list calls, ignoring filter.');
|
|
425
464
|
}
|
|
465
|
+
if (opts.withData) {
|
|
466
|
+
warnWithDataDeprecatedForList('run');
|
|
467
|
+
}
|
|
468
|
+
const useAnalytics = !opts.withData && Boolean(world.analytics);
|
|
426
469
|
const resolveData = opts.withData ? 'all' : 'none';
|
|
470
|
+
const status = opts.status;
|
|
471
|
+
// Resolve --since/--until into an explicit listing window. Only the
|
|
472
|
+
// analytics read path supports one; the runtime storage APIs have no time
|
|
473
|
+
// filter. Without the flags the backend applies its default window
|
|
474
|
+
// (trailing 24h on the Vercel backend).
|
|
475
|
+
const timeWindow = resolveTimeWindow(opts);
|
|
476
|
+
if (timeWindow && !useAnalytics) {
|
|
477
|
+
logger.warn('--since/--until require the analytics read path and are ignored by this backend.');
|
|
478
|
+
}
|
|
427
479
|
// Determine which props to show based on withData flag
|
|
428
480
|
const props = opts.withData
|
|
429
481
|
? WORKFLOW_RUN_LISTED_PROPS
|
|
430
482
|
: WORKFLOW_RUN_LISTED_PROPS.filter((prop) => !WORKFLOW_RUN_IO_PROPS.includes(prop));
|
|
483
|
+
const fetchRunsPage = async (cursor) => {
|
|
484
|
+
const pagination = {
|
|
485
|
+
sortOrder: opts.sort || 'desc',
|
|
486
|
+
cursor,
|
|
487
|
+
limit: opts.limit || DEFAULT_PAGE_SIZE,
|
|
488
|
+
};
|
|
489
|
+
if (useAnalytics && world.analytics) {
|
|
490
|
+
const runs = await world.analytics.runs.list({
|
|
491
|
+
workflowName: opts.workflowName,
|
|
492
|
+
status,
|
|
493
|
+
...(timeWindow ?? {}),
|
|
494
|
+
pagination,
|
|
495
|
+
});
|
|
496
|
+
return {
|
|
497
|
+
data: runs.data,
|
|
498
|
+
cursor: runs.cursor,
|
|
499
|
+
hasMore: runs.hasMore,
|
|
500
|
+
pageInfo: getPageInfo(runs),
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
const runs = await world.runs.list({
|
|
504
|
+
workflowName: opts.workflowName,
|
|
505
|
+
status,
|
|
506
|
+
pagination,
|
|
507
|
+
resolveData,
|
|
508
|
+
});
|
|
509
|
+
const data = await Promise.all(runs.data.map((r) => hydrateResourceIO(r, resolveKey)));
|
|
510
|
+
return {
|
|
511
|
+
data: data,
|
|
512
|
+
cursor: runs.cursor,
|
|
513
|
+
hasMore: runs.hasMore,
|
|
514
|
+
pageInfo: getPageInfo(runs),
|
|
515
|
+
};
|
|
516
|
+
};
|
|
431
517
|
// For JSON output, just fetch once and return
|
|
432
518
|
if (opts.json) {
|
|
433
519
|
try {
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
status: opts.status,
|
|
437
|
-
pagination: {
|
|
438
|
-
sortOrder: opts.sort || 'desc',
|
|
439
|
-
cursor: opts.cursor,
|
|
440
|
-
limit: opts.limit || DEFAULT_PAGE_SIZE,
|
|
441
|
-
},
|
|
442
|
-
resolveData,
|
|
443
|
-
});
|
|
444
|
-
const runsWithHydratedIO = await Promise.all(runs.data.map((r) => hydrateResourceIO(r, resolveKey)));
|
|
445
|
-
showJson({ ...runs, data: runsWithHydratedIO });
|
|
520
|
+
const page = await fetchRunsPage(opts.cursor);
|
|
521
|
+
showJsonPage(page);
|
|
446
522
|
return;
|
|
447
523
|
}
|
|
448
524
|
catch (error) {
|
|
@@ -457,21 +533,7 @@ export const listRuns = async (world, opts = {}) => {
|
|
|
457
533
|
interactive: opts.interactive,
|
|
458
534
|
fetchPage: async (cursor) => {
|
|
459
535
|
try {
|
|
460
|
-
|
|
461
|
-
workflowName: opts.workflowName,
|
|
462
|
-
status: opts.status,
|
|
463
|
-
pagination: {
|
|
464
|
-
sortOrder: opts.sort || 'desc',
|
|
465
|
-
cursor,
|
|
466
|
-
limit: opts.limit || DEFAULT_PAGE_SIZE,
|
|
467
|
-
},
|
|
468
|
-
resolveData,
|
|
469
|
-
});
|
|
470
|
-
return {
|
|
471
|
-
data: runs.data,
|
|
472
|
-
cursor: runs.cursor,
|
|
473
|
-
hasMore: runs.hasMore,
|
|
474
|
-
};
|
|
536
|
+
return await fetchRunsPage(cursor);
|
|
475
537
|
}
|
|
476
538
|
catch (error) {
|
|
477
539
|
if (handleApiError(error, opts.backend)) {
|
|
@@ -481,8 +543,7 @@ export const listRuns = async (world, opts = {}) => {
|
|
|
481
543
|
}
|
|
482
544
|
},
|
|
483
545
|
displayPage: async (runs) => {
|
|
484
|
-
|
|
485
|
-
logger.log(showTable(runsWithHydratedIO, props, opts));
|
|
546
|
+
logger.log(showTable(runs, props, opts));
|
|
486
547
|
},
|
|
487
548
|
});
|
|
488
549
|
};
|
|
@@ -547,26 +608,53 @@ export const listSteps = async (world, opts = {
|
|
|
547
608
|
logger.error('No run found.');
|
|
548
609
|
return;
|
|
549
610
|
}
|
|
611
|
+
if (opts.withData) {
|
|
612
|
+
warnWithDataDeprecatedForList('step');
|
|
613
|
+
}
|
|
614
|
+
const useAnalytics = !opts.withData && Boolean(world.analytics);
|
|
550
615
|
const resolveData = opts.withData ? 'all' : 'none';
|
|
551
616
|
// Determine which props to show based on withData flag
|
|
552
617
|
const props = opts.withData
|
|
553
618
|
? STEP_LISTED_PROPS
|
|
554
619
|
: STEP_LISTED_PROPS.filter((prop) => !STEP_IO_PROPS.includes(prop));
|
|
620
|
+
const fetchStepsPage = async (cursor) => {
|
|
621
|
+
logger.debug(`Fetching steps for run ${runId}`);
|
|
622
|
+
const pagination = {
|
|
623
|
+
sortOrder: opts.sort || 'desc',
|
|
624
|
+
cursor,
|
|
625
|
+
limit: opts.limit || DEFAULT_PAGE_SIZE,
|
|
626
|
+
};
|
|
627
|
+
if (useAnalytics && world.analytics) {
|
|
628
|
+
const steps = await world.analytics.steps.list({ runId, pagination });
|
|
629
|
+
const page = {
|
|
630
|
+
data: steps.data,
|
|
631
|
+
cursor: steps.cursor,
|
|
632
|
+
hasMore: steps.hasMore,
|
|
633
|
+
pageInfo: getPageInfo(steps),
|
|
634
|
+
};
|
|
635
|
+
if (cursor || page.data.length > 0 || page.hasMore) {
|
|
636
|
+
return page;
|
|
637
|
+
}
|
|
638
|
+
logger.debug(`No analytics steps found for run ${runId}; falling back to storage`);
|
|
639
|
+
}
|
|
640
|
+
const stepChunks = await world.steps.list({
|
|
641
|
+
runId,
|
|
642
|
+
pagination,
|
|
643
|
+
resolveData,
|
|
644
|
+
});
|
|
645
|
+
const data = await Promise.all(stepChunks.data.map((s) => hydrateResourceIO(s, resolveKey)));
|
|
646
|
+
return {
|
|
647
|
+
data: data,
|
|
648
|
+
cursor: stepChunks.cursor,
|
|
649
|
+
hasMore: stepChunks.hasMore,
|
|
650
|
+
pageInfo: getPageInfo(stepChunks),
|
|
651
|
+
};
|
|
652
|
+
};
|
|
555
653
|
// For JSON output, just fetch once and return
|
|
556
654
|
if (opts.json) {
|
|
557
|
-
logger.debug(`Fetching steps for run ${runId}`);
|
|
558
655
|
try {
|
|
559
|
-
const
|
|
560
|
-
|
|
561
|
-
pagination: {
|
|
562
|
-
sortOrder: opts.sort || 'desc',
|
|
563
|
-
cursor: opts.cursor,
|
|
564
|
-
limit: opts.limit || DEFAULT_PAGE_SIZE,
|
|
565
|
-
},
|
|
566
|
-
resolveData,
|
|
567
|
-
});
|
|
568
|
-
const stepsWithHydratedIO = await Promise.all(stepChunks.data.map((s) => hydrateResourceIO(s, resolveKey)));
|
|
569
|
-
showJson(stepsWithHydratedIO);
|
|
656
|
+
const page = await fetchStepsPage(opts.cursor);
|
|
657
|
+
showJson(page.data);
|
|
570
658
|
return;
|
|
571
659
|
}
|
|
572
660
|
catch (error) {
|
|
@@ -580,22 +668,8 @@ export const listSteps = async (world, opts = {
|
|
|
580
668
|
initialCursor: opts.cursor,
|
|
581
669
|
interactive: opts.interactive,
|
|
582
670
|
fetchPage: async (cursor) => {
|
|
583
|
-
logger.debug(`Fetching steps for run ${runId}`);
|
|
584
671
|
try {
|
|
585
|
-
|
|
586
|
-
runId,
|
|
587
|
-
pagination: {
|
|
588
|
-
sortOrder: opts.sort || 'desc',
|
|
589
|
-
cursor,
|
|
590
|
-
limit: opts.limit || DEFAULT_PAGE_SIZE,
|
|
591
|
-
},
|
|
592
|
-
resolveData,
|
|
593
|
-
});
|
|
594
|
-
return {
|
|
595
|
-
data: stepChunks.data,
|
|
596
|
-
cursor: stepChunks.cursor,
|
|
597
|
-
hasMore: stepChunks.hasMore,
|
|
598
|
-
};
|
|
672
|
+
return await fetchStepsPage(cursor);
|
|
599
673
|
}
|
|
600
674
|
catch (error) {
|
|
601
675
|
if (handleApiError(error, opts.backend)) {
|
|
@@ -605,8 +679,7 @@ export const listSteps = async (world, opts = {
|
|
|
605
679
|
}
|
|
606
680
|
},
|
|
607
681
|
displayPage: async (steps) => {
|
|
608
|
-
|
|
609
|
-
logger.log(showTable(stepsWithHydratedIO, props, opts));
|
|
682
|
+
logger.log(showTable(steps, props, opts));
|
|
610
683
|
showInspectInfoBox('step');
|
|
611
684
|
},
|
|
612
685
|
});
|
|
@@ -730,40 +803,60 @@ export const listEvents = async (world, opts = {}) => {
|
|
|
730
803
|
logger.error('No run found.');
|
|
731
804
|
return;
|
|
732
805
|
}
|
|
806
|
+
if (opts.withData) {
|
|
807
|
+
warnWithDataDeprecatedForList('event');
|
|
808
|
+
}
|
|
809
|
+
const useAnalytics = !opts.withData && Boolean(world.analytics);
|
|
733
810
|
const correlationIdFilter = opts.hookId || opts.stepId;
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
811
|
+
// Determine which props to show based on withData flag
|
|
812
|
+
const props = opts.withData
|
|
813
|
+
? EVENT_LISTED_PROPS
|
|
814
|
+
: EVENT_LISTED_PROPS.filter((prop) => !EVENT_IO_PROPS.includes(prop));
|
|
815
|
+
const fetchEventsPage = async (cursor) => {
|
|
816
|
+
logger.debug(`Fetching events for run ${runId}`);
|
|
817
|
+
const pagination = {
|
|
737
818
|
sortOrder: opts.sort || 'desc',
|
|
738
|
-
cursor
|
|
819
|
+
cursor,
|
|
739
820
|
limit: opts.limit || DEFAULT_PAGE_SIZE,
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
821
|
+
};
|
|
822
|
+
if (useAnalytics && world.analytics) {
|
|
823
|
+
const events = await world.analytics.events.list({
|
|
824
|
+
runId,
|
|
825
|
+
correlationId: correlationIdFilter,
|
|
826
|
+
pagination,
|
|
827
|
+
});
|
|
828
|
+
const page = {
|
|
829
|
+
data: events.data,
|
|
830
|
+
cursor: events.cursor,
|
|
831
|
+
hasMore: events.hasMore,
|
|
832
|
+
pageInfo: getPageInfo(events),
|
|
752
833
|
};
|
|
834
|
+
if (cursor || page.data.length > 0 || page.hasMore) {
|
|
835
|
+
return page;
|
|
836
|
+
}
|
|
837
|
+
logger.debug(`No analytics events found for run ${runId}; falling back to storage`);
|
|
753
838
|
}
|
|
754
|
-
|
|
839
|
+
const result = await world.events.list({
|
|
840
|
+
runId,
|
|
841
|
+
pagination,
|
|
842
|
+
resolveData: opts.withData ? 'all' : 'none',
|
|
843
|
+
});
|
|
844
|
+
const filtered = correlationIdFilter
|
|
845
|
+
? result.data.filter((e) => e.correlationId === correlationIdFilter)
|
|
846
|
+
: result.data;
|
|
847
|
+
const data = await Promise.all(filtered.map((e) => hydrateResourceIO(e, resolveKey)));
|
|
848
|
+
return {
|
|
849
|
+
data: data,
|
|
850
|
+
cursor: result.cursor,
|
|
851
|
+
hasMore: result.hasMore,
|
|
852
|
+
pageInfo: getPageInfo(result),
|
|
853
|
+
};
|
|
755
854
|
};
|
|
756
|
-
// Determine which props to show based on withData flag
|
|
757
|
-
const props = opts.withData
|
|
758
|
-
? EVENT_LISTED_PROPS
|
|
759
|
-
: EVENT_LISTED_PROPS.filter((prop) => !EVENT_IO_PROPS.includes(prop));
|
|
760
855
|
// For JSON output, just fetch once and return
|
|
761
856
|
if (opts.json) {
|
|
762
|
-
logger.debug(`Fetching events for run ${runId}`);
|
|
763
857
|
try {
|
|
764
|
-
const
|
|
765
|
-
|
|
766
|
-
showJson(hydratedEvents);
|
|
858
|
+
const page = await fetchEventsPage(opts.cursor);
|
|
859
|
+
showJson(page.data);
|
|
767
860
|
return;
|
|
768
861
|
}
|
|
769
862
|
catch (error) {
|
|
@@ -777,14 +870,8 @@ export const listEvents = async (world, opts = {}) => {
|
|
|
777
870
|
initialCursor: opts.cursor,
|
|
778
871
|
interactive: opts.interactive,
|
|
779
872
|
fetchPage: async (cursor) => {
|
|
780
|
-
logger.debug(`Fetching events for run ${runId}`);
|
|
781
873
|
try {
|
|
782
|
-
|
|
783
|
-
return {
|
|
784
|
-
data: events.data,
|
|
785
|
-
cursor: events.cursor,
|
|
786
|
-
hasMore: events.hasMore,
|
|
787
|
-
};
|
|
874
|
+
return await fetchEventsPage(cursor);
|
|
788
875
|
}
|
|
789
876
|
catch (error) {
|
|
790
877
|
if (handleApiError(error, opts.backend)) {
|
|
@@ -794,8 +881,7 @@ export const listEvents = async (world, opts = {}) => {
|
|
|
794
881
|
}
|
|
795
882
|
},
|
|
796
883
|
displayPage: async (events) => {
|
|
797
|
-
|
|
798
|
-
logger.log(showTable(hydratedEvents, props, opts));
|
|
884
|
+
logger.log(showTable(events, props, opts));
|
|
799
885
|
showInspectInfoBox('event');
|
|
800
886
|
},
|
|
801
887
|
});
|
|
@@ -810,26 +896,35 @@ export const listHooks = async (world, opts = {}) => {
|
|
|
810
896
|
}
|
|
811
897
|
const runId = opts.runId;
|
|
812
898
|
const resolveData = opts.withData ? 'all' : 'none';
|
|
813
|
-
//
|
|
814
|
-
|
|
899
|
+
// Hooks always read from the runtime storage API. Unlike runs/steps/events,
|
|
900
|
+
// the analytics read path omits `ownerId` (and the secret hook token used by
|
|
901
|
+
// resume/copy-token surfaces), so hook listing stays on the canonical APIs.
|
|
902
|
+
const fetchHooksPage = async (cursor) => {
|
|
815
903
|
if (!runId) {
|
|
816
904
|
logger.debug('Fetching all hooks');
|
|
817
905
|
}
|
|
818
906
|
else {
|
|
819
907
|
logger.debug(`Fetching hooks for run ${runId}`);
|
|
820
908
|
}
|
|
909
|
+
const pagination = {
|
|
910
|
+
sortOrder: opts.sort || 'desc',
|
|
911
|
+
cursor,
|
|
912
|
+
limit: opts.limit || DEFAULT_PAGE_SIZE,
|
|
913
|
+
};
|
|
914
|
+
const hooks = await world.hooks.list({ runId, pagination, resolveData });
|
|
915
|
+
const data = await Promise.all(hooks.data.map((h) => hydrateResourceIO(h, resolveKey)));
|
|
916
|
+
return {
|
|
917
|
+
data: data,
|
|
918
|
+
cursor: hooks.cursor,
|
|
919
|
+
hasMore: hooks.hasMore,
|
|
920
|
+
pageInfo: getPageInfo(hooks),
|
|
921
|
+
};
|
|
922
|
+
};
|
|
923
|
+
// For JSON output, just fetch once and return
|
|
924
|
+
if (opts.json) {
|
|
821
925
|
try {
|
|
822
|
-
const
|
|
823
|
-
|
|
824
|
-
pagination: {
|
|
825
|
-
sortOrder: opts.sort || 'desc',
|
|
826
|
-
cursor: opts.cursor,
|
|
827
|
-
limit: opts.limit || DEFAULT_PAGE_SIZE,
|
|
828
|
-
},
|
|
829
|
-
resolveData,
|
|
830
|
-
});
|
|
831
|
-
const hydratedHooks = await Promise.all(hooks.data.map((h) => hydrateResourceIO(h, resolveKey)));
|
|
832
|
-
showJson({ ...hooks, data: hydratedHooks });
|
|
926
|
+
const page = await fetchHooksPage(opts.cursor);
|
|
927
|
+
showJsonPage(page);
|
|
833
928
|
return;
|
|
834
929
|
}
|
|
835
930
|
catch (error) {
|
|
@@ -844,27 +939,8 @@ export const listHooks = async (world, opts = {}) => {
|
|
|
844
939
|
initialCursor: opts.cursor,
|
|
845
940
|
interactive: opts.interactive,
|
|
846
941
|
fetchPage: async (cursor) => {
|
|
847
|
-
if (!runId) {
|
|
848
|
-
logger.debug('Fetching all hooks');
|
|
849
|
-
}
|
|
850
|
-
else {
|
|
851
|
-
logger.debug(`Fetching hooks for run ${runId}`);
|
|
852
|
-
}
|
|
853
942
|
try {
|
|
854
|
-
|
|
855
|
-
runId,
|
|
856
|
-
pagination: {
|
|
857
|
-
sortOrder: opts.sort || 'desc',
|
|
858
|
-
cursor,
|
|
859
|
-
limit: opts.limit || DEFAULT_PAGE_SIZE,
|
|
860
|
-
},
|
|
861
|
-
resolveData,
|
|
862
|
-
});
|
|
863
|
-
return {
|
|
864
|
-
data: hooks.data,
|
|
865
|
-
cursor: hooks.cursor,
|
|
866
|
-
hasMore: hooks.hasMore,
|
|
867
|
-
};
|
|
943
|
+
return await fetchHooksPage(cursor);
|
|
868
944
|
}
|
|
869
945
|
catch (error) {
|
|
870
946
|
if (handleApiError(error, opts.backend)) {
|
|
@@ -874,8 +950,7 @@ export const listHooks = async (world, opts = {}) => {
|
|
|
874
950
|
}
|
|
875
951
|
},
|
|
876
952
|
displayPage: async (hooks) => {
|
|
877
|
-
|
|
878
|
-
logger.log(showTable(hydratedHooks, HOOK_LISTED_PROPS, opts));
|
|
953
|
+
logger.log(showTable(hooks, HOOK_LISTED_PROPS, opts));
|
|
879
954
|
showInspectInfoBox('hook');
|
|
880
955
|
},
|
|
881
956
|
});
|
|
@@ -908,6 +983,42 @@ export const showHook = async (world, hookId, opts = {}) => {
|
|
|
908
983
|
throw error;
|
|
909
984
|
}
|
|
910
985
|
};
|
|
986
|
+
/**
|
|
987
|
+
* List waits/sleeps via the analytics read path. The analytics wait shape is
|
|
988
|
+
* keyed by `waitId`/`status` rather than the `correlationId`/`eventId` columns
|
|
989
|
+
* reconstructed from the event stream in the fallback path.
|
|
990
|
+
*/
|
|
991
|
+
const listSleepsViaAnalytics = async (analytics, opts) => {
|
|
992
|
+
const fetchSleepsPage = async (cursor) => {
|
|
993
|
+
const waits = await analytics.waits.list({
|
|
994
|
+
runId: opts.runId,
|
|
995
|
+
pagination: {
|
|
996
|
+
sortOrder: opts.sort || 'desc',
|
|
997
|
+
cursor,
|
|
998
|
+
limit: opts.limit || DEFAULT_PAGE_SIZE,
|
|
999
|
+
},
|
|
1000
|
+
});
|
|
1001
|
+
return {
|
|
1002
|
+
data: waits.data,
|
|
1003
|
+
cursor: waits.cursor,
|
|
1004
|
+
hasMore: waits.hasMore,
|
|
1005
|
+
pageInfo: getPageInfo(waits),
|
|
1006
|
+
};
|
|
1007
|
+
};
|
|
1008
|
+
if (opts.json) {
|
|
1009
|
+
const page = await fetchSleepsPage(opts.cursor);
|
|
1010
|
+
showJson(page.data);
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
await setupListPagination({
|
|
1014
|
+
initialCursor: opts.cursor,
|
|
1015
|
+
interactive: opts.interactive,
|
|
1016
|
+
fetchPage: fetchSleepsPage,
|
|
1017
|
+
displayPage: async (waits) => {
|
|
1018
|
+
logger.log(showTable(waits, ['waitId', 'status', 'createdAt', 'resumeAt', 'completedAt'], { ...opts, disableRelativeDates: true }));
|
|
1019
|
+
},
|
|
1020
|
+
});
|
|
1021
|
+
};
|
|
911
1022
|
export const listSleeps = async (world, opts = {}) => {
|
|
912
1023
|
if (!opts.runId) {
|
|
913
1024
|
logger.error('run-id is required for listing sleeps. Usage: `workflow inspect sleeps --runId=<id>`');
|
|
@@ -922,6 +1033,19 @@ export const listSleeps = async (world, opts = {}) => {
|
|
|
922
1033
|
if (opts.withData) {
|
|
923
1034
|
logger.warn('`withData` flag is ignored when listing sleeps');
|
|
924
1035
|
}
|
|
1036
|
+
// Prefer the analytics read path for wait/sleep listing when available.
|
|
1037
|
+
if (world.analytics) {
|
|
1038
|
+
try {
|
|
1039
|
+
await listSleepsViaAnalytics(world.analytics, opts);
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
catch (error) {
|
|
1043
|
+
if (handleApiError(error, opts.backend)) {
|
|
1044
|
+
process.exit(1);
|
|
1045
|
+
}
|
|
1046
|
+
throw error;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
925
1049
|
try {
|
|
926
1050
|
// Fetch all events for the run with resolveData='all' to get wait eventData
|
|
927
1051
|
const events = await world.events.list({
|
|
@@ -939,7 +1063,7 @@ export const listSleeps = async (world, opts = {}) => {
|
|
|
939
1063
|
// Group wait events by correlationId
|
|
940
1064
|
const waitEventsByCorrelation = new Map();
|
|
941
1065
|
for (const event of events.data) {
|
|
942
|
-
if (event.correlationId
|
|
1066
|
+
if (isWaitEventType(event.eventType) && event.correlationId) {
|
|
943
1067
|
const existing = waitEventsByCorrelation.get(event.correlationId) ?? [];
|
|
944
1068
|
existing.push(event);
|
|
945
1069
|
waitEventsByCorrelation.set(event.correlationId, existing);
|
|
@@ -997,4 +1121,4 @@ export const listSleeps = async (world, opts = {}) => {
|
|
|
997
1121
|
throw error;
|
|
998
1122
|
}
|
|
999
1123
|
};
|
|
1000
|
-
//# sourceMappingURL=output.js.map
|
|
1124
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0cHV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9pbnNwZWN0L291dHB1dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdEQsT0FBTyxFQUVMLG9CQUFvQixFQUNwQixtQkFBbUIsR0FDcEIsTUFBTSw4QkFBOEIsQ0FBQztBQUN0QyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsYUFBYSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUUsT0FBTyxFQUdMLGVBQWUsR0FJaEIsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFFMUIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxZQUFZLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTFDLE9BQU8sRUFDTCxzQ0FBc0MsRUFDdEMsbUNBQW1DLEdBQ3BDLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFFTCxpQkFBaUIsRUFDakIsY0FBYyxFQUNkLFlBQVksR0FDYixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXJEOzs7Ozs7R0FNRztBQUNILFNBQVMsY0FBYyxDQUFDLEtBQVksRUFBRSxPQUFnQjtJQUNwRCxJQUFJLENBQUMsT0FBTztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQzFCLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDL0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQTJDLENBQUM7SUFDakUsT0FBTyxDQUFDLEtBQWEsRUFBRSxFQUFFO1FB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Q25CLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDcEMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNwQyxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQzdELENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDZCxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDakIsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLENBQUMsR0FBRyxDQUNSLFNBQVMsQ0FDUCxNQUE4QyxFQUM5QyxpQkFBaUIsRUFDakIsRUFBRSxHQUFHLElBQUksRUFBRSxvQkFBb0IsRUFBRSxJQUFJLEVBQUUsQ0FDeEMsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixJQUFJLGNBQWMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQixDQUFDO1FBQ0QsTUFBTSxLQUFLLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW1wb3J0S2V5IH0gZnJvbSAnQHdvcmtmbG93L2NvcmUvZW5jcnlwdGlvbic7XG5pbXBvcnQge1xuICB0eXBlIEVuY3J5cHRpb25LZXlQYXJhbSxcbiAgZ2V0RGVzZXJpYWxpemVTdHJlYW0sXG4gIGdldEV4dGVybmFsUmV2aXZlcnMsXG59IGZyb20gJ0B3b3JrZmxvdy9jb3JlL3NlcmlhbGl6YXRpb24nO1xuaW1wb3J0IHsgVkVSQ0VMXzQwM19FUlJPUl9NRVNTQUdFIH0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQgeyBwYXJzZVN0ZXBOYW1lLCBwYXJzZVdvcmtmbG93TmFtZSB9IGZyb20gJ0B3b3JrZmxvdy91dGlscy9wYXJzZS1uYW1lJztcbmltcG9ydCB7XG4gIHR5cGUgRXZlbnQsXG4gIHR5cGUgSG9vayxcbiAgaXNXYWl0RXZlbnRUeXBlLFxuICB0eXBlIFN0ZXAsXG4gIHR5cGUgV29ya2Zsb3dSdW4sXG4gIHR5cGUgV29ybGQsXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgY2hhbGsgZnJvbSAnY2hhbGsnO1xuXG5pbXBvcnQgeyBmb3JtYXREaXN0YW5jZSB9IGZyb20gJ2RhdGUtZm5zJztcbmltcG9ydCBUYWJsZSBmcm9tICdlYXN5LXRhYmxlJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL2NvbmZpZy9sb2cuanMnO1xuaW1wb3J0IHR5cGUgeyBJbnNwZWN0Q0xJT3B0aW9ucyB9IGZyb20gJy4uL2NvbmZpZy90eXBlcy5qcyc7XG5pbXBvcnQge1xuICBnZXRPYnNlcnZhYmlsaXR5VXBncmFkZVJlcXVpcmVkTWVzc2FnZSxcbiAgaXNPYnNlcnZhYmlsaXR5VXBncmFkZVJlcXVpcmVkRXJyb3IsXG59IGZyb20gJy4vZXJyb3JzLmpzJztcbmltcG9ydCB7XG4gIHR5cGUgRW5jcnlwdGlvbktleVJlc29sdmVyLFxuICBoeWRyYXRlUmVzb3VyY2VJTyxcbiAgaXNFbmNyeXB0ZWRSZWYsXG4gIGlzRXhwaXJlZFJlZixcbn0gZnJvbSAnLi9oeWRyYXRpb24uanMnO1xuaW1wb3J0IHsgcmVzb2x2ZVRpbWVXaW5kb3cgfSBmcm9tICcuL3RpbWUtd2luZG93LmpzJztcblxuLyoqXG4gKiBDcmVhdGUgYW4gRW5jcnlwdGlvbktleVJlc29sdmVyIGZyb20gYSBXb3JsZCBpbnN0YW5jZS5cbiAqIFJldHVybnMgbnVsbCBpZiBkZWNyeXB0IGlzIGZhbHNlIOKAlCBlbmNyeXB0ZWQgZGF0YSB3aWxsIHNob3cgYXMgYSBwbGFjZWhvbGRlci5cbiAqXG4gKiBUaGUgcmVzb2x2ZXIgZmV0Y2hlcyB0aGUgZnVsbCBXb3JrZmxvd1J1biAoY2FjaGVkIHBlciBydW5JZCkgc28gdGhhdCB0aGVcbiAqIFdvcmxkIGNhbiBpbnNwZWN0IGRlcGxveW1lbnQtc3BlY2lmaWMgZmllbGRzIGZvciBrZXkgcmVzb2x1dGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUmVzb2x2ZXIod29ybGQ6IFdvcmxkLCBkZWNyeXB0OiBib29sZWFuKTogRW5jcnlwdGlvbktleVJlc29sdmVyIHtcbiAgaWYgKCFkZWNyeXB0KSByZXR1cm4gbnVsbDtcbiAgaWYgKCF3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgY2FjaGUgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxVaW50OEFycmF5IHwgdW5kZWZpbmVkPj4oKTtcbiAgcmV0dXJuIChydW5JZDogc3RyaW5nKSA9PiB7XG4gICAgbGV0IGNhY2hlZCA9IGNhY2hlLmdldChydW5JZCk7XG4gICAgaWYgKCFjYWNoZWQpIHtcbiAgICAgIGNhY2hlZCA9IHdvcmxkLnJ1bnNcbiAgICAgICAgLmdldChydW5JZClcbiAgICAgICAgLnRoZW4oKHJ1bikgPT4gd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1biEocnVuKSk7XG4gICAgICBjYWNoZS5zZXQocnVuSWQsIGNhY2hlZCk7XG4gICAgfVxuICAgIHJldHVybiBjYWNoZWQ7XG4gIH07XG59XG5cbmltcG9ydCB7XG4gIHR5cGUgQW5hbHl0aWNzUGFnZUluZm8sXG4gIHR5cGUgUGFnZURhdGEsXG4gIHNldHVwTGlzdFBhZ2luYXRpb24sXG59IGZyb20gJy4vcGFnaW5hdGlvbi5qcyc7XG5pbXBvcnQgeyBzdHJlYW1Ub0NvbnNvbGUgfSBmcm9tICcuL3N0cmVhbS5qcyc7XG5pbXBvcnQge1xuICBmb3JtYXRJU09EYXRlLFxuICBmb3JtYXRTdGF0dXMgYXMgZm9ybWF0U3RhdHVzQWJicmV2LFxuICBnZXREaXNwbGF5U2V0dGluZ3MsXG4gIGdldFRlcm1pbmFsV2lkdGgsXG4gIGlzQ0ksXG59IGZyb20gJy4vdGVybWluYWwtdXRpbHMuanMnO1xuXG5jb25zdCBERUZBVUxUX1BBR0VfU0laRSA9IDIwO1xubGV0IFRBQkxFX1RSVU5DQVRFX0lPX0xFTkdUSCA9IDE1OyAvLyBXaWxsIGJlIGFkanVzdGVkIGJhc2VkIG9uIHRlcm1pbmFsIHdpZHRoXG5cbmNvbnN0IFdPUktGTE9XX1JVTl9JT19QUk9QUzogKGtleW9mIFdvcmtmbG93UnVuKVtdID0gWydpbnB1dCcsICdvdXRwdXQnXTtcblxuY29uc3QgU1RFUF9JT19QUk9QUzogKGtleW9mIFN0ZXApW10gPSBbJ2lucHV0JywgJ291dHB1dCddO1xuXG5jb25zdCBXT1JLRkxPV19SVU5fTElTVEVEX1BST1BTOiAoa2V5b2YgV29ya2Zsb3dSdW4pW10gPSBbXG4gICdydW5JZCcsXG4gICd3b3JrZmxvd05hbWUnLFxuICAnc3RhdHVzJyxcbiAgJ3N0YXJ0ZWRBdCcsXG4gICdjb21wbGV0ZWRBdCcsXG4gIC4uLldPUktGTE9XX1JVTl9JT19QUk9QUyxcbl07XG5cbmNvbnN0IFNURVBfTElTVEVEX1BST1BTOiAoa2V5b2YgU3RlcClbXSA9IFtcbiAgJ3J1bklkJyxcbiAgJ3N0ZXBJZCcsXG4gICdzdGVwTmFtZScsXG4gICdzdGF0dXMnLFxuICAnc3RhcnRlZEF0JyxcbiAgJ2NvbXBsZXRlZEF0JyxcbiAgLi4uU1RFUF9JT19QUk9QUyxcbl07XG5cbmNvbnN0IEVWRU5UX0lPX1BST1BTOiAoa2V5b2YgRXZlbnQgfCAnZXZlbnREYXRhJylbXSA9IFsnZXZlbnREYXRhJ107XG5cbmNvbnN0IEVWRU5UX0xJU1RFRF9QUk9QUzogKGtleW9mIEV2ZW50IHwgJ2V2ZW50RGF0YScpW10gPSBbXG4gICdldmVudElkJyxcbiAgJ2V2ZW50VHlwZScsXG4gICdjb3JyZWxhdGlvbklkJyxcbiAgJ2NyZWF0ZWRBdCcsXG4gIC4uLkVWRU5UX0lPX1BST1BTLFxuXTtcblxuLy8gY29uc3QgSE9PS19EQVRBX1BST1BTOiAoa2V5b2YgSG9vayB8ICdoYXNSZXNwb25zZScpW10gPSBbJ2hhc1Jlc3BvbnNlJ107XG5cbmNvbnN0IEhPT0tfTElTVEVEX1BST1BTOiAoa2V5b2YgSG9vayB8ICdoYXNSZXNwb25zZScpW10gPSBbXG4gICdydW5JZCcsXG4gICdob29rSWQnLFxuICAnb3duZXJJZCcsXG4gICdjcmVhdGVkQXQnLFxuICAvLyAuLi5IT09LX0RBVEFfUFJPUFMsXG5dO1xuXG5pbnRlcmZhY2UgU2xlZXAge1xuICBjb3JyZWxhdGlvbklkOiBzdHJpbmc7XG4gIHJ1bklkOiBzdHJpbmc7XG4gIGV2ZW50SWQ6IHN0cmluZztcbiAgY3JlYXRlZEF0OiBEYXRlO1xuICByZXN1bWVBdDogRGF0ZSB8IHVuZGVmaW5lZDtcbiAgY29tcGxldGVkQXQ6IERhdGUgfCB1bmRlZmluZWQ7XG59XG5cbmNvbnN0IFdBSVRfTElTVEVEX1BST1BTOiAoa2V5b2YgU2xlZXApW10gPSBbXG4gICdjb3JyZWxhdGlvbklkJyxcbiAgJ2V2ZW50SWQnLFxuICAnY3JlYXRlZEF0JyxcbiAgJ3Jlc3VtZUF0JyxcbiAgJ2NvbXBsZXRlZEF0Jyxcbl07XG5cbmNvbnN0IFNUQVRVU19DT0xPUlM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogc3RyaW5nKSA9PiBzdHJpbmc+ID0ge1xuICBydW5uaW5nOiBjaGFsay5ibHVlLFxuICBjb21wbGV0ZWQ6IGNoYWxrLmdyZWVuLFxuICBmYWlsZWQ6IGNoYWxrLnJlZCxcbiAgY2FuY2VsbGVkOiBjaGFsay5zdHJpa2V0aHJvdWdoLnllbGxvdyxcbiAgcGVuZGluZzogY2hhbGsuYmx1ZSxcbiAgd2FpdGluZzogY2hhbGsuYmx1ZSxcbn07XG5cbmNvbnN0IGlzU3RyZWFtSWQgPSAodmFsdWU6IHN0cmluZykgPT4ge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS5zdGFydHNXaXRoKCdzdHJtXycpO1xufTtcblxuY29uc3Qgc2hvd1N0YXR1c0xlZ2VuZCA9ICgpID0+IHtcbiAgbG9nZ2VyLmxvZygnXFxuU3RhdHVzIExlZ2VuZDonKTtcbiAgY29uc3Qgc3RhdHVzZXMgPSBbXG4gICAgJ3J1bm5pbmcnLFxuICAgICdjb21wbGV0ZWQnLFxuICAgICdmYWlsZWQnLFxuICAgICdjYW5jZWxsZWQnLFxuICAgICdwZW5kaW5nJyxcbiAgICAnd2FpdGluZycsXG4gIF07XG5cbiAgY29uc3QgbGVnZW5kSXRlbXMgPSBzdGF0dXNlcy5tYXAoKHN0YXR1cykgPT4ge1xuICAgIGNvbnN0IGNvbG9yRnVuYyA9IFNUQVRVU19DT0xPUlNbc3RhdHVzXTtcbiAgICBjb25zdCBhYmJyZXYgPSBmb3JtYXRTdGF0dXNBYmJyZXYoc3RhdHVzLCB0cnVlKTtcbiAgICByZXR1cm4gYCR7Y29sb3JGdW5jKGFiYnJldil9ID0gJHtzdGF0dXN9YDtcbiAgfSk7XG5cbiAgbG9nZ2VyLmxvZyhgICAke2xlZ2VuZEl0ZW1zLmpvaW4oJyAgJyl9YCk7XG4gIGxvZ2dlci5sb2coJycpO1xufTtcblxuY29uc3QgaXNTbGVlcFN0ZXAgPSAoc3RlcE5hbWU6IHN0cmluZykgPT4ge1xuICByZXR1cm4gc3RlcE5hbWUuaW5jbHVkZXMoJy1zbGVlcCcpO1xufTtcblxuY29uc3QgY2hlY2tBbmRIYW5kbGVWZXJjZWxBY2Nlc3NFcnJvciA9IChcbiAgZXJyb3I6IHVua25vd24sXG4gIGJhY2tlbmQ/OiBzdHJpbmdcbik6IGJvb2xlYW4gPT4ge1xuICBpZiAoYmFja2VuZCA9PT0gJ3ZlcmNlbCcgJiYgZXJyb3IgJiYgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0Jykge1xuICAgIGNvbnN0IGVyciA9IGVycm9yIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIGlmIChlcnIuc3RhdHVzID09PSA0MDMpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihWRVJDRUxfNDAzX0VSUk9SX01FU1NBR0UpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmNvbnN0IGV4dHJhY3RFcnJvck1lc3NhZ2UgPSAoXG4gIGVycjogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChlcnIubWVzc2FnZSAmJiB0eXBlb2YgZXJyLm1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGVyci5tZXNzYWdlO1xuICB9XG5cbiAgaWYgKGVyci5ib2R5ICYmIHR5cGVvZiBlcnIuYm9keSA9PT0gJ29iamVjdCcpIHtcbiAgICBjb25zdCBib2R5ID0gZXJyLmJvZHkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgaWYgKGJvZHkubWVzc2FnZSAmJiB0eXBlb2YgYm9keS5tZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGJvZHkubWVzc2FnZTtcbiAgICB9XG4gICAgaWYgKGJvZHkuZXJyb3IgJiYgdHlwZW9mIGJvZHkuZXJyb3IgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gYm9keS5lcnJvcjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufTtcblxuY29uc3QgZ2V0UGFnZUluZm8gPSAocmVzdWx0OiB1bmtub3duKTogQW5hbHl0aWNzUGFnZUluZm8gfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoXG4gICAgdHlwZW9mIHJlc3VsdCAhPT0gJ29iamVjdCcgfHxcbiAgICByZXN1bHQgPT09IG51bGwgfHxcbiAgICAhKCdwYWdlSW5mbycgaW4gcmVzdWx0KVxuICApIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiAocmVzdWx0IGFzIHsgcGFnZUluZm8/OiBBbmFseXRpY3NQYWdlSW5mbyB9KS5wYWdlSW5mbztcbn07XG5cbmNvbnN0IGhhbmRsZUFwaUVycm9yID0gKGVycm9yOiB1bmtub3duLCBiYWNrZW5kPzogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gIC8vIEZpcnN0IGNoZWNrIGZvciBWZXJjZWwgYWNjZXNzIGVycm9yc1xuICBpZiAoY2hlY2tBbmRIYW5kbGVWZXJjZWxBY2Nlc3NFcnJvcihlcnJvciwgYmFja2VuZCkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChpc09ic2VydmFiaWxpdHlVcGdyYWRlUmVxdWlyZWRFcnJvcihlcnJvcikpIHtcbiAgICBsb2dnZXIuZXJyb3IoZ2V0T2JzZXJ2YWJpbGl0eVVwZ3JhZGVSZXF1aXJlZE1lc3NhZ2UoKSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBIYW5kbGUgb3RoZXIgSFRUUCBlcnJvcnNcbiAgaWYgKGVycm9yICYmIHR5cGVvZiBlcnJvciA9PT0gJ29iamVjdCcpIHtcbiAgICBjb25zdCBlcnIgPSBlcnJvciBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuICAgIC8vIEhhbmRsZSA0MDAgQmFkIFJlcXVlc3RcbiAgICBpZiAoZXJyLnN0YXR1cyA9PT0gNDAwKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0JhZCBSZXF1ZXN0OiBUaGUgcmVxdWVzdCB3YXMgaW52YWxpZC4nKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBleHRyYWN0RXJyb3JNZXNzYWdlKGVycik7XG4gICAgICBpZiAobWVzc2FnZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYERldGFpbHM6ICR7bWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBvdGhlciBIVFRQIGVycm9ycyAoNDA0LCA1MDAsIGV0Yy4pXG4gICAgaWYgKHR5cGVvZiBlcnIuc3RhdHVzID09PSAnbnVtYmVyJyAmJiBlcnIuc3RhdHVzID49IDQwMCkge1xuICAgICAgbG9nZ2VyLmVycm9yKGBIVFRQIEVycm9yICR7ZXJyLnN0YXR1c306ICR7Z2V0U3RhdHVzVGV4dChlcnIuc3RhdHVzKX1gKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBleHRyYWN0RXJyb3JNZXNzYWdlKGVycik7XG4gICAgICBpZiAobWVzc2FnZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYERldGFpbHM6ICR7bWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmNvbnN0IGdldFN0YXR1c1RleHQgPSAoc3RhdHVzOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBzdGF0dXNUZXh0czogUmVjb3JkPG51bWJlciwgc3RyaW5nPiA9IHtcbiAgICA0MDA6ICdCYWQgUmVxdWVzdCcsXG4gICAgNDAxOiAnVW5hdXRob3JpemVkJyxcbiAgICA0MDI6ICdQYXltZW50IFJlcXVpcmVkJyxcbiAgICA0MDM6ICdGb3JiaWRkZW4nLFxuICAgIDQwNDogJ05vdCBGb3VuZCcsXG4gICAgNDI5OiAnVG9vIE1hbnkgUmVxdWVzdHMnLFxuICAgIDUwMDogJ0ludGVybmFsIFNlcnZlciBFcnJvcicsXG4gICAgNTAyOiAnQmFkIEdhdGV3YXknLFxuICAgIDUwMzogJ1NlcnZpY2UgVW5hdmFpbGFibGUnLFxuICB9O1xuICByZXR1cm4gc3RhdHVzVGV4dHNbc3RhdHVzXSB8fCAnVW5rbm93biBFcnJvcic7XG59O1xuXG5jb25zdCB0cnVuY2F0ZU5hbWVJZk5lZWRlZCA9IChuYW1lOiBzdHJpbmcsIG1heExlbmd0aDogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgcmV0dXJuIG1heExlbmd0aCA8IG5hbWUubGVuZ3RoID8gYCR7bmFtZS5zdWJzdHJpbmcoMCwgbWF4TGVuZ3RoKX0uLi5gIDogbmFtZTtcbn07XG5cbmNvbnN0IGZvcm1hdE5hbWVGaWVsZCA9IChcbiAgbmFtZU5vblVuaXF1ZTogc3RyaW5nLFxuICB0cnVuY2F0ZUxlbmd0aDogbnVtYmVyLFxuICBpc1NsZWVwOiBib29sZWFuXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCB0cnVuY2F0ZWROYW1lID0gdHJ1bmNhdGVOYW1lSWZOZWVkZWQobmFtZU5vblVuaXF1ZSwgdHJ1bmNhdGVMZW5ndGgpO1xuICBpZiAoaXNTbGVlcCkge1xuICAgIHJldHVybiBjaGFsay55ZWxsb3dCcmlnaHQodHJ1bmNhdGVkTmFtZSk7XG4gIH1cbiAgcmV0dXJuIGNoYWxrLmJsdWUuYmx1ZUJyaWdodCh0cnVuY2F0ZWROYW1lKTtcbn07XG5cbmNvbnN0IGZvcm1hdElkRmllbGQgPSAoXG4gIHByb3A6IHN0cmluZyxcbiAgdmFsdWU6IHVua25vd24sXG4gIHNob3VsZFRydW5jYXRlSWRzOiBib29sZWFuXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4ge1xuICBjb25zdCB2YWx1ZVN0ciA9IFN0cmluZyh2YWx1ZSk7XG4gIGNvbnN0IGlkU3RyID0gc2hvdWxkVHJ1bmNhdGVJZHMgPyB0cnVuY2F0ZUlkVG9MYXN0Q2hhcnModmFsdWVTdHIpIDogdmFsdWVTdHI7XG4gIGlmIChwcm9wID09PSAnc3RyZWFtSWQnKSB7XG4gICAgcmV0dXJuIGNoYWxrLmdyZWVuKGlkU3RyKTtcbiAgfVxuICByZXR1cm4gaWRTdHI7XG59O1xuXG5leHBvcnQgY29uc3QgZm9ybWF0VGFibGVWYWx1ZSA9IChcbiAgcHJvcDogc3RyaW5nLFxuICB2YWx1ZTogdW5rbm93bixcbiAgb3B0czogSW5zcGVjdENMSU9wdGlvbnMgPSB7fSxcbiAgZGlzcGxheVNldHRpbmdzPzogUmV0dXJuVHlwZTx0eXBlb2YgZ2V0RGlzcGxheVNldHRpbmdzPixcbiAgaXRlbT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4pID0+IHtcbiAgY29uc3QgbmFtZXNUcnVuY2F0ZSA9IGRpc3BsYXlTZXR0aW5ncz8ubmFtZXNUcnVuY2F0ZUxlbmd0aCA/PyA0MDtcbiAgY29uc3Qgc2hvdWxkVHJ1bmNhdGVJZHMgPSBkaXNwbGF5U2V0dGluZ3M/LnRydW5jYXRlSWRzVG9MYXN0Q2hhcnMgPz8gZmFsc2U7XG5cbiAgLy8gSGFuZGxlIElEcyB3aXRoIHBvdGVudGlhbCB0cnVuY2F0aW9uXG4gIGlmIChcbiAgICBbXG4gICAgICAnc3RyZWFtSWQnLFxuICAgICAgJ3J1bklkJyxcbiAgICAgICdzdGVwSWQnLFxuICAgICAgJ2hvb2tJZCcsXG4gICAgICAnZXZlbnRJZCcsXG4gICAgICAnY29ycmVsYXRpb25JZCcsXG4gICAgICAnb3duZXJJZCcsXG4gICAgXS5pbmNsdWRlcyhwcm9wKVxuICApIHtcbiAgICByZXR1cm4gZm9ybWF0SWRGaWVsZChwcm9wLCB2YWx1ZSwgc2hvdWxkVHJ1bmNhdGVJZHMpO1xuICB9XG5cbiAgLy8gSGFuZGxlIG5hbWVzIHdpdGggdHJ1bmNhdGlvblxuICBpZiAocHJvcCA9PT0gJ3N0ZXBOYW1lJykge1xuICAgIGNvbnN0IG5hbWVOb25VbmlxdWUgPSBwYXJzZVN0ZXBOYW1lKFN0cmluZyh2YWx1ZSkpPy5zaG9ydE5hbWUgfHwgJz8nO1xuICAgIHJldHVybiBmb3JtYXROYW1lRmllbGQoXG4gICAgICBuYW1lTm9uVW5pcXVlLFxuICAgICAgbmFtZXNUcnVuY2F0ZSxcbiAgICAgIGlzU2xlZXBTdGVwKFN0cmluZyh2YWx1ZSkpXG4gICAgKTtcbiAgfVxuXG4gIGlmIChwcm9wID09PSAnd29ya2Zsb3dOYW1lJykge1xuICAgIGNvbnN0IG5hbWVOb25VbmlxdWUgPSBwYXJzZVdvcmtmbG93TmFtZShTdHJpbmcodmFsdWUpKT8uc2hvcnROYW1lIHx8ICc/JztcbiAgICBjb25zdCB0cnVuY2F0ZWROYW1lID0gdHJ1bmNhdGVOYW1lSWZOZWVkZWQobmFtZU5vblVuaXF1ZSwgbmFtZXNUcnVuY2F0ZSk7XG4gICAgcmV0dXJuIGNoYWxrLmJsdWUuYmx1ZUJyaWdodCh0cnVuY2F0ZWROYW1lKTtcbiAgfVxuXG4gIGlmIChwcm9wID09PSAnb3V0cHV0JyB8fCBwcm9wID09PSAnaW5wdXQnIHx8IHByb3AgPT09ICdlcnJvcicpIHtcbiAgICBpZiAoXG4gICAgICBpdGVtICYmXG4gICAgICAnZXhwaXJlZEF0JyBpbiBpdGVtICYmXG4gICAgICBpdGVtLmV4cGlyZWRBdCAhPSBudWxsICYmXG4gICAgICBuZXcgRGF0ZShpdGVtLmV4cGlyZWRBdCBhcyBzdHJpbmcgfCBudW1iZXIgfCBEYXRlKSA8IG5ldyBEYXRlKClcbiAgICApIHtcbiAgICAgIHJldHVybiBFWFBJUkVEX0RBVEFfTUVTU0FHRTtcbiAgICB9XG4gICAgcmV0dXJuIGlubGluZUZvcm1hdElPKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChwcm9wID09PSAnc3RhdHVzJykge1xuICAgIGNvbnN0IHN0YXR1cyA9IHZhbHVlIGFzIFdvcmtmbG93UnVuWydzdGF0dXMnXSB8IFN0ZXBbJ3N0YXR1cyddO1xuICAgIGNvbnN0IGNvbG9yRnVuYyA9XG4gICAgICBTVEFUVVNfQ09MT1JTW3N0YXR1c10gPz8gKChmb3JtYXR0ZWQ6IHN0cmluZykgPT4gZm9ybWF0dGVkKTtcbiAgICBjb25zdCBmb3JtYXR0ZWRTdGF0dXMgPSBkaXNwbGF5U2V0dGluZ3M/LmFiYnJldmlhdGVTdGF0dXNcbiAgICAgID8gZm9ybWF0U3RhdHVzQWJicmV2KHN0YXR1cywgdHJ1ZSlcbiAgICAgIDogc3RhdHVzO1xuICAgIHJldHVybiBjb2xvckZ1bmMoZm9ybWF0dGVkU3RhdHVzKTtcbiAgfVxuXG4gIGlmIChwcm9wID09PSAnZXZlbnREYXRhJykge1xuICAgIHJldHVybiB0cnVuY2F0ZVN0cmluZyhKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICB9XG5cbiAgaWYgKHByb3AgPT09ICdoYXNSZXNwb25zZScpIHtcbiAgICByZXR1cm4gdmFsdWUgPyBjaGFsay5ncmVlbigndHJ1ZScpIDogY2hhbGsuZ3JheSgnZmFsc2UnKTtcbiAgfVxuXG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICByZXR1cm4gZm9ybWF0VGFibGVUaW1lc3RhbXAodmFsdWUsIG9wdHMsIGRpc3BsYXlTZXR0aW5ncyk7XG4gIH1cblxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5jb25zdCBnZXRWaXNpYmxlUHJvcHMgPSAoXG4gIHByb3BzOiBzdHJpbmdbXSxcbiAgZGlzcGxheVNldHRpbmdzOiBSZXR1cm5UeXBlPHR5cGVvZiBnZXREaXNwbGF5U2V0dGluZ3M+XG4pOiBzdHJpbmdbXSA9PiB7XG4gIGlmIChkaXNwbGF5U2V0dGluZ3MuaGlkZUNvbXBsZXRlZEF0KSB7XG4gICAgcmV0dXJuIHByb3BzLmZpbHRlcigocHJvcCkgPT4gcHJvcCAhPT0gJ2NvbXBsZXRlZEF0Jyk7XG4gIH1cbiAgcmV0dXJuIHByb3BzO1xufTtcblxuY29uc3Qgc2hvd1RhYmxlID0gKFxuICBkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLFxuICBwcm9wczogc3RyaW5nW10sXG4gIG9wdHM6IEluc3BlY3RDTElPcHRpb25zID0ge31cbikgPT4ge1xuICAvLyBHZXQgZGlzcGxheSBzZXR0aW5ncyBiYXNlZCBvbiB0ZXJtaW5hbCB3aWR0aFxuICBjb25zdCB0ZXJtaW5hbFdpZHRoID0gZ2V0VGVybWluYWxXaWR0aCgpO1xuICBjb25zdCBkaXNwbGF5U2V0dGluZ3MgPSBnZXREaXNwbGF5U2V0dGluZ3MoXG4gICAgdGVybWluYWxXaWR0aCxcbiAgICBvcHRzLndpdGhEYXRhIHx8IGZhbHNlLFxuICAgIHByb3BzLmluY2x1ZGVzKCdydW5OYW1lJylcbiAgKTtcblxuICAvLyBGaWx0ZXIgb3V0IGNvbXBsZXRlZEF0IGNvbHVtbiBpZiBuZWVkZWRcbiAgY29uc3QgdmlzaWJsZVByb3BzID0gZ2V0VmlzaWJsZVByb3BzKHByb3BzLCBkaXNwbGF5U2V0dGluZ3MpO1xuXG4gIC8vIFVwZGF0ZSB0cnVuY2F0ZSBsZW5ndGggZm9yIElPIGZpZWxkc1xuICBjb25zdCBvcmlnaW5hbFRydW5jYXRlTGVuZ3RoID0gVEFCTEVfVFJVTkNBVEVfSU9fTEVOR1RIO1xuICBUQUJMRV9UUlVOQ0FURV9JT19MRU5HVEggPSBkaXNwbGF5U2V0dGluZ3MuZGF0YUZpZWxkV2lkdGg7XG5cbiAgLy8gU2hvdyBzdGF0dXMgbGVnZW5kIGlmIHVzaW5nIGFiYnJldmlhdGVkIHN0YXR1c1xuICBpZiAoXG4gICAgZGF0YS5sZW5ndGggPiAwICYmXG4gICAgZGlzcGxheVNldHRpbmdzLmFiYnJldmlhdGVTdGF0dXMgJiZcbiAgICB2aXNpYmxlUHJvcHMuaW5jbHVkZXMoJ3N0YXR1cycpXG4gICkge1xuICAgIHNob3dTdGF0dXNMZWdlbmQoKTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBoZWFkZXIgbWFwcGluZyBmb3IgYWJicmV2aWF0ZWQgc3RhdHVzXG4gIGNvbnN0IGhlYWRlck1hcDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBpZiAoZGlzcGxheVNldHRpbmdzLmFiYnJldmlhdGVTdGF0dXMgJiYgdmlzaWJsZVByb3BzLmluY2x1ZGVzKCdzdGF0dXMnKSkge1xuICAgIGhlYWRlck1hcFsnc3RhdHVzJ10gPSAnUyc7XG4gIH1cblxuICAvLyBBZGQgYSBibGFuayBsaW5lIGJlZm9yZSBhbnkgdGFibGVcbiAgY29uc3QgdGFibGUgPSBuZXcgVGFibGUoKTtcbiAgaWYgKGRhdGEgJiYgZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICBsb2dnZXIud2FybignTm8gZGF0YSBmb3VuZCBmb3IgdGhpcyBxdWVyeSBhbmQgcmVzb3VyY2UuXFxuJyk7XG4gICAgZm9yIChjb25zdCBwcm9wIG9mIHZpc2libGVQcm9wcykge1xuICAgICAgY29uc3QgaGVhZGVyID0gaGVhZGVyTWFwW3Byb3BdIHx8IHByb3A7XG4gICAgICB0YWJsZS5jZWxsKGhlYWRlciwgJ04vQScpO1xuICAgIH1cbiAgICB0YWJsZS5uZXdSb3coKTtcbiAgICAvLyBSZXN0b3JlIG9yaWdpbmFsIHRydW5jYXRlIGxlbmd0aFxuICAgIFRBQkxFX1RSVU5DQVRFX0lPX0xFTkdUSCA9IG9yaWdpbmFsVHJ1bmNhdGVMZW5ndGg7XG4gICAgcmV0dXJuIHRhYmxlLnRvU3RyaW5nKCk7XG4gIH0gZWxzZSBpZiAoIWRhdGEpIHtcbiAgICBsb2dnZXIud2FybignRXhwZWN0aW5nIGFuIGFycmF5IG9mIGRhdGEsIGJ1dCBnb3QgbnVsbC5cXG4nKTtcbiAgfVxuICBsb2dnZXIubG9nKCcnKTtcbiAgZm9yIChjb25zdCBpdGVtIG9mIGRhdGEpIHtcbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgdmlzaWJsZVByb3BzKSB7XG4gICAgICBjb25zdCBoZWFkZXIgPSBoZWFkZXJNYXBbcHJvcF0gfHwgcHJvcDtcbiAgICAgIGNvbnN0IHZhbHVlID0gaXRlbVtwcm9wXTtcbiAgICAgIHRhYmxlLmNlbGwoXG4gICAgICAgIGhlYWRlcixcbiAgICAgICAgZm9ybWF0VGFibGVWYWx1ZShwcm9wLCB2YWx1ZSwgb3B0cywgZGlzcGxheVNldHRpbmdzLCBpdGVtKVxuICAgICAgKTtcbiAgICB9XG4gICAgdGFibGUubmV3Um93KCk7XG4gIH1cblxuICAvLyBSZXN0b3JlIG9yaWdpbmFsIHRydW5jYXRlIGxlbmd0aFxuICBUQUJMRV9UUlVOQ0FURV9JT19MRU5HVEggPSBvcmlnaW5hbFRydW5jYXRlTGVuZ3RoO1xuICByZXR1cm4gdGFibGUudG9TdHJpbmcoKTtcbn07XG5cbmNvbnN0IHNob3dKc29uID0gKGRhdGE6IHVua25vd24pID0+IHtcbiAgY29uc3QganNvbiA9IEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpO1xuICBwcm9jZXNzLnN0ZG91dC53cml0ZShgJHtqc29ufVxcbmApO1xufTtcblxuY29uc3Qgc2hvd0pzb25QYWdlID0gPFQ+KHBhZ2U6IFBhZ2VEYXRhPFQ+KSA9PiB7XG4gIHNob3dKc29uKHtcbiAgICBkYXRhOiBwYWdlLmRhdGEsXG4gICAgY3Vyc29yOiBwYWdlLmN1cnNvcixcbiAgICBoYXNNb3JlOiBwYWdlLmhhc01vcmUsXG4gICAgLi4uKHBhZ2UucGFnZUluZm8gPyB7IHBhZ2VJbmZvOiBwYWdlLnBhZ2VJbmZvIH0gOiB7fSksXG4gIH0pO1xufTtcblxuLyoqXG4gKiBJbiB0YWJsZXMsIHdlIHdhbnQgdG8gc2hvdyBhIHNob3J0ZXIgdGltZXN0YW1wLCBZWVlZLU1NLUREIEhIOk1NOlNTXG4gKi9cbmNvbnN0IGZvcm1hdFRhYmxlVGltZXN0YW1wID0gKFxuICB2YWx1ZTogRGF0ZSxcbiAgb3B0czogSW5zcGVjdENMSU9wdGlvbnMgPSB7fSxcbiAgZGlzcGxheVNldHRpbmdzPzogUmV0dXJuVHlwZTx0eXBlb2YgZ2V0RGlzcGxheVNldHRpbmdzPlxuKSA9PiB7XG4gIC8vIEZvcm1hdCBJU08gdGltZSB3aXRob3V0IFQgYW5kIFpcbiAgY29uc3QgaXNvVGltZSA9IGZvcm1hdElTT0RhdGUodmFsdWUpO1xuXG4gIC8vIFNob3cgcmVsYXRpdmUgdGltZSBvbmx5IGlmOlxuICAvLyAtIE5vdCBpbiBDSSBtb2RlXG4gIC8vIC0gRGlzcGxheSBzZXR0aW5ncyBhbGxvdyBpdCAoYmFzZWQgb24gdGVybWluYWwgd2lkdGgpXG4gIC8vIC0gd2l0aERhdGEgaXMgZGlzYWJsZWQgKG1vcmUgc3BhY2UgYXZhaWxhYmxlKVxuICAvLyAtIE5vdCBpbiBKU09OIG1vZGVcbiAgLy8gLSBkaXNhYmxlUmVsYXRpdmVEYXRlcyBpcyBub3Qgc2V0XG4gIGNvbnN0IHNob3VsZFNob3dSZWxhdGl2ZSA9XG4gICAgIWlzQ0koKSAmJlxuICAgIGRpc3BsYXlTZXR0aW5ncz8uc2hvd1JlbGF0aXZlRGF0ZXMgIT09IGZhbHNlICYmXG4gICAgIW9wdHMud2l0aERhdGEgJiZcbiAgICAhb3B0cy5qc29uICYmXG4gICAgIW9wdHMuZGlzYWJsZVJlbGF0aXZlRGF0ZXM7XG5cbiAgaWYgKHNob3VsZFNob3dSZWxhdGl2ZSkge1xuICAgIGNvbnN0IHJlbGF0aXZlID0gZm9ybWF0RGlzdGFuY2UodmFsdWUsIG5ldyBEYXRlKCksIHsgYWRkU3VmZml4OiB0cnVlIH0pO1xuICAgIHJldHVybiBgJHtpc29UaW1lfSAoJHtyZWxhdGl2ZX0pYDtcbiAgfVxuXG4gIHJldHVybiBpc29UaW1lO1xufTtcblxuY29uc3QgdHJ1bmNhdGVTdHJpbmcgPSAoXG4gIHN0cjogc3RyaW5nLFxuICBtYXhMZW5ndGg6IG51bWJlciA9IFRBQkxFX1RSVU5DQVRFX0lPX0xFTkdUSFxuKSA9PiB7XG4gIHJldHVybiBzdHIgJiYgc3RyLmxlbmd0aCA+IG1heExlbmd0aFxuICAgID8gYCR7c3RyLnN1YnN0cmluZygwLCBtYXhMZW5ndGgpfS4uLmBcbiAgICA6IHN0cjtcbn07XG5cbmNvbnN0IHRydW5jYXRlSWRUb0xhc3RDaGFycyA9IChpZDogc3RyaW5nLCBjaGFyczogbnVtYmVyID0gNCk6IHN0cmluZyA9PiB7XG4gIGlmICghaWQgfHwgaWQubGVuZ3RoIDw9IGNoYXJzKSByZXR1cm4gaWQ7XG4gIHJldHVybiBgLi4uJHtpZC5zdWJzdHJpbmcoaWQubGVuZ3RoIC0gY2hhcnMpfWA7XG59O1xuXG5jb25zdCBzaG93SW5zcGVjdEluZm9Cb3ggPSAocmVzb3VyY2U6IHN0cmluZykgPT4ge1xuICBsb2dnZXIuaW5mbyhcbiAgICBgVG8gdmlldyBkZXRhaWxzIGZvciBhICR7cmVzb3VyY2V9LCB1c2UgXFxgd29ya2Zsb3cgaW5zcGVjdCAke3Jlc291cmNlfVxcYCA8aWQ+YFxuICApO1xuICBsb2dnZXIuaW5mbyhcbiAgICBgVG8gdmlldyB0aGUgY29udGVudCBvZiBhbnkgc3RyZWFtLCB1c2UgXFxgd29ya2Zsb3cgaW5zcGVjdCBzdHJlYW0gPHN0cmVhbS1pZD5cXGBgXG4gICk7XG59O1xuXG5jb25zdCBFWFBJUkVEX0RBVEFfTUVTU0FHRSA9IGNoYWxrLmdyYXkoJzxkYXRhIGV4cGlyZWQ+Jyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgcnVuIGhhcyBleHBpcmVkIGRhdGEgc3RvcmFnZSAocnVuLWxldmVsIGV4cGlyZWRBdCBmaWVsZCkuXG4gKiBPbmx5IHJldHVybnMgdHJ1ZSB3aGVuIGBleHBpcmVkQXRgIGlzIGluIHRoZSBwYXN0LlxuICovXG5leHBvcnQgY29uc3QgaGFzRXhwaXJlZERhdGEgPSAocnVuOiBXb3JrZmxvd1J1bik6IGJvb2xlYW4gPT4ge1xuICByZXR1cm4gKFxuICAgICdleHBpcmVkQXQnIGluIHJ1biAmJlxuICAgIHJ1bi5leHBpcmVkQXQgIT0gbnVsbCAmJlxuICAgIG5ldyBEYXRlKHJ1bi5leHBpcmVkQXQpIDwgbmV3IERhdGUoKVxuICApO1xufTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYW55IGRhdGEgZmllbGQgaW4gYSBoeWRyYXRlZCByZXNvdXJjZSBoYXMgYmVlbiByZXBsYWNlZCB3aXRoIGFuXG4gKiBleHBpcmVkIHBsYWNlaG9sZGVyLiBXb3JrcyBmb3IgcnVucywgc3RlcHMsIGhvb2tzLCBhbmQgZXZlbnRzIOKAlCB1bmxpa2VcbiAqIGBoYXNFeHBpcmVkRGF0YWAgd2hpY2ggb25seSBjaGVja3MgdGhlIHJ1bi1sZXZlbCBgZXhwaXJlZEF0YCBmaWVsZC5cbiAqL1xuY29uc3QgaGFzRXhwaXJlZEZpZWxkcyA9IChyZXNvdXJjZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBib29sZWFuID0+IHtcbiAgcmV0dXJuIFsnaW5wdXQnLCAnb3V0cHV0JywgJ2Vycm9yJywgJ21ldGFkYXRhJ10uc29tZSgoa2V5KSA9PlxuICAgIGlzRXhwaXJlZFJlZihyZXNvdXJjZVtrZXldKVxuICApO1xufTtcblxuLyoqXG4gKiBUYWtlcyBoeWRyYXRlZCBzdGVwL3dvcmtmbG93IGlucHV0L291dHB1dCBhbmQgc2VyaWFsaXplcyBpdCBmb3IgaW5saW5lIGRpc3BsYXkuXG4gKi9cbmNvbnN0IGlubGluZUZvcm1hdElPID0gPFQ+KGlvOiBULCB0b3BMZXZlbDogYm9vbGVhbiA9IHRydWUpOiBzdHJpbmcgPT4ge1xuICBjb25zdCB0eXBlID0gdHlwZW9mIGlvO1xuICBsZXQgdmFsdWUgPSAnJztcbiAgaWYgKGlvID09PSB1bmRlZmluZWQpIHtcbiAgICB2YWx1ZSA9ICc8ZW1wdHk+JztcbiAgfSBlbHNlIGlmIChpbyA9PT0gbnVsbCkge1xuICAgIHZhbHVlID0gJzxudWxsPic7XG4gIH0gZWxzZSBpZiAoaXNFbmNyeXB0ZWRSZWYoaW8pKSB7XG4gICAgdmFsdWUgPSBjaGFsay5kaW0ueWVsbG93KCdcXHV7MUY1MTJ9IEVuY3J5cHRlZCcpO1xuICB9IGVsc2UgaWYgKGlzRXhwaXJlZFJlZihpbykpIHtcbiAgICB2YWx1ZSA9IGNoYWxrLmdyYXkoJzxkYXRhIGV4cGlyZWQ+Jyk7XG4gIH0gZWxzZSBpZiAoaW8gJiYgQXJyYXkuaXNBcnJheShpbykpIHtcbiAgICBpZiAoaW8ubGVuZ3RoID09PSAwKSB7XG4gICAgICB2YWx1ZSA9ICc8ZW1wdHk+JztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgc3RyaW5naWZpZWQgPSBpb1xuICAgICAgICAubWFwKChpdGVtKSA9PiBpbmxpbmVGb3JtYXRJTyhpdGVtLCBmYWxzZSkpXG4gICAgICAgIC5qb2luKCcsJyk7XG4gICAgICBpZiAoc3RyaW5naWZpZWQubGVuZ3RoID4gVEFCTEVfVFJVTkNBVEVfSU9fTEVOR1RIICYmIHRvcExldmVsKSB7XG4gICAgICAgIHZhbHVlID0gY2hhbGsueWVsbG93KGAke2lvLmxlbmd0aH0gYXJnc2ApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSBzdHJpbmdpZmllZDtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICBpZiAoaW8gaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICB2YWx1ZSA9IGlvLnRvSVNPU3RyaW5nKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlID0gdHJ1bmNhdGVTdHJpbmcoSlNPTi5zdHJpbmdpZnkoaW8pKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoWydzdHJpbmcnLCAnbnVtYmVyJywgJ2Jvb2xlYW4nXS5pbmNsdWRlcyh0eXBlKSkge1xuICAgIGlmIChpc1N0cmVhbUlkKGlvIGFzIHN0cmluZykpIHtcbiAgICAgIHZhbHVlID0gaW8udG9TdHJpbmcoKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIChpbyBhcyBzdHJpbmcpLmluY2x1ZGVzKCdzdHJtXycpKSB7XG4gICAgICB2YWx1ZSA9IGlvIGFzIHN0cmluZztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgPSB0cnVuY2F0ZVN0cmluZyhTdHJpbmcoaW8pKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFsdWUgPSBgPCR7dHlwZX0+YDtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59O1xuXG4vKipcbiAqIExpc3Qgdmlld3Mgc3VyZmFjZSBtZXRhZGF0YSBvbmx5LiBXaGVuIHRoZSBhY3RpdmUgYmFja2VuZCBleHBvc2VzIHRoZVxuICogb3B0aW9uYWwgYHdvcmxkLmFuYWx5dGljc2AgcmVhZCBuYW1lc3BhY2Ugd2UgcmVhZCBsaXN0IHBhZ2VzIGZyb20gaXRcbiAqIChtZXRhZGF0YS1vbmx5IOKAlCBubyBwYXlsb2FkIHJlc29sdXRpb24pOyBvdGhlcndpc2Ugd2UgZmFsbCBiYWNrIHRvIHRoZVxuICogcnVudGltZSBzdG9yYWdlIEFQSXMgd2l0aCBgcmVzb2x2ZURhdGE6ICdub25lJ2AuXG4gKlxuICogYC0td2l0aERhdGFgIGZvcmNlcyB0aGUgcnVudGltZSBwYXRoIHNvIHBheWxvYWRzIGNhbiBiZSByZXNvbHZlZCBpbnRvIHRoZVxuICogdGFibGUuIEl0IGlzIGRlcHJlY2F0ZWQgZm9yIGxpc3Qgdmlld3M6IHZpZXcgcGF5bG9hZHMgcGVyLXJlc291cmNlIHdpdGhcbiAqIGB3b3JrZmxvdyBpbnNwZWN0IDxyZXNvdXJjZT4gPGlkPmAuXG4gKi9cbmNvbnN0IHdhcm5XaXRoRGF0YURlcHJlY2F0ZWRGb3JMaXN0ID0gKHNpbmd1bGFyOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgbG9nZ2VyLndhcm4oXG4gICAgYCctLXdpdGhEYXRhJyBpcyBkZXByZWNhdGVkIGZvciBsaXN0IHZpZXdzIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgcmVsZWFzZS4gVXNlICd3b3JrZmxvdyBpbnNwZWN0ICR7c2luZ3VsYXJ9IDxpZD4nIHRvIHZpZXcgcGF5bG9hZHMgZm9yIGEgc2luZ2xlICR7c2luZ3VsYXJ9LmBcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBsaXN0UnVucyA9IGFzeW5jICh3b3JsZDogV29ybGQsIG9wdHM6IEluc3BlY3RDTElPcHRpb25zID0ge30pID0+IHtcbiAgY29uc3QgcmVzb2x2ZUtleSA9IGNyZWF0ZVJlc29sdmVyKHdvcmxkLCBvcHRzPy5kZWNyeXB0ID8/IGZhbHNlKTtcblxuICBpZiAob3B0cy5zdGVwSWQgfHwgb3B0cy5ydW5JZCkge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJ0ZpbHRlcmluZyBieSBzdGVwLWlkIG9yIHJ1bi1pZCBpcyBub3Qgc3VwcG9ydGVkIGluIGxpc3QgY2FsbHMsIGlnbm9yaW5nIGZpbHRlci4nXG4gICAgKTtcbiAgfVxuXG4gIGlmIChvcHRzLndpdGhEYXRhKSB7XG4gICAgd2FybldpdGhEYXRhRGVwcmVjYXRlZEZvckxpc3QoJ3J1bicpO1xuICB9XG5cbiAgY29uc3QgdXNlQW5hbHl0aWNzID0gIW9wdHMud2l0aERhdGEgJiYgQm9vbGVhbih3b3JsZC5hbmFseXRpY3MpO1xuICBjb25zdCByZXNvbHZlRGF0YSA9IG9wdHMud2l0aERhdGEgPyAnYWxsJyA6ICdub25lJztcbiAgY29uc3Qgc3RhdHVzID0gb3B0cy5zdGF0dXM7XG5cbiAgLy8gUmVzb2x2ZSAtLXNpbmNlLy0tdW50aWwgaW50byBhbiBleHBsaWNpdCBsaXN0aW5nIHdpbmRvdy4gT25seSB0aGVcbiAgLy8gYW5hbHl0aWNzIHJlYWQgcGF0aCBzdXBwb3J0cyBvbmU7IHRoZSBydW50aW1lIHN0b3JhZ2UgQVBJcyBoYXZlIG5vIHRpbWVcbiAgLy8gZmlsdGVyLiBXaXRob3V0IHRoZSBmbGFncyB0aGUgYmFja2VuZCBhcHBsaWVzIGl0cyBkZWZhdWx0IHdpbmRvd1xuICAvLyAodHJhaWxpbmcgMjRoIG9uIHRoZSBWZXJjZWwgYmFja2VuZCkuXG4gIGNvbnN0IHRpbWVXaW5kb3cgPSByZXNvbHZlVGltZVdpbmRvdyhvcHRzKTtcbiAgaWYgKHRpbWVXaW5kb3cgJiYgIXVzZUFuYWx5dGljcykge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJy0tc2luY2UvLS11bnRpbCByZXF1aXJlIHRoZSBhbmFseXRpY3MgcmVhZCBwYXRoIGFuZCBhcmUgaWdub3JlZCBieSB0aGlzIGJhY2tlbmQuJ1xuICAgICk7XG4gIH1cblxuICAvLyBEZXRlcm1pbmUgd2hpY2ggcHJvcHMgdG8gc2hvdyBiYXNlZCBvbiB3aXRoRGF0YSBmbGFnXG4gIGNvbnN0IHByb3BzID0gb3B0cy53aXRoRGF0YVxuICAgID8gV09SS0ZMT1dfUlVOX0xJU1RFRF9QUk9QU1xuICAgIDogV09SS0ZMT1dfUlVOX0xJU1RFRF9QUk9QUy5maWx0ZXIoXG4gICAgICAgIChwcm9wKSA9PiAhV09SS0ZMT1dfUlVOX0lPX1BST1BTLmluY2x1ZGVzKHByb3ApXG4gICAgICApO1xuXG4gIGNvbnN0IGZldGNoUnVuc1BhZ2UgPSBhc3luYyAoXG4gICAgY3Vyc29yOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgKTogUHJvbWlzZTxQYWdlRGF0YTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4+ID0+IHtcbiAgICBjb25zdCBwYWdpbmF0aW9uID0ge1xuICAgICAgc29ydE9yZGVyOiBvcHRzLnNvcnQgfHwgJ2Rlc2MnLFxuICAgICAgY3Vyc29yLFxuICAgICAgbGltaXQ6IG9wdHMubGltaXQgfHwgREVGQVVMVF9QQUdFX1NJWkUsXG4gICAgfTtcbiAgICBpZiAodXNlQW5hbHl0aWNzICYmIHdvcmxkLmFuYWx5dGljcykge1xuICAgICAgY29uc3QgcnVucyA9IGF3YWl0IHdvcmxkLmFuYWx5dGljcy5ydW5zLmxpc3Qoe1xuICAgICAgICB3b3JrZmxvd05hbWU6IG9wdHMud29ya2Zsb3dOYW1lLFxuICAgICAgICBzdGF0dXMsXG4gICAgICAgIC4uLih0aW1lV2luZG93ID8/IHt9KSxcbiAgICAgICAgcGFnaW5hdGlvbixcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGF0YTogcnVucy5kYXRhIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSxcbiAgICAgICAgY3Vyc29yOiBydW5zLmN1cnNvcixcbiAgICAgICAgaGFzTW9yZTogcnVucy5oYXNNb3JlLFxuICAgICAgICBwYWdlSW5mbzogZ2V0UGFnZUluZm8ocnVucyksXG4gICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBydW5zID0gYXdhaXQgd29ybGQucnVucy5saXN0KHtcbiAgICAgIHdvcmtmbG93TmFtZTogb3B0cy53b3JrZmxvd05hbWUsXG4gICAgICBzdGF0dXMsXG4gICAgICBwYWdpbmF0aW9uLFxuICAgICAgcmVzb2x2ZURhdGEsXG4gICAgfSk7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgcnVucy5kYXRhLm1hcCgocikgPT4gaHlkcmF0ZVJlc291cmNlSU8ociwgcmVzb2x2ZUtleSkpXG4gICAgKTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogZGF0YSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sXG4gICAgICBjdXJzb3I6IHJ1bnMuY3Vyc29yLFxuICAgICAgaGFzTW9yZTogcnVucy5oYXNNb3JlLFxuICAgICAgcGFnZUluZm86IGdldFBhZ2VJbmZvKHJ1bnMpLFxuICAgIH07XG4gIH07XG5cbiAgLy8gRm9yIEpTT04gb3V0cHV0LCBqdXN0IGZldGNoIG9uY2UgYW5kIHJldHVyblxuICBpZiAob3B0cy5qc29uKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBmZXRjaFJ1bnNQYWdlKG9wdHMuY3Vyc29yKTtcbiAgICAgIHNob3dKc29uUGFnZShwYWdlKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGhhbmRsZUFwaUVycm9yKGVycm9yLCBvcHRzLmJhY2tlbmQpKSB7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGF3YWl0IHNldHVwTGlzdFBhZ2luYXRpb248UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KHtcbiAgICBpbml0aWFsQ3Vyc29yOiBvcHRzLmN1cnNvcixcbiAgICBpbnRlcmFjdGl2ZTogb3B0cy5pbnRlcmFjdGl2ZSxcbiAgICBmZXRjaFBhZ2U6IGFzeW5jIChjdXJzb3IpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmZXRjaFJ1bnNQYWdlKGN1cnNvcik7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfSxcbiAgICBkaXNwbGF5UGFnZTogYXN5bmMgKHJ1bnMpID0+IHtcbiAgICAgIGxvZ2dlci5sb2coc2hvd1RhYmxlKHJ1bnMsIHByb3BzLCBvcHRzKSk7XG4gICAgfSxcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0UmVjZW50UnVuID0gYXN5bmMgKFxuICB3b3JsZDogV29ybGQsXG4gIG9wdHM6IEluc3BlY3RDTElPcHRpb25zID0ge31cbikgPT4ge1xuICBjb25zdCByZXNvbHZlS2V5ID0gY3JlYXRlUmVzb2x2ZXIod29ybGQsIG9wdHM/LmRlY3J5cHQgPz8gZmFsc2UpO1xuXG4gIGxvZ2dlci53YXJuKGBObyBydW5JZCBwcm92aWRlZCwgZmV0Y2hpbmcgZGF0YSBmb3IgbGF0ZXN0IHJ1biBpbnN0ZWFkLmApO1xuICB0cnkge1xuICAgIGNvbnN0IHJ1bnMgPSBhd2FpdCB3b3JsZC5ydW5zLmxpc3Qoe1xuICAgICAgcGFnaW5hdGlvbjogeyBsaW1pdDogMSwgc29ydE9yZGVyOiBvcHRzLnNvcnQgfHwgJ2Rlc2MnIH0sXG4gICAgICByZXNvbHZlRGF0YTogJ25vbmUnLCAvLyBEb24ndCBuZWVkIGRhdGEgZm9yIGp1c3QgZ2V0dGluZyB0aGUgSURcbiAgICB9KTtcbiAgICBydW5zLmRhdGEgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHJ1bnMuZGF0YS5tYXAoKHIpID0+IGh5ZHJhdGVSZXNvdXJjZUlPKHIsIHJlc29sdmVLZXkpKVxuICAgICk7XG4gICAgcmV0dXJuIHJ1bnMuZGF0YVswXTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzaG93UnVuID0gYXN5bmMgKFxuICB3b3JsZDogV29ybGQsXG4gIHJ1bklkOiBzdHJpbmcsXG4gIG9wdHM6IEluc3BlY3RDTElPcHRpb25zID0ge31cbikgPT4ge1xuICBjb25zdCByZXNvbHZlS2V5ID0gY3JlYXRlUmVzb2x2ZXIod29ybGQsIG9wdHM/LmRlY3J5cHQgPz8gZmFsc2UpO1xuXG4gIGlmIChvcHRzLndpdGhEYXRhKSB7XG4gICAgbG9nZ2VyLndhcm4oJ2B3aXRoRGF0YWAgZmxhZyBpcyBpZ25vcmVkIHdoZW4gc2hvd2luZyBpbmRpdmlkdWFsIHJlc291cmNlcycpO1xuICB9XG4gIHRyeSB7XG4gICAgY29uc3QgcnVuID0gYXdhaXQgd29ybGQucnVucy5nZXQocnVuSWQsIHsgcmVzb2x2ZURhdGE6ICdhbGwnIH0pO1xuICAgIGNvbnN0IHJ1bldpdGhIeWRyYXRlZElPID0gYXdhaXQgaHlkcmF0ZVJlc291cmNlSU8ocnVuLCByZXNvbHZlS2V5KTtcbiAgICBpZiAob3B0cy5qc29uKSB7XG4gICAgICBzaG93SnNvbihydW5XaXRoSHlkcmF0ZWRJTyk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChoYXNFeHBpcmVkRGF0YShydW4pKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgIFwiVGhpcyBydW4ncyBkYXRhIChpbnB1dC9vdXRwdXQvZXJyb3IpIGhhcyBleHBpcmVkIGFuZCBpcyBubyBsb25nZXIgYXZhaWxhYmxlLlwiXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBsb2dnZXIubG9nKHJ1bldpdGhIeWRyYXRlZElPKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGhhbmRsZUFwaUVycm9yKGVycm9yLCBvcHRzLmJhY2tlbmQpKSB7XG4gICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgbGlzdFN0ZXBzID0gYXN5bmMgKFxuICB3b3JsZDogV29ybGQsXG4gIG9wdHM6IEluc3BlY3RDTElPcHRpb25zID0ge1xuICAgIHJ1bklkOiB1bmRlZmluZWQsXG4gIH1cbikgPT4ge1xuICBjb25zdCByZXNvbHZlS2V5ID0gY3JlYXRlUmVzb2x2ZXIod29ybGQsIG9wdHM/LmRlY3J5cHQgPz8gZmFsc2UpO1xuXG4gIGlmIChvcHRzLnN0ZXBJZCkge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJ0ZpbHRlcmluZyBieSBzdGVwLWlkIGlzIG5vdCBzdXBwb3J0ZWQgaW4gbGlzdCBjYWxscywgaWdub3JpbmcgZmlsdGVyLidcbiAgICApO1xuICB9XG4gIGlmIChvcHRzLndvcmtmbG93TmFtZSkge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJ0ZpbHRlcmluZyBieSB3b3JrZmxvdy1uYW1lIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHN0ZXBzLCBpZ25vcmluZyBmaWx0ZXIuJ1xuICAgICk7XG4gIH1cblxuICBjb25zdCBydW5JZCA9IG9wdHMucnVuSWRcbiAgICA/IG9wdHMucnVuSWRcbiAgICA6IChhd2FpdCBnZXRSZWNlbnRSdW4od29ybGQsIG9wdHMpKT8ucnVuSWQ7XG4gIGlmICghcnVuSWQpIHtcbiAgICBsb2dnZXIuZXJyb3IoJ05vIHJ1biBmb3VuZC4nKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAob3B0cy53aXRoRGF0YSkge1xuICAgIHdhcm5XaXRoRGF0YURlcHJlY2F0ZWRGb3JMaXN0KCdzdGVwJyk7XG4gIH1cblxuICBjb25zdCB1c2VBbmFseXRpY3MgPSAhb3B0cy53aXRoRGF0YSAmJiBCb29sZWFuKHdvcmxkLmFuYWx5dGljcyk7XG4gIGNvbnN0IHJlc29sdmVEYXRhID0gb3B0cy53aXRoRGF0YSA/ICdhbGwnIDogJ25vbmUnO1xuXG4gIC8vIERldGVybWluZSB3aGljaCBwcm9wcyB0byBzaG93IGJhc2VkIG9uIHdpdGhEYXRhIGZsYWdcbiAgY29uc3QgcHJvcHMgPSBvcHRzLndpdGhEYXRhXG4gICAgPyBTVEVQX0xJU1RFRF9QUk9QU1xuICAgIDogU1RFUF9MSVNURURfUFJPUFMuZmlsdGVyKChwcm9wKSA9PiAhU1RFUF9JT19QUk9QUy5pbmNsdWRlcyhwcm9wKSk7XG5cbiAgY29uc3QgZmV0Y2hTdGVwc1BhZ2UgPSBhc3luYyAoXG4gICAgY3Vyc29yOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgKTogUHJvbWlzZTxQYWdlRGF0YTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4+ID0+IHtcbiAgICBsb2dnZXIuZGVidWcoYEZldGNoaW5nIHN0ZXBzIGZvciBydW4gJHtydW5JZH1gKTtcbiAgICBjb25zdCBwYWdpbmF0aW9uID0ge1xuICAgICAgc29ydE9yZGVyOiBvcHRzLnNvcnQgfHwgJ2Rlc2MnLFxuICAgICAgY3Vyc29yLFxuICAgICAgbGltaXQ6IG9wdHMubGltaXQgfHwgREVGQVVMVF9QQUdFX1NJWkUsXG4gICAgfTtcbiAgICBpZiAodXNlQW5hbHl0aWNzICYmIHdvcmxkLmFuYWx5dGljcykge1xuICAgICAgY29uc3Qgc3RlcHMgPSBhd2FpdCB3b3JsZC5hbmFseXRpY3Muc3RlcHMubGlzdCh7IHJ1bklkLCBwYWdpbmF0aW9uIH0pO1xuICAgICAgY29uc3QgcGFnZSA9IHtcbiAgICAgICAgZGF0YTogc3RlcHMuZGF0YSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sXG4gICAgICAgIGN1cnNvcjogc3RlcHMuY3Vyc29yLFxuICAgICAgICBoYXNNb3JlOiBzdGVwcy5oYXNNb3JlLFxuICAgICAgICBwYWdlSW5mbzogZ2V0UGFnZUluZm8oc3RlcHMpLFxuICAgICAgfTtcbiAgICAgIGlmIChjdXJzb3IgfHwgcGFnZS5kYXRhLmxlbmd0aCA+IDAgfHwgcGFnZS5oYXNNb3JlKSB7XG4gICAgICAgIHJldHVybiBwYWdlO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgTm8gYW5hbHl0aWNzIHN0ZXBzIGZvdW5kIGZvciBydW4gJHtydW5JZH07IGZhbGxpbmcgYmFjayB0byBzdG9yYWdlYFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3Qgc3RlcENodW5rcyA9IGF3YWl0IHdvcmxkLnN0ZXBzLmxpc3Qoe1xuICAgICAgcnVuSWQsXG4gICAgICBwYWdpbmF0aW9uLFxuICAgICAgcmVzb2x2ZURhdGEsXG4gICAgfSk7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgc3RlcENodW5rcy5kYXRhLm1hcCgocykgPT4gaHlkcmF0ZVJlc291cmNlSU8ocywgcmVzb2x2ZUtleSkpXG4gICAgKTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogZGF0YSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sXG4gICAgICBjdXJzb3I6IHN0ZXBDaHVua3MuY3Vyc29yLFxuICAgICAgaGFzTW9yZTogc3RlcENodW5rcy5oYXNNb3JlLFxuICAgICAgcGFnZUluZm86IGdldFBhZ2VJbmZvKHN0ZXBDaHVua3MpLFxuICAgIH07XG4gIH07XG5cbiAgLy8gRm9yIEpTT04gb3V0cHV0LCBqdXN0IGZldGNoIG9uY2UgYW5kIHJldHVyblxuICBpZiAob3B0cy5qc29uKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBmZXRjaFN0ZXBzUGFnZShvcHRzLmN1cnNvcik7XG4gICAgICBzaG93SnNvbihwYWdlLmRhdGEpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgYXdhaXQgc2V0dXBMaXN0UGFnaW5hdGlvbjxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oe1xuICAgIGluaXRpYWxDdXJzb3I6IG9wdHMuY3Vyc29yLFxuICAgIGludGVyYWN0aXZlOiBvcHRzLmludGVyYWN0aXZlLFxuICAgIGZldGNoUGFnZTogYXN5bmMgKGN1cnNvcikgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGZldGNoU3RlcHNQYWdlKGN1cnNvcik7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfSxcbiAgICBkaXNwbGF5UGFnZTogYXN5bmMgKHN0ZXBzKSA9PiB7XG4gICAgICBsb2dnZXIubG9nKHNob3dUYWJsZShzdGVwcywgcHJvcHMsIG9wdHMpKTtcbiAgICAgIHNob3dJbnNwZWN0SW5mb0JveCgnc3RlcCcpO1xuICAgIH0sXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHNob3dTdGVwID0gYXN5bmMgKFxuICB3b3JsZDogV29ybGQsXG4gIHN0ZXBJZDogc3RyaW5nLFxuICBvcHRzOiBJbnNwZWN0Q0xJT3B0aW9ucyA9IHt9XG4pID0+IHtcbiAgY29uc3QgcmVzb2x2ZUtleSA9IGNyZWF0ZVJlc29sdmVyKHdvcmxkLCBvcHRzPy5kZWNyeXB0ID8/IGZhbHNlKTtcblxuICBpZiAob3B0cy53aXRoRGF0YSkge1xuICAgIGxvZ2dlci53YXJuKCdgd2l0aERhdGFgIGZsYWcgaXMgaWdub3JlZCB3aGVuIHNob3dpbmcgaW5kaXZpZHVhbCByZXNvdXJjZXMnKTtcbiAgfVxuICBpZiAob3B0cy5zdGVwSWQpIHtcbiAgICBsb2dnZXIud2FybihcbiAgICAgICdGaWx0ZXJpbmcgYnkgc3RlcC1pZCBpcyBub3Qgc3VwcG9ydGVkIGluIGdldCBjYWxscywgaWdub3JpbmcgZmlsdGVyLidcbiAgICApO1xuICB9XG5cbiAgY29uc3QgcnVuSWQgPSBvcHRzLnJ1bklkID8/IChhd2FpdCBnZXRSZWNlbnRSdW4od29ybGQsIG9wdHMpKT8ucnVuSWQ7XG4gIGlmICghcnVuSWQpIHtcbiAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAncnVuLWlkIGlzIHJlcXVpcmVkIGZvciBzaG93aW5nIGEgc3RlcC4gVXNhZ2U6IGB3b3JrZmxvdyBpbnNwZWN0IHN0ZXAgPFNURVBfSUQ+IC0tcnVuSWQ9PFJVTl9JRD5gJ1xuICAgICk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBzdGVwID0gYXdhaXQgd29ybGQuc3RlcHMuZ2V0KHJ1bklkLCBzdGVwSWQsIHtcbiAgICAgIHJlc29sdmVEYXRhOiAnYWxsJyxcbiAgICB9KTtcbiAgICBjb25zdCBzdGVwV2l0aEh5ZHJhdGVkSU8gPSBhd2FpdCBoeWRyYXRlUmVzb3VyY2VJTyhzdGVwLCByZXNvbHZlS2V5KTtcbiAgICBpZiAob3B0cy5qc29uKSB7XG4gICAgICBzaG93SnNvbihzdGVwV2l0aEh5ZHJhdGVkSU8pO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoXG4gICAgICAgIGhhc0V4cGlyZWRGaWVsZHMoXG4gICAgICAgICAgc3RlcFdpdGhIeWRyYXRlZElPIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgIFwiVGhpcyBzdGVwJ3MgZGF0YSAoaW5wdXQvb3V0cHV0L2Vycm9yKSBoYXMgZXhwaXJlZCBhbmQgaXMgbm8gbG9uZ2VyIGF2YWlsYWJsZS5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmxvZyhzdGVwV2l0aEh5ZHJhdGVkSU8pO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzaG93U3RyZWFtID0gYXN5bmMgKFxuICB3b3JsZDogV29ybGQsXG4gIHN0cmVhbUlkOiBzdHJpbmcsXG4gIG9wdHM6IEluc3BlY3RDTElPcHRpb25zID0ge31cbikgPT4ge1xuICBpZiAob3B0cy5zdGVwSWQpIHtcbiAgICBsb2dnZXIud2FybihcbiAgICAgICdGaWx0ZXJpbmcgYnkgc3RlcC1pZCBpcyBub3Qgc3VwcG9ydGVkIHdoZW4gc2hvd2luZyBhIHN0cmVhbSwgaWdub3JpbmcgZmlsdGVyLidcbiAgICApO1xuICB9XG4gIGlmICghb3B0cy5ydW5JZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignLS1ydW4gaXMgcmVxdWlyZWQgd2hlbiBzaG93aW5nIGEgc3RyZWFtJyk7XG4gIH1cbiAgY29uc3QgcmF3U3RyZWFtID0gYXdhaXQgd29ybGQuc3RyZWFtcy5nZXQob3B0cy5ydW5JZCwgc3RyZWFtSWQpO1xuXG4gIC8vIE9ubHkgcmVzb2x2ZSB0aGUgZW5jcnlwdGlvbiBrZXkgd2hlbiAtLWRlY3J5cHQgaXMgcGFzc2VkIGFuZCAtLXJ1biBpcyBwcm92aWRlZC5cbiAgLy8gV2UgZmV0Y2ggdGhlIGZ1bGwgV29ya2Zsb3dSdW4gb2JqZWN0IHNvIHRoYXQgZ2V0RW5jcnlwdGlvbktleUZvclJ1biBoYXNcbiAgLy8gYWNjZXNzIHRvIHRoZSBkZXBsb3ltZW50SWQgKG5lZWRlZCBmb3IgQVBJLWJhc2VkIGtleSByZXNvbHV0aW9uKS5cbiAgbGV0IGVuY3J5cHRpb25LZXk6IEVuY3J5cHRpb25LZXlQYXJhbTtcbiAgaWYgKG9wdHMuZGVjcnlwdCAmJiBvcHRzLnJ1bklkKSB7XG4gICAgZW5jcnlwdGlvbktleSA9IChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBydW4gPSBhd2FpdCB3b3JsZC5ydW5zLmdldChvcHRzLnJ1bklkISk7XG4gICAgICBjb25zdCByYXdLZXkgPSBhd2FpdCB3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuPy4ocnVuKTtcbiAgICAgIHJldHVybiByYXdLZXkgPyBhd2FpdCBpbXBvcnRLZXkocmF3S2V5KSA6IHVuZGVmaW5lZDtcbiAgICB9KSgpO1xuICB9IGVsc2UgaWYgKG9wdHMuZGVjcnlwdCAmJiAhb3B0cy5ydW5JZCkge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJ0Nhbm5vdCBkZWNyeXB0IHN0cmVhbSBjb250ZW50IHdpdGhvdXQgYSBydW4gSUQuIFVzZSAtLXJ1bj08cnVuLWlkPiB3aXRoIC0tZGVjcnlwdC4nXG4gICAgKTtcbiAgfVxuXG4gIC8vIERlc2VyaWFsaXplIHRoZSBzdHJlYW0gdG8gZ2V0IEphdmFTY3JpcHQgb2JqZWN0c1xuICBjb25zdCByZXZpdmVycyA9IGdldEV4dGVybmFsUmV2aXZlcnMoXG4gICAgZ2xvYmFsVGhpcyxcbiAgICBbXSxcbiAgICBvcHRzLnJ1bklkID8/ICcnLFxuICAgIGVuY3J5cHRpb25LZXlcbiAgKTtcbiAgY29uc3QgdHJhbnNmb3JtID0gZ2V0RGVzZXJpYWxpemVTdHJlYW0ocmV2aXZlcnMsIGVuY3J5cHRpb25LZXkpO1xuICBjb25zdCBzdHJlYW0gPSByYXdTdHJlYW0ucGlwZVRocm91Z2godHJhbnNmb3JtKTtcblxuICBsb2dnZXIuaW5mbygnU3RyZWFtaW5nIHRvIHN0ZG91dCwgcHJlc3MgQ1RSTCtDIHRvIGFib3J0LicpO1xuICBsb2dnZXIuaW5mbyhcbiAgICAnVXNlIC0tanNvbiB0byBvdXRwdXQgdGhlIHN0cmVhbSBhcyBuZXdsaW5lLWRlbGltaXRlZCBKU09OIHdpdGhvdXQgaW5mbyBsb2dzLlxcbidcbiAgKTtcbiAgYXdhaXQgc3RyZWFtVG9Db25zb2xlKHN0cmVhbSwgc3RyZWFtSWQsIG9wdHMpO1xufTtcblxuLyoqXG4gKiBMaXN0aW5nIHN0cmVhbXMgb25seSBsaXN0cyBhdmFpbGFibGUgc3RyZWFtIElEcyBiYXNlZCBvbiBydW4vc3RlcCBwYXNzZWQsXG4gKiBhbmQgZG9lc24ndCByZWFkIGFueSBkYXRhIGZyb20gdGhlIHN0cmVhbXMuXG4gKi9cbmV4cG9ydCBjb25zdCBsaXN0U3RyZWFtc0J5UnVuSWQgPSBhc3luYyAoXG4gIHdvcmxkOiBXb3JsZCxcbiAgb3B0czogSW5zcGVjdENMSU9wdGlvbnMgPSB7fVxuKSA9PiB7XG4gIGlmIChvcHRzLndpdGhEYXRhKSB7XG4gICAgbG9nZ2VyLndhcm4oJ2B3aXRoRGF0YWAgZmxhZyBpcyBpZ25vcmVkIHdoZW4gbGlzdGluZyBzdHJlYW1zJyk7XG4gIH1cbiAgaWYgKG9wdHMud29ya2Zsb3dOYW1lKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICAnRmlsdGVyaW5nIGJ5IHdvcmtmbG93LW5hbWUgaXMgbm90IHN1cHBvcnRlZCBmb3Igc3RyZWFtcywgaWdub3JpbmcgZmlsdGVyLidcbiAgICApO1xuICB9XG4gIGlmIChvcHRzLnN0ZXBJZCkge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJ0ZpbHRlcmluZyBieSBzdGVwLWlkIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHN0cmVhbXMsIGlnbm9yaW5nIGZpbHRlci4nXG4gICAgKTtcbiAgfVxuXG4gIGxldCBydW5JZCA9IG9wdHMucnVuSWQ7XG4gIGlmICghcnVuSWQpIHtcbiAgICBsb2dnZXIud2FybihcbiAgICAgICdObyBydW4taWQgcHJvdmlkZWQuIExpc3Rpbmcgc3RyZWFtcyBmb3IgbGF0ZXN0IHJ1biBpbnN0ZWFkLicsXG4gICAgICAnVXNlIC0tcnVuPTxydW4taWQ+IHRvIGZpbHRlciBzdHJlYW1zIGJ5IHJ1bi4nXG4gICAgKTtcbiAgICBjb25zdCBydW4gPSBhd2FpdCBnZXRSZWNlbnRSdW4od29ybGQsIG9wdHMpO1xuICAgIGlmICghcnVuKSB7XG4gICAgICBsb2dnZXIud2FybignTm8gcnVucyBmb3VuZC4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcnVuSWQgPSBydW4ucnVuSWQ7XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IHN0cmVhbUlkcyA9IGF3YWl0IHdvcmxkLnN0cmVhbXMubGlzdChydW5JZCk7XG4gICAgY29uc3QgbWF0Y2hpbmdTdHJlYW1zID0gc3RyZWFtSWRzLm1hcCgoc3RyZWFtSWQpID0+ICh7XG4gICAgICBydW5JZCxcbiAgICAgIHN0cmVhbUlkLFxuICAgIH0pKTtcblxuICAgIGlmIChvcHRzLmpzb24pIHtcbiAgICAgIHNob3dKc29uKG1hdGNoaW5nU3RyZWFtcyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxvZ2dlci5sb2coc2hvd1RhYmxlKG1hdGNoaW5nU3RyZWFtcywgWydydW5JZCcsICdzdHJlYW1JZCddKSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGhhbmRsZUFwaUVycm9yKGVycm9yLCBvcHRzLmJhY2tlbmQpKSB7XG4gICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgbGlzdEV2ZW50cyA9IGFzeW5jIChcbiAgd29ybGQ6IFdvcmxkLFxuICBvcHRzOiBJbnNwZWN0Q0xJT3B0aW9ucyA9IHt9XG4pID0+IHtcbiAgY29uc3QgcmVzb2x2ZUtleSA9IGNyZWF0ZVJlc29sdmVyKHdvcmxkLCBvcHRzPy5kZWNyeXB0ID8/IGZhbHNlKTtcbiAgaWYgKG9wdHMud29ya2Zsb3dOYW1lKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICAnRmlsdGVyaW5nIGJ5IHdvcmtmbG93LW5hbWUgaXMgbm90IHN1cHBvcnRlZCBmb3IgZXZlbnRzLCBpZ25vcmluZyBmaWx0ZXIuJ1xuICAgICk7XG4gIH1cblxuICBjb25zdCBydW5JZCA9IG9wdHMucnVuSWQgPz8gKGF3YWl0IGdldFJlY2VudFJ1bih3b3JsZCwgb3B0cykpPy5ydW5JZDtcbiAgaWYgKCFydW5JZCkge1xuICAgIGxvZ2dlci5lcnJvcignTm8gcnVuIGZvdW5kLicpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChvcHRzLndpdGhEYXRhKSB7XG4gICAgd2FybldpdGhEYXRhRGVwcmVjYXRlZEZvckxpc3QoJ2V2ZW50Jyk7XG4gIH1cblxuICBjb25zdCB1c2VBbmFseXRpY3MgPSAhb3B0cy53aXRoRGF0YSAmJiBCb29sZWFuKHdvcmxkLmFuYWx5dGljcyk7XG4gIGNvbnN0IGNvcnJlbGF0aW9uSWRGaWx0ZXIgPSBvcHRzLmhvb2tJZCB8fCBvcHRzLnN0ZXBJZDtcblxuICAvLyBEZXRlcm1pbmUgd2hpY2ggcHJvcHMgdG8gc2hvdyBiYXNlZCBvbiB3aXRoRGF0YSBmbGFnXG4gIGNvbnN0IHByb3BzID0gb3B0cy53aXRoRGF0YVxuICAgID8gRVZFTlRfTElTVEVEX1BST1BTXG4gICAgOiBFVkVOVF9MSVNURURfUFJPUFMuZmlsdGVyKChwcm9wKSA9PiAhRVZFTlRfSU9fUFJPUFMuaW5jbHVkZXMocHJvcCkpO1xuXG4gIGNvbnN0IGZldGNoRXZlbnRzUGFnZSA9IGFzeW5jIChcbiAgICBjdXJzb3I6IHN0cmluZyB8IHVuZGVmaW5lZFxuICApOiBQcm9taXNlPFBhZ2VEYXRhPFJlY29yZDxzdHJpbmcsIHVua25vd24+Pj4gPT4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhgRmV0Y2hpbmcgZXZlbnRzIGZvciBydW4gJHtydW5JZH1gKTtcbiAgICBjb25zdCBwYWdpbmF0aW9uID0ge1xuICAgICAgc29ydE9yZGVyOiBvcHRzLnNvcnQgfHwgJ2Rlc2MnLFxuICAgICAgY3Vyc29yLFxuICAgICAgbGltaXQ6IG9wdHMubGltaXQgfHwgREVGQVVMVF9QQUdFX1NJWkUsXG4gICAgfTtcbiAgICBpZiAodXNlQW5hbHl0aWNzICYmIHdvcmxkLmFuYWx5dGljcykge1xuICAgICAgY29uc3QgZXZlbnRzID0gYXdhaXQgd29ybGQuYW5hbHl0aWNzLmV2ZW50cy5saXN0KHtcbiAgICAgICAgcnVuSWQsXG4gICAgICAgIGNvcnJlbGF0aW9uSWQ6IGNvcnJlbGF0aW9uSWRGaWx0ZXIsXG4gICAgICAgIHBhZ2luYXRpb24sXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHBhZ2UgPSB7XG4gICAgICAgIGRhdGE6IGV2ZW50cy5kYXRhIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSxcbiAgICAgICAgY3Vyc29yOiBldmVudHMuY3Vyc29yLFxuICAgICAgICBoYXNNb3JlOiBldmVudHMuaGFzTW9yZSxcbiAgICAgICAgcGFnZUluZm86IGdldFBhZ2VJbmZvKGV2ZW50cyksXG4gICAgICB9O1xuICAgICAgaWYgKGN1cnNvciB8fCBwYWdlLmRhdGEubGVuZ3RoID4gMCB8fCBwYWdlLmhhc01vcmUpIHtcbiAgICAgICAgcmV0dXJuIHBhZ2U7XG4gICAgICB9XG4gICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgIGBObyBhbmFseXRpY3MgZXZlbnRzIGZvdW5kIGZvciBydW4gJHtydW5JZH07IGZhbGxpbmcgYmFjayB0byBzdG9yYWdlYFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd29ybGQuZXZlbnRzLmxpc3Qoe1xuICAgICAgcnVuSWQsXG4gICAgICBwYWdpbmF0aW9uLFxuICAgICAgcmVzb2x2ZURhdGE6IG9wdHMud2l0aERhdGEgPyAnYWxsJyA6ICdub25lJyxcbiAgICB9KTtcbiAgICBjb25zdCBmaWx0ZXJlZCA9IGNvcnJlbGF0aW9uSWRGaWx0ZXJcbiAgICAgID8gcmVzdWx0LmRhdGEuZmlsdGVyKChlKSA9PiBlLmNvcnJlbGF0aW9uSWQgPT09IGNvcnJlbGF0aW9uSWRGaWx0ZXIpXG4gICAgICA6IHJlc3VsdC5kYXRhO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGZpbHRlcmVkLm1hcCgoZSkgPT4gaHlkcmF0ZVJlc291cmNlSU8oZSwgcmVzb2x2ZUtleSkpXG4gICAgKTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogZGF0YSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sXG4gICAgICBjdXJzb3I6IHJlc3VsdC5jdXJzb3IsXG4gICAgICBoYXNNb3JlOiByZXN1bHQuaGFzTW9yZSxcbiAgICAgIHBhZ2VJbmZvOiBnZXRQYWdlSW5mbyhyZXN1bHQpLFxuICAgIH07XG4gIH07XG5cbiAgLy8gRm9yIEpTT04gb3V0cHV0LCBqdXN0IGZldGNoIG9uY2UgYW5kIHJldHVyblxuICBpZiAob3B0cy5qc29uKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBmZXRjaEV2ZW50c1BhZ2Uob3B0cy5jdXJzb3IpO1xuICAgICAgc2hvd0pzb24ocGFnZS5kYXRhKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGhhbmRsZUFwaUVycm9yKGVycm9yLCBvcHRzLmJhY2tlbmQpKSB7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGF3YWl0IHNldHVwTGlzdFBhZ2luYXRpb248UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KHtcbiAgICBpbml0aWFsQ3Vyc29yOiBvcHRzLmN1cnNvcixcbiAgICBpbnRlcmFjdGl2ZTogb3B0cy5pbnRlcmFjdGl2ZSxcbiAgICBmZXRjaFBhZ2U6IGFzeW5jIChjdXJzb3IpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmZXRjaEV2ZW50c1BhZ2UoY3Vyc29yKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChoYW5kbGVBcGlFcnJvcihlcnJvciwgb3B0cy5iYWNrZW5kKSkge1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIGRpc3BsYXlQYWdlOiBhc3luYyAoZXZlbnRzKSA9PiB7XG4gICAgICBsb2dnZXIubG9nKHNob3dUYWJsZShldmVudHMsIHByb3BzLCBvcHRzKSk7XG4gICAgICBzaG93SW5zcGVjdEluZm9Cb3goJ2V2ZW50Jyk7XG4gICAgfSxcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgbGlzdEhvb2tzID0gYXN5bmMgKHdvcmxkOiBXb3JsZCwgb3B0czogSW5zcGVjdENMSU9wdGlvbnMgPSB7fSkgPT4ge1xuICBjb25zdCByZXNvbHZlS2V5ID0gY3JlYXRlUmVzb2x2ZXIod29ybGQsIG9wdHM/LmRlY3J5cHQgPz8gZmFsc2UpO1xuXG4gIGlmIChvcHRzLndvcmtmbG93TmFtZSkge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJ0ZpbHRlcmluZyBieSB3b3JrZmxvdy1uYW1lIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGhvb2tzLCBpZ25vcmluZyBmaWx0ZXIuJ1xuICAgICk7XG4gIH1cbiAgaWYgKG9wdHMuc3RlcElkKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICAnRmlsdGVyaW5nIGJ5IHN0ZXAtaWQgaXMgbm90IHN1cHBvcnRlZCBmb3IgaG9va3MsIGlnbm9yaW5nIGZpbHRlci4nXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHJ1bklkID0gb3B0cy5ydW5JZDtcbiAgY29uc3QgcmVzb2x2ZURhdGEgPSBvcHRzLndpdGhEYXRhID8gJ2FsbCcgOiAnbm9uZSc7XG4gIC8vIEhvb2tzIGFsd2F5cyByZWFkIGZyb20gdGhlIHJ1bnRpbWUgc3RvcmFnZSBBUEkuIFVubGlrZSBydW5zL3N0ZXBzL2V2ZW50cyxcbiAgLy8gdGhlIGFuYWx5dGljcyByZWFkIHBhdGggb21pdHMgYG93bmVySWRgIChhbmQgdGhlIHNlY3JldCBob29rIHRva2VuIHVzZWQgYnlcbiAgLy8gcmVzdW1lL2NvcHktdG9rZW4gc3VyZmFjZXMpLCBzbyBob29rIGxpc3Rpbmcgc3RheXMgb24gdGhlIGNhbm9uaWNhbCBBUElzLlxuICBjb25zdCBmZXRjaEhvb2tzUGFnZSA9IGFzeW5jIChcbiAgICBjdXJzb3I6IHN0cmluZyB8IHVuZGVmaW5lZFxuICApOiBQcm9taXNlPFBhZ2VEYXRhPFJlY29yZDxzdHJpbmcsIHVua25vd24+Pj4gPT4ge1xuICAgIGlmICghcnVuSWQpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnRmV0Y2hpbmcgYWxsIGhvb2tzJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgRmV0Y2hpbmcgaG9va3MgZm9yIHJ1biAke3J1bklkfWApO1xuICAgIH1cbiAgICBjb25zdCBwYWdpbmF0aW9uID0ge1xuICAgICAgc29ydE9yZGVyOiBvcHRzLnNvcnQgfHwgJ2Rlc2MnLFxuICAgICAgY3Vyc29yLFxuICAgICAgbGltaXQ6IG9wdHMubGltaXQgfHwgREVGQVVMVF9QQUdFX1NJWkUsXG4gICAgfTtcbiAgICBjb25zdCBob29rcyA9IGF3YWl0IHdvcmxkLmhvb2tzLmxpc3QoeyBydW5JZCwgcGFnaW5hdGlvbiwgcmVzb2x2ZURhdGEgfSk7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgaG9va3MuZGF0YS5tYXAoKGgpID0+IGh5ZHJhdGVSZXNvdXJjZUlPKGgsIHJlc29sdmVLZXkpKVxuICAgICk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IGRhdGEgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLFxuICAgICAgY3Vyc29yOiBob29rcy5jdXJzb3IsXG4gICAgICBoYXNNb3JlOiBob29rcy5oYXNNb3JlLFxuICAgICAgcGFnZUluZm86IGdldFBhZ2VJbmZvKGhvb2tzKSxcbiAgICB9O1xuICB9O1xuXG4gIC8vIEZvciBKU09OIG91dHB1dCwganVzdCBmZXRjaCBvbmNlIGFuZCByZXR1cm5cbiAgaWYgKG9wdHMuanNvbikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgZmV0Y2hIb29rc1BhZ2Uob3B0cy5jdXJzb3IpO1xuICAgICAgc2hvd0pzb25QYWdlKHBhZ2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgLy8gU2V0dXAgcGFnaW5hdGlvbiB3aXRoIG5ldyBtZWNoYW5pc21cbiAgYXdhaXQgc2V0dXBMaXN0UGFnaW5hdGlvbjxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oe1xuICAgIGluaXRpYWxDdXJzb3I6IG9wdHMuY3Vyc29yLFxuICAgIGludGVyYWN0aXZlOiBvcHRzLmludGVyYWN0aXZlLFxuICAgIGZldGNoUGFnZTogYXN5bmMgKGN1cnNvcikgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGZldGNoSG9va3NQYWdlKGN1cnNvcik7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfSxcbiAgICBkaXNwbGF5UGFnZTogYXN5bmMgKGhvb2tzKSA9PiB7XG4gICAgICBsb2dnZXIubG9nKHNob3dUYWJsZShob29rcywgSE9PS19MSVNURURfUFJPUFMsIG9wdHMpKTtcbiAgICAgIHNob3dJbnNwZWN0SW5mb0JveCgnaG9vaycpO1xuICAgIH0sXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHNob3dIb29rID0gYXN5bmMgKFxuICB3b3JsZDogV29ybGQsXG4gIGhvb2tJZDogc3RyaW5nLFxuICBvcHRzOiBJbnNwZWN0Q0xJT3B0aW9ucyA9IHt9XG4pID0+IHtcbiAgY29uc3QgcmVzb2x2ZUtleSA9IGNyZWF0ZVJlc29sdmVyKHdvcmxkLCBvcHRzPy5kZWNyeXB0ID8/IGZhbHNlKTtcblxuICBpZiAob3B0cy53aXRoRGF0YSkge1xuICAgIGxvZ2dlci53YXJuKCdgd2l0aERhdGFgIGZsYWcgaXMgaWdub3JlZCB3aGVuIHNob3dpbmcgaW5kaXZpZHVhbCByZXNvdXJjZXMnKTtcbiAgfVxuICB0cnkge1xuICAgIGNvbnN0IGhvb2sgPSBhd2FpdCB3b3JsZC5ob29rcy5nZXQoaG9va0lkLCB7XG4gICAgICByZXNvbHZlRGF0YTogJ2FsbCcsXG4gICAgfSk7XG4gICAgY29uc3QgaHlkcmF0ZWRIb29rID0gYXdhaXQgaHlkcmF0ZVJlc291cmNlSU8oaG9vaywgcmVzb2x2ZUtleSk7XG4gICAgaWYgKG9wdHMuanNvbikge1xuICAgICAgc2hvd0pzb24oaHlkcmF0ZWRIb29rKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKFxuICAgICAgICBoYXNFeHBpcmVkRmllbGRzKGh5ZHJhdGVkSG9vayBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVxuICAgICAgKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgIFwiVGhpcyBob29rJ3MgZGF0YSAobWV0YWRhdGEpIGhhcyBleHBpcmVkIGFuZCBpcyBubyBsb25nZXIgYXZhaWxhYmxlLlwiXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBsb2dnZXIubG9nKGh5ZHJhdGVkSG9vayk7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChoYW5kbGVBcGlFcnJvcihlcnJvciwgb3B0cy5iYWNrZW5kKSkge1xuICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufTtcblxuLyoqXG4gKiBMaXN0IHdhaXRzL3NsZWVwcyB2aWEgdGhlIGFuYWx5dGljcyByZWFkIHBhdGguIFRoZSBhbmFseXRpY3Mgd2FpdCBzaGFwZSBpc1xuICoga2V5ZWQgYnkgYHdhaXRJZGAvYHN0YXR1c2AgcmF0aGVyIHRoYW4gdGhlIGBjb3JyZWxhdGlvbklkYC9gZXZlbnRJZGAgY29sdW1uc1xuICogcmVjb25zdHJ1Y3RlZCBmcm9tIHRoZSBldmVudCBzdHJlYW0gaW4gdGhlIGZhbGxiYWNrIHBhdGguXG4gKi9cbmNvbnN0IGxpc3RTbGVlcHNWaWFBbmFseXRpY3MgPSBhc3luYyAoXG4gIGFuYWx5dGljczogTm9uTnVsbGFibGU8V29ybGRbJ2FuYWx5dGljcyddPixcbiAgb3B0czogSW5zcGVjdENMSU9wdGlvbnNcbik6IFByb21pc2U8dm9pZD4gPT4ge1xuICBjb25zdCBmZXRjaFNsZWVwc1BhZ2UgPSBhc3luYyAoXG4gICAgY3Vyc29yOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgKTogUHJvbWlzZTxQYWdlRGF0YTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4+ID0+IHtcbiAgICBjb25zdCB3YWl0cyA9IGF3YWl0IGFuYWx5dGljcy53YWl0cy5saXN0KHtcbiAgICAgIHJ1bklkOiBvcHRzLnJ1bklkIGFzIHN0cmluZyxcbiAgICAgIHBhZ2luYXRpb246IHtcbiAgICAgICAgc29ydE9yZGVyOiBvcHRzLnNvcnQgfHwgJ2Rlc2MnLFxuICAgICAgICBjdXJzb3IsXG4gICAgICAgIGxpbWl0OiBvcHRzLmxpbWl0IHx8IERFRkFVTFRfUEFHRV9TSVpFLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiB3YWl0cy5kYXRhIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSxcbiAgICAgIGN1cnNvcjogd2FpdHMuY3Vyc29yLFxuICAgICAgaGFzTW9yZTogd2FpdHMuaGFzTW9yZSxcbiAgICAgIHBhZ2VJbmZvOiBnZXRQYWdlSW5mbyh3YWl0cyksXG4gICAgfTtcbiAgfTtcblxuICBpZiAob3B0cy5qc29uKSB7XG4gICAgY29uc3QgcGFnZSA9IGF3YWl0IGZldGNoU2xlZXBzUGFnZShvcHRzLmN1cnNvcik7XG4gICAgc2hvd0pzb24ocGFnZS5kYXRhKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBhd2FpdCBzZXR1cExpc3RQYWdpbmF0aW9uPFJlY29yZDxzdHJpbmcsIHVua25vd24+Pih7XG4gICAgaW5pdGlhbEN1cnNvcjogb3B0cy5jdXJzb3IsXG4gICAgaW50ZXJhY3RpdmU6IG9wdHMuaW50ZXJhY3RpdmUsXG4gICAgZmV0Y2hQYWdlOiBmZXRjaFNsZWVwc1BhZ2UsXG4gICAgZGlzcGxheVBhZ2U6IGFzeW5jICh3YWl0cykgPT4ge1xuICAgICAgbG9nZ2VyLmxvZyhcbiAgICAgICAgc2hvd1RhYmxlKFxuICAgICAgICAgIHdhaXRzLFxuICAgICAgICAgIFsnd2FpdElkJywgJ3N0YXR1cycsICdjcmVhdGVkQXQnLCAncmVzdW1lQXQnLCAnY29tcGxldGVkQXQnXSxcbiAgICAgICAgICB7IC4uLm9wdHMsIGRpc2FibGVSZWxhdGl2ZURhdGVzOiB0cnVlIH1cbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9LFxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBsaXN0U2xlZXBzID0gYXN5bmMgKFxuICB3b3JsZDogV29ybGQsXG4gIG9wdHM6IEluc3BlY3RDTElPcHRpb25zID0ge31cbikgPT4ge1xuICBpZiAoIW9wdHMucnVuSWQpIHtcbiAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAncnVuLWlkIGlzIHJlcXVpcmVkIGZvciBsaXN0aW5nIHNsZWVwcy4gVXNhZ2U6IGB3b3JrZmxvdyBpbnNwZWN0IHNsZWVwcyAtLXJ1bklkPTxpZD5gJ1xuICAgICk7XG4gICAgcHJvY2Vzcy5leGl0KDEpO1xuICB9XG5cbiAgaWYgKG9wdHMuc3RlcElkKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICAnRmlsdGVyaW5nIGJ5IHN0ZXAtaWQgaXMgbm90IHN1cHBvcnRlZCBmb3Igc2xlZXBzLCBpZ25vcmluZyBmaWx0ZXIuJ1xuICAgICk7XG4gIH1cbiAgaWYgKG9wdHMud29ya2Zsb3dOYW1lKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICAnRmlsdGVyaW5nIGJ5IHdvcmtmbG93LW5hbWUgaXMgbm90IHN1cHBvcnRlZCBmb3Igc2xlZXBzLCBpZ25vcmluZyBmaWx0ZXIuJ1xuICAgICk7XG4gIH1cbiAgaWYgKG9wdHMud2l0aERhdGEpIHtcbiAgICBsb2dnZXIud2FybignYHdpdGhEYXRhYCBmbGFnIGlzIGlnbm9yZWQgd2hlbiBsaXN0aW5nIHNsZWVwcycpO1xuICB9XG5cbiAgLy8gUHJlZmVyIHRoZSBhbmFseXRpY3MgcmVhZCBwYXRoIGZvciB3YWl0L3NsZWVwIGxpc3Rpbmcgd2hlbiBhdmFpbGFibGUuXG4gIGlmICh3b3JsZC5hbmFseXRpY3MpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgbGlzdFNsZWVwc1ZpYUFuYWx5dGljcyh3b3JsZC5hbmFseXRpY3MsIG9wdHMpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBGZXRjaCBhbGwgZXZlbnRzIGZvciB0aGUgcnVuIHdpdGggcmVzb2x2ZURhdGE9J2FsbCcgdG8gZ2V0IHdhaXQgZXZlbnREYXRhXG4gICAgY29uc3QgZXZlbnRzID0gYXdhaXQgd29ybGQuZXZlbnRzLmxpc3Qoe1xuICAgICAgcnVuSWQ6IG9wdHMucnVuSWQsXG4gICAgICBwYWdpbmF0aW9uOiB7XG4gICAgICAgIHNvcnRPcmRlcjogb3B0cy5zb3J0IHx8ICdkZXNjJyxcbiAgICAgICAgbGltaXQ6IDEwMDAsXG4gICAgICB9LFxuICAgICAgcmVzb2x2ZURhdGE6ICdhbGwnLFxuICAgIH0pO1xuXG4gICAgLy8gU2hvdyBpbmZvIG1lc3NhZ2UgaWYgdGhlcmUgbWlnaHQgYmUgbW9yZSBzbGVlcHNcbiAgICBpZiAoZXZlbnRzLmhhc01vcmUpIHtcbiAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAnV2FybmluZzogVGhpcyBydW4gaGFzIG1vcmUgdGhhbiAxMDAwIGV2ZW50cy4gU29tZSBzbGVlcHMgbWlnaHQgbm90IGJlIHNob3duLiBQbGVhc2UgdXNlIHRoZSB3ZWIgVUkgdG8gZW5zdXJlIGdldHRpbmcgYSBjb21wbGV0ZSBsaXN0LidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gR3JvdXAgd2FpdCBldmVudHMgYnkgY29ycmVsYXRpb25JZFxuICAgIGNvbnN0IHdhaXRFdmVudHNCeUNvcnJlbGF0aW9uID0gbmV3IE1hcDxzdHJpbmcsIEV2ZW50W10+KCk7XG4gICAgZm9yIChjb25zdCBldmVudCBvZiBldmVudHMuZGF0YSkge1xuICAgICAgaWYgKGlzV2FpdEV2ZW50VHlwZShldmVudC5ldmVudFR5cGUpICYmIGV2ZW50LmNvcnJlbGF0aW9uSWQpIHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSB3YWl0RXZlbnRzQnlDb3JyZWxhdGlvbi5nZXQoZXZlbnQuY29ycmVsYXRpb25JZCkgPz8gW107XG4gICAgICAgIGV4aXN0aW5nLnB1c2goZXZlbnQpO1xuICAgICAgICB3YWl0RXZlbnRzQnlDb3JyZWxhdGlvbi5zZXQoZXZlbnQuY29ycmVsYXRpb25JZCwgZXhpc3RpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh3YWl0RXZlbnRzQnlDb3JyZWxhdGlvbi5zaXplID09PSAwKSB7XG4gICAgICBsb2dnZXIud2FybignTm8gc2xlZXBzIGZvdW5kIGZvciB0aGlzIHJ1bi4nKTtcbiAgICAgIGlmIChvcHRzLmpzb24pIHtcbiAgICAgICAgc2hvd0pzb24oW10pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLmxvZyhcbiAgICAgICAgICBzaG93VGFibGUoW10gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSwgV0FJVF9MSVNURURfUFJPUFMsIHtcbiAgICAgICAgICAgIC4uLm9wdHMsXG4gICAgICAgICAgICBkaXNhYmxlUmVsYXRpdmVEYXRlczogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEJ1aWxkIHNsZWVwcyBmcm9tIGdyb3VwZWQgd2FpdCBldmVudHNcbiAgICBjb25zdCBzbGVlcHM6IFNsZWVwW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IFtjb3JyZWxhdGlvbklkLCBjb3JyZWxhdGlvbkV2ZW50c10gb2Ygd2FpdEV2ZW50c0J5Q29ycmVsYXRpb24pIHtcbiAgICAgIC8vIFN0aXRjaCB1cCB3YWl0X2NyZWF0ZWQgYW5kIHdhaXRfY29tcGxldGVkIGV2ZW50c1xuICAgICAgY29uc3Qgd2FpdENyZWF0ZWQgPSBjb3JyZWxhdGlvbkV2ZW50cy5maW5kKFxuICAgICAgICAoZTogRXZlbnQpID0+IGUuZXZlbnRUeXBlID09PSAnd2FpdF9jcmVhdGVkJ1xuICAgICAgKTtcbiAgICAgIGNvbnN0IHdhaXRDb21wbGV0ZWQgPSBjb3JyZWxhdGlvbkV2ZW50cy5maW5kKFxuICAgICAgICAoZTogRXZlbnQpID0+IGUuZXZlbnRUeXBlID09PSAnd2FpdF9jb21wbGV0ZWQnXG4gICAgICApO1xuXG4gICAgICBpZiAod2FpdENyZWF0ZWQpIHtcbiAgICAgICAgY29uc3Qgc2xlZXA6IFNsZWVwID0ge1xuICAgICAgICAgIGNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgcnVuSWQ6IHdhaXRDcmVhdGVkLnJ1bklkLFxuICAgICAgICAgIGV2ZW50SWQ6IHdhaXRDcmVhdGVkLmV2ZW50SWQsXG4gICAgICAgICAgY3JlYXRlZEF0OiB3YWl0Q3JlYXRlZC5jcmVhdGVkQXQsXG4gICAgICAgICAgcmVzdW1lQXQ6XG4gICAgICAgICAgICB3YWl0Q3JlYXRlZC5ldmVudFR5cGUgPT09ICd3YWl0X2NyZWF0ZWQnXG4gICAgICAgICAgICAgID8gd2FpdENyZWF0ZWQuZXZlbnREYXRhLnJlc3VtZUF0XG4gICAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGNvbXBsZXRlZEF0OiB3YWl0Q29tcGxldGVkPy5jcmVhdGVkQXQsXG4gICAgICAgIH07XG4gICAgICAgIHNsZWVwcy5wdXNoKHNsZWVwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTb3J0IHNsZWVwcyBieSBjcmVhdGVkQXRcbiAgICBzbGVlcHMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgY29uc3QgdGltZUEgPSBhLmNyZWF0ZWRBdC5nZXRUaW1lKCk7XG4gICAgICBjb25zdCB0aW1lQiA9IGIuY3JlYXRlZEF0LmdldFRpbWUoKTtcbiAgICAgIHJldHVybiBvcHRzLnNvcnQgPT09ICdhc2MnID8gdGltZUEgLSB0aW1lQiA6IHRpbWVCIC0gdGltZUE7XG4gICAgfSk7XG5cbiAgICBpZiAob3B0cy5qc29uKSB7XG4gICAgICBzaG93SnNvbihzbGVlcHMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxvZ2dlci5sb2coXG4gICAgICBzaG93VGFibGUoXG4gICAgICAgIHNsZWVwcyBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sXG4gICAgICAgIFdBSVRfTElTVEVEX1BST1BTLFxuICAgICAgICB7IC4uLm9wdHMsIGRpc2FibGVSZWxhdGl2ZURhdGVzOiB0cnVlIH1cbiAgICAgIClcbiAgICApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChoYW5kbGVBcGlFcnJvcihlcnJvciwgb3B0cy5iYWNrZW5kKSkge1xuICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufTtcbiJdfQ==
|