@workflow/cli 5.0.0-beta.4 → 5.0.0-beta.40

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.
Files changed (108) hide show
  1. package/dist/base.js +1 -1
  2. package/dist/commands/build.js +1 -1
  3. package/dist/commands/cancel.d.ts +1 -0
  4. package/dist/commands/cancel.d.ts.map +1 -1
  5. package/dist/commands/cancel.js +36 -55
  6. package/dist/commands/dev.js +1 -1
  7. package/dist/commands/health.d.ts +1 -3
  8. package/dist/commands/health.d.ts.map +1 -1
  9. package/dist/commands/health.js +26 -50
  10. package/dist/commands/init.js +1 -1
  11. package/dist/commands/inspect.d.ts +4 -0
  12. package/dist/commands/inspect.d.ts.map +1 -1
  13. package/dist/commands/inspect.js +37 -7
  14. package/dist/commands/start.d.ts +1 -0
  15. package/dist/commands/start.d.ts.map +1 -1
  16. package/dist/commands/start.js +8 -3
  17. package/dist/commands/transform.js +1 -1
  18. package/dist/commands/validate.js +1 -1
  19. package/dist/commands/web.d.ts +2 -0
  20. package/dist/commands/web.d.ts.map +1 -1
  21. package/dist/commands/web.js +9 -3
  22. package/dist/lib/bulk-cancel.d.ts +74 -0
  23. package/dist/lib/bulk-cancel.d.ts.map +1 -0
  24. package/dist/lib/bulk-cancel.js +197 -0
  25. package/dist/lib/bulk-cancel.test.d.ts +2 -0
  26. package/dist/lib/bulk-cancel.test.d.ts.map +1 -0
  27. package/dist/lib/bulk-cancel.test.js +366 -0
  28. package/dist/lib/config/log.js +1 -1
  29. package/dist/lib/config/types.d.ts +6 -1
  30. package/dist/lib/config/types.d.ts.map +1 -1
  31. package/dist/lib/config/types.js +1 -1
  32. package/dist/lib/config/workflow-config.d.ts.map +1 -1
  33. package/dist/lib/config/workflow-config.js +2 -2
  34. package/dist/lib/inspect/auth.js +1 -1
  35. package/dist/lib/inspect/env.d.ts +1 -1
  36. package/dist/lib/inspect/env.js +2 -2
  37. package/dist/lib/inspect/errors.d.ts +3 -0
  38. package/dist/lib/inspect/errors.d.ts.map +1 -0
  39. package/dist/lib/inspect/errors.js +27 -0
  40. package/dist/lib/inspect/flags.d.ts +9 -0
  41. package/dist/lib/inspect/flags.d.ts.map +1 -1
  42. package/dist/lib/inspect/flags.js +23 -1
  43. package/dist/lib/inspect/hydration.d.ts +22 -0
  44. package/dist/lib/inspect/hydration.d.ts.map +1 -1
  45. package/dist/lib/inspect/hydration.js +107 -49
  46. package/dist/lib/inspect/hydration.test.d.ts +2 -0
  47. package/dist/lib/inspect/hydration.test.d.ts.map +1 -0
  48. package/dist/lib/inspect/hydration.test.js +23 -0
  49. package/dist/lib/inspect/output.d.ts +2 -2
  50. package/dist/lib/inspect/output.d.ts.map +1 -1
  51. package/dist/lib/inspect/output.js +327 -136
  52. package/dist/lib/inspect/output.test.js +663 -3
  53. package/dist/lib/inspect/pagination.d.ts +10 -1
  54. package/dist/lib/inspect/pagination.d.ts.map +1 -1
  55. package/dist/lib/inspect/pagination.js +20 -4
  56. package/dist/lib/inspect/run.d.ts.map +1 -1
  57. package/dist/lib/inspect/run.js +33 -10
  58. package/dist/lib/inspect/setup.d.ts.map +1 -1
  59. package/dist/lib/inspect/setup.js +42 -6
  60. package/dist/lib/inspect/stream.js +1 -1
  61. package/dist/lib/inspect/terminal-utils.js +1 -1
  62. package/dist/lib/inspect/time-window.d.ts +28 -0
  63. package/dist/lib/inspect/time-window.d.ts.map +1 -0
  64. package/dist/lib/inspect/time-window.js +61 -0
  65. package/dist/lib/inspect/time-window.test.d.ts +2 -0
  66. package/dist/lib/inspect/time-window.test.d.ts.map +1 -0
  67. package/dist/lib/inspect/time-window.test.js +58 -0
  68. package/dist/lib/inspect/vercel-api.d.ts +5 -2
  69. package/dist/lib/inspect/vercel-api.d.ts.map +1 -1
  70. package/dist/lib/inspect/vercel-api.js +12 -37
  71. package/dist/lib/inspect/vercel-api.test.d.ts +2 -0
  72. package/dist/lib/inspect/vercel-api.test.d.ts.map +1 -0
  73. package/dist/lib/inspect/vercel-api.test.js +21 -0
  74. package/dist/lib/inspect/vercel-link.js +1 -1
  75. package/dist/lib/inspect/web.d.ts +24 -0
  76. package/dist/lib/inspect/web.d.ts.map +1 -1
  77. package/dist/lib/inspect/web.js +122 -3
  78. package/dist/lib/update-check.js +1 -1
  79. package/package.json +15 -14
  80. package/dist/base.js.map +0 -1
  81. package/dist/commands/build.js.map +0 -1
  82. package/dist/commands/cancel.js.map +0 -1
  83. package/dist/commands/dev.js.map +0 -1
  84. package/dist/commands/health.js.map +0 -1
  85. package/dist/commands/init.js.map +0 -1
  86. package/dist/commands/inspect.js.map +0 -1
  87. package/dist/commands/start.js.map +0 -1
  88. package/dist/commands/transform.js.map +0 -1
  89. package/dist/commands/validate.js.map +0 -1
  90. package/dist/commands/web.js.map +0 -1
  91. package/dist/lib/config/log.js.map +0 -1
  92. package/dist/lib/config/types.js.map +0 -1
  93. package/dist/lib/config/workflow-config.js.map +0 -1
  94. package/dist/lib/inspect/auth.js.map +0 -1
  95. package/dist/lib/inspect/env.js.map +0 -1
  96. package/dist/lib/inspect/flags.js.map +0 -1
  97. package/dist/lib/inspect/hydration.js.map +0 -1
  98. package/dist/lib/inspect/output.js.map +0 -1
  99. package/dist/lib/inspect/output.test.js.map +0 -1
  100. package/dist/lib/inspect/pagination.js.map +0 -1
  101. package/dist/lib/inspect/run.js.map +0 -1
  102. package/dist/lib/inspect/setup.js.map +0 -1
  103. package/dist/lib/inspect/stream.js.map +0 -1
  104. package/dist/lib/inspect/terminal-utils.js.map +0 -1
  105. package/dist/lib/inspect/vercel-api.js.map +0 -1
  106. package/dist/lib/inspect/vercel-link.js.map +0 -1
  107. package/dist/lib/inspect/web.js.map +0 -1
  108. package/dist/lib/update-check.js.map +0 -1
@@ -1,12 +1,14 @@
1
- import { importKey } from '@workflow/core/encryption';
2
- import { getDeserializeStream, getExternalRevivers, } from '@workflow/core/serialization';
1
+ import { deriveRunPayloadKeys, getDeserializeStream, getExternalRevivers, } from '@workflow/core/serialization';
3
2
  import { VERCEL_403_ERROR_MESSAGE } from '@workflow/errors';
4
3
  import { parseStepName, parseWorkflowName } from '@workflow/utils/parse-name';
4
+ import { isWaitEventType, } from '@workflow/world';
5
5
  import chalk from 'chalk';
6
6
  import { formatDistance } from 'date-fns';
7
7
  import Table from 'easy-table';
8
8
  import { logger } from '../config/log.js';
9
+ import { getObservabilityUpgradeRequiredMessage, isObservabilityUpgradeRequiredError, } from './errors.js';
9
10
  import { hydrateResourceIO, isEncryptedRef, isExpiredRef, } from './hydration.js';
11
+ import { resolveTimeWindow } from './time-window.js';
10
12
  /**
11
13
  * Create an EncryptionKeyResolver from a World instance.
12
14
  * Returns null if decrypt is false — encrypted data will show as a placeholder.
@@ -31,7 +33,7 @@ function createResolver(world, decrypt) {
31
33
  return cached;
32
34
  };
33
35
  }
34
- import { setupListPagination } from './pagination.js';
36
+ import { setupListPagination, } from './pagination.js';
35
37
  import { streamToConsole } from './stream.js';
36
38
  import { formatISODate, formatStatus as formatStatusAbbrev, getDisplaySettings, getTerminalWidth, isCI, } from './terminal-utils.js';
37
39
  const DEFAULT_PAGE_SIZE = 20;
@@ -84,6 +86,7 @@ const STATUS_COLORS = {
84
86
  failed: chalk.red,
85
87
  cancelled: chalk.strikethrough.yellow,
86
88
  pending: chalk.blue,
89
+ waiting: chalk.blue,
87
90
  };
88
91
  const isStreamId = (value) => {
89
92
  return typeof value === 'string' && value.startsWith('strm_');
@@ -96,6 +99,7 @@ const showStatusLegend = () => {
96
99
  'failed',
97
100
  'cancelled',
98
101
  'pending',
102
+ 'waiting',
99
103
  ];
100
104
  const legendItems = statuses.map((status) => {
101
105
  const colorFunc = STATUS_COLORS[status];
@@ -133,11 +137,23 @@ const extractErrorMessage = (err) => {
133
137
  }
134
138
  return undefined;
135
139
  };
140
+ const getPageInfo = (result) => {
141
+ if (typeof result !== 'object' ||
142
+ result === null ||
143
+ !('pageInfo' in result)) {
144
+ return undefined;
145
+ }
146
+ return result.pageInfo;
147
+ };
136
148
  const handleApiError = (error, backend) => {
137
149
  // First check for Vercel access errors
138
150
  if (checkAndHandleVercelAccessError(error, backend)) {
139
151
  return true;
140
152
  }
153
+ if (isObservabilityUpgradeRequiredError(error)) {
154
+ logger.error(getObservabilityUpgradeRequiredMessage());
155
+ return true;
156
+ }
141
157
  // Handle other HTTP errors
142
158
  if (error && typeof error === 'object') {
143
159
  const err = error;
@@ -166,6 +182,7 @@ const getStatusText = (status) => {
166
182
  const statusTexts = {
167
183
  400: 'Bad Request',
168
184
  401: 'Unauthorized',
185
+ 402: 'Payment Required',
169
186
  403: 'Forbidden',
170
187
  404: 'Not Found',
171
188
  429: 'Too Many Requests',
@@ -229,7 +246,7 @@ export const formatTableValue = (prop, value, opts = {}, displaySettings, item)
229
246
  }
230
247
  if (prop === 'status') {
231
248
  const status = value;
232
- const colorFunc = STATUS_COLORS[status];
249
+ const colorFunc = STATUS_COLORS[status] ?? ((formatted) => formatted);
233
250
  const formattedStatus = displaySettings?.abbreviateStatus
234
251
  ? formatStatusAbbrev(status, true)
235
252
  : status;
@@ -305,6 +322,44 @@ const showJson = (data) => {
305
322
  const json = JSON.stringify(data, null, 2);
306
323
  process.stdout.write(`${json}\n`);
307
324
  };
325
+ /**
326
+ * Defensively evaluate `World.describeRun` for one run row.
327
+ *
328
+ * The interface contract says implementations are pure and must not
329
+ * throw — but it is an external extension point, so the CLI does not
330
+ * trust that: a throwing implementation contributes no fields instead
331
+ * of crashing the command. Keys that already exist on the run row are
332
+ * dropped so a world can never overwrite canonical fields (`status`,
333
+ * `runId`, ...) in inspect output.
334
+ */
335
+ const safeWorldFields = async (describeRun, row) => {
336
+ let fields;
337
+ try {
338
+ // The hook may be sync or async; a rejection is treated the same as
339
+ // a throw — no fields.
340
+ fields = await describeRun(row);
341
+ }
342
+ catch {
343
+ return {};
344
+ }
345
+ if (!fields)
346
+ return {};
347
+ const safe = {};
348
+ for (const [key, value] of Object.entries(fields)) {
349
+ if (!(key in row)) {
350
+ safe[key] = value;
351
+ }
352
+ }
353
+ return safe;
354
+ };
355
+ const showJsonPage = (page) => {
356
+ showJson({
357
+ data: page.data,
358
+ cursor: page.cursor,
359
+ hasMore: page.hasMore,
360
+ ...(page.pageInfo ? { pageInfo: page.pageInfo } : {}),
361
+ });
362
+ };
308
363
  /**
309
364
  * In tables, we want to show a shorter timestamp, YYYY-MM-DD HH:MM:SS
310
365
  */
@@ -418,31 +473,108 @@ const inlineFormatIO = (io, topLevel = true) => {
418
473
  }
419
474
  return value;
420
475
  };
476
+ /**
477
+ * List views surface metadata only. When the active backend exposes the
478
+ * optional `world.analytics` read namespace we read list pages from it
479
+ * (metadata-only — no payload resolution); otherwise we fall back to the
480
+ * runtime storage APIs with `resolveData: 'none'`.
481
+ *
482
+ * `--withData` forces the runtime path so payloads can be resolved into the
483
+ * table. It is deprecated for list views: view payloads per-resource with
484
+ * `workflow inspect <resource> <id>`.
485
+ */
486
+ const warnWithDataDeprecatedForList = (singular) => {
487
+ 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}.`);
488
+ };
421
489
  export const listRuns = async (world, opts = {}) => {
422
490
  const resolveKey = createResolver(world, opts?.decrypt ?? false);
423
491
  if (opts.stepId || opts.runId) {
424
492
  logger.warn('Filtering by step-id or run-id is not supported in list calls, ignoring filter.');
425
493
  }
494
+ if (opts.withData) {
495
+ warnWithDataDeprecatedForList('run');
496
+ }
497
+ const useAnalytics = !opts.withData && Boolean(world.analytics);
426
498
  const resolveData = opts.withData ? 'all' : 'none';
499
+ const status = opts.status;
500
+ // Resolve --since/--until into an explicit listing window. Only the
501
+ // analytics read path supports one; the runtime storage APIs have no time
502
+ // filter. Without the flags the backend applies its default window
503
+ // (trailing 24h on the Vercel backend).
504
+ const timeWindow = resolveTimeWindow(opts);
505
+ if (timeWindow && !useAnalytics) {
506
+ logger.warn('--since/--until require the analytics read path and are ignored by this backend.');
507
+ }
427
508
  // Determine which props to show based on withData flag
428
- const props = opts.withData
509
+ const baseProps = opts.withData
429
510
  ? WORKFLOW_RUN_LISTED_PROPS
430
511
  : WORKFLOW_RUN_LISTED_PROPS.filter((prop) => !WORKFLOW_RUN_IO_PROPS.includes(prop));
512
+ // World-specific display fields (World.describeRun): each key the
513
+ // world returns becomes an extra column, inserted before `status`.
514
+ // Detached call site, so bind explicitly. `null` field values are
515
+ // preserved (they mean "applicable but undeterminable" per the
516
+ // interface contract), distinguishing them in JSON output from the
517
+ // hook being absent entirely.
518
+ const describeRun = world.describeRun?.bind(world);
519
+ const describedKeys = [];
520
+ const withWorldFields = async (rows) => {
521
+ if (!describeRun)
522
+ return rows;
523
+ // Rows evaluated concurrently so an async implementation costs one
524
+ // await per page, not per row.
525
+ return Promise.all(rows.map(async (row) => {
526
+ const fields = await safeWorldFields(describeRun, row);
527
+ for (const key of Object.keys(fields)) {
528
+ if (!describedKeys.includes(key))
529
+ describedKeys.push(key);
530
+ }
531
+ return { ...row, ...fields };
532
+ }));
533
+ };
534
+ const propsFor = (baseList) => {
535
+ const list = [...baseList];
536
+ list.splice(list.indexOf('status'), 0, ...describedKeys);
537
+ return list;
538
+ };
539
+ const fetchRunsPage = async (cursor) => {
540
+ const pagination = {
541
+ sortOrder: opts.sort || 'desc',
542
+ cursor,
543
+ limit: opts.limit || DEFAULT_PAGE_SIZE,
544
+ };
545
+ if (useAnalytics && world.analytics) {
546
+ const runs = await world.analytics.runs.list({
547
+ workflowName: opts.workflowName,
548
+ status,
549
+ ...(timeWindow ?? {}),
550
+ pagination,
551
+ });
552
+ return {
553
+ data: await withWorldFields(runs.data),
554
+ cursor: runs.cursor,
555
+ hasMore: runs.hasMore,
556
+ pageInfo: getPageInfo(runs),
557
+ };
558
+ }
559
+ const runs = await world.runs.list({
560
+ workflowName: opts.workflowName,
561
+ status,
562
+ pagination,
563
+ resolveData,
564
+ });
565
+ const data = await Promise.all(runs.data.map((r) => hydrateResourceIO(r, resolveKey)));
566
+ return {
567
+ data: await withWorldFields(data),
568
+ cursor: runs.cursor,
569
+ hasMore: runs.hasMore,
570
+ pageInfo: getPageInfo(runs),
571
+ };
572
+ };
431
573
  // For JSON output, just fetch once and return
432
574
  if (opts.json) {
433
575
  try {
434
- const runs = await world.runs.list({
435
- workflowName: opts.workflowName,
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 });
576
+ const page = await fetchRunsPage(opts.cursor);
577
+ showJsonPage(page);
446
578
  return;
447
579
  }
448
580
  catch (error) {
@@ -457,21 +589,7 @@ export const listRuns = async (world, opts = {}) => {
457
589
  interactive: opts.interactive,
458
590
  fetchPage: async (cursor) => {
459
591
  try {
460
- const runs = await world.runs.list({
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
- };
592
+ return await fetchRunsPage(cursor);
475
593
  }
476
594
  catch (error) {
477
595
  if (handleApiError(error, opts.backend)) {
@@ -481,8 +599,7 @@ export const listRuns = async (world, opts = {}) => {
481
599
  }
482
600
  },
483
601
  displayPage: async (runs) => {
484
- const runsWithHydratedIO = await Promise.all(runs.map((r) => hydrateResourceIO(r, resolveKey)));
485
- logger.log(showTable(runsWithHydratedIO, props, opts));
602
+ logger.log(showTable(runs, propsFor(baseProps), opts));
486
603
  },
487
604
  });
488
605
  };
@@ -511,7 +628,16 @@ export const showRun = async (world, runId, opts = {}) => {
511
628
  }
512
629
  try {
513
630
  const run = await world.runs.get(runId, { resolveData: 'all' });
514
- const runWithHydratedIO = await hydrateResourceIO(run, resolveKey);
631
+ const hydrated = await hydrateResourceIO(run, resolveKey);
632
+ // World-specific display fields (World.describeRun), evaluated
633
+ // defensively — see safeWorldFields. `null` field values are kept so
634
+ // structured output distinguishes "undeterminable" from "hook absent".
635
+ const worldFields = world.describeRun
636
+ ? await safeWorldFields(world.describeRun.bind(world), run)
637
+ : undefined;
638
+ const runWithHydratedIO = worldFields && Object.keys(worldFields).length > 0
639
+ ? { ...hydrated, ...worldFields }
640
+ : hydrated;
515
641
  if (opts.json) {
516
642
  showJson(runWithHydratedIO);
517
643
  return;
@@ -547,26 +673,53 @@ export const listSteps = async (world, opts = {
547
673
  logger.error('No run found.');
548
674
  return;
549
675
  }
676
+ if (opts.withData) {
677
+ warnWithDataDeprecatedForList('step');
678
+ }
679
+ const useAnalytics = !opts.withData && Boolean(world.analytics);
550
680
  const resolveData = opts.withData ? 'all' : 'none';
551
681
  // Determine which props to show based on withData flag
552
682
  const props = opts.withData
553
683
  ? STEP_LISTED_PROPS
554
684
  : STEP_LISTED_PROPS.filter((prop) => !STEP_IO_PROPS.includes(prop));
685
+ const fetchStepsPage = async (cursor) => {
686
+ logger.debug(`Fetching steps for run ${runId}`);
687
+ const pagination = {
688
+ sortOrder: opts.sort || 'desc',
689
+ cursor,
690
+ limit: opts.limit || DEFAULT_PAGE_SIZE,
691
+ };
692
+ if (useAnalytics && world.analytics) {
693
+ const steps = await world.analytics.steps.list({ runId, pagination });
694
+ const page = {
695
+ data: steps.data,
696
+ cursor: steps.cursor,
697
+ hasMore: steps.hasMore,
698
+ pageInfo: getPageInfo(steps),
699
+ };
700
+ if (cursor || page.data.length > 0 || page.hasMore) {
701
+ return page;
702
+ }
703
+ logger.debug(`No analytics steps found for run ${runId}; falling back to storage`);
704
+ }
705
+ const stepChunks = await world.steps.list({
706
+ runId,
707
+ pagination,
708
+ resolveData,
709
+ });
710
+ const data = await Promise.all(stepChunks.data.map((s) => hydrateResourceIO(s, resolveKey)));
711
+ return {
712
+ data: data,
713
+ cursor: stepChunks.cursor,
714
+ hasMore: stepChunks.hasMore,
715
+ pageInfo: getPageInfo(stepChunks),
716
+ };
717
+ };
555
718
  // For JSON output, just fetch once and return
556
719
  if (opts.json) {
557
- logger.debug(`Fetching steps for run ${runId}`);
558
720
  try {
559
- const stepChunks = await world.steps.list({
560
- runId,
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);
721
+ const page = await fetchStepsPage(opts.cursor);
722
+ showJson(page.data);
570
723
  return;
571
724
  }
572
725
  catch (error) {
@@ -580,22 +733,8 @@ export const listSteps = async (world, opts = {
580
733
  initialCursor: opts.cursor,
581
734
  interactive: opts.interactive,
582
735
  fetchPage: async (cursor) => {
583
- logger.debug(`Fetching steps for run ${runId}`);
584
736
  try {
585
- const stepChunks = await world.steps.list({
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
- };
737
+ return await fetchStepsPage(cursor);
599
738
  }
600
739
  catch (error) {
601
740
  if (handleApiError(error, opts.backend)) {
@@ -605,8 +744,7 @@ export const listSteps = async (world, opts = {
605
744
  }
606
745
  },
607
746
  displayPage: async (steps) => {
608
- const stepsWithHydratedIO = await Promise.all(steps.map((s) => hydrateResourceIO(s, resolveKey)));
609
- logger.log(showTable(stepsWithHydratedIO, props, opts));
747
+ logger.log(showTable(steps, props, opts));
610
748
  showInspectInfoBox('step');
611
749
  },
612
750
  });
@@ -663,7 +801,9 @@ export const showStream = async (world, streamId, opts = {}) => {
663
801
  encryptionKey = (async () => {
664
802
  const run = await world.runs.get(opts.runId);
665
803
  const rawKey = await world.getEncryptionKeyForRun?.(run);
666
- return rawKey ? await importKey(rawKey) : undefined;
804
+ // Full capability, so sealed ('encp') stream frames written by other
805
+ // runs are readable too — not just the run's own symmetric frames.
806
+ return rawKey ? await deriveRunPayloadKeys(rawKey) : undefined;
667
807
  })();
668
808
  }
669
809
  else if (opts.decrypt && !opts.runId) {
@@ -730,40 +870,60 @@ export const listEvents = async (world, opts = {}) => {
730
870
  logger.error('No run found.');
731
871
  return;
732
872
  }
873
+ if (opts.withData) {
874
+ warnWithDataDeprecatedForList('event');
875
+ }
876
+ const useAnalytics = !opts.withData && Boolean(world.analytics);
733
877
  const correlationIdFilter = opts.hookId || opts.stepId;
734
- const params = {
735
- runId,
736
- pagination: {
878
+ // Determine which props to show based on withData flag
879
+ const props = opts.withData
880
+ ? EVENT_LISTED_PROPS
881
+ : EVENT_LISTED_PROPS.filter((prop) => !EVENT_IO_PROPS.includes(prop));
882
+ const fetchEventsPage = async (cursor) => {
883
+ logger.debug(`Fetching events for run ${runId}`);
884
+ const pagination = {
737
885
  sortOrder: opts.sort || 'desc',
738
- cursor: opts.cursor,
886
+ cursor,
739
887
  limit: opts.limit || DEFAULT_PAGE_SIZE,
740
- },
741
- resolveData: opts.withData ? 'all' : 'none',
742
- };
743
- const listCall = async (pagination) => {
744
- const result = await world.events.list({
745
- ...params,
746
- pagination: { ...params.pagination, ...pagination },
747
- });
748
- if (correlationIdFilter) {
749
- return {
750
- ...result,
751
- data: result.data.filter((e) => e.correlationId === correlationIdFilter),
888
+ };
889
+ if (useAnalytics && world.analytics) {
890
+ const events = await world.analytics.events.list({
891
+ runId,
892
+ correlationId: correlationIdFilter,
893
+ pagination,
894
+ });
895
+ const page = {
896
+ data: events.data,
897
+ cursor: events.cursor,
898
+ hasMore: events.hasMore,
899
+ pageInfo: getPageInfo(events),
752
900
  };
901
+ if (cursor || page.data.length > 0 || page.hasMore) {
902
+ return page;
903
+ }
904
+ logger.debug(`No analytics events found for run ${runId}; falling back to storage`);
753
905
  }
754
- return result;
906
+ const result = await world.events.list({
907
+ runId,
908
+ pagination,
909
+ resolveData: opts.withData ? 'all' : 'none',
910
+ });
911
+ const filtered = correlationIdFilter
912
+ ? result.data.filter((e) => e.correlationId === correlationIdFilter)
913
+ : result.data;
914
+ const data = await Promise.all(filtered.map((e) => hydrateResourceIO(e, resolveKey)));
915
+ return {
916
+ data: data,
917
+ cursor: result.cursor,
918
+ hasMore: result.hasMore,
919
+ pageInfo: getPageInfo(result),
920
+ };
755
921
  };
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
922
  // For JSON output, just fetch once and return
761
923
  if (opts.json) {
762
- logger.debug(`Fetching events for run ${runId}`);
763
924
  try {
764
- const events = await listCall({});
765
- const hydratedEvents = await Promise.all(events.data.map((e) => hydrateResourceIO(e, resolveKey)));
766
- showJson(hydratedEvents);
925
+ const page = await fetchEventsPage(opts.cursor);
926
+ showJson(page.data);
767
927
  return;
768
928
  }
769
929
  catch (error) {
@@ -777,14 +937,8 @@ export const listEvents = async (world, opts = {}) => {
777
937
  initialCursor: opts.cursor,
778
938
  interactive: opts.interactive,
779
939
  fetchPage: async (cursor) => {
780
- logger.debug(`Fetching events for run ${runId}`);
781
940
  try {
782
- const events = await listCall({ cursor });
783
- return {
784
- data: events.data,
785
- cursor: events.cursor,
786
- hasMore: events.hasMore,
787
- };
941
+ return await fetchEventsPage(cursor);
788
942
  }
789
943
  catch (error) {
790
944
  if (handleApiError(error, opts.backend)) {
@@ -794,8 +948,7 @@ export const listEvents = async (world, opts = {}) => {
794
948
  }
795
949
  },
796
950
  displayPage: async (events) => {
797
- const hydratedEvents = await Promise.all(events.map((e) => hydrateResourceIO(e, resolveKey)));
798
- logger.log(showTable(hydratedEvents, props, opts));
951
+ logger.log(showTable(events, props, opts));
799
952
  showInspectInfoBox('event');
800
953
  },
801
954
  });
@@ -810,26 +963,35 @@ export const listHooks = async (world, opts = {}) => {
810
963
  }
811
964
  const runId = opts.runId;
812
965
  const resolveData = opts.withData ? 'all' : 'none';
813
- // For JSON output, just fetch once and return
814
- if (opts.json) {
966
+ // Hooks always read from the runtime storage API. Unlike runs/steps/events,
967
+ // the analytics read path omits `ownerId` (and the secret hook token used by
968
+ // resume/copy-token surfaces), so hook listing stays on the canonical APIs.
969
+ const fetchHooksPage = async (cursor) => {
815
970
  if (!runId) {
816
971
  logger.debug('Fetching all hooks');
817
972
  }
818
973
  else {
819
974
  logger.debug(`Fetching hooks for run ${runId}`);
820
975
  }
976
+ const pagination = {
977
+ sortOrder: opts.sort || 'desc',
978
+ cursor,
979
+ limit: opts.limit || DEFAULT_PAGE_SIZE,
980
+ };
981
+ const hooks = await world.hooks.list({ runId, pagination, resolveData });
982
+ const data = await Promise.all(hooks.data.map((h) => hydrateResourceIO(h, resolveKey)));
983
+ return {
984
+ data: data,
985
+ cursor: hooks.cursor,
986
+ hasMore: hooks.hasMore,
987
+ pageInfo: getPageInfo(hooks),
988
+ };
989
+ };
990
+ // For JSON output, just fetch once and return
991
+ if (opts.json) {
821
992
  try {
822
- const hooks = await world.hooks.list({
823
- runId,
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 });
993
+ const page = await fetchHooksPage(opts.cursor);
994
+ showJsonPage(page);
833
995
  return;
834
996
  }
835
997
  catch (error) {
@@ -844,27 +1006,8 @@ export const listHooks = async (world, opts = {}) => {
844
1006
  initialCursor: opts.cursor,
845
1007
  interactive: opts.interactive,
846
1008
  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
1009
  try {
854
- const hooks = await world.hooks.list({
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
- };
1010
+ return await fetchHooksPage(cursor);
868
1011
  }
869
1012
  catch (error) {
870
1013
  if (handleApiError(error, opts.backend)) {
@@ -874,8 +1017,7 @@ export const listHooks = async (world, opts = {}) => {
874
1017
  }
875
1018
  },
876
1019
  displayPage: async (hooks) => {
877
- const hydratedHooks = await Promise.all(hooks.map((h) => hydrateResourceIO(h, resolveKey)));
878
- logger.log(showTable(hydratedHooks, HOOK_LISTED_PROPS, opts));
1020
+ logger.log(showTable(hooks, HOOK_LISTED_PROPS, opts));
879
1021
  showInspectInfoBox('hook');
880
1022
  },
881
1023
  });
@@ -908,6 +1050,42 @@ export const showHook = async (world, hookId, opts = {}) => {
908
1050
  throw error;
909
1051
  }
910
1052
  };
1053
+ /**
1054
+ * List waits/sleeps via the analytics read path. The analytics wait shape is
1055
+ * keyed by `waitId`/`status` rather than the `correlationId`/`eventId` columns
1056
+ * reconstructed from the event stream in the fallback path.
1057
+ */
1058
+ const listSleepsViaAnalytics = async (analytics, opts) => {
1059
+ const fetchSleepsPage = async (cursor) => {
1060
+ const waits = await analytics.waits.list({
1061
+ runId: opts.runId,
1062
+ pagination: {
1063
+ sortOrder: opts.sort || 'desc',
1064
+ cursor,
1065
+ limit: opts.limit || DEFAULT_PAGE_SIZE,
1066
+ },
1067
+ });
1068
+ return {
1069
+ data: waits.data,
1070
+ cursor: waits.cursor,
1071
+ hasMore: waits.hasMore,
1072
+ pageInfo: getPageInfo(waits),
1073
+ };
1074
+ };
1075
+ if (opts.json) {
1076
+ const page = await fetchSleepsPage(opts.cursor);
1077
+ showJson(page.data);
1078
+ return;
1079
+ }
1080
+ await setupListPagination({
1081
+ initialCursor: opts.cursor,
1082
+ interactive: opts.interactive,
1083
+ fetchPage: fetchSleepsPage,
1084
+ displayPage: async (waits) => {
1085
+ logger.log(showTable(waits, ['waitId', 'status', 'createdAt', 'resumeAt', 'completedAt'], { ...opts, disableRelativeDates: true }));
1086
+ },
1087
+ });
1088
+ };
911
1089
  export const listSleeps = async (world, opts = {}) => {
912
1090
  if (!opts.runId) {
913
1091
  logger.error('run-id is required for listing sleeps. Usage: `workflow inspect sleeps --runId=<id>`');
@@ -922,6 +1100,19 @@ export const listSleeps = async (world, opts = {}) => {
922
1100
  if (opts.withData) {
923
1101
  logger.warn('`withData` flag is ignored when listing sleeps');
924
1102
  }
1103
+ // Prefer the analytics read path for wait/sleep listing when available.
1104
+ if (world.analytics) {
1105
+ try {
1106
+ await listSleepsViaAnalytics(world.analytics, opts);
1107
+ return;
1108
+ }
1109
+ catch (error) {
1110
+ if (handleApiError(error, opts.backend)) {
1111
+ process.exit(1);
1112
+ }
1113
+ throw error;
1114
+ }
1115
+ }
925
1116
  try {
926
1117
  // Fetch all events for the run with resolveData='all' to get wait eventData
927
1118
  const events = await world.events.list({
@@ -939,7 +1130,7 @@ export const listSleeps = async (world, opts = {}) => {
939
1130
  // Group wait events by correlationId
940
1131
  const waitEventsByCorrelation = new Map();
941
1132
  for (const event of events.data) {
942
- if (event.correlationId?.startsWith('wait_')) {
1133
+ if (isWaitEventType(event.eventType) && event.correlationId) {
943
1134
  const existing = waitEventsByCorrelation.get(event.correlationId) ?? [];
944
1135
  existing.push(event);
945
1136
  waitEventsByCorrelation.set(event.correlationId, existing);
@@ -997,4 +1188,4 @@ export const listSleeps = async (world, opts = {}) => {
997
1188
  throw error;
998
1189
  }
999
1190
  };
1000
- //# sourceMappingURL=output.js.map
1191
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0cHV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9pbnNwZWN0L291dHB1dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsb0JBQW9CLEVBRXBCLG9CQUFvQixFQUNwQixtQkFBbUIsR0FDcEIsTUFBTSw4QkFBOEIsQ0FBQztBQUN0QyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsYUFBYSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUUsT0FBTyxFQUdMLGVBQWUsR0FJaEIsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFFMUIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxZQUFZLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTFDLE9BQU8sRUFDTCxzQ0FBc0MsRUFDdEMsbUNBQW1DLEdBQ3BDLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFFTCxpQkFBaUIsRUFDakIsY0FBYyxFQUNkLFlBQVksR0FDYixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXJEOzs7Ozs7R0FNRztBQUNILFNBQVMsY0FBYyxDQUFDLEtBQVksRUFBRSxPQUFnQjtJQUNwRCxJQUFJLENBQUMsT0FBTztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQzFCLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDL0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQTJDLENBQUM7SUFDakUsT0FBTyxDQUFDLEtBQWEsRUFBRSxFQUFFO1FBQ3ZCLElBQUksTUFBTSxHQUFHLEtBQUssQ0FBQyxH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QUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNuQixNQUFNLEtBQUssR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3BDLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDcEMsT0FBTyxJQUFJLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUM3RCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2QsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2pCLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxDQUFDLEdBQUcsQ0FDUixTQUFTLENBQ1AsTUFBOEMsRUFDOUMsaUJBQWlCLEVBQ2pCLEVBQUUsR0FBRyxJQUFJLEVBQUUsb0JBQW9CLEVBQUUsSUFBSSxFQUFFLENBQ3hDLENBQ0YsQ0FBQztJQUNKLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsSUFBSSxjQUFjLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ3hDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEIsQ0FBQztRQUNELE1BQU0sS0FBSyxDQUFDO0lBQ2QsQ0FBQztBQUNILENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGRlcml2ZVJ1blBheWxvYWRLZXlzLFxuICB0eXBlIEVuY3J5cHRpb25LZXlQYXJhbSxcbiAgZ2V0RGVzZXJpYWxpemVTdHJlYW0sXG4gIGdldEV4dGVybmFsUmV2aXZlcnMsXG59IGZyb20gJ0B3b3JrZmxvdy9jb3JlL3NlcmlhbGl6YXRpb24nO1xuaW1wb3J0IHsgVkVSQ0VMXzQwM19FUlJPUl9NRVNTQUdFIH0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQgeyBwYXJzZVN0ZXBOYW1lLCBwYXJzZVdvcmtmbG93TmFtZSB9IGZyb20gJ0B3b3JrZmxvdy91dGlscy9wYXJzZS1uYW1lJztcbmltcG9ydCB7XG4gIHR5cGUgRXZlbnQsXG4gIHR5cGUgSG9vayxcbiAgaXNXYWl0RXZlbnRUeXBlLFxuICB0eXBlIFN0ZXAsXG4gIHR5cGUgV29ya2Zsb3dSdW4sXG4gIHR5cGUgV29ybGQsXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgY2hhbGsgZnJvbSAnY2hhbGsnO1xuXG5pbXBvcnQgeyBmb3JtYXREaXN0YW5jZSB9IGZyb20gJ2RhdGUtZm5zJztcbmltcG9ydCBUYWJsZSBmcm9tICdlYXN5LXRhYmxlJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL2NvbmZpZy9sb2cuanMnO1xuaW1wb3J0IHR5cGUgeyBJbnNwZWN0Q0xJT3B0aW9ucyB9IGZyb20gJy4uL2NvbmZpZy90eXBlcy5qcyc7XG5pbXBvcnQge1xuICBnZXRPYnNlcnZhYmlsaXR5VXBncmFkZVJlcXVpcmVkTWVzc2FnZSxcbiAgaXNPYnNlcnZhYmlsaXR5VXBncmFkZVJlcXVpcmVkRXJyb3IsXG59IGZyb20gJy4vZXJyb3JzLmpzJztcbmltcG9ydCB7XG4gIHR5cGUgRW5jcnlwdGlvbktleVJlc29sdmVyLFxuICBoeWRyYXRlUmVzb3VyY2VJTyxcbiAgaXNFbmNyeXB0ZWRSZWYsXG4gIGlzRXhwaXJlZFJlZixcbn0gZnJvbSAnLi9oeWRyYXRpb24uanMnO1xuaW1wb3J0IHsgcmVzb2x2ZVRpbWVXaW5kb3cgfSBmcm9tICcuL3RpbWUtd2luZG93LmpzJztcblxuLyoqXG4gKiBDcmVhdGUgYW4gRW5jcnlwdGlvbktleVJlc29sdmVyIGZyb20gYSBXb3JsZCBpbnN0YW5jZS5cbiAqIFJldHVybnMgbnVsbCBpZiBkZWNyeXB0IGlzIGZhbHNlIOKAlCBlbmNyeXB0ZWQgZGF0YSB3aWxsIHNob3cgYXMgYSBwbGFjZWhvbGRlci5cbiAqXG4gKiBUaGUgcmVzb2x2ZXIgZmV0Y2hlcyB0aGUgZnVsbCBXb3JrZmxvd1J1biAoY2FjaGVkIHBlciBydW5JZCkgc28gdGhhdCB0aGVcbiAqIFdvcmxkIGNhbiBpbnNwZWN0IGRlcGxveW1lbnQtc3BlY2lmaWMgZmllbGRzIGZvciBrZXkgcmVzb2x1dGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUmVzb2x2ZXIod29ybGQ6IFdvcmxkLCBkZWNyeXB0OiBib29sZWFuKTogRW5jcnlwdGlvbktleVJlc29sdmVyIHtcbiAgaWYgKCFkZWNyeXB0KSByZXR1cm4gbnVsbDtcbiAgaWYgKCF3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgY2FjaGUgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxVaW50OEFycmF5IHwgdW5kZWZpbmVkPj4oKTtcbiAgcmV0dXJuIChydW5JZDogc3RyaW5nKSA9PiB7XG4gICAgbGV0IGNhY2hlZCA9IGNhY2hlLmdldChydW5JZCk7XG4gICAgaWYgKCFjYWNoZWQpIHtcbiAgICAgIGNhY2hlZCA9IHdvcmxkLnJ1bnNcbiAgICAgICAgLmdldChydW5JZClcbiAgICAgICAgLnRoZW4oKHJ1bikgPT4gd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1biEocnVuKSk7XG4gICAgICBjYWNoZS5zZXQocnVuSWQsIGNhY2hlZCk7XG4gICAgfVxuICAgIHJldHVybiBjYWNoZWQ7XG4gIH07XG59XG5cbmltcG9ydCB7XG4gIHR5cGUgQW5hbHl0aWNzUGFnZUluZm8sXG4gIHR5cGUgUGFnZURhdGEsXG4gIHNldHVwTGlzdFBhZ2luYXRpb24sXG59IGZyb20gJy4vcGFnaW5hdGlvbi5qcyc7XG5pbXBvcnQgeyBzdHJlYW1Ub0NvbnNvbGUgfSBmcm9tICcuL3N0cmVhbS5qcyc7XG5pbXBvcnQge1xuICBmb3JtYXRJU09EYXRlLFxuICBmb3JtYXRTdGF0dXMgYXMgZm9ybWF0U3RhdHVzQWJicmV2LFxuICBnZXREaXNwbGF5U2V0dGluZ3MsXG4gIGdldFRlcm1pbmFsV2lkdGgsXG4gIGlzQ0ksXG59IGZyb20gJy4vdGVybWluYWwtdXRpbHMuanMnO1xuXG5jb25zdCBERUZBVUxUX1BBR0VfU0laRSA9IDIwO1xubGV0IFRBQkxFX1RSVU5DQVRFX0lPX0xFTkdUSCA9IDE1OyAvLyBXaWxsIGJlIGFkanVzdGVkIGJhc2VkIG9uIHRlcm1pbmFsIHdpZHRoXG5cbmNvbnN0IFdPUktGTE9XX1JVTl9JT19QUk9QUzogKGtleW9mIFdvcmtmbG93UnVuKVtdID0gWydpbnB1dCcsICdvdXRwdXQnXTtcblxuY29uc3QgU1RFUF9JT19QUk9QUzogKGtleW9mIFN0ZXApW10gPSBbJ2lucHV0JywgJ291dHB1dCddO1xuXG5jb25zdCBXT1JLRkxPV19SVU5fTElTVEVEX1BST1BTOiAoa2V5b2YgV29ya2Zsb3dSdW4pW10gPSBbXG4gICdydW5JZCcsXG4gICd3b3JrZmxvd05hbWUnLFxuICAnc3RhdHVzJyxcbiAgJ3N0YXJ0ZWRBdCcsXG4gICdjb21wbGV0ZWRBdCcsXG4gIC4uLldPUktGTE9XX1JVTl9JT19QUk9QUyxcbl07XG5cbmNvbnN0IFNURVBfTElTVEVEX1BST1BTOiAoa2V5b2YgU3RlcClbXSA9IFtcbiAgJ3J1bklkJyxcbiAgJ3N0ZXBJZCcsXG4gICdzdGVwTmFtZScsXG4gICdzdGF0dXMnLFxuICAnc3RhcnRlZEF0JyxcbiAgJ2NvbXBsZXRlZEF0JyxcbiAgLi4uU1RFUF9JT19QUk9QUyxcbl07XG5cbmNvbnN0IEVWRU5UX0lPX1BST1BTOiAoa2V5b2YgRXZlbnQgfCAnZXZlbnREYXRhJylbXSA9IFsnZXZlbnREYXRhJ107XG5cbmNvbnN0IEVWRU5UX0xJU1RFRF9QUk9QUzogKGtleW9mIEV2ZW50IHwgJ2V2ZW50RGF0YScpW10gPSBbXG4gICdldmVudElkJyxcbiAgJ2V2ZW50VHlwZScsXG4gICdjb3JyZWxhdGlvbklkJyxcbiAgJ2NyZWF0ZWRBdCcsXG4gIC4uLkVWRU5UX0lPX1BST1BTLFxuXTtcblxuLy8gY29uc3QgSE9PS19EQVRBX1BST1BTOiAoa2V5b2YgSG9vayB8ICdoYXNSZXNwb25zZScpW10gPSBbJ2hhc1Jlc3BvbnNlJ107XG5cbmNvbnN0IEhPT0tfTElTVEVEX1BST1BTOiAoa2V5b2YgSG9vayB8ICdoYXNSZXNwb25zZScpW10gPSBbXG4gICdydW5JZCcsXG4gICdob29rSWQnLFxuICAnb3duZXJJZCcsXG4gICdjcmVhdGVkQXQnLFxuICAvLyAuLi5IT09LX0RBVEFfUFJPUFMsXG5dO1xuXG5pbnRlcmZhY2UgU2xlZXAge1xuICBjb3JyZWxhdGlvbklkOiBzdHJpbmc7XG4gIHJ1bklkOiBzdHJpbmc7XG4gIGV2ZW50SWQ6IHN0cmluZztcbiAgY3JlYXRlZEF0OiBEYXRlO1xuICByZXN1bWVBdDogRGF0ZSB8IHVuZGVmaW5lZDtcbiAgY29tcGxldGVkQXQ6IERhdGUgfCB1bmRlZmluZWQ7XG59XG5cbmNvbnN0IFdBSVRfTElTVEVEX1BST1BTOiAoa2V5b2YgU2xlZXApW10gPSBbXG4gICdjb3JyZWxhdGlvbklkJyxcbiAgJ2V2ZW50SWQnLFxuICAnY3JlYXRlZEF0JyxcbiAgJ3Jlc3VtZUF0JyxcbiAgJ2NvbXBsZXRlZEF0Jyxcbl07XG5cbmNvbnN0IFNUQVRVU19DT0xPUlM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogc3RyaW5nKSA9PiBzdHJpbmc+ID0ge1xuICBydW5uaW5nOiBjaGFsay5ibHVlLFxuICBjb21wbGV0ZWQ6IGNoYWxrLmdyZWVuLFxuICBmYWlsZWQ6IGNoYWxrLnJlZCxcbiAgY2FuY2VsbGVkOiBjaGFsay5zdHJpa2V0aHJvdWdoLnllbGxvdyxcbiAgcGVuZGluZzogY2hhbGsuYmx1ZSxcbiAgd2FpdGluZzogY2hhbGsuYmx1ZSxcbn07XG5cbmNvbnN0IGlzU3RyZWFtSWQgPSAodmFsdWU6IHN0cmluZykgPT4ge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS5zdGFydHNXaXRoKCdzdHJtXycpO1xufTtcblxuY29uc3Qgc2hvd1N0YXR1c0xlZ2VuZCA9ICgpID0+IHtcbiAgbG9nZ2VyLmxvZygnXFxuU3RhdHVzIExlZ2VuZDonKTtcbiAgY29uc3Qgc3RhdHVzZXMgPSBbXG4gICAgJ3J1bm5pbmcnLFxuICAgICdjb21wbGV0ZWQnLFxuICAgICdmYWlsZWQnLFxuICAgICdjYW5jZWxsZWQnLFxuICAgICdwZW5kaW5nJyxcbiAgICAnd2FpdGluZycsXG4gIF07XG5cbiAgY29uc3QgbGVnZW5kSXRlbXMgPSBzdGF0dXNlcy5tYXAoKHN0YXR1cykgPT4ge1xuICAgIGNvbnN0IGNvbG9yRnVuYyA9IFNUQVRVU19DT0xPUlNbc3RhdHVzXTtcbiAgICBjb25zdCBhYmJyZXYgPSBmb3JtYXRTdGF0dXNBYmJyZXYoc3RhdHVzLCB0cnVlKTtcbiAgICByZXR1cm4gYCR7Y29sb3JGdW5jKGFiYnJldil9ID0gJHtzdGF0dXN9YDtcbiAgfSk7XG5cbiAgbG9nZ2VyLmxvZyhgICAke2xlZ2VuZEl0ZW1zLmpvaW4oJyAgJyl9YCk7XG4gIGxvZ2dlci5sb2coJycpO1xufTtcblxuY29uc3QgaXNTbGVlcFN0ZXAgPSAoc3RlcE5hbWU6IHN0cmluZykgPT4ge1xuICByZXR1cm4gc3RlcE5hbWUuaW5jbHVkZXMoJy1zbGVlcCcpO1xufTtcblxuY29uc3QgY2hlY2tBbmRIYW5kbGVWZXJjZWxBY2Nlc3NFcnJvciA9IChcbiAgZXJyb3I6IHVua25vd24sXG4gIGJhY2tlbmQ/OiBzdHJpbmdcbik6IGJvb2xlYW4gPT4ge1xuICBpZiAoYmFja2VuZCA9PT0gJ3ZlcmNlbCcgJiYgZXJyb3IgJiYgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0Jykge1xuICAgIGNvbnN0IGVyciA9IGVycm9yIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIGlmIChlcnIuc3RhdHVzID09PSA0MDMpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihWRVJDRUxfNDAzX0VSUk9SX01FU1NBR0UpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmNvbnN0IGV4dHJhY3RFcnJvck1lc3NhZ2UgPSAoXG4gIGVycjogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChlcnIubWVzc2FnZSAmJiB0eXBlb2YgZXJyLm1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGVyci5tZXNzYWdlO1xuICB9XG5cbiAgaWYgKGVyci5ib2R5ICYmIHR5cGVvZiBlcnIuYm9keSA9PT0gJ29iamVjdCcpIHtcbiAgICBjb25zdCBib2R5ID0gZXJyLmJvZHkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgaWYgKGJvZHkubWVzc2FnZSAmJiB0eXBlb2YgYm9keS5tZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGJvZHkubWVzc2FnZTtcbiAgICB9XG4gICAgaWYgKGJvZHkuZXJyb3IgJiYgdHlwZW9mIGJvZHkuZXJyb3IgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gYm9keS5lcnJvcjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufTtcblxuY29uc3QgZ2V0UGFnZUluZm8gPSAocmVzdWx0OiB1bmtub3duKTogQW5hbHl0aWNzUGFnZUluZm8gfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoXG4gICAgdHlwZW9mIHJlc3VsdCAhPT0gJ29iamVjdCcgfHxcbiAgICByZXN1bHQgPT09IG51bGwgfHxcbiAgICAhKCdwYWdlSW5mbycgaW4gcmVzdWx0KVxuICApIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiAocmVzdWx0IGFzIHsgcGFnZUluZm8/OiBBbmFseXRpY3NQYWdlSW5mbyB9KS5wYWdlSW5mbztcbn07XG5cbmNvbnN0IGhhbmRsZUFwaUVycm9yID0gKGVycm9yOiB1bmtub3duLCBiYWNrZW5kPzogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gIC8vIEZpcnN0IGNoZWNrIGZvciBWZXJjZWwgYWNjZXNzIGVycm9yc1xuICBpZiAoY2hlY2tBbmRIYW5kbGVWZXJjZWxBY2Nlc3NFcnJvcihlcnJvciwgYmFja2VuZCkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChpc09ic2VydmFiaWxpdHlVcGdyYWRlUmVxdWlyZWRFcnJvcihlcnJvcikpIHtcbiAgICBsb2dnZXIuZXJyb3IoZ2V0T2JzZXJ2YWJpbGl0eVVwZ3JhZGVSZXF1aXJlZE1lc3NhZ2UoKSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBIYW5kbGUgb3RoZXIgSFRUUCBlcnJvcnNcbiAgaWYgKGVycm9yICYmIHR5cGVvZiBlcnJvciA9PT0gJ29iamVjdCcpIHtcbiAgICBjb25zdCBlcnIgPSBlcnJvciBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuICAgIC8vIEhhbmRsZSA0MDAgQmFkIFJlcXVlc3RcbiAgICBpZiAoZXJyLnN0YXR1cyA9PT0gNDAwKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0JhZCBSZXF1ZXN0OiBUaGUgcmVxdWVzdCB3YXMgaW52YWxpZC4nKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBleHRyYWN0RXJyb3JNZXNzYWdlKGVycik7XG4gICAgICBpZiAobWVzc2FnZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYERldGFpbHM6ICR7bWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBvdGhlciBIVFRQIGVycm9ycyAoNDA0LCA1MDAsIGV0Yy4pXG4gICAgaWYgKHR5cGVvZiBlcnIuc3RhdHVzID09PSAnbnVtYmVyJyAmJiBlcnIuc3RhdHVzID49IDQwMCkge1xuICAgICAgbG9nZ2VyLmVycm9yKGBIVFRQIEVycm9yICR7ZXJyLnN0YXR1c306ICR7Z2V0U3RhdHVzVGV4dChlcnIuc3RhdHVzKX1gKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBleHRyYWN0RXJyb3JNZXNzYWdlKGVycik7XG4gICAgICBpZiAobWVzc2FnZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYERldGFpbHM6ICR7bWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmNvbnN0IGdldFN0YXR1c1RleHQgPSAoc3RhdHVzOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBzdGF0dXNUZXh0czogUmVjb3JkPG51bWJlciwgc3RyaW5nPiA9IHtcbiAgICA0MDA6ICdCYWQgUmVxdWVzdCcsXG4gICAgNDAxOiAnVW5hdXRob3JpemVkJyxcbiAgICA0MDI6ICdQYXltZW50IFJlcXVpcmVkJyxcbiAgICA0MDM6ICdGb3JiaWRkZW4nLFxuICAgIDQwNDogJ05vdCBGb3VuZCcsXG4gICAgNDI5OiAnVG9vIE1hbnkgUmVxdWVzdHMnLFxuICAgIDUwMDogJ0ludGVybmFsIFNlcnZlciBFcnJvcicsXG4gICAgNTAyOiAnQmFkIEdhdGV3YXknLFxuICAgIDUwMzogJ1NlcnZpY2UgVW5hdmFpbGFibGUnLFxuICB9O1xuICByZXR1cm4gc3RhdHVzVGV4dHNbc3RhdHVzXSB8fCAnVW5rbm93biBFcnJvcic7XG59O1xuXG5jb25zdCB0cnVuY2F0ZU5hbWVJZk5lZWRlZCA9IChuYW1lOiBzdHJpbmcsIG1heExlbmd0aDogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgcmV0dXJuIG1heExlbmd0aCA8IG5hbWUubGVuZ3RoID8gYCR7bmFtZS5zdWJzdHJpbmcoMCwgbWF4TGVuZ3RoKX0uLi5gIDogbmFtZTtcbn07XG5cbmNvbnN0IGZvcm1hdE5hbWVGaWVsZCA9IChcbiAgbmFtZU5vblVuaXF1ZTogc3RyaW5nLFxuICB0cnVuY2F0ZUxlbmd0aDogbnVtYmVyLFxuICBpc1NsZWVwOiBib29sZWFuXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCB0cnVuY2F0ZWROYW1lID0gdHJ1bmNhdGVOYW1lSWZOZWVkZWQobmFtZU5vblVuaXF1ZSwgdHJ1bmNhdGVMZW5ndGgpO1xuICBpZiAoaXNTbGVlcCkge1xuICAgIHJldHVybiBjaGFsay55ZWxsb3dCcmlnaHQodHJ1bmNhdGVkTmFtZSk7XG4gIH1cbiAgcmV0dXJuIGNoYWxrLmJsdWUuYmx1ZUJyaWdodCh0cnVuY2F0ZWROYW1lKTtcbn07XG5cbmNvbnN0IGZvcm1hdElkRmllbGQgPSAoXG4gIHByb3A6IHN0cmluZyxcbiAgdmFsdWU6IHVua25vd24sXG4gIHNob3VsZFRydW5jYXRlSWRzOiBib29sZWFuXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4ge1xuICBjb25zdCB2YWx1ZVN0ciA9IFN0cmluZyh2YWx1ZSk7XG4gIGNvbnN0IGlkU3RyID0gc2hvdWxkVHJ1bmNhdGVJZHMgPyB0cnVuY2F0ZUlkVG9MYXN0Q2hhcnModmFsdWVTdHIpIDogdmFsdWVTdHI7XG4gIGlmIChwcm9wID09PSAnc3RyZWFtSWQnKSB7XG4gICAgcmV0dXJuIGNoYWxrLmdyZWVuKGlkU3RyKTtcbiAgfVxuICByZXR1cm4gaWRTdHI7XG59O1xuXG5leHBvcnQgY29uc3QgZm9ybWF0VGFibGVWYWx1ZSA9IChcbiAgcHJvcDogc3RyaW5nLFxuICB2YWx1ZTogdW5rbm93bixcbiAgb3B0czogSW5zcGVjdENMSU9wdGlvbnMgPSB7fSxcbiAgZGlzcGxheVNldHRpbmdzPzogUmV0dXJuVHlwZTx0eXBlb2YgZ2V0RGlzcGxheVNldHRpbmdzPixcbiAgaXRlbT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4pID0+IHtcbiAgY29uc3QgbmFtZXNUcnVuY2F0ZSA9IGRpc3BsYXlTZXR0aW5ncz8ubmFtZXNUcnVuY2F0ZUxlbmd0aCA/PyA0MDtcbiAgY29uc3Qgc2hvdWxkVHJ1bmNhdGVJZHMgPSBkaXNwbGF5U2V0dGluZ3M/LnRydW5jYXRlSWRzVG9MYXN0Q2hhcnMgPz8gZmFsc2U7XG5cbiAgLy8gSGFuZGxlIElEcyB3aXRoIHBvdGVudGlhbCB0cnVuY2F0aW9uXG4gIGlmIChcbiAgICBbXG4gICAgICAnc3RyZWFtSWQnLFxuICAgICAgJ3J1bklkJyxcbiAgICAgICdzdGVwSWQnLFxuICAgICAgJ2hvb2tJZCcsXG4gICAgICAnZXZlbnRJZCcsXG4gICAgICAnY29ycmVsYXRpb25JZCcsXG4gICAgICAnb3duZXJJZCcsXG4gICAgXS5pbmNsdWRlcyhwcm9wKVxuICApIHtcbiAgICByZXR1cm4gZm9ybWF0SWRGaWVsZChwcm9wLCB2YWx1ZSwgc2hvdWxkVHJ1bmNhdGVJZHMpO1xuICB9XG5cbiAgLy8gSGFuZGxlIG5hbWVzIHdpdGggdHJ1bmNhdGlvblxuICBpZiAocHJvcCA9PT0gJ3N0ZXBOYW1lJykge1xuICAgIGNvbnN0IG5hbWVOb25VbmlxdWUgPSBwYXJzZVN0ZXBOYW1lKFN0cmluZyh2YWx1ZSkpPy5zaG9ydE5hbWUgfHwgJz8nO1xuICAgIHJldHVybiBmb3JtYXROYW1lRmllbGQoXG4gICAgICBuYW1lTm9uVW5pcXVlLFxuICAgICAgbmFtZXNUcnVuY2F0ZSxcbiAgICAgIGlzU2xlZXBTdGVwKFN0cmluZyh2YWx1ZSkpXG4gICAgKTtcbiAgfVxuXG4gIGlmIChwcm9wID09PSAnd29ya2Zsb3dOYW1lJykge1xuICAgIGNvbnN0IG5hbWVOb25VbmlxdWUgPSBwYXJzZVdvcmtmbG93TmFtZShTdHJpbmcodmFsdWUpKT8uc2hvcnROYW1lIHx8ICc/JztcbiAgICBjb25zdCB0cnVuY2F0ZWROYW1lID0gdHJ1bmNhdGVOYW1lSWZOZWVkZWQobmFtZU5vblVuaXF1ZSwgbmFtZXNUcnVuY2F0ZSk7XG4gICAgcmV0dXJuIGNoYWxrLmJsdWUuYmx1ZUJyaWdodCh0cnVuY2F0ZWROYW1lKTtcbiAgfVxuXG4gIGlmIChwcm9wID09PSAnb3V0cHV0JyB8fCBwcm9wID09PSAnaW5wdXQnIHx8IHByb3AgPT09ICdlcnJvcicpIHtcbiAgICBpZiAoXG4gICAgICBpdGVtICYmXG4gICAgICAnZXhwaXJlZEF0JyBpbiBpdGVtICYmXG4gICAgICBpdGVtLmV4cGlyZWRBdCAhPSBudWxsICYmXG4gICAgICBuZXcgRGF0ZShpdGVtLmV4cGlyZWRBdCBhcyBzdHJpbmcgfCBudW1iZXIgfCBEYXRlKSA8IG5ldyBEYXRlKClcbiAgICApIHtcbiAgICAgIHJldHVybiBFWFBJUkVEX0RBVEFfTUVTU0FHRTtcbiAgICB9XG4gICAgcmV0dXJuIGlubGluZUZvcm1hdElPKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChwcm9wID09PSAnc3RhdHVzJykge1xuICAgIGNvbnN0IHN0YXR1cyA9IHZhbHVlIGFzIFdvcmtmbG93UnVuWydzdGF0dXMnXSB8IFN0ZXBbJ3N0YXR1cyddO1xuICAgIGNvbnN0IGNvbG9yRnVuYyA9XG4gICAgICBTVEFUVVNfQ09MT1JTW3N0YXR1c10gPz8gKChmb3JtYXR0ZWQ6IHN0cmluZykgPT4gZm9ybWF0dGVkKTtcbiAgICBjb25zdCBmb3JtYXR0ZWRTdGF0dXMgPSBkaXNwbGF5U2V0dGluZ3M/LmFiYnJldmlhdGVTdGF0dXNcbiAgICAgID8gZm9ybWF0U3RhdHVzQWJicmV2KHN0YXR1cywgdHJ1ZSlcbiAgICAgIDogc3RhdHVzO1xuICAgIHJldHVybiBjb2xvckZ1bmMoZm9ybWF0dGVkU3RhdHVzKTtcbiAgfVxuXG4gIGlmIChwcm9wID09PSAnZXZlbnREYXRhJykge1xuICAgIHJldHVybiB0cnVuY2F0ZVN0cmluZyhKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICB9XG5cbiAgaWYgKHByb3AgPT09ICdoYXNSZXNwb25zZScpIHtcbiAgICByZXR1cm4gdmFsdWUgPyBjaGFsay5ncmVlbigndHJ1ZScpIDogY2hhbGsuZ3JheSgnZmFsc2UnKTtcbiAgfVxuXG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICByZXR1cm4gZm9ybWF0VGFibGVUaW1lc3RhbXAodmFsdWUsIG9wdHMsIGRpc3BsYXlTZXR0aW5ncyk7XG4gIH1cblxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5jb25zdCBnZXRWaXNpYmxlUHJvcHMgPSAoXG4gIHByb3BzOiBzdHJpbmdbXSxcbiAgZGlzcGxheVNldHRpbmdzOiBSZXR1cm5UeXBlPHR5cGVvZiBnZXREaXNwbGF5U2V0dGluZ3M+XG4pOiBzdHJpbmdbXSA9PiB7XG4gIGlmIChkaXNwbGF5U2V0dGluZ3MuaGlkZUNvbXBsZXRlZEF0KSB7XG4gICAgcmV0dXJuIHByb3BzLmZpbHRlcigocHJvcCkgPT4gcHJvcCAhPT0gJ2NvbXBsZXRlZEF0Jyk7XG4gIH1cbiAgcmV0dXJuIHByb3BzO1xufTtcblxuY29uc3Qgc2hvd1RhYmxlID0gKFxuICBkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLFxuICBwcm9wczogc3RyaW5nW10sXG4gIG9wdHM6IEluc3BlY3RDTElPcHRpb25zID0ge31cbikgPT4ge1xuICAvLyBHZXQgZGlzcGxheSBzZXR0aW5ncyBiYXNlZCBvbiB0ZXJtaW5hbCB3aWR0aFxuICBjb25zdCB0ZXJtaW5hbFdpZHRoID0gZ2V0VGVybWluYWxXaWR0aCgpO1xuICBjb25zdCBkaXNwbGF5U2V0dGluZ3MgPSBnZXREaXNwbGF5U2V0dGluZ3MoXG4gICAgdGVybWluYWxXaWR0aCxcbiAgICBvcHRzLndpdGhEYXRhIHx8IGZhbHNlLFxuICAgIHByb3BzLmluY2x1ZGVzKCdydW5OYW1lJylcbiAgKTtcblxuICAvLyBGaWx0ZXIgb3V0IGNvbXBsZXRlZEF0IGNvbHVtbiBpZiBuZWVkZWRcbiAgY29uc3QgdmlzaWJsZVByb3BzID0gZ2V0VmlzaWJsZVByb3BzKHByb3BzLCBkaXNwbGF5U2V0dGluZ3MpO1xuXG4gIC8vIFVwZGF0ZSB0cnVuY2F0ZSBsZW5ndGggZm9yIElPIGZpZWxkc1xuICBjb25zdCBvcmlnaW5hbFRydW5jYXRlTGVuZ3RoID0gVEFCTEVfVFJVTkNBVEVfSU9fTEVOR1RIO1xuICBUQUJMRV9UUlVOQ0FURV9JT19MRU5HVEggPSBkaXNwbGF5U2V0dGluZ3MuZGF0YUZpZWxkV2lkdGg7XG5cbiAgLy8gU2hvdyBzdGF0dXMgbGVnZW5kIGlmIHVzaW5nIGFiYnJldmlhdGVkIHN0YXR1c1xuICBpZiAoXG4gICAgZGF0YS5sZW5ndGggPiAwICYmXG4gICAgZGlzcGxheVNldHRpbmdzLmFiYnJldmlhdGVTdGF0dXMgJiZcbiAgICB2aXNpYmxlUHJvcHMuaW5jbHVkZXMoJ3N0YXR1cycpXG4gICkge1xuICAgIHNob3dTdGF0dXNMZWdlbmQoKTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBoZWFkZXIgbWFwcGluZyBmb3IgYWJicmV2aWF0ZWQgc3RhdHVzXG4gIGNvbnN0IGhlYWRlck1hcDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBpZiAoZGlzcGxheVNldHRpbmdzLmFiYnJldmlhdGVTdGF0dXMgJiYgdmlzaWJsZVByb3BzLmluY2x1ZGVzKCdzdGF0dXMnKSkge1xuICAgIGhlYWRlck1hcFsnc3RhdHVzJ10gPSAnUyc7XG4gIH1cblxuICAvLyBBZGQgYSBibGFuayBsaW5lIGJlZm9yZSBhbnkgdGFibGVcbiAgY29uc3QgdGFibGUgPSBuZXcgVGFibGUoKTtcbiAgaWYgKGRhdGEgJiYgZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICBsb2dnZXIud2FybignTm8gZGF0YSBmb3VuZCBmb3IgdGhpcyBxdWVyeSBhbmQgcmVzb3VyY2UuXFxuJyk7XG4gICAgZm9yIChjb25zdCBwcm9wIG9mIHZpc2libGVQcm9wcykge1xuICAgICAgY29uc3QgaGVhZGVyID0gaGVhZGVyTWFwW3Byb3BdIHx8IHByb3A7XG4gICAgICB0YWJsZS5jZWxsKGhlYWRlciwgJ04vQScpO1xuICAgIH1cbiAgICB0YWJsZS5uZXdSb3coKTtcbiAgICAvLyBSZXN0b3JlIG9yaWdpbmFsIHRydW5jYXRlIGxlbmd0aFxuICAgIFRBQkxFX1RSVU5DQVRFX0lPX0xFTkdUSCA9IG9yaWdpbmFsVHJ1bmNhdGVMZW5ndGg7XG4gICAgcmV0dXJuIHRhYmxlLnRvU3RyaW5nKCk7XG4gIH0gZWxzZSBpZiAoIWRhdGEpIHtcbiAgICBsb2dnZXIud2FybignRXhwZWN0aW5nIGFuIGFycmF5IG9mIGRhdGEsIGJ1dCBnb3QgbnVsbC5cXG4nKTtcbiAgfVxuICBsb2dnZXIubG9nKCcnKTtcbiAgZm9yIChjb25zdCBpdGVtIG9mIGRhdGEpIHtcbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgdmlzaWJsZVByb3BzKSB7XG4gICAgICBjb25zdCBoZWFkZXIgPSBoZWFkZXJNYXBbcHJvcF0gfHwgcHJvcDtcbiAgICAgIGNvbnN0IHZhbHVlID0gaXRlbVtwcm9wXTtcbiAgICAgIHRhYmxlLmNlbGwoXG4gICAgICAgIGhlYWRlcixcbiAgICAgICAgZm9ybWF0VGFibGVWYWx1ZShwcm9wLCB2YWx1ZSwgb3B0cywgZGlzcGxheVNldHRpbmdzLCBpdGVtKVxuICAgICAgKTtcbiAgICB9XG4gICAgdGFibGUubmV3Um93KCk7XG4gIH1cblxuICAvLyBSZXN0b3JlIG9yaWdpbmFsIHRydW5jYXRlIGxlbmd0aFxuICBUQUJMRV9UUlVOQ0FURV9JT19MRU5HVEggPSBvcmlnaW5hbFRydW5jYXRlTGVuZ3RoO1xuICByZXR1cm4gdGFibGUudG9TdHJpbmcoKTtcbn07XG5cbmNvbnN0IHNob3dKc29uID0gKGRhdGE6IHVua25vd24pID0+IHtcbiAgY29uc3QganNvbiA9IEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpO1xuICBwcm9jZXNzLnN0ZG91dC53cml0ZShgJHtqc29ufVxcbmApO1xufTtcblxuLyoqXG4gKiBEZWZlbnNpdmVseSBldmFsdWF0ZSBgV29ybGQuZGVzY3JpYmVSdW5gIGZvciBvbmUgcnVuIHJvdy5cbiAqXG4gKiBUaGUgaW50ZXJmYWNlIGNvbnRyYWN0IHNheXMgaW1wbGVtZW50YXRpb25zIGFyZSBwdXJlIGFuZCBtdXN0IG5vdFxuICogdGhyb3cg4oCUIGJ1dCBpdCBpcyBhbiBleHRlcm5hbCBleHRlbnNpb24gcG9pbnQsIHNvIHRoZSBDTEkgZG9lcyBub3RcbiAqIHRydXN0IHRoYXQ6IGEgdGhyb3dpbmcgaW1wbGVtZW50YXRpb24gY29udHJpYnV0ZXMgbm8gZmllbGRzIGluc3RlYWRcbiAqIG9mIGNyYXNoaW5nIHRoZSBjb21tYW5kLiBLZXlzIHRoYXQgYWxyZWFkeSBleGlzdCBvbiB0aGUgcnVuIHJvdyBhcmVcbiAqIGRyb3BwZWQgc28gYSB3b3JsZCBjYW4gbmV2ZXIgb3ZlcndyaXRlIGNhbm9uaWNhbCBmaWVsZHMgKGBzdGF0dXNgLFxuICogYHJ1bklkYCwgLi4uKSBpbiBpbnNwZWN0IG91dHB1dC5cbiAqL1xuY29uc3Qgc2FmZVdvcmxkRmllbGRzID0gYXN5bmMgKFxuICBkZXNjcmliZVJ1bjogTm9uTnVsbGFibGU8V29ybGRbJ2Rlc2NyaWJlUnVuJ10+LFxuICByb3c6IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bGw+PiA9PiB7XG4gIGxldCBmaWVsZHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bGw+IHwgbnVsbDtcbiAgdHJ5IHtcbiAgICAvLyBUaGUgaG9vayBtYXkgYmUgc3luYyBvciBhc3luYzsgYSByZWplY3Rpb24gaXMgdHJlYXRlZCB0aGUgc2FtZSBhc1xuICAgIC8vIGEgdGhyb3cg4oCUIG5vIGZpZWxkcy5cbiAgICBmaWVsZHMgPSBhd2FpdCBkZXNjcmliZVJ1bihyb3cpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgaWYgKCFmaWVsZHMpIHJldHVybiB7fTtcbiAgY29uc3Qgc2FmZTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVsbD4gPSB7fTtcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZmllbGRzKSkge1xuICAgIGlmICghKGtleSBpbiByb3cpKSB7XG4gICAgICBzYWZlW2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHNhZmU7XG59O1xuXG5jb25zdCBzaG93SnNvblBhZ2UgPSA8VD4ocGFnZTogUGFnZURhdGE8VD4pID0+IHtcbiAgc2hvd0pzb24oe1xuICAgIGRhdGE6IHBhZ2UuZGF0YSxcbiAgICBjdXJzb3I6IHBhZ2UuY3Vyc29yLFxuICAgIGhhc01vcmU6IHBhZ2UuaGFzTW9yZSxcbiAgICAuLi4ocGFnZS5wYWdlSW5mbyA/IHsgcGFnZUluZm86IHBhZ2UucGFnZUluZm8gfSA6IHt9KSxcbiAgfSk7XG59O1xuXG4vKipcbiAqIEluIHRhYmxlcywgd2Ugd2FudCB0byBzaG93IGEgc2hvcnRlciB0aW1lc3RhbXAsIFlZWVktTU0tREQgSEg6TU06U1NcbiAqL1xuY29uc3QgZm9ybWF0VGFibGVUaW1lc3RhbXAgPSAoXG4gIHZhbHVlOiBEYXRlLFxuICBvcHRzOiBJbnNwZWN0Q0xJT3B0aW9ucyA9IHt9LFxuICBkaXNwbGF5U2V0dGluZ3M/OiBSZXR1cm5UeXBlPHR5cGVvZiBnZXREaXNwbGF5U2V0dGluZ3M+XG4pID0+IHtcbiAgLy8gRm9ybWF0IElTTyB0aW1lIHdpdGhvdXQgVCBhbmQgWlxuICBjb25zdCBpc29UaW1lID0gZm9ybWF0SVNPRGF0ZSh2YWx1ZSk7XG5cbiAgLy8gU2hvdyByZWxhdGl2ZSB0aW1lIG9ubHkgaWY6XG4gIC8vIC0gTm90IGluIENJIG1vZGVcbiAgLy8gLSBEaXNwbGF5IHNldHRpbmdzIGFsbG93IGl0IChiYXNlZCBvbiB0ZXJtaW5hbCB3aWR0aClcbiAgLy8gLSB3aXRoRGF0YSBpcyBkaXNhYmxlZCAobW9yZSBzcGFjZSBhdmFpbGFibGUpXG4gIC8vIC0gTm90IGluIEpTT04gbW9kZVxuICAvLyAtIGRpc2FibGVSZWxhdGl2ZURhdGVzIGlzIG5vdCBzZXRcbiAgY29uc3Qgc2hvdWxkU2hvd1JlbGF0aXZlID1cbiAgICAhaXNDSSgpICYmXG4gICAgZGlzcGxheVNldHRpbmdzPy5zaG93UmVsYXRpdmVEYXRlcyAhPT0gZmFsc2UgJiZcbiAgICAhb3B0cy53aXRoRGF0YSAmJlxuICAgICFvcHRzLmpzb24gJiZcbiAgICAhb3B0cy5kaXNhYmxlUmVsYXRpdmVEYXRlcztcblxuICBpZiAoc2hvdWxkU2hvd1JlbGF0aXZlKSB7XG4gICAgY29uc3QgcmVsYXRpdmUgPSBmb3JtYXREaXN0YW5jZSh2YWx1ZSwgbmV3IERhdGUoKSwgeyBhZGRTdWZmaXg6IHRydWUgfSk7XG4gICAgcmV0dXJuIGAke2lzb1RpbWV9ICgke3JlbGF0aXZlfSlgO1xuICB9XG5cbiAgcmV0dXJuIGlzb1RpbWU7XG59O1xuXG5jb25zdCB0cnVuY2F0ZVN0cmluZyA9IChcbiAgc3RyOiBzdHJpbmcsXG4gIG1heExlbmd0aDogbnVtYmVyID0gVEFCTEVfVFJVTkNBVEVfSU9fTEVOR1RIXG4pID0+IHtcbiAgcmV0dXJuIHN0ciAmJiBzdHIubGVuZ3RoID4gbWF4TGVuZ3RoXG4gICAgPyBgJHtzdHIuc3Vic3RyaW5nKDAsIG1heExlbmd0aCl9Li4uYFxuICAgIDogc3RyO1xufTtcblxuY29uc3QgdHJ1bmNhdGVJZFRvTGFzdENoYXJzID0gKGlkOiBzdHJpbmcsIGNoYXJzOiBudW1iZXIgPSA0KTogc3RyaW5nID0+IHtcbiAgaWYgKCFpZCB8fCBpZC5sZW5ndGggPD0gY2hhcnMpIHJldHVybiBpZDtcbiAgcmV0dXJuIGAuLi4ke2lkLnN1YnN0cmluZyhpZC5sZW5ndGggLSBjaGFycyl9YDtcbn07XG5cbmNvbnN0IHNob3dJbnNwZWN0SW5mb0JveCA9IChyZXNvdXJjZTogc3RyaW5nKSA9PiB7XG4gIGxvZ2dlci5pbmZvKFxuICAgIGBUbyB2aWV3IGRldGFpbHMgZm9yIGEgJHtyZXNvdXJjZX0sIHVzZSBcXGB3b3JrZmxvdyBpbnNwZWN0ICR7cmVzb3VyY2V9XFxgIDxpZD5gXG4gICk7XG4gIGxvZ2dlci5pbmZvKFxuICAgIGBUbyB2aWV3IHRoZSBjb250ZW50IG9mIGFueSBzdHJlYW0sIHVzZSBcXGB3b3JrZmxvdyBpbnNwZWN0IHN0cmVhbSA8c3RyZWFtLWlkPlxcYGBcbiAgKTtcbn07XG5cbmNvbnN0IEVYUElSRURfREFUQV9NRVNTQUdFID0gY2hhbGsuZ3JheSgnPGRhdGEgZXhwaXJlZD4nKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBydW4gaGFzIGV4cGlyZWQgZGF0YSBzdG9yYWdlIChydW4tbGV2ZWwgZXhwaXJlZEF0IGZpZWxkKS5cbiAqIE9ubHkgcmV0dXJucyB0cnVlIHdoZW4gYGV4cGlyZWRBdGAgaXMgaW4gdGhlIHBhc3QuXG4gKi9cbmV4cG9ydCBjb25zdCBoYXNFeHBpcmVkRGF0YSA9IChydW46IFdvcmtmbG93UnVuKTogYm9vbGVhbiA9PiB7XG4gIHJldHVybiAoXG4gICAgJ2V4cGlyZWRBdCcgaW4gcnVuICYmXG4gICAgcnVuLmV4cGlyZWRBdCAhPSBudWxsICYmXG4gICAgbmV3IERhdGUocnVuLmV4cGlyZWRBdCkgPCBuZXcgRGF0ZSgpXG4gICk7XG59O1xuXG4vKipcbiAqIENoZWNrcyBpZiBhbnkgZGF0YSBmaWVsZCBpbiBhIGh5ZHJhdGVkIHJlc291cmNlIGhhcyBiZWVuIHJlcGxhY2VkIHdpdGggYW5cbiAqIGV4cGlyZWQgcGxhY2Vob2xkZXIuIFdvcmtzIGZvciBydW5zLCBzdGVwcywgaG9va3MsIGFuZCBldmVudHMg4oCUIHVubGlrZVxuICogYGhhc0V4cGlyZWREYXRhYCB3aGljaCBvbmx5IGNoZWNrcyB0aGUgcnVuLWxldmVsIGBleHBpcmVkQXRgIGZpZWxkLlxuICovXG5jb25zdCBoYXNFeHBpcmVkRmllbGRzID0gKHJlc291cmNlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IGJvb2xlYW4gPT4ge1xuICByZXR1cm4gWydpbnB1dCcsICdvdXRwdXQnLCAnZXJyb3InLCAnbWV0YWRhdGEnXS5zb21lKChrZXkpID0+XG4gICAgaXNFeHBpcmVkUmVmKHJlc291cmNlW2tleV0pXG4gICk7XG59O1xuXG4vKipcbiAqIFRha2VzIGh5ZHJhdGVkIHN0ZXAvd29ya2Zsb3cgaW5wdXQvb3V0cHV0IGFuZCBzZXJpYWxpemVzIGl0IGZvciBpbmxpbmUgZGlzcGxheS5cbiAqL1xuY29uc3QgaW5saW5lRm9ybWF0SU8gPSA8VD4oaW86IFQsIHRvcExldmVsOiBib29sZWFuID0gdHJ1ZSk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHR5cGUgPSB0eXBlb2YgaW87XG4gIGxldCB2YWx1ZSA9ICcnO1xuICBpZiAoaW8gPT09IHVuZGVmaW5lZCkge1xuICAgIHZhbHVlID0gJzxlbXB0eT4nO1xuICB9IGVsc2UgaWYgKGlvID09PSBudWxsKSB7XG4gICAgdmFsdWUgPSAnPG51bGw+JztcbiAgfSBlbHNlIGlmIChpc0VuY3J5cHRlZFJlZihpbykpIHtcbiAgICB2YWx1ZSA9IGNoYWxrLmRpbS55ZWxsb3coJ1xcdXsxRjUxMn0gRW5jcnlwdGVkJyk7XG4gIH0gZWxzZSBpZiAoaXNFeHBpcmVkUmVmKGlvKSkge1xuICAgIHZhbHVlID0gY2hhbGsuZ3JheSgnPGRhdGEgZXhwaXJlZD4nKTtcbiAgfSBlbHNlIGlmIChpbyAmJiBBcnJheS5pc0FycmF5KGlvKSkge1xuICAgIGlmIChpby5sZW5ndGggPT09IDApIHtcbiAgICAgIHZhbHVlID0gJzxlbXB0eT4nO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzdHJpbmdpZmllZCA9IGlvXG4gICAgICAgIC5tYXAoKGl0ZW0pID0+IGlubGluZUZvcm1hdElPKGl0ZW0sIGZhbHNlKSlcbiAgICAgICAgLmpvaW4oJywnKTtcbiAgICAgIGlmIChzdHJpbmdpZmllZC5sZW5ndGggPiBUQUJMRV9UUlVOQ0FURV9JT19MRU5HVEggJiYgdG9wTGV2ZWwpIHtcbiAgICAgICAgdmFsdWUgPSBjaGFsay55ZWxsb3coYCR7aW8ubGVuZ3RofSBhcmdzYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWx1ZSA9IHN0cmluZ2lmaWVkO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgIGlmIChpbyBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIHZhbHVlID0gaW8udG9JU09TdHJpbmcoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgPSB0cnVuY2F0ZVN0cmluZyhKU09OLnN0cmluZ2lmeShpbykpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChbJ3N0cmluZycsICdudW1iZXInLCAnYm9vbGVhbiddLmluY2x1ZGVzKHR5cGUpKSB7XG4gICAgaWYgKGlzU3RyZWFtSWQoaW8gYXMgc3RyaW5nKSkge1xuICAgICAgdmFsdWUgPSBpby50b1N0cmluZygpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgKGlvIGFzIHN0cmluZykuaW5jbHVkZXMoJ3N0cm1fJykpIHtcbiAgICAgIHZhbHVlID0gaW8gYXMgc3RyaW5nO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSA9IHRydW5jYXRlU3RyaW5nKFN0cmluZyhpbykpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YWx1ZSA9IGA8JHt0eXBlfT5gO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn07XG5cbi8qKlxuICogTGlzdCB2aWV3cyBzdXJmYWNlIG1ldGFkYXRhIG9ubHkuIFdoZW4gdGhlIGFjdGl2ZSBiYWNrZW5kIGV4cG9zZXMgdGhlXG4gKiBvcHRpb25hbCBgd29ybGQuYW5hbHl0aWNzYCByZWFkIG5hbWVzcGFjZSB3ZSByZWFkIGxpc3QgcGFnZXMgZnJvbSBpdFxuICogKG1ldGFkYXRhLW9ubHkg4oCUIG5vIHBheWxvYWQgcmVzb2x1dGlvbik7IG90aGVyd2lzZSB3ZSBmYWxsIGJhY2sgdG8gdGhlXG4gKiBydW50aW1lIHN0b3JhZ2UgQVBJcyB3aXRoIGByZXNvbHZlRGF0YTogJ25vbmUnYC5cbiAqXG4gKiBgLS13aXRoRGF0YWAgZm9yY2VzIHRoZSBydW50aW1lIHBhdGggc28gcGF5bG9hZHMgY2FuIGJlIHJlc29sdmVkIGludG8gdGhlXG4gKiB0YWJsZS4gSXQgaXMgZGVwcmVjYXRlZCBmb3IgbGlzdCB2aWV3czogdmlldyBwYXlsb2FkcyBwZXItcmVzb3VyY2Ugd2l0aFxuICogYHdvcmtmbG93IGluc3BlY3QgPHJlc291cmNlPiA8aWQ+YC5cbiAqL1xuY29uc3Qgd2FybldpdGhEYXRhRGVwcmVjYXRlZEZvckxpc3QgPSAoc2luZ3VsYXI6IHN0cmluZyk6IHZvaWQgPT4ge1xuICBsb2dnZXIud2FybihcbiAgICBgJy0td2l0aERhdGEnIGlzIGRlcHJlY2F0ZWQgZm9yIGxpc3Qgdmlld3MgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSByZWxlYXNlLiBVc2UgJ3dvcmtmbG93IGluc3BlY3QgJHtzaW5ndWxhcn0gPGlkPicgdG8gdmlldyBwYXlsb2FkcyBmb3IgYSBzaW5nbGUgJHtzaW5ndWxhcn0uYFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGxpc3RSdW5zID0gYXN5bmMgKHdvcmxkOiBXb3JsZCwgb3B0czogSW5zcGVjdENMSU9wdGlvbnMgPSB7fSkgPT4ge1xuICBjb25zdCByZXNvbHZlS2V5ID0gY3JlYXRlUmVzb2x2ZXIod29ybGQsIG9wdHM/LmRlY3J5cHQgPz8gZmFsc2UpO1xuXG4gIGlmIChvcHRzLnN0ZXBJZCB8fCBvcHRzLnJ1bklkKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICAnRmlsdGVyaW5nIGJ5IHN0ZXAtaWQgb3IgcnVuLWlkIGlzIG5vdCBzdXBwb3J0ZWQgaW4gbGlzdCBjYWxscywgaWdub3JpbmcgZmlsdGVyLidcbiAgICApO1xuICB9XG5cbiAgaWYgKG9wdHMud2l0aERhdGEpIHtcbiAgICB3YXJuV2l0aERhdGFEZXByZWNhdGVkRm9yTGlzdCgncnVuJyk7XG4gIH1cblxuICBjb25zdCB1c2VBbmFseXRpY3MgPSAhb3B0cy53aXRoRGF0YSAmJiBCb29sZWFuKHdvcmxkLmFuYWx5dGljcyk7XG4gIGNvbnN0IHJlc29sdmVEYXRhID0gb3B0cy53aXRoRGF0YSA/ICdhbGwnIDogJ25vbmUnO1xuICBjb25zdCBzdGF0dXMgPSBvcHRzLnN0YXR1cztcblxuICAvLyBSZXNvbHZlIC0tc2luY2UvLS11bnRpbCBpbnRvIGFuIGV4cGxpY2l0IGxpc3Rpbmcgd2luZG93LiBPbmx5IHRoZVxuICAvLyBhbmFseXRpY3MgcmVhZCBwYXRoIHN1cHBvcnRzIG9uZTsgdGhlIHJ1bnRpbWUgc3RvcmFnZSBBUElzIGhhdmUgbm8gdGltZVxuICAvLyBmaWx0ZXIuIFdpdGhvdXQgdGhlIGZsYWdzIHRoZSBiYWNrZW5kIGFwcGxpZXMgaXRzIGRlZmF1bHQgd2luZG93XG4gIC8vICh0cmFpbGluZyAyNGggb24gdGhlIFZlcmNlbCBiYWNrZW5kKS5cbiAgY29uc3QgdGltZVdpbmRvdyA9IHJlc29sdmVUaW1lV2luZG93KG9wdHMpO1xuICBpZiAodGltZVdpbmRvdyAmJiAhdXNlQW5hbHl0aWNzKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICAnLS1zaW5jZS8tLXVudGlsIHJlcXVpcmUgdGhlIGFuYWx5dGljcyByZWFkIHBhdGggYW5kIGFyZSBpZ25vcmVkIGJ5IHRoaXMgYmFja2VuZC4nXG4gICAgKTtcbiAgfVxuXG4gIC8vIERldGVybWluZSB3aGljaCBwcm9wcyB0byBzaG93IGJhc2VkIG9uIHdpdGhEYXRhIGZsYWdcbiAgY29uc3QgYmFzZVByb3BzID0gb3B0cy53aXRoRGF0YVxuICAgID8gV09SS0ZMT1dfUlVOX0xJU1RFRF9QUk9QU1xuICAgIDogV09SS0ZMT1dfUlVOX0xJU1RFRF9QUk9QUy5maWx0ZXIoXG4gICAgICAgIChwcm9wKSA9PiAhV09SS0ZMT1dfUlVOX0lPX1BST1BTLmluY2x1ZGVzKHByb3ApXG4gICAgICApO1xuXG4gIC8vIFdvcmxkLXNwZWNpZmljIGRpc3BsYXkgZmllbGRzIChXb3JsZC5kZXNjcmliZVJ1bik6IGVhY2gga2V5IHRoZVxuICAvLyB3b3JsZCByZXR1cm5zIGJlY29tZXMgYW4gZXh0cmEgY29sdW1uLCBpbnNlcnRlZCBiZWZvcmUgYHN0YXR1c2AuXG4gIC8vIERldGFjaGVkIGNhbGwgc2l0ZSwgc28gYmluZCBleHBsaWNpdGx5LiBgbnVsbGAgZmllbGQgdmFsdWVzIGFyZVxuICAvLyBwcmVzZXJ2ZWQgKHRoZXkgbWVhbiBcImFwcGxpY2FibGUgYnV0IHVuZGV0ZXJtaW5hYmxlXCIgcGVyIHRoZVxuICAvLyBpbnRlcmZhY2UgY29udHJhY3QpLCBkaXN0aW5ndWlzaGluZyB0aGVtIGluIEpTT04gb3V0cHV0IGZyb20gdGhlXG4gIC8vIGhvb2sgYmVpbmcgYWJzZW50IGVudGlyZWx5LlxuICBjb25zdCBkZXNjcmliZVJ1biA9IHdvcmxkLmRlc2NyaWJlUnVuPy5iaW5kKHdvcmxkKTtcbiAgY29uc3QgZGVzY3JpYmVkS2V5czogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgd2l0aFdvcmxkRmllbGRzID0gYXN5bmMgKFxuICAgIHJvd3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdPiA9PiB7XG4gICAgaWYgKCFkZXNjcmliZVJ1bikgcmV0dXJuIHJvd3M7XG4gICAgLy8gUm93cyBldmFsdWF0ZWQgY29uY3VycmVudGx5IHNvIGFuIGFzeW5jIGltcGxlbWVudGF0aW9uIGNvc3RzIG9uZVxuICAgIC8vIGF3YWl0IHBlciBwYWdlLCBub3QgcGVyIHJvdy5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICByb3dzLm1hcChhc3luYyAocm93KSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkcyA9IGF3YWl0IHNhZmVXb3JsZEZpZWxkcyhkZXNjcmliZVJ1biwgcm93KTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoZmllbGRzKSkge1xuICAgICAgICAgIGlmICghZGVzY3JpYmVkS2V5cy5pbmNsdWRlcyhrZXkpKSBkZXNjcmliZWRLZXlzLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyAuLi5yb3csIC4uLmZpZWxkcyB9O1xuICAgICAgfSlcbiAgICApO1xuICB9O1xuICBjb25zdCBwcm9wc0ZvciA9IChiYXNlTGlzdDogKGtleW9mIFdvcmtmbG93UnVuKVtdKTogc3RyaW5nW10gPT4ge1xuICAgIGNvbnN0IGxpc3Q6IHN0cmluZ1tdID0gWy4uLmJhc2VMaXN0XTtcbiAgICBsaXN0LnNwbGljZShsaXN0LmluZGV4T2YoJ3N0YXR1cycpLCAwLCAuLi5kZXNjcmliZWRLZXlzKTtcbiAgICByZXR1cm4gbGlzdDtcbiAgfTtcblxuICBjb25zdCBmZXRjaFJ1bnNQYWdlID0gYXN5bmMgKFxuICAgIGN1cnNvcjogc3RyaW5nIHwgdW5kZWZpbmVkXG4gICk6IFByb21pc2U8UGFnZURhdGE8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+PiA9PiB7XG4gICAgY29uc3QgcGFnaW5hdGlvbiA9IHtcbiAgICAgIHNvcnRPcmRlcjogb3B0cy5zb3J0IHx8ICdkZXNjJyxcbiAgICAgIGN1cnNvcixcbiAgICAgIGxpbWl0OiBvcHRzLmxpbWl0IHx8IERFRkFVTFRfUEFHRV9TSVpFLFxuICAgIH07XG4gICAgaWYgKHVzZUFuYWx5dGljcyAmJiB3b3JsZC5hbmFseXRpY3MpIHtcbiAgICAgIGNvbnN0IHJ1bnMgPSBhd2FpdCB3b3JsZC5hbmFseXRpY3MucnVucy5saXN0KHtcbiAgICAgICAgd29ya2Zsb3dOYW1lOiBvcHRzLndvcmtmbG93TmFtZSxcbiAgICAgICAgc3RhdHVzLFxuICAgICAgICAuLi4odGltZVdpbmRvdyA/PyB7fSksXG4gICAgICAgIHBhZ2luYXRpb24sXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRhdGE6IGF3YWl0IHdpdGhXb3JsZEZpZWxkcyhcbiAgICAgICAgICBydW5zLmRhdGEgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdXG4gICAgICAgICksXG4gICAgICAgIGN1cnNvcjogcnVucy5jdXJzb3IsXG4gICAgICAgIGhhc01vcmU6IHJ1bnMuaGFzTW9yZSxcbiAgICAgICAgcGFnZUluZm86IGdldFBhZ2VJbmZvKHJ1bnMpLFxuICAgICAgfTtcbiAgICB9XG4gICAgY29uc3QgcnVucyA9IGF3YWl0IHdvcmxkLnJ1bnMubGlzdCh7XG4gICAgICB3b3JrZmxvd05hbWU6IG9wdHMud29ya2Zsb3dOYW1lLFxuICAgICAgc3RhdHVzLFxuICAgICAgcGFnaW5hdGlvbixcbiAgICAgIHJlc29sdmVEYXRhLFxuICAgIH0pO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHJ1bnMuZGF0YS5tYXAoKHIpID0+IGh5ZHJhdGVSZXNvdXJjZUlPKHIsIHJlc29sdmVLZXkpKVxuICAgICk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IGF3YWl0IHdpdGhXb3JsZEZpZWxkcyhkYXRhIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSksXG4gICAgICBjdXJzb3I6IHJ1bnMuY3Vyc29yLFxuICAgICAgaGFzTW9yZTogcnVucy5oYXNNb3JlLFxuICAgICAgcGFnZUluZm86IGdldFBhZ2VJbmZvKHJ1bnMpLFxuICAgIH07XG4gIH07XG5cbiAgLy8gRm9yIEpTT04gb3V0cHV0LCBqdXN0IGZldGNoIG9uY2UgYW5kIHJldHVyblxuICBpZiAob3B0cy5qc29uKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBmZXRjaFJ1bnNQYWdlKG9wdHMuY3Vyc29yKTtcbiAgICAgIHNob3dKc29uUGFnZShwYWdlKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGhhbmRsZUFwaUVycm9yKGVycm9yLCBvcHRzLmJhY2tlbmQpKSB7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGF3YWl0IHNldHVwTGlzdFBhZ2luYXRpb248UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KHtcbiAgICBpbml0aWFsQ3Vyc29yOiBvcHRzLmN1cnNvcixcbiAgICBpbnRlcmFjdGl2ZTogb3B0cy5pbnRlcmFjdGl2ZSxcbiAgICBmZXRjaFBhZ2U6IGFzeW5jIChjdXJzb3IpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmZXRjaFJ1bnNQYWdlKGN1cnNvcik7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfSxcbiAgICBkaXNwbGF5UGFnZTogYXN5bmMgKHJ1bnMpID0+IHtcbiAgICAgIGxvZ2dlci5sb2coc2hvd1RhYmxlKHJ1bnMsIHByb3BzRm9yKGJhc2VQcm9wcyksIG9wdHMpKTtcbiAgICB9LFxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRSZWNlbnRSdW4gPSBhc3luYyAoXG4gIHdvcmxkOiBXb3JsZCxcbiAgb3B0czogSW5zcGVjdENMSU9wdGlvbnMgPSB7fVxuKSA9PiB7XG4gIGNvbnN0IHJlc29sdmVLZXkgPSBjcmVhdGVSZXNvbHZlcih3b3JsZCwgb3B0cz8uZGVjcnlwdCA/PyBmYWxzZSk7XG5cbiAgbG9nZ2VyLndhcm4oYE5vIHJ1bklkIHByb3ZpZGVkLCBmZXRjaGluZyBkYXRhIGZvciBsYXRlc3QgcnVuIGluc3RlYWQuYCk7XG4gIHRyeSB7XG4gICAgY29uc3QgcnVucyA9IGF3YWl0IHdvcmxkLnJ1bnMubGlzdCh7XG4gICAgICBwYWdpbmF0aW9uOiB7IGxpbWl0OiAxLCBzb3J0T3JkZXI6IG9wdHMuc29ydCB8fCAnZGVzYycgfSxcbiAgICAgIHJlc29sdmVEYXRhOiAnbm9uZScsIC8vIERvbid0IG5lZWQgZGF0YSBmb3IganVzdCBnZXR0aW5nIHRoZSBJRFxuICAgIH0pO1xuICAgIHJ1bnMuZGF0YSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgcnVucy5kYXRhLm1hcCgocikgPT4gaHlkcmF0ZVJlc291cmNlSU8ociwgcmVzb2x2ZUtleSkpXG4gICAgKTtcbiAgICByZXR1cm4gcnVucy5kYXRhWzBdO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChoYW5kbGVBcGlFcnJvcihlcnJvciwgb3B0cy5iYWNrZW5kKSkge1xuICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHNob3dSdW4gPSBhc3luYyAoXG4gIHdvcmxkOiBXb3JsZCxcbiAgcnVuSWQ6IHN0cmluZyxcbiAgb3B0czogSW5zcGVjdENMSU9wdGlvbnMgPSB7fVxuKSA9PiB7XG4gIGNvbnN0IHJlc29sdmVLZXkgPSBjcmVhdGVSZXNvbHZlcih3b3JsZCwgb3B0cz8uZGVjcnlwdCA/PyBmYWxzZSk7XG5cbiAgaWYgKG9wdHMud2l0aERhdGEpIHtcbiAgICBsb2dnZXIud2FybignYHdpdGhEYXRhYCBmbGFnIGlzIGlnbm9yZWQgd2hlbiBzaG93aW5nIGluZGl2aWR1YWwgcmVzb3VyY2VzJyk7XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCBydW4gPSBhd2FpdCB3b3JsZC5ydW5zLmdldChydW5JZCwgeyByZXNvbHZlRGF0YTogJ2FsbCcgfSk7XG4gICAgY29uc3QgaHlkcmF0ZWQgPSBhd2FpdCBoeWRyYXRlUmVzb3VyY2VJTyhydW4sIHJlc29sdmVLZXkpO1xuICAgIC8vIFdvcmxkLXNwZWNpZmljIGRpc3BsYXkgZmllbGRzIChXb3JsZC5kZXNjcmliZVJ1biksIGV2YWx1YXRlZFxuICAgIC8vIGRlZmVuc2l2ZWx5IOKAlCBzZWUgc2FmZVdvcmxkRmllbGRzLiBgbnVsbGAgZmllbGQgdmFsdWVzIGFyZSBrZXB0IHNvXG4gICAgLy8gc3RydWN0dXJlZCBvdXRwdXQgZGlzdGluZ3Vpc2hlcyBcInVuZGV0ZXJtaW5hYmxlXCIgZnJvbSBcImhvb2sgYWJzZW50XCIuXG4gICAgY29uc3Qgd29ybGRGaWVsZHMgPSB3b3JsZC5kZXNjcmliZVJ1blxuICAgICAgPyBhd2FpdCBzYWZlV29ybGRGaWVsZHMoXG4gICAgICAgICAgd29ybGQuZGVzY3JpYmVSdW4uYmluZCh3b3JsZCksXG4gICAgICAgICAgcnVuIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgICAgICAgKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcnVuV2l0aEh5ZHJhdGVkSU8gPVxuICAgICAgd29ybGRGaWVsZHMgJiYgT2JqZWN0LmtleXMod29ybGRGaWVsZHMpLmxlbmd0aCA+IDBcbiAgICAgICAgPyB7IC4uLmh5ZHJhdGVkLCAuLi53b3JsZEZpZWxkcyB9XG4gICAgICAgIDogaHlkcmF0ZWQ7XG4gICAgaWYgKG9wdHMuanNvbikge1xuICAgICAgc2hvd0pzb24ocnVuV2l0aEh5ZHJhdGVkSU8pO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaGFzRXhwaXJlZERhdGEocnVuKSkge1xuICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICBcIlRoaXMgcnVuJ3MgZGF0YSAoaW5wdXQvb3V0cHV0L2Vycm9yKSBoYXMgZXhwaXJlZCBhbmQgaXMgbm8gbG9uZ2VyIGF2YWlsYWJsZS5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmxvZyhydW5XaXRoSHlkcmF0ZWRJTyk7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChoYW5kbGVBcGlFcnJvcihlcnJvciwgb3B0cy5iYWNrZW5kKSkge1xuICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGxpc3RTdGVwcyA9IGFzeW5jIChcbiAgd29ybGQ6IFdvcmxkLFxuICBvcHRzOiBJbnNwZWN0Q0xJT3B0aW9ucyA9IHtcbiAgICBydW5JZDogdW5kZWZpbmVkLFxuICB9XG4pID0+IHtcbiAgY29uc3QgcmVzb2x2ZUtleSA9IGNyZWF0ZVJlc29sdmVyKHdvcmxkLCBvcHRzPy5kZWNyeXB0ID8/IGZhbHNlKTtcblxuICBpZiAob3B0cy5zdGVwSWQpIHtcbiAgICBsb2dnZXIud2FybihcbiAgICAgICdGaWx0ZXJpbmcgYnkgc3RlcC1pZCBpcyBub3Qgc3VwcG9ydGVkIGluIGxpc3QgY2FsbHMsIGlnbm9yaW5nIGZpbHRlci4nXG4gICAgKTtcbiAgfVxuICBpZiAob3B0cy53b3JrZmxvd05hbWUpIHtcbiAgICBsb2dnZXIud2FybihcbiAgICAgICdGaWx0ZXJpbmcgYnkgd29ya2Zsb3ctbmFtZSBpcyBub3Qgc3VwcG9ydGVkIGZvciBzdGVwcywgaWdub3JpbmcgZmlsdGVyLidcbiAgICApO1xuICB9XG5cbiAgY29uc3QgcnVuSWQgPSBvcHRzLnJ1bklkXG4gICAgPyBvcHRzLnJ1bklkXG4gICAgOiAoYXdhaXQgZ2V0UmVjZW50UnVuKHdvcmxkLCBvcHRzKSk/LnJ1bklkO1xuICBpZiAoIXJ1bklkKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdObyBydW4gZm91bmQuJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKG9wdHMud2l0aERhdGEpIHtcbiAgICB3YXJuV2l0aERhdGFEZXByZWNhdGVkRm9yTGlzdCgnc3RlcCcpO1xuICB9XG5cbiAgY29uc3QgdXNlQW5hbHl0aWNzID0gIW9wdHMud2l0aERhdGEgJiYgQm9vbGVhbih3b3JsZC5hbmFseXRpY3MpO1xuICBjb25zdCByZXNvbHZlRGF0YSA9IG9wdHMud2l0aERhdGEgPyAnYWxsJyA6ICdub25lJztcblxuICAvLyBEZXRlcm1pbmUgd2hpY2ggcHJvcHMgdG8gc2hvdyBiYXNlZCBvbiB3aXRoRGF0YSBmbGFnXG4gIGNvbnN0IHByb3BzID0gb3B0cy53aXRoRGF0YVxuICAgID8gU1RFUF9MSVNURURfUFJPUFNcbiAgICA6IFNURVBfTElTVEVEX1BST1BTLmZpbHRlcigocHJvcCkgPT4gIVNURVBfSU9fUFJPUFMuaW5jbHVkZXMocHJvcCkpO1xuXG4gIGNvbnN0IGZldGNoU3RlcHNQYWdlID0gYXN5bmMgKFxuICAgIGN1cnNvcjogc3RyaW5nIHwgdW5kZWZpbmVkXG4gICk6IFByb21pc2U8UGFnZURhdGE8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+PiA9PiB7XG4gICAgbG9nZ2VyLmRlYnVnKGBGZXRjaGluZyBzdGVwcyBmb3IgcnVuICR7cnVuSWR9YCk7XG4gICAgY29uc3QgcGFnaW5hdGlvbiA9IHtcbiAgICAgIHNvcnRPcmRlcjogb3B0cy5zb3J0IHx8ICdkZXNjJyxcbiAgICAgIGN1cnNvcixcbiAgICAgIGxpbWl0OiBvcHRzLmxpbWl0IHx8IERFRkFVTFRfUEFHRV9TSVpFLFxuICAgIH07XG4gICAgaWYgKHVzZUFuYWx5dGljcyAmJiB3b3JsZC5hbmFseXRpY3MpIHtcbiAgICAgIGNvbnN0IHN0ZXBzID0gYXdhaXQgd29ybGQuYW5hbHl0aWNzLnN0ZXBzLmxpc3QoeyBydW5JZCwgcGFnaW5hdGlvbiB9KTtcbiAgICAgIGNvbnN0IHBhZ2UgPSB7XG4gICAgICAgIGRhdGE6IHN0ZXBzLmRhdGEgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLFxuICAgICAgICBjdXJzb3I6IHN0ZXBzLmN1cnNvcixcbiAgICAgICAgaGFzTW9yZTogc3RlcHMuaGFzTW9yZSxcbiAgICAgICAgcGFnZUluZm86IGdldFBhZ2VJbmZvKHN0ZXBzKSxcbiAgICAgIH07XG4gICAgICBpZiAoY3Vyc29yIHx8IHBhZ2UuZGF0YS5sZW5ndGggPiAwIHx8IHBhZ2UuaGFzTW9yZSkge1xuICAgICAgICByZXR1cm4gcGFnZTtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYE5vIGFuYWx5dGljcyBzdGVwcyBmb3VuZCBmb3IgcnVuICR7cnVuSWR9OyBmYWxsaW5nIGJhY2sgdG8gc3RvcmFnZWBcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHN0ZXBDaHVua3MgPSBhd2FpdCB3b3JsZC5zdGVwcy5saXN0KHtcbiAgICAgIHJ1bklkLFxuICAgICAgcGFnaW5hdGlvbixcbiAgICAgIHJlc29sdmVEYXRhLFxuICAgIH0pO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHN0ZXBDaHVua3MuZGF0YS5tYXAoKHMpID0+IGh5ZHJhdGVSZXNvdXJjZUlPKHMsIHJlc29sdmVLZXkpKVxuICAgICk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IGRhdGEgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLFxuICAgICAgY3Vyc29yOiBzdGVwQ2h1bmtzLmN1cnNvcixcbiAgICAgIGhhc01vcmU6IHN0ZXBDaHVua3MuaGFzTW9yZSxcbiAgICAgIHBhZ2VJbmZvOiBnZXRQYWdlSW5mbyhzdGVwQ2h1bmtzKSxcbiAgICB9O1xuICB9O1xuXG4gIC8vIEZvciBKU09OIG91dHB1dCwganVzdCBmZXRjaCBvbmNlIGFuZCByZXR1cm5cbiAgaWYgKG9wdHMuanNvbikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgZmV0Y2hTdGVwc1BhZ2Uob3B0cy5jdXJzb3IpO1xuICAgICAgc2hvd0pzb24ocGFnZS5kYXRhKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGhhbmRsZUFwaUVycm9yKGVycm9yLCBvcHRzLmJhY2tlbmQpKSB7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGF3YWl0IHNldHVwTGlzdFBhZ2luYXRpb248UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KHtcbiAgICBpbml0aWFsQ3Vyc29yOiBvcHRzLmN1cnNvcixcbiAgICBpbnRlcmFjdGl2ZTogb3B0cy5pbnRlcmFjdGl2ZSxcbiAgICBmZXRjaFBhZ2U6IGFzeW5jIChjdXJzb3IpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmZXRjaFN0ZXBzUGFnZShjdXJzb3IpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGhhbmRsZUFwaUVycm9yKGVycm9yLCBvcHRzLmJhY2tlbmQpKSB7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgIH0sXG4gICAgZGlzcGxheVBhZ2U6IGFzeW5jIChzdGVwcykgPT4ge1xuICAgICAgbG9nZ2VyLmxvZyhzaG93VGFibGUoc3RlcHMsIHByb3BzLCBvcHRzKSk7XG4gICAgICBzaG93SW5zcGVjdEluZm9Cb3goJ3N0ZXAnKTtcbiAgICB9LFxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaG93U3RlcCA9IGFzeW5jIChcbiAgd29ybGQ6IFdvcmxkLFxuICBzdGVwSWQ6IHN0cmluZyxcbiAgb3B0czogSW5zcGVjdENMSU9wdGlvbnMgPSB7fVxuKSA9PiB7XG4gIGNvbnN0IHJlc29sdmVLZXkgPSBjcmVhdGVSZXNvbHZlcih3b3JsZCwgb3B0cz8uZGVjcnlwdCA/PyBmYWxzZSk7XG5cbiAgaWYgKG9wdHMud2l0aERhdGEpIHtcbiAgICBsb2dnZXIud2FybignYHdpdGhEYXRhYCBmbGFnIGlzIGlnbm9yZWQgd2hlbiBzaG93aW5nIGluZGl2aWR1YWwgcmVzb3VyY2VzJyk7XG4gIH1cbiAgaWYgKG9wdHMuc3RlcElkKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICAnRmlsdGVyaW5nIGJ5IHN0ZXAtaWQgaXMgbm90IHN1cHBvcnRlZCBpbiBnZXQgY2FsbHMsIGlnbm9yaW5nIGZpbHRlci4nXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHJ1bklkID0gb3B0cy5ydW5JZCA/PyAoYXdhaXQgZ2V0UmVjZW50UnVuKHdvcmxkLCBvcHRzKSk/LnJ1bklkO1xuICBpZiAoIXJ1bklkKSB7XG4gICAgbG9nZ2VyLmVycm9yKFxuICAgICAgJ3J1bi1pZCBpcyByZXF1aXJlZCBmb3Igc2hvd2luZyBhIHN0ZXAuIFVzYWdlOiBgd29ya2Zsb3cgaW5zcGVjdCBzdGVwIDxTVEVQX0lEPiAtLXJ1bklkPTxSVU5fSUQ+YCdcbiAgICApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3Qgc3RlcCA9IGF3YWl0IHdvcmxkLnN0ZXBzLmdldChydW5JZCwgc3RlcElkLCB7XG4gICAgICByZXNvbHZlRGF0YTogJ2FsbCcsXG4gICAgfSk7XG4gICAgY29uc3Qgc3RlcFdpdGhIeWRyYXRlZElPID0gYXdhaXQgaHlkcmF0ZVJlc291cmNlSU8oc3RlcCwgcmVzb2x2ZUtleSk7XG4gICAgaWYgKG9wdHMuanNvbikge1xuICAgICAgc2hvd0pzb24oc3RlcFdpdGhIeWRyYXRlZElPKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKFxuICAgICAgICBoYXNFeHBpcmVkRmllbGRzKFxuICAgICAgICAgIHN0ZXBXaXRoSHlkcmF0ZWRJTyBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICBcIlRoaXMgc3RlcCdzIGRhdGEgKGlucHV0L291dHB1dC9lcnJvcikgaGFzIGV4cGlyZWQgYW5kIGlzIG5vIGxvbmdlciBhdmFpbGFibGUuXCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5sb2coc3RlcFdpdGhIeWRyYXRlZElPKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGhhbmRsZUFwaUVycm9yKGVycm9yLCBvcHRzLmJhY2tlbmQpKSB7XG4gICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2hvd1N0cmVhbSA9IGFzeW5jIChcbiAgd29ybGQ6IFdvcmxkLFxuICBzdHJlYW1JZDogc3RyaW5nLFxuICBvcHRzOiBJbnNwZWN0Q0xJT3B0aW9ucyA9IHt9XG4pID0+IHtcbiAgaWYgKG9wdHMuc3RlcElkKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICAnRmlsdGVyaW5nIGJ5IHN0ZXAtaWQgaXMgbm90IHN1cHBvcnRlZCB3aGVuIHNob3dpbmcgYSBzdHJlYW0sIGlnbm9yaW5nIGZpbHRlci4nXG4gICAgKTtcbiAgfVxuICBpZiAoIW9wdHMucnVuSWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJy0tcnVuIGlzIHJlcXVpcmVkIHdoZW4gc2hvd2luZyBhIHN0cmVhbScpO1xuICB9XG4gIGNvbnN0IHJhd1N0cmVhbSA9IGF3YWl0IHdvcmxkLnN0cmVhbXMuZ2V0KG9wdHMucnVuSWQsIHN0cmVhbUlkKTtcblxuICAvLyBPbmx5IHJlc29sdmUgdGhlIGVuY3J5cHRpb24ga2V5IHdoZW4gLS1kZWNyeXB0IGlzIHBhc3NlZCBhbmQgLS1ydW4gaXMgcHJvdmlkZWQuXG4gIC8vIFdlIGZldGNoIHRoZSBmdWxsIFdvcmtmbG93UnVuIG9iamVjdCBzbyB0aGF0IGdldEVuY3J5cHRpb25LZXlGb3JSdW4gaGFzXG4gIC8vIGFjY2VzcyB0byB0aGUgZGVwbG95bWVudElkIChuZWVkZWQgZm9yIEFQSS1iYXNlZCBrZXkgcmVzb2x1dGlvbikuXG4gIGxldCBlbmNyeXB0aW9uS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW07XG4gIGlmIChvcHRzLmRlY3J5cHQgJiYgb3B0cy5ydW5JZCkge1xuICAgIGVuY3J5cHRpb25LZXkgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcnVuID0gYXdhaXQgd29ybGQucnVucy5nZXQob3B0cy5ydW5JZCEpO1xuICAgICAgY29uc3QgcmF3S2V5ID0gYXdhaXQgd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1bj8uKHJ1bik7XG4gICAgICAvLyBGdWxsIGNhcGFiaWxpdHksIHNvIHNlYWxlZCAoJ2VuY3AnKSBzdHJlYW0gZnJhbWVzIHdyaXR0ZW4gYnkgb3RoZXJcbiAgICAgIC8vIHJ1bnMgYXJlIHJlYWRhYmxlIHRvbyDigJQgbm90IGp1c3QgdGhlIHJ1bidzIG93biBzeW1tZXRyaWMgZnJhbWVzLlxuICAgICAgcmV0dXJuIHJhd0tleSA/IGF3YWl0IGRlcml2ZVJ1blBheWxvYWRLZXlzKHJhd0tleSkgOiB1bmRlZmluZWQ7XG4gICAgfSkoKTtcbiAgfSBlbHNlIGlmIChvcHRzLmRlY3J5cHQgJiYgIW9wdHMucnVuSWQpIHtcbiAgICBsb2dnZXIud2FybihcbiAgICAgICdDYW5ub3QgZGVjcnlwdCBzdHJlYW0gY29udGVudCB3aXRob3V0IGEgcnVuIElELiBVc2UgLS1ydW49PHJ1bi1pZD4gd2l0aCAtLWRlY3J5cHQuJ1xuICAgICk7XG4gIH1cblxuICAvLyBEZXNlcmlhbGl6ZSB0aGUgc3RyZWFtIHRvIGdldCBKYXZhU2NyaXB0IG9iamVjdHNcbiAgY29uc3QgcmV2aXZlcnMgPSBnZXRFeHRlcm5hbFJldml2ZXJzKFxuICAgIGdsb2JhbFRoaXMsXG4gICAgW10sXG4gICAgb3B0cy5ydW5JZCA/PyAnJyxcbiAgICBlbmNyeXB0aW9uS2V5XG4gICk7XG4gIGNvbnN0IHRyYW5zZm9ybSA9IGdldERlc2VyaWFsaXplU3RyZWFtKHJldml2ZXJzLCBlbmNyeXB0aW9uS2V5KTtcbiAgY29uc3Qgc3RyZWFtID0gcmF3U3RyZWFtLnBpcGVUaHJvdWdoKHRyYW5zZm9ybSk7XG5cbiAgbG9nZ2VyLmluZm8oJ1N0cmVhbWluZyB0byBzdGRvdXQsIHByZXNzIENUUkwrQyB0byBhYm9ydC4nKTtcbiAgbG9nZ2VyLmluZm8oXG4gICAgJ1VzZSAtLWpzb24gdG8gb3V0cHV0IHRoZSBzdHJlYW0gYXMgbmV3bGluZS1kZWxpbWl0ZWQgSlNPTiB3aXRob3V0IGluZm8gbG9ncy5cXG4nXG4gICk7XG4gIGF3YWl0IHN0cmVhbVRvQ29uc29sZShzdHJlYW0sIHN0cmVhbUlkLCBvcHRzKTtcbn07XG5cbi8qKlxuICogTGlzdGluZyBzdHJlYW1zIG9ubHkgbGlzdHMgYXZhaWxhYmxlIHN0cmVhbSBJRHMgYmFzZWQgb24gcnVuL3N0ZXAgcGFzc2VkLFxuICogYW5kIGRvZXNuJ3QgcmVhZCBhbnkgZGF0YSBmcm9tIHRoZSBzdHJlYW1zLlxuICovXG5leHBvcnQgY29uc3QgbGlzdFN0cmVhbXNCeVJ1bklkID0gYXN5bmMgKFxuICB3b3JsZDogV29ybGQsXG4gIG9wdHM6IEluc3BlY3RDTElPcHRpb25zID0ge31cbikgPT4ge1xuICBpZiAob3B0cy53aXRoRGF0YSkge1xuICAgIGxvZ2dlci53YXJuKCdgd2l0aERhdGFgIGZsYWcgaXMgaWdub3JlZCB3aGVuIGxpc3Rpbmcgc3RyZWFtcycpO1xuICB9XG4gIGlmIChvcHRzLndvcmtmbG93TmFtZSkge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJ0ZpbHRlcmluZyBieSB3b3JrZmxvdy1uYW1lIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHN0cmVhbXMsIGlnbm9yaW5nIGZpbHRlci4nXG4gICAgKTtcbiAgfVxuICBpZiAob3B0cy5zdGVwSWQpIHtcbiAgICBsb2dnZXIud2FybihcbiAgICAgICdGaWx0ZXJpbmcgYnkgc3RlcC1pZCBpcyBub3Qgc3VwcG9ydGVkIGZvciBzdHJlYW1zLCBpZ25vcmluZyBmaWx0ZXIuJ1xuICAgICk7XG4gIH1cblxuICBsZXQgcnVuSWQgPSBvcHRzLnJ1bklkO1xuICBpZiAoIXJ1bklkKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICAnTm8gcnVuLWlkIHByb3ZpZGVkLiBMaXN0aW5nIHN0cmVhbXMgZm9yIGxhdGVzdCBydW4gaW5zdGVhZC4nLFxuICAgICAgJ1VzZSAtLXJ1bj08cnVuLWlkPiB0byBmaWx0ZXIgc3RyZWFtcyBieSBydW4uJ1xuICAgICk7XG4gICAgY29uc3QgcnVuID0gYXdhaXQgZ2V0UmVjZW50UnVuKHdvcmxkLCBvcHRzKTtcbiAgICBpZiAoIXJ1bikge1xuICAgICAgbG9nZ2VyLndhcm4oJ05vIHJ1bnMgZm91bmQuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJ1bklkID0gcnVuLnJ1bklkO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBzdHJlYW1JZHMgPSBhd2FpdCB3b3JsZC5zdHJlYW1zLmxpc3QocnVuSWQpO1xuICAgIGNvbnN0IG1hdGNoaW5nU3RyZWFtcyA9IHN0cmVhbUlkcy5tYXAoKHN0cmVhbUlkKSA9PiAoe1xuICAgICAgcnVuSWQsXG4gICAgICBzdHJlYW1JZCxcbiAgICB9KSk7XG5cbiAgICBpZiAob3B0cy5qc29uKSB7XG4gICAgICBzaG93SnNvbihtYXRjaGluZ1N0cmVhbXMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsb2dnZXIubG9nKHNob3dUYWJsZShtYXRjaGluZ1N0cmVhbXMsIFsncnVuSWQnLCAnc3RyZWFtSWQnXSkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChoYW5kbGVBcGlFcnJvcihlcnJvciwgb3B0cy5iYWNrZW5kKSkge1xuICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGxpc3RFdmVudHMgPSBhc3luYyAoXG4gIHdvcmxkOiBXb3JsZCxcbiAgb3B0czogSW5zcGVjdENMSU9wdGlvbnMgPSB7fVxuKSA9PiB7XG4gIGNvbnN0IHJlc29sdmVLZXkgPSBjcmVhdGVSZXNvbHZlcih3b3JsZCwgb3B0cz8uZGVjcnlwdCA/PyBmYWxzZSk7XG4gIGlmIChvcHRzLndvcmtmbG93TmFtZSkge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJ0ZpbHRlcmluZyBieSB3b3JrZmxvdy1uYW1lIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGV2ZW50cywgaWdub3JpbmcgZmlsdGVyLidcbiAgICApO1xuICB9XG5cbiAgY29uc3QgcnVuSWQgPSBvcHRzLnJ1bklkID8/IChhd2FpdCBnZXRSZWNlbnRSdW4od29ybGQsIG9wdHMpKT8ucnVuSWQ7XG4gIGlmICghcnVuSWQpIHtcbiAgICBsb2dnZXIuZXJyb3IoJ05vIHJ1biBmb3VuZC4nKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAob3B0cy53aXRoRGF0YSkge1xuICAgIHdhcm5XaXRoRGF0YURlcHJlY2F0ZWRGb3JMaXN0KCdldmVudCcpO1xuICB9XG5cbiAgY29uc3QgdXNlQW5hbHl0aWNzID0gIW9wdHMud2l0aERhdGEgJiYgQm9vbGVhbih3b3JsZC5hbmFseXRpY3MpO1xuICBjb25zdCBjb3JyZWxhdGlvbklkRmlsdGVyID0gb3B0cy5ob29rSWQgfHwgb3B0cy5zdGVwSWQ7XG5cbiAgLy8gRGV0ZXJtaW5lIHdoaWNoIHByb3BzIHRvIHNob3cgYmFzZWQgb24gd2l0aERhdGEgZmxhZ1xuICBjb25zdCBwcm9wcyA9IG9wdHMud2l0aERhdGFcbiAgICA/IEVWRU5UX0xJU1RFRF9QUk9QU1xuICAgIDogRVZFTlRfTElTVEVEX1BST1BTLmZpbHRlcigocHJvcCkgPT4gIUVWRU5UX0lPX1BST1BTLmluY2x1ZGVzKHByb3ApKTtcblxuICBjb25zdCBmZXRjaEV2ZW50c1BhZ2UgPSBhc3luYyAoXG4gICAgY3Vyc29yOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgKTogUHJvbWlzZTxQYWdlRGF0YTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4+ID0+IHtcbiAgICBsb2dnZXIuZGVidWcoYEZldGNoaW5nIGV2ZW50cyBmb3IgcnVuICR7cnVuSWR9YCk7XG4gICAgY29uc3QgcGFnaW5hdGlvbiA9IHtcbiAgICAgIHNvcnRPcmRlcjogb3B0cy5zb3J0IHx8ICdkZXNjJyxcbiAgICAgIGN1cnNvcixcbiAgICAgIGxpbWl0OiBvcHRzLmxpbWl0IHx8IERFRkFVTFRfUEFHRV9TSVpFLFxuICAgIH07XG4gICAgaWYgKHVzZUFuYWx5dGljcyAmJiB3b3JsZC5hbmFseXRpY3MpIHtcbiAgICAgIGNvbnN0IGV2ZW50cyA9IGF3YWl0IHdvcmxkLmFuYWx5dGljcy5ldmVudHMubGlzdCh7XG4gICAgICAgIHJ1bklkLFxuICAgICAgICBjb3JyZWxhdGlvbklkOiBjb3JyZWxhdGlvbklkRmlsdGVyLFxuICAgICAgICBwYWdpbmF0aW9uLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBwYWdlID0ge1xuICAgICAgICBkYXRhOiBldmVudHMuZGF0YSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sXG4gICAgICAgIGN1cnNvcjogZXZlbnRzLmN1cnNvcixcbiAgICAgICAgaGFzTW9yZTogZXZlbnRzLmhhc01vcmUsXG4gICAgICAgIHBhZ2VJbmZvOiBnZXRQYWdlSW5mbyhldmVudHMpLFxuICAgICAgfTtcbiAgICAgIGlmIChjdXJzb3IgfHwgcGFnZS5kYXRhLmxlbmd0aCA+IDAgfHwgcGFnZS5oYXNNb3JlKSB7XG4gICAgICAgIHJldHVybiBwYWdlO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgTm8gYW5hbHl0aWNzIGV2ZW50cyBmb3VuZCBmb3IgcnVuICR7cnVuSWR9OyBmYWxsaW5nIGJhY2sgdG8gc3RvcmFnZWBcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdvcmxkLmV2ZW50cy5saXN0KHtcbiAgICAgIHJ1bklkLFxuICAgICAgcGFnaW5hdGlvbixcbiAgICAgIHJlc29sdmVEYXRhOiBvcHRzLndpdGhEYXRhID8gJ2FsbCcgOiAnbm9uZScsXG4gICAgfSk7XG4gICAgY29uc3QgZmlsdGVyZWQgPSBjb3JyZWxhdGlvbklkRmlsdGVyXG4gICAgICA/IHJlc3VsdC5kYXRhLmZpbHRlcigoZSkgPT4gZS5jb3JyZWxhdGlvbklkID09PSBjb3JyZWxhdGlvbklkRmlsdGVyKVxuICAgICAgOiByZXN1bHQuZGF0YTtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBmaWx0ZXJlZC5tYXAoKGUpID0+IGh5ZHJhdGVSZXNvdXJjZUlPKGUsIHJlc29sdmVLZXkpKVxuICAgICk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IGRhdGEgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLFxuICAgICAgY3Vyc29yOiByZXN1bHQuY3Vyc29yLFxuICAgICAgaGFzTW9yZTogcmVzdWx0Lmhhc01vcmUsXG4gICAgICBwYWdlSW5mbzogZ2V0UGFnZUluZm8ocmVzdWx0KSxcbiAgICB9O1xuICB9O1xuXG4gIC8vIEZvciBKU09OIG91dHB1dCwganVzdCBmZXRjaCBvbmNlIGFuZCByZXR1cm5cbiAgaWYgKG9wdHMuanNvbikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgZmV0Y2hFdmVudHNQYWdlKG9wdHMuY3Vyc29yKTtcbiAgICAgIHNob3dKc29uKHBhZ2UuZGF0YSk7XG4gICAgICByZXR1cm47XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChoYW5kbGVBcGlFcnJvcihlcnJvciwgb3B0cy5iYWNrZW5kKSkge1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBhd2FpdCBzZXR1cExpc3RQYWdpbmF0aW9uPFJlY29yZDxzdHJpbmcsIHVua25vd24+Pih7XG4gICAgaW5pdGlhbEN1cnNvcjogb3B0cy5jdXJzb3IsXG4gICAgaW50ZXJhY3RpdmU6IG9wdHMuaW50ZXJhY3RpdmUsXG4gICAgZmV0Y2hQYWdlOiBhc3luYyAoY3Vyc29yKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgZmV0Y2hFdmVudHNQYWdlKGN1cnNvcik7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfSxcbiAgICBkaXNwbGF5UGFnZTogYXN5bmMgKGV2ZW50cykgPT4ge1xuICAgICAgbG9nZ2VyLmxvZyhzaG93VGFibGUoZXZlbnRzLCBwcm9wcywgb3B0cykpO1xuICAgICAgc2hvd0luc3BlY3RJbmZvQm94KCdldmVudCcpO1xuICAgIH0sXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGxpc3RIb29rcyA9IGFzeW5jICh3b3JsZDogV29ybGQsIG9wdHM6IEluc3BlY3RDTElPcHRpb25zID0ge30pID0+IHtcbiAgY29uc3QgcmVzb2x2ZUtleSA9IGNyZWF0ZVJlc29sdmVyKHdvcmxkLCBvcHRzPy5kZWNyeXB0ID8/IGZhbHNlKTtcblxuICBpZiAob3B0cy53b3JrZmxvd05hbWUpIHtcbiAgICBsb2dnZXIud2FybihcbiAgICAgICdGaWx0ZXJpbmcgYnkgd29ya2Zsb3ctbmFtZSBpcyBub3Qgc3VwcG9ydGVkIGZvciBob29rcywgaWdub3JpbmcgZmlsdGVyLidcbiAgICApO1xuICB9XG4gIGlmIChvcHRzLnN0ZXBJZCkge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJ0ZpbHRlcmluZyBieSBzdGVwLWlkIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGhvb2tzLCBpZ25vcmluZyBmaWx0ZXIuJ1xuICAgICk7XG4gIH1cblxuICBjb25zdCBydW5JZCA9IG9wdHMucnVuSWQ7XG4gIGNvbnN0IHJlc29sdmVEYXRhID0gb3B0cy53aXRoRGF0YSA/ICdhbGwnIDogJ25vbmUnO1xuICAvLyBIb29rcyBhbHdheXMgcmVhZCBmcm9tIHRoZSBydW50aW1lIHN0b3JhZ2UgQVBJLiBVbmxpa2UgcnVucy9zdGVwcy9ldmVudHMsXG4gIC8vIHRoZSBhbmFseXRpY3MgcmVhZCBwYXRoIG9taXRzIGBvd25lcklkYCAoYW5kIHRoZSBzZWNyZXQgaG9vayB0b2tlbiB1c2VkIGJ5XG4gIC8vIHJlc3VtZS9jb3B5LXRva2VuIHN1cmZhY2VzKSwgc28gaG9vayBsaXN0aW5nIHN0YXlzIG9uIHRoZSBjYW5vbmljYWwgQVBJcy5cbiAgY29uc3QgZmV0Y2hIb29rc1BhZ2UgPSBhc3luYyAoXG4gICAgY3Vyc29yOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgKTogUHJvbWlzZTxQYWdlRGF0YTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4+ID0+IHtcbiAgICBpZiAoIXJ1bklkKSB7XG4gICAgICBsb2dnZXIuZGVidWcoJ0ZldGNoaW5nIGFsbCBob29rcycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2dnZXIuZGVidWcoYEZldGNoaW5nIGhvb2tzIGZvciBydW4gJHtydW5JZH1gKTtcbiAgICB9XG4gICAgY29uc3QgcGFnaW5hdGlvbiA9IHtcbiAgICAgIHNvcnRPcmRlcjogb3B0cy5zb3J0IHx8ICdkZXNjJyxcbiAgICAgIGN1cnNvcixcbiAgICAgIGxpbWl0OiBvcHRzLmxpbWl0IHx8IERFRkFVTFRfUEFHRV9TSVpFLFxuICAgIH07XG4gICAgY29uc3QgaG9va3MgPSBhd2FpdCB3b3JsZC5ob29rcy5saXN0KHsgcnVuSWQsIHBhZ2luYXRpb24sIHJlc29sdmVEYXRhIH0pO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGhvb2tzLmRhdGEubWFwKChoKSA9PiBoeWRyYXRlUmVzb3VyY2VJTyhoLCByZXNvbHZlS2V5KSlcbiAgICApO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiBkYXRhIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSxcbiAgICAgIGN1cnNvcjogaG9va3MuY3Vyc29yLFxuICAgICAgaGFzTW9yZTogaG9va3MuaGFzTW9yZSxcbiAgICAgIHBhZ2VJbmZvOiBnZXRQYWdlSW5mbyhob29rcyksXG4gICAgfTtcbiAgfTtcblxuICAvLyBGb3IgSlNPTiBvdXRwdXQsIGp1c3QgZmV0Y2ggb25jZSBhbmQgcmV0dXJuXG4gIGlmIChvcHRzLmpzb24pIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IGZldGNoSG9va3NQYWdlKG9wdHMuY3Vyc29yKTtcbiAgICAgIHNob3dKc29uUGFnZShwYWdlKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGhhbmRsZUFwaUVycm9yKGVycm9yLCBvcHRzLmJhY2tlbmQpKSB7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8vIFNldHVwIHBhZ2luYXRpb24gd2l0aCBuZXcgbWVjaGFuaXNtXG4gIGF3YWl0IHNldHVwTGlzdFBhZ2luYXRpb248UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KHtcbiAgICBpbml0aWFsQ3Vyc29yOiBvcHRzLmN1cnNvcixcbiAgICBpbnRlcmFjdGl2ZTogb3B0cy5pbnRlcmFjdGl2ZSxcbiAgICBmZXRjaFBhZ2U6IGFzeW5jIChjdXJzb3IpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmZXRjaEhvb2tzUGFnZShjdXJzb3IpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGhhbmRsZUFwaUVycm9yKGVycm9yLCBvcHRzLmJhY2tlbmQpKSB7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgIH0sXG4gICAgZGlzcGxheVBhZ2U6IGFzeW5jIChob29rcykgPT4ge1xuICAgICAgbG9nZ2VyLmxvZyhzaG93VGFibGUoaG9va3MsIEhPT0tfTElTVEVEX1BST1BTLCBvcHRzKSk7XG4gICAgICBzaG93SW5zcGVjdEluZm9Cb3goJ2hvb2snKTtcbiAgICB9LFxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaG93SG9vayA9IGFzeW5jIChcbiAgd29ybGQ6IFdvcmxkLFxuICBob29rSWQ6IHN0cmluZyxcbiAgb3B0czogSW5zcGVjdENMSU9wdGlvbnMgPSB7fVxuKSA9PiB7XG4gIGNvbnN0IHJlc29sdmVLZXkgPSBjcmVhdGVSZXNvbHZlcih3b3JsZCwgb3B0cz8uZGVjcnlwdCA/PyBmYWxzZSk7XG5cbiAgaWYgKG9wdHMud2l0aERhdGEpIHtcbiAgICBsb2dnZXIud2FybignYHdpdGhEYXRhYCBmbGFnIGlzIGlnbm9yZWQgd2hlbiBzaG93aW5nIGluZGl2aWR1YWwgcmVzb3VyY2VzJyk7XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCBob29rID0gYXdhaXQgd29ybGQuaG9va3MuZ2V0KGhvb2tJZCwge1xuICAgICAgcmVzb2x2ZURhdGE6ICdhbGwnLFxuICAgIH0pO1xuICAgIGNvbnN0IGh5ZHJhdGVkSG9vayA9IGF3YWl0IGh5ZHJhdGVSZXNvdXJjZUlPKGhvb2ssIHJlc29sdmVLZXkpO1xuICAgIGlmIChvcHRzLmpzb24pIHtcbiAgICAgIHNob3dKc29uKGh5ZHJhdGVkSG9vayk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChcbiAgICAgICAgaGFzRXhwaXJlZEZpZWxkcyhoeWRyYXRlZEhvb2sgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilcbiAgICAgICkge1xuICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICBcIlRoaXMgaG9vaydzIGRhdGEgKG1ldGFkYXRhKSBoYXMgZXhwaXJlZCBhbmQgaXMgbm8gbG9uZ2VyIGF2YWlsYWJsZS5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmxvZyhoeWRyYXRlZEhvb2spO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn07XG5cbi8qKlxuICogTGlzdCB3YWl0cy9zbGVlcHMgdmlhIHRoZSBhbmFseXRpY3MgcmVhZCBwYXRoLiBUaGUgYW5hbHl0aWNzIHdhaXQgc2hhcGUgaXNcbiAqIGtleWVkIGJ5IGB3YWl0SWRgL2BzdGF0dXNgIHJhdGhlciB0aGFuIHRoZSBgY29ycmVsYXRpb25JZGAvYGV2ZW50SWRgIGNvbHVtbnNcbiAqIHJlY29uc3RydWN0ZWQgZnJvbSB0aGUgZXZlbnQgc3RyZWFtIGluIHRoZSBmYWxsYmFjayBwYXRoLlxuICovXG5jb25zdCBsaXN0U2xlZXBzVmlhQW5hbHl0aWNzID0gYXN5bmMgKFxuICBhbmFseXRpY3M6IE5vbk51bGxhYmxlPFdvcmxkWydhbmFseXRpY3MnXT4sXG4gIG9wdHM6IEluc3BlY3RDTElPcHRpb25zXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgY29uc3QgZmV0Y2hTbGVlcHNQYWdlID0gYXN5bmMgKFxuICAgIGN1cnNvcjogc3RyaW5nIHwgdW5kZWZpbmVkXG4gICk6IFByb21pc2U8UGFnZURhdGE8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+PiA9PiB7XG4gICAgY29uc3Qgd2FpdHMgPSBhd2FpdCBhbmFseXRpY3Mud2FpdHMubGlzdCh7XG4gICAgICBydW5JZDogb3B0cy5ydW5JZCBhcyBzdHJpbmcsXG4gICAgICBwYWdpbmF0aW9uOiB7XG4gICAgICAgIHNvcnRPcmRlcjogb3B0cy5zb3J0IHx8ICdkZXNjJyxcbiAgICAgICAgY3Vyc29yLFxuICAgICAgICBsaW1pdDogb3B0cy5saW1pdCB8fCBERUZBVUxUX1BBR0VfU0laRSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogd2FpdHMuZGF0YSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sXG4gICAgICBjdXJzb3I6IHdhaXRzLmN1cnNvcixcbiAgICAgIGhhc01vcmU6IHdhaXRzLmhhc01vcmUsXG4gICAgICBwYWdlSW5mbzogZ2V0UGFnZUluZm8od2FpdHMpLFxuICAgIH07XG4gIH07XG5cbiAgaWYgKG9wdHMuanNvbikge1xuICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBmZXRjaFNsZWVwc1BhZ2Uob3B0cy5jdXJzb3IpO1xuICAgIHNob3dKc29uKHBhZ2UuZGF0YSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgYXdhaXQgc2V0dXBMaXN0UGFnaW5hdGlvbjxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oe1xuICAgIGluaXRpYWxDdXJzb3I6IG9wdHMuY3Vyc29yLFxuICAgIGludGVyYWN0aXZlOiBvcHRzLmludGVyYWN0aXZlLFxuICAgIGZldGNoUGFnZTogZmV0Y2hTbGVlcHNQYWdlLFxuICAgIGRpc3BsYXlQYWdlOiBhc3luYyAod2FpdHMpID0+IHtcbiAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgIHNob3dUYWJsZShcbiAgICAgICAgICB3YWl0cyxcbiAgICAgICAgICBbJ3dhaXRJZCcsICdzdGF0dXMnLCAnY3JlYXRlZEF0JywgJ3Jlc3VtZUF0JywgJ2NvbXBsZXRlZEF0J10sXG4gICAgICAgICAgeyAuLi5vcHRzLCBkaXNhYmxlUmVsYXRpdmVEYXRlczogdHJ1ZSB9XG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfSxcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgbGlzdFNsZWVwcyA9IGFzeW5jIChcbiAgd29ybGQ6IFdvcmxkLFxuICBvcHRzOiBJbnNwZWN0Q0xJT3B0aW9ucyA9IHt9XG4pID0+IHtcbiAgaWYgKCFvcHRzLnJ1bklkKSB7XG4gICAgbG9nZ2VyLmVycm9yKFxuICAgICAgJ3J1bi1pZCBpcyByZXF1aXJlZCBmb3IgbGlzdGluZyBzbGVlcHMuIFVzYWdlOiBgd29ya2Zsb3cgaW5zcGVjdCBzbGVlcHMgLS1ydW5JZD08aWQ+YCdcbiAgICApO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuXG4gIGlmIChvcHRzLnN0ZXBJZCkge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJ0ZpbHRlcmluZyBieSBzdGVwLWlkIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHNsZWVwcywgaWdub3JpbmcgZmlsdGVyLidcbiAgICApO1xuICB9XG4gIGlmIChvcHRzLndvcmtmbG93TmFtZSkge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgJ0ZpbHRlcmluZyBieSB3b3JrZmxvdy1uYW1lIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHNsZWVwcywgaWdub3JpbmcgZmlsdGVyLidcbiAgICApO1xuICB9XG4gIGlmIChvcHRzLndpdGhEYXRhKSB7XG4gICAgbG9nZ2VyLndhcm4oJ2B3aXRoRGF0YWAgZmxhZyBpcyBpZ25vcmVkIHdoZW4gbGlzdGluZyBzbGVlcHMnKTtcbiAgfVxuXG4gIC8vIFByZWZlciB0aGUgYW5hbHl0aWNzIHJlYWQgcGF0aCBmb3Igd2FpdC9zbGVlcCBsaXN0aW5nIHdoZW4gYXZhaWxhYmxlLlxuICBpZiAod29ybGQuYW5hbHl0aWNzKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGxpc3RTbGVlcHNWaWFBbmFseXRpY3Mod29ybGQuYW5hbHl0aWNzLCBvcHRzKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGhhbmRsZUFwaUVycm9yKGVycm9yLCBvcHRzLmJhY2tlbmQpKSB7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gRmV0Y2ggYWxsIGV2ZW50cyBmb3IgdGhlIHJ1biB3aXRoIHJlc29sdmVEYXRhPSdhbGwnIHRvIGdldCB3YWl0IGV2ZW50RGF0YVxuICAgIGNvbnN0IGV2ZW50cyA9IGF3YWl0IHdvcmxkLmV2ZW50cy5saXN0KHtcbiAgICAgIHJ1bklkOiBvcHRzLnJ1bklkLFxuICAgICAgcGFnaW5hdGlvbjoge1xuICAgICAgICBzb3J0T3JkZXI6IG9wdHMuc29ydCB8fCAnZGVzYycsXG4gICAgICAgIGxpbWl0OiAxMDAwLFxuICAgICAgfSxcbiAgICAgIHJlc29sdmVEYXRhOiAnYWxsJyxcbiAgICB9KTtcblxuICAgIC8vIFNob3cgaW5mbyBtZXNzYWdlIGlmIHRoZXJlIG1pZ2h0IGJlIG1vcmUgc2xlZXBzXG4gICAgaWYgKGV2ZW50cy5oYXNNb3JlKSB7XG4gICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgJ1dhcm5pbmc6IFRoaXMgcnVuIGhhcyBtb3JlIHRoYW4gMTAwMCBldmVudHMuIFNvbWUgc2xlZXBzIG1pZ2h0IG5vdCBiZSBzaG93bi4gUGxlYXNlIHVzZSB0aGUgd2ViIFVJIHRvIGVuc3VyZSBnZXR0aW5nIGEgY29tcGxldGUgbGlzdC4nXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEdyb3VwIHdhaXQgZXZlbnRzIGJ5IGNvcnJlbGF0aW9uSWRcbiAgICBjb25zdCB3YWl0RXZlbnRzQnlDb3JyZWxhdGlvbiA9IG5ldyBNYXA8c3RyaW5nLCBFdmVudFtdPigpO1xuICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzLmRhdGEpIHtcbiAgICAgIGlmIChpc1dhaXRFdmVudFR5cGUoZXZlbnQuZXZlbnRUeXBlKSAmJiBldmVudC5jb3JyZWxhdGlvbklkKSB7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nID0gd2FpdEV2ZW50c0J5Q29ycmVsYXRpb24uZ2V0KGV2ZW50LmNvcnJlbGF0aW9uSWQpID8/IFtdO1xuICAgICAgICBleGlzdGluZy5wdXNoKGV2ZW50KTtcbiAgICAgICAgd2FpdEV2ZW50c0J5Q29ycmVsYXRpb24uc2V0KGV2ZW50LmNvcnJlbGF0aW9uSWQsIGV4aXN0aW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAod2FpdEV2ZW50c0J5Q29ycmVsYXRpb24uc2l6ZSA9PT0gMCkge1xuICAgICAgbG9nZ2VyLndhcm4oJ05vIHNsZWVwcyBmb3VuZCBmb3IgdGhpcyBydW4uJyk7XG4gICAgICBpZiAob3B0cy5qc29uKSB7XG4gICAgICAgIHNob3dKc29uKFtdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgc2hvd1RhYmxlKFtdIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sIFdBSVRfTElTVEVEX1BST1BTLCB7XG4gICAgICAgICAgICAuLi5vcHRzLFxuICAgICAgICAgICAgZGlzYWJsZVJlbGF0aXZlRGF0ZXM6IHRydWUsXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBCdWlsZCBzbGVlcHMgZnJvbSBncm91cGVkIHdhaXQgZXZlbnRzXG4gICAgY29uc3Qgc2xlZXBzOiBTbGVlcFtdID0gW107XG4gICAgZm9yIChjb25zdCBbY29ycmVsYXRpb25JZCwgY29ycmVsYXRpb25FdmVudHNdIG9mIHdhaXRFdmVudHNCeUNvcnJlbGF0aW9uKSB7XG4gICAgICAvLyBTdGl0Y2ggdXAgd2FpdF9jcmVhdGVkIGFuZCB3YWl0X2NvbXBsZXRlZCBldmVudHNcbiAgICAgIGNvbnN0IHdhaXRDcmVhdGVkID0gY29ycmVsYXRpb25FdmVudHMuZmluZChcbiAgICAgICAgKGU6IEV2ZW50KSA9PiBlLmV2ZW50VHlwZSA9PT0gJ3dhaXRfY3JlYXRlZCdcbiAgICAgICk7XG4gICAgICBjb25zdCB3YWl0Q29tcGxldGVkID0gY29ycmVsYXRpb25FdmVudHMuZmluZChcbiAgICAgICAgKGU6IEV2ZW50KSA9PiBlLmV2ZW50VHlwZSA9PT0gJ3dhaXRfY29tcGxldGVkJ1xuICAgICAgKTtcblxuICAgICAgaWYgKHdhaXRDcmVhdGVkKSB7XG4gICAgICAgIGNvbnN0IHNsZWVwOiBTbGVlcCA9IHtcbiAgICAgICAgICBjb3JyZWxhdGlvbklkLFxuICAgICAgICAgIHJ1bklkOiB3YWl0Q3JlYXRlZC5ydW5JZCxcbiAgICAgICAgICBldmVudElkOiB3YWl0Q3JlYXRlZC5ldmVudElkLFxuICAgICAgICAgIGNyZWF0ZWRBdDogd2FpdENyZWF0ZWQuY3JlYXRlZEF0LFxuICAgICAgICAgIHJlc3VtZUF0OlxuICAgICAgICAgICAgd2FpdENyZWF0ZWQuZXZlbnRUeXBlID09PSAnd2FpdF9jcmVhdGVkJ1xuICAgICAgICAgICAgICA/IHdhaXRDcmVhdGVkLmV2ZW50RGF0YS5yZXN1bWVBdFxuICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICBjb21wbGV0ZWRBdDogd2FpdENvbXBsZXRlZD8uY3JlYXRlZEF0LFxuICAgICAgICB9O1xuICAgICAgICBzbGVlcHMucHVzaChzbGVlcCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gU29ydCBzbGVlcHMgYnkgY3JlYXRlZEF0XG4gICAgc2xlZXBzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgIGNvbnN0IHRpbWVBID0gYS5jcmVhdGVkQXQuZ2V0VGltZSgpO1xuICAgICAgY29uc3QgdGltZUIgPSBiLmNyZWF0ZWRBdC5nZXRUaW1lKCk7XG4gICAgICByZXR1cm4gb3B0cy5zb3J0ID09PSAnYXNjJyA/IHRpbWVBIC0gdGltZUIgOiB0aW1lQiAtIHRpbWVBO1xuICAgIH0pO1xuXG4gICAgaWYgKG9wdHMuanNvbikge1xuICAgICAgc2hvd0pzb24oc2xlZXBzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2dnZXIubG9nKFxuICAgICAgc2hvd1RhYmxlKFxuICAgICAgICBzbGVlcHMgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLFxuICAgICAgICBXQUlUX0xJU1RFRF9QUk9QUyxcbiAgICAgICAgeyAuLi5vcHRzLCBkaXNhYmxlUmVsYXRpdmVEYXRlczogdHJ1ZSB9XG4gICAgICApXG4gICAgKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoaGFuZGxlQXBpRXJyb3IoZXJyb3IsIG9wdHMuYmFja2VuZCkpIHtcbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn07XG4iXX0=