@workflow/core 5.0.0-beta.40 → 5.0.0-beta.42

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 (82) hide show
  1. package/dist/events-consumer.d.ts +224 -6
  2. package/dist/events-consumer.d.ts.map +1 -1
  3. package/dist/events-consumer.js +497 -50
  4. package/dist/private.d.ts +87 -18
  5. package/dist/private.d.ts.map +1 -1
  6. package/dist/private.js +118 -47
  7. package/dist/runtime/constants.d.ts +50 -1
  8. package/dist/runtime/constants.d.ts.map +1 -1
  9. package/dist/runtime/constants.js +59 -3
  10. package/dist/runtime/helpers.d.ts +212 -70
  11. package/dist/runtime/helpers.d.ts.map +1 -1
  12. package/dist/runtime/helpers.js +275 -86
  13. package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -1
  14. package/dist/runtime/quickjs-assets.generated.js +2 -2
  15. package/dist/runtime/quickjs-entrypoint.d.ts +8 -9
  16. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -1
  17. package/dist/runtime/quickjs-entrypoint.js +172 -41
  18. package/dist/runtime/quickjs-runtime.d.ts +36 -1
  19. package/dist/runtime/quickjs-runtime.d.ts.map +1 -1
  20. package/dist/runtime/quickjs-runtime.js +613 -185
  21. package/dist/runtime/quickjs-serde.d.ts +107 -0
  22. package/dist/runtime/quickjs-serde.d.ts.map +1 -0
  23. package/dist/runtime/quickjs-serde.js +2098 -0
  24. package/dist/runtime/replay-budget.d.ts +13 -14
  25. package/dist/runtime/replay-budget.d.ts.map +1 -1
  26. package/dist/runtime/replay-budget.js +20 -73
  27. package/dist/runtime/resume-hook.d.ts.map +1 -1
  28. package/dist/runtime/resume-hook.js +57 -13
  29. package/dist/runtime/resume-latency.d.ts +143 -0
  30. package/dist/runtime/resume-latency.d.ts.map +1 -0
  31. package/dist/runtime/resume-latency.js +153 -0
  32. package/dist/runtime/runs.d.ts.map +1 -1
  33. package/dist/runtime/runs.js +3 -4
  34. package/dist/runtime/start.js +2 -7
  35. package/dist/runtime/step-executor.d.ts +27 -12
  36. package/dist/runtime/step-executor.d.ts.map +1 -1
  37. package/dist/runtime/step-executor.js +105 -15
  38. package/dist/runtime/suspension-handler.d.ts +46 -8
  39. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  40. package/dist/runtime/suspension-handler.js +173 -15
  41. package/dist/runtime/world-compatibility.d.ts +16 -0
  42. package/dist/runtime/world-compatibility.d.ts.map +1 -1
  43. package/dist/runtime/world-compatibility.js +26 -5
  44. package/dist/runtime.d.ts.map +1 -1
  45. package/dist/runtime.js +911 -524
  46. package/dist/serialization/codec-devalue-vm.d.ts +7 -0
  47. package/dist/serialization/codec-devalue-vm.d.ts.map +1 -1
  48. package/dist/serialization/codec-devalue-vm.js +12 -1
  49. package/dist/serialization/codec-devalue.d.ts.map +1 -1
  50. package/dist/serialization/codec-devalue.js +15 -4
  51. package/dist/serialization/workflow-vm.d.ts +8 -3
  52. package/dist/serialization/workflow-vm.d.ts.map +1 -1
  53. package/dist/serialization/workflow-vm.js +9 -4
  54. package/dist/serialization.d.ts.map +1 -1
  55. package/dist/serialization.js +8 -3
  56. package/dist/step.js +2 -2
  57. package/dist/telemetry/semantic-conventions.d.ts +104 -0
  58. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  59. package/dist/telemetry/semantic-conventions.js +84 -1
  60. package/dist/test-support/orchestrator-context.d.ts +25 -0
  61. package/dist/test-support/orchestrator-context.d.ts.map +1 -0
  62. package/dist/test-support/orchestrator-context.js +91 -0
  63. package/dist/version.d.ts +1 -1
  64. package/dist/version.js +2 -2
  65. package/dist/vm/index.d.ts.map +1 -1
  66. package/dist/vm/index.js +9 -6
  67. package/dist/workflow/abort-controller.d.ts.map +1 -1
  68. package/dist/workflow/abort-controller.js +4 -6
  69. package/dist/workflow/attribute-dispatcher.js +2 -2
  70. package/dist/workflow/hook.js +2 -2
  71. package/dist/workflow/sleep.js +2 -2
  72. package/dist/workflow.d.ts +10 -0
  73. package/dist/workflow.d.ts.map +1 -1
  74. package/dist/workflow.js +94 -20
  75. package/docs/how-it-works/event-sourcing.mdx +11 -3
  76. package/package.json +7 -7
  77. package/dist/correlation-id.d.ts +0 -109
  78. package/dist/correlation-id.d.ts.map +0 -1
  79. package/dist/correlation-id.js +0 -139
  80. package/dist/serialization/vm-bundle-entry.d.ts +0 -12
  81. package/dist/serialization/vm-bundle-entry.d.ts.map +0 -1
  82. package/dist/serialization/vm-bundle-entry.js +0 -58
@@ -15,7 +15,9 @@
15
15
  *
16
16
  * The VM bootstrap is deliberately split into two phases:
17
17
  * 1. Static initialization (`initWorkflowVM`) — run-independent setup:
18
- * VM creation, the serde bundle, and the workflow primitives.
18
+ * VM creation and the workflow primitives. (Serialization lives on
19
+ * the host — see quickjs-serde.ts — so no serde code is evaluated
20
+ * in the VM.)
19
21
  * 2. Per-run initialization (inline in `runQuickJSWorkflow`) — seeded
20
22
  * PRNG/ULID host functions, workflow bundle evaluation, run metadata,
21
23
  * workflow input, and start.
@@ -81,13 +83,14 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
81
83
  import * as nanoid from 'nanoid';
82
84
  import { JSException, QuickJS, } from 'quickjs-wasi';
83
85
  import seedrandom from 'seedrandom';
86
+ import { monotonicFactory } from 'ulid';
84
87
  import { runtimeLogger } from '../logger.js';
85
88
  import { decompress } from '../serialization/compression.js';
86
89
  import { decrypt } from '../serialization/encryption.js';
87
- import { getReplayTimeoutMs } from './constants.js';
90
+ import { getReplayTimeoutMs, isQuickJSBaselineSnapshotEnabled, } from './constants.js';
88
91
  import { quickjsExtensions, quickjsWasm } from './quickjs-assets.generated.js';
92
+ import { adoptSerdeRoot, captureSerdeRoot, createQuickJSSerde, exportSerdeRoot, } from './quickjs-serde.js';
89
93
  import { runIdCreatedAt } from './run-id-time.js';
90
- import { VM_SERDE_BUNDLE } from './vm-serde-bundle.generated.js';
91
94
  // ---- Host -> VM payload preparation ----
92
95
  /**
93
96
  * Prepare persisted payload bytes for consumption inside the VM: decrypt
@@ -148,17 +151,17 @@ globalThis.__terminalBuffer = {};
148
151
 
149
152
  // Registers a resolver for an awaited primitive, first draining any
150
153
  // buffered terminal recorded for the correlationId. Entries are prepared
151
- // host-side (bytes already decrypted; see processEvents).
154
+ // host-side: bytes are decrypted AND deserialized into VM values by the
155
+ // host serde before buffering (the VM has no in-guest deserializer on
156
+ // the host-serde engine), so draining only forwards the stored value.
152
157
  globalThis.__registerResolver = function(correlationId, resolve, reject) {
153
158
  var buffered = globalThis.__terminalBuffer[correlationId];
154
159
  if (buffered) {
155
160
  delete globalThis.__terminalBuffer[correlationId];
156
- if (buffered.kind === "resolve_bytes") {
157
- resolve(globalThis[Symbol.for("workflow-deserialize")](buffered.bytes));
158
- } else if (buffered.kind === "resolve_value") {
161
+ if (buffered.kind === "resolve_value") {
159
162
  resolve(buffered.value);
160
- } else if (buffered.kind === "reject_bytes") {
161
- reject(globalThis[Symbol.for("workflow-deserialize")](buffered.bytes));
163
+ } else if (buffered.kind === "reject_value") {
164
+ reject(buffered.value);
162
165
  } else if (buffered.kind === "reject_error") {
163
166
  var e = new Error(buffered.message);
164
167
  e.name = "FatalError";
@@ -314,13 +317,14 @@ globalThis[Symbol.for("WORKFLOW_USE_STEP")] = function(stepId, closureVarsFn) {
314
317
  var correlationId = "step_" + globalThis.__generateUlid();
315
318
  // Capture 'this' for method invocations (e.g., MyClass.method())
316
319
  var thisVal = (this !== undefined && this !== null && this !== globalThis) ? this : undefined;
317
- // Serialize step input using the host-provided devalue serializer.
318
- // This produces a format-prefixed Uint8Array ("devl" + devalue.stringify).
319
- var input = globalThis[Symbol.for("workflow-serialize")]({
320
+ // The RAW input value. Serialization happens on the host, which reads
321
+ // this through a handle when it collects the pending op — no
322
+ // serializer code runs inside the VM.
323
+ var input = {
320
324
  args: args,
321
325
  closureVars: closureVarsFn ? closureVarsFn() : undefined,
322
326
  thisVal: thisVal,
323
- });
327
+ };
324
328
  globalThis.__pending.push({
325
329
  type: "step",
326
330
  correlationId: correlationId,
@@ -537,16 +541,15 @@ globalThis[Symbol.for("WORKFLOW_CREATE_HOOK")] = function(options) {
537
541
  }
538
542
  }
539
543
 
540
- // Register in pending operations.
541
- // Serialize metadata inside the VM so Response/Request objects are
542
- // properly handled by the devalue reducers before crossing the boundary.
544
+ // Register in pending operations. Metadata stays a RAW value; the host
545
+ // serializes it through a handle when it collects the pending op.
543
546
  var pendingOp = {
544
547
  type: "hook",
545
548
  correlationId: correlationId,
546
549
  token: token,
547
550
  tokenRetentionUntil: tokenRetentionUntil,
548
551
  isWebhook: !!options.isWebhook,
549
- metadata: options.metadata ? globalThis[Symbol.for("workflow-serialize")](options.metadata) : undefined,
552
+ metadata: options.metadata,
550
553
  hasCreatedEvent: false,
551
554
  };
552
555
  globalThis.__pending.push(pendingOp);
@@ -747,8 +750,8 @@ WorkflowAbortSignal.prototype.throwIfAborted = function() {
747
750
  : __makeAbortError();
748
751
  }
749
752
  };
750
- // Expose for the serde bundle's revivers (evaluated before this bootstrap;
751
- // they look the class up lazily at revive time).
753
+ // Expose for the host serde's revivers (they look the class up lazily,
754
+ // through a handle, at revive time).
752
755
  globalThis.__WorkflowAbortSignal = WorkflowAbortSignal;
753
756
 
754
757
  // Registry of live abort signals keyed by their hook correlationId. The
@@ -779,17 +782,17 @@ globalThis.AbortController.prototype.abort = function(reason) {
779
782
  if (this.signal.aborted) return; // already aborted (e.g. from replay)
780
783
  this.signal._setAborted(reason);
781
784
  // Mark the pending hook op so the host records the abort. The payload
782
- // is serialized in the VM so the reason crosses the boundary with
785
+ // stays a RAW value; the host serializes it through a handle with full
783
786
  // type fidelity (Errors, DOMException, custom values).
784
787
  var token = this[__ABORT_HOOK_TOKEN];
785
788
  for (var i = 0; i < globalThis.__pending.length; i++) {
786
789
  var item = globalThis.__pending[i];
787
790
  if (item.type === "hook" && item.token === token) {
788
791
  item.abortRequested = true;
789
- item.abortPayload = globalThis[Symbol.for("workflow-serialize")]({
792
+ item.abortPayload = {
790
793
  aborted: true,
791
794
  reason: reason,
792
- });
795
+ };
793
796
  break;
794
797
  }
795
798
  }
@@ -860,9 +863,10 @@ globalThis[Symbol.for("WORKFLOW_GET_STREAM_ID")] = function(namespace) {
860
863
  * Phase 1 — static (run-independent) VM initialization.
861
864
  *
862
865
  * Creates a QuickJS VM and loads everything that does not depend on a
863
- * specific workflow run: the serde bundle (devalue-based serialization
864
- * used at the host/VM boundary) and the workflow-primitive bootstrap
865
- * (useStep / sleep / createHook / Response-Request polyfills).
866
+ * specific workflow run: the workflow-primitive bootstrap (useStep /
867
+ * sleep / createHook / Response-Request polyfills). Serialization is
868
+ * host-side (quickjs-serde.ts) and captures its intrinsics from the VM
869
+ * right after this returns.
866
870
  *
867
871
  * `getNowMs` backs the VM's WASI clock (`Date.now()` / `new Date()`
868
872
  * inside the VM). The callback itself is static — the per-run state it
@@ -913,33 +917,218 @@ function getCompiledAssets() {
913
917
  }
914
918
  return compiledAssetsPromise;
915
919
  }
916
- async function initWorkflowVM(getNowMs, interruptBudget) {
917
- // Deterministic replay clock: Date.now() / new Date() inside the VM
918
- // read the host-controlled clock instead of wall time. Replay
919
- // re-executes the workflow from the top on every invocation, so the
920
- // clock must be derived from the event log (not real time) for the
921
- // workflow to observe stable timestamps across invocations.
922
- const wasi = (memory) => ({
920
+ /**
921
+ * WASI clock override reading the given accessor shared between fresh
922
+ * boots (initWorkflowVM) and baseline-snapshot restores, so the two
923
+ * paths cannot drift on rounding/encoding.
924
+ *
925
+ * Deterministic replay clock: Date.now() / new Date() inside the VM
926
+ * read the host-controlled clock instead of wall time. Replay
927
+ * re-executes the workflow from the top on every invocation, so the
928
+ * clock must be derived from the event log (not real time) for the
929
+ * workflow to observe stable timestamps across invocations.
930
+ */
931
+ function makeDeterministicClockWasi(getNowMs) {
932
+ return (memory) => ({
923
933
  clock_time_get(_clockId, _precision, resultPtr) {
924
934
  const timeNs = BigInt(Math.round(getNowMs())) * 1000000n;
925
935
  new DataView(memory.buffer).setBigUint64(resultPtr, timeNs, true);
926
936
  return 0;
927
937
  },
928
938
  });
939
+ }
940
+ async function initWorkflowVM(getNowMs, interruptBudget) {
929
941
  const assets = await getCompiledAssets();
930
942
  const vm = await QuickJS.create({
931
943
  wasm: assets.wasm,
932
944
  memoryLimit: 256 * 1024 * 1024,
933
945
  interruptHandler: createInterruptHandler(interruptBudget),
934
946
  extensions: assets.extensions,
935
- wasi,
947
+ wasi: makeDeterministicClockWasi(getNowMs),
936
948
  });
937
- // Evaluate the VM serde bundle
938
- vm.evalCode(VM_SERDE_BUNDLE, 'vm-serde.js').dispose();
939
949
  // Bootstrap workflow primitives
940
950
  vm.evalCode(VM_BOOTSTRAP, 'bootstrap.js').dispose();
941
951
  return vm;
942
952
  }
953
+ // ---- Baseline snapshot (startup optimization) --------------------------
954
+ //
955
+ // Evaluating the workflow bundle dominates VM startup (~74ms of a ~77ms
956
+ // boot for a 1.3MB bundle), and full event replay pays it on EVERY
957
+ // invocation. The bundle is identical across all runs of a deployment, so
958
+ // the engine hydrates one VM per function instance (bootstrap + bundle
959
+ // eval), snapshots its memory, and starts every invocation by restoring
960
+ // the snapshot (~3ms) instead of re-evaluating.
961
+ //
962
+ // Determinism: replay requires module-scope user code to observe the
963
+ // run-seeded PRNG and the run's deterministic clock. A restored heap
964
+ // carries whatever module scope computed at HYDRATE time, so the
965
+ // optimization is only sound when module scope consumed neither
966
+ // randomness nor time. Both are detected during hydrate — the placeholder
967
+ // host fns count draws, the hydrate clock counts reads — and a bundle
968
+ // that used either is marked ineligible: every invocation falls back to
969
+ // fresh evaluation, preserving exact node:vm-parity semantics. When the
970
+ // gate passes, restore is byte-equivalent to fresh eval (verified by the
971
+ // parity tests): the per-run host fns are re-registered by name on the
972
+ // restored VM (quickjs-wasi restore semantics) before the workflow body
973
+ // runs, so the seeded draw sequence — and every correlationId — is
974
+ // identical.
975
+ //
976
+ // The cache is per function instance and keyed on the bundle string
977
+ // (reference-stable: the generated flow route holds it in a module-level
978
+ // const). Capped at a few entries so tests with many distinct bundles
979
+ // don't accumulate 16MB snapshots.
980
+ /**
981
+ * Eval filename used when hydrating the baseline VM. The baseline is
982
+ * shared by EVERY workflow in the bundle, so the filename baked into
983
+ * its compiled code (and therefore into snapshot-path stack frames)
984
+ * must be workflow-independent — hydrating under the first caller's
985
+ * workflowId would break `remapErrorStack`'s filename matching for
986
+ * every other workflow in the bundle. Remap call sites match this
987
+ * constant IN ADDITION to the run's module specifier (which covers
988
+ * fresh-path frames).
989
+ */
990
+ export const BASELINE_BUNDLE_FILENAME = 'workflow-bundle.js';
991
+ const baselineCache = new Map();
992
+ const BASELINE_CACHE_MAX_ENTRIES = 4;
993
+ /** Test-only: reset the baseline cache between test cases. */
994
+ export function __clearBaselineSnapshotCacheForTests() {
995
+ baselineCache.clear();
996
+ }
997
+ /** Test-only: observe how a bundle was classified. */
998
+ export async function __peekBaselineEntryForTests(workflowCode) {
999
+ return baselineCache.get(workflowCode);
1000
+ }
1001
+ /**
1002
+ * Hydrate a VM with the workflow bundle and snapshot it, gating on
1003
+ * module-scope nondeterminism (see the section comment above). Returns an
1004
+ * `ineligible` entry instead of throwing on eval failure — the fresh path
1005
+ * re-evaluates and produces the real, source-mapped error.
1006
+ */
1007
+ async function prepareBaselineSnapshot(workflowCode, workflowId) {
1008
+ const hydrateStart = Date.now();
1009
+ let clockReads = 0;
1010
+ const budget = { start: Date.now() };
1011
+ const assets = await getCompiledAssets();
1012
+ const vm = await QuickJS.create({
1013
+ wasm: assets.wasm,
1014
+ memoryLimit: 256 * 1024 * 1024,
1015
+ interruptHandler: createInterruptHandler(budget),
1016
+ extensions: assets.extensions,
1017
+ wasi: ((memory) => ({
1018
+ clock_time_get(_clockId, _precision, resultPtr) {
1019
+ clockReads++;
1020
+ const timeNs = BigInt(hydrateStart) * 1000000n;
1021
+ new DataView(memory.buffer).setBigUint64(resultPtr, timeNs, true);
1022
+ return 0;
1023
+ },
1024
+ })),
1025
+ });
1026
+ try {
1027
+ vm.evalCode(VM_BOOTSTRAP, 'bootstrap.js').dispose();
1028
+ // Placeholder host fns under the SAME NAMES the per-run phase uses.
1029
+ // They exist so module-scope code can execute at hydrate time, and to
1030
+ // detect that it did: any draw means the heap would bake
1031
+ // hydrate-seeded values that per-run fresh eval would compute
1032
+ // differently. runWorkflowInVM re-registers all three names with the
1033
+ // run-seeded closures after restore.
1034
+ let draws = 0;
1035
+ {
1036
+ const env_1 = { stack: [], error: void 0, hasError: false };
1037
+ try {
1038
+ const randomFn = __addDisposableResource(env_1, vm.newFunction('random', () => {
1039
+ draws++;
1040
+ return vm.newNumber(Math.random());
1041
+ }), false);
1042
+ const math = __addDisposableResource(env_1, vm.global.getProp('Math'), false);
1043
+ math.setProp('random', randomFn);
1044
+ const nanoidFn = __addDisposableResource(env_1, vm.newFunction('__generateNanoid', () => {
1045
+ draws++;
1046
+ return vm.newString('baseline-placeholder');
1047
+ }), false);
1048
+ vm.setProp(vm.global, '__generateNanoid', nanoidFn);
1049
+ const ulidFn = __addDisposableResource(env_1, vm.newFunction('__generateUlid', () => {
1050
+ draws++;
1051
+ return vm.newString('00000000000000000000000000');
1052
+ }), false);
1053
+ vm.setProp(vm.global, '__generateUlid', ulidFn);
1054
+ }
1055
+ catch (e_1) {
1056
+ env_1.error = e_1;
1057
+ env_1.hasError = true;
1058
+ }
1059
+ finally {
1060
+ __disposeResources(env_1);
1061
+ }
1062
+ }
1063
+ // Serde capture root — created BEFORE the bundle evaluates, exactly
1064
+ // like the fresh path's capture. Its box pointer rides the
1065
+ // BaselineEntry and each restored VM re-adopts it, so serde
1066
+ // initialization never executes guest code after user code has run.
1067
+ // This is what makes module-scope intrinsic patching (polyfills,
1068
+ // stateful wrappers around Object.getOwnPropertyDescriptor, …)
1069
+ // HARMLESS on the snapshot path rather than merely detectable: the
1070
+ // serde uses the pristine pre-eval captures on both paths, and no
1071
+ // post-eval probe exists whose side effects could bake into the
1072
+ // snapshot. The handle is deliberately NOT disposed before the
1073
+ // snapshot — the box must stay live in the memory image (the
1074
+ // baseline VM's dispose below tears down the whole instance without
1075
+ // freeing individual boxes).
1076
+ const serdeRoot = captureSerdeRoot(vm);
1077
+ clockReads = 0; // only count reads made by the bundle itself
1078
+ try {
1079
+ // Workflow-independent filename — see BASELINE_BUNDLE_FILENAME.
1080
+ vm.evalCode(workflowCode, BASELINE_BUNDLE_FILENAME).dispose();
1081
+ }
1082
+ catch {
1083
+ // Let the fresh path re-evaluate and surface the real error with
1084
+ // proper filename / source-map handling.
1085
+ return {
1086
+ state: 'ineligible',
1087
+ reason: 'module scope threw during hydrate',
1088
+ };
1089
+ }
1090
+ if (draws > 0 || clockReads > 0) {
1091
+ runtimeLogger.info('QuickJS baseline snapshot disabled for this bundle: module scope consumed nondeterministic inputs; every invocation will evaluate the bundle fresh', { workflowId, draws, clockReads });
1092
+ return {
1093
+ state: 'ineligible',
1094
+ reason: `module scope consumed ${draws} PRNG draw(s) and ${clockReads} clock read(s)`,
1095
+ };
1096
+ }
1097
+ const snapshot = vm.snapshot();
1098
+ runtimeLogger.debug('QuickJS baseline snapshot prepared', {
1099
+ workflowId,
1100
+ hydrateMs: Date.now() - hydrateStart,
1101
+ });
1102
+ return {
1103
+ state: 'ready',
1104
+ snapshot,
1105
+ serdeRootPtr: exportSerdeRoot(vm, serdeRoot),
1106
+ };
1107
+ }
1108
+ finally {
1109
+ vm.dispose();
1110
+ }
1111
+ }
1112
+ /**
1113
+ * Cached baseline entry for a bundle, preparing it on first access.
1114
+ * Concurrent first invocations share one hydrate via the cached promise;
1115
+ * a hydrate that REJECTS (infrastructure failure, not bundle eval — that
1116
+ * returns `ineligible`) is evicted so a later invocation can retry.
1117
+ */
1118
+ function getBaselineEntry(workflowCode, workflowId) {
1119
+ let entry = baselineCache.get(workflowCode);
1120
+ if (!entry) {
1121
+ if (baselineCache.size >= BASELINE_CACHE_MAX_ENTRIES) {
1122
+ const oldest = baselineCache.keys().next().value;
1123
+ if (oldest !== undefined)
1124
+ baselineCache.delete(oldest);
1125
+ }
1126
+ entry = prepareBaselineSnapshot(workflowCode, workflowId);
1127
+ baselineCache.set(workflowCode, entry);
1128
+ entry.catch(() => baselineCache.delete(workflowCode));
1129
+ }
1130
+ return entry;
1131
+ }
943
1132
  /**
944
1133
  * Run a workflow invocation to its first settled state and dispose the
945
1134
  * VM. Convenience wrapper over {@link startQuickJSWorkflow} for callers
@@ -991,8 +1180,60 @@ export async function startQuickJSWorkflow(options) {
991
1180
  vmNowMs = Math.max(vmNowMs, ms);
992
1181
  };
993
1182
  // ---- Phase 1: static initialization ----
1183
+ //
1184
+ // Baseline-snapshot fast path (default ON; see the section comment at
1185
+ // prepareBaselineSnapshot): restore a bundle-hydrated VM instead of
1186
+ // booting fresh and re-evaluating the bundle. `ineligible` bundles
1187
+ // (module-scope nondeterminism, eval failure) take the fresh path with
1188
+ // identical semantics.
994
1189
  const interruptBudget = { start: Date.now() };
995
- const vm = await initWorkflowVM(() => vmNowMs, interruptBudget);
1190
+ let baselineSnapshot;
1191
+ let baselineSerdeRootPtr;
1192
+ if (isQuickJSBaselineSnapshotEnabled()) {
1193
+ try {
1194
+ const entry = await getBaselineEntry(workflowCode, workflowId);
1195
+ if (entry.state === 'ready') {
1196
+ baselineSnapshot = entry.snapshot;
1197
+ baselineSerdeRootPtr = entry.serdeRootPtr;
1198
+ }
1199
+ }
1200
+ catch (err) {
1201
+ // A rejection here is an infrastructure failure during hydrate
1202
+ // (e.g. vm.snapshot() under memory pressure, QuickJS.create or
1203
+ // getCompiledAssets() failing) — NOT bundle eval, which returns
1204
+ // an ineligible entry. getBaselineEntry has already evicted the
1205
+ // cached promise so a later invocation can retry. This invocation
1206
+ // must fall back to fresh evaluation (which would have succeeded)
1207
+ // rather than fail the whole run for a snapshot-only failure mode.
1208
+ runtimeLogger.warn('QuickJS baseline snapshot hydrate failed; falling back to fresh evaluation for this invocation', { workflowId, error: err });
1209
+ }
1210
+ }
1211
+ let vm;
1212
+ if (baselineSnapshot) {
1213
+ const assets = await getCompiledAssets();
1214
+ vm = await QuickJS.restore(baselineSnapshot, {
1215
+ wasm: assets.wasm,
1216
+ memoryLimit: 256 * 1024 * 1024,
1217
+ interruptHandler: createInterruptHandler(interruptBudget),
1218
+ extensions: assets.extensions,
1219
+ wasi: makeDeterministicClockWasi(() => vmNowMs),
1220
+ });
1221
+ }
1222
+ else {
1223
+ vm = await initWorkflowVM(() => vmNowMs, interruptBudget);
1224
+ }
1225
+ // Host-side serde: captures the VM's intrinsics (bootstrap included)
1226
+ // before any user code runs. All serialization now happens on the host
1227
+ // through handles — no serializer code is evaluated inside the VM.
1228
+ // Fresh path: capture now (no user code has run — the bundle evaluates
1229
+ // later in the per-run phase). Snapshot path: re-adopt the capture root
1230
+ // the baseline hydrate created BEFORE the bundle evaluated — the box
1231
+ // lives in the restored memory image at the recorded offset. Both give
1232
+ // the serde pristine capture-before-user-code intrinsics; neither
1233
+ // executes guest code here.
1234
+ const serde = baselineSnapshot && baselineSerdeRootPtr !== undefined
1235
+ ? createQuickJSSerde(vm, adoptSerdeRoot(vm, baselineSerdeRootPtr))
1236
+ : createQuickJSSerde(vm);
996
1237
  // Any throw between here and the terminal paths (which dispose the VM
997
1238
  // inside checkWorkflowState / extractError before RETURNING) would leak
998
1239
  // a live QuickJS instance and its WASM linear memory for the lifetime
@@ -1015,66 +1256,91 @@ export async function startQuickJSWorkflow(options) {
1015
1256
  vm.evalCode(`globalThis.__worldCapabilities = ${JSON.stringify(options.worldCapabilities)};`).dispose();
1016
1257
  // Seeded Math.random
1017
1258
  {
1018
- const env_1 = { stack: [], error: void 0, hasError: false };
1259
+ const env_2 = { stack: [], error: void 0, hasError: false };
1019
1260
  try {
1020
- const randomFn = __addDisposableResource(env_1, vm.newFunction('random', () => vm.newNumber(rng())), false);
1021
- const math = __addDisposableResource(env_1, vm.global.getProp('Math'), false);
1261
+ const randomFn = __addDisposableResource(env_2, vm.newFunction('random', () => vm.newNumber(rng())), false);
1262
+ const math = __addDisposableResource(env_2, vm.global.getProp('Math'), false);
1022
1263
  math.setProp('random', randomFn);
1023
1264
  }
1024
- catch (e_1) {
1025
- env_1.error = e_1;
1026
- env_1.hasError = true;
1265
+ catch (e_2) {
1266
+ env_2.error = e_2;
1267
+ env_2.hasError = true;
1027
1268
  }
1028
1269
  finally {
1029
- __disposeResources(env_1);
1270
+ __disposeResources(env_2);
1030
1271
  }
1031
1272
  }
1032
1273
  // Seeded nanoid generator
1033
1274
  {
1034
- const env_2 = { stack: [], error: void 0, hasError: false };
1275
+ const env_3 = { stack: [], error: void 0, hasError: false };
1035
1276
  try {
1036
- const nanoidFn = __addDisposableResource(env_2, vm.newFunction('__generateNanoid', () => vm.newString(generateNanoid())), false);
1277
+ const nanoidFn = __addDisposableResource(env_3, vm.newFunction('__generateNanoid', () => vm.newString(generateNanoid())), false);
1037
1278
  vm.setProp(vm.global, '__generateNanoid', nanoidFn);
1038
1279
  }
1039
- catch (e_2) {
1040
- env_2.error = e_2;
1041
- env_2.hasError = true;
1280
+ catch (e_3) {
1281
+ env_3.error = e_3;
1282
+ env_3.hasError = true;
1042
1283
  }
1043
1284
  finally {
1044
- __disposeResources(env_2);
1285
+ __disposeResources(env_3);
1045
1286
  }
1046
1287
  }
1047
- // Inject a deterministic timestamp for the VM's ULID factory. ULIDs
1048
- // produced inside the VM use this as their time prefix instead of
1049
- // Date.now(), so two concurrent workflow invocations of the same run
1050
- // produce IDENTICAL correlationIds (the random portion also matches
1051
- // because the PRNG is seeded the same way) and the world's
1288
+ // Host-side deterministic ULID generator for correlationIds. Uses the
1289
+ // same `ulid` package and monotonic factory as before, drawing from
1290
+ // the SAME seeded PRNG instance as the VM's Math.random — so the
1291
+ // interleaved draw sequence (and therefore every correlationId) is
1292
+ // byte-identical to what the previous in-VM ULID factory produced for
1293
+ // the same run. The time prefix is derived from the runId's embedded
1294
+ // ULID (stable across invocations by construction — unlike
1295
+ // `startedAt`, which differs between turbo's synthesized run object
1296
+ // and the durably stored run), so two concurrent invocations of the
1297
+ // same run produce IDENTICAL correlationIds and the world's
1052
1298
  // EntityConflictError on `events.create` dedups one of each pair.
1053
- // Derived from the runId's embedded ULID (stable across invocations by
1054
- // construction — unlike `startedAt`, which differs between turbo's
1055
- // synthesized run object and the durably stored run).
1056
- vm.evalCode(`globalThis.__ulidTimestamp = ${runIdCreatedAt(workflowRun.runId) ?? (+workflowRun.createdAt || startedAt)};`).dispose();
1057
- // `process.env` — parity with the node:vm engine, which exposes a frozen
1058
- // copy of the host env (vm/index.ts). Injected per run so the snapshot of
1059
- // the env is taken at invocation time, same as node.
1060
1299
  {
1061
- const envHandle = vm.newString(JSON.stringify(process.env));
1062
- vm.setProp(vm.global, '__wdk_env', envHandle);
1063
- envHandle.dispose();
1064
- vm.evalCode('globalThis.process = { env: Object.freeze(JSON.parse(globalThis.__wdk_env)) };' +
1065
- 'delete globalThis.__wdk_env;').dispose();
1300
+ const env_4 = { stack: [], error: void 0, hasError: false };
1301
+ try {
1302
+ const ulidFactory = monotonicFactory(() => rng());
1303
+ const ulidTimestamp = runIdCreatedAt(workflowRun.runId) ??
1304
+ (+workflowRun.createdAt || startedAt);
1305
+ const ulidFn = __addDisposableResource(env_4, vm.newFunction('__generateUlid', () => vm.newString(ulidFactory(ulidTimestamp))), false);
1306
+ vm.setProp(vm.global, '__generateUlid', ulidFn);
1307
+ }
1308
+ catch (e_4) {
1309
+ env_4.error = e_4;
1310
+ env_4.hasError = true;
1311
+ }
1312
+ finally {
1313
+ __disposeResources(env_4);
1314
+ }
1066
1315
  }
1316
+ // `process.env` — parity with the node:vm engine, which exposes a frozen
1317
+ // copy of the host env (vm/index.ts). Injected per run so the snapshot of
1318
+ // the env is taken at invocation time, same as node. Handle-based (no
1319
+ // guest source evaluated): on the baseline-snapshot path this runs
1320
+ // after user code, and a guest-source injection would execute through
1321
+ // potentially patched globals (JSON.parse, Object.freeze) — visible
1322
+ // to module-scope wrappers only on the restore path, diverging
1323
+ // replays.
1324
+ serde.installProcessEnv(process.env);
1067
1325
  // Execute the workflow bundle — use the workflowId as the eval filename
1068
1326
  // so QuickJS stack traces reference the workflow name, enabling source map
1069
1327
  // remapping by remapErrorStack (which matches frames by filename).
1070
1328
  // Evaluated in the per-run phase (after Math.random seeding) so that
1071
1329
  // module-scope user code draws from the seeded PRNG, matching the
1072
- // node:vm engine's replay determinism.
1073
- try {
1074
- vm.evalCode(workflowCode, workflowId || 'workflow.js').dispose();
1075
- }
1076
- catch (err) {
1077
- return makeSettledSession(extractError(vm, err, 'Workflow evaluation failed'));
1330
+ // node:vm engine's replay determinism. Skipped on the
1331
+ // baseline-snapshot path: the restored heap already carries the
1332
+ // evaluated bundle, and the baseline gate guarantees module scope
1333
+ // consumed no PRNG draws or clock reads — so skipping the eval is
1334
+ // observationally identical to re-running it (the run-seeded host
1335
+ // fns registered above rebind the SAME names the restored heap's
1336
+ // function objects dispatch through).
1337
+ if (!baselineSnapshot) {
1338
+ try {
1339
+ vm.evalCode(workflowCode, workflowId || 'workflow.js').dispose();
1340
+ }
1341
+ catch (err) {
1342
+ return makeSettledSession(extractError(vm, err, 'Workflow evaluation failed'));
1343
+ }
1078
1344
  }
1079
1345
  // Extract workflow arguments. Prefer the run_created event; fall back
1080
1346
  // to the queue message's runInput if the event log is incomplete
@@ -1094,7 +1360,9 @@ export async function startQuickJSWorkflow(options) {
1094
1360
  byteLength: decryptedInput.byteLength,
1095
1361
  source: runCreatedInput ? 'run_created' : 'queueMessage.runInput',
1096
1362
  });
1097
- const inputHandle = vm.newUint8Array(decryptedInput);
1363
+ // Build the argument value directly in the VM via the host-side
1364
+ // serde (guest code never sees the wire bytes).
1365
+ const inputHandle = serde.deserialize(decryptedInput);
1098
1366
  vm.setProp(vm.global, '__wdk_input', inputHandle);
1099
1367
  inputHandle.dispose();
1100
1368
  }
@@ -1148,24 +1416,30 @@ export async function startQuickJSWorkflow(options) {
1148
1416
  __wfnErr.name = "WorkflowNotRegisteredError";
1149
1417
  throw __wfnErr;
1150
1418
  }
1151
- var __args = globalThis.__wdk_input
1152
- ? globalThis[Symbol.for("workflow-deserialize")](globalThis.__wdk_input)
1419
+ var __args = globalThis.__wdk_input !== undefined
1420
+ ? globalThis.__wdk_input
1153
1421
  : [];
1154
1422
  delete globalThis.__wdk_input;
1155
1423
  if (!Array.isArray(__args)) __args = [__args];
1156
1424
  __wfn.apply(null, __args).then(
1157
- function(result) { globalThis.__workflowResult = globalThis[Symbol.for("workflow-serialize")](result); },
1425
+ function(result) {
1426
+ // Store the RAW result; the host serializes it through a handle.
1427
+ // A separate done flag distinguishes "completed with undefined"
1428
+ // from "not completed".
1429
+ globalThis.__workflowDone = true;
1430
+ globalThis.__workflowResult = result;
1431
+ },
1158
1432
  function(error) {
1159
1433
  // Preserve display info on the host-side failed object
1160
- // (matches the legacy host-visible shape) AND serialize the
1161
- // entire thrown value so the host can dehydrate the original
1434
+ // (matches the legacy host-visible shape) AND keep the RAW
1435
+ // thrown value so the host can serialize the original
1162
1436
  // type-identity, cause chain, or non-Error throws verbatim
1163
1437
  // through the standard error pipeline.
1164
1438
  globalThis.__workflowError = {
1165
1439
  message: error && error.message != null ? String(error.message) : String(error),
1166
1440
  stack: error && error.stack ? error.stack : "",
1167
1441
  name: error && error.name ? error.name : (error instanceof Error ? "Error" : typeof error),
1168
- valueBytes: globalThis[Symbol.for("workflow-serialize")](error),
1442
+ value: error,
1169
1443
  };
1170
1444
  }
1171
1445
  );
@@ -1182,7 +1456,7 @@ export async function startQuickJSWorkflow(options) {
1182
1456
  let maxIterations = 100;
1183
1457
  let madeProgress;
1184
1458
  do {
1185
- madeProgress = await processEvents(vm, events, advanceClock, options.encryptionKey);
1459
+ madeProgress = await processEvents(vm, serde, events, advanceClock, options.encryptionKey);
1186
1460
  let batch;
1187
1461
  do {
1188
1462
  batch = vm.executePendingJobs();
@@ -1202,7 +1476,7 @@ export async function startQuickJSWorkflow(options) {
1202
1476
  }
1203
1477
  }
1204
1478
  // ---- Check result ----
1205
- return makeLiveSession(vm, interruptBudget, advanceClock, options.encryptionKey);
1479
+ return makeLiveSession(vm, serde, interruptBudget, advanceClock, options.encryptionKey);
1206
1480
  }
1207
1481
  }
1208
1482
  /** Session wrapper for a result whose VM is already settled/disposed. */
@@ -1220,8 +1494,8 @@ function makeSettledSession(result) {
1220
1494
  * the VM stays alive so `continueWithEvents` can resume it in place;
1221
1495
  * terminal states dispose the VM immediately (inside checkWorkflowState).
1222
1496
  */
1223
- function makeLiveSession(vm, interruptBudget, advanceClock, encryptionKey) {
1224
- const result = checkWorkflowState(vm, { keepAliveOnSuspend: true });
1497
+ function makeLiveSession(vm, serde, interruptBudget, advanceClock, encryptionKey) {
1498
+ const result = checkWorkflowState(vm, serde, { keepAliveOnSuspend: true });
1225
1499
  let alive = !!result.suspended;
1226
1500
  const session = {
1227
1501
  result,
@@ -1235,7 +1509,7 @@ function makeLiveSession(vm, interruptBudget, advanceClock, encryptionKey) {
1235
1509
  let maxIterations = 100;
1236
1510
  let madeProgress;
1237
1511
  do {
1238
- madeProgress = await processEvents(vm, newEvents, advanceClock, encryptionKey);
1512
+ madeProgress = await processEvents(vm, serde, newEvents, advanceClock, encryptionKey);
1239
1513
  let batch;
1240
1514
  do {
1241
1515
  batch = vm.executePendingJobs();
@@ -1243,7 +1517,9 @@ function makeLiveSession(vm, interruptBudget, advanceClock, encryptionKey) {
1243
1517
  madeProgress = true;
1244
1518
  } while (batch > 0);
1245
1519
  } while (madeProgress && --maxIterations > 0);
1246
- const next = checkWorkflowState(vm, { keepAliveOnSuspend: true });
1520
+ const next = checkWorkflowState(vm, serde, {
1521
+ keepAliveOnSuspend: true,
1522
+ });
1247
1523
  if (!next.suspended)
1248
1524
  alive = false;
1249
1525
  session.result = next;
@@ -1264,7 +1540,7 @@ function makeLiveSession(vm, interruptBudget, advanceClock, encryptionKey) {
1264
1540
  return session;
1265
1541
  }
1266
1542
  // ---- Event Processing ----
1267
- async function processEvents(vm, events, advanceClock, encryptionKey) {
1543
+ async function processEvents(vm, serde, events, advanceClock, encryptionKey) {
1268
1544
  let resolved = false;
1269
1545
  for (const event of events) {
1270
1546
  // Advance the VM's deterministic clock to this event's creation time
@@ -1303,10 +1579,10 @@ async function processEvents(vm, events, advanceClock, encryptionKey) {
1303
1579
  prefix: new TextDecoder().decode(decryptedOutput.subarray(0, 4)),
1304
1580
  byteLength: decryptedOutput.byteLength,
1305
1581
  });
1306
- const bytesHandle = vm.newUint8Array(decryptedOutput);
1307
- vm.setProp(vm.global, '__tmp_result', bytesHandle);
1308
- bytesHandle.dispose();
1309
- vm.evalCode(`globalThis.__resolvers[${cidJs}].resolve(globalThis[Symbol.for("workflow-deserialize")](globalThis.__tmp_result));` +
1582
+ const valueHandle = serde.deserialize(decryptedOutput);
1583
+ vm.setProp(vm.global, '__tmp_result', valueHandle);
1584
+ valueHandle.dispose();
1585
+ vm.evalCode(`globalThis.__resolvers[${cidJs}].resolve(globalThis.__tmp_result);` +
1310
1586
  `delete globalThis.__resolvers[${cidJs}];` +
1311
1587
  `delete globalThis.__tmp_result;`).dispose();
1312
1588
  }
@@ -1339,10 +1615,12 @@ async function processEvents(vm, events, advanceClock, encryptionKey) {
1339
1615
  // the await never settles.
1340
1616
  if (rawOutput instanceof Uint8Array) {
1341
1617
  const decryptedOutput = await prepareBytesForVM(rawOutput, encryptionKey);
1342
- const bytesHandle = vm.newUint8Array(decryptedOutput);
1343
- vm.setProp(vm.global, '__tmp_buf', bytesHandle);
1344
- bytesHandle.dispose();
1345
- vm.evalCode(`globalThis.__terminalBuffer[${cidJs}] = { kind: "resolve_bytes", bytes: globalThis.__tmp_buf };` +
1618
+ // Host serde: deserialize into a VM value NOW (same path as
1619
+ // the resolver branch above) and buffer the value itself.
1620
+ const valueHandle = serde.deserialize(decryptedOutput);
1621
+ vm.setProp(vm.global, '__tmp_buf', valueHandle);
1622
+ valueHandle.dispose();
1623
+ vm.evalCode(`globalThis.__terminalBuffer[${cidJs}] = { kind: "resolve_value", value: globalThis.__tmp_buf };` +
1346
1624
  `delete globalThis.__tmp_buf;`).dispose();
1347
1625
  }
1348
1626
  else {
@@ -1365,12 +1643,11 @@ async function processEvents(vm, events, advanceClock, encryptionKey) {
1365
1643
  // (TypeError, FatalError with original cause chain, etc.) with
1366
1644
  // the original message and stack preserved.
1367
1645
  const decrypted = await prepareBytesForVM(errorData, encryptionKey);
1368
- const bytesHandle = vm.newUint8Array(decrypted);
1369
- vm.setProp(vm.global, '__tmp_error', bytesHandle);
1370
- bytesHandle.dispose();
1646
+ const errorHandle = serde.deserialize(decrypted);
1647
+ vm.setProp(vm.global, '__tmp_error', errorHandle);
1648
+ errorHandle.dispose();
1371
1649
  vm.evalCode(`(function(){` +
1372
- `var e=globalThis[Symbol.for("workflow-deserialize")](globalThis.__tmp_error);` +
1373
- `globalThis.__resolvers[${cidJs}].reject(e);` +
1650
+ `globalThis.__resolvers[${cidJs}].reject(globalThis.__tmp_error);` +
1374
1651
  `delete globalThis.__resolvers[${cidJs}];` +
1375
1652
  `delete globalThis.__tmp_error;` +
1376
1653
  `})()`).dispose();
@@ -1411,10 +1688,12 @@ async function processEvents(vm, events, advanceClock, encryptionKey) {
1411
1688
  const errorData = eventData?.error;
1412
1689
  if (errorData instanceof Uint8Array) {
1413
1690
  const decrypted = await prepareBytesForVM(errorData, encryptionKey);
1414
- const bytesHandle = vm.newUint8Array(decrypted);
1415
- vm.setProp(vm.global, '__tmp_buf', bytesHandle);
1416
- bytesHandle.dispose();
1417
- vm.evalCode(`globalThis.__terminalBuffer[${cidJs}] = { kind: "reject_bytes", bytes: globalThis.__tmp_buf };` +
1691
+ // Host serde: deserialize into the VM error value NOW (same
1692
+ // path as the resolver branch above) and buffer it.
1693
+ const errorHandle = serde.deserialize(decrypted);
1694
+ vm.setProp(vm.global, '__tmp_buf', errorHandle);
1695
+ errorHandle.dispose();
1696
+ vm.evalCode(`globalThis.__terminalBuffer[${cidJs}] = { kind: "reject_value", value: globalThis.__tmp_buf };` +
1418
1697
  `delete globalThis.__tmp_buf;`).dispose();
1419
1698
  }
1420
1699
  else {
@@ -1534,11 +1813,11 @@ async function processEvents(vm, events, advanceClock, encryptionKey) {
1534
1813
  const rawAbortPayload = eventData?.payload;
1535
1814
  if (rawAbortPayload instanceof Uint8Array) {
1536
1815
  const decrypted = await prepareBytesForVM(rawAbortPayload, encryptionKey);
1537
- const bytesHandle = vm.newUint8Array(decrypted);
1538
- vm.setProp(vm.global, '__tmp_abort', bytesHandle);
1539
- bytesHandle.dispose();
1816
+ const payloadHandle = serde.deserialize(decrypted);
1817
+ vm.setProp(vm.global, '__tmp_abort', payloadHandle);
1818
+ payloadHandle.dispose();
1540
1819
  vm.evalCode(`(function(){` +
1541
- `var p=globalThis[Symbol.for("workflow-deserialize")](globalThis.__tmp_abort);` +
1820
+ `var p=globalThis.__tmp_abort;` +
1542
1821
  `delete globalThis.__tmp_abort;` +
1543
1822
  `globalThis.__abortSignals[${cidJs}]._setAborted(p&&typeof p==="object"?p.reason:undefined);` +
1544
1823
  `})()`).dispose();
@@ -1584,10 +1863,10 @@ async function processEvents(vm, events, advanceClock, encryptionKey) {
1584
1863
  if (rawPayload instanceof Uint8Array) {
1585
1864
  // Decrypt if encrypted — the VM only understands 'devl' format
1586
1865
  const decryptedPayload = await prepareBytesForVM(rawPayload, encryptionKey);
1587
- const bytesHandle = vm.newUint8Array(decryptedPayload);
1588
- vm.setProp(vm.global, '__tmp_result', bytesHandle);
1589
- bytesHandle.dispose();
1590
- vm.evalCode(`globalThis.__resolvers[${cidJs}].resolve(globalThis[Symbol.for("workflow-deserialize")](globalThis.__tmp_result));` +
1866
+ const payloadHandle = serde.deserialize(decryptedPayload);
1867
+ vm.setProp(vm.global, '__tmp_result', payloadHandle);
1868
+ payloadHandle.dispose();
1869
+ vm.evalCode(`globalThis.__resolvers[${cidJs}].resolve(globalThis.__tmp_result);` +
1591
1870
  `delete globalThis.__resolvers[${cidJs}];` +
1592
1871
  `delete globalThis.__tmp_result;`).dispose();
1593
1872
  }
@@ -1626,13 +1905,13 @@ async function processEvents(vm, events, advanceClock, encryptionKey) {
1626
1905
  if (rawPayload instanceof Uint8Array) {
1627
1906
  // Decrypt if encrypted — the VM only understands 'devl' format
1628
1907
  const decryptedPayload = await prepareBytesForVM(rawPayload, encryptionKey);
1629
- const bytesHandle = vm.newUint8Array(decryptedPayload);
1630
- vm.setProp(vm.global, '__tmp_result', bytesHandle);
1631
- bytesHandle.dispose();
1908
+ const payloadHandle = serde.deserialize(decryptedPayload);
1909
+ vm.setProp(vm.global, '__tmp_result', payloadHandle);
1910
+ payloadHandle.dispose();
1632
1911
  // NOTE: replacement is a function so `$`-sequences in the
1633
1912
  // substituted JS never get interpreted as String.replace
1634
1913
  // special replacement patterns.
1635
- vm.evalCode(bufferAndTrack.replace('%PAYLOAD%', () => 'globalThis[Symbol.for("workflow-deserialize")](globalThis.__tmp_result)') + 'delete globalThis.__tmp_result;').dispose();
1914
+ vm.evalCode(bufferAndTrack.replace('%PAYLOAD%', () => 'globalThis.__tmp_result') + 'delete globalThis.__tmp_result;').dispose();
1636
1915
  }
1637
1916
  else {
1638
1917
  const serialized = rawPayload !== undefined
@@ -1769,10 +2048,124 @@ function markCreated(vm, cidJs, opType) {
1769
2048
  * attributes/hooks/steps/waits) and pending abort recordings are surfaced
1770
2049
  * for the entrypoint to flush.
1771
2050
  */
1772
- function collectDrainOperations(vm) {
1773
- const env_3 = { stack: [], error: void 0, hasError: false };
2051
+ /**
2052
+ * Per-VM cache of serialized pending-op field bytes, keyed
2053
+ * `correlationId:field`. A step's raw input is immutable once pushed, so
2054
+ * its bytes are computed once even though the op is re-collected on every
2055
+ * suspension it stays pending through.
2056
+ */
2057
+ const pendingByteCache = new WeakMap();
2058
+ function ensurePendingByteCache(vm) {
2059
+ let cache = pendingByteCache.get(vm);
2060
+ if (!cache) {
2061
+ cache = new Map();
2062
+ pendingByteCache.set(vm, cache);
2063
+ }
2064
+ return cache;
2065
+ }
2066
+ /**
2067
+ * The pending-op fields that hold RAW guest values (the bootstrap no longer
2068
+ * serializes them in the VM). Collection projects them out of the dumped
2069
+ * plain metadata and serializes each through a handle with the host serde.
2070
+ */
2071
+ const RAW_PENDING_FIELDS = ['input', 'metadata', 'abortPayload'];
2072
+ /**
2073
+ * Dump a filtered view of `globalThis.__pending` to host PendingOperation
2074
+ * objects, serializing the raw-value fields host-side. `filterExpr` is a
2075
+ * guest expression that evaluates to the array of ops to collect.
2076
+ */
2077
+ function dumpPendingOps(vm, serde, filterExpr, byteCache) {
2078
+ const env_5 = { stack: [], error: void 0, hasError: false };
1774
2079
  try {
1775
- const h = __addDisposableResource(env_3, vm.evalCode(`(function(){
2080
+ const projected = __addDisposableResource(env_5, vm.evalCode(`(function(){
2081
+ var ops = ${filterExpr};
2082
+ globalThis.__rawFields = [];
2083
+ // Settled ops — created, resolver-less, no abort in flight — are
2084
+ // never collected again by either the suspension or the drain
2085
+ // filter, so their cached bytes are dead weight; surface their cids
2086
+ // so the host can evict them (see the byte-cache eviction below).
2087
+ var settled = [];
2088
+ globalThis.__pending.forEach(function(p){
2089
+ if (p.hasCreatedEvent && !globalThis.__resolvers[p.correlationId] && !p.abortRequested) {
2090
+ settled.push(p.correlationId);
2091
+ }
2092
+ });
2093
+ return { settled: settled, ops: ops.map(function(p){
2094
+ var q = {};
2095
+ for (var k in p) {
2096
+ if (k === 'input' || k === 'metadata' || k === 'abortPayload') continue;
2097
+ q[k] = p[k];
2098
+ }
2099
+ var raw = {};
2100
+ ['input', 'metadata', 'abortPayload'].forEach(function(f){
2101
+ if (p[f] !== undefined) {
2102
+ raw[f] = globalThis.__rawFields.length;
2103
+ globalThis.__rawFields.push(p[f]);
2104
+ }
2105
+ });
2106
+ q.__rawIndices = raw;
2107
+ return q;
2108
+ }) };
2109
+ })()`), false);
2110
+ const dumped = vm.dump(projected);
2111
+ const plainOps = dumped.ops;
2112
+ // Byte-cache eviction: entries for settled ops can never be read again
2113
+ // (neither collection filter matches a settled op), so dropping them
2114
+ // bounds the cache by the LIVE pending set instead of growing
2115
+ // monotonically for the VM's lifetime — which matters for the inline
2116
+ // loop's long-lived sessions and snapshot-restored VMs.
2117
+ if (byteCache && dumped.settled.length > 0) {
2118
+ for (const cid of dumped.settled) {
2119
+ for (const field of RAW_PENDING_FIELDS) {
2120
+ byteCache.delete(`${cid}:${field}`);
2121
+ }
2122
+ }
2123
+ }
2124
+ const rawFields = __addDisposableResource(env_5, vm.evalCode('globalThis.__rawFields'), false);
2125
+ for (const op of plainOps) {
2126
+ const rawIndices = op.__rawIndices ?? {};
2127
+ delete op.__rawIndices;
2128
+ for (const field of RAW_PENDING_FIELDS) {
2129
+ const index = rawIndices[field];
2130
+ if (index === undefined)
2131
+ continue;
2132
+ const cacheKey = `${op.correlationId}:${field}`;
2133
+ let bytes = byteCache?.get(cacheKey);
2134
+ if (!bytes) {
2135
+ const env_6 = { stack: [], error: void 0, hasError: false };
2136
+ try {
2137
+ const valueHandle = __addDisposableResource(env_6, rawFields.getProp(String(index)), false);
2138
+ bytes = serde.serialize(valueHandle);
2139
+ byteCache?.set(cacheKey, bytes);
2140
+ }
2141
+ catch (e_5) {
2142
+ env_6.error = e_5;
2143
+ env_6.hasError = true;
2144
+ }
2145
+ finally {
2146
+ __disposeResources(env_6);
2147
+ }
2148
+ }
2149
+ op[field] = bytes;
2150
+ }
2151
+ }
2152
+ vm.evalCode('delete globalThis.__rawFields').dispose();
2153
+ return plainOps;
2154
+ }
2155
+ catch (e_6) {
2156
+ env_5.error = e_6;
2157
+ env_5.hasError = true;
2158
+ }
2159
+ finally {
2160
+ __disposeResources(env_5);
2161
+ }
2162
+ }
2163
+ function collectDrainOperations(vm, serde) {
2164
+ // Share the per-VM byte cache with the suspension path: an op that was
2165
+ // serialized during a suspension pass must reuse those exact bytes at
2166
+ // terminal drain — re-serializing can invoke getters again and produce
2167
+ // a DIFFERENT byte sequence for what the event log treats as one value.
2168
+ return dumpPendingOps(vm, serde, `(function(){
1776
2169
  var toDispose = [];
1777
2170
  globalThis.__pending.forEach(function(p){
1778
2171
  if (p.type === "hook" && p.isSystem && !p.abortRequested && !p.disposed) {
@@ -1796,64 +2189,111 @@ function collectDrainOperations(vm) {
1796
2189
  if (p.type === "hook" && p.disposed) return false;
1797
2190
  return true;
1798
2191
  });
1799
- })()`), false);
1800
- return vm.dump(h);
1801
- }
1802
- catch (e_3) {
1803
- env_3.error = e_3;
1804
- env_3.hasError = true;
1805
- }
1806
- finally {
1807
- __disposeResources(env_3);
1808
- }
2192
+ })()`, ensurePendingByteCache(vm));
1809
2193
  }
1810
- function checkWorkflowState(vm, opts = {}) {
1811
- // Check completed — __workflowResult is a format-prefixed Uint8Array
2194
+ function checkWorkflowState(vm, serde, opts = {}) {
2195
+ // Check completed — __workflowResult holds the RAW return value (with a
2196
+ // separate done flag so `undefined` results are distinguishable); the
2197
+ // host serializes it through a handle.
1812
2198
  {
1813
- const env_4 = { stack: [], error: void 0, hasError: false };
2199
+ const env_7 = { stack: [], error: void 0, hasError: false };
1814
2200
  try {
1815
- const h = __addDisposableResource(env_4, vm.evalCode('globalThis.__workflowResult'), false);
1816
- if (!h.isUndefined) {
1817
- const resultBytes = h.toUint8Array();
1818
- const drainOperations = collectDrainOperations(vm);
1819
- vm.dispose();
1820
- return {
1821
- completed: {
1822
- result: resultBytes,
1823
- ...(drainOperations.length > 0 ? { drainOperations } : {}),
1824
- },
1825
- };
2201
+ const done = __addDisposableResource(env_7, vm.evalCode('globalThis.__workflowDone === true'), false);
2202
+ if (done.toBoolean()) {
2203
+ const env_8 = { stack: [], error: void 0, hasError: false };
2204
+ try {
2205
+ const h = __addDisposableResource(env_8, vm.evalCode('globalThis.__workflowResult'), false);
2206
+ const resultBytes = serde.serialize(h);
2207
+ const drainOperations = collectDrainOperations(vm, serde);
2208
+ vm.dispose();
2209
+ return {
2210
+ completed: {
2211
+ result: resultBytes,
2212
+ ...(drainOperations.length > 0 ? { drainOperations } : {}),
2213
+ },
2214
+ };
2215
+ }
2216
+ catch (e_7) {
2217
+ env_8.error = e_7;
2218
+ env_8.hasError = true;
2219
+ }
2220
+ finally {
2221
+ __disposeResources(env_8);
2222
+ }
1826
2223
  }
1827
2224
  }
1828
- catch (e_4) {
1829
- env_4.error = e_4;
1830
- env_4.hasError = true;
2225
+ catch (e_8) {
2226
+ env_7.error = e_8;
2227
+ env_7.hasError = true;
1831
2228
  }
1832
2229
  finally {
1833
- __disposeResources(env_4);
2230
+ __disposeResources(env_7);
1834
2231
  }
1835
2232
  }
1836
2233
  // Check failed
1837
2234
  {
1838
- const env_5 = { stack: [], error: void 0, hasError: false };
2235
+ const env_9 = { stack: [], error: void 0, hasError: false };
1839
2236
  try {
1840
- const h = __addDisposableResource(env_5, vm.evalCode('globalThis.__workflowError'), false);
2237
+ const h = __addDisposableResource(env_9, vm.evalCode('globalThis.__workflowError'), false);
1841
2238
  if (!h.isUndefined) {
1842
- const errorObj = vm.dump(h);
2239
+ // The display fields are plain strings; the thrown value itself is
2240
+ // RAW and serialized host-side through a handle.
2241
+ const errorObj = h.isString
2242
+ ? h.toString()
2243
+ : (() => {
2244
+ const env_12 = { stack: [], error: void 0, hasError: false };
2245
+ try {
2246
+ const plain = __addDisposableResource(env_12, vm.evalCode('(function(e){return {message: e.message, stack: e.stack, name: e.name};})(globalThis.__workflowError)'), false);
2247
+ return vm.dump(plain);
2248
+ }
2249
+ catch (e_12) {
2250
+ env_12.error = e_12;
2251
+ env_12.hasError = true;
2252
+ }
2253
+ finally {
2254
+ __disposeResources(env_12);
2255
+ }
2256
+ })();
2257
+ let valueBytes;
2258
+ if (!h.isString) {
2259
+ const env_10 = { stack: [], error: void 0, hasError: false };
2260
+ try {
2261
+ const rawValue = __addDisposableResource(env_10, h.getProp('value'), false);
2262
+ try {
2263
+ valueBytes = serde.serialize(rawValue);
2264
+ }
2265
+ catch (serializeErr) {
2266
+ // A thrown value the codec cannot serialize must not mask the
2267
+ // workflow failure itself — fall back to the display fields.
2268
+ runtimeLogger.warn('QuickJS runtime: failed to serialize thrown workflow error', {
2269
+ message: serializeErr instanceof Error
2270
+ ? serializeErr.message
2271
+ : String(serializeErr),
2272
+ });
2273
+ }
2274
+ }
2275
+ catch (e_9) {
2276
+ env_10.error = e_9;
2277
+ env_10.hasError = true;
2278
+ }
2279
+ finally {
2280
+ __disposeResources(env_10);
2281
+ }
2282
+ }
1843
2283
  const failed = typeof errorObj === 'string'
1844
2284
  ? { message: errorObj }
1845
2285
  : {
1846
2286
  message: errorObj.message,
1847
2287
  stack: errorObj.stack || undefined,
1848
2288
  name: errorObj.name || undefined,
1849
- valueBytes: errorObj.valueBytes,
2289
+ valueBytes,
1850
2290
  };
1851
2291
  runtimeLogger.error('QuickJS runtime: workflow failed in VM', {
1852
2292
  errorMessage: failed.message,
1853
2293
  errorName: failed.name,
1854
2294
  errorStack: failed.stack,
1855
2295
  });
1856
- const drainOperations = collectDrainOperations(vm);
2296
+ const drainOperations = collectDrainOperations(vm, serde);
1857
2297
  vm.dispose();
1858
2298
  return {
1859
2299
  failed: {
@@ -1863,53 +2303,41 @@ function checkWorkflowState(vm, opts = {}) {
1863
2303
  };
1864
2304
  }
1865
2305
  }
1866
- catch (e_5) {
1867
- env_5.error = e_5;
1868
- env_5.hasError = true;
2306
+ catch (e_10) {
2307
+ env_9.error = e_10;
2308
+ env_9.hasError = true;
1869
2309
  }
1870
2310
  finally {
1871
- __disposeResources(env_5);
2311
+ __disposeResources(env_9);
1872
2312
  }
1873
2313
  }
1874
2314
  // Check suspended — the workflow is suspended if there are active resolvers
1875
2315
  // OR pending operations that haven't been created yet (e.g. hooks created
1876
2316
  // upfront but not yet awaited)
1877
2317
  {
1878
- const env_6 = { stack: [], error: void 0, hasError: false };
2318
+ const env_11 = { stack: [], error: void 0, hasError: false };
1879
2319
  try {
1880
- const h = __addDisposableResource(env_6, vm.evalCode('Object.keys(globalThis.__resolvers).length > 0 || globalThis.__pending.some(function(p){return!p.hasCreatedEvent;})'), false);
2320
+ const h = __addDisposableResource(env_11, vm.evalCode('Object.keys(globalThis.__resolvers).length > 0 || globalThis.__pending.some(function(p){return!p.hasCreatedEvent;})'), false);
1881
2321
  if (vm.dump(h)) {
1882
- const env_7 = { stack: [], error: void 0, hasError: false };
1883
- try {
1884
- const pendingH = __addDisposableResource(env_7, vm.evalCode(
1885
- // Ops with an active resolver or without a created event are
1886
- // pending; abort-requested hooks are also surfaced (even when
1887
- // already created and unawaited) so the host records the abort.
1888
- `globalThis.__pending.filter(function(p){return!!globalThis.__resolvers[p.correlationId] || !p.hasCreatedEvent || p.abortRequested;})`), false);
1889
- const pendingOps = vm.dump(pendingH);
1890
- if (!opts.keepAliveOnSuspend)
1891
- vm.dispose();
1892
- return {
1893
- suspended: {
1894
- pendingOperations: pendingOps,
1895
- },
1896
- };
1897
- }
1898
- catch (e_6) {
1899
- env_7.error = e_6;
1900
- env_7.hasError = true;
1901
- }
1902
- finally {
1903
- __disposeResources(env_7);
1904
- }
2322
+ // Ops with an active resolver or without a created event are
2323
+ // pending; abort-requested hooks are also surfaced (even when
2324
+ // already created and unawaited) so the host records the abort.
2325
+ const pendingOps = dumpPendingOps(vm, serde, `globalThis.__pending.filter(function(p){return!!globalThis.__resolvers[p.correlationId] || !p.hasCreatedEvent || p.abortRequested;})`, ensurePendingByteCache(vm));
2326
+ if (!opts.keepAliveOnSuspend)
2327
+ vm.dispose();
2328
+ return {
2329
+ suspended: {
2330
+ pendingOperations: pendingOps,
2331
+ },
2332
+ };
1905
2333
  }
1906
2334
  }
1907
- catch (e_7) {
1908
- env_6.error = e_7;
1909
- env_6.hasError = true;
2335
+ catch (e_11) {
2336
+ env_11.error = e_11;
2337
+ env_11.hasError = true;
1910
2338
  }
1911
2339
  finally {
1912
- __disposeResources(env_6);
2340
+ __disposeResources(env_11);
1913
2341
  }
1914
2342
  }
1915
2343
  vm.dispose();
@@ -1941,4 +2369,4 @@ function createInterruptHandler(budget) {
1941
2369
  const timeout = getReplayTimeoutMs();
1942
2370
  return () => Date.now() - budget.start > timeout;
1943
2371
  }
1944
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVpY2tqcy1ydW50aW1lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvcXVpY2tqcy1ydW50aW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyQkc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBUUgsT0FBTyxLQUFLLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDakMsT0FBTyxFQUVMLFdBQVcsRUFDWCxPQUFPLEdBRVIsTUFBTSxjQUFjLENBQUM7QUFDdEIsT0FBTyxVQUFVLE1BQU0sWUFBWSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRTdELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN6RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDL0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUVqRSwyQ0FBMkM7QUFFM0M7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxLQUFLLFVBQVUsaUJBQWlCLENBQzlCLElBQWdCLEVBQ2hCLEdBQW1CO0lBRW5CLE9BQU8sQ0FBQyxNQUFNLFVBQVUsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBZSxDQUFDO0FBQ3BFLENBQUM7QUF3SkQsOEJBQThCO0FBRTlCOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxZQUFZLEdBQUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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LEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNiLE9BQU87UUFDTCxNQUFNLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRTtLQUNqQyxDQUFDO0FBQ0osQ0FBQztBQXFCRCxTQUFTLHNCQUFzQixDQUFDLE1BQXVCO0lBQ3JELE1BQU0sT0FBTyxHQUFHLGtCQUFrQixFQUFFLENBQUM7SUFDckMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUM7QUFDbkQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUXVpY2tKUyBXQVNNIHdvcmtmbG93IFZNLlxuICpcbiAqIEFuIGFsdGVybmF0aXZlIGVuZ2luZSBmb3IgdGhlIGV2ZW50LXJlcGxheSBleGVjdXRpb24gbW9kZWw6IHRoZSB3b3JrZmxvd1xuICogY29kZSBydW5zIGluc2lkZSBhIFF1aWNrSlMgV0FTTSBWTSAodmlhIHF1aWNranMtd2FzaSkgaW5zdGVhZCBvZiBhXG4gKiBgbm9kZTp2bWAgY29udGV4dC4gRXZlcnkgaW52b2NhdGlvbiBjcmVhdGVzIGEgZnJlc2ggVk0sIHJlLWV4ZWN1dGVzIHRoZVxuICogd29ya2Zsb3cgZnVuY3Rpb24gZnJvbSB0aGUgdG9wLCBhbmQgcmVwbGF5cyB0aGUgcmVjb3JkZWQgZXZlbnQgbG9nIHRvXG4gKiByZXNvbHZlIGF3YWl0ZWQgcHJpbWl0aXZlcyDigJQgdGhlIHNhbWUgcmVwbGF5IHNlbWFudGljcyBhcyB0aGUgYG5vZGU6dm1gXG4gKiBlbmdpbmUuXG4gKlxuICogVGhlIHdvcmtmbG93IHByaW1pdGl2ZXMgKHVzZVN0ZXAsIHNsZWVwLCBjcmVhdGVIb29rKSBhcmUgaW1wbGVtZW50ZWQgYXNcbiAqIEphdmFTY3JpcHQgY29kZSBydW5uaW5nIGluc2lkZSB0aGUgUXVpY2tKUyBWTS4gVGhlIGhvc3QgY29tbXVuaWNhdGVzIHdpdGhcbiAqIHRoZSBWTSBieSBldmFsdWF0aW5nIHNtYWxsIEpTIHNuaXBwZXRzIHRvIHJlYWQgcGVuZGluZyBvcGVyYXRpb25zIGFuZFxuICogcmVzb2x2ZS9yZWplY3QgcHJvbWlzZXMuXG4gKlxuICogVGhlIFZNIGJvb3RzdHJhcCBpcyBkZWxpYmVyYXRlbHkgc3BsaXQgaW50byB0d28gcGhhc2VzOlxuICogICAxLiBTdGF0aWMgaW5pdGlhbGl6YXRpb24gKGBpbml0V29ya2Zsb3dWTWApIOKAlCBydW4taW5kZXBlbmRlbnQgc2V0dXA6XG4gKiAgICAgIFZNIGNyZWF0aW9uLCB0aGUgc2VyZGUgYnVuZGxlLCBhbmQgdGhlIHdvcmtmbG93IHByaW1pdGl2ZXMuXG4gKiAgIDIuIFBlci1ydW4gaW5pdGlhbGl6YXRpb24gKGlubGluZSBpbiBgcnVuUXVpY2tKU1dvcmtmbG93YCkg4oCUIHNlZWRlZFxuICogICAgICBQUk5HL1VMSUQgaG9zdCBmdW5jdGlvbnMsIHdvcmtmbG93IGJ1bmRsZSBldmFsdWF0aW9uLCBydW4gbWV0YWRhdGEsXG4gKiAgICAgIHdvcmtmbG93IGlucHV0LCBhbmQgc3RhcnQuXG4gKiBLZWVwaW5nIHRoZSBwaGFzZXMgc2VwYXJhdGUgaXMgZ3JvdW5kd29yayBmb3IgVk0tbWVtb3J5IHNuYXBzaG90dGluZzpcbiAqIGEgZm9sbG93LXVwIGNhbiBwZXJzaXN0L3Jlc3RvcmUgdGhlIFZNIGF0IHRoZSBwaGFzZSBib3VuZGFyeSAoZS5nLiBhXG4gKiBidWlsZC10aW1lIGluaXRpYWwgc25hcHNob3QpIHdpdGhvdXQgcmVzdHJ1Y3R1cmluZyB0aGlzIG1vZHVsZS4gTm90ZVxuICogdGhhdCBidW5kbGUgZXZhbHVhdGlvbiBjdXJyZW50bHkgc2l0cyBpbiB0aGUgcGVyLXJ1biBwaGFzZSBzbyB0aGF0XG4gKiBtb2R1bGUtc2NvcGUgdXNlciBjb2RlIG9ic2VydmVzIHRoZSBzZWVkZWQgYE1hdGgucmFuZG9tYCwgbWF0Y2hpbmcgdGhlXG4gKiBgbm9kZTp2bWAgZW5naW5lJ3MgcmVwbGF5IGRldGVybWluaXNtLlxuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgRXZlbnQsXG4gIFJ1bklucHV0LFxuICBXb3JrZmxvd1J1bixcbiAgV29ybGRDYXBhYmlsaXRpZXMsXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgKiBhcyBuYW5vaWQgZnJvbSAnbmFub2lkJztcbmltcG9ydCB7XG4gIHR5cGUgRXh0ZW5zaW9uRGVzY3JpcHRvcixcbiAgSlNFeGNlcHRpb24sXG4gIFF1aWNrSlMsXG4gIHR5cGUgV2FzaU9wdGlvbnMsXG59IGZyb20gJ3F1aWNranMtd2FzaSc7XG5pbXBvcnQgc2VlZHJhbmRvbSBmcm9tICdzZWVkcmFuZG9tJztcbmltcG9ydCB7IHJ1bnRpbWVMb2dnZXIgfSBmcm9tICcuLi9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZGVjb21wcmVzcyB9IGZyb20gJy4uL3NlcmlhbGl6YXRpb24vY29tcHJlc3Npb24uanMnO1xuaW1wb3J0IHR5cGUgeyBEZWNyeXB0aW9uS2V5IH0gZnJvbSAnLi4vc2VyaWFsaXphdGlvbi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB7IGRlY3J5cHQgfSBmcm9tICcuLi9zZXJpYWxpemF0aW9uL2VuY3J5cHRpb24uanMnO1xuaW1wb3J0IHsgZ2V0UmVwbGF5VGltZW91dE1zIH0gZnJvbSAnLi9jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgcXVpY2tqc0V4dGVuc2lvbnMsIHF1aWNranNXYXNtIH0gZnJvbSAnLi9xdWlja2pzLWFzc2V0cy5nZW5lcmF0ZWQuanMnO1xuaW1wb3J0IHsgcnVuSWRDcmVhdGVkQXQgfSBmcm9tICcuL3J1bi1pZC10aW1lLmpzJztcbmltcG9ydCB7IFZNX1NFUkRFX0JVTkRMRSB9IGZyb20gJy4vdm0tc2VyZGUtYnVuZGxlLmdlbmVyYXRlZC5qcyc7XG5cbi8vIC0tLS0gSG9zdCAtPiBWTSBwYXlsb2FkIHByZXBhcmF0aW9uIC0tLS1cblxuLyoqXG4gKiBQcmVwYXJlIHBlcnNpc3RlZCBwYXlsb2FkIGJ5dGVzIGZvciBjb25zdW1wdGlvbiBpbnNpZGUgdGhlIFZNOiBkZWNyeXB0XG4gKiAod2hlbiBhbiBlbmNyeXB0aW9uIGtleSBpcyBjb25maWd1cmVkKSBhbmQgZGVjb21wcmVzcyAoc3BlY1ZlcnNpb24gPj0gNVxuICogcGF5bG9hZHMgbWF5IGJlIGd6aXAvenN0ZC1jb21wcmVzc2VkKS4gVGhlIFZNIG9ubHkgdW5kZXJzdGFuZHMgcGxhaW5cbiAqIGZvcm1hdC1wcmVmaXhlZCAnZGV2bCcgYnl0ZXMg4oCUIGl0IGhhcyBuZWl0aGVyIHRoZSBrZXkgbWF0ZXJpYWwgbm9yIHpsaWIuXG4gKiBUaGUga2V5IGlzIHRoZSBydW4ncyBmdWxsIERlY3J5cHRpb25LZXkgY2FwYWJpbGl0eSAoc3ltbWV0cmljIEFFUyBrZXkgK1xuICogWDI1NTE5IGtleXBhaXIpIHNvIHNlYWxlZCBgZW5jcGAgaG9vayBwYXlsb2FkcyBmcm9tIGNyb3NzLWRlcGxveW1lbnRcbiAqIHJlc3VtZUhvb2soKSBjYWxscyBvcGVuIGhlcmUgdG9vLCBub3QganVzdCBzeW1tZXRyaWMgYGVuY3JgIG9uZXMuXG4gKiBCb3RoIHN0YWdlcyBhcmUgZm9ybWF0LXByZWZpeCBkaXNwYXRjaGVkLCBzbyBwbGFpbnRleHQvdW5jb21wcmVzc2VkXG4gKiBkYXRhIHBhc3NlcyB0aHJvdWdoIHVuY2hhbmdlZC4gTWlycm9ycyBgcHJlcGFyZVJlcGxheVBheWxvYWRgIGluXG4gKiBzZXJpYWxpemF0aW9uLnRzICh0aGUgbm9kZTp2bSBlbmdpbmUncyBlcXVpdmFsZW50IGhvc3Qtc2lkZSBzdGFnZSkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHByZXBhcmVCeXRlc0ZvclZNKFxuICBkYXRhOiBVaW50OEFycmF5LFxuICBrZXk/OiBEZWNyeXB0aW9uS2V5XG4pOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgcmV0dXJuIChhd2FpdCBkZWNvbXByZXNzKGF3YWl0IGRlY3J5cHQoZGF0YSwga2V5KSkpIGFzIFVpbnQ4QXJyYXk7XG59XG5cbi8vIC0tLS0gVHlwZXMgLS0tLVxuXG5leHBvcnQgaW50ZXJmYWNlIFBlbmRpbmdTdGVwIHtcbiAgdHlwZTogJ3N0ZXAnO1xuICBjb3JyZWxhdGlvbklkOiBzdHJpbmc7XG4gIHN0ZXBJZDogc3RyaW5nO1xuICAvKiogRm9ybWF0LXByZWZpeGVkIGRldmFsdWUtc2VyaWFsaXplZCBzdGVwIGlucHV0IChhcmdzICsgY2xvc3VyZVZhcnMpICovXG4gIGlucHV0OiBVaW50OEFycmF5O1xuICAvKiogV2hldGhlciBhIHN0ZXBfY3JlYXRlZCBldmVudCBhbHJlYWR5IGV4aXN0cyBmb3IgdGhpcyBzdGVwICovXG4gIGhhc0NyZWF0ZWRFdmVudDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZW5kaW5nV2FpdCB7XG4gIHR5cGU6ICd3YWl0JztcbiAgY29ycmVsYXRpb25JZDogc3RyaW5nO1xuICAvKiogSVNPIHN0cmluZyBvZiB3aGVuIHRvIHJlc3VtZSAqL1xuICByZXN1bWVBdDogc3RyaW5nO1xuICAvKiogV2hldGhlciBhIHdhaXRfY3JlYXRlZCBldmVudCBhbHJlYWR5IGV4aXN0cyBmb3IgdGhpcyB3YWl0ICovXG4gIGhhc0NyZWF0ZWRFdmVudDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZW5kaW5nSG9vayB7XG4gIHR5cGU6ICdob29rJztcbiAgY29ycmVsYXRpb25JZDogc3RyaW5nO1xuICB0b2tlbjogc3RyaW5nO1xuICAvKiogRWFybGllc3QgdG9rZW4gcmV1c2UgdGltZSwgYXMgbWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBVbml4IGVwb2NoLiAqL1xuICB0b2tlblJldGVudGlvblVudGlsPzogbnVtYmVyO1xuICBpc1dlYmhvb2s6IGJvb2xlYW47XG4gIG1ldGFkYXRhPzogdW5rbm93bjtcbiAgaGFzQ3JlYXRlZEV2ZW50OiBib29sZWFuO1xuICAvKipcbiAgICogVHJ1ZSBmb3IgaW50ZXJuYWwgc3lzdGVtIGhvb2tzIChlLmcuIEFib3J0Q29udHJvbGxlcidzIGhvb2spLCB3aGljaFxuICAgKiBhcmUgZXhlbXB0IGZyb20gdXNlci1ob29rIHRva2VuIG5hbWVzcGFjZSBjb25mbGljdCBjaGVja3MuXG4gICAqL1xuICBpc1N5c3RlbT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBTZXQgd2hlbiB0aGUgd29ya2Zsb3cgY2FsbGVkIEFib3J0Q29udHJvbGxlci5hYm9ydCgpIGR1cmluZyB0aGlzXG4gICAqIGludm9jYXRpb24uIFRoZSBob3N0IG11c3QgcmVjb3JkIHRoZSBhYm9ydDogY3JlYXRlIGEgaG9va19yZWNlaXZlZFxuICAgKiBldmVudCBjYXJyeWluZyBgYWJvcnRQYXlsb2FkYCBhbmQgd3JpdGUvY2xvc2UgdGhlIGFib3J0IHN0cmVhbS5cbiAgICovXG4gIGFib3J0UmVxdWVzdGVkPzogYm9vbGVhbjtcbiAgLyoqIFZNLXNlcmlhbGl6ZWQgYHsgYWJvcnRlZDogdHJ1ZSwgcmVhc29uIH1gIHBheWxvYWQgZm9yIHRoZSBhYm9ydC4gKi9cbiAgYWJvcnRQYXlsb2FkPzogVWludDhBcnJheTtcbiAgLyoqIFNldCBieSB0aGUgY29tcGxldGlvbiBkcmFpbiB3aGVuIGEgc3lzdGVtIGhvb2sgaXMgaW1wbGljaXRseSBkaXNwb3NlZC4gKi9cbiAgZGlzcG9zZWQ/OiBib29sZWFuO1xuICAvKipcbiAgICogVHJ1ZSB3aGVuIHRoZSB3b3JrZmxvdyBpcyBhd2FpdGluZyBob29rLmdldENvbmZsaWN0KCkgZm9yIHRoaXMgaG9vay5cbiAgICogVGhlIGVudHJ5cG9pbnQgcmUtaW52b2tlcyB0aGUgd29ya2Zsb3cgcmlnaHQgYWZ0ZXIgd3JpdGluZ1xuICAgKiBob29rX2NyZWF0ZWQgc28gcmVwbGF5IGNhbiBjb25maXJtIGNyZWF0aW9uIGFuZCByZXNvbHZlIHRoZSBhd2FpdGVyLlxuICAgKi9cbiAgaGFzR2V0Q29uZmxpY3RBd2FpdGVyPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZW5kaW5nQXR0cmlidXRlIHtcbiAgdHlwZTogJ2F0dHJpYnV0ZSc7XG4gIGNvcnJlbGF0aW9uSWQ6IHN0cmluZztcbiAgLyoqIE5vcm1hbGl6ZWQgYXR0cmlidXRlIGNoYW5nZXMgKHBsYWluIEpTT04tYWJsZSBvYmplY3RzKSAqL1xuICBjaGFuZ2VzOiB1bmtub3duW107XG4gIGFsbG93UmVzZXJ2ZWRBdHRyaWJ1dGVzPzogYm9vbGVhbjtcbiAgLyoqIFdoZXRoZXIgYW4gYXR0cl9zZXQgZXZlbnQgYWxyZWFkeSBleGlzdHMgZm9yIHRoaXMgd3JpdGUgKi9cbiAgaGFzQ3JlYXRlZEV2ZW50OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBlbmRpbmdIb29rRGlzcG9zZSB7XG4gIHR5cGU6ICdob29rX2Rpc3Bvc2UnO1xuICBjb3JyZWxhdGlvbklkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUb2tlbiBvZiB0aGUgaG9vayBiZWluZyBkaXNwb3NlZC4gVXNlZCBieSB0aGUgZW50cnlwb2ludCB0byBvcmRlclxuICAgKiBzYW1lLXRva2VuIGhvb2sgb3BlcmF0aW9ucyBzZXF1ZW50aWFsbHkgaW4gY29kZSBvcmRlci5cbiAgICovXG4gIHRva2VuPzogc3RyaW5nO1xuICBoYXNDcmVhdGVkRXZlbnQ6IGJvb2xlYW47XG59XG5cbmV4cG9ydCB0eXBlIFBlbmRpbmdPcGVyYXRpb24gPVxuICB8IFBlbmRpbmdTdGVwXG4gIHwgUGVuZGluZ1dhaXRcbiAgfCBQZW5kaW5nSG9va1xuICB8IFBlbmRpbmdBdHRyaWJ1dGVcbiAgfCBQZW5kaW5nSG9va0Rpc3Bvc2U7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVpY2tKU1J1bnRpbWVSZXN1bHQge1xuICAvKiogVGhlIHdvcmtmbG93IGNvbXBsZXRlZCDigJQgcmVzdWx0IGlzIGZvcm1hdC1wcmVmaXhlZCBkZXZhbHVlIGJ5dGVzICovXG4gIGNvbXBsZXRlZD86IHtcbiAgICByZXN1bHQ6IFVpbnQ4QXJyYXk7XG4gICAgLyoqXG4gICAgICogTGVmdG92ZXIgcGVuZGluZyBvcGVyYXRpb25zIHRoYXQgc3RpbGwgbmVlZCBkdXJhYmxlIHNpZGUgZWZmZWN0cyBhdFxuICAgICAqIGNvbXBsZXRpb246IGFib3J0IHJlY29yZGluZ3MsIHN5c3RlbS1ob29rIGRpc3Bvc2FscywgZmlyZS1hbmQtZm9yZ2V0XG4gICAgICogYXR0cmlidXRlL2hvb2svc3RlcCBldmVudHMuIE1pcnJvcnMgdGhlIG5vZGU6dm0gZW5naW5lJ3NcbiAgICAgKiBkcmFpblBlbmRpbmdRdWV1ZUl0ZW1zLiBUaGUgZW50cnlwb2ludCBkaXNwYXRjaGVzIHRoZXNlIFdJVEhPVVRcbiAgICAgKiBxdWV1ZWluZyBzdGVwcyBvciByZXF1ZXVpbmcgdGhlIHJ1bi5cbiAgICAgKi9cbiAgICBkcmFpbk9wZXJhdGlvbnM/OiBQZW5kaW5nT3BlcmF0aW9uW107XG4gIH07XG4gIC8qKiBUaGUgd29ya2Zsb3cgc3VzcGVuZGVkIHdpdGggcGVuZGluZyBvcGVyYXRpb25zICovXG4gIHN1c3BlbmRlZD86IHtcbiAgICBwZW5kaW5nT3BlcmF0aW9uczogUGVuZGluZ09wZXJhdGlvbltdO1xuICB9O1xuICAvKiogVGhlIHdvcmtmbG93IGZhaWxlZCAqL1xuICBmYWlsZWQ/OiB7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICAgIHN0YWNrPzogc3RyaW5nO1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgLyoqIFNlZSBjb21wbGV0ZWQuZHJhaW5PcGVyYXRpb25zIOKAlCBzYW1lIHNlbWFudGljcyBvbiBmYWlsdXJlLiAqL1xuICAgIGRyYWluT3BlcmF0aW9ucz86IFBlbmRpbmdPcGVyYXRpb25bXTtcbiAgICAvKipcbiAgICAgKiBGb3JtYXQtcHJlZml4ZWQgZGV2YWx1ZSBieXRlcyBvZiB0aGUgb3JpZ2luYWwgdGhyb3duIHZhbHVlXG4gICAgICogKEVycm9yIHN1YmNsYXNzIHdpdGggY2F1c2UgY2hhaW4sIHBsYWluIG9iamVjdCwgcHJpbWl0aXZlLCBldGMuKS5cbiAgICAgKiBTZXQgd2hlbiB0aGUgVk0tc2lkZSByZWplY3Rpb24gaGFuZGxlciBzdWNjZXNzZnVsbHkgc2VyaWFsaXplc1xuICAgICAqIHRoZSB0aHJvd24gdmFsdWUuIFRoZSBob3N0IHVzZXMgdGhlc2UgYnl0ZXMgdG8gcmVjb25zdHJ1Y3QgdGhlXG4gICAgICogb3JpZ2luYWwgdmFsdWUgdGhyb3VnaCB0aGUgc3RhbmRhcmQgZXJyb3IgaHlkcmF0aW9uIHBpcGVsaW5lLFxuICAgICAqIHByZXNlcnZpbmcgdHlwZSBpZGVudGl0eSAoVHlwZUVycm9yLCBGYXRhbEVycm9yKSBhbmQgbm9uLUVycm9yXG4gICAgICogdGhyb3dzIHZlcmJhdGltLiBGYWxscyBiYWNrIHRvIHRoZSBtZXNzYWdlL3N0YWNrL25hbWUgZmllbGRzXG4gICAgICogd2hlbiB0aGlzIGlzIHVuZGVmaW5lZCAoZS5nLiBleHRyYWN0RXJyb3IgcHNldWRvLWZhaWx1cmVzKS5cbiAgICAgKi9cbiAgICB2YWx1ZUJ5dGVzPzogVWludDhBcnJheTtcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBRdWlja0pTUnVudGltZU9wdGlvbnMge1xuICAvKiogVGhlIGNvbXBpbGVkIHdvcmtmbG93IGJ1bmRsZSBjb2RlICh3b3JrZmxvdyBtb2RlIG91dHB1dCBmcm9tIFNXQykgKi9cbiAgd29ya2Zsb3dDb2RlOiBzdHJpbmc7XG4gIC8qKiBUaGUgd29ya2Zsb3cgSUQgKGUuZy4gXCJ3b3JrZmxvdy8vLi93b3JrZmxvd3MvMV9zaW1wbGUvL3NpbXBsZVwiKSAqL1xuICB3b3JrZmxvd0lkOiBzdHJpbmc7XG4gIC8qKiBUaGUgd29ya2Zsb3cgcnVuIGVudGl0eSAqL1xuICB3b3JrZmxvd1J1bjogV29ya2Zsb3dSdW47XG4gIC8qKiBGZWF0dXJlcyBzdXBwb3J0ZWQgYnkgdGhlIFdvcmxkIGV4ZWN1dGluZyB0aGlzIHdvcmtmbG93LiAqL1xuICB3b3JsZENhcGFiaWxpdGllcz86IFdvcmxkQ2FwYWJpbGl0aWVzO1xuICAvKipcbiAgICogVGhlIGZ1bGwgZXZlbnQgbG9nIGZvciB0aGUgcnVuLiBFdmVyeSBpbnZvY2F0aW9uIHJlcGxheXMgdGhlIGNvbXBsZXRlXG4gICAqIGxvZyBmcm9tIHRoZSBzdGFydCAoc2FtZSByZXBsYXkgc2VtYW50aWNzIGFzIHRoZSBgbm9kZTp2bWAgZW5naW5lKS5cbiAgICovXG4gIGV2ZW50czogRXZlbnRbXTtcbiAgLyoqIEVuY3J5cHRpb24ga2V5IGZvciBkZWNyeXB0aW5nIGV2ZW50IHBheWxvYWRzICh1bmRlZmluZWQgaWYgdW5lbmNyeXB0ZWQpICovXG4gIGVuY3J5cHRpb25LZXk/OiBEZWNyeXB0aW9uS2V5O1xuICAvKipcbiAgICogVGhlIGxvY2FsIHBvcnQgdGhlIHdvcmtmbG93IHNlcnZlciBpcyBsaXN0ZW5pbmcgb24sIHVzZWQgdG8gcG9wdWxhdGVcbiAgICogYHdvcmtmbG93TWV0YWRhdGEudXJsYC4gUmVzb2x2ZWQgYXQgY2FsbCB0aW1lIG9uIHRoZSBob3N0IHNpZGUgc28gdGhlXG4gICAqIFZNIGRvZXNuJ3QgaGF2ZSB0byBwcm9iZSB0aGUgZmlsZXN5c3RlbS4gSWdub3JlZCBvbiBWZXJjZWwg4oCUIFZFUkNFTF9VUkxcbiAgICogdGFrZXMgcHJlY2VkZW5jZSB0aGVyZS5cbiAgICovXG4gIHBvcnQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBGYWxsYmFjayB3b3JrZmxvdyBpbnB1dCBmcm9tIHRoZSBxdWV1ZSBtZXNzYWdlJ3MgcmVzaWxpZW50LXN0YXJ0XG4gICAqIHBheWxvYWQuIFVzZWQgd2hlbiB0aGUgZmV0Y2hlZCBldmVudCBsb2cgbGFja3MgYSBgcnVuX2NyZWF0ZWRgIGV2ZW50XG4gICAqIChldmVudHVhbGx5LWNvbnNpc3RlbnQgcmVhZCBhZnRlciB0aGUgcGFyZW50J3Mgc3RhcnQoKSB3cm90ZSBpdCkuXG4gICAqL1xuICBydW5JbnB1dD86IFJ1bklucHV0O1xufVxuXG4vLyAtLS0tIFZNIEJvb3RzdHJhcCBDb2RlIC0tLS1cblxuLyoqXG4gKiBKYXZhU2NyaXB0IGNvZGUgdGhhdCBydW5zIGluc2lkZSB0aGUgUXVpY2tKUyBWTSB0byBzZXQgdXAgdGhlIHdvcmtmbG93XG4gKiBwcmltaXRpdmVzLiBUaGlzIHNldHMgdXA6XG4gKiAtIGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cyAoTWFwKSAtIHdvcmtmbG93IHJlZ2lzdHJ5XG4gKiAtIGdsb2JhbFRoaXMuX19yZXNvbHZlcnMgKE9iamVjdCkgLSBwZW5kaW5nIHByb21pc2UgcmVzb2x2ZS9yZWplY3QgZnVuY3Rpb25zXG4gKiAtIGdsb2JhbFRoaXMuX19wZW5kaW5nIChBcnJheSkgLSBtZXRhZGF0YSBhYm91dCBwZW5kaW5nIG9wZXJhdGlvbnNcbiAqIC0gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildIC0gc3RlcCBwcm94eSBmYWN0b3J5XG4gKiAtIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1NMRUVQXCIpXSAtIHNsZWVwIGZ1bmN0aW9uXG4gKi9cbmNvbnN0IFZNX0JPT1RTVFJBUCA9IGBcbi8vIFN5bWJvbC5kaXNwb3NlIC8gU3ltYm9sLmFzeW5jRGlzcG9zZSBwb2x5ZmlsbHMgZm9yIFF1aWNrSlNcbmlmICh0eXBlb2YgU3ltYm9sLmRpc3Bvc2UgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgU3ltYm9sLmRpc3Bvc2UgPSBTeW1ib2wuZm9yKFwiU3ltYm9sLmRpc3Bvc2VcIik7XG59XG5pZiAodHlwZW9mIFN5bWJvbC5hc3luY0Rpc3Bvc2UgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgU3ltYm9sLmFzeW5jRGlzcG9zZSA9IFN5bWJvbC5mb3IoXCJTeW1ib2wuYXN5bmNEaXNwb3NlXCIpO1xufVxuXG5nbG9iYWxUaGlzLl9fcHJpdmF0ZV93b3JrZmxvd3MgPSBuZXcgTWFwKCk7XG5nbG9iYWxUaGlzLl9fcmVzb2x2ZXJzID0ge307XG5nbG9iYWxUaGlzLl9fcGVuZGluZyA9IFtdO1xuZ2xvYmFsVGhpcy5fX3dvcmtmbG93UmVzdWx0ID0gdW5kZWZpbmVkO1xuZ2xvYmFsVGhpcy5fX3dvcmtmbG93RXJyb3IgPSB1bmRlZmluZWQ7XG4vLyBCdWZmZXIgZm9yIGhvb2tfcmVjZWl2ZWQgcGF5bG9hZHMgdGhhdCBhcnJpdmUgYmVmb3JlIHRoZSBob29rIGlzIGF3YWl0ZWQuXG4vLyBLZXllZCBieSBjb3JyZWxhdGlvbklkIOKGkiBhcnJheSBvZiBwYXlsb2FkcyAocHJlc2VydmVzIGRlbGl2ZXJ5IG9yZGVyKS5cbi8vIFRoaXMgbWlycm9ycyB0aGUgZXZlbnQtcmVwbGF5IHJ1bnRpbWUncyBwYXlsb2Fkc1F1ZXVlIGluIGhvb2sudHMuXG5nbG9iYWxUaGlzLl9faG9va1BheWxvYWRCdWZmZXIgPSB7fTtcblxuLy8gQnVmZmVyIGZvciBzdGVwL3dhaXQvYXR0ciB0ZXJtaW5hbCBvdXRjb21lcyB0aGF0IGFycml2ZSBiZWZvcmUgdGhpcyBWTVxuLy8gaGFzIGNvbnN0cnVjdGVkIHRoZSBjb3JyZXNwb25kaW5nIGF3YWl0aW5nIHByb21pc2UuIEluIGZyZXNoLVZNIHJlcGxheVxuLy8gdGhlIG11bHRpLXBhc3MgZXZlbnQgc2NhbiBtYWtlcyB0aGlzIHVucmVhY2hhYmxlIChhd2FpdHMgYXJlXG4vLyByZWNvbnN0cnVjdGVkIGJlZm9yZSB0aGVpciB0ZXJtaW5hbHMgYXJlIHJlLXNjYW5uZWQpLCBidXQgdGhlIGxpdmVcbi8vIGNvbnRpbnVhdGlvbiBwYXRoIChjb250aW51ZVdpdGhFdmVudHMpIHNjYW5zIGVhY2ggZGVsdGEgZXhhY3RseSBvbmNlIOKAlFxuLy8gYSBjb25jdXJyZW50IGludm9jYXRpb24ncyB0ZXJtaW5hbCBhcnJpdmluZyBiZWZvcmUgdGhpcyBWTSByZWFjaGVzIHRoZVxuLy8gYXdhaXQgd291bGQgb3RoZXJ3aXNlIGJlIGRyb3BwZWQgb24gdGhlIGZsb29yIGFuZCB0aGUgYXdhaXQgd291bGRcbi8vIG5ldmVyIHNldHRsZSAodGhlIGZlZWQncyBzZWVuLXNldCBtZWFucyBpdCBpcyBuZXZlciByZS1kZWxpdmVyZWQpLlxuLy8gTWlycm9ycyBfX2hvb2tQYXlsb2FkQnVmZmVyLCB3aGljaCBleGlzdHMgZm9yIGV4YWN0bHkgdGhpcyByZWFzb24gb25cbi8vIHRoZSBob29rIHBhdGguIEtleWVkIGJ5IGNvcnJlbGF0aW9uSWQg4oaSIHNpbmdsZSB0ZXJtaW5hbCAoc3RlcHMsIHdhaXRzXG4vLyBhbmQgYXR0cnMgc2V0dGxlIGV4YWN0bHkgb25jZSkuXG5nbG9iYWxUaGlzLl9fdGVybWluYWxCdWZmZXIgPSB7fTtcblxuLy8gUmVnaXN0ZXJzIGEgcmVzb2x2ZXIgZm9yIGFuIGF3YWl0ZWQgcHJpbWl0aXZlLCBmaXJzdCBkcmFpbmluZyBhbnlcbi8vIGJ1ZmZlcmVkIHRlcm1pbmFsIHJlY29yZGVkIGZvciB0aGUgY29ycmVsYXRpb25JZC4gRW50cmllcyBhcmUgcHJlcGFyZWRcbi8vIGhvc3Qtc2lkZSAoYnl0ZXMgYWxyZWFkeSBkZWNyeXB0ZWQ7IHNlZSBwcm9jZXNzRXZlbnRzKS5cbmdsb2JhbFRoaXMuX19yZWdpc3RlclJlc29sdmVyID0gZnVuY3Rpb24oY29ycmVsYXRpb25JZCwgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gIHZhciBidWZmZXJlZCA9IGdsb2JhbFRoaXMuX190ZXJtaW5hbEJ1ZmZlcltjb3JyZWxhdGlvbklkXTtcbiAgaWYgKGJ1ZmZlcmVkKSB7XG4gICAgZGVsZXRlIGdsb2JhbFRoaXMuX190ZXJtaW5hbEJ1ZmZlcltjb3JyZWxhdGlvbklkXTtcbiAgICBpZiAoYnVmZmVyZWQua2luZCA9PT0gXCJyZXNvbHZlX2J5dGVzXCIpIHtcbiAgICAgIHJlc29sdmUoZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwid29ya2Zsb3ctZGVzZXJpYWxpemVcIildKGJ1ZmZlcmVkLmJ5dGVzKSk7XG4gICAgfSBlbHNlIGlmIChidWZmZXJlZC5raW5kID09PSBcInJlc29sdmVfdmFsdWVcIikge1xuICAgICAgcmVzb2x2ZShidWZmZXJlZC52YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChidWZmZXJlZC5raW5kID09PSBcInJlamVjdF9ieXRlc1wiKSB7XG4gICAgICByZWplY3QoZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwid29ya2Zsb3ctZGVzZXJpYWxpemVcIildKGJ1ZmZlcmVkLmJ5dGVzKSk7XG4gICAgfSBlbHNlIGlmIChidWZmZXJlZC5raW5kID09PSBcInJlamVjdF9lcnJvclwiKSB7XG4gICAgICB2YXIgZSA9IG5ldyBFcnJvcihidWZmZXJlZC5tZXNzYWdlKTtcbiAgICAgIGUubmFtZSA9IFwiRmF0YWxFcnJvclwiO1xuICAgICAgZS5mYXRhbCA9IHRydWU7XG4gICAgICBpZiAoYnVmZmVyZWQuc3RhY2spIGUuc3RhY2sgPSBidWZmZXJlZC5zdGFjaztcbiAgICAgIHJlamVjdChlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cbiAgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1tjb3JyZWxhdGlvbklkXSA9IHsgcmVzb2x2ZTogcmVzb2x2ZSwgcmVqZWN0OiByZWplY3QgfTtcbn07XG5cbi8vIFN0dWJzIGZvciBXZWIgQVBJcyB0aGF0IHRoZSB3b3JrZmxvdyBidW5kbGUgbWF5IHJlZmVyZW5jZSBidXQgYXJlIG5vdFxuLy8gYXZhaWxhYmxlIGluIFF1aWNrSlMuIE5hdGl2ZSBDIGV4dGVuc2lvbnMgKGVuY29kaW5nLCBoZWFkZXJzLCB1cmwsXG4vLyBzdHJ1Y3R1cmVkLWNsb25lKSBwcm92aWRlIHRoZSByZWFsIGltcGxlbWVudGF0aW9uczsgdGhlc2UgYXJlIG1pbmltYWxcbi8vIHN0dWJzIGZvciBBUElzIHRoYXQgZG9uJ3QgaGF2ZSBuYXRpdmUgZXh0ZW5zaW9ucyB5ZXQuIChidG9hL2F0b2IgYW5kXG4vLyB0aGUgVWludDhBcnJheSBiYXNlNjQvaGV4IG1ldGhvZHMgYXJlIGJ1aWx0IGludG8gcXVpY2tqcy13YXNpID49IDMuKVxuXG5pZiAodHlwZW9mIFJlYWRhYmxlU3RyZWFtID09PSBcInVuZGVmaW5lZFwiKSB7XG4gIC8vIE1pbmltYWwgUmVhZGFibGVTdHJlYW0gdGhhdCBzdG9yZXMgYm9keSBkYXRhIGZvciBSZXNwb25zZS5qc29uKCkvdGV4dCgpXG4gIGdsb2JhbFRoaXMuUmVhZGFibGVTdHJlYW0gPSBmdW5jdGlvbigpIHt9O1xuICBnbG9iYWxUaGlzLlJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZS5fX2JvZHlEYXRhID0gbnVsbDtcbn1cblxuaWYgKHR5cGVvZiBXcml0YWJsZVN0cmVhbSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICBnbG9iYWxUaGlzLldyaXRhYmxlU3RyZWFtID0gZnVuY3Rpb24oKSB7fTtcbn1cblxuaWYgKHR5cGVvZiBUcmFuc2Zvcm1TdHJlYW0gPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgZ2xvYmFsVGhpcy5UcmFuc2Zvcm1TdHJlYW0gPSBmdW5jdGlvbigpIHt9O1xufVxuXG5pZiAodHlwZW9mIGNvbnNvbGUgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgZ2xvYmFsVGhpcy5jb25zb2xlID0geyBsb2c6IGZ1bmN0aW9uKCl7fSwgZXJyb3I6IGZ1bmN0aW9uKCl7fSwgd2FybjogZnVuY3Rpb24oKXt9LCBpbmZvOiBmdW5jdGlvbigpe30gfTtcbn1cbi8vIFN0dWIgZXhwb3J0cy9tb2R1bGUgZm9yIENKUyBidW5kbGUgZm9ybWF0XG5nbG9iYWxUaGlzLmV4cG9ydHMgPSB7fTtcbmdsb2JhbFRoaXMubW9kdWxlID0geyBleHBvcnRzOiBnbG9iYWxUaGlzLmV4cG9ydHMgfTtcbi8vIE5PVEU6IFRleHRFbmNvZGVyL1RleHREZWNvZGVyIGFyZSBwcm92aWRlZCBieSB0aGUgbmF0aXZlIGVuY29kaW5nIGV4dGVuc2lvbi5cblxuLy8gLS0tLSBEZXRlcm1pbmlzdGljIFxcYGNyeXB0b1xcYCAocGFyaXR5IHdpdGggdGhlIG5vZGU6dm0gZW5naW5lKSAtLS0tXG4vLyBnZXRSYW5kb21WYWx1ZXMgLyByYW5kb21VVUlEIGRyYXcgZnJvbSBNYXRoLnJhbmRvbSwgd2hpY2ggdGhlIGhvc3Rcbi8vIHJlcGxhY2VzIHdpdGggdGhlIHJ1bidzIHNlZWRlZCBQUk5HIGJlZm9yZSBhbnkgdXNlciBjb2RlIHJ1bnMg4oCUIHNvIHRoZVxuLy8gdmFsdWVzIHJlcGxheSBkZXRlcm1pbmlzdGljYWxseSBhbmQgbWF0Y2ggdGhlIG5vZGUgZW5naW5lLCB3aG9zZVxuLy8gaW1wbGVtZW50YXRpb25zIGRyYXcgZnJvbSB0aGUgc2FtZSBzZWVkZWQgc2VxdWVuY2UgKHNlZSB2bS9pbmRleC50cykuXG4vLyBFdmVyeSBjcnlwdG8uc3VidGxlIG1ldGhvZCB0aHJvd3Mgd2l0aCB0aGUgc2FtZSBndWlkYW5jZSBhcyB0aGUgbm9kZVxuLy8gZW5naW5lJ3Mgbm9uLXJlcGxheWFibGUgbWV0aG9kczsgdW5saWtlIG5vZGUsIFxcYGRpZ2VzdFxcYCBpcyBhbHNvXG4vLyB1bmF2YWlsYWJsZSBoZXJlIChubyBuYXRpdmUgaGFzaCBpbiB0aGUgVk0geWV0KS5cbihmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gZ2V0UmFuZG9tVmFsdWVzKGFycmF5KSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgYXJyYXlbaV0gPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAyNTYpO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cbiAgLy8gTWlycm9ycyB2bS91dWlkLnRzIGNyZWF0ZVJhbmRvbVVVSUQ6IGlkZW50aWNhbCBkcmF3IHBhdHRlcm4gZnJvbSB0aGVcbiAgLy8gc2VlZGVkIFBSTkcsIHNvIGJvdGggZW5naW5lcyBwcm9kdWNlIHRoZSBzYW1lIFVVSUQgYXQgdGhlIHNhbWUgcG9pbnRcbiAgLy8gaW4gYSByZXBsYXkuXG4gIGZ1bmN0aW9uIHJhbmRvbVVVSUQoKSB7XG4gICAgdmFyIGNoYXJzID0gXCIwMTIzNDU2Nzg5YWJjZGVmXCI7XG4gICAgdmFyIHV1aWQgPSBcIlwiO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMzY7IGkrKykge1xuICAgICAgaWYgKGkgPT09IDggfHwgaSA9PT0gMTMgfHwgaSA9PT0gMTggfHwgaSA9PT0gMjMpIHtcbiAgICAgICAgdXVpZCArPSBcIi1cIjtcbiAgICAgIH0gZWxzZSBpZiAoaSA9PT0gMTQpIHtcbiAgICAgICAgdXVpZCArPSBcIjRcIjtcbiAgICAgIH0gZWxzZSBpZiAoaSA9PT0gMTkpIHtcbiAgICAgICAgdXVpZCArPSBjaGFyc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiA0KSArIDhdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdXVpZCArPSBjaGFyc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxNildO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdXVpZDtcbiAgfVxuICBmdW5jdGlvbiBzdWJ0bGVUaHJvdyhuYW1lKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcihcIlxcYGNyeXB0by5zdWJ0bGUuXCIgKyBuYW1lICsgXCIoKVxcYCBpcyBub3QgYXZhaWxhYmxlIGluc2lkZSBhIHdvcmtmbG93IGZ1bmN0aW9uLiBNb3ZlIGl0IHRvIGEgc3RlcCBmdW5jdGlvbiB3aGVyZSBmdWxsIE5vZGUuanMgY3J5cHRvIGlzIGF2YWlsYWJsZS5cIik7XG4gICAgICBlcnIubmFtZSA9IFwiV29ya2Zsb3dSdW50aW1lRXJyb3JcIjtcbiAgICAgIHRocm93IGVycjtcbiAgICB9O1xuICB9XG4gIHZhciBzdWJ0bGUgPSB7fTtcbiAgW1wiZW5jcnlwdFwiLFwiZGVjcnlwdFwiLFwic2lnblwiLFwidmVyaWZ5XCIsXCJkaWdlc3RcIixcImdlbmVyYXRlS2V5XCIsXCJkZXJpdmVLZXlcIixcImRlcml2ZUJpdHNcIixcImltcG9ydEtleVwiLFwiZXhwb3J0S2V5XCIsXCJ3cmFwS2V5XCIsXCJ1bndyYXBLZXlcIl0uZm9yRWFjaChmdW5jdGlvbihtKSB7XG4gICAgc3VidGxlW21dID0gc3VidGxlVGhyb3cobSk7XG4gIH0pO1xuICBnbG9iYWxUaGlzLmNyeXB0byA9IHtcbiAgICBnZXRSYW5kb21WYWx1ZXM6IGdldFJhbmRvbVZhbHVlcyxcbiAgICByYW5kb21VVUlEOiByYW5kb21VVUlELFxuICAgIHN1YnRsZTogc3VidGxlLFxuICB9O1xufSkoKTtcblxuLy8gLS0tLSBMb3VkIEludGwgLyBsb2NhbGUgZ3VhcmRzIC0tLS1cbi8vIFF1aWNrSlMgaGFzIG5vIElDVTogXFxgSW50bFxcYCBpcyBhYnNlbnQgYW5kIHRvTG9jYWxlU3RyaW5nLWZhbWlseSBtZXRob2RzXG4vLyBzaWxlbnRseSBpZ25vcmUgdGhlaXIgbG9jYWxlIGFyZ3VtZW50LiBTaWxlbnQgZGl2ZXJnZW5jZSBmcm9tIHRoZSBub2RlXG4vLyBlbmdpbmUgd291bGQgd3JpdGUgZGlmZmVyZW50IHZhbHVlcyBpbnRvIGEgZHVyYWJsZSBldmVudCBsb2cgd2l0aCBub1xuLy8gZXJyb3IgYW55d2hlcmUg4oCUIHNvIG1ha2UgdGhlIGdhcCBsb3VkIGluc3RlYWQ6IEludGwgY29uc3RydWN0b3JzIHRocm93LFxuLy8gYW5kIHRvTG9jYWxlKiBtZXRob2RzIHRocm93IE9OTFkgd2hlbiBjYWxsZWQgd2l0aCBhbiBleHBsaWNpdCBsb2NhbGVcbi8vICh0aGUgbm8tYXJndW1lbnQgZm9ybXMga2VlcCBRdWlja0pTJ3MgZGVmYXVsdCBiZWhhdmlvcikuXG4oZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIGludGxUaHJvdyhuYW1lKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcihcIlxcYEludGwuXCIgKyBuYW1lICsgXCJcXGAgaXMgbm90IGF2YWlsYWJsZSBpbiB0aGUgUXVpY2tKUyB3b3JrZmxvdyBlbmdpbmUgKG5vIElDVSkuIFBlcmZvcm0gbG9jYWxlLXNlbnNpdGl2ZSBmb3JtYXR0aW5nIGluIGEgc3RlcCBmdW5jdGlvbiwgb3IgdXNlIFdPUktGTE9XX1ZNPW5vZGUuXCIpO1xuICAgICAgZXJyLm5hbWUgPSBcIldvcmtmbG93UnVudGltZUVycm9yXCI7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfTtcbiAgfVxuICBpZiAodHlwZW9mIEludGwgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICB2YXIgaW50bCA9IHt9O1xuICAgIFtcIkNvbGxhdG9yXCIsXCJEYXRlVGltZUZvcm1hdFwiLFwiRGlzcGxheU5hbWVzXCIsXCJEdXJhdGlvbkZvcm1hdFwiLFwiTGlzdEZvcm1hdFwiLFwiTG9jYWxlXCIsXCJOdW1iZXJGb3JtYXRcIixcIlBsdXJhbFJ1bGVzXCIsXCJSZWxhdGl2ZVRpbWVGb3JtYXRcIixcIlNlZ21lbnRlclwiXS5mb3JFYWNoKGZ1bmN0aW9uKG4pIHtcbiAgICAgIGludGxbbl0gPSBpbnRsVGhyb3cobik7XG4gICAgfSk7XG4gICAgaW50bC5nZXRDYW5vbmljYWxMb2NhbGVzID0gaW50bFRocm93KFwiZ2V0Q2Fub25pY2FsTG9jYWxlc1wiKTtcbiAgICBnbG9iYWxUaGlzLkludGwgPSBpbnRsO1xuICB9XG4gIGZ1bmN0aW9uIGd1YXJkTG9jYWxlKHByb3RvLCBtZXRob2QpIHtcbiAgICB2YXIgb3JpZ2luYWwgPSBwcm90b1ttZXRob2RdO1xuICAgIGlmICh0eXBlb2Ygb3JpZ2luYWwgIT09IFwiZnVuY3Rpb25cIikgcmV0dXJuO1xuICAgIHByb3RvW21ldGhvZF0gPSBmdW5jdGlvbihsb2NhbGVzKSB7XG4gICAgICBpZiAobG9jYWxlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoXCJcXGBcIiArIG1ldGhvZCArIFwiKGxvY2FsZXMsIC4uLilcXGAgd2l0aCBhbiBleHBsaWNpdCBsb2NhbGUgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgUXVpY2tKUyB3b3JrZmxvdyBlbmdpbmUgKG5vIElDVSkg4oCUIGl0IHdvdWxkIHNpbGVudGx5IGlnbm9yZSB0aGUgbG9jYWxlLiBGb3JtYXQgaW4gYSBzdGVwIGZ1bmN0aW9uLCBvciBjYWxsIHdpdGhvdXQgYXJndW1lbnRzIGZvciB0aGUgZW5naW5lIGRlZmF1bHQuXCIpO1xuICAgICAgICBlcnIubmFtZSA9IFwiV29ya2Zsb3dSdW50aW1lRXJyb3JcIjtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9yaWdpbmFsLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgfVxuICBndWFyZExvY2FsZShOdW1iZXIucHJvdG90eXBlLCBcInRvTG9jYWxlU3RyaW5nXCIpO1xuICBndWFyZExvY2FsZShEYXRlLnByb3RvdHlwZSwgXCJ0b0xvY2FsZVN0cmluZ1wiKTtcbiAgZ3VhcmRMb2NhbGUoRGF0ZS5wcm90b3R5cGUsIFwidG9Mb2NhbGVEYXRlU3RyaW5nXCIpO1xuICBndWFyZExvY2FsZShEYXRlLnByb3RvdHlwZSwgXCJ0b0xvY2FsZVRpbWVTdHJpbmdcIik7XG4gIGd1YXJkTG9jYWxlKFN0cmluZy5wcm90b3R5cGUsIFwidG9Mb2NhbGVMb3dlckNhc2VcIik7XG4gIGd1YXJkTG9jYWxlKFN0cmluZy5wcm90b3R5cGUsIFwidG9Mb2NhbGVVcHBlckNhc2VcIik7XG4gIC8vIGxvY2FsZUNvbXBhcmUncyBsb2NhbGVzIGFyZ3VtZW50IGlzIHRoZSBTRUNPTkQgcGFyYW1ldGVyLlxuICAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9yaWdpbmFsID0gU3RyaW5nLnByb3RvdHlwZS5sb2NhbGVDb21wYXJlO1xuICAgIFN0cmluZy5wcm90b3R5cGUubG9jYWxlQ29tcGFyZSA9IGZ1bmN0aW9uKHRoYXQsIGxvY2FsZXMpIHtcbiAgICAgIGlmIChsb2NhbGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcihcIlxcYGxvY2FsZUNvbXBhcmUodGhhdCwgbG9jYWxlcywgLi4uKVxcYCB3aXRoIGFuIGV4cGxpY2l0IGxvY2FsZSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBRdWlja0pTIHdvcmtmbG93IGVuZ2luZSAobm8gSUNVKS4gQ29tcGFyZSBpbiBhIHN0ZXAgZnVuY3Rpb24sIG9yIGNhbGwgd2l0aG91dCBhIGxvY2FsZS5cIik7XG4gICAgICAgIGVyci5uYW1lID0gXCJXb3JrZmxvd1J1bnRpbWVFcnJvclwiO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgICByZXR1cm4gb3JpZ2luYWwuY2FsbCh0aGlzLCB0aGF0KTtcbiAgICB9O1xuICB9KSgpO1xufSkoKTtcblxuZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildID0gZnVuY3Rpb24oc3RlcElkLCBjbG9zdXJlVmFyc0ZuKSB7XG4gIHZhciBmbiA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICB2YXIgY29ycmVsYXRpb25JZCA9IFwic3RlcF9cIiArIGdsb2JhbFRoaXMuX19nZW5lcmF0ZVVsaWQoKTtcbiAgICAvLyBDYXB0dXJlICd0aGlzJyBmb3IgbWV0aG9kIGludm9jYXRpb25zIChlLmcuLCBNeUNsYXNzLm1ldGhvZCgpKVxuICAgIHZhciB0aGlzVmFsID0gKHRoaXMgIT09IHVuZGVmaW5lZCAmJiB0aGlzICE9PSBudWxsICYmIHRoaXMgIT09IGdsb2JhbFRoaXMpID8gdGhpcyA6IHVuZGVmaW5lZDtcbiAgICAvLyBTZXJpYWxpemUgc3RlcCBpbnB1dCB1c2luZyB0aGUgaG9zdC1wcm92aWRlZCBkZXZhbHVlIHNlcmlhbGl6ZXIuXG4gICAgLy8gVGhpcyBwcm9kdWNlcyBhIGZvcm1hdC1wcmVmaXhlZCBVaW50OEFycmF5IChcImRldmxcIiArIGRldmFsdWUuc3RyaW5naWZ5KS5cbiAgICB2YXIgaW5wdXQgPSBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJ3b3JrZmxvdy1zZXJpYWxpemVcIildKHtcbiAgICAgIGFyZ3M6IGFyZ3MsXG4gICAgICBjbG9zdXJlVmFyczogY2xvc3VyZVZhcnNGbiA/IGNsb3N1cmVWYXJzRm4oKSA6IHVuZGVmaW5lZCxcbiAgICAgIHRoaXNWYWw6IHRoaXNWYWwsXG4gICAgfSk7XG4gICAgZ2xvYmFsVGhpcy5fX3BlbmRpbmcucHVzaCh7XG4gICAgICB0eXBlOiBcInN0ZXBcIixcbiAgICAgIGNvcnJlbGF0aW9uSWQ6IGNvcnJlbGF0aW9uSWQsXG4gICAgICBzdGVwSWQ6IHN0ZXBJZCxcbiAgICAgIGlucHV0OiBpbnB1dCxcbiAgICAgIGhhc0NyZWF0ZWRFdmVudDogZmFsc2UsXG4gICAgfSk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgZ2xvYmFsVGhpcy5fX3JlZ2lzdGVyUmVzb2x2ZXIoY29ycmVsYXRpb25JZCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICB9KTtcbiAgfTtcbiAgLy8gU2V0IHN0ZXBJZCBvbiB0aGUgcHJveHkgc28gdGhlIFN0ZXBGdW5jdGlvbiByZWR1Y2VyIGNhbiBkZXRlY3QgYW5kXG4gIC8vIHNlcmlhbGl6ZSBzdGVwIGZ1bmN0aW9uIHJlZmVyZW5jZXMgKGUuZy4gd2hlbiBwYXNzZWQgYXMgYXJndW1lbnRzKS5cbiAgZm4uc3RlcElkID0gc3RlcElkO1xuICBpZiAoY2xvc3VyZVZhcnNGbikgZm4uX19jbG9zdXJlVmFyc0ZuID0gY2xvc3VyZVZhcnNGbjtcbiAgLy8gT3ZlcnJpZGUgLmJpbmQgc28gYSBib3VuZCBzdGVwIHByb3h5IChlLmcuIHRoZSBTV0MgcGx1Z2luJ3NcbiAgLy8gdXNlU3RlcCguLi4pLmJpbmQodGhpcykgZm9yIGxleGljYWwtdGhpcyBhcnJvdyBzdGVwcykga2VlcHMgaXRzXG4gIC8vIHN0ZXBJZCBhbmQgcmVjb3JkcyB0aGUgYm91bmQgcmVjZWl2ZXIgLyBwcmVmaWxsZWQgYXJncyDigJQgdGhlIG5hdGl2ZVxuICAvLyBiaW5kIGRyb3BzIG93biBwcm9wZXJ0aWVzLCB3aGljaCB3b3VsZCBtYWtlIHRoZSBTdGVwRnVuY3Rpb25cbiAgLy8gcmVkdWNlciBmYWlsIHRvIHJlY29nbml6ZSB0aGUgcHJveHkgd2hlbiBpdCBjcm9zc2VzIGEgc2VyaWFsaXphdGlvblxuICAvLyBib3VuZGFyeS4gTWlycm9ycyB0aGUgbm9kZTp2bSBlbmdpbmUncyBvdmVycmlkZSBpbiBzdGVwLnRzLlxuICBmbi5iaW5kID0gZnVuY3Rpb24odGhpc0FyZykge1xuICAgIHZhciBwYXJ0aWFsQXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgdmFyIGJvdW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQuYXBwbHkodGhpcywgW3RoaXNBcmddLmNvbmNhdChwYXJ0aWFsQXJncykpO1xuICAgIGJvdW5kLnN0ZXBJZCA9IHN0ZXBJZDtcbiAgICBpZiAoY2xvc3VyZVZhcnNGbikgYm91bmQuX19jbG9zdXJlVmFyc0ZuID0gY2xvc3VyZVZhcnNGbjtcbiAgICBib3VuZC5fX2JvdW5kVGhpcyA9IHRoaXNBcmc7XG4gICAgaWYgKHBhcnRpYWxBcmdzLmxlbmd0aCA+IDApIGJvdW5kLl9fYm91bmRBcmdzID0gcGFydGlhbEFyZ3M7XG4gICAgcmV0dXJuIGJvdW5kO1xuICB9O1xuICByZXR1cm4gZm47XG59O1xuXG4vLyBQYXJzZXMgYW4gXCJtc1wiIGxpYnJhcnkgc3R5bGUgZHVyYXRpb24gc3RyaW5nIGludG8gbWlsbGlzZWNvbmRzLlxuLy8gU3VwcG9ydHMgdGhlIHNhbWUgdW5pdHMgYXMgdGhlIHJlcGxheSBydW50aW1lICh3aGljaCB1c2VzIHRoZSBcIm1zXCJcbi8vIHBhY2thZ2UpOiBtcyAvIHMgLyBtIC8gaCAvIGQgLyB3IC8geSwgd2l0aCB2ZXJib3NlIGFsaWFzZXNcbi8vIChzZWNvbmRzLCBtaW51dGVzLCAuLi4pLlxuZ2xvYmFsVGhpcy5fX3BhcnNlRHVyYXRpb25NcyA9IGZ1bmN0aW9uKHN0cikge1xuICBzdHIgPSBTdHJpbmcoc3RyKTtcbiAgaWYgKHN0ci5sZW5ndGggPiAxMDApIHJldHVybiB1bmRlZmluZWQ7XG4gIHZhciBtYXRjaCA9IHN0ci5tYXRjaChcbiAgICAvXigtPyg/OlxcXFxkKyk/XFxcXC4/XFxcXGQrKSAqKG1pbGxpc2Vjb25kcz98bXNlY3M/fG1zfHNlY29uZHM/fHNlY3M/fHN8bWludXRlcz98bWlucz98bXxob3Vycz98aHJzP3xofGRheXM/fGR8d2Vla3M/fHd8eWVhcnM/fHlycz98eSk/JC9pXG4gICk7XG4gIGlmICghbWF0Y2gpIHJldHVybiB1bmRlZmluZWQ7XG4gIHZhciBuID0gcGFyc2VGbG9hdChtYXRjaFsxXSk7XG4gIHZhciB0eXBlID0gKG1hdGNoWzJdIHx8IFwibXNcIikudG9Mb3dlckNhc2UoKTtcbiAgdmFyIHMgPSAxMDAwLCBtID0gNjAgKiBzLCBoID0gNjAgKiBtLCBkID0gMjQgKiBoLCB3ID0gNyAqIGQsIHkgPSAzNjUuMjUgKiBkO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFwieWVhcnNcIjogY2FzZSBcInllYXJcIjogY2FzZSBcInlyc1wiOiBjYXNlIFwieXJcIjogY2FzZSBcInlcIjogcmV0dXJuIG4gKiB5O1xuICAgIGNhc2UgXCJ3ZWVrc1wiOiBjYXNlIFwid2Vla1wiOiBjYXNlIFwid1wiOiByZXR1cm4gbiAqIHc7XG4gICAgY2FzZSBcImRheXNcIjogY2FzZSBcImRheVwiOiBjYXNlIFwiZFwiOiByZXR1cm4gbiAqIGQ7XG4gICAgY2FzZSBcImhvdXJzXCI6IGNhc2UgXCJob3VyXCI6IGNhc2UgXCJocnNcIjogY2FzZSBcImhyXCI6IGNhc2UgXCJoXCI6IHJldHVybiBuICogaDtcbiAgICBjYXNlIFwibWludXRlc1wiOiBjYXNlIFwibWludXRlXCI6IGNhc2UgXCJtaW5zXCI6IGNhc2UgXCJtaW5cIjogY2FzZSBcIm1cIjogcmV0dXJuIG4gKiBtO1xuICAgIGNhc2UgXCJzZWNvbmRzXCI6IGNhc2UgXCJzZWNvbmRcIjogY2FzZSBcInNlY3NcIjogY2FzZSBcInNlY1wiOiBjYXNlIFwic1wiOiByZXR1cm4gbiAqIHM7XG4gICAgY2FzZSBcIm1pbGxpc2Vjb25kc1wiOiBjYXNlIFwibWlsbGlzZWNvbmRcIjogY2FzZSBcIm1zZWNzXCI6IGNhc2UgXCJtc2VjXCI6IGNhc2UgXCJtc1wiOiByZXR1cm4gbjtcbiAgICBkZWZhdWx0OiByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59O1xuXG5nbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19TTEVFUFwiKV0gPSBmdW5jdGlvbihwYXJhbSkge1xuICB2YXIgY29ycmVsYXRpb25JZCA9IFwid2FpdF9cIiArIGdsb2JhbFRoaXMuX19nZW5lcmF0ZVVsaWQoKTtcbiAgdmFyIHJlc3VtZUF0O1xuICBpZiAodHlwZW9mIHBhcmFtID09PSBcIm51bWJlclwiKSB7XG4gICAgcmVzdW1lQXQgPSBuZXcgRGF0ZShEYXRlLm5vdygpICsgcGFyYW0pLnRvSVNPU3RyaW5nKCk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHBhcmFtID09PSBcInN0cmluZ1wiKSB7XG4gICAgdmFyIG1zID0gZ2xvYmFsVGhpcy5fX3BhcnNlRHVyYXRpb25NcyhwYXJhbSk7XG4gICAgaWYgKHR5cGVvZiBtcyA9PT0gXCJudW1iZXJcIiAmJiBpc0Zpbml0ZShtcykpIHtcbiAgICAgIHJlc3VtZUF0ID0gbmV3IERhdGUoRGF0ZS5ub3coKSArIG1zKS50b0lTT1N0cmluZygpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBOb3QgYSBkdXJhdGlvbiBzdHJpbmcg4oCUIHRyeSBhcyBhbiBhYnNvbHV0ZSBkYXRlIHN0cmluZy5cbiAgICAgIHZhciBkYXRlID0gbmV3IERhdGUocGFyYW0pO1xuICAgICAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHNsZWVwIHBhcmFtZXRlcjogXCIgKyBwYXJhbSk7XG4gICAgICB9XG4gICAgICByZXN1bWVBdCA9IGRhdGUudG9JU09TdHJpbmcoKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAocGFyYW0gaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgaWYgKGlzTmFOKHBhcmFtLmdldFRpbWUoKSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgc2xlZXAgcGFyYW1ldGVyOiBcIiArIHBhcmFtKTtcbiAgICB9XG4gICAgcmVzdW1lQXQgPSBwYXJhbS50b0lTT1N0cmluZygpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgc2xlZXAgcGFyYW1ldGVyOiBcIiArIHBhcmFtKTtcbiAgfVxuICBnbG9iYWxUaGlzLl9fcGVuZGluZy5wdXNoKHtcbiAgICB0eXBlOiBcIndhaXRcIixcbiAgICBjb3JyZWxhdGlvbklkOiBjb3JyZWxhdGlvbklkLFxuICAgIHJlc3VtZUF0OiByZXN1bWVBdCxcbiAgICBoYXNDcmVhdGVkRXZlbnQ6IGZhbHNlLFxuICB9KTtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGdsb2JhbFRoaXMuX19yZWdpc3RlclJlc29sdmVyKGNvcnJlbGF0aW9uSWQsIHJlc29sdmUsIHJlamVjdCk7XG4gIH0pO1xufTtcblxuLy8gUmVzcG9uc2UvUmVxdWVzdCBwb2x5ZmlsbHMg4oCUIC5qc29uKCkvLnRleHQoKS8uYXJyYXlCdWZmZXIoKSBhcmUgdXNlU3RlcFxuLy8gcHJveGllcyB0aGF0IGV4ZWN1dGUgb24gdGhlIGhvc3Qgc2lkZS4gVGhlIHByb3hpZXMgYXJlIGFzc2lnbmVkIGRpcmVjdGx5XG4vLyB0byB0aGUgcHJvdG90eXBlcyBzbyB0aGF0ICd0aGlzJyAodGhlIFJlc3BvbnNlL1JlcXVlc3QgaW5zdGFuY2UpIGlzXG4vLyBzZXJpYWxpemVkIGFzIHRoaXNWYWwgYnkgV09SS0ZMT1dfVVNFX1NURVAsIG1hdGNoaW5nIHRoZSBldmVudC1yZXBsYXlcbi8vIHJ1bnRpbWUncyBhcHByb2FjaCAoY29tbWl0IGRjYjA3NjEpLlxuaWYgKHR5cGVvZiBSZXNwb25zZSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICB2YXIgX19CT0RZX0lOSVQgPSBTeW1ib2wuZm9yKFwiQk9EWV9JTklUXCIpO1xuXG4gIGdsb2JhbFRoaXMuUmVzcG9uc2UgPSBmdW5jdGlvbihib2R5LCBpbml0KSB7XG4gICAgaW5pdCA9IGluaXQgfHwge307XG4gICAgdGhpcy5zdGF0dXMgPSBpbml0LnN0YXR1cyB8fCAyMDA7XG4gICAgdGhpcy5zdGF0dXNUZXh0ID0gaW5pdC5zdGF0dXNUZXh0IHx8IFwiXCI7XG4gICAgdGhpcy5oZWFkZXJzID0gbmV3IGdsb2JhbFRoaXMuSGVhZGVycyhpbml0LmhlYWRlcnMgfHwgW10pO1xuICAgIHRoaXMudHlwZSA9IFwiZGVmYXVsdFwiO1xuICAgIHRoaXMudXJsID0gXCJcIjtcbiAgICB0aGlzLnJlZGlyZWN0ZWQgPSBmYWxzZTtcbiAgICBpZiAoYm9keSAhPT0gbnVsbCAmJiBib2R5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuYm9keSA9IE9iamVjdC5jcmVhdGUoZ2xvYmFsVGhpcy5SZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUpO1xuICAgICAgdGhpcy5ib2R5W19fQk9EWV9JTklUXSA9IGJvZHk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYm9keSA9IG51bGw7XG4gICAgfVxuICB9O1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsVGhpcy5SZXNwb25zZS5wcm90b3R5cGUsIFwib2tcIiwge1xuICAgIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLnN0YXR1cyA+PSAyMDAgJiYgdGhpcy5zdGF0dXMgPCAzMDA7IH1cbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxUaGlzLlJlc3BvbnNlLnByb3RvdHlwZSwgXCJib2R5VXNlZFwiLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9XG4gIH0pO1xuICAvLyBBc3NpZ24gdXNlU3RlcCBwcm94aWVzIGRpcmVjdGx5IOKAlCAndGhpcycgYmluZGluZyBwcm92aWRlcyB0aGVcbiAgLy8gUmVzcG9uc2UgaW5zdGFuY2UsIHdoaWNoIGdldHMgc2VyaWFsaXplZCBhcyB0aGlzVmFsIGJ5IHRoZSBwcm94eS5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoZ2xvYmFsVGhpcy5SZXNwb25zZS5wcm90b3R5cGUsIHtcbiAgICBhcnJheUJ1ZmZlcjogeyB2YWx1ZTogZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwiX19idWlsdGluX3Jlc3BvbnNlX2FycmF5X2J1ZmZlclwiKSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9LFxuICAgIGpzb246IHsgdmFsdWU6IGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcIl9fYnVpbHRpbl9yZXNwb25zZV9qc29uXCIpLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0sXG4gICAgdGV4dDogeyB2YWx1ZTogZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwiX19idWlsdGluX3Jlc3BvbnNlX3RleHRcIiksIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSxcbiAgfSk7XG4gIGdsb2JhbFRoaXMuUmVzcG9uc2UucHJvdG90eXBlLmJ5dGVzID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuYXJyYXlCdWZmZXIoKS50aGVuKGZ1bmN0aW9uKGJ1ZikgeyByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYnVmKTsgfSk7XG4gIH07XG4gIGdsb2JhbFRoaXMuUmVzcG9uc2UucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHIgPSBPYmplY3QuY3JlYXRlKGdsb2JhbFRoaXMuUmVzcG9uc2UucHJvdG90eXBlKTtcbiAgICByLnN0YXR1cyA9IHRoaXMuc3RhdHVzOyByLnN0YXR1c1RleHQgPSB0aGlzLnN0YXR1c1RleHQ7XG4gICAgci5oZWFkZXJzID0gdGhpcy5oZWFkZXJzOyByLnR5cGUgPSB0aGlzLnR5cGU7XG4gICAgci51cmwgPSB0aGlzLnVybDsgci5yZWRpcmVjdGVkID0gdGhpcy5yZWRpcmVjdGVkOyByLmJvZHkgPSB0aGlzLmJvZHk7XG4gICAgcmV0dXJuIHI7XG4gIH07XG4gIGdsb2JhbFRoaXMuUmVzcG9uc2UuanNvbiA9IGZ1bmN0aW9uKGRhdGEsIGluaXQpIHtcbiAgICB2YXIgYm9keSA9IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICAgIHZhciBoZWFkZXJzID0gbmV3IGdsb2JhbFRoaXMuSGVhZGVycyhpbml0ID8gaW5pdC5oZWFkZXJzIDogW10pO1xuICAgIGlmICghaGVhZGVycy5oYXMoXCJjb250ZW50LXR5cGVcIikpIHsgaGVhZGVycy5zZXQoXCJjb250ZW50LXR5cGVcIiwgXCJhcHBsaWNhdGlvbi9qc29uXCIpOyB9XG4gICAgcmV0dXJuIG5ldyBnbG9iYWxUaGlzLlJlc3BvbnNlKGJvZHksIHsgc3RhdHVzOiAoaW5pdCAmJiBpbml0LnN0YXR1cykgfHwgMjAwLCBzdGF0dXNUZXh0OiAoaW5pdCAmJiBpbml0LnN0YXR1c1RleHQpIHx8IFwiXCIsIGhlYWRlcnM6IGhlYWRlcnMgfSk7XG4gIH07XG59XG5pZiAodHlwZW9mIFJlcXVlc3QgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgZ2xvYmFsVGhpcy5SZXF1ZXN0ID0gZnVuY3Rpb24oaW5wdXQsIGluaXQpIHtcbiAgICBpbml0ID0gaW5pdCB8fCB7fTtcbiAgICBpZiAodHlwZW9mIGlucHV0ID09PSBcInN0cmluZ1wiKSB7IHRoaXMudXJsID0gaW5wdXQ7IH1cbiAgICBlbHNlIGlmIChpbnB1dCAmJiB0eXBlb2YgaW5wdXQgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRoaXMudXJsID0gaW5wdXQudXJsIHx8IFwiXCI7IHRoaXMubWV0aG9kID0gaW5wdXQubWV0aG9kO1xuICAgICAgdGhpcy5oZWFkZXJzID0gaW5wdXQuaGVhZGVyczsgdGhpcy5ib2R5ID0gaW5wdXQuYm9keTtcbiAgICB9XG4gICAgaWYgKGluaXQubWV0aG9kKSB0aGlzLm1ldGhvZCA9IGluaXQubWV0aG9kLnRvVXBwZXJDYXNlKCk7XG4gICAgaWYgKCF0aGlzLm1ldGhvZCkgdGhpcy5tZXRob2QgPSBcIkdFVFwiO1xuICAgIGlmIChpbml0LmhlYWRlcnMpIHRoaXMuaGVhZGVycyA9IG5ldyBnbG9iYWxUaGlzLkhlYWRlcnMoaW5pdC5oZWFkZXJzKTtcbiAgICBpZiAoIXRoaXMuaGVhZGVycykgdGhpcy5oZWFkZXJzID0gbmV3IGdsb2JhbFRoaXMuSGVhZGVycygpO1xuICAgIGlmIChpbml0LmJvZHkgIT09IHVuZGVmaW5lZCkgdGhpcy5ib2R5ID0gaW5pdC5ib2R5O1xuICAgIGlmICghdGhpcy5ib2R5KSB0aGlzLmJvZHkgPSBudWxsO1xuICAgIHRoaXMuZHVwbGV4ID0gaW5pdC5kdXBsZXggfHwgXCJoYWxmXCI7XG4gIH07XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxUaGlzLlJlcXVlc3QucHJvdG90eXBlLCBcImJvZHlVc2VkXCIsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gZmFsc2U7IH1cbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGdsb2JhbFRoaXMuUmVxdWVzdC5wcm90b3R5cGUsIHtcbiAgICBhcnJheUJ1ZmZlcjogeyB2YWx1ZTogZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwiX19idWlsdGluX3Jlc3BvbnNlX2FycmF5X2J1ZmZlclwiKSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9LFxuICAgIGpzb246IHsgdmFsdWU6IGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXShcIl9fYnVpbHRpbl9yZXNwb25zZV9qc29uXCIpLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0sXG4gICAgdGV4dDogeyB2YWx1ZTogZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwiX19idWlsdGluX3Jlc3BvbnNlX3RleHRcIiksIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSxcbiAgfSk7XG59XG5cbi8vIGNyZWF0ZUhvb2sg4oCUIHJldHVybnMgYSBIb29rIG9iamVjdCB0aGF0IGlzIGJvdGggYSBUaGVuYWJsZSBhbmQgQXN5bmNJdGVyYWJsZS5cbi8vIEVhY2ggYXdhaXQveWllbGQgY3JlYXRlcyBhIG5ldyBwcm9taXNlIGtleWVkIGJ5IHRoZSBzYW1lIGNvcnJlbGF0aW9uSWQuXG4vLyBUaGUgcHJvbWlzZSBpcyByZXNvbHZlZCB3aGVuIGEgaG9va19yZWNlaXZlZCBldmVudCBhcnJpdmVzLlxuZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfQ1JFQVRFX0hPT0tcIildID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgaWYgKG9wdGlvbnMuaXNXZWJob29rID09PSB0cnVlICYmIG9wdGlvbnMuZXhwZXJpbWVudGFsX21pblJldGVudGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdXZWJob29rIGhvb2tzIGRvIG5vdCBzdXBwb3J0IFxcYGV4cGVyaW1lbnRhbF9taW5SZXRlbnRpb25cXGAuIFVzZSBhIG5vbi13ZWJob29rIFxcYGNyZWF0ZUhvb2soKVxcYCB3aXRoIFxcYHJlc3VtZUhvb2soKVxcYC4nKTtcbiAgfVxuICBpZiAob3B0aW9ucy5leHBlcmltZW50YWxfbWluUmV0ZW50aW9uICE9PSB1bmRlZmluZWQgJiYgZ2xvYmFsVGhpcy5fX3dvcmxkQ2FwYWJpbGl0aWVzPy5ob29rUmV0ZW50aW9uPy5hY3RpdmUgIT09IHRydWUpIHtcbiAgICB2YXIgdW5zdXBwb3J0ZWRSZXRlbnRpb25FcnJvciA9IG5ldyBFcnJvcignVGhlIGNvbmZpZ3VyZWQgV29ybGQgZG9lcyBub3Qgc3VwcG9ydCBcXGBleHBlcmltZW50YWxfbWluUmV0ZW50aW9uXFxgIGZvciBIb29rcy4nKTtcbiAgICB1bnN1cHBvcnRlZFJldGVudGlvbkVycm9yLm5hbWUgPSBcIkZhdGFsRXJyb3JcIjtcbiAgICB1bnN1cHBvcnRlZFJldGVudGlvbkVycm9yLmZhdGFsID0gdHJ1ZTtcbiAgICB0aHJvdyB1bnN1cHBvcnRlZFJldGVudGlvbkVycm9yO1xuICB9XG4gIHZhciB0b2tlbiA9IG9wdGlvbnMudG9rZW4gfHwgZ2xvYmFsVGhpcy5fX2dlbmVyYXRlTmFub2lkKCk7XG4gIHZhciBjb3JyZWxhdGlvbklkID0gXCJob29rX1wiICsgZ2xvYmFsVGhpcy5fX2dlbmVyYXRlVWxpZCgpO1xuICB2YXIgaXNEaXNwb3NlZCA9IGZhbHNlO1xuICB2YXIgaGFzQ3JlYXRlZEV2ZW50ID0gZmFsc2U7XG4gIHZhciB0b2tlblJldGVudGlvblVudGlsO1xuICBpZiAob3B0aW9ucy5leHBlcmltZW50YWxfbWluUmV0ZW50aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgbWluUmV0ZW50aW9uID0gb3B0aW9ucy5leHBlcmltZW50YWxfbWluUmV0ZW50aW9uO1xuICAgIGlmICh0eXBlb2YgbWluUmV0ZW50aW9uID09PSBcIm51bWJlclwiKSB7XG4gICAgICBpZiAobWluUmV0ZW50aW9uIDwgMCB8fCAhaXNGaW5pdGUobWluUmV0ZW50aW9uKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGR1cmF0aW9uOiBcIiArIG1pblJldGVudGlvbiArIFwiLiBFeHBlY3RlZCBhIG5vbi1uZWdhdGl2ZSBmaW5pdGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcy5cIik7XG4gICAgICB9XG4gICAgICB0b2tlblJldGVudGlvblVudGlsID0gRGF0ZS5ub3coKSArIG1pblJldGVudGlvbjtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBtaW5SZXRlbnRpb24gPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHZhciByZXRlbnRpb25NcyA9IGdsb2JhbFRoaXMuX19wYXJzZUR1cmF0aW9uTXMobWluUmV0ZW50aW9uKTtcbiAgICAgIGlmICh0eXBlb2YgcmV0ZW50aW9uTXMgIT09IFwibnVtYmVyXCIgfHwgcmV0ZW50aW9uTXMgPCAwIHx8ICFpc0Zpbml0ZShyZXRlbnRpb25NcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGR1cmF0aW9uOiBcIicgKyBtaW5SZXRlbnRpb24gKyAnXCIuIEV4cGVjdGVkIGEgdmFsaWQgZHVyYXRpb24gc3RyaW5nIGxpa2UgXCIxc1wiLCBcIjFtXCIsIFwiMWhcIiwgZXRjLicpO1xuICAgICAgfVxuICAgICAgdG9rZW5SZXRlbnRpb25VbnRpbCA9IERhdGUubm93KCkgKyByZXRlbnRpb25NcztcbiAgICB9IGVsc2UgaWYgKG1pblJldGVudGlvbiBpbnN0YW5jZW9mIERhdGUgfHwgKG1pblJldGVudGlvbiAmJiB0eXBlb2YgbWluUmV0ZW50aW9uLmdldFRpbWUgPT09IFwiZnVuY3Rpb25cIikpIHtcbiAgICAgIC8vIEFjY2VwdCBEYXRlLWxpa2Ugb2JqZWN0cyAoYW55dGhpbmcgd2l0aCBnZXRUaW1lKSwgbWF0Y2hpbmdcbiAgICAgIC8vIHBhcnNlRHVyYXRpb25Ub0RhdGU6IHZhbHVlcyB0aGF0IGNyb3NzZWQgdGhlIHNlcmRlIGJvdW5kYXJ5IG1heVxuICAgICAgLy8gbm90IGJlIHJlYWxtLW5hdGl2ZSBEYXRlIGluc3RhbmNlcy5cbiAgICAgIHRva2VuUmV0ZW50aW9uVW50aWwgPSBtaW5SZXRlbnRpb24uZ2V0VGltZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGR1cmF0aW9uIHBhcmFtZXRlci4gRXhwZWN0ZWQgYSBkdXJhdGlvbiBzdHJpbmcsIG51bWJlciAobWlsbGlzZWNvbmRzKSwgb3IgRGF0ZSBvYmplY3QuXCIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJlZ2lzdGVyIGluIHBlbmRpbmcgb3BlcmF0aW9ucy5cbiAgLy8gU2VyaWFsaXplIG1ldGFkYXRhIGluc2lkZSB0aGUgVk0gc28gUmVzcG9uc2UvUmVxdWVzdCBvYmplY3RzIGFyZVxuICAvLyBwcm9wZXJseSBoYW5kbGVkIGJ5IHRoZSBkZXZhbHVlIHJlZHVjZXJzIGJlZm9yZSBjcm9zc2luZyB0aGUgYm91bmRhcnkuXG4gIHZhciBwZW5kaW5nT3AgPSB7XG4gICAgdHlwZTogXCJob29rXCIsXG4gICAgY29ycmVsYXRpb25JZDogY29ycmVsYXRpb25JZCxcbiAgICB0b2tlbjogdG9rZW4sXG4gICAgdG9rZW5SZXRlbnRpb25VbnRpbDogdG9rZW5SZXRlbnRpb25VbnRpbCxcbiAgICBpc1dlYmhvb2s6ICEhb3B0aW9ucy5pc1dlYmhvb2ssXG4gICAgbWV0YWRhdGE6IG9wdGlvbnMubWV0YWRhdGEgPyBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJ3b3JrZmxvdy1zZXJpYWxpemVcIildKG9wdGlvbnMubWV0YWRhdGEpIDogdW5kZWZpbmVkLFxuICAgIGhhc0NyZWF0ZWRFdmVudDogZmFsc2UsXG4gIH07XG4gIGdsb2JhbFRoaXMuX19wZW5kaW5nLnB1c2gocGVuZGluZ09wKTtcblxuICAvLyBQZXItaG9vayBsaWZlY3ljbGUgc3RhdGUgYmFja2luZyBob29rLmdldENvbmZsaWN0KCk6IHJlc29sdmVzIG51bGxcbiAgLy8gb25jZSBjcmVhdGlvbiBpcyBjb25maXJtZWQgKGhvb2tfY3JlYXRlZCksIG9yIHJlc29sdmVzIHdpdGggdGhlXG4gIC8vIGNvbmZsaWN0aW5nIFJ1biBoYW5kbGUgLyByZWplY3RzIHdpdGggSG9va0NvbmZsaWN0RXJyb3Igb25cbiAgLy8gaG9va19jb25mbGljdC4gU3RhdGUgdHJhbnNpdGlvbnMgYXJlIGRyaXZlbiBieSB0aGUgaG9zdCBkdXJpbmcgZXZlbnRcbiAgLy8gcHJvY2Vzc2luZyAoc2VlIHByb2Nlc3NFdmVudHMpLlxuICBnbG9iYWxUaGlzLl9faG9va3MgPSBnbG9iYWxUaGlzLl9faG9va3MgfHwge307XG4gIGdsb2JhbFRoaXMuX19ob29rc1tjb3JyZWxhdGlvbklkXSA9IHtcbiAgICB0b2tlbjogdG9rZW4sXG4gICAgY3JlYXRlZDogZmFsc2UsXG4gICAgY29uZmxpY3Q6IG51bGwsXG4gICAgZ2V0Q29uZmxpY3RSZXNvbHZlcnM6IFtdLFxuICB9O1xuXG4gIC8vIEVhY2ggYXdhaXQgY3JlYXRlcyBhIG5ldyBwcm9taXNlIGZvciB0aGUgbmV4dCBwYXlsb2FkLlxuICAvLyBUaGUgY29ycmVsYXRpb25JZCBzdGF5cyB0aGUgc2FtZSDigJQgdGhlIHJlc29sdmVyIGlzIHJlcGxhY2VkIGVhY2ggdGltZS5cbiAgZnVuY3Rpb24gY3JlYXRlSG9va1Byb21pc2UoKSB7XG4gICAgLy8gQ2hlY2sgdGhlIHBheWxvYWQgYnVmZmVyIGZpcnN0IOKAlCBpZiBhIGhvb2tfcmVjZWl2ZWQgZXZlbnQgYXJyaXZlZFxuICAgIC8vIGJlZm9yZSB0aGlzIGhvb2sgd2FzIGF3YWl0ZWQsIHRoZSBwYXlsb2FkIHdhcyBidWZmZXJlZCBpbiB0aGUgVk1cbiAgICAvLyBoZWFwLiBEcmFpbiBpdCBpbW1lZGlhdGVseSAobWF0Y2hpbmcgZXZlbnQtcmVwbGF5IHBheWxvYWRzUXVldWUpLlxuICAgIHZhciBidWYgPSBnbG9iYWxUaGlzLl9faG9va1BheWxvYWRCdWZmZXJbY29ycmVsYXRpb25JZF07XG4gICAgaWYgKGJ1ZiAmJiBidWYubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShidWYuc2hpZnQoKSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbY29ycmVsYXRpb25JZF0gPSB7IHJlc29sdmU6IHJlc29sdmUsIHJlamVjdDogcmVqZWN0IH07XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBkaXNwb3NlSG9vaygpIHtcbiAgICBpZiAoaXNEaXNwb3NlZCkgcmV0dXJuO1xuICAgIGlzRGlzcG9zZWQgPSB0cnVlO1xuICAgIC8vIEEgY29uZmxpY3RlZCBob29rIHdhcyBuZXZlciBjcmVhdGVkICh0aGUgd29ybGQgcmVqZWN0ZWQgaXRzIGNsYWltXG4gICAgLy8g4oCUIHRoZSB0b2tlbiBiZWxvbmdzIHRvIGFub3RoZXIgcnVuKSwgc28gdGhlcmUgaXMgbm8gZW50aXR5IHRvXG4gICAgLy8gZGlzcG9zZS4gTWlycm9ycyB0aGUgbm9kZTp2bSBlbmdpbmUsIHdoZXJlIGhvb2tfY29uZmxpY3QgcmVtb3Zlc1xuICAgIC8vIHRoZSBpbnZvY2F0aW9uLXF1ZXVlIGl0ZW0gYmVmb3JlIGRpc3Bvc2UgY2FuIG1hcmsgaXQuIEVtaXR0aW5nIGFcbiAgICAvLyBob29rX2Rpc3Bvc2VkIGhlcmUgd291bGQgYmUgcmVqZWN0ZWQgYnkgdGhlIHdvcmxkJ3NcbiAgICAvLyBob29rLWV4aXN0ZW5jZSB2YWxpZGF0aW9uLlxuICAgIHZhciBzdGF0ZSA9IGdsb2JhbFRoaXMuX19ob29rc1tjb3JyZWxhdGlvbklkXTtcbiAgICBpZiAoIXN0YXRlIHx8ICFzdGF0ZS5jb25mbGljdCkge1xuICAgICAgLy8gU2lnbmFsIHRvIHRoZSBlbnRyeXBvaW50IHRvIGNyZWF0ZSBhIGhvb2tfZGlzcG9zZWQgZXZlbnQuIFRoZVxuICAgICAgLy8gdG9rZW4gaXMgY2FycmllZCBzbyB0aGUgZW50cnlwb2ludCBjYW4gb3JkZXIgc2FtZS10b2tlbiBob29rXG4gICAgICAvLyBvcGVyYXRpb25zIHNlcXVlbnRpYWxseSAoYSBkaXNwb3NlIG11c3QgcmVsZWFzZSB0aGUgdG9rZW4gYmVmb3JlXG4gICAgICAvLyBhIGxhdGVyIHNhbWUtdG9rZW4gaG9vaydzIGNyZWF0aW9uIGlzIHZhbGlkYXRlZCkuXG4gICAgICBnbG9iYWxUaGlzLl9fcGVuZGluZy5wdXNoKHtcbiAgICAgICAgdHlwZTogXCJob29rX2Rpc3Bvc2VcIixcbiAgICAgICAgY29ycmVsYXRpb25JZDogY29ycmVsYXRpb25JZCxcbiAgICAgICAgdG9rZW46IHRva2VuLFxuICAgICAgICBoYXNDcmVhdGVkRXZlbnQ6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgfVxuICAgIC8vIElmIHRoZXJlJ3MgYSBwZW5kaW5nIHJlc29sdmVyLCByZXNvbHZlIGl0IHdpdGggdW5kZWZpbmVkIHRvIGJyZWFrIHRoZSBpdGVyYXRvclxuICAgIGlmIChnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzW2NvcnJlbGF0aW9uSWRdKSB7XG4gICAgICBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzW2NvcnJlbGF0aW9uSWRdLnJlc29sdmUodW5kZWZpbmVkKTtcbiAgICAgIGRlbGV0ZSBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzW2NvcnJlbGF0aW9uSWRdO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGdldENvbmZsaWN0KCkge1xuICAgIHZhciBzdGF0ZSA9IGdsb2JhbFRoaXMuX19ob29rc1tjb3JyZWxhdGlvbklkXTtcbiAgICBpZiAoc3RhdGUuY29uZmxpY3QpIHtcbiAgICAgIHJldHVybiBzdGF0ZS5jb25mbGljdC5ydW5cbiAgICAgICAgPyBQcm9taXNlLnJlc29sdmUoc3RhdGUuY29uZmxpY3QucnVuKVxuICAgICAgICA6IFByb21pc2UucmVqZWN0KHN0YXRlLmNvbmZsaWN0LmVycm9yKTtcbiAgICB9XG4gICAgaWYgKHN0YXRlLmNyZWF0ZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG4gICAgfVxuICAgIC8vIENyZWF0aW9uIG5vdCB5ZXQgY29uZmlybWVkIGJ5IHRoZSBldmVudCBsb2cg4oCUIHBhcmsgdGhlIGF3YWl0ZXIgYW5kXG4gICAgLy8gZmxhZyB0aGUgcGVuZGluZyBvcCBzbyB0aGUgZW50cnlwb2ludCByZS1pbnZva2VzIHRoZSB3b3JrZmxvdyByaWdodFxuICAgIC8vIGFmdGVyIHdyaXRpbmcgaG9va19jcmVhdGVkIChub3RoaW5nIGV4dGVybmFsIHJlc3VtZXMgYSBnZXRDb25mbGljdFxuICAgIC8vIGF3YWl0ZXI7IGNvbmZpcm1hdGlvbiBvbmx5IGNvbWVzIGZyb20gcmVwbGF5aW5nIHRoZSBuZXcgZXZlbnQpLlxuICAgIHBlbmRpbmdPcC5oYXNHZXRDb25mbGljdEF3YWl0ZXIgPSB0cnVlO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHN0YXRlLmdldENvbmZsaWN0UmVzb2x2ZXJzLnB1c2goeyByZXNvbHZlOiByZXNvbHZlLCByZWplY3Q6IHJlamVjdCB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHZhciBob29rID0ge1xuICAgIHRva2VuOiB0b2tlbixcbiAgICB0aGVuOiBmdW5jdGlvbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICAgICAgcmV0dXJuIGNyZWF0ZUhvb2tQcm9taXNlKCkudGhlbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCk7XG4gICAgfSxcbiAgICBnZXRDb25mbGljdDogZ2V0Q29uZmxpY3QsXG4gICAgZGlzcG9zZTogZGlzcG9zZUhvb2ssXG4gIH07XG5cbiAgLy8gU3ltYm9sLmRpc3Bvc2UgZm9yIGV4cGxpY2l0IHJlc291cmNlIG1hbmFnZW1lbnRcbiAgaG9va1tTeW1ib2wuZGlzcG9zZV0gPSBkaXNwb3NlSG9vaztcblxuICAvLyBBc3luY0l0ZXJhYmxlIOKAlCB5aWVsZHMgcGF5bG9hZHMgdW50aWwgZGlzcG9zZWRcbiAgaG9va1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmV4dDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmIChpc0Rpc3Bvc2VkKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNyZWF0ZUhvb2tQcm9taXNlKCkudGhlbihmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgIC8vIElmIGRpc3Bvc2VkIHdoaWxlIHdhaXRpbmcsIHNpZ25hbCBkb25lXG4gICAgICAgICAgaWYgKGlzRGlzcG9zZWQpIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcbiAgICAgICAgICByZXR1cm4geyBkb25lOiBmYWxzZSwgdmFsdWU6IHZhbHVlIH07XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIHJldHVybjogZnVuY3Rpb24oKSB7XG4gICAgICAgIGRpc3Bvc2VIb29rKCk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyBkb25lOiB0cnVlLCB2YWx1ZTogdW5kZWZpbmVkIH0pO1xuICAgICAgfSxcbiAgICB9O1xuICB9O1xuXG4gIHJldHVybiBob29rO1xufTtcblxuLy8gc2V0QXR0cmlidXRlcyDigJQgYXR0YWNoZXMgcGxhaW50ZXh0IG1ldGFkYXRhIHRvIHRoZSBjdXJyZW50IHJ1bi5cbi8vIFZhbGlkYXRpb24gaGFwcGVucyBpbiBsaWJyYXJ5IGNvZGUgKG5vcm1hbGl6ZUF0dHJpYnV0ZUNoYW5nZXMpIGJlZm9yZVxuLy8gdGhpcyBkaXNwYXRjaGVyIGlzIGludm9rZWQsIHNvIFwiY2hhbmdlc1wiIGlzIGFscmVhZHkgbm9ybWFsaXplZC4gVGhlXG4vLyByZXR1cm5lZCBwcm9taXNlIHJlc29sdmVzIHdoZW4gdGhlIG1hdGNoaW5nIGF0dHJfc2V0IGV2ZW50IGlzXG4vLyBvYnNlcnZlZCBkdXJpbmcgZXZlbnQgcHJvY2Vzc2luZyDigJQgbWlycm9yaW5nIHRoZSBub2RlOnZtIGVuZ2luZSdzXG4vLyBjcmVhdGVTZXRBdHRyaWJ1dGVzIChhdHRyaWJ1dGUtZGlzcGF0Y2hlci50cykuXG5nbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19TRVRfQVRUUklCVVRFU1wiKV0gPSBmdW5jdGlvbihjaGFuZ2VzLCBvcHRpb25zKSB7XG4gIHZhciBjb3JyZWxhdGlvbklkID0gXCJhdHRyX1wiICsgZ2xvYmFsVGhpcy5fX2dlbmVyYXRlVWxpZCgpO1xuICBnbG9iYWxUaGlzLl9fcGVuZGluZy5wdXNoKHtcbiAgICB0eXBlOiBcImF0dHJpYnV0ZVwiLFxuICAgIGNvcnJlbGF0aW9uSWQ6IGNvcnJlbGF0aW9uSWQsXG4gICAgY2hhbmdlczogY2hhbmdlcyxcbiAgICBhbGxvd1Jlc2VydmVkQXR0cmlidXRlczogISEob3B0aW9ucyAmJiBvcHRpb25zLmFsbG93UmVzZXJ2ZWRBdHRyaWJ1dGVzKSxcbiAgICBoYXNDcmVhdGVkRXZlbnQ6IGZhbHNlLFxuICB9KTtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGdsb2JhbFRoaXMuX19yZWdpc3RlclJlc29sdmVyKGNvcnJlbGF0aW9uSWQsIHJlc29sdmUsIHJlamVjdCk7XG4gIH0pO1xufTtcblxuLy8gLS0tLSBBYm9ydENvbnRyb2xsZXIgLyBBYm9ydFNpZ25hbCAoaG9vay1iYWNrZWQpIC0tLS1cbi8vIFBvcnQgb2Ygd29ya2Zsb3cvYWJvcnQtY29udHJvbGxlci50cyB0byB0aGUgVk0gcGVuZGluZy1vcCBtb2RlbDpcbi8vIHRoZSBjb250cm9sbGVyIHJlZ2lzdGVycyBhIHN5c3RlbSBob29rOyBhYm9ydCgpIGZsaXBzIHRoZSBzaWduYWxcbi8vIHN5bmNocm9ub3VzbHkgYW5kIG1hcmtzIHRoZSBwZW5kaW5nIG9wIHNvIHRoZSBob3N0IHJlY29yZHMgdGhlIGFib3J0XG4vLyAoaG9va19yZWNlaXZlZCBldmVudCArIHN0cmVhbSBwYWNrZXQpLiBPbiByZXBsYXksIHRoZSByZWNvcmRlZFxuLy8gaG9va19yZWNlaXZlZCBldmVudCBjYWxscyBfc2V0QWJvcnRlZCBkdXJpbmcgZXZlbnQgcHJvY2Vzc2luZyBhbmQgdGhlXG4vLyB3b3JrZmxvdydzIG93biBhYm9ydCgpIGNhbGwgYmVjb21lcyBhIG5vLW9wLlxudmFyIF9fQUJPUlRfU1RSRUFNX05BTUUgPSBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfQUJPUlRfU1RSRUFNX05BTUVcIik7XG52YXIgX19BQk9SVF9IT09LX1RPS0VOID0gU3ltYm9sLmZvcihcIldPUktGTE9XX0FCT1JUX0hPT0tfVE9LRU5cIik7XG5cbmZ1bmN0aW9uIF9fbWFrZUFib3J0RXJyb3IoKSB7XG4gIGlmICh0eXBlb2YgRE9NRXhjZXB0aW9uICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgcmV0dXJuIG5ldyBET01FeGNlcHRpb24oXCJUaGUgb3BlcmF0aW9uIHdhcyBhYm9ydGVkLlwiLCBcIkFib3J0RXJyb3JcIik7XG4gIH1cbiAgdmFyIGUgPSBuZXcgRXJyb3IoXCJUaGUgb3BlcmF0aW9uIHdhcyBhYm9ydGVkLlwiKTtcbiAgZS5uYW1lID0gXCJBYm9ydEVycm9yXCI7XG4gIHJldHVybiBlO1xufVxuXG5mdW5jdGlvbiBXb3JrZmxvd0Fib3J0U2lnbmFsKHN0cmVhbU5hbWUsIGhvb2tUb2tlbikge1xuICB0aGlzLmFib3J0ZWQgPSBmYWxzZTtcbiAgdGhpcy5yZWFzb24gPSB1bmRlZmluZWQ7XG4gIHRoaXNbX19BQk9SVF9TVFJFQU1fTkFNRV0gPSBzdHJlYW1OYW1lO1xuICB0aGlzW19fQUJPUlRfSE9PS19UT0tFTl0gPSBob29rVG9rZW47XG4gIHRoaXMuX19saXN0ZW5lcnMgPSBbXTtcbiAgdGhpcy5fX29uYWJvcnQgPSBudWxsO1xufVxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFdvcmtmbG93QWJvcnRTaWduYWwucHJvdG90eXBlLCBcIm9uYWJvcnRcIiwge1xuICBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5fX29uYWJvcnQ7IH0sXG4gIHNldDogZnVuY3Rpb24oaGFuZGxlcikge1xuICAgIHRoaXMuX19vbmFib3J0ID0gaGFuZGxlcjtcbiAgICBpZiAoaGFuZGxlciAmJiB0aGlzLmFib3J0ZWQpIGhhbmRsZXIuY2FsbCh0aGlzKTtcbiAgfSxcbn0pO1xuV29ya2Zsb3dBYm9ydFNpZ25hbC5wcm90b3R5cGUuX3NldEFib3J0ZWQgPSBmdW5jdGlvbihyZWFzb24pIHtcbiAgaWYgKHRoaXMuYWJvcnRlZCkgcmV0dXJuO1xuICB0aGlzLmFib3J0ZWQgPSB0cnVlO1xuICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgaWYgKHRoaXMuX19vbmFib3J0KSB0aGlzLl9fb25hYm9ydC5jYWxsKHRoaXMpO1xuICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fX2xpc3RlbmVycztcbiAgdGhpcy5fX2xpc3RlbmVycyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykgbGlzdGVuZXJzW2ldKCk7XG59O1xuV29ya2Zsb3dBYm9ydFNpZ25hbC5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlICE9PSBcImFib3J0XCIpIHJldHVybjtcbiAgaWYgKHRoaXMuYWJvcnRlZCkge1xuICAgIC8vIEZpcmUgc3luY2hyb25vdXNseSAobm90IG9uIGEgbWljcm90YXNrKSBmb3IgZGV0ZXJtaW5pc3RpYyByZXBsYXkg4oCUXG4gICAgLy8gbWF0Y2hlcyB0aGUgbm9kZTp2bSBlbmdpbmUncyBXb3JrZmxvd0Fib3J0U2lnbmFsLlxuICAgIGxpc3RlbmVyKCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRoaXMuX19saXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG59O1xuV29ya2Zsb3dBYm9ydFNpZ25hbC5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlICE9PSBcImFib3J0XCIpIHJldHVybjtcbiAgdGhpcy5fX2xpc3RlbmVycyA9IHRoaXMuX19saXN0ZW5lcnMuZmlsdGVyKGZ1bmN0aW9uKGwpIHsgcmV0dXJuIGwgIT09IGxpc3RlbmVyOyB9KTtcbn07XG5Xb3JrZmxvd0Fib3J0U2lnbmFsLnByb3RvdHlwZS50aHJvd0lmQWJvcnRlZCA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5hYm9ydGVkKSB7XG4gICAgdGhyb3cgdGhpcy5yZWFzb24gIT09IHVuZGVmaW5lZCAmJiB0aGlzLnJlYXNvbiAhPT0gbnVsbFxuICAgICAgPyB0aGlzLnJlYXNvblxuICAgICAgOiBfX21ha2VBYm9ydEVycm9yKCk7XG4gIH1cbn07XG4vLyBFeHBvc2UgZm9yIHRoZSBzZXJkZSBidW5kbGUncyByZXZpdmVycyAoZXZhbHVhdGVkIGJlZm9yZSB0aGlzIGJvb3RzdHJhcDtcbi8vIHRoZXkgbG9vayB0aGUgY2xhc3MgdXAgbGF6aWx5IGF0IHJldml2ZSB0aW1lKS5cbmdsb2JhbFRoaXMuX19Xb3JrZmxvd0Fib3J0U2lnbmFsID0gV29ya2Zsb3dBYm9ydFNpZ25hbDtcblxuLy8gUmVnaXN0cnkgb2YgbGl2ZSBhYm9ydCBzaWduYWxzIGtleWVkIGJ5IHRoZWlyIGhvb2sgY29ycmVsYXRpb25JZC4gVGhlXG4vLyBob3N0IGRlbGl2ZXJzIGhvb2tfcmVjZWl2ZWQgZXZlbnRzIGZvciB0aGVzZSBpZHMgYXMgX3NldEFib3J0ZWQgY2FsbHMuXG5nbG9iYWxUaGlzLl9fYWJvcnRTaWduYWxzID0ge307XG5cbmdsb2JhbFRoaXMuQWJvcnRDb250cm9sbGVyID0gZnVuY3Rpb24gV29ya2Zsb3dBYm9ydENvbnRyb2xsZXIoKSB7XG4gIHZhciBpZCA9IGdsb2JhbFRoaXMuX19nZW5lcmF0ZVVsaWQoKTtcbiAgdmFyIHN0cmVhbU5hbWUgPSBcInN0cm1fXCIgKyBpZCArIFwiX3N5c3RlbV9hYm9ydFwiO1xuICB2YXIgaG9va1Rva2VuID0gXCJhYnJ0X1wiICsgaWQ7XG4gIHRoaXNbX19BQk9SVF9TVFJFQU1fTkFNRV0gPSBzdHJlYW1OYW1lO1xuICB0aGlzW19fQUJPUlRfSE9PS19UT0tFTl0gPSBob29rVG9rZW47XG4gIHRoaXMuc2lnbmFsID0gbmV3IFdvcmtmbG93QWJvcnRTaWduYWwoc3RyZWFtTmFtZSwgaG9va1Rva2VuKTtcbiAgdmFyIGNvcnJlbGF0aW9uSWQgPSBcImhvb2tfXCIgKyBnbG9iYWxUaGlzLl9fZ2VuZXJhdGVVbGlkKCk7XG4gIC8vIFJlZ2lzdGVyIGFuIGludGVybmFsIHN5c3RlbSBob29rLiBpc1N5c3RlbSBwcmV2ZW50cyB0b2tlbiBuYW1lc3BhY2VcbiAgLy8gY29uZmxpY3RzIHdpdGggdXNlciBob29rcy5cbiAgZ2xvYmFsVGhpcy5fX3BlbmRpbmcucHVzaCh7XG4gICAgdHlwZTogXCJob29rXCIsXG4gICAgY29ycmVsYXRpb25JZDogY29ycmVsYXRpb25JZCxcbiAgICB0b2tlbjogaG9va1Rva2VuLFxuICAgIGlzV2ViaG9vazogZmFsc2UsXG4gICAgaXNTeXN0ZW06IHRydWUsXG4gICAgaGFzQ3JlYXRlZEV2ZW50OiBmYWxzZSxcbiAgfSk7XG4gIGdsb2JhbFRoaXMuX19hYm9ydFNpZ25hbHNbY29ycmVsYXRpb25JZF0gPSB0aGlzLnNpZ25hbDtcbn07XG5nbG9iYWxUaGlzLkFib3J0Q29udHJvbGxlci5wcm90b3R5cGUuYWJvcnQgPSBmdW5jdGlvbihyZWFzb24pIHtcbiAgaWYgKHRoaXMuc2lnbmFsLmFib3J0ZWQpIHJldHVybjsgLy8gYWxyZWFkeSBhYm9ydGVkIChlLmcuIGZyb20gcmVwbGF5KVxuICB0aGlzLnNpZ25hbC5fc2V0QWJvcnRlZChyZWFzb24pO1xuICAvLyBNYXJrIHRoZSBwZW5kaW5nIGhvb2sgb3Agc28gdGhlIGhvc3QgcmVjb3JkcyB0aGUgYWJvcnQuIFRoZSBwYXlsb2FkXG4gIC8vIGlzIHNlcmlhbGl6ZWQgaW4gdGhlIFZNIHNvIHRoZSByZWFzb24gY3Jvc3NlcyB0aGUgYm91bmRhcnkgd2l0aFxuICAvLyB0eXBlIGZpZGVsaXR5IChFcnJvcnMsIERPTUV4Y2VwdGlvbiwgY3VzdG9tIHZhbHVlcykuXG4gIHZhciB0b2tlbiA9IHRoaXNbX19BQk9SVF9IT09LX1RPS0VOXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBnbG9iYWxUaGlzLl9fcGVuZGluZy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpdGVtID0gZ2xvYmFsVGhpcy5fX3BlbmRpbmdbaV07XG4gICAgaWYgKGl0ZW0udHlwZSA9PT0gXCJob29rXCIgJiYgaXRlbS50b2tlbiA9PT0gdG9rZW4pIHtcbiAgICAgIGl0ZW0uYWJvcnRSZXF1ZXN0ZWQgPSB0cnVlO1xuICAgICAgaXRlbS5hYm9ydFBheWxvYWQgPSBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJ3b3JrZmxvdy1zZXJpYWxpemVcIildKHtcbiAgICAgICAgYWJvcnRlZDogdHJ1ZSxcbiAgICAgICAgcmVhc29uOiByZWFzb24sXG4gICAgICB9KTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufTtcblxuZ2xvYmFsVGhpcy5BYm9ydFNpZ25hbCA9IHtcbiAgYWJvcnQ6IGZ1bmN0aW9uKHJlYXNvbikge1xuICAgIHZhciBzID0gbmV3IFdvcmtmbG93QWJvcnRTaWduYWwoXCJcIiwgXCJcIik7XG4gICAgcy5fc2V0QWJvcnRlZChyZWFzb24gIT09IHVuZGVmaW5lZCA/IHJlYXNvbiA6IF9fbWFrZUFib3J0RXJyb3IoKSk7XG4gICAgcmV0dXJuIHM7XG4gIH0sXG4gIGFueTogZnVuY3Rpb24oc2lnbmFscykge1xuICAgIHZhciBjb21wb3NpdGUgPSBuZXcgV29ya2Zsb3dBYm9ydFNpZ25hbChcIlwiLCBcIlwiKTtcbiAgICB2YXIgYXJyID0gQXJyYXkuZnJvbShzaWduYWxzKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFycltpXS5hYm9ydGVkKSB7XG4gICAgICAgIGNvbXBvc2l0ZS5fc2V0QWJvcnRlZChhcnJbaV0ucmVhc29uKTtcbiAgICAgICAgcmV0dXJuIGNvbXBvc2l0ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIGxpc3RlbmVycyA9IFtdO1xuICAgIHZhciBjbGVhbnVwID0gZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxpc3RlbmVycy5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAobGlzdGVuZXJzW2pdLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgbGlzdGVuZXJzW2pdLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgbGlzdGVuZXJzW2pdLmxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGlzdGVuZXJzLmxlbmd0aCA9IDA7XG4gICAgfTtcbiAgICBhcnIuZm9yRWFjaChmdW5jdGlvbihzaWduYWwpIHtcbiAgICAgIGlmICghc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIpIHJldHVybjtcbiAgICAgIHZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoIWNvbXBvc2l0ZS5hYm9ydGVkKSB7XG4gICAgICAgICAgY29tcG9zaXRlLl9zZXRBYm9ydGVkKHNpZ25hbC5yZWFzb24pO1xuICAgICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGxpc3RlbmVycy5wdXNoKHsgc2lnbmFsOiBzaWduYWwsIGxpc3RlbmVyOiBsaXN0ZW5lciB9KTtcbiAgICAgIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgbGlzdGVuZXIpO1xuICAgIH0pO1xuICAgIHJldHVybiBjb21wb3NpdGU7XG4gIH0sXG4gIHRpbWVvdXQ6IGZ1bmN0aW9uKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIFwiQWJvcnRTaWduYWwudGltZW91dCgpIGlzIG5vdCBzdXBwb3J0ZWQgaW4gd29ya2Zsb3cgZnVuY3Rpb25zLiBcIiArXG4gICAgICAgIFwiVXNlIHNsZWVwKCkgd2l0aCBhbiBBYm9ydENvbnRyb2xsZXIgaW5zdGVhZC4gXCIgK1xuICAgICAgICBcIlNlZTogL2RvY3MvZXJyb3JzL2Fib3J0LXNpZ25hbC10aW1lb3V0LWluLXdvcmtmbG93XCJcbiAgICApO1xuICB9LFxufTtcblxuLy8gV09SS0ZMT1dfR0VUX1NUUkVBTV9JRCDigJQgZ2VuZXJhdGVzIGEgc3RyZWFtIElEIGZvciBhIHdvcmtmbG93IHJ1bi5cbi8vIFJlcGxpY2F0ZXMgZ2V0V29ya2Zsb3dSdW5TdHJlYW1JZCgpIGZyb20gdXRpbC50cyBpbnNpZGUgdGhlIFF1aWNrSlMgVk0uXG4vLyBVc2VzIHRoZSBidWlsdC1pbiBidG9hKCkgZm9yIGJhc2U2NHVybCBlbmNvZGluZy5cbmdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX0dFVF9TVFJFQU1fSURcIildID0gZnVuY3Rpb24obmFtZXNwYWNlKSB7XG4gIHZhciBydW5JZCA9IGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX0NPTlRFWFRcIildXG4gICAgPyBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19DT05URVhUXCIpXS53b3JrZmxvd1J1bklkXG4gICAgOiBcIlwiO1xuICB2YXIgc3RyZWFtSWQgPSBydW5JZC5yZXBsYWNlKFwid3J1bl9cIiwgXCJzdHJtX1wiKSArIFwiX3VzZXJcIjtcbiAgaWYgKCFuYW1lc3BhY2UpIHJldHVybiBzdHJlYW1JZDtcbiAgLy8gYmFzZTY0dXJsOiBidG9hIHRoZW4gcmVwbGFjZSArIHdpdGggLSwgLyB3aXRoIF8sIHN0cmlwID1cbiAgdmFyIGI2NCA9IGJ0b2EobmFtZXNwYWNlKS5yZXBsYWNlKC9cXFxcKy9nLCBcIi1cIikucmVwbGFjZSgvXFxcXC8vZywgXCJfXCIpLnJlcGxhY2UoLz0rJC8sIFwiXCIpO1xuICByZXR1cm4gc3RyZWFtSWQgKyBcIl9cIiArIGI2NDtcbn07XG5gO1xuXG4vLyAtLS0tIFJ1bnRpbWUgLS0tLVxuXG4vKipcbiAqIFBoYXNlIDEg4oCUIHN0YXRpYyAocnVuLWluZGVwZW5kZW50KSBWTSBpbml0aWFsaXphdGlvbi5cbiAqXG4gKiBDcmVhdGVzIGEgUXVpY2tKUyBWTSBhbmQgbG9hZHMgZXZlcnl0aGluZyB0aGF0IGRvZXMgbm90IGRlcGVuZCBvbiBhXG4gKiBzcGVjaWZpYyB3b3JrZmxvdyBydW46IHRoZSBzZXJkZSBidW5kbGUgKGRldmFsdWUtYmFzZWQgc2VyaWFsaXphdGlvblxuICogdXNlZCBhdCB0aGUgaG9zdC9WTSBib3VuZGFyeSkgYW5kIHRoZSB3b3JrZmxvdy1wcmltaXRpdmUgYm9vdHN0cmFwXG4gKiAodXNlU3RlcCAvIHNsZWVwIC8gY3JlYXRlSG9vayAvIFJlc3BvbnNlLVJlcXVlc3QgcG9seWZpbGxzKS5cbiAqXG4gKiBgZ2V0Tm93TXNgIGJhY2tzIHRoZSBWTSdzIFdBU0kgY2xvY2sgKGBEYXRlLm5vdygpYCAvIGBuZXcgRGF0ZSgpYFxuICogaW5zaWRlIHRoZSBWTSkuIFRoZSBjYWxsYmFjayBpdHNlbGYgaXMgc3RhdGljIOKAlCB0aGUgcGVyLXJ1biBzdGF0ZSBpdFxuICogcmVhZHMgbGl2ZXMgb24gdGhlIGhvc3QgYW5kIGlzIGFkdmFuY2VkIGFzIGV2ZW50cyBhcmUgY29uc3VtZWQsXG4gKiBtYXRjaGluZyB0aGUgbm9kZTp2bSBlbmdpbmUncyBkZXRlcm1pbmlzdGljIHJlcGxheSBjbG9jay5cbiAqXG4gKiBUaGlzIHBoYXNlIGlzIHRoZSBmdXR1cmUgYm91bmRhcnkgZm9yIFZNLW1lbW9yeSBzbmFwc2hvdHRpbmc6IGFcbiAqIGJ1aWxkLXRpbWUgc25hcHNob3QgY2FuIGNhcHR1cmUgdGhlIFZNIHJpZ2h0IGFmdGVyIHRoaXMgZnVuY3Rpb24gYW5kXG4gKiBuZXcgcnVucyBjYW4gcmVzdG9yZSBmcm9tIGl0IGluc3RlYWQgb2YgcGF5aW5nIFZNIGNyZWF0aW9uICsgZXZhbCBjb3N0XG4gKiAoYFF1aWNrSlMucmVzdG9yZWAgYWNjZXB0cyB0aGUgc2FtZSB3YXNpIG92ZXJyaWRlKS5cbiAqL1xuLyoqXG4gKiBMb29zZWx5LXR5cGVkIGFjY2Vzc29yIGZvciB0aGUgYFdlYkFzc2VtYmx5YCBnbG9iYWwuIFRoZSBwYWNrYWdlXG4gKiB0c2NvbmZpZydzIGBsaWI6IFtcImVzMjAyMlwiXWAgZG9lcyBub3QgaW5jbHVkZSB0aGUgRE9NIGxpYiB3aGVyZSB0aGVcbiAqIGBXZWJBc3NlbWJseWAgbmFtZXNwYWNlIHR5cGVzIGxpdmU7IHRoZSBydW50aW1lIGdsb2JhbCBpcyBhdmFpbGFibGUgb25cbiAqIGV2ZXJ5IFdBU00tY2FwYWJsZSBwbGF0Zm9ybSB0aGlzIGVuZ2luZSB0YXJnZXRzLlxuICovXG5jb25zdCBXZWJBc3NlbWJseUdsb2JhbCA9IChnbG9iYWxUaGlzIGFzIGFueSkuV2ViQXNzZW1ibHkgYXMge1xuICBjb21waWxlKGJ5dGVzOiBVaW50OEFycmF5KTogUHJvbWlzZTxvYmplY3Q+O1xufTtcblxudHlwZSBDb21waWxlZEV4dGVuc2lvbiA9IE9taXQ8RXh0ZW5zaW9uRGVzY3JpcHRvciwgJ3dhc20nPiAmIHtcbiAgd2FzbTogRXh0ZW5zaW9uRGVzY3JpcHRvclsnd2FzbSddO1xufTtcblxuLyoqXG4gKiBQcm9jZXNzLXdpZGUgY2FjaGUgb2YgdGhlIGNvbXBpbGVkIGBXZWJBc3NlbWJseS5Nb2R1bGVgcyBmb3IgdGhlIG1haW5cbiAqIFF1aWNrSlMgcnVudGltZSBhbmQgaXRzIG5hdGl2ZSBleHRlbnNpb25zLiBgV2ViQXNzZW1ibHkuY29tcGlsZWAgb2YgdGhlXG4gKiB+NjAwIEtCIHJ1bnRpbWUgYmluYXJ5IGlzIHRoZSBtb3N0IGV4cGVuc2l2ZSBwYXJ0IG9mIFZNIGNyZWF0aW9uIGFuZCBpc1xuICogcHVyZSAobm8gcGVyLVZNIHN0YXRlIOKAlCBpbnN0YW50aWF0aW9uIGJpbmRzIHRoZSBwZXItVk0gbWVtb3J5KSwgc28gaXRcbiAqIG9ubHkgbmVlZHMgdG8gaGFwcGVuIG9uY2UgcGVyIHByb2Nlc3MuIFRoZSBwcm9taXNlIGlzIGNhY2hlZCAobm90IHRoZVxuICogcmVzdWx0KSBzbyBjb25jdXJyZW50IGZpcnN0IGludm9jYXRpb25zIHNoYXJlIGEgc2luZ2xlIGNvbXBpbGF0aW9uLlxuICovXG5sZXQgY29tcGlsZWRBc3NldHNQcm9taXNlOlxuICB8IFByb21pc2U8e1xuICAgICAgd2FzbTogb2JqZWN0O1xuICAgICAgZXh0ZW5zaW9uczogQ29tcGlsZWRFeHRlbnNpb25bXTtcbiAgICB9PlxuICB8IHVuZGVmaW5lZDtcblxuZnVuY3Rpb24gZ2V0Q29tcGlsZWRBc3NldHMoKSB7XG4gIGlmICghY29tcGlsZWRBc3NldHNQcm9taXNlKSB7XG4gICAgY29tcGlsZWRBc3NldHNQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IFt3YXNtLCAuLi5leHRlbnNpb25Nb2R1bGVzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgV2ViQXNzZW1ibHlHbG9iYWwuY29tcGlsZShxdWlja2pzV2FzbSksXG4gICAgICAgIC4uLnF1aWNranNFeHRlbnNpb25zLm1hcCgoZXh0KSA9PlxuICAgICAgICAgIFdlYkFzc2VtYmx5R2xvYmFsLmNvbXBpbGUoZXh0Lndhc20gYXMgVWludDhBcnJheSlcbiAgICAgICAgKSxcbiAgICAgIF0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgd2FzbSxcbiAgICAgICAgZXh0ZW5zaW9uczogcXVpY2tqc0V4dGVuc2lvbnMubWFwKChleHQsIGkpID0+ICh7XG4gICAgICAgICAgLi4uZXh0LFxuICAgICAgICAgIHdhc206IGV4dGVuc2lvbk1vZHVsZXNbaV0gYXMgRXh0ZW5zaW9uRGVzY3JpcHRvclsnd2FzbSddLFxuICAgICAgICB9KSksXG4gICAgICB9O1xuICAgIH0pKCk7XG4gICAgLy8gT24gZmFpbHVyZSwgY2xlYXIgdGhlIGNhY2hlIHNvIGEgbGF0ZXIgaW52b2NhdGlvbiBjYW4gcmV0cnkgcmF0aGVyXG4gICAgLy8gdGhhbiBiZWluZyBzdHVjayB3aXRoIGEgcmVqZWN0ZWQgcHJvbWlzZSBmb3JldmVyLlxuICAgIGNvbXBpbGVkQXNzZXRzUHJvbWlzZS5jYXRjaCgoKSA9PiB7XG4gICAgICBjb21waWxlZEFzc2V0c1Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGNvbXBpbGVkQXNzZXRzUHJvbWlzZTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gaW5pdFdvcmtmbG93Vk0oXG4gIGdldE5vd01zOiAoKSA9PiBudW1iZXIsXG4gIGludGVycnVwdEJ1ZGdldDogSW50ZXJydXB0QnVkZ2V0XG4pOiBQcm9taXNlPFF1aWNrSlM+IHtcbiAgLy8gRGV0ZXJtaW5pc3RpYyByZXBsYXkgY2xvY2s6IERhdGUubm93KCkgLyBuZXcgRGF0ZSgpIGluc2lkZSB0aGUgVk1cbiAgLy8gcmVhZCB0aGUgaG9zdC1jb250cm9sbGVkIGNsb2NrIGluc3RlYWQgb2Ygd2FsbCB0aW1lLiBSZXBsYXlcbiAgLy8gcmUtZXhlY3V0ZXMgdGhlIHdvcmtmbG93IGZyb20gdGhlIHRvcCBvbiBldmVyeSBpbnZvY2F0aW9uLCBzbyB0aGVcbiAgLy8gY2xvY2sgbXVzdCBiZSBkZXJpdmVkIGZyb20gdGhlIGV2ZW50IGxvZyAobm90IHJlYWwgdGltZSkgZm9yIHRoZVxuICAvLyB3b3JrZmxvdyB0byBvYnNlcnZlIHN0YWJsZSB0aW1lc3RhbXBzIGFjcm9zcyBpbnZvY2F0aW9ucy5cbiAgY29uc3Qgd2FzaTogV2FzaU9wdGlvbnMgPSAobWVtb3J5KSA9PiAoe1xuICAgIGNsb2NrX3RpbWVfZ2V0KF9jbG9ja0lkOiBudW1iZXIsIF9wcmVjaXNpb246IGJpZ2ludCwgcmVzdWx0UHRyOiBudW1iZXIpIHtcbiAgICAgIGNvbnN0IHRpbWVOcyA9IEJpZ0ludChNYXRoLnJvdW5kKGdldE5vd01zKCkpKSAqIDFfMDAwXzAwMG47XG4gICAgICBuZXcgRGF0YVZpZXcobWVtb3J5LmJ1ZmZlcikuc2V0QmlnVWludDY0KHJlc3VsdFB0ciwgdGltZU5zLCB0cnVlKTtcbiAgICAgIHJldHVybiAwO1xuICAgIH0sXG4gIH0pO1xuXG4gIGNvbnN0IGFzc2V0cyA9IGF3YWl0IGdldENvbXBpbGVkQXNzZXRzKCk7XG4gIGNvbnN0IHZtID0gYXdhaXQgUXVpY2tKUy5jcmVhdGUoe1xuICAgIHdhc206IGFzc2V0cy53YXNtIGFzIG5ldmVyLFxuICAgIG1lbW9yeUxpbWl0OiAyNTYgKiAxMDI0ICogMTAyNCxcbiAgICBpbnRlcnJ1cHRIYW5kbGVyOiBjcmVhdGVJbnRlcnJ1cHRIYW5kbGVyKGludGVycnVwdEJ1ZGdldCksXG4gICAgZXh0ZW5zaW9uczogYXNzZXRzLmV4dGVuc2lvbnMsXG4gICAgd2FzaSxcbiAgfSk7XG5cbiAgLy8gRXZhbHVhdGUgdGhlIFZNIHNlcmRlIGJ1bmRsZVxuICB2bS5ldmFsQ29kZShWTV9TRVJERV9CVU5ETEUsICd2bS1zZXJkZS5qcycpLmRpc3Bvc2UoKTtcblxuICAvLyBCb290c3RyYXAgd29ya2Zsb3cgcHJpbWl0aXZlc1xuICB2bS5ldmFsQ29kZShWTV9CT09UU1RSQVAsICdib290c3RyYXAuanMnKS5kaXNwb3NlKCk7XG5cbiAgcmV0dXJuIHZtO1xufVxuXG4vKipcbiAqIEEgbGl2ZSBRdWlja0pTIHdvcmtmbG93IGludm9jYXRpb24uIFdoZW4gdGhlIGluaXRpYWwgYHJlc3VsdGAgaXNcbiAqIGBzdXNwZW5kZWRgLCB0aGUgVk0gaXMga2VwdCBhbGl2ZSBzbyB0aGUgY2FsbGVyIGNhbiBmZWVkIG5ld2x5IHJlY29yZGVkXG4gKiBldmVudHMgKGUuZy4gdGVybWluYWwgZXZlbnRzIG9mIGlubGluZS1leGVjdXRlZCBzdGVwcykgaW50byB0aGUgU0FNRSBWTVxuICogdmlhIGBjb250aW51ZVdpdGhFdmVudHNgIOKAlCByZXN1bWluZyBleGVjdXRpb24gZXhhY3RseSB3aGVyZSBpdCBsZWZ0IG9mZlxuICogd2l0aG91dCBhIGZyZXNoLVZNIHJlLXJlcGxheS4gVGVybWluYWwgcmVzdWx0cyBkaXNwb3NlIHRoZSBWTVxuICogYXV0b21hdGljYWxseTsgYGRpc3Bvc2UoKWAgbXVzdCBiZSBjYWxsZWQgd2hlbiBhYmFuZG9uaW5nIGEgc3VzcGVuZGVkXG4gKiBzZXNzaW9uIChpZGVtcG90ZW50KS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdWlja0pTV29ya2Zsb3dTZXNzaW9uIHtcbiAgcmVzdWx0OiBRdWlja0pTUnVudGltZVJlc3VsdDtcbiAgLyoqXG4gICAqIFByb2Nlc3MgbmV3bHkgcmVjb3JkZWQgZXZlbnRzIGluIHRoZSBsaXZlIFZNIGFuZCByZS1ldmFsdWF0ZSB0aGVcbiAgICogd29ya2Zsb3cgc3RhdGUuIE9ubHkgdmFsaWQgd2hpbGUgdGhlIGxhc3QgcmVzdWx0IHdhcyBgc3VzcGVuZGVkYC5cbiAgICogUmVzZXRzIHRoZSBWTSdzIGludGVycnVwdCBidWRnZXQgZm9yIHRoZSBuZXcgZXhlY3V0aW9uIGJ1cnN0LlxuICAgKi9cbiAgY29udGludWVXaXRoRXZlbnRzKG5ld0V2ZW50czogRXZlbnRbXSk6IFByb21pc2U8UXVpY2tKU1J1bnRpbWVSZXN1bHQ+O1xuICAvKiogRGlzcG9zZSB0aGUgVk0gaWYgaXQgaXMgc3RpbGwgYWxpdmUuIFNhZmUgdG8gY2FsbCBtdWx0aXBsZSB0aW1lcy4gKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xufVxuXG4vKipcbiAqIFJ1biBhIHdvcmtmbG93IGludm9jYXRpb24gdG8gaXRzIGZpcnN0IHNldHRsZWQgc3RhdGUgYW5kIGRpc3Bvc2UgdGhlXG4gKiBWTS4gQ29udmVuaWVuY2Ugd3JhcHBlciBvdmVyIHtAbGluayBzdGFydFF1aWNrSlNXb3JrZmxvd30gZm9yIGNhbGxlcnNcbiAqIChhbmQgdGVzdHMpIHRoYXQgZG9uJ3QgdXNlIGxpdmUtVk0gY29udGludWF0aW9uLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuUXVpY2tKU1dvcmtmbG93KFxuICBvcHRpb25zOiBRdWlja0pTUnVudGltZU9wdGlvbnNcbik6IFByb21pc2U8UXVpY2tKU1J1bnRpbWVSZXN1bHQ+IHtcbiAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHN0YXJ0UXVpY2tKU1dvcmtmbG93KG9wdGlvbnMpO1xuICBzZXNzaW9uLmRpc3Bvc2UoKTtcbiAgcmV0dXJuIHNlc3Npb24ucmVzdWx0O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRRdWlja0pTV29ya2Zsb3coXG4gIG9wdGlvbnM6IFF1aWNrSlNSdW50aW1lT3B0aW9uc1xuKTogUHJvbWlzZTxRdWlja0pTV29ya2Zsb3dTZXNzaW9uPiB7XG4gIGNvbnN0IHsgd29ya2Zsb3dDb2RlLCB3b3JrZmxvd0lkLCB3b3JrZmxvd1J1biwgZXZlbnRzIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IHN0YXJ0ZWRBdCA9IHdvcmtmbG93UnVuLnN0YXJ0ZWRBdCA/ICt3b3JrZmxvd1J1bi5zdGFydGVkQXQgOiBEYXRlLm5vdygpO1xuXG4gIC8vIERldGVybWluaXN0aWMgUFJORyBzZWVkIOKAlCBpZGVudGljYWwgZm9yIEVWRVJZIGludm9jYXRpb24gb2YgdGhlIHNhbWVcbiAgLy8gcnVuLiBGdWxsIGV2ZW50IHJlcGxheSByZXF1aXJlcyB0aGlzOiBlYWNoIGludm9jYXRpb24gcmUtZXhlY3V0ZXMgdGhlXG4gIC8vIHdvcmtmbG93IGZyb20gdGhlIHRvcCBhbmQgbXVzdCByZWdlbmVyYXRlIHRoZSBleGFjdCBzYW1lIGNvcnJlbGF0aW9uSWRcbiAgLy8gc2VxdWVuY2Ugc28gdGhhdCBwZW5kaW5nIG9wZXJhdGlvbnMgcmUtY3JlYXRlZCBieSByZXBsYXkgbWF0Y2ggdGhlXG4gIC8vIGV2ZW50cyByZWNvcmRlZCBieSBlYXJsaWVyIGludm9jYXRpb25zLiBTZXF1ZW50aWFsIG9wZXJhdGlvbnMgd2l0aGluXG4gIC8vIG9uZSBleGVjdXRpb24gc3RpbGwgZ2V0IGRpc3RpbmN0IGlkcyBiZWNhdXNlIHRoZSBQUk5HIGFkdmFuY2VzIGFzIHRoZVxuICAvLyB3b3JrZmxvdyBkcmF3cyBmcm9tIGl0LiBJZGVudGljYWwgc2VlZGluZyBhY3Jvc3MgQ09OQ1VSUkVOVCBpbnZvY2F0aW9uc1xuICAvLyBvZiB0aGUgc2FtZSBydW4gaXMgYWxzbyBsb2FkLWJlYXJpbmc6IGJvdGggcHJvZHVjZSB0aGUgc2FtZSBpZHMsIGFuZFxuICAvLyB0aGUgd29ybGQncyBwZXItKHJ1bklkLCBjb3JyZWxhdGlvbklkKSB1bmlxdWVuZXNzIHR1cm5zIHRoZSBkdXBsaWNhdGVcbiAgLy8gYGV2ZW50cy5jcmVhdGVgIGludG8gYW4gRW50aXR5Q29uZmxpY3RFcnJvciB0aGF0IHRoZSBlbnRyeXBvaW50XG4gIC8vIHN3YWxsb3dzLlxuICAvL1xuICAvLyBUaGUgc2VlZCBpbnB1dHMgTVVTVCBiZSBzdGFibGUgYWNyb3NzIGludm9jYXRpb25zLiBOb3RhYmx5XG4gIC8vIGBzdGFydGVkQXRgIGlzIE5PVDogdW5kZXIgdHVyYm8gdGhlIGZpcnN0IGludm9jYXRpb24gcnVucyBhZ2FpbnN0IGFcbiAgLy8gc3ludGhlc2l6ZWQgcnVuIG9iamVjdCB3aG9zZSB0aW1lc3RhbXBzIGRpZmZlciBmcm9tIHRoZSBkdXJhYmx5XG4gIC8vIHN0b3JlZCBvbmVzIHRoYXQgbGF0ZXIgaW52b2NhdGlvbnMgbG9hZC4gTWF0Y2hlcyB0aGUgbm9kZTp2bVxuICAvLyBlbmdpbmUncyBzZWVkICh3b3JrZmxvdy50cykuXG4gIGNvbnN0IHNlZWQgPSBbXG4gICAgd29ya2Zsb3dSdW4ucnVuSWQsXG4gICAgd29ya2Zsb3dSdW4ud29ya2Zsb3dOYW1lLFxuICAgIHdvcmtmbG93UnVuLmRlcGxveW1lbnRJZCxcbiAgXS5qb2luKCc6Jyk7XG4gIGNvbnN0IHJuZyA9IHNlZWRyYW5kb20oc2VlZCk7XG5cbiAgLy8gU2VlZGVkIG5hbm9pZCBnZW5lcmF0b3Ig4oCUIHVzZXMgdGhlIHNhbWUgbmFub2lkIHBhY2thZ2UgYW5kIHNlZWRlZCBQUk5HXG4gIC8vIGFzIHRoZSBub2RlOnZtIGVuZ2luZSBmb3IgY29uc2lzdGVudCB0b2tlbiBnZW5lcmF0aW9uLlxuICBjb25zdCBnZW5lcmF0ZU5hbm9pZCA9IG5hbm9pZC5jdXN0b21SYW5kb20obmFub2lkLnVybEFscGhhYmV0LCAyMSwgKHNpemUpID0+XG4gICAgbmV3IFVpbnQ4QXJyYXkoc2l6ZSkubWFwKCgpID0+IDI1NiAqIHJuZygpKVxuICApO1xuXG4gIC8vIERldGVybWluaXN0aWMgcmVwbGF5IGNsb2NrLCBtaXJyb3JpbmcgdGhlIG5vZGU6dm0gZW5naW5lIChzZWVcbiAgLy8gd29ya2Zsb3cudHMpOiB0aGUgaW5pdGlhbCB2YWx1ZSBpcyB0aGUgcnVuJ3MgY3JlYXRpb24gdGltZSByZWNvdmVyZWRcbiAgLy8gZnJvbSB0aGUgVUxJRCBlbWJlZGRlZCBpbiBgcnVuSWRgIChmYWxsaW5nIGJhY2sgdG8gYGNyZWF0ZWRBdGApLCBhbmRcbiAgLy8gaXQgYWR2YW5jZXMgdG8gZWFjaCBwcm9jZXNzZWQgZXZlbnQncyBgY3JlYXRlZEF0YCBhcyB0aGUgZXZlbnQgbG9nIGlzXG4gIC8vIHJlcGxheWVkLiBNb25vdG9uaWMgKE1hdGgubWF4KSBzbyB0aGUgb3V0ZXIgcHJvY2Vzc0V2ZW50cyByZS1zY2FuXG4gIC8vIGxvb3AgY2FuJ3QgbW92ZSB0aGUgY2xvY2sgYmFja3dhcmRzIG1pZC1leGVjdXRpb24uXG4gIGxldCB2bU5vd01zID1cbiAgICBydW5JZENyZWF0ZWRBdCh3b3JrZmxvd1J1bi5ydW5JZCkgPz8gKCt3b3JrZmxvd1J1bi5jcmVhdGVkQXQgfHwgc3RhcnRlZEF0KTtcbiAgY29uc3QgYWR2YW5jZUNsb2NrID0gKG1zOiBudW1iZXIpID0+IHtcbiAgICBpZiAoTnVtYmVyLmlzRmluaXRlKG1zKSkgdm1Ob3dNcyA9IE1hdGgubWF4KHZtTm93TXMsIG1zKTtcbiAgfTtcblxuICAvLyAtLS0tIFBoYXNlIDE6IHN0YXRpYyBpbml0aWFsaXphdGlvbiAtLS0tXG4gIGNvbnN0IGludGVycnVwdEJ1ZGdldDogSW50ZXJydXB0QnVkZ2V0ID0geyBzdGFydDogRGF0ZS5ub3coKSB9O1xuICBjb25zdCB2bSA9IGF3YWl0IGluaXRXb3JrZmxvd1ZNKCgpID0+IHZtTm93TXMsIGludGVycnVwdEJ1ZGdldCk7XG5cbiAgLy8gQW55IHRocm93IGJldHdlZW4gaGVyZSBhbmQgdGhlIHRlcm1pbmFsIHBhdGhzICh3aGljaCBkaXNwb3NlIHRoZSBWTVxuICAvLyBpbnNpZGUgY2hlY2tXb3JrZmxvd1N0YXRlIC8gZXh0cmFjdEVycm9yIGJlZm9yZSBSRVRVUk5JTkcpIHdvdWxkIGxlYWtcbiAgLy8gYSBsaXZlIFF1aWNrSlMgaW5zdGFuY2UgYW5kIGl0cyBXQVNNIGxpbmVhciBtZW1vcnkgZm9yIHRoZSBsaWZldGltZVxuICAvLyBvZiB0aGUgY29tcHV0ZSBpbnN0YW5jZSDigJQgd2hpY2ggaXMgcmV1c2VkLiBEaXNwb3NlIG9uIHRoZSB3YXkgb3V0IG9mXG4gIC8vIGFuIGV4Y2VwdGlvbmFsIGV4aXQgYW5kIHJldGhyb3cuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHJ1bldvcmtmbG93SW5WTSgpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0cnkge1xuICAgICAgdm0uZGlzcG9zZSgpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gQWxyZWFkeSBkaXNwb3NlZCBieSBhIHRlcm1pbmFsIHBhdGgg4oCUIGlnbm9yZS5cbiAgICB9XG4gICAgdGhyb3cgZXJyO1xuICB9XG5cbiAgLy8gLS0tLSBQaGFzZSAyOiBwZXItcnVuIGluaXRpYWxpemF0aW9uIC0tLS1cbiAgYXN5bmMgZnVuY3Rpb24gcnVuV29ya2Zsb3dJblZNKCk6IFByb21pc2U8UXVpY2tKU1dvcmtmbG93U2Vzc2lvbj4ge1xuICAgIHZtLmV2YWxDb2RlKFxuICAgICAgYGdsb2JhbFRoaXMuX193b3JsZENhcGFiaWxpdGllcyA9ICR7SlNPTi5zdHJpbmdpZnkob3B0aW9ucy53b3JsZENhcGFiaWxpdGllcyl9O2BcbiAgICApLmRpc3Bvc2UoKTtcblxuICAgIC8vIFNlZWRlZCBNYXRoLnJhbmRvbVxuICAgIHtcbiAgICAgIHVzaW5nIHJhbmRvbUZuID0gdm0ubmV3RnVuY3Rpb24oJ3JhbmRvbScsICgpID0+IHZtLm5ld051bWJlcihybmcoKSkpO1xuICAgICAgdXNpbmcgbWF0aCA9IHZtLmdsb2JhbC5nZXRQcm9wKCdNYXRoJyk7XG4gICAgICBtYXRoLnNldFByb3AoJ3JhbmRvbScsIHJhbmRvbUZuKTtcbiAgICB9XG5cbiAgICAvLyBTZWVkZWQgbmFub2lkIGdlbmVyYXRvclxuICAgIHtcbiAgICAgIHVzaW5nIG5hbm9pZEZuID0gdm0ubmV3RnVuY3Rpb24oJ19fZ2VuZXJhdGVOYW5vaWQnLCAoKSA9PlxuICAgICAgICB2bS5uZXdTdHJpbmcoZ2VuZXJhdGVOYW5vaWQoKSlcbiAgICAgICk7XG4gICAgICB2bS5zZXRQcm9wKHZtLmdsb2JhbCwgJ19fZ2VuZXJhdGVOYW5vaWQnLCBuYW5vaWRGbik7XG4gICAgfVxuXG4gICAgLy8gSW5qZWN0IGEgZGV0ZXJtaW5pc3RpYyB0aW1lc3RhbXAgZm9yIHRoZSBWTSdzIFVMSUQgZmFjdG9yeS4gVUxJRHNcbiAgICAvLyBwcm9kdWNlZCBpbnNpZGUgdGhlIFZNIHVzZSB0aGlzIGFzIHRoZWlyIHRpbWUgcHJlZml4IGluc3RlYWQgb2ZcbiAgICAvLyBEYXRlLm5vdygpLCBzbyB0d28gY29uY3VycmVudCB3b3JrZmxvdyBpbnZvY2F0aW9ucyBvZiB0aGUgc2FtZSBydW5cbiAgICAvLyBwcm9kdWNlIElERU5USUNBTCBjb3JyZWxhdGlvbklkcyAodGhlIHJhbmRvbSBwb3J0aW9uIGFsc28gbWF0Y2hlc1xuICAgIC8vIGJlY2F1c2UgdGhlIFBSTkcgaXMgc2VlZGVkIHRoZSBzYW1lIHdheSkgYW5kIHRoZSB3b3JsZCdzXG4gICAgLy8gRW50aXR5Q29uZmxpY3RFcnJvciBvbiBgZXZlbnRzLmNyZWF0ZWAgZGVkdXBzIG9uZSBvZiBlYWNoIHBhaXIuXG4gICAgLy8gRGVyaXZlZCBmcm9tIHRoZSBydW5JZCdzIGVtYmVkZGVkIFVMSUQgKHN0YWJsZSBhY3Jvc3MgaW52b2NhdGlvbnMgYnlcbiAgICAvLyBjb25zdHJ1Y3Rpb24g4oCUIHVubGlrZSBgc3RhcnRlZEF0YCwgd2hpY2ggZGlmZmVycyBiZXR3ZWVuIHR1cmJvJ3NcbiAgICAvLyBzeW50aGVzaXplZCBydW4gb2JqZWN0IGFuZCB0aGUgZHVyYWJseSBzdG9yZWQgcnVuKS5cbiAgICB2bS5ldmFsQ29kZShcbiAgICAgIGBnbG9iYWxUaGlzLl9fdWxpZFRpbWVzdGFtcCA9ICR7cnVuSWRDcmVhdGVkQXQod29ya2Zsb3dSdW4ucnVuSWQpID8/ICgrd29ya2Zsb3dSdW4uY3JlYXRlZEF0IHx8IHN0YXJ0ZWRBdCl9O2BcbiAgICApLmRpc3Bvc2UoKTtcblxuICAgIC8vIGBwcm9jZXNzLmVudmAg4oCUIHBhcml0eSB3aXRoIHRoZSBub2RlOnZtIGVuZ2luZSwgd2hpY2ggZXhwb3NlcyBhIGZyb3plblxuICAgIC8vIGNvcHkgb2YgdGhlIGhvc3QgZW52ICh2bS9pbmRleC50cykuIEluamVjdGVkIHBlciBydW4gc28gdGhlIHNuYXBzaG90IG9mXG4gICAgLy8gdGhlIGVudiBpcyB0YWtlbiBhdCBpbnZvY2F0aW9uIHRpbWUsIHNhbWUgYXMgbm9kZS5cbiAgICB7XG4gICAgICBjb25zdCBlbnZIYW5kbGUgPSB2bS5uZXdTdHJpbmcoSlNPTi5zdHJpbmdpZnkocHJvY2Vzcy5lbnYpKTtcbiAgICAgIHZtLnNldFByb3Aodm0uZ2xvYmFsLCAnX193ZGtfZW52JywgZW52SGFuZGxlKTtcbiAgICAgIGVudkhhbmRsZS5kaXNwb3NlKCk7XG4gICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgJ2dsb2JhbFRoaXMucHJvY2VzcyA9IHsgZW52OiBPYmplY3QuZnJlZXplKEpTT04ucGFyc2UoZ2xvYmFsVGhpcy5fX3dka19lbnYpKSB9OycgK1xuICAgICAgICAgICdkZWxldGUgZ2xvYmFsVGhpcy5fX3dka19lbnY7J1xuICAgICAgKS5kaXNwb3NlKCk7XG4gICAgfVxuXG4gICAgLy8gRXhlY3V0ZSB0aGUgd29ya2Zsb3cgYnVuZGxlIOKAlCB1c2UgdGhlIHdvcmtmbG93SWQgYXMgdGhlIGV2YWwgZmlsZW5hbWVcbiAgICAvLyBzbyBRdWlja0pTIHN0YWNrIHRyYWNlcyByZWZlcmVuY2UgdGhlIHdvcmtmbG93IG5hbWUsIGVuYWJsaW5nIHNvdXJjZSBtYXBcbiAgICAvLyByZW1hcHBpbmcgYnkgcmVtYXBFcnJvclN0YWNrICh3aGljaCBtYXRjaGVzIGZyYW1lcyBieSBmaWxlbmFtZSkuXG4gICAgLy8gRXZhbHVhdGVkIGluIHRoZSBwZXItcnVuIHBoYXNlIChhZnRlciBNYXRoLnJhbmRvbSBzZWVkaW5nKSBzbyB0aGF0XG4gICAgLy8gbW9kdWxlLXNjb3BlIHVzZXIgY29kZSBkcmF3cyBmcm9tIHRoZSBzZWVkZWQgUFJORywgbWF0Y2hpbmcgdGhlXG4gICAgLy8gbm9kZTp2bSBlbmdpbmUncyByZXBsYXkgZGV0ZXJtaW5pc20uXG4gICAgdHJ5IHtcbiAgICAgIHZtLmV2YWxDb2RlKHdvcmtmbG93Q29kZSwgd29ya2Zsb3dJZCB8fCAnd29ya2Zsb3cuanMnKS5kaXNwb3NlKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gbWFrZVNldHRsZWRTZXNzaW9uKFxuICAgICAgICBleHRyYWN0RXJyb3Iodm0sIGVyciwgJ1dvcmtmbG93IGV2YWx1YXRpb24gZmFpbGVkJylcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gRXh0cmFjdCB3b3JrZmxvdyBhcmd1bWVudHMuIFByZWZlciB0aGUgcnVuX2NyZWF0ZWQgZXZlbnQ7IGZhbGwgYmFja1xuICAgIC8vIHRvIHRoZSBxdWV1ZSBtZXNzYWdlJ3MgcnVuSW5wdXQgaWYgdGhlIGV2ZW50IGxvZyBpcyBpbmNvbXBsZXRlXG4gICAgLy8gKGV2ZW50dWFsbHktY29uc2lzdGVudCByZWFkIGFmdGVyIHN0YXJ0KCkpLiBGYWlsaW5nIHRvIGZpbmQgaW5wdXRcbiAgICAvLyBmb3IgYSBmaXJzdCBpbnZvY2F0aW9uIGlzIGZhdGFsIOKAlCBydW5uaW5nIHRoZSB3b3JrZmxvdyBmdW5jdGlvblxuICAgIC8vIHdpdGggbm8gYXJncyB3b3VsZCBzaWxlbnRseSB0dXJuIHR5cGVkIGFyZ3VtZW50cyBpbnRvIGB1bmRlZmluZWRgXG4gICAgLy8gYW5kLCBmb3IgcmVjdXJzaXZlIHdvcmtmbG93cywgcHJvZHVjZSBleHBvbmVudGlhbCBmYW4tb3V0LlxuICAgIGNvbnN0IHJ1bkNyZWF0ZWRFdmVudCA9IGV2ZW50cy5maW5kKChlKSA9PiBlLmV2ZW50VHlwZSA9PT0gJ3J1bl9jcmVhdGVkJyk7XG4gICAgY29uc3QgcnVuQ3JlYXRlZElucHV0ID1cbiAgICAgIHJ1bkNyZWF0ZWRFdmVudCAmJiAnZXZlbnREYXRhJyBpbiBydW5DcmVhdGVkRXZlbnRcbiAgICAgICAgPyAocnVuQ3JlYXRlZEV2ZW50LmV2ZW50RGF0YSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik/LmlucHV0XG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IHJ1bklucHV0OiB1bmtub3duID1cbiAgICAgIHJ1bkNyZWF0ZWRJbnB1dCA/PyAob3B0aW9ucy5ydW5JbnB1dD8uaW5wdXQgYXMgdW5rbm93bik7XG5cbiAgICBpZiAocnVuSW5wdXQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICBjb25zdCBkZWNyeXB0ZWRJbnB1dCA9IGF3YWl0IHByZXBhcmVCeXRlc0ZvclZNKFxuICAgICAgICBydW5JbnB1dCxcbiAgICAgICAgb3B0aW9ucy5lbmNyeXB0aW9uS2V5XG4gICAgICApO1xuICAgICAgcnVudGltZUxvZ2dlci5kZWJ1ZygnUXVpY2tKUyBydW50aW1lOiBydW4gaW5wdXQgZm9ybWF0Jywge1xuICAgICAgICBwcmVmaXg6IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShkZWNyeXB0ZWRJbnB1dC5zdWJhcnJheSgwLCA0KSksXG4gICAgICAgIGJ5dGVMZW5ndGg6IGRlY3J5cHRlZElucHV0LmJ5dGVMZW5ndGgsXG4gICAgICAgIHNvdXJjZTogcnVuQ3JlYXRlZElucHV0ID8gJ3J1bl9jcmVhdGVkJyA6ICdxdWV1ZU1lc3NhZ2UucnVuSW5wdXQnLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBpbnB1dEhhbmRsZSA9IHZtLm5ld1VpbnQ4QXJyYXkoZGVjcnlwdGVkSW5wdXQpO1xuICAgICAgdm0uc2V0UHJvcCh2bS5nbG9iYWwsICdfX3dka19pbnB1dCcsIGlucHV0SGFuZGxlKTtcbiAgICAgIGlucHV0SGFuZGxlLmRpc3Bvc2UoKTtcbiAgICB9IGVsc2UgaWYgKHJ1bklucHV0ID09PSB1bmRlZmluZWQgJiYgZXZlbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIFRoZSBldmVudCBsb2cgaXMgbm9uLWVtcHR5ICh3ZSBnb3QgcnVuX3N0YXJ0ZWQgb3Igc2ltaWxhcikgYnV0XG4gICAgICAvLyBubyBydW5fY3JlYXRlZCBldmVudCB3YXMgZm91bmQgYW5kIG5vIHF1ZXVlLXByb3ZpZGVkIHJ1bklucHV0IGlzXG4gICAgICAvLyBhdmFpbGFibGUuIFRoaXMgaXMgdGhlIHJhY2UgY29uZGl0aW9uIG9ic2VydmVkIGR1cmluZyB0aGUgZmliXG4gICAgICAvLyBpbmNpZGVudCDigJQgc2lsZW50bHkgZHJvcHBpbmcgYXJndW1lbnRzIHdvdWxkIHR1cm4gYG5gIGludG9cbiAgICAgIC8vIGB1bmRlZmluZWRgIGFuZCwgZm9yIHJlY3Vyc2l2ZSB3b3JrZmxvd3MsIGNhdXNlIGV4cG9uZW50aWFsXG4gICAgICAvLyBmYW4tb3V0LiBGYWlsIGxvdWQ6IHRoZSB0aHJvdyBlc2NhcGVzIHRoZSBlbnRyeXBvaW50IGludG8gdGhlXG4gICAgICAvLyByZXBsYXkgbG9vcCdzIGNhdGNoIGluIHJ1bnRpbWUudHMgKHRoZSBRdWlja0pTIGRpc3BhdGNoIHJ1bnNcbiAgICAgIC8vIGluc2lkZSB0aGF0IGxvb3AncyB0cnkpLCB3aGljaCByZWNvcmRzIHJ1bl9mYWlsZWQuIEEgdmlzaWJsZVxuICAgICAgLy8gdGVybWluYWwgZmFpbHVyZSBpc1xuICAgICAgLy8gcHJlZmVycmVkIG92ZXIgc2lsZW50bHkgZXhlY3V0aW5nIHdpdGggdW5kZWZpbmVkIGFyZ3VtZW50cyDigJQgdGhlXG4gICAgICAvLyBxdWV1ZS1wcm92aWRlZCBydW5JbnB1dCBmYWxsYmFjayBhYm92ZSBtYWtlcyB0aGlzIHBhdGggcmFyZS5cbiAgICAgIC8vIEVtcHR5IGBldmVudHNgIGlzIGFsbG93ZWQgYmVjYXVzZSB0ZXN0cyB0aGF0IGJvb3RzdHJhcCBhIHdvcmtmbG93XG4gICAgICAvLyB3aXRoIG5vIGFyZ3VtZW50cyByZWx5IG9uIHRoZSBvbGQgcGVybWlzc2l2ZSBiZWhhdmlvci5cbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYENhbm5vdCBzdGFydCB3b3JrZmxvdyBydW4gXCIke3dvcmtmbG93UnVuLnJ1bklkfVwiOiBubyBydW5fY3JlYXRlZCBldmVudCBmb3VuZCBhbmQgbm8gcnVuSW5wdXQgaW4gdGhlIHF1ZXVlIHBheWxvYWQsIGJ1dCBvdGhlciBldmVudHMgYXJlIHByZXNlbnQgKGxpa2VseSBhIHJlYWQtYWZ0ZXItd3JpdGUgcmFjZSBkdXJpbmcgc3RhcnQoKSkuYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBTZXQgd29ya2Zsb3cgY29udGV4dCBtZXRhZGF0YSAoZm9yIGdldFdvcmtmbG93TWV0YWRhdGEoKSkuXG4gICAgLy8gTXVzdCBtYXRjaCB0aGUgc2hhcGUgdGhhdCB0aGUgbm9kZTp2bSBlbmdpbmUgcHJvZHVjZXMgKHNlZVxuICAgIC8vIHBhY2thZ2VzL2NvcmUvc3JjL3dvcmtmbG93LnRzOiBydW5Xb3JrZmxvdyDihpIgY3R4KSBzbyB1c2VyIGNvZGVcbiAgICAvLyB0aGF0IGNvbXBhcmVzIGBnZXRXb3JrZmxvd01ldGFkYXRhKClgIHZhbHVlcyBiZXR3ZWVuIGEgc3RlcFxuICAgIC8vIChzZXJ2ZXItc2lkZSkgYW5kIHRoZSB3b3JrZmxvdyAoVk0tc2lkZSkgc2VlcyBpZGVudGljYWwgb2JqZWN0cy5cbiAgICB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IHtcbiAgICAgICAgd29ya2Zsb3dOYW1lOiB3b3JrZmxvd1J1bi53b3JrZmxvd05hbWUsXG4gICAgICAgIHdvcmtmbG93UnVuSWQ6IHdvcmtmbG93UnVuLnJ1bklkLFxuICAgICAgICB3b3JrZmxvd1N0YXJ0ZWRBdDogd29ya2Zsb3dSdW4uc3RhcnRlZEF0XG4gICAgICAgICAgPyBuZXcgRGF0ZSgrd29ya2Zsb3dSdW4uc3RhcnRlZEF0KVxuICAgICAgICAgIDogbmV3IERhdGUoKSxcbiAgICAgICAgdXJsOiBwcm9jZXNzLmVudi5WRVJDRUxfVVJMXG4gICAgICAgICAgPyBgaHR0cHM6Ly8ke3Byb2Nlc3MuZW52LlZFUkNFTF9VUkx9YFxuICAgICAgICAgIDogYGh0dHA6Ly9sb2NhbGhvc3Q6JHtvcHRpb25zLnBvcnQgPz8gMzAwMH1gLFxuICAgICAgICBmZWF0dXJlczogeyBlbmNyeXB0aW9uOiAhIW9wdGlvbnMuZW5jcnlwdGlvbktleSB9LFxuICAgICAgfTtcbiAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICBgZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfQ09OVEVYVFwiKV0gPSAke0pTT04uc3RyaW5naWZ5KG1ldGFkYXRhKX07YCArXG4gICAgICAgICAgYGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX0NPTlRFWFRcIildLndvcmtmbG93U3RhcnRlZEF0ID0gbmV3IERhdGUoJHtKU09OLnN0cmluZ2lmeShtZXRhZGF0YS53b3JrZmxvd1N0YXJ0ZWRBdC50b0lTT1N0cmluZygpKX0pO2BcbiAgICAgICkuZGlzcG9zZSgpO1xuICAgIH1cblxuICAgIC8vIFN0YXJ0IHRoZSB3b3JrZmxvdyBmdW5jdGlvbi4gSWYgdGhlIHdvcmtmbG93IGlzbid0IHJlZ2lzdGVyZWQsXG4gICAgLy8gdGhyb3cgYW4gZXJyb3IgdGFnZ2VkIHdpdGggYG5hbWUgPSBcIldvcmtmbG93Tm90UmVnaXN0ZXJlZEVycm9yXCJgXG4gICAgLy8gc28gdGhlIGhvc3Qtc2lkZSBlbnRyeXBvaW50IGNhbiByZWNvbnN0cnVjdCBhIHJlYWxcbiAgICAvLyBXb3JrZmxvd05vdFJlZ2lzdGVyZWRFcnJvciAoYSBXb3JrZmxvd1J1bnRpbWVFcnJvciBzdWJjbGFzcyB0aGF0XG4gICAgLy8gY2xhc3NpZmllcyBhcyBSVU5USU1FX0VSUk9SKSByYXRoZXIgdGhhbiBhIGdlbmVyaWMgdXNlciBlcnJvci5cbiAgICAvLyBTZWUgcXVpY2tqcy1lbnRyeXBvaW50LnRzJ3MgcnVuX2ZhaWxlZCBicmFuY2guXG4gICAgdHJ5IHtcbiAgICAgIHZtLmV2YWxDb2RlKGBcbiAgICAgIHZhciBfX3dmbiA9IGdsb2JhbFRoaXMuX19wcml2YXRlX3dvcmtmbG93cy5nZXQoJHtKU09OLnN0cmluZ2lmeSh3b3JrZmxvd0lkKX0pO1xuICAgICAgaWYgKCFfX3dmbikge1xuICAgICAgICB2YXIgX193Zm5FcnIgPSBuZXcgRXJyb3IoXCJXb3JrZmxvdyBcXFxcXCJcIiArICR7SlNPTi5zdHJpbmdpZnkod29ya2Zsb3dJZCl9ICsgXCJcXFxcXCIgaXMgbm90IHJlZ2lzdGVyZWQgaW4gdGhlIGN1cnJlbnQgZGVwbG95bWVudC5cIik7XG4gICAgICAgIF9fd2ZuRXJyLm5hbWUgPSBcIldvcmtmbG93Tm90UmVnaXN0ZXJlZEVycm9yXCI7XG4gICAgICAgIHRocm93IF9fd2ZuRXJyO1xuICAgICAgfVxuICAgICAgdmFyIF9fYXJncyA9IGdsb2JhbFRoaXMuX193ZGtfaW5wdXRcbiAgICAgICAgPyBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJ3b3JrZmxvdy1kZXNlcmlhbGl6ZVwiKV0oZ2xvYmFsVGhpcy5fX3dka19pbnB1dClcbiAgICAgICAgOiBbXTtcbiAgICAgIGRlbGV0ZSBnbG9iYWxUaGlzLl9fd2RrX2lucHV0O1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KF9fYXJncykpIF9fYXJncyA9IFtfX2FyZ3NdO1xuICAgICAgX193Zm4uYXBwbHkobnVsbCwgX19hcmdzKS50aGVuKFxuICAgICAgICBmdW5jdGlvbihyZXN1bHQpIHsgZ2xvYmFsVGhpcy5fX3dvcmtmbG93UmVzdWx0ID0gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwid29ya2Zsb3ctc2VyaWFsaXplXCIpXShyZXN1bHQpOyB9LFxuICAgICAgICBmdW5jdGlvbihlcnJvcikge1xuICAgICAgICAgIC8vIFByZXNlcnZlIGRpc3BsYXkgaW5mbyBvbiB0aGUgaG9zdC1zaWRlIGZhaWxlZCBvYmplY3RcbiAgICAgICAgICAvLyAobWF0Y2hlcyB0aGUgbGVnYWN5IGhvc3QtdmlzaWJsZSBzaGFwZSkgQU5EIHNlcmlhbGl6ZSB0aGVcbiAgICAgICAgICAvLyBlbnRpcmUgdGhyb3duIHZhbHVlIHNvIHRoZSBob3N0IGNhbiBkZWh5ZHJhdGUgdGhlIG9yaWdpbmFsXG4gICAgICAgICAgLy8gdHlwZS1pZGVudGl0eSwgY2F1c2UgY2hhaW4sIG9yIG5vbi1FcnJvciB0aHJvd3MgdmVyYmF0aW1cbiAgICAgICAgICAvLyB0aHJvdWdoIHRoZSBzdGFuZGFyZCBlcnJvciBwaXBlbGluZS5cbiAgICAgICAgICBnbG9iYWxUaGlzLl9fd29ya2Zsb3dFcnJvciA9IHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yICYmIGVycm9yLm1lc3NhZ2UgIT0gbnVsbCA/IFN0cmluZyhlcnJvci5tZXNzYWdlKSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgICBzdGFjazogZXJyb3IgJiYgZXJyb3Iuc3RhY2sgPyBlcnJvci5zdGFjayA6IFwiXCIsXG4gICAgICAgICAgICBuYW1lOiBlcnJvciAmJiBlcnJvci5uYW1lID8gZXJyb3IubmFtZSA6IChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gXCJFcnJvclwiIDogdHlwZW9mIGVycm9yKSxcbiAgICAgICAgICAgIHZhbHVlQnl0ZXM6IGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIndvcmtmbG93LXNlcmlhbGl6ZVwiKV0oZXJyb3IpLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgYCkuZGlzcG9zZSgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIG1ha2VTZXR0bGVkU2Vzc2lvbihcbiAgICAgICAgZXh0cmFjdEVycm9yKHZtLCBlcnIsICdGYWlsZWQgdG8gc3RhcnQgd29ya2Zsb3cnKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBQcm9jZXNzIGV2ZW50cyBhbmQgZHJhaW4gam9icyBpbiBhIGxvb3AuIEV2ZW50cyBtYXkgcmVzb2x2ZSBwcm9taXNlc1xuICAgIC8vIHRoYXQgdW5ibG9jayB3b3JrZmxvdyBjb2RlLCB3aGljaCB0aGVuIGNyZWF0ZXMgTkVXIHJlc29sdmVycyBmb3JcbiAgICAvLyBzdWJzZXF1ZW50IGV2ZW50cy4gUmUtcHJvY2Vzc2luZyBldmVudHMgbWF0Y2hlcyB0aGVzZSBuZXcgcmVzb2x2ZXJzXG4gICAgLy8gYWdhaW5zdCBldmVudHMgdGhhdCB3ZXJlIGFscmVhZHkgZGVsaXZlcmVkLlxuICAgIHtcbiAgICAgIGxldCBtYXhJdGVyYXRpb25zID0gMTAwO1xuICAgICAgbGV0IG1hZGVQcm9ncmVzczogYm9vbGVhbjtcbiAgICAgIGRvIHtcbiAgICAgICAgbWFkZVByb2dyZXNzID0gYXdhaXQgcHJvY2Vzc0V2ZW50cyhcbiAgICAgICAgICB2bSxcbiAgICAgICAgICBldmVudHMsXG4gICAgICAgICAgYWR2YW5jZUNsb2NrLFxuICAgICAgICAgIG9wdGlvbnMuZW5jcnlwdGlvbktleVxuICAgICAgICApO1xuICAgICAgICBsZXQgYmF0Y2g6IG51bWJlcjtcbiAgICAgICAgZG8ge1xuICAgICAgICAgIGJhdGNoID0gdm0uZXhlY3V0ZVBlbmRpbmdKb2JzKCk7XG4gICAgICAgICAgaWYgKGJhdGNoID4gMCkgbWFkZVByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgfSB3aGlsZSAoYmF0Y2ggPiAwKTtcbiAgICAgIH0gd2hpbGUgKG1hZGVQcm9ncmVzcyAmJiAtLW1heEl0ZXJhdGlvbnMgPiAwKTtcbiAgICAgIGlmIChtYWRlUHJvZ3Jlc3MgJiYgbWF4SXRlcmF0aW9ucyA9PT0gMCkge1xuICAgICAgICAvLyBUaGUgZHJhaW4gbG9vcCBoaXQgaXRzIGJvdW5kIHdoaWxlIHN0aWxsIG1ha2luZyBwcm9ncmVzcyDigJRcbiAgICAgICAgLy8gcHJvY2VlZGluZyBhcyBpZiBpdCBjb252ZXJnZWQgd291bGQgcHJlc2VudCBhcyBhIG15c3RlcmlvdXNcbiAgICAgICAgLy8gc3VzcGVuc2lvbiBvciByZXBsYXkgZGl2ZXJnZW5jZS4gTWFrZSB0aGUgZ2l2aW5nLXVwIHZpc2libGUgc29cbiAgICAgICAgLy8gYSB3ZWRnZSBpcyBhdHRyaWJ1dGFibGUgdG8gdGhpcyBib3VuZCByYXRoZXIgdGhhbiBhIG15c3RlcnkuXG4gICAgICAgIHJ1bnRpbWVMb2dnZXIud2FybihcbiAgICAgICAgICAnUXVpY2tKUyBydW50aW1lOiBldmVudCBkcmFpbiBsb29wIGhpdCBpdHMgaXRlcmF0aW9uIGJvdW5kIGJlZm9yZSByZWFjaGluZyBhIGZpeGVkIHBvaW50JyxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB3b3JrZmxvd1J1bklkOiB3b3JrZmxvd1J1bi5ydW5JZCxcbiAgICAgICAgICAgIGV2ZW50Q291bnQ6IGV2ZW50cy5sZW5ndGgsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIC0tLS0gQ2hlY2sgcmVzdWx0IC0tLS1cbiAgICByZXR1cm4gbWFrZUxpdmVTZXNzaW9uKFxuICAgICAgdm0sXG4gICAgICBpbnRlcnJ1cHRCdWRnZXQsXG4gICAgICBhZHZhbmNlQ2xvY2ssXG4gICAgICBvcHRpb25zLmVuY3J5cHRpb25LZXlcbiAgICApO1xuICB9XG59XG5cbi8qKiBTZXNzaW9uIHdyYXBwZXIgZm9yIGEgcmVzdWx0IHdob3NlIFZNIGlzIGFscmVhZHkgc2V0dGxlZC9kaXNwb3NlZC4gKi9cbmZ1bmN0aW9uIG1ha2VTZXR0bGVkU2Vzc2lvbihcbiAgcmVzdWx0OiBRdWlja0pTUnVudGltZVJlc3VsdFxuKTogUXVpY2tKU1dvcmtmbG93U2Vzc2lvbiB7XG4gIHJldHVybiB7XG4gICAgcmVzdWx0LFxuICAgIGNvbnRpbnVlV2l0aEV2ZW50czogKCkgPT4ge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnUXVpY2tKUyB3b3JrZmxvdyBzZXNzaW9uIGlzIHNldHRsZWQg4oCUIGNvbnRpbnVlV2l0aEV2ZW50cyBpcyBvbmx5IHZhbGlkIHdoaWxlIHN1c3BlbmRlZCdcbiAgICAgICk7XG4gICAgfSxcbiAgICBkaXNwb3NlOiAoKSA9PiB7fSxcbiAgfTtcbn1cblxuLyoqXG4gKiBFdmFsdWF0ZSB0aGUgVk0ncyBzdGF0ZSBhbmQgd3JhcCBpdCBpbiBhIGxpdmUgc2Vzc2lvbi4gV2hpbGUgc3VzcGVuZGVkLFxuICogdGhlIFZNIHN0YXlzIGFsaXZlIHNvIGBjb250aW51ZVdpdGhFdmVudHNgIGNhbiByZXN1bWUgaXQgaW4gcGxhY2U7XG4gKiB0ZXJtaW5hbCBzdGF0ZXMgZGlzcG9zZSB0aGUgVk0gaW1tZWRpYXRlbHkgKGluc2lkZSBjaGVja1dvcmtmbG93U3RhdGUpLlxuICovXG5mdW5jdGlvbiBtYWtlTGl2ZVNlc3Npb24oXG4gIHZtOiBRdWlja0pTLFxuICBpbnRlcnJ1cHRCdWRnZXQ6IEludGVycnVwdEJ1ZGdldCxcbiAgYWR2YW5jZUNsb2NrOiAobXM6IG51bWJlcikgPT4gdm9pZCxcbiAgZW5jcnlwdGlvbktleT86IERlY3J5cHRpb25LZXlcbik6IFF1aWNrSlNXb3JrZmxvd1Nlc3Npb24ge1xuICBjb25zdCByZXN1bHQgPSBjaGVja1dvcmtmbG93U3RhdGUodm0sIHsga2VlcEFsaXZlT25TdXNwZW5kOiB0cnVlIH0pO1xuICBsZXQgYWxpdmUgPSAhIXJlc3VsdC5zdXNwZW5kZWQ7XG5cbiAgY29uc3Qgc2Vzc2lvbjogUXVpY2tKU1dvcmtmbG93U2Vzc2lvbiA9IHtcbiAgICByZXN1bHQsXG4gICAgYXN5bmMgY29udGludWVXaXRoRXZlbnRzKFxuICAgICAgbmV3RXZlbnRzOiBFdmVudFtdXG4gICAgKTogUHJvbWlzZTxRdWlja0pTUnVudGltZVJlc3VsdD4ge1xuICAgICAgaWYgKCFhbGl2ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ1F1aWNrSlMgd29ya2Zsb3cgc2Vzc2lvbiBpcyBub3QgYWxpdmUg4oCUIGNvbnRpbnVlV2l0aEV2ZW50cyBpcyBvbmx5IHZhbGlkIHdoaWxlIHN1c3BlbmRlZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIEZyZXNoIGV4ZWN1dGlvbiBidXJzdCDigJQgdGhlIGludGVycnVwdCBidWRnZXQgYm91bmRzIFZNIGNvbXB1dGUsXG4gICAgICAvLyBub3Qgd2FsbCB0aW1lIHNwZW50IHdhaXRpbmcgb24gaW5saW5lIHN0ZXBzIGJldHdlZW4gYnVyc3RzLlxuICAgICAgaW50ZXJydXB0QnVkZ2V0LnN0YXJ0ID0gRGF0ZS5ub3coKTtcblxuICAgICAgbGV0IG1heEl0ZXJhdGlvbnMgPSAxMDA7XG4gICAgICBsZXQgbWFkZVByb2dyZXNzOiBib29sZWFuO1xuICAgICAgZG8ge1xuICAgICAgICBtYWRlUHJvZ3Jlc3MgPSBhd2FpdCBwcm9jZXNzRXZlbnRzKFxuICAgICAgICAgIHZtLFxuICAgICAgICAgIG5ld0V2ZW50cyxcbiAgICAgICAgICBhZHZhbmNlQ2xvY2ssXG4gICAgICAgICAgZW5jcnlwdGlvbktleVxuICAgICAgICApO1xuICAgICAgICBsZXQgYmF0Y2g6IG51bWJlcjtcbiAgICAgICAgZG8ge1xuICAgICAgICAgIGJhdGNoID0gdm0uZXhlY3V0ZVBlbmRpbmdKb2JzKCk7XG4gICAgICAgICAgaWYgKGJhdGNoID4gMCkgbWFkZVByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgfSB3aGlsZSAoYmF0Y2ggPiAwKTtcbiAgICAgIH0gd2hpbGUgKG1hZGVQcm9ncmVzcyAmJiAtLW1heEl0ZXJhdGlvbnMgPiAwKTtcblxuICAgICAgY29uc3QgbmV4dCA9IGNoZWNrV29ya2Zsb3dTdGF0ZSh2bSwgeyBrZWVwQWxpdmVPblN1c3BlbmQ6IHRydWUgfSk7XG4gICAgICBpZiAoIW5leHQuc3VzcGVuZGVkKSBhbGl2ZSA9IGZhbHNlO1xuICAgICAgc2Vzc2lvbi5yZXN1bHQgPSBuZXh0O1xuICAgICAgcmV0dXJuIG5leHQ7XG4gICAgfSxcbiAgICBkaXNwb3NlKCk6IHZvaWQge1xuICAgICAgaWYgKGFsaXZlKSB7XG4gICAgICAgIGFsaXZlID0gZmFsc2U7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdm0uZGlzcG9zZSgpO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAvLyBBbHJlYWR5IGRpc3Bvc2VkIOKAlCBpZ25vcmUuXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICB9O1xuICByZXR1cm4gc2Vzc2lvbjtcbn1cblxuLy8gLS0tLSBFdmVudCBQcm9jZXNzaW5nIC0tLS1cblxuYXN5bmMgZnVuY3Rpb24gcHJvY2Vzc0V2ZW50cyhcbiAgdm06IFF1aWNrSlMsXG4gIGV2ZW50czogRXZlbnRbXSxcbiAgYWR2YW5jZUNsb2NrOiAobXM6IG51bWJlcikgPT4gdm9pZCxcbiAgZW5jcnlwdGlvbktleT86IERlY3J5cHRpb25LZXlcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBsZXQgcmVzb2x2ZWQgPSBmYWxzZTtcbiAgZm9yIChjb25zdCBldmVudCBvZiBldmVudHMpIHtcbiAgICAvLyBBZHZhbmNlIHRoZSBWTSdzIGRldGVybWluaXN0aWMgY2xvY2sgdG8gdGhpcyBldmVudCdzIGNyZWF0aW9uIHRpbWVcbiAgICAvLyBCRUZPUkUgcmVzb2x2aW5nIGFueXRoaW5nLCBzbyB3b3JrZmxvdyBjb2RlIHVuYmxvY2tlZCBieSB0aGlzIGV2ZW50XG4gICAgLy8gb2JzZXJ2ZXMgRGF0ZS5ub3coKSBhdCAob3IgYWZ0ZXIg4oCUIHRoZSBjbG9jayBpcyBtb25vdG9uaWMpIHRoZSB0aW1lXG4gICAgLy8gdGhlIGV2ZW50IHdhcyByZWNvcmRlZC4gTWlycm9ycyB0aGUgbm9kZTp2bSBlbmdpbmUnc1xuICAgIC8vIGBvbkNvbnN1bWVkRXZlbnQg4oaSIHVwZGF0ZVRpbWVzdGFtcCgrZXZlbnQuY3JlYXRlZEF0KWAuXG4gICAgYWR2YW5jZUNsb2NrKCtldmVudC5jcmVhdGVkQXQpO1xuXG4gICAgY29uc3QgY2lkID0gZXZlbnQuY29ycmVsYXRpb25JZDtcbiAgICBpZiAoIWNpZCkgY29udGludWU7XG5cbiAgICAvLyBKU09OLnN0cmluZ2lmeSBoYW5kbGVzIHF1b3RlcywgYmFja3NsYXNoZXMgYW5kIGNvbnRyb2wgY2hhcmFjdGVycztcbiAgICAvLyBjb3JyZWxhdGlvbiBpZHMgYXJlIGhvc3QtZ2VuZXJhdGVkIFVMSURzIHRvZGF5LCBidXQgdGhlIGV2YWwtc3RyaW5nXG4gICAgLy8gc2FmZXR5IHNob3VsZG4ndCBkZXBlbmQgb24gdGhhdCBpbnZhcmlhbnQgYmVpbmcgYXNzZXJ0ZWQgbm93aGVyZS5cbiAgICBjb25zdCBjaWRKcyA9IEpTT04uc3RyaW5naWZ5KGNpZCk7XG4gICAgY29uc3QgZXZlbnREYXRhID1cbiAgICAgICdldmVudERhdGEnIGluIGV2ZW50XG4gICAgICAgID8gKGV2ZW50LmV2ZW50RGF0YSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilcbiAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAvLyBMb2cgdGhlIGV2ZW50IGFuZCB3aGV0aGVyIHRoZSByZXNvbHZlciBleGlzdHNcbiAgICBzd2l0Y2ggKGV2ZW50LmV2ZW50VHlwZSkge1xuICAgICAgY2FzZSAnc3RlcF9jb21wbGV0ZWQnOiB7XG4gICAgICAgIGNvbnN0IGhhc1Jlc29sdmVyID0gdm0uZHVtcChcbiAgICAgICAgICB2bS5ldmFsQ29kZShgISFnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XWApXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHJhd091dHB1dCA9IGV2ZW50RGF0YT8ucmVzdWx0ID8/IGV2ZW50RGF0YT8ub3V0cHV0O1xuICAgICAgICBpZiAoaGFzUmVzb2x2ZXIpIHtcbiAgICAgICAgICBpZiAocmF3T3V0cHV0IGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgICAgICAgLy8gRGVjcnlwdCBpZiBlbmNyeXB0ZWQg4oCUIHRoZSBWTSBvbmx5IHVuZGVyc3RhbmRzICdkZXZsJyBmb3JtYXRcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuZGVidWcoJ1F1aWNrSlMgcnVudGltZTogc3RlcCByZXN1bHQgcmF3Jywge1xuICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBjaWQsXG4gICAgICAgICAgICAgIHJhd1ByZWZpeDogbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKHJhd091dHB1dC5zdWJhcnJheSgwLCA0KSksXG4gICAgICAgICAgICAgIHJhd0J5dGVMZW5ndGg6IHJhd091dHB1dC5ieXRlTGVuZ3RoLFxuICAgICAgICAgICAgICBpc0J1ZmZlcjogQnVmZmVyLmlzQnVmZmVyKHJhd091dHB1dCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZE91dHB1dCA9IGF3YWl0IHByZXBhcmVCeXRlc0ZvclZNKFxuICAgICAgICAgICAgICByYXdPdXRwdXQsXG4gICAgICAgICAgICAgIGVuY3J5cHRpb25LZXlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBydW50aW1lTG9nZ2VyLmRlYnVnKCdRdWlja0pTIHJ1bnRpbWU6IHN0ZXAgcmVzdWx0IGRlY3J5cHRlZCcsIHtcbiAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogY2lkLFxuICAgICAgICAgICAgICBwcmVmaXg6IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShkZWNyeXB0ZWRPdXRwdXQuc3ViYXJyYXkoMCwgNCkpLFxuICAgICAgICAgICAgICBieXRlTGVuZ3RoOiBkZWNyeXB0ZWRPdXRwdXQuYnl0ZUxlbmd0aCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgYnl0ZXNIYW5kbGUgPSB2bS5uZXdVaW50OEFycmF5KGRlY3J5cHRlZE91dHB1dCk7XG4gICAgICAgICAgICB2bS5zZXRQcm9wKHZtLmdsb2JhbCwgJ19fdG1wX3Jlc3VsdCcsIGJ5dGVzSGFuZGxlKTtcbiAgICAgICAgICAgIGJ5dGVzSGFuZGxlLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV0ucmVzb2x2ZShnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJ3b3JrZmxvdy1kZXNlcmlhbGl6ZVwiKV0oZ2xvYmFsVGhpcy5fX3RtcF9yZXN1bHQpKTtgICtcbiAgICAgICAgICAgICAgICBgZGVsZXRlIGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dO2AgK1xuICAgICAgICAgICAgICAgIGBkZWxldGUgZ2xvYmFsVGhpcy5fX3RtcF9yZXN1bHQ7YFxuICAgICAgICAgICAgKS5kaXNwb3NlKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuZGVidWcoJ1F1aWNrSlMgcnVudGltZTogc3RlcCByZXN1bHQgbm9uLWJpbmFyeScsIHtcbiAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogY2lkLFxuICAgICAgICAgICAgICB0eXBlOiB0eXBlb2YgcmF3T3V0cHV0LFxuICAgICAgICAgICAgICBpc051bGw6IHJhd091dHB1dCA9PT0gbnVsbCxcbiAgICAgICAgICAgICAgaXNVbmRlZmluZWQ6IHJhd091dHB1dCA9PT0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBjb25zdHJ1Y3RvcjogcmF3T3V0cHV0Py5jb25zdHJ1Y3Rvcj8ubmFtZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3Qgc2VyaWFsaXplZCA9XG4gICAgICAgICAgICAgIHJhd091dHB1dCAhPT0gdW5kZWZpbmVkID8gSlNPTi5zdHJpbmdpZnkocmF3T3V0cHV0KSA6ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XS5yZXNvbHZlKCR7c2VyaWFsaXplZH0pO2AgK1xuICAgICAgICAgICAgICAgIGBkZWxldGUgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV07YFxuICAgICAgICAgICAgKS5kaXNwb3NlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIERyYWluIEFMTCBtaWNyb3Rhc2tzIGFmdGVyIHJlc29sdmVcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBsZXQgYjogbnVtYmVyO1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICBiID0gdm0uZXhlY3V0ZVBlbmRpbmdKb2JzKCk7XG4gICAgICAgICAgICB9IHdoaWxlIChiID4gMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5vIHJlc29sdmVyIHlldCDigJQgYnVmZmVyIHRoZSBwcmVwYXJlZCBvdXRjb21lIHNvIHRoZSBwcm9taXNlXG4gICAgICAgICAgLy8gc2V0dGxlcyB0aGUgbW9tZW50IHRoZSBWTSBjb25zdHJ1Y3RzIGl0IChzZWUgX190ZXJtaW5hbEJ1ZmZlclxuICAgICAgICAgIC8vIGluIHRoZSBib290c3RyYXApLiBXaXRob3V0IHRoaXMsIHRoZSBsaXZlLWNvbnRpbnVhdGlvbiBwYXRoXG4gICAgICAgICAgLy8gKHdoaWNoIHNjYW5zIGVhY2ggZGVsdGEgZXhhY3RseSBvbmNlKSBkcm9wcyB0aGUgdGVybWluYWwgYW5kXG4gICAgICAgICAgLy8gdGhlIGF3YWl0IG5ldmVyIHNldHRsZXMuXG4gICAgICAgICAgaWYgKHJhd091dHB1dCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZE91dHB1dCA9IGF3YWl0IHByZXBhcmVCeXRlc0ZvclZNKFxuICAgICAgICAgICAgICByYXdPdXRwdXQsXG4gICAgICAgICAgICAgIGVuY3J5cHRpb25LZXlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBieXRlc0hhbmRsZSA9IHZtLm5ld1VpbnQ4QXJyYXkoZGVjcnlwdGVkT3V0cHV0KTtcbiAgICAgICAgICAgIHZtLnNldFByb3Aodm0uZ2xvYmFsLCAnX190bXBfYnVmJywgYnl0ZXNIYW5kbGUpO1xuICAgICAgICAgICAgYnl0ZXNIYW5kbGUuZGlzcG9zZSgpO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fdGVybWluYWxCdWZmZXJbJHtjaWRKc31dID0geyBraW5kOiBcInJlc29sdmVfYnl0ZXNcIiwgYnl0ZXM6IGdsb2JhbFRoaXMuX190bXBfYnVmIH07YCArXG4gICAgICAgICAgICAgICAgYGRlbGV0ZSBnbG9iYWxUaGlzLl9fdG1wX2J1ZjtgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc2VyaWFsaXplZCA9XG4gICAgICAgICAgICAgIHJhd091dHB1dCAhPT0gdW5kZWZpbmVkID8gSlNPTi5zdHJpbmdpZnkocmF3T3V0cHV0KSA6ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fdGVybWluYWxCdWZmZXJbJHtjaWRKc31dID0geyBraW5kOiBcInJlc29sdmVfdmFsdWVcIiwgdmFsdWU6ICR7c2VyaWFsaXplZH0gfTtgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbWFya0NyZWF0ZWQodm0sIGNpZEpzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdzdGVwX2ZhaWxlZCc6IHtcbiAgICAgICAgY29uc3QgaGFzUmVzb2x2ZXIgPSB2bS5kdW1wKFxuICAgICAgICAgIHZtLmV2YWxDb2RlKGAhIWdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dYClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGhhc1Jlc29sdmVyKSB7XG4gICAgICAgICAgY29uc3QgZXJyb3JEYXRhID0gZXZlbnREYXRhPy5lcnJvcjtcbiAgICAgICAgICBpZiAoZXJyb3JEYXRhIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgICAgICAgLy8gTW9kZXJuIHBhdGggKHBvc3QtIzE4NTEpOiB0aGUgc3RlcCBoYW5kbGVyIGRlaHlkcmF0ZWQgdGhlXG4gICAgICAgICAgICAvLyB0aHJvd24gdmFsdWUgdGhyb3VnaCB0aGUgZmlyc3QtY2xhc3MgZXJyb3IgcGlwZWxpbmUuIERlY3J5cHRcbiAgICAgICAgICAgIC8vIChpZiBlbmNyeXB0ZWQpIGFuZCBwYXNzIHRoZSBieXRlcyB0byB0aGUgVk0tc2lkZSBkZXNlcmlhbGl6ZXJcbiAgICAgICAgICAgIC8vIHNvIHRoZSB3b3JrZmxvdyBjYXRjaCBzZWVzIGEgcHJvcGVybHkgdHlwZWQgRXJyb3Igc3ViY2xhc3NcbiAgICAgICAgICAgIC8vIChUeXBlRXJyb3IsIEZhdGFsRXJyb3Igd2l0aCBvcmlnaW5hbCBjYXVzZSBjaGFpbiwgZXRjLikgd2l0aFxuICAgICAgICAgICAgLy8gdGhlIG9yaWdpbmFsIG1lc3NhZ2UgYW5kIHN0YWNrIHByZXNlcnZlZC5cbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZCA9IGF3YWl0IHByZXBhcmVCeXRlc0ZvclZNKGVycm9yRGF0YSwgZW5jcnlwdGlvbktleSk7XG4gICAgICAgICAgICBjb25zdCBieXRlc0hhbmRsZSA9IHZtLm5ld1VpbnQ4QXJyYXkoZGVjcnlwdGVkKTtcbiAgICAgICAgICAgIHZtLnNldFByb3Aodm0uZ2xvYmFsLCAnX190bXBfZXJyb3InLCBieXRlc0hhbmRsZSk7XG4gICAgICAgICAgICBieXRlc0hhbmRsZS5kaXNwb3NlKCk7XG4gICAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgICAgYChmdW5jdGlvbigpe2AgK1xuICAgICAgICAgICAgICAgIGB2YXIgZT1nbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJ3b3JrZmxvdy1kZXNlcmlhbGl6ZVwiKV0oZ2xvYmFsVGhpcy5fX3RtcF9lcnJvcik7YCArXG4gICAgICAgICAgICAgICAgYGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dLnJlamVjdChlKTtgICtcbiAgICAgICAgICAgICAgICBgZGVsZXRlIGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dO2AgK1xuICAgICAgICAgICAgICAgIGBkZWxldGUgZ2xvYmFsVGhpcy5fX3RtcF9lcnJvcjtgICtcbiAgICAgICAgICAgICAgICBgfSkoKWBcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBMZWdhY3kgcGF0aDogcHJlLXBpcGVsaW5lIGV2ZW50cyBzdG9yZWQgZXJyb3IgYXNcbiAgICAgICAgICAgIC8vIGB7IG1lc3NhZ2UsIHN0YWNrLCBjb2RlIH1gLiBSZWNvbnN0cnVjdCBhIEZhdGFsRXJyb3Igc29cbiAgICAgICAgICAgIC8vIHdvcmtmbG93IGNhdGNoIGNhbiBkZXRlY3QgaXQgdmlhIEZhdGFsRXJyb3IuaXMoKSwgbWF0Y2hpbmdcbiAgICAgICAgICAgIC8vIHRoZSBvcmlnaW5hbCBWMSBzdGVwIGhhbmRsZXIgYmVoYXZpb3IuXG4gICAgICAgICAgICBjb25zdCBpc0Vycm9yT2JqZWN0ID1cbiAgICAgICAgICAgICAgdHlwZW9mIGVycm9yRGF0YSA9PT0gJ29iamVjdCcgJiYgZXJyb3JEYXRhICE9PSBudWxsO1xuICAgICAgICAgICAgY29uc3QgbXNnID0gaXNFcnJvck9iamVjdFxuICAgICAgICAgICAgICA/ICgoKGVycm9yRGF0YSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikubWVzc2FnZSBhcyBzdHJpbmcpID8/XG4gICAgICAgICAgICAgICAgJ1N0ZXAgZmFpbGVkJylcbiAgICAgICAgICAgICAgOiB0eXBlb2YgZXJyb3JEYXRhID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgID8gZXJyb3JEYXRhXG4gICAgICAgICAgICAgICAgOiAnU3RlcCBmYWlsZWQnO1xuICAgICAgICAgICAgY29uc3QgZXJyb3JTdGFjayA9XG4gICAgICAgICAgICAgIChpc0Vycm9yT2JqZWN0XG4gICAgICAgICAgICAgICAgPyAoZXJyb3JEYXRhIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5zdGFja1xuICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkKSA/PyAoZXZlbnREYXRhPy5zdGFjayBhcyBzdHJpbmcgfCB1bmRlZmluZWQpO1xuICAgICAgICAgICAgY29uc3Qgc3RhY2tBc3NpZ25tZW50ID0gZXJyb3JTdGFja1xuICAgICAgICAgICAgICA/IGBlLnN0YWNrPSR7SlNPTi5zdHJpbmdpZnkoZXJyb3JTdGFjayl9O2BcbiAgICAgICAgICAgICAgOiAnJztcbiAgICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgICBgKGZ1bmN0aW9uKCl7dmFyIGU9bmV3IEVycm9yKCR7SlNPTi5zdHJpbmdpZnkobXNnKX0pO2UubmFtZT1cIkZhdGFsRXJyb3JcIjtlLmZhdGFsPXRydWU7JHtzdGFja0Fzc2lnbm1lbnR9YCArXG4gICAgICAgICAgICAgICAgYGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dLnJlamVjdChlKTtgICtcbiAgICAgICAgICAgICAgICBgZGVsZXRlIGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dO30pKClgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAge1xuICAgICAgICAgICAgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgbGV0IGI6IG51bWJlcjtcbiAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgYiA9IHZtLmV4ZWN1dGVQZW5kaW5nSm9icygpO1xuICAgICAgICAgICAgfSB3aGlsZSAoYiA+IDApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBObyByZXNvbHZlciB5ZXQg4oCUIGJ1ZmZlciB0aGUgcHJlcGFyZWQgcmVqZWN0aW9uIChzZWUgdGhlXG4gICAgICAgICAgLy8gc3RlcF9jb21wbGV0ZWQgYnJhbmNoIGFib3ZlIGZvciB0aGUgcmF0aW9uYWxlKS5cbiAgICAgICAgICBjb25zdCBlcnJvckRhdGEgPSBldmVudERhdGE/LmVycm9yO1xuICAgICAgICAgIGlmIChlcnJvckRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgICBjb25zdCBkZWNyeXB0ZWQgPSBhd2FpdCBwcmVwYXJlQnl0ZXNGb3JWTShlcnJvckRhdGEsIGVuY3J5cHRpb25LZXkpO1xuICAgICAgICAgICAgY29uc3QgYnl0ZXNIYW5kbGUgPSB2bS5uZXdVaW50OEFycmF5KGRlY3J5cHRlZCk7XG4gICAgICAgICAgICB2bS5zZXRQcm9wKHZtLmdsb2JhbCwgJ19fdG1wX2J1ZicsIGJ5dGVzSGFuZGxlKTtcbiAgICAgICAgICAgIGJ5dGVzSGFuZGxlLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX3Rlcm1pbmFsQnVmZmVyWyR7Y2lkSnN9XSA9IHsga2luZDogXCJyZWplY3RfYnl0ZXNcIiwgYnl0ZXM6IGdsb2JhbFRoaXMuX190bXBfYnVmIH07YCArXG4gICAgICAgICAgICAgICAgYGRlbGV0ZSBnbG9iYWxUaGlzLl9fdG1wX2J1ZjtgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgaXNFcnJvck9iamVjdCA9XG4gICAgICAgICAgICAgIHR5cGVvZiBlcnJvckRhdGEgPT09ICdvYmplY3QnICYmIGVycm9yRGF0YSAhPT0gbnVsbDtcbiAgICAgICAgICAgIGNvbnN0IG1zZyA9IGlzRXJyb3JPYmplY3RcbiAgICAgICAgICAgICAgPyAoKChlcnJvckRhdGEgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLm1lc3NhZ2UgYXMgc3RyaW5nKSA/P1xuICAgICAgICAgICAgICAgICdTdGVwIGZhaWxlZCcpXG4gICAgICAgICAgICAgIDogdHlwZW9mIGVycm9yRGF0YSA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICAgICA/IGVycm9yRGF0YVxuICAgICAgICAgICAgICAgIDogJ1N0ZXAgZmFpbGVkJztcbiAgICAgICAgICAgIGNvbnN0IGVycm9yU3RhY2sgPVxuICAgICAgICAgICAgICAoaXNFcnJvck9iamVjdFxuICAgICAgICAgICAgICAgID8gKGVycm9yRGF0YSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikuc3RhY2tcbiAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZCkgPz8gKGV2ZW50RGF0YT8uc3RhY2sgYXMgc3RyaW5nIHwgdW5kZWZpbmVkKTtcbiAgICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX3Rlcm1pbmFsQnVmZmVyWyR7Y2lkSnN9XSA9IHsga2luZDogXCJyZWplY3RfZXJyb3JcIiwgbWVzc2FnZTogJHtKU09OLnN0cmluZ2lmeShtc2cpfSwgc3RhY2s6ICR7ZXJyb3JTdGFjayA/IEpTT04uc3RyaW5naWZ5KGVycm9yU3RhY2spIDogJ3VuZGVmaW5lZCd9IH07YFxuICAgICAgICAgICAgKS5kaXNwb3NlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG1hcmtDcmVhdGVkKHZtLCBjaWRKcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnd2FpdF9jb21wbGV0ZWQnOiB7XG4gICAgICAgIGNvbnN0IGhhc1Jlc29sdmVyID0gdm0uZHVtcChcbiAgICAgICAgICB2bS5ldmFsQ29kZShgISFnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XWApXG4gICAgICAgICk7XG4gICAgICAgIGlmIChoYXNSZXNvbHZlcikge1xuICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgYGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dLnJlc29sdmUoKTtgICtcbiAgICAgICAgICAgICAgYGRlbGV0ZSBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XTtgXG4gICAgICAgICAgKS5kaXNwb3NlKCk7XG4gICAgICAgICAge1xuICAgICAgICAgICAgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgbGV0IGI6IG51bWJlcjtcbiAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgYiA9IHZtLmV4ZWN1dGVQZW5kaW5nSm9icygpO1xuICAgICAgICAgICAgfSB3aGlsZSAoYiA+IDApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBObyByZXNvbHZlciB5ZXQg4oCUIGJ1ZmZlciAoc2VlIHN0ZXBfY29tcGxldGVkIGFib3ZlKS5cbiAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fdGVybWluYWxCdWZmZXJbJHtjaWRKc31dID0geyBraW5kOiBcInJlc29sdmVfdW5kZWZpbmVkXCIgfTtgXG4gICAgICAgICAgKS5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgbWFya0NyZWF0ZWQodm0sIGNpZEpzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdhdHRyX3NldCc6IHtcbiAgICAgICAgLy8gT25seSB3b3JrZmxvdy13cml0dGVuIGF0dHJpYnV0ZSBldmVudHMgcmVzb2x2ZSBhIHBlbmRpbmdcbiAgICAgICAgLy8gc2V0QXR0cmlidXRlcygpIHByb21pc2U7IHN0ZXAvc3lzdGVtIHdyaXRlcnMgc2hhcmUgbm9cbiAgICAgICAgLy8gY29ycmVsYXRpb25JZHMgd2l0aCBWTSByZXNvbHZlcnMsIHNvIHRoZSBndWFyZCBpcyBkZWZlbnNpdmUuXG4gICAgICAgIGNvbnN0IHdyaXRlciA9IChldmVudERhdGE/LndyaXRlciBhcyB7IHR5cGU/OiBzdHJpbmcgfSB8IHVuZGVmaW5lZClcbiAgICAgICAgICA/LnR5cGU7XG4gICAgICAgIGlmICh3cml0ZXIgIT09ICd3b3JrZmxvdycpIGJyZWFrO1xuICAgICAgICBjb25zdCBoYXNSZXNvbHZlciA9IHZtLmR1bXAoXG4gICAgICAgICAgdm0uZXZhbENvZGUoYCEhZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV1gKVxuICAgICAgICApO1xuICAgICAgICBpZiAoIWhhc1Jlc29sdmVyKSB7XG4gICAgICAgICAgLy8gTm8gcmVzb2x2ZXIgeWV0IOKAlCBidWZmZXIgKHNlZSBzdGVwX2NvbXBsZXRlZCBhYm92ZSkuXG4gICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX3Rlcm1pbmFsQnVmZmVyWyR7Y2lkSnN9XSA9IHsga2luZDogXCJyZXNvbHZlX3VuZGVmaW5lZFwiIH07YFxuICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNSZXNvbHZlcikge1xuICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgYGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dLnJlc29sdmUoKTtgICtcbiAgICAgICAgICAgICAgYGRlbGV0ZSBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XTtgXG4gICAgICAgICAgKS5kaXNwb3NlKCk7XG4gICAgICAgICAge1xuICAgICAgICAgICAgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgbGV0IGI6IG51bWJlcjtcbiAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgYiA9IHZtLmV4ZWN1dGVQZW5kaW5nSm9icygpO1xuICAgICAgICAgICAgfSB3aGlsZSAoYiA+IDApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBtYXJrQ3JlYXRlZCh2bSwgY2lkSnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2hvb2tfcmVjZWl2ZWQnOiB7XG4gICAgICAgIC8vIENoZWNrIGlmIHRoaXMgZXZlbnQgd2FzIGFscmVhZHkgcHJvY2Vzc2VkIChkZWxpdmVyZWQgb3JcbiAgICAgICAgLy8gYnVmZmVyZWQpIHdpdGhpbiB0aGlzIGludm9jYXRpb24uIFByZXZlbnRzIGRvdWJsZS1kZWxpdmVyeSB3aGVuXG4gICAgICAgIC8vIHRoZSBvdXRlciBsb29wIHJlLXNjYW5zIGV2ZW50cy5cbiAgICAgICAgY29uc3QgYWxyZWFkeVByb2Nlc3NlZCA9IGV2ZW50LmV2ZW50SWRcbiAgICAgICAgICA/IHZtLmR1bXAoXG4gICAgICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgICAgIGAhIShnbG9iYWxUaGlzLl9faG9va1BheWxvYWRCdWZmZXIuX19wcm9jZXNzZWRFdmVudElkcyAmJiBnbG9iYWxUaGlzLl9faG9va1BheWxvYWRCdWZmZXIuX19wcm9jZXNzZWRFdmVudElkc1ske0pTT04uc3RyaW5naWZ5KGV2ZW50LmV2ZW50SWQpfV0pYFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiBmYWxzZTtcbiAgICAgICAgaWYgKGFscmVhZHlQcm9jZXNzZWQpIHtcbiAgICAgICAgICBydW50aW1lTG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgJ1F1aWNrSlMgcnVudGltZTogaG9va19yZWNlaXZlZCBhbHJlYWR5IHByb2Nlc3NlZCcsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IGNpZCxcbiAgICAgICAgICAgICAgZXZlbnRJZDogZXZlbnQuZXZlbnRJZCxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICAgIG1hcmtDcmVhdGVkKHZtLCBjaWRKcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZXNpbGllbnQtcmVzdW1lIGRlZHVwIChwYXJpdHkgd2l0aCB0aGUgbm9kZSBlbmdpbmUnc1xuICAgICAgICAvLyBFdmVudHNDb25zdW1lciBpbiB3b3JrZmxvdy9ob29rLnRzKTogdHdvIGhvb2tfcmVjZWl2ZWQgcm93cyBmb3JcbiAgICAgICAgLy8gT05FIHJlc3VtZSBhdHRlbXB0IHNoYXJlIGEgY2xpZW50LW1pbnRlZCBgcmVzdW1lSWRgIChhIGR1cGxpY2F0ZVxuICAgICAgICAvLyBjYW4gYmUgY29tbWl0dGVkIHdoZW4gdGhlIG1hdGVyaWFsaXphdGlvbiBmYWxsYmFjayByYWNlcyBhXG4gICAgICAgIC8vIGRlbGF5ZWQgZGlyZWN0IHdyaXRlIOKAlCBob29rX3JlY2VpdmVkIGhhcyBubyBzdG9yYWdlIHVuaXF1ZW5lc3NcbiAgICAgICAgLy8gY29uc3RyYWludCkuIERlbGl2ZXIgb25seSB0aGUgZmlyc3QtaW4tbG9nIG9jY3VycmVuY2UuIFRoZSBzZWVuXG4gICAgICAgIC8vIHNldCBsaXZlcyBpbiB0aGUgVk0gaGVhcCBzbyBpdCBpcyBkZXRlcm1pbmlzdGljIHBlciByZXBsYXkgYW5kXG4gICAgICAgIC8vIHN1cnZpdmVzIGV2ZW50IHJlLXNjYW5zIHdpdGhpbiB0aGUgaW52b2NhdGlvbi4gRXZlbnRzIHdpdGhvdXQgYVxuICAgICAgICAvLyByZXN1bWVJZCAob2xkZXIgU0RLcykgYXJlIG5ldmVyIGRlZHVwZWQuXG4gICAgICAgIHtcbiAgICAgICAgICAvLyBUb3AtbGV2ZWwgZXZlbnQucmVzdW1lSWQgaXMgdGhlIGNhbm9uaWNhbCBsb2NhdGlvbiAodGhlIGJhY2tlbmRcbiAgICAgICAgICAvLyBob2lzdHMgaXQgdG8gYSBmaXJzdC1jbGFzcyBjb2x1bW4pOyB0aGUgbmVzdGVkXG4gICAgICAgICAgLy8gZXZlbnREYXRhLnJlc3VtZUlkIGZvcm0gaXMgYSBkZXByZWNhdGVkIGxlZ2FjeSBmYWxsYmFjayDigJRcbiAgICAgICAgICAvLyBtaXJyb3JzIHRoZSBub2RlIGVuZ2luZSdzIGRlZHVwIGluIHdvcmtmbG93L2hvb2sudHMuXG4gICAgICAgICAgY29uc3QgcmVzdW1lSWQgPVxuICAgICAgICAgICAgKGV2ZW50IGFzIHsgcmVzdW1lSWQ/OiB1bmtub3duIH0pLnJlc3VtZUlkID8/XG4gICAgICAgICAgICAoZXZlbnREYXRhIGFzIHsgcmVzdW1lSWQ/OiB1bmtub3duIH0gfCB1bmRlZmluZWQpPy5yZXN1bWVJZDtcbiAgICAgICAgICBpZiAodHlwZW9mIHJlc3VtZUlkID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uc3QgcmVzdW1lSWRKcyA9IEpTT04uc3RyaW5naWZ5KHJlc3VtZUlkKTtcbiAgICAgICAgICAgIGNvbnN0IGR1cGxpY2F0ZSA9IHZtLmR1bXAoXG4gICAgICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgICAgIGAoZ2xvYmFsVGhpcy5fX2hvb2tTZWVuUmVzdW1lSWRzID0gZ2xvYmFsVGhpcy5fX2hvb2tTZWVuUmVzdW1lSWRzIHx8IHt9KVske3Jlc3VtZUlkSnN9XSA9PT0gdHJ1ZWBcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChkdXBsaWNhdGUpIHtcbiAgICAgICAgICAgICAgcnVudGltZUxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgICAgICAnUXVpY2tKUyBydW50aW1lOiBkdXBsaWNhdGUgaG9va19yZWNlaXZlZCBmb3IgdGhlIHNhbWUgcmVzdW1lIGF0dGVtcHQsIGRyb3BwaW5nJyxcbiAgICAgICAgICAgICAgICB7IGNvcnJlbGF0aW9uSWQ6IGNpZCwgZXZlbnRJZDogZXZlbnQuZXZlbnRJZCwgcmVzdW1lSWQgfVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBpZiAoZXZlbnQuZXZlbnRJZCkge1xuICAgICAgICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgICAgICAgYChnbG9iYWxUaGlzLl9faG9va1BheWxvYWRCdWZmZXIuX19wcm9jZXNzZWRFdmVudElkcyA9IGdsb2JhbFRoaXMuX19ob29rUGF5bG9hZEJ1ZmZlci5fX3Byb2Nlc3NlZEV2ZW50SWRzIHx8IHt9KVske0pTT04uc3RyaW5naWZ5KGV2ZW50LmV2ZW50SWQpfV0gPSB0cnVlO2BcbiAgICAgICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBtYXJrQ3JlYXRlZCh2bSwgY2lkSnMpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX2hvb2tTZWVuUmVzdW1lSWRzWyR7cmVzdW1lSWRKc31dID0gdHJ1ZTtgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBYm9ydCBkZWxpdmVyeTogaG9va19yZWNlaXZlZCBmb3IgYW4gQWJvcnRDb250cm9sbGVyJ3Mgc3lzdGVtXG4gICAgICAgIC8vIGhvb2sgZmxpcHMgdGhlIHJlZ2lzdGVyZWQgc2lnbmFsIGluc3RlYWQgb2YgcmVzb2x2aW5nIGEgcHJvbWlzZS5cbiAgICAgICAgLy8gVGhlIHBheWxvYWQgaXMgdGhlIGRlaHlkcmF0ZWQgYHsgYWJvcnRlZDogdHJ1ZSwgcmVhc29uIH1gIG9iamVjdC5cbiAgICAgICAgY29uc3QgaXNBYm9ydEhvb2sgPSB2bS5kdW1wKFxuICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgYCEhKGdsb2JhbFRoaXMuX19hYm9ydFNpZ25hbHMgJiYgZ2xvYmFsVGhpcy5fX2Fib3J0U2lnbmFsc1ske2NpZEpzfV0pYFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGlzQWJvcnRIb29rKSB7XG4gICAgICAgICAgY29uc3QgcmF3QWJvcnRQYXlsb2FkID0gZXZlbnREYXRhPy5wYXlsb2FkO1xuICAgICAgICAgIGlmIChyYXdBYm9ydFBheWxvYWQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgICBjb25zdCBkZWNyeXB0ZWQgPSBhd2FpdCBwcmVwYXJlQnl0ZXNGb3JWTShcbiAgICAgICAgICAgICAgcmF3QWJvcnRQYXlsb2FkLFxuICAgICAgICAgICAgICBlbmNyeXB0aW9uS2V5XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgYnl0ZXNIYW5kbGUgPSB2bS5uZXdVaW50OEFycmF5KGRlY3J5cHRlZCk7XG4gICAgICAgICAgICB2bS5zZXRQcm9wKHZtLmdsb2JhbCwgJ19fdG1wX2Fib3J0JywgYnl0ZXNIYW5kbGUpO1xuICAgICAgICAgICAgYnl0ZXNIYW5kbGUuZGlzcG9zZSgpO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGAoZnVuY3Rpb24oKXtgICtcbiAgICAgICAgICAgICAgICBgdmFyIHA9Z2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwid29ya2Zsb3ctZGVzZXJpYWxpemVcIildKGdsb2JhbFRoaXMuX190bXBfYWJvcnQpO2AgK1xuICAgICAgICAgICAgICAgIGBkZWxldGUgZ2xvYmFsVGhpcy5fX3RtcF9hYm9ydDtgICtcbiAgICAgICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX2Fib3J0U2lnbmFsc1ske2NpZEpzfV0uX3NldEFib3J0ZWQocCYmdHlwZW9mIHA9PT1cIm9iamVjdFwiP3AucmVhc29uOnVuZGVmaW5lZCk7YCArXG4gICAgICAgICAgICAgICAgYH0pKClgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fYWJvcnRTaWduYWxzWyR7Y2lkSnN9XS5fc2V0QWJvcnRlZCh1bmRlZmluZWQpO2BcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBUaGUgYWJvcnQgaXMgZHVyYWJseSByZWNvcmRlZCDigJQgY2xlYXIgdGhlIHBlbmRpbmcgb3Anc1xuICAgICAgICAgIC8vIGFib3J0UmVxdWVzdGVkIG1hcmtlciBzbyB0aGUgaG9zdCBkb2Vzbid0IHJlLXJlY29yZCBpdCAodGhlXG4gICAgICAgICAgLy8gd29ya2Zsb3cncyBvd24gYWJvcnQoKSBjYWxsIGNhbiBzZXQgdGhlIGZsYWcgYmVmb3JlIHRoaXNcbiAgICAgICAgICAvLyBldmVudCBpcyBwcm9jZXNzZWQgd2hlbiBpdCBoYXBwZW5zIGxhdGVyIGluIHJlcGxheSBvcmRlcixcbiAgICAgICAgICAvLyBhbmQgaG9va19yZWNlaXZlZCBldmVudHMgYXJlIG5vdCB1bmlxdWUgcGVyIGNvcnJlbGF0aW9uSWQpLlxuICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgYChmdW5jdGlvbigpe2AgK1xuICAgICAgICAgICAgICBgdmFyIHA9Z2xvYmFsVGhpcy5fX3BlbmRpbmcuZmluZChmdW5jdGlvbihxKXtyZXR1cm4gcS5jb3JyZWxhdGlvbklkPT09JHtKU09OLnN0cmluZ2lmeShjaWQpfSYmcS50eXBlPT09XCJob29rXCI7fSk7YCArXG4gICAgICAgICAgICAgIGBpZihwKXAuYWJvcnRSZXF1ZXN0ZWQ9ZmFsc2U7YCArXG4gICAgICAgICAgICAgIGB9KSgpYFxuICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIGlmIChldmVudC5ldmVudElkKSB7XG4gICAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgICAgYChnbG9iYWxUaGlzLl9faG9va1BheWxvYWRCdWZmZXIuX19wcm9jZXNzZWRFdmVudElkcyA9IGdsb2JhbFRoaXMuX19ob29rUGF5bG9hZEJ1ZmZlci5fX3Byb2Nlc3NlZEV2ZW50SWRzIHx8IHt9KVske0pTT04uc3RyaW5naWZ5KGV2ZW50LmV2ZW50SWQpfV0gPSB0cnVlO2BcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBsZXQgYjogbnVtYmVyO1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICBiID0gdm0uZXhlY3V0ZVBlbmRpbmdKb2JzKCk7XG4gICAgICAgICAgICB9IHdoaWxlIChiID4gMCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG1hcmtDcmVhdGVkKHZtLCBjaWRKcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBoYXNSZXNvbHZlciA9IHZtLmR1bXAoXG4gICAgICAgICAgdm0uZXZhbENvZGUoYCEhZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV1gKVxuICAgICAgICApO1xuICAgICAgICBjb25zdCByYXdQYXlsb2FkID0gZXZlbnREYXRhPy5wYXlsb2FkID8/IGV2ZW50RGF0YT8ucmVzdWx0O1xuICAgICAgICBydW50aW1lTG9nZ2VyLmRlYnVnKCdRdWlja0pTIHJ1bnRpbWU6IHByb2Nlc3NpbmcgaG9va19yZWNlaXZlZCcsIHtcbiAgICAgICAgICBjb3JyZWxhdGlvbklkOiBjaWQsXG4gICAgICAgICAgZXZlbnRJZDogZXZlbnQuZXZlbnRJZCxcbiAgICAgICAgICBoYXNSZXNvbHZlcixcbiAgICAgICAgICBwYXlsb2FkVHlwZTogdHlwZW9mIHJhd1BheWxvYWQsXG4gICAgICAgICAgcGF5bG9hZElzVWludDhBcnJheTogcmF3UGF5bG9hZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXksXG4gICAgICAgICAgcGF5bG9hZEtleXM6XG4gICAgICAgICAgICByYXdQYXlsb2FkICYmIHR5cGVvZiByYXdQYXlsb2FkID09PSAnb2JqZWN0J1xuICAgICAgICAgICAgICA/IE9iamVjdC5rZXlzKHJhd1BheWxvYWQpXG4gICAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGhhc1Jlc29sdmVyKSB7XG4gICAgICAgICAgaWYgKHJhd1BheWxvYWQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgICAvLyBEZWNyeXB0IGlmIGVuY3J5cHRlZCDigJQgdGhlIFZNIG9ubHkgdW5kZXJzdGFuZHMgJ2RldmwnIGZvcm1hdFxuICAgICAgICAgICAgY29uc3QgZGVjcnlwdGVkUGF5bG9hZCA9IGF3YWl0IHByZXBhcmVCeXRlc0ZvclZNKFxuICAgICAgICAgICAgICByYXdQYXlsb2FkLFxuICAgICAgICAgICAgICBlbmNyeXB0aW9uS2V5XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgYnl0ZXNIYW5kbGUgPSB2bS5uZXdVaW50OEFycmF5KGRlY3J5cHRlZFBheWxvYWQpO1xuICAgICAgICAgICAgdm0uc2V0UHJvcCh2bS5nbG9iYWwsICdfX3RtcF9yZXN1bHQnLCBieXRlc0hhbmRsZSk7XG4gICAgICAgICAgICBieXRlc0hhbmRsZS5kaXNwb3NlKCk7XG4gICAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgICAgYGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dLnJlc29sdmUoZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwid29ya2Zsb3ctZGVzZXJpYWxpemVcIildKGdsb2JhbFRoaXMuX190bXBfcmVzdWx0KSk7YCArXG4gICAgICAgICAgICAgICAgYGRlbGV0ZSBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XTtgICtcbiAgICAgICAgICAgICAgICBgZGVsZXRlIGdsb2JhbFRoaXMuX190bXBfcmVzdWx0O2BcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzZXJpYWxpemVkID1cbiAgICAgICAgICAgICAgcmF3UGF5bG9hZCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyBKU09OLnN0cmluZ2lmeShyYXdQYXlsb2FkKVxuICAgICAgICAgICAgICAgIDogJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgICAgYGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dLnJlc29sdmUoJHtzZXJpYWxpemVkfSk7YCArXG4gICAgICAgICAgICAgICAgYGRlbGV0ZSBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XTtgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gTWFyayB0aGlzIGV2ZW50IGFzIHByb2Nlc3NlZCBpbiB0aGUgVk0gaGVhcCB0byBwcmV2ZW50XG4gICAgICAgICAgLy8gZG91YmxlLWRlbGl2ZXJ5IHdoZW4gdGhlIG91dGVyIGxvb3AgcmUtc2NhbnMgZXZlbnRzLlxuICAgICAgICAgIGlmIChldmVudC5ldmVudElkKSB7XG4gICAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgICAgYChnbG9iYWxUaGlzLl9faG9va1BheWxvYWRCdWZmZXIuX19wcm9jZXNzZWRFdmVudElkcyA9IGdsb2JhbFRoaXMuX19ob29rUGF5bG9hZEJ1ZmZlci5fX3Byb2Nlc3NlZEV2ZW50SWRzIHx8IHt9KVske0pTT04uc3RyaW5naWZ5KGV2ZW50LmV2ZW50SWQpfV0gPSB0cnVlO2BcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBsZXQgYjogbnVtYmVyO1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICBiID0gdm0uZXhlY3V0ZVBlbmRpbmdKb2JzKCk7XG4gICAgICAgICAgICB9IHdoaWxlIChiID4gMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5vIHJlc29sdmVyIHlldCDigJQgYnVmZmVyIHRoZSBwYXlsb2FkIGluIHRoZSBWTSBoZWFwLiBXaGVuXG4gICAgICAgICAgLy8gY3JlYXRlSG9va1Byb21pc2UoKSBpcyBjYWxsZWQgbGF0ZXIsIGl0IHdpbGwgZHJhaW4gdGhpcyBidWZmZXJcbiAgICAgICAgICAvLyBmaXJzdCAobWF0Y2hpbmcgdGhlIG5vZGU6dm0gZW5naW5lJ3MgcGF5bG9hZHNRdWV1ZSBiZWhhdmlvcikuXG4gICAgICAgICAgY29uc3QgZXZlbnRJZEpzID0gZXZlbnQuZXZlbnRJZFxuICAgICAgICAgICAgPyBKU09OLnN0cmluZ2lmeShldmVudC5ldmVudElkKVxuICAgICAgICAgICAgOiAnbnVsbCc7XG4gICAgICAgICAgY29uc3QgYnVmZmVyQW5kVHJhY2sgPVxuICAgICAgICAgICAgYChnbG9iYWxUaGlzLl9faG9va1BheWxvYWRCdWZmZXJbJHtjaWRKc31dID0gZ2xvYmFsVGhpcy5fX2hvb2tQYXlsb2FkQnVmZmVyWyR7Y2lkSnN9XSB8fCBbXSlgICtcbiAgICAgICAgICAgIGAucHVzaCglUEFZTE9BRCUpO2AgK1xuICAgICAgICAgICAgKGV2ZW50LmV2ZW50SWRcbiAgICAgICAgICAgICAgPyBgKGdsb2JhbFRoaXMuX19ob29rUGF5bG9hZEJ1ZmZlci5fX3Byb2Nlc3NlZEV2ZW50SWRzID0gZ2xvYmFsVGhpcy5fX2hvb2tQYXlsb2FkQnVmZmVyLl9fcHJvY2Vzc2VkRXZlbnRJZHMgfHwge30pWyR7ZXZlbnRJZEpzfV0gPSB0cnVlO2BcbiAgICAgICAgICAgICAgOiAnJyk7XG4gICAgICAgICAgaWYgKHJhd1BheWxvYWQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgICAvLyBEZWNyeXB0IGlmIGVuY3J5cHRlZCDigJQgdGhlIFZNIG9ubHkgdW5kZXJzdGFuZHMgJ2RldmwnIGZvcm1hdFxuICAgICAgICAgICAgY29uc3QgZGVjcnlwdGVkUGF5bG9hZCA9IGF3YWl0IHByZXBhcmVCeXRlc0ZvclZNKFxuICAgICAgICAgICAgICByYXdQYXlsb2FkLFxuICAgICAgICAgICAgICBlbmNyeXB0aW9uS2V5XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgYnl0ZXNIYW5kbGUgPSB2bS5uZXdVaW50OEFycmF5KGRlY3J5cHRlZFBheWxvYWQpO1xuICAgICAgICAgICAgdm0uc2V0UHJvcCh2bS5nbG9iYWwsICdfX3RtcF9yZXN1bHQnLCBieXRlc0hhbmRsZSk7XG4gICAgICAgICAgICBieXRlc0hhbmRsZS5kaXNwb3NlKCk7XG4gICAgICAgICAgICAvLyBOT1RFOiByZXBsYWNlbWVudCBpcyBhIGZ1bmN0aW9uIHNvIGAkYC1zZXF1ZW5jZXMgaW4gdGhlXG4gICAgICAgICAgICAvLyBzdWJzdGl0dXRlZCBKUyBuZXZlciBnZXQgaW50ZXJwcmV0ZWQgYXMgU3RyaW5nLnJlcGxhY2VcbiAgICAgICAgICAgIC8vIHNwZWNpYWwgcmVwbGFjZW1lbnQgcGF0dGVybnMuXG4gICAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgICAgYnVmZmVyQW5kVHJhY2sucmVwbGFjZShcbiAgICAgICAgICAgICAgICAnJVBBWUxPQUQlJyxcbiAgICAgICAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgICAgICAgJ2dsb2JhbFRoaXNbU3ltYm9sLmZvcihcIndvcmtmbG93LWRlc2VyaWFsaXplXCIpXShnbG9iYWxUaGlzLl9fdG1wX3Jlc3VsdCknXG4gICAgICAgICAgICAgICkgKyAnZGVsZXRlIGdsb2JhbFRoaXMuX190bXBfcmVzdWx0OydcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzZXJpYWxpemVkID1cbiAgICAgICAgICAgICAgcmF3UGF5bG9hZCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyBKU09OLnN0cmluZ2lmeShyYXdQYXlsb2FkKVxuICAgICAgICAgICAgICAgIDogJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICAvLyBGdW5jdGlvbiByZXBsYWNlbWVudDogYSBKU09OLXNlcmlhbGl6ZWQgcGF5bG9hZCBjYW4gY29udGFpblxuICAgICAgICAgICAgLy8gYCQmYCwgYCQnYCwgYCRcXGBgLCAuLi4gd2hpY2ggU3RyaW5nLnJlcGxhY2Ugd291bGQgb3RoZXJ3aXNlXG4gICAgICAgICAgICAvLyBleHBhbmQsIHNpbGVudGx5IGNvcnJ1cHRpbmcgdGhlIGluamVjdGVkIGNvZGUuXG4gICAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgICAgYnVmZmVyQW5kVHJhY2sucmVwbGFjZSgnJVBBWUxPQUQlJywgKCkgPT4gc2VyaWFsaXplZClcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBtYXJrQ3JlYXRlZCh2bSwgY2lkSnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2hvb2tfY29uZmxpY3QnOiB7XG4gICAgICAgIC8vIEFub3RoZXIgd29ya2Zsb3cgb3ducyB0aGlzIGhvb2sgdG9rZW4uIFBheWxvYWQgYXdhaXRlcnMgcmVqZWN0XG4gICAgICAgIC8vIHdpdGggSG9va0NvbmZsaWN0RXJyb3I7IGdldENvbmZsaWN0KCkgYXdhaXRlcnMgcmVzb2x2ZSB3aXRoIGFcbiAgICAgICAgLy8gUnVuIGhhbmRsZSBmb3IgdGhlIGNvbmZsaWN0aW5nIHJ1biAocmV2aXZlZCB0aHJvdWdoIHRoZSBWTSdzXG4gICAgICAgIC8vIGNsYXNzIHJlZ2lzdHJ5IHNvIGl0cyBtZXRob2RzIGFyZSBkdXJhYmxlIHN0ZXAgcHJveGllcykgb3JcbiAgICAgICAgLy8gcmVqZWN0IHdpdGggdGhlIGVycm9yIHdoZW4gbm8gaGFuZGxlIGNhbiBiZSBjb25zdHJ1Y3RlZCDigJRcbiAgICAgICAgLy8gbWlycm9yaW5nIHRoZSBub2RlOnZtIGVuZ2luZSdzIGhvb2sudHMgaG9va19jb25mbGljdCBoYW5kbGluZy5cbiAgICAgICAgY29uc3QgY29uZmxpY3RUb2tlbiA9IChldmVudERhdGE/LnRva2VuIGFzIHN0cmluZykgPz8gJ3Vua25vd24nO1xuICAgICAgICBjb25zdCBjb25mbGljdGluZ1J1bklkID0gZXZlbnREYXRhPy5jb25mbGljdGluZ1J1bklkIGFzXG4gICAgICAgICAgfCBzdHJpbmdcbiAgICAgICAgICB8IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgZGlkU2V0dGxlID0gdm0uZHVtcChcbiAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgIGAoZnVuY3Rpb24oKXtcbiAgICAgICAgICAgICAgdmFyIGNpZCA9ICR7SlNPTi5zdHJpbmdpZnkoY2lkKX07XG4gICAgICAgICAgICAgIHZhciB0b2tlbiA9ICR7SlNPTi5zdHJpbmdpZnkoY29uZmxpY3RUb2tlbil9O1xuICAgICAgICAgICAgICB2YXIgY29uZmxpY3RpbmdSdW5JZCA9ICR7SlNPTi5zdHJpbmdpZnkoY29uZmxpY3RpbmdSdW5JZCA/PyBudWxsKX07XG4gICAgICAgICAgICAgIHZhciBFcnJDbHMgPSBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoJ0B3b3JrZmxvdy9lcnJvcnMvL0hvb2tDb25mbGljdEVycm9yJyldO1xuICAgICAgICAgICAgICB2YXIgZXJyO1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIEVyckNscyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIGVyciA9IG5ldyBFcnJDbHModG9rZW4sIGNvbmZsaWN0aW5nUnVuSWQgfHwgdW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBlcnIgPSBuZXcgRXJyb3IoJ0hvb2sgdG9rZW4gXCInICsgdG9rZW4gKyAnXCIgaXMgYWxyZWFkeSBpbiB1c2UgYnkgYW5vdGhlciB3b3JrZmxvdycpO1xuICAgICAgICAgICAgICAgIGVyci5uYW1lID0gJ0hvb2tDb25mbGljdEVycm9yJztcbiAgICAgICAgICAgICAgICBlcnIudG9rZW4gPSB0b2tlbjtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmxpY3RpbmdSdW5JZCkgZXJyLmNvbmZsaWN0aW5nUnVuSWQgPSBjb25mbGljdGluZ1J1bklkO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHZhciBydW4gPSBudWxsO1xuICAgICAgICAgICAgICBpZiAoY29uZmxpY3RpbmdSdW5JZCkge1xuICAgICAgICAgICAgICAgIHZhciByZWcgPSBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoJ3dvcmtmbG93LWNsYXNzLXJlZ2lzdHJ5JyldO1xuICAgICAgICAgICAgICAgIHZhciBSdW5DbHMgPSByZWcgJiYgcmVnLmdldCgnY2xhc3MvL3dvcmtmbG93Ly9SdW4nKTtcbiAgICAgICAgICAgICAgICB2YXIgZGVzID0gUnVuQ2xzICYmIFJ1bkNsc1tTeW1ib2wuZm9yKCd3b3JrZmxvdy1kZXNlcmlhbGl6ZScpXTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGRlcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgcnVuID0gZGVzLmNhbGwoUnVuQ2xzLCB7IHJ1bklkOiBjb25mbGljdGluZ1J1bklkIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB2YXIgc2V0dGxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICB2YXIgc3RhdGUgPSBnbG9iYWxUaGlzLl9faG9va3MgJiYgZ2xvYmFsVGhpcy5fX2hvb2tzW2NpZF07XG4gICAgICAgICAgICAgIGlmIChzdGF0ZSAmJiAhc3RhdGUuY29uZmxpY3QpIHtcbiAgICAgICAgICAgICAgICBzdGF0ZS5jb25mbGljdCA9IHsgZXJyb3I6IGVyciwgcnVuOiBydW4gfTtcbiAgICAgICAgICAgICAgICB2YXIgZ2MgPSBzdGF0ZS5nZXRDb25mbGljdFJlc29sdmVycztcbiAgICAgICAgICAgICAgICBzdGF0ZS5nZXRDb25mbGljdFJlc29sdmVycyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ2MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgIGlmIChydW4pIHsgZ2NbaV0ucmVzb2x2ZShydW4pOyB9IGVsc2UgeyBnY1tpXS5yZWplY3QoZXJyKTsgfVxuICAgICAgICAgICAgICAgICAgc2V0dGxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzW2NpZF0pIHtcbiAgICAgICAgICAgICAgICBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzW2NpZF0ucmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbY2lkXTtcbiAgICAgICAgICAgICAgICBzZXR0bGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gc2V0dGxlZDtcbiAgICAgICAgICAgIH0pKClgXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICBpZiAoZGlkU2V0dGxlKSB7XG4gICAgICAgICAgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgIGxldCBiOiBudW1iZXI7XG4gICAgICAgICAgZG8ge1xuICAgICAgICAgICAgYiA9IHZtLmV4ZWN1dGVQZW5kaW5nSm9icygpO1xuICAgICAgICAgIH0gd2hpbGUgKGIgPiAwKTtcbiAgICAgICAgfVxuICAgICAgICBtYXJrQ3JlYXRlZCh2bSwgY2lkSnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3N0ZXBfY3JlYXRlZCc6XG4gICAgICBjYXNlICdzdGVwX3N0YXJ0ZWQnOlxuICAgICAgY2FzZSAnc3RlcF9yZXRyeWluZyc6XG4gICAgICBjYXNlICd3YWl0X2NyZWF0ZWQnOiB7XG4gICAgICAgIG1hcmtDcmVhdGVkKHZtLCBjaWRKcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnaG9va19jcmVhdGVkJzoge1xuICAgICAgICAvLyBDb25maXJtIGNyZWF0aW9uIGZvciBnZXRDb25mbGljdCgpIGF3YWl0ZXJzOiByZXNvbHZlIHRoZW0gd2l0aFxuICAgICAgICAvLyBudWxsIChubyBjb25mbGljdCkgb25jZSB0aGUgZXZlbnQgbG9nIHByb3ZlcyB0aGUgaG9vayBleGlzdHMuXG4gICAgICAgIGNvbnN0IHNldHRsZWRHZXRDb25mbGljdCA9IHZtLmR1bXAoXG4gICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICBgKGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICAgIHZhciBzdGF0ZSA9IGdsb2JhbFRoaXMuX19ob29rcyAmJiBnbG9iYWxUaGlzLl9faG9va3NbJHtKU09OLnN0cmluZ2lmeShjaWQpfV07XG4gICAgICAgICAgICAgIGlmICghc3RhdGUpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgc3RhdGUuY3JlYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgIHZhciBnYyA9IHN0YXRlLmdldENvbmZsaWN0UmVzb2x2ZXJzO1xuICAgICAgICAgICAgICBzdGF0ZS5nZXRDb25mbGljdFJlc29sdmVycyA9IFtdO1xuICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGdjLmxlbmd0aDsgaSsrKSBnY1tpXS5yZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgICByZXR1cm4gZ2MubGVuZ3RoID4gMDtcbiAgICAgICAgICAgIH0pKClgXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICBpZiAoc2V0dGxlZEdldENvbmZsaWN0KSB7XG4gICAgICAgICAgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgIGxldCBiOiBudW1iZXI7XG4gICAgICAgICAgZG8ge1xuICAgICAgICAgICAgYiA9IHZtLmV4ZWN1dGVQZW5kaW5nSm9icygpO1xuICAgICAgICAgIH0gd2hpbGUgKGIgPiAwKTtcbiAgICAgICAgfVxuICAgICAgICBtYXJrQ3JlYXRlZCh2bSwgY2lkSnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2hvb2tfZGlzcG9zZWQnOiB7XG4gICAgICAgIC8vIERpc2FtYmlndWF0ZSBmcm9tIHRoZSBgaG9va2AgcGVuZGluZyBvcCB3aXRoIHRoZSBzYW1lXG4gICAgICAgIC8vIGNvcnJlbGF0aW9uSWQg4oCUIHdlIHdhbnQgdG8gbWFyayB0aGUgYGhvb2tfZGlzcG9zZWAgZW50cnkuXG4gICAgICAgIG1hcmtDcmVhdGVkKHZtLCBjaWRKcywgJ2hvb2tfZGlzcG9zZScpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc29sdmVkO1xufVxuXG5mdW5jdGlvbiBtYXJrQ3JlYXRlZCh2bTogUXVpY2tKUywgY2lkSnM6IHN0cmluZywgb3BUeXBlPzogc3RyaW5nKTogdm9pZCB7XG4gIC8vIGBjaWRKc2AgaXMgdGhlIEpTT04uc3RyaW5naWZ5LXF1b3RlZCBjb3JyZWxhdGlvbiBpZCAoc2VlIHByb2Nlc3NFdmVudHMpLlxuICAvLyBgaG9va2AgYW5kIGBob29rX2Rpc3Bvc2VgIHBlbmRpbmcgb3BzIHNoYXJlIHRoZSBzYW1lIGNvcnJlbGF0aW9uSWQsXG4gIC8vIHNvIHdoZW4gcHJvY2Vzc2luZyBgaG9va19kaXNwb3NlZGAgZXZlbnRzIHdlIG11c3QgZGlzYW1iaWd1YXRlIGJ5XG4gIC8vIHR5cGUg4oCUIG90aGVyd2lzZSBgLmZpbmQoKWAgcmV0dXJucyB0aGUgb3JpZ2luYWwgYGhvb2tgIG9wIGFuZCB0aGVcbiAgLy8gYGhvb2tfZGlzcG9zZWAgb3AgaXMgbmV2ZXIgbWFya2VkLCBjYXVzaW5nIHRoZSBlbnRyeXBvaW50IHRvIGtlZXBcbiAgLy8gcmV0cnlpbmcgYSBob29rX2Rpc3Bvc2VkIGZvciBhbiBhbHJlYWR5LWRlbGV0ZWQgZW50aXR5LlxuICBjb25zdCBwcmVkaWNhdGUgPSBvcFR5cGVcbiAgICA/IGBmdW5jdGlvbihwKXtyZXR1cm4gcC5jb3JyZWxhdGlvbklkPT09JHtjaWRKc30mJnAudHlwZT09PSR7SlNPTi5zdHJpbmdpZnkob3BUeXBlKX07fWBcbiAgICA6IGBmdW5jdGlvbihwKXtyZXR1cm4gcC5jb3JyZWxhdGlvbklkPT09JHtjaWRKc307fWA7XG4gIHZtLmV2YWxDb2RlKFxuICAgIGB2YXIgX19wPWdsb2JhbFRoaXMuX19wZW5kaW5nLmZpbmQoJHtwcmVkaWNhdGV9KTtgICtcbiAgICAgIGBpZihfX3ApX19wLmhhc0NyZWF0ZWRFdmVudD10cnVlO2BcbiAgKS5kaXNwb3NlKCk7XG59XG5cbi8vIC0tLS0gU3RhdGUgQ2hlY2tpbmcgLS0tLVxuXG4vKipcbiAqIENvbGxlY3QgbGVmdG92ZXIgcGVuZGluZyBvcGVyYXRpb25zIHRoYXQgbmVlZCBkdXJhYmxlIHNpZGUgZWZmZWN0cyB3aGVuXG4gKiB0aGUgd29ya2Zsb3cgcmVhY2hlcyBhIHRlcm1pbmFsIHN0YXRlLiBNaXJyb3JzIHRoZSBub2RlOnZtIGVuZ2luZSdzXG4gKiBkcmFpblBlbmRpbmdRdWV1ZUl0ZW1zICh3b3JrZmxvdy50cyk6IHN0aWxsLWFsaXZlIHN5c3RlbSBob29rc1xuICogKEFib3J0Q29udHJvbGxlcikgd2l0aG91dCBhbiBhYm9ydCBpbiBmbGlnaHQgYXJlIGltcGxpY2l0bHkgZGlzcG9zZWQgc29cbiAqIHRoZXkgZG9uJ3QgbGVhayBob29rIHJvd3M7IG9wcyB3aXRob3V0IGNyZWF0ZWQgZXZlbnRzIChmaXJlLWFuZC1mb3JnZXRcbiAqIGF0dHJpYnV0ZXMvaG9va3Mvc3RlcHMvd2FpdHMpIGFuZCBwZW5kaW5nIGFib3J0IHJlY29yZGluZ3MgYXJlIHN1cmZhY2VkXG4gKiBmb3IgdGhlIGVudHJ5cG9pbnQgdG8gZmx1c2guXG4gKi9cbmZ1bmN0aW9uIGNvbGxlY3REcmFpbk9wZXJhdGlvbnModm06IFF1aWNrSlMpOiBQZW5kaW5nT3BlcmF0aW9uW10ge1xuICB1c2luZyBoID0gdm0uZXZhbENvZGUoYChmdW5jdGlvbigpe1xuICAgIHZhciB0b0Rpc3Bvc2UgPSBbXTtcbiAgICBnbG9iYWxUaGlzLl9fcGVuZGluZy5mb3JFYWNoKGZ1bmN0aW9uKHApe1xuICAgICAgaWYgKHAudHlwZSA9PT0gXCJob29rXCIgJiYgcC5pc1N5c3RlbSAmJiAhcC5hYm9ydFJlcXVlc3RlZCAmJiAhcC5kaXNwb3NlZCkge1xuICAgICAgICBwLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgLy8gT25seSBkaXNwb3NlIGhvb2tzIHRoYXQgd2VyZSBkdXJhYmx5IGNyZWF0ZWQ7IGEgaG9vayB0aGF0IG5ldmVyXG4gICAgICAgIC8vIHJlYWNoZWQgc3RvcmFnZSBoYXMgbm90aGluZyB0byBjbGVhbiB1cC5cbiAgICAgICAgaWYgKHAuaGFzQ3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgdG9EaXNwb3NlLnB1c2goe1xuICAgICAgICAgICAgdHlwZTogXCJob29rX2Rpc3Bvc2VcIixcbiAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHAuY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgIGhhc0NyZWF0ZWRFdmVudDogZmFsc2UsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICB0b0Rpc3Bvc2UuZm9yRWFjaChmdW5jdGlvbihkKXsgZ2xvYmFsVGhpcy5fX3BlbmRpbmcucHVzaChkKTsgfSk7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXMuX19wZW5kaW5nLmZpbHRlcihmdW5jdGlvbihwKXtcbiAgICAgIGlmIChwLmFib3J0UmVxdWVzdGVkKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGlmIChwLmhhc0NyZWF0ZWRFdmVudCkgcmV0dXJuIGZhbHNlO1xuICAgICAgLy8gU2tpcCBzeXN0ZW0gaG9va3MgdGhhdCB3ZXJlIGRpc3Bvc2VkIGJlZm9yZSBldmVyIGJlaW5nIGNyZWF0ZWQuXG4gICAgICBpZiAocC50eXBlID09PSBcImhvb2tcIiAmJiBwLmRpc3Bvc2VkKSByZXR1cm4gZmFsc2U7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcbiAgfSkoKWApO1xuICByZXR1cm4gdm0uZHVtcChoKSBhcyBQZW5kaW5nT3BlcmF0aW9uW107XG59XG5cbmZ1bmN0aW9uIGNoZWNrV29ya2Zsb3dTdGF0ZShcbiAgdm06IFF1aWNrSlMsXG4gIG9wdHM6IHsga2VlcEFsaXZlT25TdXNwZW5kPzogYm9vbGVhbiB9ID0ge31cbik6IFF1aWNrSlNSdW50aW1lUmVzdWx0IHtcbiAgLy8gQ2hlY2sgY29tcGxldGVkIOKAlCBfX3dvcmtmbG93UmVzdWx0IGlzIGEgZm9ybWF0LXByZWZpeGVkIFVpbnQ4QXJyYXlcbiAge1xuICAgIHVzaW5nIGggPSB2bS5ldmFsQ29kZSgnZ2xvYmFsVGhpcy5fX3dvcmtmbG93UmVzdWx0Jyk7XG4gICAgaWYgKCFoLmlzVW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCByZXN1bHRCeXRlcyA9IGgudG9VaW50OEFycmF5KCk7XG4gICAgICBjb25zdCBkcmFpbk9wZXJhdGlvbnMgPSBjb2xsZWN0RHJhaW5PcGVyYXRpb25zKHZtKTtcbiAgICAgIHZtLmRpc3Bvc2UoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbXBsZXRlZDoge1xuICAgICAgICAgIHJlc3VsdDogcmVzdWx0Qnl0ZXMsXG4gICAgICAgICAgLi4uKGRyYWluT3BlcmF0aW9ucy5sZW5ndGggPiAwID8geyBkcmFpbk9wZXJhdGlvbnMgfSA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgZmFpbGVkXG4gIHtcbiAgICB1c2luZyBoID0gdm0uZXZhbENvZGUoJ2dsb2JhbFRoaXMuX193b3JrZmxvd0Vycm9yJyk7XG4gICAgaWYgKCFoLmlzVW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBlcnJvck9iaiA9IHZtLmR1bXAoaCkgYXNcbiAgICAgICAgfCB7XG4gICAgICAgICAgICBtZXNzYWdlOiBzdHJpbmc7XG4gICAgICAgICAgICBzdGFjaz86IHN0cmluZztcbiAgICAgICAgICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgICAgICAgICB2YWx1ZUJ5dGVzPzogVWludDhBcnJheTtcbiAgICAgICAgICB9XG4gICAgICAgIHwgc3RyaW5nO1xuICAgICAgY29uc3QgZmFpbGVkID1cbiAgICAgICAgdHlwZW9mIGVycm9yT2JqID09PSAnc3RyaW5nJ1xuICAgICAgICAgID8geyBtZXNzYWdlOiBlcnJvck9iaiB9XG4gICAgICAgICAgOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yT2JqLm1lc3NhZ2UsXG4gICAgICAgICAgICAgIHN0YWNrOiBlcnJvck9iai5zdGFjayB8fCB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIG5hbWU6IGVycm9yT2JqLm5hbWUgfHwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB2YWx1ZUJ5dGVzOiBlcnJvck9iai52YWx1ZUJ5dGVzLFxuICAgICAgICAgICAgfTtcbiAgICAgIHJ1bnRpbWVMb2dnZXIuZXJyb3IoJ1F1aWNrSlMgcnVudGltZTogd29ya2Zsb3cgZmFpbGVkIGluIFZNJywge1xuICAgICAgICBlcnJvck1lc3NhZ2U6IGZhaWxlZC5tZXNzYWdlLFxuICAgICAgICBlcnJvck5hbWU6IGZhaWxlZC5uYW1lLFxuICAgICAgICBlcnJvclN0YWNrOiBmYWlsZWQuc3RhY2ssXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGRyYWluT3BlcmF0aW9ucyA9IGNvbGxlY3REcmFpbk9wZXJhdGlvbnModm0pO1xuICAgICAgdm0uZGlzcG9zZSgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZmFpbGVkOiB7XG4gICAgICAgICAgLi4uZmFpbGVkLFxuICAgICAgICAgIC4uLihkcmFpbk9wZXJhdGlvbnMubGVuZ3RoID4gMCA/IHsgZHJhaW5PcGVyYXRpb25zIH0gOiB7fSksXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIC8vIENoZWNrIHN1c3BlbmRlZCDigJQgdGhlIHdvcmtmbG93IGlzIHN1c3BlbmRlZCBpZiB0aGVyZSBhcmUgYWN0aXZlIHJlc29sdmVyc1xuICAvLyBPUiBwZW5kaW5nIG9wZXJhdGlvbnMgdGhhdCBoYXZlbid0IGJlZW4gY3JlYXRlZCB5ZXQgKGUuZy4gaG9va3MgY3JlYXRlZFxuICAvLyB1cGZyb250IGJ1dCBub3QgeWV0IGF3YWl0ZWQpXG4gIHtcbiAgICB1c2luZyBoID0gdm0uZXZhbENvZGUoXG4gICAgICAnT2JqZWN0LmtleXMoZ2xvYmFsVGhpcy5fX3Jlc29sdmVycykubGVuZ3RoID4gMCB8fCBnbG9iYWxUaGlzLl9fcGVuZGluZy5zb21lKGZ1bmN0aW9uKHApe3JldHVybiFwLmhhc0NyZWF0ZWRFdmVudDt9KSdcbiAgICApO1xuICAgIGlmICh2bS5kdW1wKGgpKSB7XG4gICAgICB1c2luZyBwZW5kaW5nSCA9IHZtLmV2YWxDb2RlKFxuICAgICAgICAvLyBPcHMgd2l0aCBhbiBhY3RpdmUgcmVzb2x2ZXIgb3Igd2l0aG91dCBhIGNyZWF0ZWQgZXZlbnQgYXJlXG4gICAgICAgIC8vIHBlbmRpbmc7IGFib3J0LXJlcXVlc3RlZCBob29rcyBhcmUgYWxzbyBzdXJmYWNlZCAoZXZlbiB3aGVuXG4gICAgICAgIC8vIGFscmVhZHkgY3JlYXRlZCBhbmQgdW5hd2FpdGVkKSBzbyB0aGUgaG9zdCByZWNvcmRzIHRoZSBhYm9ydC5cbiAgICAgICAgYGdsb2JhbFRoaXMuX19wZW5kaW5nLmZpbHRlcihmdW5jdGlvbihwKXtyZXR1cm4hIWdsb2JhbFRoaXMuX19yZXNvbHZlcnNbcC5jb3JyZWxhdGlvbklkXSB8fCAhcC5oYXNDcmVhdGVkRXZlbnQgfHwgcC5hYm9ydFJlcXVlc3RlZDt9KWBcbiAgICAgICk7XG4gICAgICBjb25zdCBwZW5kaW5nT3BzID0gdm0uZHVtcChwZW5kaW5nSCkgYXMgUGVuZGluZ09wZXJhdGlvbltdO1xuICAgICAgaWYgKCFvcHRzLmtlZXBBbGl2ZU9uU3VzcGVuZCkgdm0uZGlzcG9zZSgpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdXNwZW5kZWQ6IHtcbiAgICAgICAgICBwZW5kaW5nT3BlcmF0aW9uczogcGVuZGluZ09wcyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgdm0uZGlzcG9zZSgpO1xuICByZXR1cm4geyBmYWlsZWQ6IHsgbWVzc2FnZTogJ1dvcmtmbG93IGVuZGVkIGluIHVua25vd24gc3RhdGUnIH0gfTtcbn1cblxuLy8gLS0tLSBIZWxwZXJzIC0tLS1cblxuZnVuY3Rpb24gZXh0cmFjdEVycm9yKFxuICB2bTogUXVpY2tKUyxcbiAgZXJyOiB1bmtub3duLFxuICBmYWxsYmFja01lc3NhZ2U6IHN0cmluZ1xuKTogUXVpY2tKU1J1bnRpbWVSZXN1bHQge1xuICBsZXQgbWVzc2FnZSA9IGZhbGxiYWNrTWVzc2FnZTtcbiAgbGV0IHN0YWNrOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGxldCBuYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgaWYgKGVyciBpbnN0YW5jZW9mIEpTRXhjZXB0aW9uKSB7XG4gICAgY29uc3QgZXJyb3IgPSB2bS5kdW1wKGVyci5oYW5kbGUpIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgbnVsbDtcbiAgICBlcnIuaGFuZGxlLmRpc3Bvc2UoKTtcbiAgICBtZXNzYWdlID0gKGVycm9yPy5tZXNzYWdlIGFzIHN0cmluZykgPz8gZXJyLm1lc3NhZ2UgPz8gZmFsbGJhY2tNZXNzYWdlO1xuICAgIHN0YWNrID0gKGVycm9yPy5zdGFjayBhcyBzdHJpbmcpID8/IGVyci5zdGFjaztcbiAgICBuYW1lID0gKGVycm9yPy5uYW1lIGFzIHN0cmluZykgPz8gZXJyLm5hbWU7XG4gIH0gZWxzZSBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICBtZXNzYWdlID0gZXJyLm1lc3NhZ2UgPz8gZmFsbGJhY2tNZXNzYWdlO1xuICAgIHN0YWNrID0gZXJyLnN0YWNrO1xuICAgIG5hbWUgPSBlcnIubmFtZTtcbiAgfVxuXG4gIHZtLmRpc3Bvc2UoKTtcbiAgcmV0dXJuIHtcbiAgICBmYWlsZWQ6IHsgbWVzc2FnZSwgc3RhY2ssIG5hbWUgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBNdXRhYmxlIGludGVycnVwdCBidWRnZXQgZm9yIGEgVk0uIFF1aWNrSlMgcG9sbHMgdGhlIGludGVycnVwdCBoYW5kbGVyXG4gKiBkdXJpbmcgSlMgZXhlY3V0aW9uOyB3aGVuIGl0IHJldHVybnMgdHJ1ZSwgZXhlY3V0aW9uIGFib3J0cy4gVGhlIGJ1ZGdldFxuICogYm91bmRzIGEgc2luZ2xlIGhvc3QtPlZNIGV4ZWN1dGlvbiBidXJzdCAoYnVuZGxlIGV2YWwgKyBldmVudFxuICogcHJvY2Vzc2luZyksIG5vdCB0b3RhbCBWTSBsaWZldGltZSDigJQgdGhlIGlubGluZS1zdGVwIGxvb3Aga2VlcHMgYSBWTVxuICogYWxpdmUgYWNyb3NzIHN0ZXAgZXhlY3V0aW9ucyB0aGF0IGNhbiBsZWdpdGltYXRlbHkgdGFrZSBtaW51dGVzLCBzbyB0aGVcbiAqIGhvc3QgcmVzZXRzIHRoZSBidWRnZXQgYmVmb3JlIGVhY2ggcmUtZW50cnkgKHNlZSByZXNldEJ1ZGdldCBjYWxscykuXG4gKlxuICogVGhlIHBlci1idXJzdCBjZWlsaW5nIGlzIHRoZSBzYW1lIGNvbmZpZ3VyYWJsZSBidWRnZXQgYXMgdGhlIG5vZGVcbiAqIGVuZ2luZSdzIFJlcGxheUJ1ZGdldCAoUkVQTEFZX1RJTUVPVVRfTVMsIGRlZmF1bHQgMjQwcyk6IGEgd29ya2Zsb3dcbiAqIHdob3NlIHJlcGxheSB0aGUgbm9kZSBlbmdpbmUgaGFuZGxlcyBmaW5lIG11c3Qgbm90IGJlIGludGVycnVwdGVkIGhlcmVcbiAqIGJ5IGEgbG93ZXIgaGFyZGNvZGVkIGNlaWxpbmcuIFRoZSBpbnRlcnJ1cHQgZXJyb3IgZXNjYXBlc1xuICogcnVuUXVpY2tKU1dvcmtmbG93IGFuZCByZWFjaGVzIHRoZSByZXBsYXkgbG9vcCdzIGNhdGNoIGluIHJ1bnRpbWUudHMsXG4gKiB3aGljaCByZWNvcmRzIHJ1bl9mYWlsZWQuXG4gKi9cbmludGVyZmFjZSBJbnRlcnJ1cHRCdWRnZXQge1xuICBzdGFydDogbnVtYmVyO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVJbnRlcnJ1cHRIYW5kbGVyKGJ1ZGdldDogSW50ZXJydXB0QnVkZ2V0KTogKCkgPT4gYm9vbGVhbiB7XG4gIGNvbnN0IHRpbWVvdXQgPSBnZXRSZXBsYXlUaW1lb3V0TXMoKTtcbiAgcmV0dXJuICgpID0+IERhdGUubm93KCkgLSBidWRnZXQuc3RhcnQgPiB0aW1lb3V0O1xufVxuIl19
2372
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVpY2tqcy1ydW50aW1lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvcXVpY2tqcy1ydW50aW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZCRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFRSCxPQUFPLEtBQUssTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUNqQyxPQUFPLEVBRUwsV0FBVyxFQUNYLE9BQU8sR0FHUixNQUFNLGNBQWMsQ0FBQztBQUN0QixPQUFPLFVBQVUsTUFBTSxZQUFZLENBQUM7QUFDcEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRTdELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN6RCxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLGdDQUFnQyxHQUNqQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMvRSxPQUFPLEVBQ0wsY0FBYyxFQUNkLGdCQUFnQixFQUNoQixrQkFBa0IsRUFDbEIsZUFBZSxHQUVoQixNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVsRCwyQ0FBMkM7QUFFM0M7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxLQUFLLFVBQVUsaUJBQWlCLENBQzlCLElBQWdCLEVBQ2hCLEdBQW1CO0lBRW5CLE9BQU8sQ0FBQyxNQUFNLFVBQVUsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FB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QUFDO0lBQzdDLENBQUM7U0FBTSxJQUFJLEdBQUcsWUFBWSxLQUFLLEVBQUUsQ0FBQztRQUNoQyxPQUFPLEdBQUcsR0FBRyxDQUFDLE9BQU8sSUFBSSxlQUFlLENBQUM7UUFDekMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUM7UUFDbEIsSUFBSSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUM7SUFDbEIsQ0FBQztJQUVELEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNiLE9BQU87UUFDTCxNQUFNLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRTtLQUNqQyxDQUFDO0FBQ0osQ0FBQztBQXFCRCxTQUFTLHNCQUFzQixDQUFDLE1BQXVCO0lBQ3JELE1BQU0sT0FBTyxHQUFHLGtCQUFrQixFQUFFLENBQUM7SUFDckMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUM7QUFDbkQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUXVpY2tKUyBXQVNNIHdvcmtmbG93IFZNLlxuICpcbiAqIEFuIGFsdGVybmF0aXZlIGVuZ2luZSBmb3IgdGhlIGV2ZW50LXJlcGxheSBleGVjdXRpb24gbW9kZWw6IHRoZSB3b3JrZmxvd1xuICogY29kZSBydW5zIGluc2lkZSBhIFF1aWNrSlMgV0FTTSBWTSAodmlhIHF1aWNranMtd2FzaSkgaW5zdGVhZCBvZiBhXG4gKiBgbm9kZTp2bWAgY29udGV4dC4gRXZlcnkgaW52b2NhdGlvbiBjcmVhdGVzIGEgZnJlc2ggVk0sIHJlLWV4ZWN1dGVzIHRoZVxuICogd29ya2Zsb3cgZnVuY3Rpb24gZnJvbSB0aGUgdG9wLCBhbmQgcmVwbGF5cyB0aGUgcmVjb3JkZWQgZXZlbnQgbG9nIHRvXG4gKiByZXNvbHZlIGF3YWl0ZWQgcHJpbWl0aXZlcyDigJQgdGhlIHNhbWUgcmVwbGF5IHNlbWFudGljcyBhcyB0aGUgYG5vZGU6dm1gXG4gKiBlbmdpbmUuXG4gKlxuICogVGhlIHdvcmtmbG93IHByaW1pdGl2ZXMgKHVzZVN0ZXAsIHNsZWVwLCBjcmVhdGVIb29rKSBhcmUgaW1wbGVtZW50ZWQgYXNcbiAqIEphdmFTY3JpcHQgY29kZSBydW5uaW5nIGluc2lkZSB0aGUgUXVpY2tKUyBWTS4gVGhlIGhvc3QgY29tbXVuaWNhdGVzIHdpdGhcbiAqIHRoZSBWTSBieSBldmFsdWF0aW5nIHNtYWxsIEpTIHNuaXBwZXRzIHRvIHJlYWQgcGVuZGluZyBvcGVyYXRpb25zIGFuZFxuICogcmVzb2x2ZS9yZWplY3QgcHJvbWlzZXMuXG4gKlxuICogVGhlIFZNIGJvb3RzdHJhcCBpcyBkZWxpYmVyYXRlbHkgc3BsaXQgaW50byB0d28gcGhhc2VzOlxuICogICAxLiBTdGF0aWMgaW5pdGlhbGl6YXRpb24gKGBpbml0V29ya2Zsb3dWTWApIOKAlCBydW4taW5kZXBlbmRlbnQgc2V0dXA6XG4gKiAgICAgIFZNIGNyZWF0aW9uIGFuZCB0aGUgd29ya2Zsb3cgcHJpbWl0aXZlcy4gKFNlcmlhbGl6YXRpb24gbGl2ZXMgb25cbiAqICAgICAgdGhlIGhvc3Qg4oCUIHNlZSBxdWlja2pzLXNlcmRlLnRzIOKAlCBzbyBubyBzZXJkZSBjb2RlIGlzIGV2YWx1YXRlZFxuICogICAgICBpbiB0aGUgVk0uKVxuICogICAyLiBQZXItcnVuIGluaXRpYWxpemF0aW9uIChpbmxpbmUgaW4gYHJ1blF1aWNrSlNXb3JrZmxvd2ApIOKAlCBzZWVkZWRcbiAqICAgICAgUFJORy9VTElEIGhvc3QgZnVuY3Rpb25zLCB3b3JrZmxvdyBidW5kbGUgZXZhbHVhdGlvbiwgcnVuIG1ldGFkYXRhLFxuICogICAgICB3b3JrZmxvdyBpbnB1dCwgYW5kIHN0YXJ0LlxuICogS2VlcGluZyB0aGUgcGhhc2VzIHNlcGFyYXRlIGlzIGdyb3VuZHdvcmsgZm9yIFZNLW1lbW9yeSBzbmFwc2hvdHRpbmc6XG4gKiBhIGZvbGxvdy11cCBjYW4gcGVyc2lzdC9yZXN0b3JlIHRoZSBWTSBhdCB0aGUgcGhhc2UgYm91bmRhcnkgKGUuZy4gYVxuICogYnVpbGQtdGltZSBpbml0aWFsIHNuYXBzaG90KSB3aXRob3V0IHJlc3RydWN0dXJpbmcgdGhpcyBtb2R1bGUuIE5vdGVcbiAqIHRoYXQgYnVuZGxlIGV2YWx1YXRpb24gY3VycmVudGx5IHNpdHMgaW4gdGhlIHBlci1ydW4gcGhhc2Ugc28gdGhhdFxuICogbW9kdWxlLXNjb3BlIHVzZXIgY29kZSBvYnNlcnZlcyB0aGUgc2VlZGVkIGBNYXRoLnJhbmRvbWAsIG1hdGNoaW5nIHRoZVxuICogYG5vZGU6dm1gIGVuZ2luZSdzIHJlcGxheSBkZXRlcm1pbmlzbS5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7XG4gIEV2ZW50LFxuICBSdW5JbnB1dCxcbiAgV29ya2Zsb3dSdW4sXG4gIFdvcmxkQ2FwYWJpbGl0aWVzLFxufSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0ICogYXMgbmFub2lkIGZyb20gJ25hbm9pZCc7XG5pbXBvcnQge1xuICB0eXBlIEV4dGVuc2lvbkRlc2NyaXB0b3IsXG4gIEpTRXhjZXB0aW9uLFxuICBRdWlja0pTLFxuICB0eXBlIFNuYXBzaG90LFxuICB0eXBlIFdhc2lPcHRpb25zLFxufSBmcm9tICdxdWlja2pzLXdhc2knO1xuaW1wb3J0IHNlZWRyYW5kb20gZnJvbSAnc2VlZHJhbmRvbSc7XG5pbXBvcnQgeyBtb25vdG9uaWNGYWN0b3J5IH0gZnJvbSAndWxpZCc7XG5pbXBvcnQgeyBydW50aW1lTG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IGRlY29tcHJlc3MgfSBmcm9tICcuLi9zZXJpYWxpemF0aW9uL2NvbXByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIHsgRGVjcnlwdGlvbktleSB9IGZyb20gJy4uL3NlcmlhbGl6YXRpb24vZW5jcnlwdGlvbi5qcyc7XG5pbXBvcnQgeyBkZWNyeXB0IH0gZnJvbSAnLi4vc2VyaWFsaXphdGlvbi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB7XG4gIGdldFJlcGxheVRpbWVvdXRNcyxcbiAgaXNRdWlja0pTQmFzZWxpbmVTbmFwc2hvdEVuYWJsZWQsXG59IGZyb20gJy4vY29uc3RhbnRzLmpzJztcbmltcG9ydCB7IHF1aWNranNFeHRlbnNpb25zLCBxdWlja2pzV2FzbSB9IGZyb20gJy4vcXVpY2tqcy1hc3NldHMuZ2VuZXJhdGVkLmpzJztcbmltcG9ydCB7XG4gIGFkb3B0U2VyZGVSb290LFxuICBjYXB0dXJlU2VyZGVSb290LFxuICBjcmVhdGVRdWlja0pTU2VyZGUsXG4gIGV4cG9ydFNlcmRlUm9vdCxcbiAgdHlwZSBRdWlja0pTU2VyZGUsXG59IGZyb20gJy4vcXVpY2tqcy1zZXJkZS5qcyc7XG5pbXBvcnQgeyBydW5JZENyZWF0ZWRBdCB9IGZyb20gJy4vcnVuLWlkLXRpbWUuanMnO1xuXG4vLyAtLS0tIEhvc3QgLT4gVk0gcGF5bG9hZCBwcmVwYXJhdGlvbiAtLS0tXG5cbi8qKlxuICogUHJlcGFyZSBwZXJzaXN0ZWQgcGF5bG9hZCBieXRlcyBmb3IgY29uc3VtcHRpb24gaW5zaWRlIHRoZSBWTTogZGVjcnlwdFxuICogKHdoZW4gYW4gZW5jcnlwdGlvbiBrZXkgaXMgY29uZmlndXJlZCkgYW5kIGRlY29tcHJlc3MgKHNwZWNWZXJzaW9uID49IDVcbiAqIHBheWxvYWRzIG1heSBiZSBnemlwL3pzdGQtY29tcHJlc3NlZCkuIFRoZSBWTSBvbmx5IHVuZGVyc3RhbmRzIHBsYWluXG4gKiBmb3JtYXQtcHJlZml4ZWQgJ2RldmwnIGJ5dGVzIOKAlCBpdCBoYXMgbmVpdGhlciB0aGUga2V5IG1hdGVyaWFsIG5vciB6bGliLlxuICogVGhlIGtleSBpcyB0aGUgcnVuJ3MgZnVsbCBEZWNyeXB0aW9uS2V5IGNhcGFiaWxpdHkgKHN5bW1ldHJpYyBBRVMga2V5ICtcbiAqIFgyNTUxOSBrZXlwYWlyKSBzbyBzZWFsZWQgYGVuY3BgIGhvb2sgcGF5bG9hZHMgZnJvbSBjcm9zcy1kZXBsb3ltZW50XG4gKiByZXN1bWVIb29rKCkgY2FsbHMgb3BlbiBoZXJlIHRvbywgbm90IGp1c3Qgc3ltbWV0cmljIGBlbmNyYCBvbmVzLlxuICogQm90aCBzdGFnZXMgYXJlIGZvcm1hdC1wcmVmaXggZGlzcGF0Y2hlZCwgc28gcGxhaW50ZXh0L3VuY29tcHJlc3NlZFxuICogZGF0YSBwYXNzZXMgdGhyb3VnaCB1bmNoYW5nZWQuIE1pcnJvcnMgYHByZXBhcmVSZXBsYXlQYXlsb2FkYCBpblxuICogc2VyaWFsaXphdGlvbi50cyAodGhlIG5vZGU6dm0gZW5naW5lJ3MgZXF1aXZhbGVudCBob3N0LXNpZGUgc3RhZ2UpLlxuICovXG5hc3luYyBmdW5jdGlvbiBwcmVwYXJlQnl0ZXNGb3JWTShcbiAgZGF0YTogVWludDhBcnJheSxcbiAga2V5PzogRGVjcnlwdGlvbktleVxuKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIHJldHVybiAoYXdhaXQgZGVjb21wcmVzcyhhd2FpdCBkZWNyeXB0KGRhdGEsIGtleSkpKSBhcyBVaW50OEFycmF5O1xufVxuXG4vLyAtLS0tIFR5cGVzIC0tLS1cblxuZXhwb3J0IGludGVyZmFjZSBQZW5kaW5nU3RlcCB7XG4gIHR5cGU6ICdzdGVwJztcbiAgY29ycmVsYXRpb25JZDogc3RyaW5nO1xuICBzdGVwSWQ6IHN0cmluZztcbiAgLyoqIEZvcm1hdC1wcmVmaXhlZCBkZXZhbHVlLXNlcmlhbGl6ZWQgc3RlcCBpbnB1dCAoYXJncyArIGNsb3N1cmVWYXJzKSAqL1xuICBpbnB1dDogVWludDhBcnJheTtcbiAgLyoqIFdoZXRoZXIgYSBzdGVwX2NyZWF0ZWQgZXZlbnQgYWxyZWFkeSBleGlzdHMgZm9yIHRoaXMgc3RlcCAqL1xuICBoYXNDcmVhdGVkRXZlbnQ6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGVuZGluZ1dhaXQge1xuICB0eXBlOiAnd2FpdCc7XG4gIGNvcnJlbGF0aW9uSWQ6IHN0cmluZztcbiAgLyoqIElTTyBzdHJpbmcgb2Ygd2hlbiB0byByZXN1bWUgKi9cbiAgcmVzdW1lQXQ6IHN0cmluZztcbiAgLyoqIFdoZXRoZXIgYSB3YWl0X2NyZWF0ZWQgZXZlbnQgYWxyZWFkeSBleGlzdHMgZm9yIHRoaXMgd2FpdCAqL1xuICBoYXNDcmVhdGVkRXZlbnQ6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGVuZGluZ0hvb2sge1xuICB0eXBlOiAnaG9vayc7XG4gIGNvcnJlbGF0aW9uSWQ6IHN0cmluZztcbiAgdG9rZW46IHN0cmluZztcbiAgLyoqIEVhcmxpZXN0IHRva2VuIHJldXNlIHRpbWUsIGFzIG1pbGxpc2Vjb25kcyBzaW5jZSB0aGUgVW5peCBlcG9jaC4gKi9cbiAgdG9rZW5SZXRlbnRpb25VbnRpbD86IG51bWJlcjtcbiAgaXNXZWJob29rOiBib29sZWFuO1xuICBtZXRhZGF0YT86IHVua25vd247XG4gIGhhc0NyZWF0ZWRFdmVudDogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFRydWUgZm9yIGludGVybmFsIHN5c3RlbSBob29rcyAoZS5nLiBBYm9ydENvbnRyb2xsZXIncyBob29rKSwgd2hpY2hcbiAgICogYXJlIGV4ZW1wdCBmcm9tIHVzZXItaG9vayB0b2tlbiBuYW1lc3BhY2UgY29uZmxpY3QgY2hlY2tzLlxuICAgKi9cbiAgaXNTeXN0ZW0/OiBib29sZWFuO1xuICAvKipcbiAgICogU2V0IHdoZW4gdGhlIHdvcmtmbG93IGNhbGxlZCBBYm9ydENvbnRyb2xsZXIuYWJvcnQoKSBkdXJpbmcgdGhpc1xuICAgKiBpbnZvY2F0aW9uLiBUaGUgaG9zdCBtdXN0IHJlY29yZCB0aGUgYWJvcnQ6IGNyZWF0ZSBhIGhvb2tfcmVjZWl2ZWRcbiAgICogZXZlbnQgY2FycnlpbmcgYGFib3J0UGF5bG9hZGAgYW5kIHdyaXRlL2Nsb3NlIHRoZSBhYm9ydCBzdHJlYW0uXG4gICAqL1xuICBhYm9ydFJlcXVlc3RlZD86IGJvb2xlYW47XG4gIC8qKiBWTS1zZXJpYWxpemVkIGB7IGFib3J0ZWQ6IHRydWUsIHJlYXNvbiB9YCBwYXlsb2FkIGZvciB0aGUgYWJvcnQuICovXG4gIGFib3J0UGF5bG9hZD86IFVpbnQ4QXJyYXk7XG4gIC8qKiBTZXQgYnkgdGhlIGNvbXBsZXRpb24gZHJhaW4gd2hlbiBhIHN5c3RlbSBob29rIGlzIGltcGxpY2l0bHkgZGlzcG9zZWQuICovXG4gIGRpc3Bvc2VkPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFRydWUgd2hlbiB0aGUgd29ya2Zsb3cgaXMgYXdhaXRpbmcgaG9vay5nZXRDb25mbGljdCgpIGZvciB0aGlzIGhvb2suXG4gICAqIFRoZSBlbnRyeXBvaW50IHJlLWludm9rZXMgdGhlIHdvcmtmbG93IHJpZ2h0IGFmdGVyIHdyaXRpbmdcbiAgICogaG9va19jcmVhdGVkIHNvIHJlcGxheSBjYW4gY29uZmlybSBjcmVhdGlvbiBhbmQgcmVzb2x2ZSB0aGUgYXdhaXRlci5cbiAgICovXG4gIGhhc0dldENvbmZsaWN0QXdhaXRlcj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGVuZGluZ0F0dHJpYnV0ZSB7XG4gIHR5cGU6ICdhdHRyaWJ1dGUnO1xuICBjb3JyZWxhdGlvbklkOiBzdHJpbmc7XG4gIC8qKiBOb3JtYWxpemVkIGF0dHJpYnV0ZSBjaGFuZ2VzIChwbGFpbiBKU09OLWFibGUgb2JqZWN0cykgKi9cbiAgY2hhbmdlczogdW5rbm93bltdO1xuICBhbGxvd1Jlc2VydmVkQXR0cmlidXRlcz86IGJvb2xlYW47XG4gIC8qKiBXaGV0aGVyIGFuIGF0dHJfc2V0IGV2ZW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIHdyaXRlICovXG4gIGhhc0NyZWF0ZWRFdmVudDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZW5kaW5nSG9va0Rpc3Bvc2Uge1xuICB0eXBlOiAnaG9va19kaXNwb3NlJztcbiAgY29ycmVsYXRpb25JZDogc3RyaW5nO1xuICAvKipcbiAgICogVG9rZW4gb2YgdGhlIGhvb2sgYmVpbmcgZGlzcG9zZWQuIFVzZWQgYnkgdGhlIGVudHJ5cG9pbnQgdG8gb3JkZXJcbiAgICogc2FtZS10b2tlbiBob29rIG9wZXJhdGlvbnMgc2VxdWVudGlhbGx5IGluIGNvZGUgb3JkZXIuXG4gICAqL1xuICB0b2tlbj86IHN0cmluZztcbiAgaGFzQ3JlYXRlZEV2ZW50OiBib29sZWFuO1xufVxuXG5leHBvcnQgdHlwZSBQZW5kaW5nT3BlcmF0aW9uID1cbiAgfCBQZW5kaW5nU3RlcFxuICB8IFBlbmRpbmdXYWl0XG4gIHwgUGVuZGluZ0hvb2tcbiAgfCBQZW5kaW5nQXR0cmlidXRlXG4gIHwgUGVuZGluZ0hvb2tEaXNwb3NlO1xuXG5leHBvcnQgaW50ZXJmYWNlIFF1aWNrSlNSdW50aW1lUmVzdWx0IHtcbiAgLyoqIFRoZSB3b3JrZmxvdyBjb21wbGV0ZWQg4oCUIHJlc3VsdCBpcyBmb3JtYXQtcHJlZml4ZWQgZGV2YWx1ZSBieXRlcyAqL1xuICBjb21wbGV0ZWQ/OiB7XG4gICAgcmVzdWx0OiBVaW50OEFycmF5O1xuICAgIC8qKlxuICAgICAqIExlZnRvdmVyIHBlbmRpbmcgb3BlcmF0aW9ucyB0aGF0IHN0aWxsIG5lZWQgZHVyYWJsZSBzaWRlIGVmZmVjdHMgYXRcbiAgICAgKiBjb21wbGV0aW9uOiBhYm9ydCByZWNvcmRpbmdzLCBzeXN0ZW0taG9vayBkaXNwb3NhbHMsIGZpcmUtYW5kLWZvcmdldFxuICAgICAqIGF0dHJpYnV0ZS9ob29rL3N0ZXAgZXZlbnRzLiBNaXJyb3JzIHRoZSBub2RlOnZtIGVuZ2luZSdzXG4gICAgICogZHJhaW5QZW5kaW5nUXVldWVJdGVtcy4gVGhlIGVudHJ5cG9pbnQgZGlzcGF0Y2hlcyB0aGVzZSBXSVRIT1VUXG4gICAgICogcXVldWVpbmcgc3RlcHMgb3IgcmVxdWV1aW5nIHRoZSBydW4uXG4gICAgICovXG4gICAgZHJhaW5PcGVyYXRpb25zPzogUGVuZGluZ09wZXJhdGlvbltdO1xuICB9O1xuICAvKiogVGhlIHdvcmtmbG93IHN1c3BlbmRlZCB3aXRoIHBlbmRpbmcgb3BlcmF0aW9ucyAqL1xuICBzdXNwZW5kZWQ/OiB7XG4gICAgcGVuZGluZ09wZXJhdGlvbnM6IFBlbmRpbmdPcGVyYXRpb25bXTtcbiAgfTtcbiAgLyoqIFRoZSB3b3JrZmxvdyBmYWlsZWQgKi9cbiAgZmFpbGVkPzoge1xuICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICBzdGFjaz86IHN0cmluZztcbiAgICBuYW1lPzogc3RyaW5nO1xuICAgIC8qKiBTZWUgY29tcGxldGVkLmRyYWluT3BlcmF0aW9ucyDigJQgc2FtZSBzZW1hbnRpY3Mgb24gZmFpbHVyZS4gKi9cbiAgICBkcmFpbk9wZXJhdGlvbnM/OiBQZW5kaW5nT3BlcmF0aW9uW107XG4gICAgLyoqXG4gICAgICogRm9ybWF0LXByZWZpeGVkIGRldmFsdWUgYnl0ZXMgb2YgdGhlIG9yaWdpbmFsIHRocm93biB2YWx1ZVxuICAgICAqIChFcnJvciBzdWJjbGFzcyB3aXRoIGNhdXNlIGNoYWluLCBwbGFpbiBvYmplY3QsIHByaW1pdGl2ZSwgZXRjLikuXG4gICAgICogU2V0IHdoZW4gdGhlIFZNLXNpZGUgcmVqZWN0aW9uIGhhbmRsZXIgc3VjY2Vzc2Z1bGx5IHNlcmlhbGl6ZXNcbiAgICAgKiB0aGUgdGhyb3duIHZhbHVlLiBUaGUgaG9zdCB1c2VzIHRoZXNlIGJ5dGVzIHRvIHJlY29uc3RydWN0IHRoZVxuICAgICAqIG9yaWdpbmFsIHZhbHVlIHRocm91Z2ggdGhlIHN0YW5kYXJkIGVycm9yIGh5ZHJhdGlvbiBwaXBlbGluZSxcbiAgICAgKiBwcmVzZXJ2aW5nIHR5cGUgaWRlbnRpdHkgKFR5cGVFcnJvciwgRmF0YWxFcnJvcikgYW5kIG5vbi1FcnJvclxuICAgICAqIHRocm93cyB2ZXJiYXRpbS4gRmFsbHMgYmFjayB0byB0aGUgbWVzc2FnZS9zdGFjay9uYW1lIGZpZWxkc1xuICAgICAqIHdoZW4gdGhpcyBpcyB1bmRlZmluZWQgKGUuZy4gZXh0cmFjdEVycm9yIHBzZXVkby1mYWlsdXJlcykuXG4gICAgICovXG4gICAgdmFsdWVCeXRlcz86IFVpbnQ4QXJyYXk7XG4gIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVpY2tKU1J1bnRpbWVPcHRpb25zIHtcbiAgLyoqIFRoZSBjb21waWxlZCB3b3JrZmxvdyBidW5kbGUgY29kZSAod29ya2Zsb3cgbW9kZSBvdXRwdXQgZnJvbSBTV0MpICovXG4gIHdvcmtmbG93Q29kZTogc3RyaW5nO1xuICAvKiogVGhlIHdvcmtmbG93IElEIChlLmcuIFwid29ya2Zsb3cvLy4vd29ya2Zsb3dzLzFfc2ltcGxlLy9zaW1wbGVcIikgKi9cbiAgd29ya2Zsb3dJZDogc3RyaW5nO1xuICAvKiogVGhlIHdvcmtmbG93IHJ1biBlbnRpdHkgKi9cbiAgd29ya2Zsb3dSdW46IFdvcmtmbG93UnVuO1xuICAvKiogRmVhdHVyZXMgc3VwcG9ydGVkIGJ5IHRoZSBXb3JsZCBleGVjdXRpbmcgdGhpcyB3b3JrZmxvdy4gKi9cbiAgd29ybGRDYXBhYmlsaXRpZXM/OiBXb3JsZENhcGFiaWxpdGllcztcbiAgLyoqXG4gICAqIFRoZSBmdWxsIGV2ZW50IGxvZyBmb3IgdGhlIHJ1bi4gRXZlcnkgaW52b2NhdGlvbiByZXBsYXlzIHRoZSBjb21wbGV0ZVxuICAgKiBsb2cgZnJvbSB0aGUgc3RhcnQgKHNhbWUgcmVwbGF5IHNlbWFudGljcyBhcyB0aGUgYG5vZGU6dm1gIGVuZ2luZSkuXG4gICAqL1xuICBldmVudHM6IEV2ZW50W107XG4gIC8qKiBFbmNyeXB0aW9uIGtleSBmb3IgZGVjcnlwdGluZyBldmVudCBwYXlsb2FkcyAodW5kZWZpbmVkIGlmIHVuZW5jcnlwdGVkKSAqL1xuICBlbmNyeXB0aW9uS2V5PzogRGVjcnlwdGlvbktleTtcbiAgLyoqXG4gICAqIFRoZSBsb2NhbCBwb3J0IHRoZSB3b3JrZmxvdyBzZXJ2ZXIgaXMgbGlzdGVuaW5nIG9uLCB1c2VkIHRvIHBvcHVsYXRlXG4gICAqIGB3b3JrZmxvd01ldGFkYXRhLnVybGAuIFJlc29sdmVkIGF0IGNhbGwgdGltZSBvbiB0aGUgaG9zdCBzaWRlIHNvIHRoZVxuICAgKiBWTSBkb2Vzbid0IGhhdmUgdG8gcHJvYmUgdGhlIGZpbGVzeXN0ZW0uIElnbm9yZWQgb24gVmVyY2VsIOKAlCBWRVJDRUxfVVJMXG4gICAqIHRha2VzIHByZWNlZGVuY2UgdGhlcmUuXG4gICAqL1xuICBwb3J0PzogbnVtYmVyO1xuICAvKipcbiAgICogRmFsbGJhY2sgd29ya2Zsb3cgaW5wdXQgZnJvbSB0aGUgcXVldWUgbWVzc2FnZSdzIHJlc2lsaWVudC1zdGFydFxuICAgKiBwYXlsb2FkLiBVc2VkIHdoZW4gdGhlIGZldGNoZWQgZXZlbnQgbG9nIGxhY2tzIGEgYHJ1bl9jcmVhdGVkYCBldmVudFxuICAgKiAoZXZlbnR1YWxseS1jb25zaXN0ZW50IHJlYWQgYWZ0ZXIgdGhlIHBhcmVudCdzIHN0YXJ0KCkgd3JvdGUgaXQpLlxuICAgKi9cbiAgcnVuSW5wdXQ/OiBSdW5JbnB1dDtcbn1cblxuLy8gLS0tLSBWTSBCb290c3RyYXAgQ29kZSAtLS0tXG5cbi8qKlxuICogSmF2YVNjcmlwdCBjb2RlIHRoYXQgcnVucyBpbnNpZGUgdGhlIFF1aWNrSlMgVk0gdG8gc2V0IHVwIHRoZSB3b3JrZmxvd1xuICogcHJpbWl0aXZlcy4gVGhpcyBzZXRzIHVwOlxuICogLSBnbG9iYWxUaGlzLl9fcHJpdmF0ZV93b3JrZmxvd3MgKE1hcCkgLSB3b3JrZmxvdyByZWdpc3RyeVxuICogLSBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzIChPYmplY3QpIC0gcGVuZGluZyBwcm9taXNlIHJlc29sdmUvcmVqZWN0IGZ1bmN0aW9uc1xuICogLSBnbG9iYWxUaGlzLl9fcGVuZGluZyAoQXJyYXkpIC0gbWV0YWRhdGEgYWJvdXQgcGVuZGluZyBvcGVyYXRpb25zXG4gKiAtIGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXSAtIHN0ZXAgcHJveHkgZmFjdG9yeVxuICogLSBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19TTEVFUFwiKV0gLSBzbGVlcCBmdW5jdGlvblxuICovXG5jb25zdCBWTV9CT09UU1RSQVAgPSBgXG4vLyBTeW1ib2wuZGlzcG9zZSAvIFN5bWJvbC5hc3luY0Rpc3Bvc2UgcG9seWZpbGxzIGZvciBRdWlja0pTXG5pZiAodHlwZW9mIFN5bWJvbC5kaXNwb3NlID09PSBcInVuZGVmaW5lZFwiKSB7XG4gIFN5bWJvbC5kaXNwb3NlID0gU3ltYm9sLmZvcihcIlN5bWJvbC5kaXNwb3NlXCIpO1xufVxuaWYgKHR5cGVvZiBTeW1ib2wuYXN5bmNEaXNwb3NlID09PSBcInVuZGVmaW5lZFwiKSB7XG4gIFN5bWJvbC5hc3luY0Rpc3Bvc2UgPSBTeW1ib2wuZm9yKFwiU3ltYm9sLmFzeW5jRGlzcG9zZVwiKTtcbn1cblxuZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzID0gbmV3IE1hcCgpO1xuZ2xvYmFsVGhpcy5fX3Jlc29sdmVycyA9IHt9O1xuZ2xvYmFsVGhpcy5fX3BlbmRpbmcgPSBbXTtcbmdsb2JhbFRoaXMuX193b3JrZmxvd1Jlc3VsdCA9IHVuZGVmaW5lZDtcbmdsb2JhbFRoaXMuX193b3JrZmxvd0Vycm9yID0gdW5kZWZpbmVkO1xuLy8gQnVmZmVyIGZvciBob29rX3JlY2VpdmVkIHBheWxvYWRzIHRoYXQgYXJyaXZlIGJlZm9yZSB0aGUgaG9vayBpcyBhd2FpdGVkLlxuLy8gS2V5ZWQgYnkgY29ycmVsYXRpb25JZCDihpIgYXJyYXkgb2YgcGF5bG9hZHMgKHByZXNlcnZlcyBkZWxpdmVyeSBvcmRlcikuXG4vLyBUaGlzIG1pcnJvcnMgdGhlIGV2ZW50LXJlcGxheSBydW50aW1lJ3MgcGF5bG9hZHNRdWV1ZSBpbiBob29rLnRzLlxuZ2xvYmFsVGhpcy5fX2hvb2tQYXlsb2FkQnVmZmVyID0ge307XG5cbi8vIEJ1ZmZlciBmb3Igc3RlcC93YWl0L2F0dHIgdGVybWluYWwgb3V0Y29tZXMgdGhhdCBhcnJpdmUgYmVmb3JlIHRoaXMgVk1cbi8vIGhhcyBjb25zdHJ1Y3RlZCB0aGUgY29ycmVzcG9uZGluZyBhd2FpdGluZyBwcm9taXNlLiBJbiBmcmVzaC1WTSByZXBsYXlcbi8vIHRoZSBtdWx0aS1wYXNzIGV2ZW50IHNjYW4gbWFrZXMgdGhpcyB1bnJlYWNoYWJsZSAoYXdhaXRzIGFyZVxuLy8gcmVjb25zdHJ1Y3RlZCBiZWZvcmUgdGhlaXIgdGVybWluYWxzIGFyZSByZS1zY2FubmVkKSwgYnV0IHRoZSBsaXZlXG4vLyBjb250aW51YXRpb24gcGF0aCAoY29udGludWVXaXRoRXZlbnRzKSBzY2FucyBlYWNoIGRlbHRhIGV4YWN0bHkgb25jZSDigJRcbi8vIGEgY29uY3VycmVudCBpbnZvY2F0aW9uJ3MgdGVybWluYWwgYXJyaXZpbmcgYmVmb3JlIHRoaXMgVk0gcmVhY2hlcyB0aGVcbi8vIGF3YWl0IHdvdWxkIG90aGVyd2lzZSBiZSBkcm9wcGVkIG9uIHRoZSBmbG9vciBhbmQgdGhlIGF3YWl0IHdvdWxkXG4vLyBuZXZlciBzZXR0bGUgKHRoZSBmZWVkJ3Mgc2Vlbi1zZXQgbWVhbnMgaXQgaXMgbmV2ZXIgcmUtZGVsaXZlcmVkKS5cbi8vIE1pcnJvcnMgX19ob29rUGF5bG9hZEJ1ZmZlciwgd2hpY2ggZXhpc3RzIGZvciBleGFjdGx5IHRoaXMgcmVhc29uIG9uXG4vLyB0aGUgaG9vayBwYXRoLiBLZXllZCBieSBjb3JyZWxhdGlvbklkIOKGkiBzaW5nbGUgdGVybWluYWwgKHN0ZXBzLCB3YWl0c1xuLy8gYW5kIGF0dHJzIHNldHRsZSBleGFjdGx5IG9uY2UpLlxuZ2xvYmFsVGhpcy5fX3Rlcm1pbmFsQnVmZmVyID0ge307XG5cbi8vIFJlZ2lzdGVycyBhIHJlc29sdmVyIGZvciBhbiBhd2FpdGVkIHByaW1pdGl2ZSwgZmlyc3QgZHJhaW5pbmcgYW55XG4vLyBidWZmZXJlZCB0ZXJtaW5hbCByZWNvcmRlZCBmb3IgdGhlIGNvcnJlbGF0aW9uSWQuIEVudHJpZXMgYXJlIHByZXBhcmVkXG4vLyBob3N0LXNpZGU6IGJ5dGVzIGFyZSBkZWNyeXB0ZWQgQU5EIGRlc2VyaWFsaXplZCBpbnRvIFZNIHZhbHVlcyBieSB0aGVcbi8vIGhvc3Qgc2VyZGUgYmVmb3JlIGJ1ZmZlcmluZyAodGhlIFZNIGhhcyBubyBpbi1ndWVzdCBkZXNlcmlhbGl6ZXIgb25cbi8vIHRoZSBob3N0LXNlcmRlIGVuZ2luZSksIHNvIGRyYWluaW5nIG9ubHkgZm9yd2FyZHMgdGhlIHN0b3JlZCB2YWx1ZS5cbmdsb2JhbFRoaXMuX19yZWdpc3RlclJlc29sdmVyID0gZnVuY3Rpb24oY29ycmVsYXRpb25JZCwgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gIHZhciBidWZmZXJlZCA9IGdsb2JhbFRoaXMuX190ZXJtaW5hbEJ1ZmZlcltjb3JyZWxhdGlvbklkXTtcbiAgaWYgKGJ1ZmZlcmVkKSB7XG4gICAgZGVsZXRlIGdsb2JhbFRoaXMuX190ZXJtaW5hbEJ1ZmZlcltjb3JyZWxhdGlvbklkXTtcbiAgICBpZiAoYnVmZmVyZWQua2luZCA9PT0gXCJyZXNvbHZlX3ZhbHVlXCIpIHtcbiAgICAgIHJlc29sdmUoYnVmZmVyZWQudmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoYnVmZmVyZWQua2luZCA9PT0gXCJyZWplY3RfdmFsdWVcIikge1xuICAgICAgcmVqZWN0KGJ1ZmZlcmVkLnZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKGJ1ZmZlcmVkLmtpbmQgPT09IFwicmVqZWN0X2Vycm9yXCIpIHtcbiAgICAgIHZhciBlID0gbmV3IEVycm9yKGJ1ZmZlcmVkLm1lc3NhZ2UpO1xuICAgICAgZS5uYW1lID0gXCJGYXRhbEVycm9yXCI7XG4gICAgICBlLmZhdGFsID0gdHJ1ZTtcbiAgICAgIGlmIChidWZmZXJlZC5zdGFjaykgZS5zdGFjayA9IGJ1ZmZlcmVkLnN0YWNrO1xuICAgICAgcmVqZWN0KGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuICBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzW2NvcnJlbGF0aW9uSWRdID0geyByZXNvbHZlOiByZXNvbHZlLCByZWplY3Q6IHJlamVjdCB9O1xufTtcblxuLy8gU3R1YnMgZm9yIFdlYiBBUElzIHRoYXQgdGhlIHdvcmtmbG93IGJ1bmRsZSBtYXkgcmVmZXJlbmNlIGJ1dCBhcmUgbm90XG4vLyBhdmFpbGFibGUgaW4gUXVpY2tKUy4gTmF0aXZlIEMgZXh0ZW5zaW9ucyAoZW5jb2RpbmcsIGhlYWRlcnMsIHVybCxcbi8vIHN0cnVjdHVyZWQtY2xvbmUpIHByb3ZpZGUgdGhlIHJlYWwgaW1wbGVtZW50YXRpb25zOyB0aGVzZSBhcmUgbWluaW1hbFxuLy8gc3R1YnMgZm9yIEFQSXMgdGhhdCBkb24ndCBoYXZlIG5hdGl2ZSBleHRlbnNpb25zIHlldC4gKGJ0b2EvYXRvYiBhbmRcbi8vIHRoZSBVaW50OEFycmF5IGJhc2U2NC9oZXggbWV0aG9kcyBhcmUgYnVpbHQgaW50byBxdWlja2pzLXdhc2kgPj0gMy4pXG5cbmlmICh0eXBlb2YgUmVhZGFibGVTdHJlYW0gPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgLy8gTWluaW1hbCBSZWFkYWJsZVN0cmVhbSB0aGF0IHN0b3JlcyBib2R5IGRhdGEgZm9yIFJlc3BvbnNlLmpzb24oKS90ZXh0KClcbiAgZ2xvYmFsVGhpcy5SZWFkYWJsZVN0cmVhbSA9IGZ1bmN0aW9uKCkge307XG4gIGdsb2JhbFRoaXMuUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLl9fYm9keURhdGEgPSBudWxsO1xufVxuXG5pZiAodHlwZW9mIFdyaXRhYmxlU3RyZWFtID09PSBcInVuZGVmaW5lZFwiKSB7XG4gIGdsb2JhbFRoaXMuV3JpdGFibGVTdHJlYW0gPSBmdW5jdGlvbigpIHt9O1xufVxuXG5pZiAodHlwZW9mIFRyYW5zZm9ybVN0cmVhbSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICBnbG9iYWxUaGlzLlRyYW5zZm9ybVN0cmVhbSA9IGZ1bmN0aW9uKCkge307XG59XG5cbmlmICh0eXBlb2YgY29uc29sZSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICBnbG9iYWxUaGlzLmNvbnNvbGUgPSB7IGxvZzogZnVuY3Rpb24oKXt9LCBlcnJvcjogZnVuY3Rpb24oKXt9LCB3YXJuOiBmdW5jdGlvbigpe30sIGluZm86IGZ1bmN0aW9uKCl7fSB9O1xufVxuLy8gU3R1YiBleHBvcnRzL21vZHVsZSBmb3IgQ0pTIGJ1bmRsZSBmb3JtYXRcbmdsb2JhbFRoaXMuZXhwb3J0cyA9IHt9O1xuZ2xvYmFsVGhpcy5tb2R1bGUgPSB7IGV4cG9ydHM6IGdsb2JhbFRoaXMuZXhwb3J0cyB9O1xuLy8gTk9URTogVGV4dEVuY29kZXIvVGV4dERlY29kZXIgYXJlIHByb3ZpZGVkIGJ5IHRoZSBuYXRpdmUgZW5jb2RpbmcgZXh0ZW5zaW9uLlxuXG4vLyAtLS0tIERldGVybWluaXN0aWMgXFxgY3J5cHRvXFxgIChwYXJpdHkgd2l0aCB0aGUgbm9kZTp2bSBlbmdpbmUpIC0tLS1cbi8vIGdldFJhbmRvbVZhbHVlcyAvIHJhbmRvbVVVSUQgZHJhdyBmcm9tIE1hdGgucmFuZG9tLCB3aGljaCB0aGUgaG9zdFxuLy8gcmVwbGFjZXMgd2l0aCB0aGUgcnVuJ3Mgc2VlZGVkIFBSTkcgYmVmb3JlIGFueSB1c2VyIGNvZGUgcnVucyDigJQgc28gdGhlXG4vLyB2YWx1ZXMgcmVwbGF5IGRldGVybWluaXN0aWNhbGx5IGFuZCBtYXRjaCB0aGUgbm9kZSBlbmdpbmUsIHdob3NlXG4vLyBpbXBsZW1lbnRhdGlvbnMgZHJhdyBmcm9tIHRoZSBzYW1lIHNlZWRlZCBzZXF1ZW5jZSAoc2VlIHZtL2luZGV4LnRzKS5cbi8vIEV2ZXJ5IGNyeXB0by5zdWJ0bGUgbWV0aG9kIHRocm93cyB3aXRoIHRoZSBzYW1lIGd1aWRhbmNlIGFzIHRoZSBub2RlXG4vLyBlbmdpbmUncyBub24tcmVwbGF5YWJsZSBtZXRob2RzOyB1bmxpa2Ugbm9kZSwgXFxgZGlnZXN0XFxgIGlzIGFsc29cbi8vIHVuYXZhaWxhYmxlIGhlcmUgKG5vIG5hdGl2ZSBoYXNoIGluIHRoZSBWTSB5ZXQpLlxuKGZ1bmN0aW9uKCkge1xuICBmdW5jdGlvbiBnZXRSYW5kb21WYWx1ZXMoYXJyYXkpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBhcnJheVtpXSA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDI1Nik7XG4gICAgfVxuICAgIHJldHVybiBhcnJheTtcbiAgfVxuICAvLyBNaXJyb3JzIHZtL3V1aWQudHMgY3JlYXRlUmFuZG9tVVVJRDogaWRlbnRpY2FsIGRyYXcgcGF0dGVybiBmcm9tIHRoZVxuICAvLyBzZWVkZWQgUFJORywgc28gYm90aCBlbmdpbmVzIHByb2R1Y2UgdGhlIHNhbWUgVVVJRCBhdCB0aGUgc2FtZSBwb2ludFxuICAvLyBpbiBhIHJlcGxheS5cbiAgZnVuY3Rpb24gcmFuZG9tVVVJRCgpIHtcbiAgICB2YXIgY2hhcnMgPSBcIjAxMjM0NTY3ODlhYmNkZWZcIjtcbiAgICB2YXIgdXVpZCA9IFwiXCI7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAzNjsgaSsrKSB7XG4gICAgICBpZiAoaSA9PT0gOCB8fCBpID09PSAxMyB8fCBpID09PSAxOCB8fCBpID09PSAyMykge1xuICAgICAgICB1dWlkICs9IFwiLVwiO1xuICAgICAgfSBlbHNlIGlmIChpID09PSAxNCkge1xuICAgICAgICB1dWlkICs9IFwiNFwiO1xuICAgICAgfSBlbHNlIGlmIChpID09PSAxOSkge1xuICAgICAgICB1dWlkICs9IGNoYXJzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDQpICsgOF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1dWlkICs9IGNoYXJzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDE2KV07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1dWlkO1xuICB9XG4gIGZ1bmN0aW9uIHN1YnRsZVRocm93KG5hbWUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZXJyID0gbmV3IEVycm9yKFwiXFxgY3J5cHRvLnN1YnRsZS5cIiArIG5hbWUgKyBcIigpXFxgIGlzIG5vdCBhdmFpbGFibGUgaW5zaWRlIGEgd29ya2Zsb3cgZnVuY3Rpb24uIE1vdmUgaXQgdG8gYSBzdGVwIGZ1bmN0aW9uIHdoZXJlIGZ1bGwgTm9kZS5qcyBjcnlwdG8gaXMgYXZhaWxhYmxlLlwiKTtcbiAgICAgIGVyci5uYW1lID0gXCJXb3JrZmxvd1J1bnRpbWVFcnJvclwiO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH07XG4gIH1cbiAgdmFyIHN1YnRsZSA9IHt9O1xuICBbXCJlbmNyeXB0XCIsXCJkZWNyeXB0XCIsXCJzaWduXCIsXCJ2ZXJpZnlcIixcImRpZ2VzdFwiLFwiZ2VuZXJhdGVLZXlcIixcImRlcml2ZUtleVwiLFwiZGVyaXZlQml0c1wiLFwiaW1wb3J0S2V5XCIsXCJleHBvcnRLZXlcIixcIndyYXBLZXlcIixcInVud3JhcEtleVwiXS5mb3JFYWNoKGZ1bmN0aW9uKG0pIHtcbiAgICBzdWJ0bGVbbV0gPSBzdWJ0bGVUaHJvdyhtKTtcbiAgfSk7XG4gIGdsb2JhbFRoaXMuY3J5cHRvID0ge1xuICAgIGdldFJhbmRvbVZhbHVlczogZ2V0UmFuZG9tVmFsdWVzLFxuICAgIHJhbmRvbVVVSUQ6IHJhbmRvbVVVSUQsXG4gICAgc3VidGxlOiBzdWJ0bGUsXG4gIH07XG59KSgpO1xuXG4vLyAtLS0tIExvdWQgSW50bCAvIGxvY2FsZSBndWFyZHMgLS0tLVxuLy8gUXVpY2tKUyBoYXMgbm8gSUNVOiBcXGBJbnRsXFxgIGlzIGFic2VudCBhbmQgdG9Mb2NhbGVTdHJpbmctZmFtaWx5IG1ldGhvZHNcbi8vIHNpbGVudGx5IGlnbm9yZSB0aGVpciBsb2NhbGUgYXJndW1lbnQuIFNpbGVudCBkaXZlcmdlbmNlIGZyb20gdGhlIG5vZGVcbi8vIGVuZ2luZSB3b3VsZCB3cml0ZSBkaWZmZXJlbnQgdmFsdWVzIGludG8gYSBkdXJhYmxlIGV2ZW50IGxvZyB3aXRoIG5vXG4vLyBlcnJvciBhbnl3aGVyZSDigJQgc28gbWFrZSB0aGUgZ2FwIGxvdWQgaW5zdGVhZDogSW50bCBjb25zdHJ1Y3RvcnMgdGhyb3csXG4vLyBhbmQgdG9Mb2NhbGUqIG1ldGhvZHMgdGhyb3cgT05MWSB3aGVuIGNhbGxlZCB3aXRoIGFuIGV4cGxpY2l0IGxvY2FsZVxuLy8gKHRoZSBuby1hcmd1bWVudCBmb3JtcyBrZWVwIFF1aWNrSlMncyBkZWZhdWx0IGJlaGF2aW9yKS5cbihmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gaW50bFRocm93KG5hbWUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZXJyID0gbmV3IEVycm9yKFwiXFxgSW50bC5cIiArIG5hbWUgKyBcIlxcYCBpcyBub3QgYXZhaWxhYmxlIGluIHRoZSBRdWlja0pTIHdvcmtmbG93IGVuZ2luZSAobm8gSUNVKS4gUGVyZm9ybSBsb2NhbGUtc2Vuc2l0aXZlIGZvcm1hdHRpbmcgaW4gYSBzdGVwIGZ1bmN0aW9uLCBvciB1c2UgV09SS0ZMT1dfVk09bm9kZS5cIik7XG4gICAgICBlcnIubmFtZSA9IFwiV29ya2Zsb3dSdW50aW1lRXJyb3JcIjtcbiAgICAgIHRocm93IGVycjtcbiAgICB9O1xuICB9XG4gIGlmICh0eXBlb2YgSW50bCA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgIHZhciBpbnRsID0ge307XG4gICAgW1wiQ29sbGF0b3JcIixcIkRhdGVUaW1lRm9ybWF0XCIsXCJEaXNwbGF5TmFtZXNcIixcIkR1cmF0aW9uRm9ybWF0XCIsXCJMaXN0Rm9ybWF0XCIsXCJMb2NhbGVcIixcIk51bWJlckZvcm1hdFwiLFwiUGx1cmFsUnVsZXNcIixcIlJlbGF0aXZlVGltZUZvcm1hdFwiLFwiU2VnbWVudGVyXCJdLmZvckVhY2goZnVuY3Rpb24obikge1xuICAgICAgaW50bFtuXSA9IGludGxUaHJvdyhuKTtcbiAgICB9KTtcbiAgICBpbnRsLmdldENhbm9uaWNhbExvY2FsZXMgPSBpbnRsVGhyb3coXCJnZXRDYW5vbmljYWxMb2NhbGVzXCIpO1xuICAgIGdsb2JhbFRoaXMuSW50bCA9IGludGw7XG4gIH1cbiAgZnVuY3Rpb24gZ3VhcmRMb2NhbGUocHJvdG8sIG1ldGhvZCkge1xuICAgIHZhciBvcmlnaW5hbCA9IHByb3RvW21ldGhvZF07XG4gICAgaWYgKHR5cGVvZiBvcmlnaW5hbCAhPT0gXCJmdW5jdGlvblwiKSByZXR1cm47XG4gICAgcHJvdG9bbWV0aG9kXSA9IGZ1bmN0aW9uKGxvY2FsZXMpIHtcbiAgICAgIGlmIChsb2NhbGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcihcIlxcYFwiICsgbWV0aG9kICsgXCIobG9jYWxlcywgLi4uKVxcYCB3aXRoIGFuIGV4cGxpY2l0IGxvY2FsZSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBRdWlja0pTIHdvcmtmbG93IGVuZ2luZSAobm8gSUNVKSDigJQgaXQgd291bGQgc2lsZW50bHkgaWdub3JlIHRoZSBsb2NhbGUuIEZvcm1hdCBpbiBhIHN0ZXAgZnVuY3Rpb24sIG9yIGNhbGwgd2l0aG91dCBhcmd1bWVudHMgZm9yIHRoZSBlbmdpbmUgZGVmYXVsdC5cIik7XG4gICAgICAgIGVyci5uYW1lID0gXCJXb3JrZmxvd1J1bnRpbWVFcnJvclwiO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgICByZXR1cm4gb3JpZ2luYWwuY2FsbCh0aGlzKTtcbiAgICB9O1xuICB9XG4gIGd1YXJkTG9jYWxlKE51bWJlci5wcm90b3R5cGUsIFwidG9Mb2NhbGVTdHJpbmdcIik7XG4gIGd1YXJkTG9jYWxlKERhdGUucHJvdG90eXBlLCBcInRvTG9jYWxlU3RyaW5nXCIpO1xuICBndWFyZExvY2FsZShEYXRlLnByb3RvdHlwZSwgXCJ0b0xvY2FsZURhdGVTdHJpbmdcIik7XG4gIGd1YXJkTG9jYWxlKERhdGUucHJvdG90eXBlLCBcInRvTG9jYWxlVGltZVN0cmluZ1wiKTtcbiAgZ3VhcmRMb2NhbGUoU3RyaW5nLnByb3RvdHlwZSwgXCJ0b0xvY2FsZUxvd2VyQ2FzZVwiKTtcbiAgZ3VhcmRMb2NhbGUoU3RyaW5nLnByb3RvdHlwZSwgXCJ0b0xvY2FsZVVwcGVyQ2FzZVwiKTtcbiAgLy8gbG9jYWxlQ29tcGFyZSdzIGxvY2FsZXMgYXJndW1lbnQgaXMgdGhlIFNFQ09ORCBwYXJhbWV0ZXIuXG4gIChmdW5jdGlvbigpIHtcbiAgICB2YXIgb3JpZ2luYWwgPSBTdHJpbmcucHJvdG90eXBlLmxvY2FsZUNvbXBhcmU7XG4gICAgU3RyaW5nLnByb3RvdHlwZS5sb2NhbGVDb21wYXJlID0gZnVuY3Rpb24odGhhdCwgbG9jYWxlcykge1xuICAgICAgaWYgKGxvY2FsZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKFwiXFxgbG9jYWxlQ29tcGFyZSh0aGF0LCBsb2NhbGVzLCAuLi4pXFxgIHdpdGggYW4gZXhwbGljaXQgbG9jYWxlIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhlIFF1aWNrSlMgd29ya2Zsb3cgZW5naW5lIChubyBJQ1UpLiBDb21wYXJlIGluIGEgc3RlcCBmdW5jdGlvbiwgb3IgY2FsbCB3aXRob3V0IGEgbG9jYWxlLlwiKTtcbiAgICAgICAgZXJyLm5hbWUgPSBcIldvcmtmbG93UnVudGltZUVycm9yXCI7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvcmlnaW5hbC5jYWxsKHRoaXMsIHRoYXQpO1xuICAgIH07XG4gIH0pKCk7XG59KSgpO1xuXG5nbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0gPSBmdW5jdGlvbihzdGVwSWQsIGNsb3N1cmVWYXJzRm4pIHtcbiAgdmFyIGZuID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIHZhciBjb3JyZWxhdGlvbklkID0gXCJzdGVwX1wiICsgZ2xvYmFsVGhpcy5fX2dlbmVyYXRlVWxpZCgpO1xuICAgIC8vIENhcHR1cmUgJ3RoaXMnIGZvciBtZXRob2QgaW52b2NhdGlvbnMgKGUuZy4sIE15Q2xhc3MubWV0aG9kKCkpXG4gICAgdmFyIHRoaXNWYWwgPSAodGhpcyAhPT0gdW5kZWZpbmVkICYmIHRoaXMgIT09IG51bGwgJiYgdGhpcyAhPT0gZ2xvYmFsVGhpcykgPyB0aGlzIDogdW5kZWZpbmVkO1xuICAgIC8vIFRoZSBSQVcgaW5wdXQgdmFsdWUuIFNlcmlhbGl6YXRpb24gaGFwcGVucyBvbiB0aGUgaG9zdCwgd2hpY2ggcmVhZHNcbiAgICAvLyB0aGlzIHRocm91Z2ggYSBoYW5kbGUgd2hlbiBpdCBjb2xsZWN0cyB0aGUgcGVuZGluZyBvcCDigJQgbm9cbiAgICAvLyBzZXJpYWxpemVyIGNvZGUgcnVucyBpbnNpZGUgdGhlIFZNLlxuICAgIHZhciBpbnB1dCA9IHtcbiAgICAgIGFyZ3M6IGFyZ3MsXG4gICAgICBjbG9zdXJlVmFyczogY2xvc3VyZVZhcnNGbiA/IGNsb3N1cmVWYXJzRm4oKSA6IHVuZGVmaW5lZCxcbiAgICAgIHRoaXNWYWw6IHRoaXNWYWwsXG4gICAgfTtcbiAgICBnbG9iYWxUaGlzLl9fcGVuZGluZy5wdXNoKHtcbiAgICAgIHR5cGU6IFwic3RlcFwiLFxuICAgICAgY29ycmVsYXRpb25JZDogY29ycmVsYXRpb25JZCxcbiAgICAgIHN0ZXBJZDogc3RlcElkLFxuICAgICAgaW5wdXQ6IGlucHV0LFxuICAgICAgaGFzQ3JlYXRlZEV2ZW50OiBmYWxzZSxcbiAgICB9KTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBnbG9iYWxUaGlzLl9fcmVnaXN0ZXJSZXNvbHZlcihjb3JyZWxhdGlvbklkLCByZXNvbHZlLCByZWplY3QpO1xuICAgIH0pO1xuICB9O1xuICAvLyBTZXQgc3RlcElkIG9uIHRoZSBwcm94eSBzbyB0aGUgU3RlcEZ1bmN0aW9uIHJlZHVjZXIgY2FuIGRldGVjdCBhbmRcbiAgLy8gc2VyaWFsaXplIHN0ZXAgZnVuY3Rpb24gcmVmZXJlbmNlcyAoZS5nLiB3aGVuIHBhc3NlZCBhcyBhcmd1bWVudHMpLlxuICBmbi5zdGVwSWQgPSBzdGVwSWQ7XG4gIGlmIChjbG9zdXJlVmFyc0ZuKSBmbi5fX2Nsb3N1cmVWYXJzRm4gPSBjbG9zdXJlVmFyc0ZuO1xuICAvLyBPdmVycmlkZSAuYmluZCBzbyBhIGJvdW5kIHN0ZXAgcHJveHkgKGUuZy4gdGhlIFNXQyBwbHVnaW4nc1xuICAvLyB1c2VTdGVwKC4uLikuYmluZCh0aGlzKSBmb3IgbGV4aWNhbC10aGlzIGFycm93IHN0ZXBzKSBrZWVwcyBpdHNcbiAgLy8gc3RlcElkIGFuZCByZWNvcmRzIHRoZSBib3VuZCByZWNlaXZlciAvIHByZWZpbGxlZCBhcmdzIOKAlCB0aGUgbmF0aXZlXG4gIC8vIGJpbmQgZHJvcHMgb3duIHByb3BlcnRpZXMsIHdoaWNoIHdvdWxkIG1ha2UgdGhlIFN0ZXBGdW5jdGlvblxuICAvLyByZWR1Y2VyIGZhaWwgdG8gcmVjb2duaXplIHRoZSBwcm94eSB3aGVuIGl0IGNyb3NzZXMgYSBzZXJpYWxpemF0aW9uXG4gIC8vIGJvdW5kYXJ5LiBNaXJyb3JzIHRoZSBub2RlOnZtIGVuZ2luZSdzIG92ZXJyaWRlIGluIHN0ZXAudHMuXG4gIGZuLmJpbmQgPSBmdW5jdGlvbih0aGlzQXJnKSB7XG4gICAgdmFyIHBhcnRpYWxBcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICB2YXIgYm91bmQgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseSh0aGlzLCBbdGhpc0FyZ10uY29uY2F0KHBhcnRpYWxBcmdzKSk7XG4gICAgYm91bmQuc3RlcElkID0gc3RlcElkO1xuICAgIGlmIChjbG9zdXJlVmFyc0ZuKSBib3VuZC5fX2Nsb3N1cmVWYXJzRm4gPSBjbG9zdXJlVmFyc0ZuO1xuICAgIGJvdW5kLl9fYm91bmRUaGlzID0gdGhpc0FyZztcbiAgICBpZiAocGFydGlhbEFyZ3MubGVuZ3RoID4gMCkgYm91bmQuX19ib3VuZEFyZ3MgPSBwYXJ0aWFsQXJncztcbiAgICByZXR1cm4gYm91bmQ7XG4gIH07XG4gIHJldHVybiBmbjtcbn07XG5cbi8vIFBhcnNlcyBhbiBcIm1zXCIgbGlicmFyeSBzdHlsZSBkdXJhdGlvbiBzdHJpbmcgaW50byBtaWxsaXNlY29uZHMuXG4vLyBTdXBwb3J0cyB0aGUgc2FtZSB1bml0cyBhcyB0aGUgcmVwbGF5IHJ1bnRpbWUgKHdoaWNoIHVzZXMgdGhlIFwibXNcIlxuLy8gcGFja2FnZSk6IG1zIC8gcyAvIG0gLyBoIC8gZCAvIHcgLyB5LCB3aXRoIHZlcmJvc2UgYWxpYXNlc1xuLy8gKHNlY29uZHMsIG1pbnV0ZXMsIC4uLikuXG5nbG9iYWxUaGlzLl9fcGFyc2VEdXJhdGlvbk1zID0gZnVuY3Rpb24oc3RyKSB7XG4gIHN0ciA9IFN0cmluZyhzdHIpO1xuICBpZiAoc3RyLmxlbmd0aCA+IDEwMCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgdmFyIG1hdGNoID0gc3RyLm1hdGNoKFxuICAgIC9eKC0/KD86XFxcXGQrKT9cXFxcLj9cXFxcZCspICoobWlsbGlzZWNvbmRzP3xtc2Vjcz98bXN8c2Vjb25kcz98c2Vjcz98c3xtaW51dGVzP3xtaW5zP3xtfGhvdXJzP3xocnM/fGh8ZGF5cz98ZHx3ZWVrcz98d3x5ZWFycz98eXJzP3x5KT8kL2lcbiAgKTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgdmFyIG4gPSBwYXJzZUZsb2F0KG1hdGNoWzFdKTtcbiAgdmFyIHR5cGUgPSAobWF0Y2hbMl0gfHwgXCJtc1wiKS50b0xvd2VyQ2FzZSgpO1xuICB2YXIgcyA9IDEwMDAsIG0gPSA2MCAqIHMsIGggPSA2MCAqIG0sIGQgPSAyNCAqIGgsIHcgPSA3ICogZCwgeSA9IDM2NS4yNSAqIGQ7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgXCJ5ZWFyc1wiOiBjYXNlIFwieWVhclwiOiBjYXNlIFwieXJzXCI6IGNhc2UgXCJ5clwiOiBjYXNlIFwieVwiOiByZXR1cm4gbiAqIHk7XG4gICAgY2FzZSBcIndlZWtzXCI6IGNhc2UgXCJ3ZWVrXCI6IGNhc2UgXCJ3XCI6IHJldHVybiBuICogdztcbiAgICBjYXNlIFwiZGF5c1wiOiBjYXNlIFwiZGF5XCI6IGNhc2UgXCJkXCI6IHJldHVybiBuICogZDtcbiAgICBjYXNlIFwiaG91cnNcIjogY2FzZSBcImhvdXJcIjogY2FzZSBcImhyc1wiOiBjYXNlIFwiaHJcIjogY2FzZSBcImhcIjogcmV0dXJuIG4gKiBoO1xuICAgIGNhc2UgXCJtaW51dGVzXCI6IGNhc2UgXCJtaW51dGVcIjogY2FzZSBcIm1pbnNcIjogY2FzZSBcIm1pblwiOiBjYXNlIFwibVwiOiByZXR1cm4gbiAqIG07XG4gICAgY2FzZSBcInNlY29uZHNcIjogY2FzZSBcInNlY29uZFwiOiBjYXNlIFwic2Vjc1wiOiBjYXNlIFwic2VjXCI6IGNhc2UgXCJzXCI6IHJldHVybiBuICogcztcbiAgICBjYXNlIFwibWlsbGlzZWNvbmRzXCI6IGNhc2UgXCJtaWxsaXNlY29uZFwiOiBjYXNlIFwibXNlY3NcIjogY2FzZSBcIm1zZWNcIjogY2FzZSBcIm1zXCI6IHJldHVybiBuO1xuICAgIGRlZmF1bHQ6IHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn07XG5cbmdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1NMRUVQXCIpXSA9IGZ1bmN0aW9uKHBhcmFtKSB7XG4gIHZhciBjb3JyZWxhdGlvbklkID0gXCJ3YWl0X1wiICsgZ2xvYmFsVGhpcy5fX2dlbmVyYXRlVWxpZCgpO1xuICB2YXIgcmVzdW1lQXQ7XG4gIGlmICh0eXBlb2YgcGFyYW0gPT09IFwibnVtYmVyXCIpIHtcbiAgICByZXN1bWVBdCA9IG5ldyBEYXRlKERhdGUubm93KCkgKyBwYXJhbSkudG9JU09TdHJpbmcoKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgcGFyYW0gPT09IFwic3RyaW5nXCIpIHtcbiAgICB2YXIgbXMgPSBnbG9iYWxUaGlzLl9fcGFyc2VEdXJhdGlvbk1zKHBhcmFtKTtcbiAgICBpZiAodHlwZW9mIG1zID09PSBcIm51bWJlclwiICYmIGlzRmluaXRlKG1zKSkge1xuICAgICAgcmVzdW1lQXQgPSBuZXcgRGF0ZShEYXRlLm5vdygpICsgbXMpLnRvSVNPU3RyaW5nKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vdCBhIGR1cmF0aW9uIHN0cmluZyDigJQgdHJ5IGFzIGFuIGFic29sdXRlIGRhdGUgc3RyaW5nLlxuICAgICAgdmFyIGRhdGUgPSBuZXcgRGF0ZShwYXJhbSk7XG4gICAgICBpZiAoaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgc2xlZXAgcGFyYW1ldGVyOiBcIiArIHBhcmFtKTtcbiAgICAgIH1cbiAgICAgIHJlc3VtZUF0ID0gZGF0ZS50b0lTT1N0cmluZygpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChwYXJhbSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICBpZiAoaXNOYU4ocGFyYW0uZ2V0VGltZSgpKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBzbGVlcCBwYXJhbWV0ZXI6IFwiICsgcGFyYW0pO1xuICAgIH1cbiAgICByZXN1bWVBdCA9IHBhcmFtLnRvSVNPU3RyaW5nKCk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBzbGVlcCBwYXJhbWV0ZXI6IFwiICsgcGFyYW0pO1xuICB9XG4gIGdsb2JhbFRoaXMuX19wZW5kaW5nLnB1c2goe1xuICAgIHR5cGU6IFwid2FpdFwiLFxuICAgIGNvcnJlbGF0aW9uSWQ6IGNvcnJlbGF0aW9uSWQsXG4gICAgcmVzdW1lQXQ6IHJlc3VtZUF0LFxuICAgIGhhc0NyZWF0ZWRFdmVudDogZmFsc2UsXG4gIH0pO1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgZ2xvYmFsVGhpcy5fX3JlZ2lzdGVyUmVzb2x2ZXIoY29ycmVsYXRpb25JZCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgfSk7XG59O1xuXG4vLyBSZXNwb25zZS9SZXF1ZXN0IHBvbHlmaWxscyDigJQgLmpzb24oKS8udGV4dCgpLy5hcnJheUJ1ZmZlcigpIGFyZSB1c2VTdGVwXG4vLyBwcm94aWVzIHRoYXQgZXhlY3V0ZSBvbiB0aGUgaG9zdCBzaWRlLiBUaGUgcHJveGllcyBhcmUgYXNzaWduZWQgZGlyZWN0bHlcbi8vIHRvIHRoZSBwcm90b3R5cGVzIHNvIHRoYXQgJ3RoaXMnICh0aGUgUmVzcG9uc2UvUmVxdWVzdCBpbnN0YW5jZSkgaXNcbi8vIHNlcmlhbGl6ZWQgYXMgdGhpc1ZhbCBieSBXT1JLRkxPV19VU0VfU1RFUCwgbWF0Y2hpbmcgdGhlIGV2ZW50LXJlcGxheVxuLy8gcnVudGltZSdzIGFwcHJvYWNoIChjb21taXQgZGNiMDc2MSkuXG5pZiAodHlwZW9mIFJlc3BvbnNlID09PSBcInVuZGVmaW5lZFwiKSB7XG4gIHZhciBfX0JPRFlfSU5JVCA9IFN5bWJvbC5mb3IoXCJCT0RZX0lOSVRcIik7XG5cbiAgZ2xvYmFsVGhpcy5SZXNwb25zZSA9IGZ1bmN0aW9uKGJvZHksIGluaXQpIHtcbiAgICBpbml0ID0gaW5pdCB8fCB7fTtcbiAgICB0aGlzLnN0YXR1cyA9IGluaXQuc3RhdHVzIHx8IDIwMDtcbiAgICB0aGlzLnN0YXR1c1RleHQgPSBpbml0LnN0YXR1c1RleHQgfHwgXCJcIjtcbiAgICB0aGlzLmhlYWRlcnMgPSBuZXcgZ2xvYmFsVGhpcy5IZWFkZXJzKGluaXQuaGVhZGVycyB8fCBbXSk7XG4gICAgdGhpcy50eXBlID0gXCJkZWZhdWx0XCI7XG4gICAgdGhpcy51cmwgPSBcIlwiO1xuICAgIHRoaXMucmVkaXJlY3RlZCA9IGZhbHNlO1xuICAgIGlmIChib2R5ICE9PSBudWxsICYmIGJvZHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5ib2R5ID0gT2JqZWN0LmNyZWF0ZShnbG9iYWxUaGlzLlJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZSk7XG4gICAgICB0aGlzLmJvZHlbX19CT0RZX0lOSVRdID0gYm9keTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5ib2R5ID0gbnVsbDtcbiAgICB9XG4gIH07XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxUaGlzLlJlc3BvbnNlLnByb3RvdHlwZSwgXCJva1wiLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMuc3RhdHVzID49IDIwMCAmJiB0aGlzLnN0YXR1cyA8IDMwMDsgfVxuICB9KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbFRoaXMuUmVzcG9uc2UucHJvdG90eXBlLCBcImJvZHlVc2VkXCIsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gZmFsc2U7IH1cbiAgfSk7XG4gIC8vIEFzc2lnbiB1c2VTdGVwIHByb3hpZXMgZGlyZWN0bHkg4oCUICd0aGlzJyBiaW5kaW5nIHByb3ZpZGVzIHRoZVxuICAvLyBSZXNwb25zZSBpbnN0YW5jZSwgd2hpY2ggZ2V0cyBzZXJpYWxpemVkIGFzIHRoaXNWYWwgYnkgdGhlIHByb3h5LlxuICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhnbG9iYWxUaGlzLlJlc3BvbnNlLnByb3RvdHlwZSwge1xuICAgIGFycmF5QnVmZmVyOiB7IHZhbHVlOiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJfX2J1aWx0aW5fcmVzcG9uc2VfYXJyYXlfYnVmZmVyXCIpLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0sXG4gICAganNvbjogeyB2YWx1ZTogZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwiX19idWlsdGluX3Jlc3BvbnNlX2pzb25cIiksIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSxcbiAgICB0ZXh0OiB7IHZhbHVlOiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJfX2J1aWx0aW5fcmVzcG9uc2VfdGV4dFwiKSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9LFxuICB9KTtcbiAgZ2xvYmFsVGhpcy5SZXNwb25zZS5wcm90b3R5cGUuYnl0ZXMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5hcnJheUJ1ZmZlcigpLnRoZW4oZnVuY3Rpb24oYnVmKSB7IHJldHVybiBuZXcgVWludDhBcnJheShidWYpOyB9KTtcbiAgfTtcbiAgZ2xvYmFsVGhpcy5SZXNwb25zZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgciA9IE9iamVjdC5jcmVhdGUoZ2xvYmFsVGhpcy5SZXNwb25zZS5wcm90b3R5cGUpO1xuICAgIHIuc3RhdHVzID0gdGhpcy5zdGF0dXM7IHIuc3RhdHVzVGV4dCA9IHRoaXMuc3RhdHVzVGV4dDtcbiAgICByLmhlYWRlcnMgPSB0aGlzLmhlYWRlcnM7IHIudHlwZSA9IHRoaXMudHlwZTtcbiAgICByLnVybCA9IHRoaXMudXJsOyByLnJlZGlyZWN0ZWQgPSB0aGlzLnJlZGlyZWN0ZWQ7IHIuYm9keSA9IHRoaXMuYm9keTtcbiAgICByZXR1cm4gcjtcbiAgfTtcbiAgZ2xvYmFsVGhpcy5SZXNwb25zZS5qc29uID0gZnVuY3Rpb24oZGF0YSwgaW5pdCkge1xuICAgIHZhciBib2R5ID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgdmFyIGhlYWRlcnMgPSBuZXcgZ2xvYmFsVGhpcy5IZWFkZXJzKGluaXQgPyBpbml0LmhlYWRlcnMgOiBbXSk7XG4gICAgaWYgKCFoZWFkZXJzLmhhcyhcImNvbnRlbnQtdHlwZVwiKSkgeyBoZWFkZXJzLnNldChcImNvbnRlbnQtdHlwZVwiLCBcImFwcGxpY2F0aW9uL2pzb25cIik7IH1cbiAgICByZXR1cm4gbmV3IGdsb2JhbFRoaXMuUmVzcG9uc2UoYm9keSwgeyBzdGF0dXM6IChpbml0ICYmIGluaXQuc3RhdHVzKSB8fCAyMDAsIHN0YXR1c1RleHQ6IChpbml0ICYmIGluaXQuc3RhdHVzVGV4dCkgfHwgXCJcIiwgaGVhZGVyczogaGVhZGVycyB9KTtcbiAgfTtcbn1cbmlmICh0eXBlb2YgUmVxdWVzdCA9PT0gXCJ1bmRlZmluZWRcIikge1xuICBnbG9iYWxUaGlzLlJlcXVlc3QgPSBmdW5jdGlvbihpbnB1dCwgaW5pdCkge1xuICAgIGluaXQgPSBpbml0IHx8IHt9O1xuICAgIGlmICh0eXBlb2YgaW5wdXQgPT09IFwic3RyaW5nXCIpIHsgdGhpcy51cmwgPSBpbnB1dDsgfVxuICAgIGVsc2UgaWYgKGlucHV0ICYmIHR5cGVvZiBpbnB1dCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgdGhpcy51cmwgPSBpbnB1dC51cmwgfHwgXCJcIjsgdGhpcy5tZXRob2QgPSBpbnB1dC5tZXRob2Q7XG4gICAgICB0aGlzLmhlYWRlcnMgPSBpbnB1dC5oZWFkZXJzOyB0aGlzLmJvZHkgPSBpbnB1dC5ib2R5O1xuICAgIH1cbiAgICBpZiAoaW5pdC5tZXRob2QpIHRoaXMubWV0aG9kID0gaW5pdC5tZXRob2QudG9VcHBlckNhc2UoKTtcbiAgICBpZiAoIXRoaXMubWV0aG9kKSB0aGlzLm1ldGhvZCA9IFwiR0VUXCI7XG4gICAgaWYgKGluaXQuaGVhZGVycykgdGhpcy5oZWFkZXJzID0gbmV3IGdsb2JhbFRoaXMuSGVhZGVycyhpbml0LmhlYWRlcnMpO1xuICAgIGlmICghdGhpcy5oZWFkZXJzKSB0aGlzLmhlYWRlcnMgPSBuZXcgZ2xvYmFsVGhpcy5IZWFkZXJzKCk7XG4gICAgaWYgKGluaXQuYm9keSAhPT0gdW5kZWZpbmVkKSB0aGlzLmJvZHkgPSBpbml0LmJvZHk7XG4gICAgaWYgKCF0aGlzLmJvZHkpIHRoaXMuYm9keSA9IG51bGw7XG4gICAgdGhpcy5kdXBsZXggPSBpbml0LmR1cGxleCB8fCBcImhhbGZcIjtcbiAgfTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbFRoaXMuUmVxdWVzdC5wcm90b3R5cGUsIFwiYm9keVVzZWRcIiwge1xuICAgIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBmYWxzZTsgfVxuICB9KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoZ2xvYmFsVGhpcy5SZXF1ZXN0LnByb3RvdHlwZSwge1xuICAgIGFycmF5QnVmZmVyOiB7IHZhbHVlOiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJfX2J1aWx0aW5fcmVzcG9uc2VfYXJyYXlfYnVmZmVyXCIpLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0sXG4gICAganNvbjogeyB2YWx1ZTogZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfVVNFX1NURVBcIildKFwiX19idWlsdGluX3Jlc3BvbnNlX2pzb25cIiksIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSxcbiAgICB0ZXh0OiB7IHZhbHVlOiBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19VU0VfU1RFUFwiKV0oXCJfX2J1aWx0aW5fcmVzcG9uc2VfdGV4dFwiKSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9LFxuICB9KTtcbn1cblxuLy8gY3JlYXRlSG9vayDigJQgcmV0dXJucyBhIEhvb2sgb2JqZWN0IHRoYXQgaXMgYm90aCBhIFRoZW5hYmxlIGFuZCBBc3luY0l0ZXJhYmxlLlxuLy8gRWFjaCBhd2FpdC95aWVsZCBjcmVhdGVzIGEgbmV3IHByb21pc2Uga2V5ZWQgYnkgdGhlIHNhbWUgY29ycmVsYXRpb25JZC5cbi8vIFRoZSBwcm9taXNlIGlzIHJlc29sdmVkIHdoZW4gYSBob29rX3JlY2VpdmVkIGV2ZW50IGFycml2ZXMuXG5nbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19DUkVBVEVfSE9PS1wiKV0gPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBpZiAob3B0aW9ucy5pc1dlYmhvb2sgPT09IHRydWUgJiYgb3B0aW9ucy5leHBlcmltZW50YWxfbWluUmV0ZW50aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYmhvb2sgaG9va3MgZG8gbm90IHN1cHBvcnQgXFxgZXhwZXJpbWVudGFsX21pblJldGVudGlvblxcYC4gVXNlIGEgbm9uLXdlYmhvb2sgXFxgY3JlYXRlSG9vaygpXFxgIHdpdGggXFxgcmVzdW1lSG9vaygpXFxgLicpO1xuICB9XG4gIGlmIChvcHRpb25zLmV4cGVyaW1lbnRhbF9taW5SZXRlbnRpb24gIT09IHVuZGVmaW5lZCAmJiBnbG9iYWxUaGlzLl9fd29ybGRDYXBhYmlsaXRpZXM/Lmhvb2tSZXRlbnRpb24/LmFjdGl2ZSAhPT0gdHJ1ZSkge1xuICAgIHZhciB1bnN1cHBvcnRlZFJldGVudGlvbkVycm9yID0gbmV3IEVycm9yKCdUaGUgY29uZmlndXJlZCBXb3JsZCBkb2VzIG5vdCBzdXBwb3J0IFxcYGV4cGVyaW1lbnRhbF9taW5SZXRlbnRpb25cXGAgZm9yIEhvb2tzLicpO1xuICAgIHVuc3VwcG9ydGVkUmV0ZW50aW9uRXJyb3IubmFtZSA9IFwiRmF0YWxFcnJvclwiO1xuICAgIHVuc3VwcG9ydGVkUmV0ZW50aW9uRXJyb3IuZmF0YWwgPSB0cnVlO1xuICAgIHRocm93IHVuc3VwcG9ydGVkUmV0ZW50aW9uRXJyb3I7XG4gIH1cbiAgdmFyIHRva2VuID0gb3B0aW9ucy50b2tlbiB8fCBnbG9iYWxUaGlzLl9fZ2VuZXJhdGVOYW5vaWQoKTtcbiAgdmFyIGNvcnJlbGF0aW9uSWQgPSBcImhvb2tfXCIgKyBnbG9iYWxUaGlzLl9fZ2VuZXJhdGVVbGlkKCk7XG4gIHZhciBpc0Rpc3Bvc2VkID0gZmFsc2U7XG4gIHZhciBoYXNDcmVhdGVkRXZlbnQgPSBmYWxzZTtcbiAgdmFyIHRva2VuUmV0ZW50aW9uVW50aWw7XG4gIGlmIChvcHRpb25zLmV4cGVyaW1lbnRhbF9taW5SZXRlbnRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBtaW5SZXRlbnRpb24gPSBvcHRpb25zLmV4cGVyaW1lbnRhbF9taW5SZXRlbnRpb247XG4gICAgaWYgKHR5cGVvZiBtaW5SZXRlbnRpb24gPT09IFwibnVtYmVyXCIpIHtcbiAgICAgIGlmIChtaW5SZXRlbnRpb24gPCAwIHx8ICFpc0Zpbml0ZShtaW5SZXRlbnRpb24pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgZHVyYXRpb246IFwiICsgbWluUmV0ZW50aW9uICsgXCIuIEV4cGVjdGVkIGEgbm9uLW5lZ2F0aXZlIGZpbml0ZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLlwiKTtcbiAgICAgIH1cbiAgICAgIHRva2VuUmV0ZW50aW9uVW50aWwgPSBEYXRlLm5vdygpICsgbWluUmV0ZW50aW9uO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG1pblJldGVudGlvbiA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdmFyIHJldGVudGlvbk1zID0gZ2xvYmFsVGhpcy5fX3BhcnNlRHVyYXRpb25NcyhtaW5SZXRlbnRpb24pO1xuICAgICAgaWYgKHR5cGVvZiByZXRlbnRpb25NcyAhPT0gXCJudW1iZXJcIiB8fCByZXRlbnRpb25NcyA8IDAgfHwgIWlzRmluaXRlKHJldGVudGlvbk1zKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZHVyYXRpb246IFwiJyArIG1pblJldGVudGlvbiArICdcIi4gRXhwZWN0ZWQgYSB2YWxpZCBkdXJhdGlvbiBzdHJpbmcgbGlrZSBcIjFzXCIsIFwiMW1cIiwgXCIxaFwiLCBldGMuJyk7XG4gICAgICB9XG4gICAgICB0b2tlblJldGVudGlvblVudGlsID0gRGF0ZS5ub3coKSArIHJldGVudGlvbk1zO1xuICAgIH0gZWxzZSBpZiAobWluUmV0ZW50aW9uIGluc3RhbmNlb2YgRGF0ZSB8fCAobWluUmV0ZW50aW9uICYmIHR5cGVvZiBtaW5SZXRlbnRpb24uZ2V0VGltZSA9PT0gXCJmdW5jdGlvblwiKSkge1xuICAgICAgLy8gQWNjZXB0IERhdGUtbGlrZSBvYmplY3RzIChhbnl0aGluZyB3aXRoIGdldFRpbWUpLCBtYXRjaGluZ1xuICAgICAgLy8gcGFyc2VEdXJhdGlvblRvRGF0ZTogdmFsdWVzIHRoYXQgY3Jvc3NlZCB0aGUgc2VyZGUgYm91bmRhcnkgbWF5XG4gICAgICAvLyBub3QgYmUgcmVhbG0tbmF0aXZlIERhdGUgaW5zdGFuY2VzLlxuICAgICAgdG9rZW5SZXRlbnRpb25VbnRpbCA9IG1pblJldGVudGlvbi5nZXRUaW1lKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgZHVyYXRpb24gcGFyYW1ldGVyLiBFeHBlY3RlZCBhIGR1cmF0aW9uIHN0cmluZywgbnVtYmVyIChtaWxsaXNlY29uZHMpLCBvciBEYXRlIG9iamVjdC5cIik7XG4gICAgfVxuICB9XG5cbiAgLy8gUmVnaXN0ZXIgaW4gcGVuZGluZyBvcGVyYXRpb25zLiBNZXRhZGF0YSBzdGF5cyBhIFJBVyB2YWx1ZTsgdGhlIGhvc3RcbiAgLy8gc2VyaWFsaXplcyBpdCB0aHJvdWdoIGEgaGFuZGxlIHdoZW4gaXQgY29sbGVjdHMgdGhlIHBlbmRpbmcgb3AuXG4gIHZhciBwZW5kaW5nT3AgPSB7XG4gICAgdHlwZTogXCJob29rXCIsXG4gICAgY29ycmVsYXRpb25JZDogY29ycmVsYXRpb25JZCxcbiAgICB0b2tlbjogdG9rZW4sXG4gICAgdG9rZW5SZXRlbnRpb25VbnRpbDogdG9rZW5SZXRlbnRpb25VbnRpbCxcbiAgICBpc1dlYmhvb2s6ICEhb3B0aW9ucy5pc1dlYmhvb2ssXG4gICAgbWV0YWRhdGE6IG9wdGlvbnMubWV0YWRhdGEsXG4gICAgaGFzQ3JlYXRlZEV2ZW50OiBmYWxzZSxcbiAgfTtcbiAgZ2xvYmFsVGhpcy5fX3BlbmRpbmcucHVzaChwZW5kaW5nT3ApO1xuXG4gIC8vIFBlci1ob29rIGxpZmVjeWNsZSBzdGF0ZSBiYWNraW5nIGhvb2suZ2V0Q29uZmxpY3QoKTogcmVzb2x2ZXMgbnVsbFxuICAvLyBvbmNlIGNyZWF0aW9uIGlzIGNvbmZpcm1lZCAoaG9va19jcmVhdGVkKSwgb3IgcmVzb2x2ZXMgd2l0aCB0aGVcbiAgLy8gY29uZmxpY3RpbmcgUnVuIGhhbmRsZSAvIHJlamVjdHMgd2l0aCBIb29rQ29uZmxpY3RFcnJvciBvblxuICAvLyBob29rX2NvbmZsaWN0LiBTdGF0ZSB0cmFuc2l0aW9ucyBhcmUgZHJpdmVuIGJ5IHRoZSBob3N0IGR1cmluZyBldmVudFxuICAvLyBwcm9jZXNzaW5nIChzZWUgcHJvY2Vzc0V2ZW50cykuXG4gIGdsb2JhbFRoaXMuX19ob29rcyA9IGdsb2JhbFRoaXMuX19ob29rcyB8fCB7fTtcbiAgZ2xvYmFsVGhpcy5fX2hvb2tzW2NvcnJlbGF0aW9uSWRdID0ge1xuICAgIHRva2VuOiB0b2tlbixcbiAgICBjcmVhdGVkOiBmYWxzZSxcbiAgICBjb25mbGljdDogbnVsbCxcbiAgICBnZXRDb25mbGljdFJlc29sdmVyczogW10sXG4gIH07XG5cbiAgLy8gRWFjaCBhd2FpdCBjcmVhdGVzIGEgbmV3IHByb21pc2UgZm9yIHRoZSBuZXh0IHBheWxvYWQuXG4gIC8vIFRoZSBjb3JyZWxhdGlvbklkIHN0YXlzIHRoZSBzYW1lIOKAlCB0aGUgcmVzb2x2ZXIgaXMgcmVwbGFjZWQgZWFjaCB0aW1lLlxuICBmdW5jdGlvbiBjcmVhdGVIb29rUHJvbWlzZSgpIHtcbiAgICAvLyBDaGVjayB0aGUgcGF5bG9hZCBidWZmZXIgZmlyc3Qg4oCUIGlmIGEgaG9va19yZWNlaXZlZCBldmVudCBhcnJpdmVkXG4gICAgLy8gYmVmb3JlIHRoaXMgaG9vayB3YXMgYXdhaXRlZCwgdGhlIHBheWxvYWQgd2FzIGJ1ZmZlcmVkIGluIHRoZSBWTVxuICAgIC8vIGhlYXAuIERyYWluIGl0IGltbWVkaWF0ZWx5IChtYXRjaGluZyBldmVudC1yZXBsYXkgcGF5bG9hZHNRdWV1ZSkuXG4gICAgdmFyIGJ1ZiA9IGdsb2JhbFRoaXMuX19ob29rUGF5bG9hZEJ1ZmZlcltjb3JyZWxhdGlvbklkXTtcbiAgICBpZiAoYnVmICYmIGJ1Zi5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGJ1Zi5zaGlmdCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1tjb3JyZWxhdGlvbklkXSA9IHsgcmVzb2x2ZTogcmVzb2x2ZSwgcmVqZWN0OiByZWplY3QgfTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRpc3Bvc2VIb29rKCkge1xuICAgIGlmIChpc0Rpc3Bvc2VkKSByZXR1cm47XG4gICAgaXNEaXNwb3NlZCA9IHRydWU7XG4gICAgLy8gQSBjb25mbGljdGVkIGhvb2sgd2FzIG5ldmVyIGNyZWF0ZWQgKHRoZSB3b3JsZCByZWplY3RlZCBpdHMgY2xhaW1cbiAgICAvLyDigJQgdGhlIHRva2VuIGJlbG9uZ3MgdG8gYW5vdGhlciBydW4pLCBzbyB0aGVyZSBpcyBubyBlbnRpdHkgdG9cbiAgICAvLyBkaXNwb3NlLiBNaXJyb3JzIHRoZSBub2RlOnZtIGVuZ2luZSwgd2hlcmUgaG9va19jb25mbGljdCByZW1vdmVzXG4gICAgLy8gdGhlIGludm9jYXRpb24tcXVldWUgaXRlbSBiZWZvcmUgZGlzcG9zZSBjYW4gbWFyayBpdC4gRW1pdHRpbmcgYVxuICAgIC8vIGhvb2tfZGlzcG9zZWQgaGVyZSB3b3VsZCBiZSByZWplY3RlZCBieSB0aGUgd29ybGQnc1xuICAgIC8vIGhvb2stZXhpc3RlbmNlIHZhbGlkYXRpb24uXG4gICAgdmFyIHN0YXRlID0gZ2xvYmFsVGhpcy5fX2hvb2tzW2NvcnJlbGF0aW9uSWRdO1xuICAgIGlmICghc3RhdGUgfHwgIXN0YXRlLmNvbmZsaWN0KSB7XG4gICAgICAvLyBTaWduYWwgdG8gdGhlIGVudHJ5cG9pbnQgdG8gY3JlYXRlIGEgaG9va19kaXNwb3NlZCBldmVudC4gVGhlXG4gICAgICAvLyB0b2tlbiBpcyBjYXJyaWVkIHNvIHRoZSBlbnRyeXBvaW50IGNhbiBvcmRlciBzYW1lLXRva2VuIGhvb2tcbiAgICAgIC8vIG9wZXJhdGlvbnMgc2VxdWVudGlhbGx5IChhIGRpc3Bvc2UgbXVzdCByZWxlYXNlIHRoZSB0b2tlbiBiZWZvcmVcbiAgICAgIC8vIGEgbGF0ZXIgc2FtZS10b2tlbiBob29rJ3MgY3JlYXRpb24gaXMgdmFsaWRhdGVkKS5cbiAgICAgIGdsb2JhbFRoaXMuX19wZW5kaW5nLnB1c2goe1xuICAgICAgICB0eXBlOiBcImhvb2tfZGlzcG9zZVwiLFxuICAgICAgICBjb3JyZWxhdGlvbklkOiBjb3JyZWxhdGlvbklkLFxuICAgICAgICB0b2tlbjogdG9rZW4sXG4gICAgICAgIGhhc0NyZWF0ZWRFdmVudDogZmFsc2UsXG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gSWYgdGhlcmUncyBhIHBlbmRpbmcgcmVzb2x2ZXIsIHJlc29sdmUgaXQgd2l0aCB1bmRlZmluZWQgdG8gYnJlYWsgdGhlIGl0ZXJhdG9yXG4gICAgaWYgKGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbY29ycmVsYXRpb25JZF0pIHtcbiAgICAgIGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbY29ycmVsYXRpb25JZF0ucmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgZGVsZXRlIGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbY29ycmVsYXRpb25JZF07XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZ2V0Q29uZmxpY3QoKSB7XG4gICAgdmFyIHN0YXRlID0gZ2xvYmFsVGhpcy5fX2hvb2tzW2NvcnJlbGF0aW9uSWRdO1xuICAgIGlmIChzdGF0ZS5jb25mbGljdCkge1xuICAgICAgcmV0dXJuIHN0YXRlLmNvbmZsaWN0LnJ1blxuICAgICAgICA/IFByb21pc2UucmVzb2x2ZShzdGF0ZS5jb25mbGljdC5ydW4pXG4gICAgICAgIDogUHJvbWlzZS5yZWplY3Qoc3RhdGUuY29uZmxpY3QuZXJyb3IpO1xuICAgIH1cbiAgICBpZiAoc3RhdGUuY3JlYXRlZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICB9XG4gICAgLy8gQ3JlYXRpb24gbm90IHlldCBjb25maXJtZWQgYnkgdGhlIGV2ZW50IGxvZyDigJQgcGFyayB0aGUgYXdhaXRlciBhbmRcbiAgICAvLyBmbGFnIHRoZSBwZW5kaW5nIG9wIHNvIHRoZSBlbnRyeXBvaW50IHJlLWludm9rZXMgdGhlIHdvcmtmbG93IHJpZ2h0XG4gICAgLy8gYWZ0ZXIgd3JpdGluZyBob29rX2NyZWF0ZWQgKG5vdGhpbmcgZXh0ZXJuYWwgcmVzdW1lcyBhIGdldENvbmZsaWN0XG4gICAgLy8gYXdhaXRlcjsgY29uZmlybWF0aW9uIG9ubHkgY29tZXMgZnJvbSByZXBsYXlpbmcgdGhlIG5ldyBldmVudCkuXG4gICAgcGVuZGluZ09wLmhhc0dldENvbmZsaWN0QXdhaXRlciA9IHRydWU7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgc3RhdGUuZ2V0Q29uZmxpY3RSZXNvbHZlcnMucHVzaCh7IHJlc29sdmU6IHJlc29sdmUsIHJlamVjdDogcmVqZWN0IH0pO1xuICAgIH0pO1xuICB9XG5cbiAgdmFyIGhvb2sgPSB7XG4gICAgdG9rZW46IHRva2VuLFxuICAgIHRoZW46IGZ1bmN0aW9uKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSB7XG4gICAgICByZXR1cm4gY3JlYXRlSG9va1Byb21pc2UoKS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKTtcbiAgICB9LFxuICAgIGdldENvbmZsaWN0OiBnZXRDb25mbGljdCxcbiAgICBkaXNwb3NlOiBkaXNwb3NlSG9vayxcbiAgfTtcblxuICAvLyBTeW1ib2wuZGlzcG9zZSBmb3IgZXhwbGljaXQgcmVzb3VyY2UgbWFuYWdlbWVudFxuICBob29rW1N5bWJvbC5kaXNwb3NlXSA9IGRpc3Bvc2VIb29rO1xuXG4gIC8vIEFzeW5jSXRlcmFibGUg4oCUIHlpZWxkcyBwYXlsb2FkcyB1bnRpbCBkaXNwb3NlZFxuICBob29rW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICBuZXh0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKGlzRGlzcG9zZWQpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHsgZG9uZTogdHJ1ZSwgdmFsdWU6IHVuZGVmaW5lZCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY3JlYXRlSG9va1Byb21pc2UoKS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgLy8gSWYgZGlzcG9zZWQgd2hpbGUgd2FpdGluZywgc2lnbmFsIGRvbmVcbiAgICAgICAgICBpZiAoaXNEaXNwb3NlZCkgcmV0dXJuIHsgZG9uZTogdHJ1ZSwgdmFsdWU6IHVuZGVmaW5lZCB9O1xuICAgICAgICAgIHJldHVybiB7IGRvbmU6IGZhbHNlLCB2YWx1ZTogdmFsdWUgfTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgcmV0dXJuOiBmdW5jdGlvbigpIHtcbiAgICAgICAgZGlzcG9zZUhvb2soKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfSk7XG4gICAgICB9LFxuICAgIH07XG4gIH07XG5cbiAgcmV0dXJuIGhvb2s7XG59O1xuXG4vLyBzZXRBdHRyaWJ1dGVzIOKAlCBhdHRhY2hlcyBwbGFpbnRleHQgbWV0YWRhdGEgdG8gdGhlIGN1cnJlbnQgcnVuLlxuLy8gVmFsaWRhdGlvbiBoYXBwZW5zIGluIGxpYnJhcnkgY29kZSAobm9ybWFsaXplQXR0cmlidXRlQ2hhbmdlcykgYmVmb3JlXG4vLyB0aGlzIGRpc3BhdGNoZXIgaXMgaW52b2tlZCwgc28gXCJjaGFuZ2VzXCIgaXMgYWxyZWFkeSBub3JtYWxpemVkLiBUaGVcbi8vIHJldHVybmVkIHByb21pc2UgcmVzb2x2ZXMgd2hlbiB0aGUgbWF0Y2hpbmcgYXR0cl9zZXQgZXZlbnQgaXNcbi8vIG9ic2VydmVkIGR1cmluZyBldmVudCBwcm9jZXNzaW5nIOKAlCBtaXJyb3JpbmcgdGhlIG5vZGU6dm0gZW5naW5lJ3Ncbi8vIGNyZWF0ZVNldEF0dHJpYnV0ZXMgKGF0dHJpYnV0ZS1kaXNwYXRjaGVyLnRzKS5cbmdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX1NFVF9BVFRSSUJVVEVTXCIpXSA9IGZ1bmN0aW9uKGNoYW5nZXMsIG9wdGlvbnMpIHtcbiAgdmFyIGNvcnJlbGF0aW9uSWQgPSBcImF0dHJfXCIgKyBnbG9iYWxUaGlzLl9fZ2VuZXJhdGVVbGlkKCk7XG4gIGdsb2JhbFRoaXMuX19wZW5kaW5nLnB1c2goe1xuICAgIHR5cGU6IFwiYXR0cmlidXRlXCIsXG4gICAgY29ycmVsYXRpb25JZDogY29ycmVsYXRpb25JZCxcbiAgICBjaGFuZ2VzOiBjaGFuZ2VzLFxuICAgIGFsbG93UmVzZXJ2ZWRBdHRyaWJ1dGVzOiAhIShvcHRpb25zICYmIG9wdGlvbnMuYWxsb3dSZXNlcnZlZEF0dHJpYnV0ZXMpLFxuICAgIGhhc0NyZWF0ZWRFdmVudDogZmFsc2UsXG4gIH0pO1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgZ2xvYmFsVGhpcy5fX3JlZ2lzdGVyUmVzb2x2ZXIoY29ycmVsYXRpb25JZCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgfSk7XG59O1xuXG4vLyAtLS0tIEFib3J0Q29udHJvbGxlciAvIEFib3J0U2lnbmFsIChob29rLWJhY2tlZCkgLS0tLVxuLy8gUG9ydCBvZiB3b3JrZmxvdy9hYm9ydC1jb250cm9sbGVyLnRzIHRvIHRoZSBWTSBwZW5kaW5nLW9wIG1vZGVsOlxuLy8gdGhlIGNvbnRyb2xsZXIgcmVnaXN0ZXJzIGEgc3lzdGVtIGhvb2s7IGFib3J0KCkgZmxpcHMgdGhlIHNpZ25hbFxuLy8gc3luY2hyb25vdXNseSBhbmQgbWFya3MgdGhlIHBlbmRpbmcgb3Agc28gdGhlIGhvc3QgcmVjb3JkcyB0aGUgYWJvcnRcbi8vIChob29rX3JlY2VpdmVkIGV2ZW50ICsgc3RyZWFtIHBhY2tldCkuIE9uIHJlcGxheSwgdGhlIHJlY29yZGVkXG4vLyBob29rX3JlY2VpdmVkIGV2ZW50IGNhbGxzIF9zZXRBYm9ydGVkIGR1cmluZyBldmVudCBwcm9jZXNzaW5nIGFuZCB0aGVcbi8vIHdvcmtmbG93J3Mgb3duIGFib3J0KCkgY2FsbCBiZWNvbWVzIGEgbm8tb3AuXG52YXIgX19BQk9SVF9TVFJFQU1fTkFNRSA9IFN5bWJvbC5mb3IoXCJXT1JLRkxPV19BQk9SVF9TVFJFQU1fTkFNRVwiKTtcbnZhciBfX0FCT1JUX0hPT0tfVE9LRU4gPSBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfQUJPUlRfSE9PS19UT0tFTlwiKTtcblxuZnVuY3Rpb24gX19tYWtlQWJvcnRFcnJvcigpIHtcbiAgaWYgKHR5cGVvZiBET01FeGNlcHRpb24gIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICByZXR1cm4gbmV3IERPTUV4Y2VwdGlvbihcIlRoZSBvcGVyYXRpb24gd2FzIGFib3J0ZWQuXCIsIFwiQWJvcnRFcnJvclwiKTtcbiAgfVxuICB2YXIgZSA9IG5ldyBFcnJvcihcIlRoZSBvcGVyYXRpb24gd2FzIGFib3J0ZWQuXCIpO1xuICBlLm5hbWUgPSBcIkFib3J0RXJyb3JcIjtcbiAgcmV0dXJuIGU7XG59XG5cbmZ1bmN0aW9uIFdvcmtmbG93QWJvcnRTaWduYWwoc3RyZWFtTmFtZSwgaG9va1Rva2VuKSB7XG4gIHRoaXMuYWJvcnRlZCA9IGZhbHNlO1xuICB0aGlzLnJlYXNvbiA9IHVuZGVmaW5lZDtcbiAgdGhpc1tfX0FCT1JUX1NUUkVBTV9OQU1FXSA9IHN0cmVhbU5hbWU7XG4gIHRoaXNbX19BQk9SVF9IT09LX1RPS0VOXSA9IGhvb2tUb2tlbjtcbiAgdGhpcy5fX2xpc3RlbmVycyA9IFtdO1xuICB0aGlzLl9fb25hYm9ydCA9IG51bGw7XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV29ya2Zsb3dBYm9ydFNpZ25hbC5wcm90b3R5cGUsIFwib25hYm9ydFwiLCB7XG4gIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLl9fb25hYm9ydDsgfSxcbiAgc2V0OiBmdW5jdGlvbihoYW5kbGVyKSB7XG4gICAgdGhpcy5fX29uYWJvcnQgPSBoYW5kbGVyO1xuICAgIGlmIChoYW5kbGVyICYmIHRoaXMuYWJvcnRlZCkgaGFuZGxlci5jYWxsKHRoaXMpO1xuICB9LFxufSk7XG5Xb3JrZmxvd0Fib3J0U2lnbmFsLnByb3RvdHlwZS5fc2V0QWJvcnRlZCA9IGZ1bmN0aW9uKHJlYXNvbikge1xuICBpZiAodGhpcy5hYm9ydGVkKSByZXR1cm47XG4gIHRoaXMuYWJvcnRlZCA9IHRydWU7XG4gIHRoaXMucmVhc29uID0gcmVhc29uO1xuICBpZiAodGhpcy5fX29uYWJvcnQpIHRoaXMuX19vbmFib3J0LmNhbGwodGhpcyk7XG4gIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9fbGlzdGVuZXJzO1xuICB0aGlzLl9fbGlzdGVuZXJzID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSsrKSBsaXN0ZW5lcnNbaV0oKTtcbn07XG5Xb3JrZmxvd0Fib3J0U2lnbmFsLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGUgIT09IFwiYWJvcnRcIikgcmV0dXJuO1xuICBpZiAodGhpcy5hYm9ydGVkKSB7XG4gICAgLy8gRmlyZSBzeW5jaHJvbm91c2x5IChub3Qgb24gYSBtaWNyb3Rhc2spIGZvciBkZXRlcm1pbmlzdGljIHJlcGxheSDigJRcbiAgICAvLyBtYXRjaGVzIHRoZSBub2RlOnZtIGVuZ2luZSdzIFdvcmtmbG93QWJvcnRTaWduYWwuXG4gICAgbGlzdGVuZXIoKTtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5fX2xpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcbn07XG5Xb3JrZmxvd0Fib3J0U2lnbmFsLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGUgIT09IFwiYWJvcnRcIikgcmV0dXJuO1xuICB0aGlzLl9fbGlzdGVuZXJzID0gdGhpcy5fX2xpc3RlbmVycy5maWx0ZXIoZnVuY3Rpb24obCkgeyByZXR1cm4gbCAhPT0gbGlzdGVuZXI7IH0pO1xufTtcbldvcmtmbG93QWJvcnRTaWduYWwucHJvdG90eXBlLnRocm93SWZBYm9ydGVkID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLmFib3J0ZWQpIHtcbiAgICB0aHJvdyB0aGlzLnJlYXNvbiAhPT0gdW5kZWZpbmVkICYmIHRoaXMucmVhc29uICE9PSBudWxsXG4gICAgICA/IHRoaXMucmVhc29uXG4gICAgICA6IF9fbWFrZUFib3J0RXJyb3IoKTtcbiAgfVxufTtcbi8vIEV4cG9zZSBmb3IgdGhlIGhvc3Qgc2VyZGUncyByZXZpdmVycyAodGhleSBsb29rIHRoZSBjbGFzcyB1cCBsYXppbHksXG4vLyB0aHJvdWdoIGEgaGFuZGxlLCBhdCByZXZpdmUgdGltZSkuXG5nbG9iYWxUaGlzLl9fV29ya2Zsb3dBYm9ydFNpZ25hbCA9IFdvcmtmbG93QWJvcnRTaWduYWw7XG5cbi8vIFJlZ2lzdHJ5IG9mIGxpdmUgYWJvcnQgc2lnbmFscyBrZXllZCBieSB0aGVpciBob29rIGNvcnJlbGF0aW9uSWQuIFRoZVxuLy8gaG9zdCBkZWxpdmVycyBob29rX3JlY2VpdmVkIGV2ZW50cyBmb3IgdGhlc2UgaWRzIGFzIF9zZXRBYm9ydGVkIGNhbGxzLlxuZ2xvYmFsVGhpcy5fX2Fib3J0U2lnbmFscyA9IHt9O1xuXG5nbG9iYWxUaGlzLkFib3J0Q29udHJvbGxlciA9IGZ1bmN0aW9uIFdvcmtmbG93QWJvcnRDb250cm9sbGVyKCkge1xuICB2YXIgaWQgPSBnbG9iYWxUaGlzLl9fZ2VuZXJhdGVVbGlkKCk7XG4gIHZhciBzdHJlYW1OYW1lID0gXCJzdHJtX1wiICsgaWQgKyBcIl9zeXN0ZW1fYWJvcnRcIjtcbiAgdmFyIGhvb2tUb2tlbiA9IFwiYWJydF9cIiArIGlkO1xuICB0aGlzW19fQUJPUlRfU1RSRUFNX05BTUVdID0gc3RyZWFtTmFtZTtcbiAgdGhpc1tfX0FCT1JUX0hPT0tfVE9LRU5dID0gaG9va1Rva2VuO1xuICB0aGlzLnNpZ25hbCA9IG5ldyBXb3JrZmxvd0Fib3J0U2lnbmFsKHN0cmVhbU5hbWUsIGhvb2tUb2tlbik7XG4gIHZhciBjb3JyZWxhdGlvbklkID0gXCJob29rX1wiICsgZ2xvYmFsVGhpcy5fX2dlbmVyYXRlVWxpZCgpO1xuICAvLyBSZWdpc3RlciBhbiBpbnRlcm5hbCBzeXN0ZW0gaG9vay4gaXNTeXN0ZW0gcHJldmVudHMgdG9rZW4gbmFtZXNwYWNlXG4gIC8vIGNvbmZsaWN0cyB3aXRoIHVzZXIgaG9va3MuXG4gIGdsb2JhbFRoaXMuX19wZW5kaW5nLnB1c2goe1xuICAgIHR5cGU6IFwiaG9va1wiLFxuICAgIGNvcnJlbGF0aW9uSWQ6IGNvcnJlbGF0aW9uSWQsXG4gICAgdG9rZW46IGhvb2tUb2tlbixcbiAgICBpc1dlYmhvb2s6IGZhbHNlLFxuICAgIGlzU3lzdGVtOiB0cnVlLFxuICAgIGhhc0NyZWF0ZWRFdmVudDogZmFsc2UsXG4gIH0pO1xuICBnbG9iYWxUaGlzLl9fYWJvcnRTaWduYWxzW2NvcnJlbGF0aW9uSWRdID0gdGhpcy5zaWduYWw7XG59O1xuZ2xvYmFsVGhpcy5BYm9ydENvbnRyb2xsZXIucHJvdG90eXBlLmFib3J0ID0gZnVuY3Rpb24ocmVhc29uKSB7XG4gIGlmICh0aGlzLnNpZ25hbC5hYm9ydGVkKSByZXR1cm47IC8vIGFscmVhZHkgYWJvcnRlZCAoZS5nLiBmcm9tIHJlcGxheSlcbiAgdGhpcy5zaWduYWwuX3NldEFib3J0ZWQocmVhc29uKTtcbiAgLy8gTWFyayB0aGUgcGVuZGluZyBob29rIG9wIHNvIHRoZSBob3N0IHJlY29yZHMgdGhlIGFib3J0LiBUaGUgcGF5bG9hZFxuICAvLyBzdGF5cyBhIFJBVyB2YWx1ZTsgdGhlIGhvc3Qgc2VyaWFsaXplcyBpdCB0aHJvdWdoIGEgaGFuZGxlIHdpdGggZnVsbFxuICAvLyB0eXBlIGZpZGVsaXR5IChFcnJvcnMsIERPTUV4Y2VwdGlvbiwgY3VzdG9tIHZhbHVlcykuXG4gIHZhciB0b2tlbiA9IHRoaXNbX19BQk9SVF9IT09LX1RPS0VOXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBnbG9iYWxUaGlzLl9fcGVuZGluZy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpdGVtID0gZ2xvYmFsVGhpcy5fX3BlbmRpbmdbaV07XG4gICAgaWYgKGl0ZW0udHlwZSA9PT0gXCJob29rXCIgJiYgaXRlbS50b2tlbiA9PT0gdG9rZW4pIHtcbiAgICAgIGl0ZW0uYWJvcnRSZXF1ZXN0ZWQgPSB0cnVlO1xuICAgICAgaXRlbS5hYm9ydFBheWxvYWQgPSB7XG4gICAgICAgIGFib3J0ZWQ6IHRydWUsXG4gICAgICAgIHJlYXNvbjogcmVhc29uLFxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufTtcblxuZ2xvYmFsVGhpcy5BYm9ydFNpZ25hbCA9IHtcbiAgYWJvcnQ6IGZ1bmN0aW9uKHJlYXNvbikge1xuICAgIHZhciBzID0gbmV3IFdvcmtmbG93QWJvcnRTaWduYWwoXCJcIiwgXCJcIik7XG4gICAgcy5fc2V0QWJvcnRlZChyZWFzb24gIT09IHVuZGVmaW5lZCA/IHJlYXNvbiA6IF9fbWFrZUFib3J0RXJyb3IoKSk7XG4gICAgcmV0dXJuIHM7XG4gIH0sXG4gIGFueTogZnVuY3Rpb24oc2lnbmFscykge1xuICAgIHZhciBjb21wb3NpdGUgPSBuZXcgV29ya2Zsb3dBYm9ydFNpZ25hbChcIlwiLCBcIlwiKTtcbiAgICB2YXIgYXJyID0gQXJyYXkuZnJvbShzaWduYWxzKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFycltpXS5hYm9ydGVkKSB7XG4gICAgICAgIGNvbXBvc2l0ZS5fc2V0QWJvcnRlZChhcnJbaV0ucmVhc29uKTtcbiAgICAgICAgcmV0dXJuIGNvbXBvc2l0ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIGxpc3RlbmVycyA9IFtdO1xuICAgIHZhciBjbGVhbnVwID0gZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxpc3RlbmVycy5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAobGlzdGVuZXJzW2pdLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgbGlzdGVuZXJzW2pdLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgbGlzdGVuZXJzW2pdLmxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGlzdGVuZXJzLmxlbmd0aCA9IDA7XG4gICAgfTtcbiAgICBhcnIuZm9yRWFjaChmdW5jdGlvbihzaWduYWwpIHtcbiAgICAgIGlmICghc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIpIHJldHVybjtcbiAgICAgIHZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoIWNvbXBvc2l0ZS5hYm9ydGVkKSB7XG4gICAgICAgICAgY29tcG9zaXRlLl9zZXRBYm9ydGVkKHNpZ25hbC5yZWFzb24pO1xuICAgICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGxpc3RlbmVycy5wdXNoKHsgc2lnbmFsOiBzaWduYWwsIGxpc3RlbmVyOiBsaXN0ZW5lciB9KTtcbiAgICAgIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgbGlzdGVuZXIpO1xuICAgIH0pO1xuICAgIHJldHVybiBjb21wb3NpdGU7XG4gIH0sXG4gIHRpbWVvdXQ6IGZ1bmN0aW9uKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIFwiQWJvcnRTaWduYWwudGltZW91dCgpIGlzIG5vdCBzdXBwb3J0ZWQgaW4gd29ya2Zsb3cgZnVuY3Rpb25zLiBcIiArXG4gICAgICAgIFwiVXNlIHNsZWVwKCkgd2l0aCBhbiBBYm9ydENvbnRyb2xsZXIgaW5zdGVhZC4gXCIgK1xuICAgICAgICBcIlNlZTogL2RvY3MvZXJyb3JzL2Fib3J0LXNpZ25hbC10aW1lb3V0LWluLXdvcmtmbG93XCJcbiAgICApO1xuICB9LFxufTtcblxuLy8gV09SS0ZMT1dfR0VUX1NUUkVBTV9JRCDigJQgZ2VuZXJhdGVzIGEgc3RyZWFtIElEIGZvciBhIHdvcmtmbG93IHJ1bi5cbi8vIFJlcGxpY2F0ZXMgZ2V0V29ya2Zsb3dSdW5TdHJlYW1JZCgpIGZyb20gdXRpbC50cyBpbnNpZGUgdGhlIFF1aWNrSlMgVk0uXG4vLyBVc2VzIHRoZSBidWlsdC1pbiBidG9hKCkgZm9yIGJhc2U2NHVybCBlbmNvZGluZy5cbmdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX0dFVF9TVFJFQU1fSURcIildID0gZnVuY3Rpb24obmFtZXNwYWNlKSB7XG4gIHZhciBydW5JZCA9IGdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIldPUktGTE9XX0NPTlRFWFRcIildXG4gICAgPyBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19DT05URVhUXCIpXS53b3JrZmxvd1J1bklkXG4gICAgOiBcIlwiO1xuICB2YXIgc3RyZWFtSWQgPSBydW5JZC5yZXBsYWNlKFwid3J1bl9cIiwgXCJzdHJtX1wiKSArIFwiX3VzZXJcIjtcbiAgaWYgKCFuYW1lc3BhY2UpIHJldHVybiBzdHJlYW1JZDtcbiAgLy8gYmFzZTY0dXJsOiBidG9hIHRoZW4gcmVwbGFjZSArIHdpdGggLSwgLyB3aXRoIF8sIHN0cmlwID1cbiAgdmFyIGI2NCA9IGJ0b2EobmFtZXNwYWNlKS5yZXBsYWNlKC9cXFxcKy9nLCBcIi1cIikucmVwbGFjZSgvXFxcXC8vZywgXCJfXCIpLnJlcGxhY2UoLz0rJC8sIFwiXCIpO1xuICByZXR1cm4gc3RyZWFtSWQgKyBcIl9cIiArIGI2NDtcbn07XG5gO1xuXG4vLyAtLS0tIFJ1bnRpbWUgLS0tLVxuXG4vKipcbiAqIFBoYXNlIDEg4oCUIHN0YXRpYyAocnVuLWluZGVwZW5kZW50KSBWTSBpbml0aWFsaXphdGlvbi5cbiAqXG4gKiBDcmVhdGVzIGEgUXVpY2tKUyBWTSBhbmQgbG9hZHMgZXZlcnl0aGluZyB0aGF0IGRvZXMgbm90IGRlcGVuZCBvbiBhXG4gKiBzcGVjaWZpYyB3b3JrZmxvdyBydW46IHRoZSB3b3JrZmxvdy1wcmltaXRpdmUgYm9vdHN0cmFwICh1c2VTdGVwIC9cbiAqIHNsZWVwIC8gY3JlYXRlSG9vayAvIFJlc3BvbnNlLVJlcXVlc3QgcG9seWZpbGxzKS4gU2VyaWFsaXphdGlvbiBpc1xuICogaG9zdC1zaWRlIChxdWlja2pzLXNlcmRlLnRzKSBhbmQgY2FwdHVyZXMgaXRzIGludHJpbnNpY3MgZnJvbSB0aGUgVk1cbiAqIHJpZ2h0IGFmdGVyIHRoaXMgcmV0dXJucy5cbiAqXG4gKiBgZ2V0Tm93TXNgIGJhY2tzIHRoZSBWTSdzIFdBU0kgY2xvY2sgKGBEYXRlLm5vdygpYCAvIGBuZXcgRGF0ZSgpYFxuICogaW5zaWRlIHRoZSBWTSkuIFRoZSBjYWxsYmFjayBpdHNlbGYgaXMgc3RhdGljIOKAlCB0aGUgcGVyLXJ1biBzdGF0ZSBpdFxuICogcmVhZHMgbGl2ZXMgb24gdGhlIGhvc3QgYW5kIGlzIGFkdmFuY2VkIGFzIGV2ZW50cyBhcmUgY29uc3VtZWQsXG4gKiBtYXRjaGluZyB0aGUgbm9kZTp2bSBlbmdpbmUncyBkZXRlcm1pbmlzdGljIHJlcGxheSBjbG9jay5cbiAqXG4gKiBUaGlzIHBoYXNlIGlzIHRoZSBmdXR1cmUgYm91bmRhcnkgZm9yIFZNLW1lbW9yeSBzbmFwc2hvdHRpbmc6IGFcbiAqIGJ1aWxkLXRpbWUgc25hcHNob3QgY2FuIGNhcHR1cmUgdGhlIFZNIHJpZ2h0IGFmdGVyIHRoaXMgZnVuY3Rpb24gYW5kXG4gKiBuZXcgcnVucyBjYW4gcmVzdG9yZSBmcm9tIGl0IGluc3RlYWQgb2YgcGF5aW5nIFZNIGNyZWF0aW9uICsgZXZhbCBjb3N0XG4gKiAoYFF1aWNrSlMucmVzdG9yZWAgYWNjZXB0cyB0aGUgc2FtZSB3YXNpIG92ZXJyaWRlKS5cbiAqL1xuLyoqXG4gKiBMb29zZWx5LXR5cGVkIGFjY2Vzc29yIGZvciB0aGUgYFdlYkFzc2VtYmx5YCBnbG9iYWwuIFRoZSBwYWNrYWdlXG4gKiB0c2NvbmZpZydzIGBsaWI6IFtcImVzMjAyMlwiXWAgZG9lcyBub3QgaW5jbHVkZSB0aGUgRE9NIGxpYiB3aGVyZSB0aGVcbiAqIGBXZWJBc3NlbWJseWAgbmFtZXNwYWNlIHR5cGVzIGxpdmU7IHRoZSBydW50aW1lIGdsb2JhbCBpcyBhdmFpbGFibGUgb25cbiAqIGV2ZXJ5IFdBU00tY2FwYWJsZSBwbGF0Zm9ybSB0aGlzIGVuZ2luZSB0YXJnZXRzLlxuICovXG5jb25zdCBXZWJBc3NlbWJseUdsb2JhbCA9IChnbG9iYWxUaGlzIGFzIGFueSkuV2ViQXNzZW1ibHkgYXMge1xuICBjb21waWxlKGJ5dGVzOiBVaW50OEFycmF5KTogUHJvbWlzZTxvYmplY3Q+O1xufTtcblxudHlwZSBDb21waWxlZEV4dGVuc2lvbiA9IE9taXQ8RXh0ZW5zaW9uRGVzY3JpcHRvciwgJ3dhc20nPiAmIHtcbiAgd2FzbTogRXh0ZW5zaW9uRGVzY3JpcHRvclsnd2FzbSddO1xufTtcblxuLyoqXG4gKiBQcm9jZXNzLXdpZGUgY2FjaGUgb2YgdGhlIGNvbXBpbGVkIGBXZWJBc3NlbWJseS5Nb2R1bGVgcyBmb3IgdGhlIG1haW5cbiAqIFF1aWNrSlMgcnVudGltZSBhbmQgaXRzIG5hdGl2ZSBleHRlbnNpb25zLiBgV2ViQXNzZW1ibHkuY29tcGlsZWAgb2YgdGhlXG4gKiB+NjAwIEtCIHJ1bnRpbWUgYmluYXJ5IGlzIHRoZSBtb3N0IGV4cGVuc2l2ZSBwYXJ0IG9mIFZNIGNyZWF0aW9uIGFuZCBpc1xuICogcHVyZSAobm8gcGVyLVZNIHN0YXRlIOKAlCBpbnN0YW50aWF0aW9uIGJpbmRzIHRoZSBwZXItVk0gbWVtb3J5KSwgc28gaXRcbiAqIG9ubHkgbmVlZHMgdG8gaGFwcGVuIG9uY2UgcGVyIHByb2Nlc3MuIFRoZSBwcm9taXNlIGlzIGNhY2hlZCAobm90IHRoZVxuICogcmVzdWx0KSBzbyBjb25jdXJyZW50IGZpcnN0IGludm9jYXRpb25zIHNoYXJlIGEgc2luZ2xlIGNvbXBpbGF0aW9uLlxuICovXG5sZXQgY29tcGlsZWRBc3NldHNQcm9taXNlOlxuICB8IFByb21pc2U8e1xuICAgICAgd2FzbTogb2JqZWN0O1xuICAgICAgZXh0ZW5zaW9uczogQ29tcGlsZWRFeHRlbnNpb25bXTtcbiAgICB9PlxuICB8IHVuZGVmaW5lZDtcblxuZnVuY3Rpb24gZ2V0Q29tcGlsZWRBc3NldHMoKSB7XG4gIGlmICghY29tcGlsZWRBc3NldHNQcm9taXNlKSB7XG4gICAgY29tcGlsZWRBc3NldHNQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IFt3YXNtLCAuLi5leHRlbnNpb25Nb2R1bGVzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgV2ViQXNzZW1ibHlHbG9iYWwuY29tcGlsZShxdWlja2pzV2FzbSksXG4gICAgICAgIC4uLnF1aWNranNFeHRlbnNpb25zLm1hcCgoZXh0KSA9PlxuICAgICAgICAgIFdlYkFzc2VtYmx5R2xvYmFsLmNvbXBpbGUoZXh0Lndhc20gYXMgVWludDhBcnJheSlcbiAgICAgICAgKSxcbiAgICAgIF0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgd2FzbSxcbiAgICAgICAgZXh0ZW5zaW9uczogcXVpY2tqc0V4dGVuc2lvbnMubWFwKChleHQsIGkpID0+ICh7XG4gICAgICAgICAgLi4uZXh0LFxuICAgICAgICAgIHdhc206IGV4dGVuc2lvbk1vZHVsZXNbaV0gYXMgRXh0ZW5zaW9uRGVzY3JpcHRvclsnd2FzbSddLFxuICAgICAgICB9KSksXG4gICAgICB9O1xuICAgIH0pKCk7XG4gICAgLy8gT24gZmFpbHVyZSwgY2xlYXIgdGhlIGNhY2hlIHNvIGEgbGF0ZXIgaW52b2NhdGlvbiBjYW4gcmV0cnkgcmF0aGVyXG4gICAgLy8gdGhhbiBiZWluZyBzdHVjayB3aXRoIGEgcmVqZWN0ZWQgcHJvbWlzZSBmb3JldmVyLlxuICAgIGNvbXBpbGVkQXNzZXRzUHJvbWlzZS5jYXRjaCgoKSA9PiB7XG4gICAgICBjb21waWxlZEFzc2V0c1Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGNvbXBpbGVkQXNzZXRzUHJvbWlzZTtcbn1cblxuLyoqXG4gKiBXQVNJIGNsb2NrIG92ZXJyaWRlIHJlYWRpbmcgdGhlIGdpdmVuIGFjY2Vzc29yIOKAlCBzaGFyZWQgYmV0d2VlbiBmcmVzaFxuICogYm9vdHMgKGluaXRXb3JrZmxvd1ZNKSBhbmQgYmFzZWxpbmUtc25hcHNob3QgcmVzdG9yZXMsIHNvIHRoZSB0d29cbiAqIHBhdGhzIGNhbm5vdCBkcmlmdCBvbiByb3VuZGluZy9lbmNvZGluZy5cbiAqXG4gKiBEZXRlcm1pbmlzdGljIHJlcGxheSBjbG9jazogRGF0ZS5ub3coKSAvIG5ldyBEYXRlKCkgaW5zaWRlIHRoZSBWTVxuICogcmVhZCB0aGUgaG9zdC1jb250cm9sbGVkIGNsb2NrIGluc3RlYWQgb2Ygd2FsbCB0aW1lLiBSZXBsYXlcbiAqIHJlLWV4ZWN1dGVzIHRoZSB3b3JrZmxvdyBmcm9tIHRoZSB0b3Agb24gZXZlcnkgaW52b2NhdGlvbiwgc28gdGhlXG4gKiBjbG9jayBtdXN0IGJlIGRlcml2ZWQgZnJvbSB0aGUgZXZlbnQgbG9nIChub3QgcmVhbCB0aW1lKSBmb3IgdGhlXG4gKiB3b3JrZmxvdyB0byBvYnNlcnZlIHN0YWJsZSB0aW1lc3RhbXBzIGFjcm9zcyBpbnZvY2F0aW9ucy5cbiAqL1xuZnVuY3Rpb24gbWFrZURldGVybWluaXN0aWNDbG9ja1dhc2koZ2V0Tm93TXM6ICgpID0+IG51bWJlcik6IFdhc2lPcHRpb25zIHtcbiAgcmV0dXJuIChtZW1vcnkpID0+ICh7XG4gICAgY2xvY2tfdGltZV9nZXQoX2Nsb2NrSWQ6IG51bWJlciwgX3ByZWNpc2lvbjogYmlnaW50LCByZXN1bHRQdHI6IG51bWJlcikge1xuICAgICAgY29uc3QgdGltZU5zID0gQmlnSW50KE1hdGgucm91bmQoZ2V0Tm93TXMoKSkpICogMV8wMDBfMDAwbjtcbiAgICAgIG5ldyBEYXRhVmlldyhtZW1vcnkuYnVmZmVyKS5zZXRCaWdVaW50NjQocmVzdWx0UHRyLCB0aW1lTnMsIHRydWUpO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSxcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGluaXRXb3JrZmxvd1ZNKFxuICBnZXROb3dNczogKCkgPT4gbnVtYmVyLFxuICBpbnRlcnJ1cHRCdWRnZXQ6IEludGVycnVwdEJ1ZGdldFxuKTogUHJvbWlzZTxRdWlja0pTPiB7XG4gIGNvbnN0IGFzc2V0cyA9IGF3YWl0IGdldENvbXBpbGVkQXNzZXRzKCk7XG4gIGNvbnN0IHZtID0gYXdhaXQgUXVpY2tKUy5jcmVhdGUoe1xuICAgIHdhc206IGFzc2V0cy53YXNtIGFzIG5ldmVyLFxuICAgIG1lbW9yeUxpbWl0OiAyNTYgKiAxMDI0ICogMTAyNCxcbiAgICBpbnRlcnJ1cHRIYW5kbGVyOiBjcmVhdGVJbnRlcnJ1cHRIYW5kbGVyKGludGVycnVwdEJ1ZGdldCksXG4gICAgZXh0ZW5zaW9uczogYXNzZXRzLmV4dGVuc2lvbnMsXG4gICAgd2FzaTogbWFrZURldGVybWluaXN0aWNDbG9ja1dhc2koZ2V0Tm93TXMpLFxuICB9KTtcblxuICAvLyBCb290c3RyYXAgd29ya2Zsb3cgcHJpbWl0aXZlc1xuICB2bS5ldmFsQ29kZShWTV9CT09UU1RSQVAsICdib290c3RyYXAuanMnKS5kaXNwb3NlKCk7XG5cbiAgcmV0dXJuIHZtO1xufVxuXG4vLyAtLS0tIEJhc2VsaW5lIHNuYXBzaG90IChzdGFydHVwIG9wdGltaXphdGlvbikgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vXG4vLyBFdmFsdWF0aW5nIHRoZSB3b3JrZmxvdyBidW5kbGUgZG9taW5hdGVzIFZNIHN0YXJ0dXAgKH43NG1zIG9mIGEgfjc3bXNcbi8vIGJvb3QgZm9yIGEgMS4zTUIgYnVuZGxlKSwgYW5kIGZ1bGwgZXZlbnQgcmVwbGF5IHBheXMgaXQgb24gRVZFUllcbi8vIGludm9jYXRpb24uIFRoZSBidW5kbGUgaXMgaWRlbnRpY2FsIGFjcm9zcyBhbGwgcnVucyBvZiBhIGRlcGxveW1lbnQsIHNvXG4vLyB0aGUgZW5naW5lIGh5ZHJhdGVzIG9uZSBWTSBwZXIgZnVuY3Rpb24gaW5zdGFuY2UgKGJvb3RzdHJhcCArIGJ1bmRsZVxuLy8gZXZhbCksIHNuYXBzaG90cyBpdHMgbWVtb3J5LCBhbmQgc3RhcnRzIGV2ZXJ5IGludm9jYXRpb24gYnkgcmVzdG9yaW5nXG4vLyB0aGUgc25hcHNob3QgKH4zbXMpIGluc3RlYWQgb2YgcmUtZXZhbHVhdGluZy5cbi8vXG4vLyBEZXRlcm1pbmlzbTogcmVwbGF5IHJlcXVpcmVzIG1vZHVsZS1zY29wZSB1c2VyIGNvZGUgdG8gb2JzZXJ2ZSB0aGVcbi8vIHJ1bi1zZWVkZWQgUFJORyBhbmQgdGhlIHJ1bidzIGRldGVybWluaXN0aWMgY2xvY2suIEEgcmVzdG9yZWQgaGVhcFxuLy8gY2FycmllcyB3aGF0ZXZlciBtb2R1bGUgc2NvcGUgY29tcHV0ZWQgYXQgSFlEUkFURSB0aW1lLCBzbyB0aGVcbi8vIG9wdGltaXphdGlvbiBpcyBvbmx5IHNvdW5kIHdoZW4gbW9kdWxlIHNjb3BlIGNvbnN1bWVkIG5laXRoZXJcbi8vIHJhbmRvbW5lc3Mgbm9yIHRpbWUuIEJvdGggYXJlIGRldGVjdGVkIGR1cmluZyBoeWRyYXRlIOKAlCB0aGUgcGxhY2Vob2xkZXJcbi8vIGhvc3QgZm5zIGNvdW50IGRyYXdzLCB0aGUgaHlkcmF0ZSBjbG9jayBjb3VudHMgcmVhZHMg4oCUIGFuZCBhIGJ1bmRsZVxuLy8gdGhhdCB1c2VkIGVpdGhlciBpcyBtYXJrZWQgaW5lbGlnaWJsZTogZXZlcnkgaW52b2NhdGlvbiBmYWxscyBiYWNrIHRvXG4vLyBmcmVzaCBldmFsdWF0aW9uLCBwcmVzZXJ2aW5nIGV4YWN0IG5vZGU6dm0tcGFyaXR5IHNlbWFudGljcy4gV2hlbiB0aGVcbi8vIGdhdGUgcGFzc2VzLCByZXN0b3JlIGlzIGJ5dGUtZXF1aXZhbGVudCB0byBmcmVzaCBldmFsICh2ZXJpZmllZCBieSB0aGVcbi8vIHBhcml0eSB0ZXN0cyk6IHRoZSBwZXItcnVuIGhvc3QgZm5zIGFyZSByZS1yZWdpc3RlcmVkIGJ5IG5hbWUgb24gdGhlXG4vLyByZXN0b3JlZCBWTSAocXVpY2tqcy13YXNpIHJlc3RvcmUgc2VtYW50aWNzKSBiZWZvcmUgdGhlIHdvcmtmbG93IGJvZHlcbi8vIHJ1bnMsIHNvIHRoZSBzZWVkZWQgZHJhdyBzZXF1ZW5jZSDigJQgYW5kIGV2ZXJ5IGNvcnJlbGF0aW9uSWQg4oCUIGlzXG4vLyBpZGVudGljYWwuXG4vL1xuLy8gVGhlIGNhY2hlIGlzIHBlciBmdW5jdGlvbiBpbnN0YW5jZSBhbmQga2V5ZWQgb24gdGhlIGJ1bmRsZSBzdHJpbmdcbi8vIChyZWZlcmVuY2Utc3RhYmxlOiB0aGUgZ2VuZXJhdGVkIGZsb3cgcm91dGUgaG9sZHMgaXQgaW4gYSBtb2R1bGUtbGV2ZWxcbi8vIGNvbnN0KS4gQ2FwcGVkIGF0IGEgZmV3IGVudHJpZXMgc28gdGVzdHMgd2l0aCBtYW55IGRpc3RpbmN0IGJ1bmRsZXNcbi8vIGRvbid0IGFjY3VtdWxhdGUgMTZNQiBzbmFwc2hvdHMuXG5cbi8qKlxuICogRXZhbCBmaWxlbmFtZSB1c2VkIHdoZW4gaHlkcmF0aW5nIHRoZSBiYXNlbGluZSBWTS4gVGhlIGJhc2VsaW5lIGlzXG4gKiBzaGFyZWQgYnkgRVZFUlkgd29ya2Zsb3cgaW4gdGhlIGJ1bmRsZSwgc28gdGhlIGZpbGVuYW1lIGJha2VkIGludG9cbiAqIGl0cyBjb21waWxlZCBjb2RlIChhbmQgdGhlcmVmb3JlIGludG8gc25hcHNob3QtcGF0aCBzdGFjayBmcmFtZXMpXG4gKiBtdXN0IGJlIHdvcmtmbG93LWluZGVwZW5kZW50IOKAlCBoeWRyYXRpbmcgdW5kZXIgdGhlIGZpcnN0IGNhbGxlcidzXG4gKiB3b3JrZmxvd0lkIHdvdWxkIGJyZWFrIGByZW1hcEVycm9yU3RhY2tgJ3MgZmlsZW5hbWUgbWF0Y2hpbmcgZm9yXG4gKiBldmVyeSBvdGhlciB3b3JrZmxvdyBpbiB0aGUgYnVuZGxlLiBSZW1hcCBjYWxsIHNpdGVzIG1hdGNoIHRoaXNcbiAqIGNvbnN0YW50IElOIEFERElUSU9OIHRvIHRoZSBydW4ncyBtb2R1bGUgc3BlY2lmaWVyICh3aGljaCBjb3ZlcnNcbiAqIGZyZXNoLXBhdGggZnJhbWVzKS5cbiAqL1xuZXhwb3J0IGNvbnN0IEJBU0VMSU5FX0JVTkRMRV9GSUxFTkFNRSA9ICd3b3JrZmxvdy1idW5kbGUuanMnO1xuXG50eXBlIEJhc2VsaW5lRW50cnkgPVxuICB8IHtcbiAgICAgIHN0YXRlOiAncmVhZHknO1xuICAgICAgc25hcHNob3Q6IFNuYXBzaG90O1xuICAgICAgLyoqXG4gICAgICAgKiBSYXcgYm94IHBvaW50ZXIgb2YgdGhlIHNlcmRlIGNhcHR1cmUgcm9vdCBjcmVhdGVkIEJFRk9SRSB0aGVcbiAgICAgICAqIGJ1bmRsZSBldmFsdWF0ZWQgKHNlZSBjYXB0dXJlU2VyZGVSb290KS4gVGhlIGJveCBsaXZlcyBpbiB0aGVcbiAgICAgICAqIHNuYXBzaG90J3MgbWVtb3J5IGltYWdlIGF0IHRoaXMgb2Zmc2V0OyBldmVyeSByZXN0b3JlZCBWTVxuICAgICAgICogcmUtYWRvcHRzIGl0IHNvIHNlcmRlIGluaXRpYWxpemF0aW9uIGV4ZWN1dGVzIG5vIGd1ZXN0IGNvZGVcbiAgICAgICAqIGFmdGVyIHVzZXIgY29kZSBoYXMgcnVuIOKAlCBjYXB0dXJlLWJlZm9yZS11c2VyLWNvZGUgc2VtYW50aWNzLFxuICAgICAgICogaWRlbnRpY2FsIHRvIHRoZSBmcmVzaCBwYXRoLlxuICAgICAgICovXG4gICAgICBzZXJkZVJvb3RQdHI6IG51bWJlcjtcbiAgICB9XG4gIHwgeyBzdGF0ZTogJ2luZWxpZ2libGUnOyByZWFzb246IHN0cmluZyB9O1xuXG5jb25zdCBiYXNlbGluZUNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8QmFzZWxpbmVFbnRyeT4+KCk7XG5jb25zdCBCQVNFTElORV9DQUNIRV9NQVhfRU5UUklFUyA9IDQ7XG5cbi8qKiBUZXN0LW9ubHk6IHJlc2V0IHRoZSBiYXNlbGluZSBjYWNoZSBiZXR3ZWVuIHRlc3QgY2FzZXMuICovXG5leHBvcnQgZnVuY3Rpb24gX19jbGVhckJhc2VsaW5lU25hcHNob3RDYWNoZUZvclRlc3RzKCk6IHZvaWQge1xuICBiYXNlbGluZUNhY2hlLmNsZWFyKCk7XG59XG5cbi8qKiBUZXN0LW9ubHk6IG9ic2VydmUgaG93IGEgYnVuZGxlIHdhcyBjbGFzc2lmaWVkLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIF9fcGVla0Jhc2VsaW5lRW50cnlGb3JUZXN0cyhcbiAgd29ya2Zsb3dDb2RlOiBzdHJpbmdcbik6IFByb21pc2U8QmFzZWxpbmVFbnRyeSB8IHVuZGVmaW5lZD4ge1xuICByZXR1cm4gYmFzZWxpbmVDYWNoZS5nZXQod29ya2Zsb3dDb2RlKTtcbn1cblxuLyoqXG4gKiBIeWRyYXRlIGEgVk0gd2l0aCB0aGUgd29ya2Zsb3cgYnVuZGxlIGFuZCBzbmFwc2hvdCBpdCwgZ2F0aW5nIG9uXG4gKiBtb2R1bGUtc2NvcGUgbm9uZGV0ZXJtaW5pc20gKHNlZSB0aGUgc2VjdGlvbiBjb21tZW50IGFib3ZlKS4gUmV0dXJucyBhblxuICogYGluZWxpZ2libGVgIGVudHJ5IGluc3RlYWQgb2YgdGhyb3dpbmcgb24gZXZhbCBmYWlsdXJlIOKAlCB0aGUgZnJlc2ggcGF0aFxuICogcmUtZXZhbHVhdGVzIGFuZCBwcm9kdWNlcyB0aGUgcmVhbCwgc291cmNlLW1hcHBlZCBlcnJvci5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcHJlcGFyZUJhc2VsaW5lU25hcHNob3QoXG4gIHdvcmtmbG93Q29kZTogc3RyaW5nLFxuICB3b3JrZmxvd0lkOiBzdHJpbmdcbik6IFByb21pc2U8QmFzZWxpbmVFbnRyeT4ge1xuICBjb25zdCBoeWRyYXRlU3RhcnQgPSBEYXRlLm5vdygpO1xuICBsZXQgY2xvY2tSZWFkcyA9IDA7XG4gIGNvbnN0IGJ1ZGdldDogSW50ZXJydXB0QnVkZ2V0ID0geyBzdGFydDogRGF0ZS5ub3coKSB9O1xuICBjb25zdCBhc3NldHMgPSBhd2FpdCBnZXRDb21waWxlZEFzc2V0cygpO1xuICBjb25zdCB2bSA9IGF3YWl0IFF1aWNrSlMuY3JlYXRlKHtcbiAgICB3YXNtOiBhc3NldHMud2FzbSBhcyBuZXZlcixcbiAgICBtZW1vcnlMaW1pdDogMjU2ICogMTAyNCAqIDEwMjQsXG4gICAgaW50ZXJydXB0SGFuZGxlcjogY3JlYXRlSW50ZXJydXB0SGFuZGxlcihidWRnZXQpLFxuICAgIGV4dGVuc2lvbnM6IGFzc2V0cy5leHRlbnNpb25zLFxuICAgIHdhc2k6ICgobWVtb3J5KSA9PiAoe1xuICAgICAgY2xvY2tfdGltZV9nZXQoX2Nsb2NrSWQ6IG51bWJlciwgX3ByZWNpc2lvbjogYmlnaW50LCByZXN1bHRQdHI6IG51bWJlcikge1xuICAgICAgICBjbG9ja1JlYWRzKys7XG4gICAgICAgIGNvbnN0IHRpbWVOcyA9IEJpZ0ludChoeWRyYXRlU3RhcnQpICogMV8wMDBfMDAwbjtcbiAgICAgICAgbmV3IERhdGFWaWV3KG1lbW9yeS5idWZmZXIpLnNldEJpZ1VpbnQ2NChyZXN1bHRQdHIsIHRpbWVOcywgdHJ1ZSk7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfSxcbiAgICB9KSkgc2F0aXNmaWVzIFdhc2lPcHRpb25zLFxuICB9KTtcbiAgdHJ5IHtcbiAgICB2bS5ldmFsQ29kZShWTV9CT09UU1RSQVAsICdib290c3RyYXAuanMnKS5kaXNwb3NlKCk7XG5cbiAgICAvLyBQbGFjZWhvbGRlciBob3N0IGZucyB1bmRlciB0aGUgU0FNRSBOQU1FUyB0aGUgcGVyLXJ1biBwaGFzZSB1c2VzLlxuICAgIC8vIFRoZXkgZXhpc3Qgc28gbW9kdWxlLXNjb3BlIGNvZGUgY2FuIGV4ZWN1dGUgYXQgaHlkcmF0ZSB0aW1lLCBhbmQgdG9cbiAgICAvLyBkZXRlY3QgdGhhdCBpdCBkaWQ6IGFueSBkcmF3IG1lYW5zIHRoZSBoZWFwIHdvdWxkIGJha2VcbiAgICAvLyBoeWRyYXRlLXNlZWRlZCB2YWx1ZXMgdGhhdCBwZXItcnVuIGZyZXNoIGV2YWwgd291bGQgY29tcHV0ZVxuICAgIC8vIGRpZmZlcmVudGx5LiBydW5Xb3JrZmxvd0luVk0gcmUtcmVnaXN0ZXJzIGFsbCB0aHJlZSBuYW1lcyB3aXRoIHRoZVxuICAgIC8vIHJ1bi1zZWVkZWQgY2xvc3VyZXMgYWZ0ZXIgcmVzdG9yZS5cbiAgICBsZXQgZHJhd3MgPSAwO1xuICAgIHtcbiAgICAgIHVzaW5nIHJhbmRvbUZuID0gdm0ubmV3RnVuY3Rpb24oJ3JhbmRvbScsICgpID0+IHtcbiAgICAgICAgZHJhd3MrKztcbiAgICAgICAgcmV0dXJuIHZtLm5ld051bWJlcihNYXRoLnJhbmRvbSgpKTtcbiAgICAgIH0pO1xuICAgICAgdXNpbmcgbWF0aCA9IHZtLmdsb2JhbC5nZXRQcm9wKCdNYXRoJyk7XG4gICAgICBtYXRoLnNldFByb3AoJ3JhbmRvbScsIHJhbmRvbUZuKTtcbiAgICAgIHVzaW5nIG5hbm9pZEZuID0gdm0ubmV3RnVuY3Rpb24oJ19fZ2VuZXJhdGVOYW5vaWQnLCAoKSA9PiB7XG4gICAgICAgIGRyYXdzKys7XG4gICAgICAgIHJldHVybiB2bS5uZXdTdHJpbmcoJ2Jhc2VsaW5lLXBsYWNlaG9sZGVyJyk7XG4gICAgICB9KTtcbiAgICAgIHZtLnNldFByb3Aodm0uZ2xvYmFsLCAnX19nZW5lcmF0ZU5hbm9pZCcsIG5hbm9pZEZuKTtcbiAgICAgIHVzaW5nIHVsaWRGbiA9IHZtLm5ld0Z1bmN0aW9uKCdfX2dlbmVyYXRlVWxpZCcsICgpID0+IHtcbiAgICAgICAgZHJhd3MrKztcbiAgICAgICAgcmV0dXJuIHZtLm5ld1N0cmluZygnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnKTtcbiAgICAgIH0pO1xuICAgICAgdm0uc2V0UHJvcCh2bS5nbG9iYWwsICdfX2dlbmVyYXRlVWxpZCcsIHVsaWRGbik7XG4gICAgfVxuXG4gICAgLy8gU2VyZGUgY2FwdHVyZSByb290IOKAlCBjcmVhdGVkIEJFRk9SRSB0aGUgYnVuZGxlIGV2YWx1YXRlcywgZXhhY3RseVxuICAgIC8vIGxpa2UgdGhlIGZyZXNoIHBhdGgncyBjYXB0dXJlLiBJdHMgYm94IHBvaW50ZXIgcmlkZXMgdGhlXG4gICAgLy8gQmFzZWxpbmVFbnRyeSBhbmQgZWFjaCByZXN0b3JlZCBWTSByZS1hZG9wdHMgaXQsIHNvIHNlcmRlXG4gICAgLy8gaW5pdGlhbGl6YXRpb24gbmV2ZXIgZXhlY3V0ZXMgZ3Vlc3QgY29kZSBhZnRlciB1c2VyIGNvZGUgaGFzIHJ1bi5cbiAgICAvLyBUaGlzIGlzIHdoYXQgbWFrZXMgbW9kdWxlLXNjb3BlIGludHJpbnNpYyBwYXRjaGluZyAocG9seWZpbGxzLFxuICAgIC8vIHN0YXRlZnVsIHdyYXBwZXJzIGFyb3VuZCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yLCDigKYpXG4gICAgLy8gSEFSTUxFU1Mgb24gdGhlIHNuYXBzaG90IHBhdGggcmF0aGVyIHRoYW4gbWVyZWx5IGRldGVjdGFibGU6IHRoZVxuICAgIC8vIHNlcmRlIHVzZXMgdGhlIHByaXN0aW5lIHByZS1ldmFsIGNhcHR1cmVzIG9uIGJvdGggcGF0aHMsIGFuZCBub1xuICAgIC8vIHBvc3QtZXZhbCBwcm9iZSBleGlzdHMgd2hvc2Ugc2lkZSBlZmZlY3RzIGNvdWxkIGJha2UgaW50byB0aGVcbiAgICAvLyBzbmFwc2hvdC4gVGhlIGhhbmRsZSBpcyBkZWxpYmVyYXRlbHkgTk9UIGRpc3Bvc2VkIGJlZm9yZSB0aGVcbiAgICAvLyBzbmFwc2hvdCDigJQgdGhlIGJveCBtdXN0IHN0YXkgbGl2ZSBpbiB0aGUgbWVtb3J5IGltYWdlICh0aGVcbiAgICAvLyBiYXNlbGluZSBWTSdzIGRpc3Bvc2UgYmVsb3cgdGVhcnMgZG93biB0aGUgd2hvbGUgaW5zdGFuY2Ugd2l0aG91dFxuICAgIC8vIGZyZWVpbmcgaW5kaXZpZHVhbCBib3hlcykuXG4gICAgY29uc3Qgc2VyZGVSb290ID0gY2FwdHVyZVNlcmRlUm9vdCh2bSk7XG5cbiAgICBjbG9ja1JlYWRzID0gMDsgLy8gb25seSBjb3VudCByZWFkcyBtYWRlIGJ5IHRoZSBidW5kbGUgaXRzZWxmXG4gICAgdHJ5IHtcbiAgICAgIC8vIFdvcmtmbG93LWluZGVwZW5kZW50IGZpbGVuYW1lIOKAlCBzZWUgQkFTRUxJTkVfQlVORExFX0ZJTEVOQU1FLlxuICAgICAgdm0uZXZhbENvZGUod29ya2Zsb3dDb2RlLCBCQVNFTElORV9CVU5ETEVfRklMRU5BTUUpLmRpc3Bvc2UoKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIExldCB0aGUgZnJlc2ggcGF0aCByZS1ldmFsdWF0ZSBhbmQgc3VyZmFjZSB0aGUgcmVhbCBlcnJvciB3aXRoXG4gICAgICAvLyBwcm9wZXIgZmlsZW5hbWUgLyBzb3VyY2UtbWFwIGhhbmRsaW5nLlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3RhdGU6ICdpbmVsaWdpYmxlJyxcbiAgICAgICAgcmVhc29uOiAnbW9kdWxlIHNjb3BlIHRocmV3IGR1cmluZyBoeWRyYXRlJyxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKGRyYXdzID4gMCB8fCBjbG9ja1JlYWRzID4gMCkge1xuICAgICAgcnVudGltZUxvZ2dlci5pbmZvKFxuICAgICAgICAnUXVpY2tKUyBiYXNlbGluZSBzbmFwc2hvdCBkaXNhYmxlZCBmb3IgdGhpcyBidW5kbGU6IG1vZHVsZSBzY29wZSBjb25zdW1lZCBub25kZXRlcm1pbmlzdGljIGlucHV0czsgZXZlcnkgaW52b2NhdGlvbiB3aWxsIGV2YWx1YXRlIHRoZSBidW5kbGUgZnJlc2gnLFxuICAgICAgICB7IHdvcmtmbG93SWQsIGRyYXdzLCBjbG9ja1JlYWRzIH1cbiAgICAgICk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdGF0ZTogJ2luZWxpZ2libGUnLFxuICAgICAgICByZWFzb246IGBtb2R1bGUgc2NvcGUgY29uc3VtZWQgJHtkcmF3c30gUFJORyBkcmF3KHMpIGFuZCAke2Nsb2NrUmVhZHN9IGNsb2NrIHJlYWQocylgLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBzbmFwc2hvdCA9IHZtLnNuYXBzaG90KCk7XG4gICAgcnVudGltZUxvZ2dlci5kZWJ1ZygnUXVpY2tKUyBiYXNlbGluZSBzbmFwc2hvdCBwcmVwYXJlZCcsIHtcbiAgICAgIHdvcmtmbG93SWQsXG4gICAgICBoeWRyYXRlTXM6IERhdGUubm93KCkgLSBoeWRyYXRlU3RhcnQsXG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXRlOiAncmVhZHknLFxuICAgICAgc25hcHNob3QsXG4gICAgICBzZXJkZVJvb3RQdHI6IGV4cG9ydFNlcmRlUm9vdCh2bSwgc2VyZGVSb290KSxcbiAgICB9O1xuICB9IGZpbmFsbHkge1xuICAgIHZtLmRpc3Bvc2UoKTtcbiAgfVxufVxuXG4vKipcbiAqIENhY2hlZCBiYXNlbGluZSBlbnRyeSBmb3IgYSBidW5kbGUsIHByZXBhcmluZyBpdCBvbiBmaXJzdCBhY2Nlc3MuXG4gKiBDb25jdXJyZW50IGZpcnN0IGludm9jYXRpb25zIHNoYXJlIG9uZSBoeWRyYXRlIHZpYSB0aGUgY2FjaGVkIHByb21pc2U7XG4gKiBhIGh5ZHJhdGUgdGhhdCBSRUpFQ1RTIChpbmZyYXN0cnVjdHVyZSBmYWlsdXJlLCBub3QgYnVuZGxlIGV2YWwg4oCUIHRoYXRcbiAqIHJldHVybnMgYGluZWxpZ2libGVgKSBpcyBldmljdGVkIHNvIGEgbGF0ZXIgaW52b2NhdGlvbiBjYW4gcmV0cnkuXG4gKi9cbmZ1bmN0aW9uIGdldEJhc2VsaW5lRW50cnkoXG4gIHdvcmtmbG93Q29kZTogc3RyaW5nLFxuICB3b3JrZmxvd0lkOiBzdHJpbmdcbik6IFByb21pc2U8QmFzZWxpbmVFbnRyeT4ge1xuICBsZXQgZW50cnkgPSBiYXNlbGluZUNhY2hlLmdldCh3b3JrZmxvd0NvZGUpO1xuICBpZiAoIWVudHJ5KSB7XG4gICAgaWYgKGJhc2VsaW5lQ2FjaGUuc2l6ZSA+PSBCQVNFTElORV9DQUNIRV9NQVhfRU5UUklFUykge1xuICAgICAgY29uc3Qgb2xkZXN0ID0gYmFzZWxpbmVDYWNoZS5rZXlzKCkubmV4dCgpLnZhbHVlO1xuICAgICAgaWYgKG9sZGVzdCAhPT0gdW5kZWZpbmVkKSBiYXNlbGluZUNhY2hlLmRlbGV0ZShvbGRlc3QpO1xuICAgIH1cbiAgICBlbnRyeSA9IHByZXBhcmVCYXNlbGluZVNuYXBzaG90KHdvcmtmbG93Q29kZSwgd29ya2Zsb3dJZCk7XG4gICAgYmFzZWxpbmVDYWNoZS5zZXQod29ya2Zsb3dDb2RlLCBlbnRyeSk7XG4gICAgZW50cnkuY2F0Y2goKCkgPT4gYmFzZWxpbmVDYWNoZS5kZWxldGUod29ya2Zsb3dDb2RlKSk7XG4gIH1cbiAgcmV0dXJuIGVudHJ5O1xufVxuXG4vKipcbiAqIEEgbGl2ZSBRdWlja0pTIHdvcmtmbG93IGludm9jYXRpb24uIFdoZW4gdGhlIGluaXRpYWwgYHJlc3VsdGAgaXNcbiAqIGBzdXNwZW5kZWRgLCB0aGUgVk0gaXMga2VwdCBhbGl2ZSBzbyB0aGUgY2FsbGVyIGNhbiBmZWVkIG5ld2x5IHJlY29yZGVkXG4gKiBldmVudHMgKGUuZy4gdGVybWluYWwgZXZlbnRzIG9mIGlubGluZS1leGVjdXRlZCBzdGVwcykgaW50byB0aGUgU0FNRSBWTVxuICogdmlhIGBjb250aW51ZVdpdGhFdmVudHNgIOKAlCByZXN1bWluZyBleGVjdXRpb24gZXhhY3RseSB3aGVyZSBpdCBsZWZ0IG9mZlxuICogd2l0aG91dCBhIGZyZXNoLVZNIHJlLXJlcGxheS4gVGVybWluYWwgcmVzdWx0cyBkaXNwb3NlIHRoZSBWTVxuICogYXV0b21hdGljYWxseTsgYGRpc3Bvc2UoKWAgbXVzdCBiZSBjYWxsZWQgd2hlbiBhYmFuZG9uaW5nIGEgc3VzcGVuZGVkXG4gKiBzZXNzaW9uIChpZGVtcG90ZW50KS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdWlja0pTV29ya2Zsb3dTZXNzaW9uIHtcbiAgcmVzdWx0OiBRdWlja0pTUnVudGltZVJlc3VsdDtcbiAgLyoqXG4gICAqIFByb2Nlc3MgbmV3bHkgcmVjb3JkZWQgZXZlbnRzIGluIHRoZSBsaXZlIFZNIGFuZCByZS1ldmFsdWF0ZSB0aGVcbiAgICogd29ya2Zsb3cgc3RhdGUuIE9ubHkgdmFsaWQgd2hpbGUgdGhlIGxhc3QgcmVzdWx0IHdhcyBgc3VzcGVuZGVkYC5cbiAgICogUmVzZXRzIHRoZSBWTSdzIGludGVycnVwdCBidWRnZXQgZm9yIHRoZSBuZXcgZXhlY3V0aW9uIGJ1cnN0LlxuICAgKi9cbiAgY29udGludWVXaXRoRXZlbnRzKG5ld0V2ZW50czogRXZlbnRbXSk6IFByb21pc2U8UXVpY2tKU1J1bnRpbWVSZXN1bHQ+O1xuICAvKiogRGlzcG9zZSB0aGUgVk0gaWYgaXQgaXMgc3RpbGwgYWxpdmUuIFNhZmUgdG8gY2FsbCBtdWx0aXBsZSB0aW1lcy4gKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xufVxuXG4vKipcbiAqIFJ1biBhIHdvcmtmbG93IGludm9jYXRpb24gdG8gaXRzIGZpcnN0IHNldHRsZWQgc3RhdGUgYW5kIGRpc3Bvc2UgdGhlXG4gKiBWTS4gQ29udmVuaWVuY2Ugd3JhcHBlciBvdmVyIHtAbGluayBzdGFydFF1aWNrSlNXb3JrZmxvd30gZm9yIGNhbGxlcnNcbiAqIChhbmQgdGVzdHMpIHRoYXQgZG9uJ3QgdXNlIGxpdmUtVk0gY29udGludWF0aW9uLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuUXVpY2tKU1dvcmtmbG93KFxuICBvcHRpb25zOiBRdWlja0pTUnVudGltZU9wdGlvbnNcbik6IFByb21pc2U8UXVpY2tKU1J1bnRpbWVSZXN1bHQ+IHtcbiAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHN0YXJ0UXVpY2tKU1dvcmtmbG93KG9wdGlvbnMpO1xuICBzZXNzaW9uLmRpc3Bvc2UoKTtcbiAgcmV0dXJuIHNlc3Npb24ucmVzdWx0O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRRdWlja0pTV29ya2Zsb3coXG4gIG9wdGlvbnM6IFF1aWNrSlNSdW50aW1lT3B0aW9uc1xuKTogUHJvbWlzZTxRdWlja0pTV29ya2Zsb3dTZXNzaW9uPiB7XG4gIGNvbnN0IHsgd29ya2Zsb3dDb2RlLCB3b3JrZmxvd0lkLCB3b3JrZmxvd1J1biwgZXZlbnRzIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IHN0YXJ0ZWRBdCA9IHdvcmtmbG93UnVuLnN0YXJ0ZWRBdCA/ICt3b3JrZmxvd1J1bi5zdGFydGVkQXQgOiBEYXRlLm5vdygpO1xuXG4gIC8vIERldGVybWluaXN0aWMgUFJORyBzZWVkIOKAlCBpZGVudGljYWwgZm9yIEVWRVJZIGludm9jYXRpb24gb2YgdGhlIHNhbWVcbiAgLy8gcnVuLiBGdWxsIGV2ZW50IHJlcGxheSByZXF1aXJlcyB0aGlzOiBlYWNoIGludm9jYXRpb24gcmUtZXhlY3V0ZXMgdGhlXG4gIC8vIHdvcmtmbG93IGZyb20gdGhlIHRvcCBhbmQgbXVzdCByZWdlbmVyYXRlIHRoZSBleGFjdCBzYW1lIGNvcnJlbGF0aW9uSWRcbiAgLy8gc2VxdWVuY2Ugc28gdGhhdCBwZW5kaW5nIG9wZXJhdGlvbnMgcmUtY3JlYXRlZCBieSByZXBsYXkgbWF0Y2ggdGhlXG4gIC8vIGV2ZW50cyByZWNvcmRlZCBieSBlYXJsaWVyIGludm9jYXRpb25zLiBTZXF1ZW50aWFsIG9wZXJhdGlvbnMgd2l0aGluXG4gIC8vIG9uZSBleGVjdXRpb24gc3RpbGwgZ2V0IGRpc3RpbmN0IGlkcyBiZWNhdXNlIHRoZSBQUk5HIGFkdmFuY2VzIGFzIHRoZVxuICAvLyB3b3JrZmxvdyBkcmF3cyBmcm9tIGl0LiBJZGVudGljYWwgc2VlZGluZyBhY3Jvc3MgQ09OQ1VSUkVOVCBpbnZvY2F0aW9uc1xuICAvLyBvZiB0aGUgc2FtZSBydW4gaXMgYWxzbyBsb2FkLWJlYXJpbmc6IGJvdGggcHJvZHVjZSB0aGUgc2FtZSBpZHMsIGFuZFxuICAvLyB0aGUgd29ybGQncyBwZXItKHJ1bklkLCBjb3JyZWxhdGlvbklkKSB1bmlxdWVuZXNzIHR1cm5zIHRoZSBkdXBsaWNhdGVcbiAgLy8gYGV2ZW50cy5jcmVhdGVgIGludG8gYW4gRW50aXR5Q29uZmxpY3RFcnJvciB0aGF0IHRoZSBlbnRyeXBvaW50XG4gIC8vIHN3YWxsb3dzLlxuICAvL1xuICAvLyBUaGUgc2VlZCBpbnB1dHMgTVVTVCBiZSBzdGFibGUgYWNyb3NzIGludm9jYXRpb25zLiBOb3RhYmx5XG4gIC8vIGBzdGFydGVkQXRgIGlzIE5PVDogdW5kZXIgdHVyYm8gdGhlIGZpcnN0IGludm9jYXRpb24gcnVucyBhZ2FpbnN0IGFcbiAgLy8gc3ludGhlc2l6ZWQgcnVuIG9iamVjdCB3aG9zZSB0aW1lc3RhbXBzIGRpZmZlciBmcm9tIHRoZSBkdXJhYmx5XG4gIC8vIHN0b3JlZCBvbmVzIHRoYXQgbGF0ZXIgaW52b2NhdGlvbnMgbG9hZC4gTWF0Y2hlcyB0aGUgbm9kZTp2bVxuICAvLyBlbmdpbmUncyBzZWVkICh3b3JrZmxvdy50cykuXG4gIGNvbnN0IHNlZWQgPSBbXG4gICAgd29ya2Zsb3dSdW4ucnVuSWQsXG4gICAgd29ya2Zsb3dSdW4ud29ya2Zsb3dOYW1lLFxuICAgIHdvcmtmbG93UnVuLmRlcGxveW1lbnRJZCxcbiAgXS5qb2luKCc6Jyk7XG4gIGNvbnN0IHJuZyA9IHNlZWRyYW5kb20oc2VlZCk7XG5cbiAgLy8gU2VlZGVkIG5hbm9pZCBnZW5lcmF0b3Ig4oCUIHVzZXMgdGhlIHNhbWUgbmFub2lkIHBhY2thZ2UgYW5kIHNlZWRlZCBQUk5HXG4gIC8vIGFzIHRoZSBub2RlOnZtIGVuZ2luZSBmb3IgY29uc2lzdGVudCB0b2tlbiBnZW5lcmF0aW9uLlxuICBjb25zdCBnZW5lcmF0ZU5hbm9pZCA9IG5hbm9pZC5jdXN0b21SYW5kb20obmFub2lkLnVybEFscGhhYmV0LCAyMSwgKHNpemUpID0+XG4gICAgbmV3IFVpbnQ4QXJyYXkoc2l6ZSkubWFwKCgpID0+IDI1NiAqIHJuZygpKVxuICApO1xuXG4gIC8vIERldGVybWluaXN0aWMgcmVwbGF5IGNsb2NrLCBtaXJyb3JpbmcgdGhlIG5vZGU6dm0gZW5naW5lIChzZWVcbiAgLy8gd29ya2Zsb3cudHMpOiB0aGUgaW5pdGlhbCB2YWx1ZSBpcyB0aGUgcnVuJ3MgY3JlYXRpb24gdGltZSByZWNvdmVyZWRcbiAgLy8gZnJvbSB0aGUgVUxJRCBlbWJlZGRlZCBpbiBgcnVuSWRgIChmYWxsaW5nIGJhY2sgdG8gYGNyZWF0ZWRBdGApLCBhbmRcbiAgLy8gaXQgYWR2YW5jZXMgdG8gZWFjaCBwcm9jZXNzZWQgZXZlbnQncyBgY3JlYXRlZEF0YCBhcyB0aGUgZXZlbnQgbG9nIGlzXG4gIC8vIHJlcGxheWVkLiBNb25vdG9uaWMgKE1hdGgubWF4KSBzbyB0aGUgb3V0ZXIgcHJvY2Vzc0V2ZW50cyByZS1zY2FuXG4gIC8vIGxvb3AgY2FuJ3QgbW92ZSB0aGUgY2xvY2sgYmFja3dhcmRzIG1pZC1leGVjdXRpb24uXG4gIGxldCB2bU5vd01zID1cbiAgICBydW5JZENyZWF0ZWRBdCh3b3JrZmxvd1J1bi5ydW5JZCkgPz8gKCt3b3JrZmxvd1J1bi5jcmVhdGVkQXQgfHwgc3RhcnRlZEF0KTtcbiAgY29uc3QgYWR2YW5jZUNsb2NrID0gKG1zOiBudW1iZXIpID0+IHtcbiAgICBpZiAoTnVtYmVyLmlzRmluaXRlKG1zKSkgdm1Ob3dNcyA9IE1hdGgubWF4KHZtTm93TXMsIG1zKTtcbiAgfTtcblxuICAvLyAtLS0tIFBoYXNlIDE6IHN0YXRpYyBpbml0aWFsaXphdGlvbiAtLS0tXG4gIC8vXG4gIC8vIEJhc2VsaW5lLXNuYXBzaG90IGZhc3QgcGF0aCAoZGVmYXVsdCBPTjsgc2VlIHRoZSBzZWN0aW9uIGNvbW1lbnQgYXRcbiAgLy8gcHJlcGFyZUJhc2VsaW5lU25hcHNob3QpOiByZXN0b3JlIGEgYnVuZGxlLWh5ZHJhdGVkIFZNIGluc3RlYWQgb2ZcbiAgLy8gYm9vdGluZyBmcmVzaCBhbmQgcmUtZXZhbHVhdGluZyB0aGUgYnVuZGxlLiBgaW5lbGlnaWJsZWAgYnVuZGxlc1xuICAvLyAobW9kdWxlLXNjb3BlIG5vbmRldGVybWluaXNtLCBldmFsIGZhaWx1cmUpIHRha2UgdGhlIGZyZXNoIHBhdGggd2l0aFxuICAvLyBpZGVudGljYWwgc2VtYW50aWNzLlxuICBjb25zdCBpbnRlcnJ1cHRCdWRnZXQ6IEludGVycnVwdEJ1ZGdldCA9IHsgc3RhcnQ6IERhdGUubm93KCkgfTtcbiAgbGV0IGJhc2VsaW5lU25hcHNob3Q6IFNuYXBzaG90IHwgdW5kZWZpbmVkO1xuICBsZXQgYmFzZWxpbmVTZXJkZVJvb3RQdHI6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgaWYgKGlzUXVpY2tKU0Jhc2VsaW5lU25hcHNob3RFbmFibGVkKCkpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZW50cnkgPSBhd2FpdCBnZXRCYXNlbGluZUVudHJ5KHdvcmtmbG93Q29kZSwgd29ya2Zsb3dJZCk7XG4gICAgICBpZiAoZW50cnkuc3RhdGUgPT09ICdyZWFkeScpIHtcbiAgICAgICAgYmFzZWxpbmVTbmFwc2hvdCA9IGVudHJ5LnNuYXBzaG90O1xuICAgICAgICBiYXNlbGluZVNlcmRlUm9vdFB0ciA9IGVudHJ5LnNlcmRlUm9vdFB0cjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIC8vIEEgcmVqZWN0aW9uIGhlcmUgaXMgYW4gaW5mcmFzdHJ1Y3R1cmUgZmFpbHVyZSBkdXJpbmcgaHlkcmF0ZVxuICAgICAgLy8gKGUuZy4gdm0uc25hcHNob3QoKSB1bmRlciBtZW1vcnkgcHJlc3N1cmUsIFF1aWNrSlMuY3JlYXRlIG9yXG4gICAgICAvLyBnZXRDb21waWxlZEFzc2V0cygpIGZhaWxpbmcpIOKAlCBOT1QgYnVuZGxlIGV2YWwsIHdoaWNoIHJldHVybnNcbiAgICAgIC8vIGFuIGluZWxpZ2libGUgZW50cnkuIGdldEJhc2VsaW5lRW50cnkgaGFzIGFscmVhZHkgZXZpY3RlZCB0aGVcbiAgICAgIC8vIGNhY2hlZCBwcm9taXNlIHNvIGEgbGF0ZXIgaW52b2NhdGlvbiBjYW4gcmV0cnkuIFRoaXMgaW52b2NhdGlvblxuICAgICAgLy8gbXVzdCBmYWxsIGJhY2sgdG8gZnJlc2ggZXZhbHVhdGlvbiAod2hpY2ggd291bGQgaGF2ZSBzdWNjZWVkZWQpXG4gICAgICAvLyByYXRoZXIgdGhhbiBmYWlsIHRoZSB3aG9sZSBydW4gZm9yIGEgc25hcHNob3Qtb25seSBmYWlsdXJlIG1vZGUuXG4gICAgICBydW50aW1lTG9nZ2VyLndhcm4oXG4gICAgICAgICdRdWlja0pTIGJhc2VsaW5lIHNuYXBzaG90IGh5ZHJhdGUgZmFpbGVkOyBmYWxsaW5nIGJhY2sgdG8gZnJlc2ggZXZhbHVhdGlvbiBmb3IgdGhpcyBpbnZvY2F0aW9uJyxcbiAgICAgICAgeyB3b3JrZmxvd0lkLCBlcnJvcjogZXJyIH1cbiAgICAgICk7XG4gICAgfVxuICB9XG4gIGxldCB2bTogUXVpY2tKUztcbiAgaWYgKGJhc2VsaW5lU25hcHNob3QpIHtcbiAgICBjb25zdCBhc3NldHMgPSBhd2FpdCBnZXRDb21waWxlZEFzc2V0cygpO1xuICAgIHZtID0gYXdhaXQgUXVpY2tKUy5yZXN0b3JlKGJhc2VsaW5lU25hcHNob3QsIHtcbiAgICAgIHdhc206IGFzc2V0cy53YXNtIGFzIG5ldmVyLFxuICAgICAgbWVtb3J5TGltaXQ6IDI1NiAqIDEwMjQgKiAxMDI0LFxuICAgICAgaW50ZXJydXB0SGFuZGxlcjogY3JlYXRlSW50ZXJydXB0SGFuZGxlcihpbnRlcnJ1cHRCdWRnZXQpLFxuICAgICAgZXh0ZW5zaW9uczogYXNzZXRzLmV4dGVuc2lvbnMsXG4gICAgICB3YXNpOiBtYWtlRGV0ZXJtaW5pc3RpY0Nsb2NrV2FzaSgoKSA9PiB2bU5vd01zKSxcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB2bSA9IGF3YWl0IGluaXRXb3JrZmxvd1ZNKCgpID0+IHZtTm93TXMsIGludGVycnVwdEJ1ZGdldCk7XG4gIH1cblxuICAvLyBIb3N0LXNpZGUgc2VyZGU6IGNhcHR1cmVzIHRoZSBWTSdzIGludHJpbnNpY3MgKGJvb3RzdHJhcCBpbmNsdWRlZClcbiAgLy8gYmVmb3JlIGFueSB1c2VyIGNvZGUgcnVucy4gQWxsIHNlcmlhbGl6YXRpb24gbm93IGhhcHBlbnMgb24gdGhlIGhvc3RcbiAgLy8gdGhyb3VnaCBoYW5kbGVzIOKAlCBubyBzZXJpYWxpemVyIGNvZGUgaXMgZXZhbHVhdGVkIGluc2lkZSB0aGUgVk0uXG4gIC8vIEZyZXNoIHBhdGg6IGNhcHR1cmUgbm93IChubyB1c2VyIGNvZGUgaGFzIHJ1biDigJQgdGhlIGJ1bmRsZSBldmFsdWF0ZXNcbiAgLy8gbGF0ZXIgaW4gdGhlIHBlci1ydW4gcGhhc2UpLiBTbmFwc2hvdCBwYXRoOiByZS1hZG9wdCB0aGUgY2FwdHVyZSByb290XG4gIC8vIHRoZSBiYXNlbGluZSBoeWRyYXRlIGNyZWF0ZWQgQkVGT1JFIHRoZSBidW5kbGUgZXZhbHVhdGVkIOKAlCB0aGUgYm94XG4gIC8vIGxpdmVzIGluIHRoZSByZXN0b3JlZCBtZW1vcnkgaW1hZ2UgYXQgdGhlIHJlY29yZGVkIG9mZnNldC4gQm90aCBnaXZlXG4gIC8vIHRoZSBzZXJkZSBwcmlzdGluZSBjYXB0dXJlLWJlZm9yZS11c2VyLWNvZGUgaW50cmluc2ljczsgbmVpdGhlclxuICAvLyBleGVjdXRlcyBndWVzdCBjb2RlIGhlcmUuXG4gIGNvbnN0IHNlcmRlID1cbiAgICBiYXNlbGluZVNuYXBzaG90ICYmIGJhc2VsaW5lU2VyZGVSb290UHRyICE9PSB1bmRlZmluZWRcbiAgICAgID8gY3JlYXRlUXVpY2tKU1NlcmRlKHZtLCBhZG9wdFNlcmRlUm9vdCh2bSwgYmFzZWxpbmVTZXJkZVJvb3RQdHIpKVxuICAgICAgOiBjcmVhdGVRdWlja0pTU2VyZGUodm0pO1xuXG4gIC8vIEFueSB0aHJvdyBiZXR3ZWVuIGhlcmUgYW5kIHRoZSB0ZXJtaW5hbCBwYXRocyAod2hpY2ggZGlzcG9zZSB0aGUgVk1cbiAgLy8gaW5zaWRlIGNoZWNrV29ya2Zsb3dTdGF0ZSAvIGV4dHJhY3RFcnJvciBiZWZvcmUgUkVUVVJOSU5HKSB3b3VsZCBsZWFrXG4gIC8vIGEgbGl2ZSBRdWlja0pTIGluc3RhbmNlIGFuZCBpdHMgV0FTTSBsaW5lYXIgbWVtb3J5IGZvciB0aGUgbGlmZXRpbWVcbiAgLy8gb2YgdGhlIGNvbXB1dGUgaW5zdGFuY2Ug4oCUIHdoaWNoIGlzIHJldXNlZC4gRGlzcG9zZSBvbiB0aGUgd2F5IG91dCBvZlxuICAvLyBhbiBleGNlcHRpb25hbCBleGl0IGFuZCByZXRocm93LlxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBydW5Xb3JrZmxvd0luVk0oKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZtLmRpc3Bvc2UoKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIEFscmVhZHkgZGlzcG9zZWQgYnkgYSB0ZXJtaW5hbCBwYXRoIOKAlCBpZ25vcmUuXG4gICAgfVxuICAgIHRocm93IGVycjtcbiAgfVxuXG4gIC8vIC0tLS0gUGhhc2UgMjogcGVyLXJ1biBpbml0aWFsaXphdGlvbiAtLS0tXG4gIGFzeW5jIGZ1bmN0aW9uIHJ1bldvcmtmbG93SW5WTSgpOiBQcm9taXNlPFF1aWNrSlNXb3JrZmxvd1Nlc3Npb24+IHtcbiAgICB2bS5ldmFsQ29kZShcbiAgICAgIGBnbG9iYWxUaGlzLl9fd29ybGRDYXBhYmlsaXRpZXMgPSAke0pTT04uc3RyaW5naWZ5KG9wdGlvbnMud29ybGRDYXBhYmlsaXRpZXMpfTtgXG4gICAgKS5kaXNwb3NlKCk7XG5cbiAgICAvLyBTZWVkZWQgTWF0aC5yYW5kb21cbiAgICB7XG4gICAgICB1c2luZyByYW5kb21GbiA9IHZtLm5ld0Z1bmN0aW9uKCdyYW5kb20nLCAoKSA9PiB2bS5uZXdOdW1iZXIocm5nKCkpKTtcbiAgICAgIHVzaW5nIG1hdGggPSB2bS5nbG9iYWwuZ2V0UHJvcCgnTWF0aCcpO1xuICAgICAgbWF0aC5zZXRQcm9wKCdyYW5kb20nLCByYW5kb21Gbik7XG4gICAgfVxuXG4gICAgLy8gU2VlZGVkIG5hbm9pZCBnZW5lcmF0b3JcbiAgICB7XG4gICAgICB1c2luZyBuYW5vaWRGbiA9IHZtLm5ld0Z1bmN0aW9uKCdfX2dlbmVyYXRlTmFub2lkJywgKCkgPT5cbiAgICAgICAgdm0ubmV3U3RyaW5nKGdlbmVyYXRlTmFub2lkKCkpXG4gICAgICApO1xuICAgICAgdm0uc2V0UHJvcCh2bS5nbG9iYWwsICdfX2dlbmVyYXRlTmFub2lkJywgbmFub2lkRm4pO1xuICAgIH1cblxuICAgIC8vIEhvc3Qtc2lkZSBkZXRlcm1pbmlzdGljIFVMSUQgZ2VuZXJhdG9yIGZvciBjb3JyZWxhdGlvbklkcy4gVXNlcyB0aGVcbiAgICAvLyBzYW1lIGB1bGlkYCBwYWNrYWdlIGFuZCBtb25vdG9uaWMgZmFjdG9yeSBhcyBiZWZvcmUsIGRyYXdpbmcgZnJvbVxuICAgIC8vIHRoZSBTQU1FIHNlZWRlZCBQUk5HIGluc3RhbmNlIGFzIHRoZSBWTSdzIE1hdGgucmFuZG9tIOKAlCBzbyB0aGVcbiAgICAvLyBpbnRlcmxlYXZlZCBkcmF3IHNlcXVlbmNlIChhbmQgdGhlcmVmb3JlIGV2ZXJ5IGNvcnJlbGF0aW9uSWQpIGlzXG4gICAgLy8gYnl0ZS1pZGVudGljYWwgdG8gd2hhdCB0aGUgcHJldmlvdXMgaW4tVk0gVUxJRCBmYWN0b3J5IHByb2R1Y2VkIGZvclxuICAgIC8vIHRoZSBzYW1lIHJ1bi4gVGhlIHRpbWUgcHJlZml4IGlzIGRlcml2ZWQgZnJvbSB0aGUgcnVuSWQncyBlbWJlZGRlZFxuICAgIC8vIFVMSUQgKHN0YWJsZSBhY3Jvc3MgaW52b2NhdGlvbnMgYnkgY29uc3RydWN0aW9uIOKAlCB1bmxpa2VcbiAgICAvLyBgc3RhcnRlZEF0YCwgd2hpY2ggZGlmZmVycyBiZXR3ZWVuIHR1cmJvJ3Mgc3ludGhlc2l6ZWQgcnVuIG9iamVjdFxuICAgIC8vIGFuZCB0aGUgZHVyYWJseSBzdG9yZWQgcnVuKSwgc28gdHdvIGNvbmN1cnJlbnQgaW52b2NhdGlvbnMgb2YgdGhlXG4gICAgLy8gc2FtZSBydW4gcHJvZHVjZSBJREVOVElDQUwgY29ycmVsYXRpb25JZHMgYW5kIHRoZSB3b3JsZCdzXG4gICAgLy8gRW50aXR5Q29uZmxpY3RFcnJvciBvbiBgZXZlbnRzLmNyZWF0ZWAgZGVkdXBzIG9uZSBvZiBlYWNoIHBhaXIuXG4gICAge1xuICAgICAgY29uc3QgdWxpZEZhY3RvcnkgPSBtb25vdG9uaWNGYWN0b3J5KCgpID0+IHJuZygpKTtcbiAgICAgIGNvbnN0IHVsaWRUaW1lc3RhbXAgPVxuICAgICAgICBydW5JZENyZWF0ZWRBdCh3b3JrZmxvd1J1bi5ydW5JZCkgPz9cbiAgICAgICAgKCt3b3JrZmxvd1J1bi5jcmVhdGVkQXQgfHwgc3RhcnRlZEF0KTtcbiAgICAgIHVzaW5nIHVsaWRGbiA9IHZtLm5ld0Z1bmN0aW9uKCdfX2dlbmVyYXRlVWxpZCcsICgpID0+XG4gICAgICAgIHZtLm5ld1N0cmluZyh1bGlkRmFjdG9yeSh1bGlkVGltZXN0YW1wKSlcbiAgICAgICk7XG4gICAgICB2bS5zZXRQcm9wKHZtLmdsb2JhbCwgJ19fZ2VuZXJhdGVVbGlkJywgdWxpZEZuKTtcbiAgICB9XG5cbiAgICAvLyBgcHJvY2Vzcy5lbnZgIOKAlCBwYXJpdHkgd2l0aCB0aGUgbm9kZTp2bSBlbmdpbmUsIHdoaWNoIGV4cG9zZXMgYSBmcm96ZW5cbiAgICAvLyBjb3B5IG9mIHRoZSBob3N0IGVudiAodm0vaW5kZXgudHMpLiBJbmplY3RlZCBwZXIgcnVuIHNvIHRoZSBzbmFwc2hvdCBvZlxuICAgIC8vIHRoZSBlbnYgaXMgdGFrZW4gYXQgaW52b2NhdGlvbiB0aW1lLCBzYW1lIGFzIG5vZGUuIEhhbmRsZS1iYXNlZCAobm9cbiAgICAvLyBndWVzdCBzb3VyY2UgZXZhbHVhdGVkKTogb24gdGhlIGJhc2VsaW5lLXNuYXBzaG90IHBhdGggdGhpcyBydW5zXG4gICAgLy8gYWZ0ZXIgdXNlciBjb2RlLCBhbmQgYSBndWVzdC1zb3VyY2UgaW5qZWN0aW9uIHdvdWxkIGV4ZWN1dGUgdGhyb3VnaFxuICAgIC8vIHBvdGVudGlhbGx5IHBhdGNoZWQgZ2xvYmFscyAoSlNPTi5wYXJzZSwgT2JqZWN0LmZyZWV6ZSkg4oCUIHZpc2libGVcbiAgICAvLyB0byBtb2R1bGUtc2NvcGUgd3JhcHBlcnMgb25seSBvbiB0aGUgcmVzdG9yZSBwYXRoLCBkaXZlcmdpbmdcbiAgICAvLyByZXBsYXlzLlxuICAgIHNlcmRlLmluc3RhbGxQcm9jZXNzRW52KHByb2Nlc3MuZW52KTtcblxuICAgIC8vIEV4ZWN1dGUgdGhlIHdvcmtmbG93IGJ1bmRsZSDigJQgdXNlIHRoZSB3b3JrZmxvd0lkIGFzIHRoZSBldmFsIGZpbGVuYW1lXG4gICAgLy8gc28gUXVpY2tKUyBzdGFjayB0cmFjZXMgcmVmZXJlbmNlIHRoZSB3b3JrZmxvdyBuYW1lLCBlbmFibGluZyBzb3VyY2UgbWFwXG4gICAgLy8gcmVtYXBwaW5nIGJ5IHJlbWFwRXJyb3JTdGFjayAod2hpY2ggbWF0Y2hlcyBmcmFtZXMgYnkgZmlsZW5hbWUpLlxuICAgIC8vIEV2YWx1YXRlZCBpbiB0aGUgcGVyLXJ1biBwaGFzZSAoYWZ0ZXIgTWF0aC5yYW5kb20gc2VlZGluZykgc28gdGhhdFxuICAgIC8vIG1vZHVsZS1zY29wZSB1c2VyIGNvZGUgZHJhd3MgZnJvbSB0aGUgc2VlZGVkIFBSTkcsIG1hdGNoaW5nIHRoZVxuICAgIC8vIG5vZGU6dm0gZW5naW5lJ3MgcmVwbGF5IGRldGVybWluaXNtLiBTa2lwcGVkIG9uIHRoZVxuICAgIC8vIGJhc2VsaW5lLXNuYXBzaG90IHBhdGg6IHRoZSByZXN0b3JlZCBoZWFwIGFscmVhZHkgY2FycmllcyB0aGVcbiAgICAvLyBldmFsdWF0ZWQgYnVuZGxlLCBhbmQgdGhlIGJhc2VsaW5lIGdhdGUgZ3VhcmFudGVlcyBtb2R1bGUgc2NvcGVcbiAgICAvLyBjb25zdW1lZCBubyBQUk5HIGRyYXdzIG9yIGNsb2NrIHJlYWRzIOKAlCBzbyBza2lwcGluZyB0aGUgZXZhbCBpc1xuICAgIC8vIG9ic2VydmF0aW9uYWxseSBpZGVudGljYWwgdG8gcmUtcnVubmluZyBpdCAodGhlIHJ1bi1zZWVkZWQgaG9zdFxuICAgIC8vIGZucyByZWdpc3RlcmVkIGFib3ZlIHJlYmluZCB0aGUgU0FNRSBuYW1lcyB0aGUgcmVzdG9yZWQgaGVhcCdzXG4gICAgLy8gZnVuY3Rpb24gb2JqZWN0cyBkaXNwYXRjaCB0aHJvdWdoKS5cbiAgICBpZiAoIWJhc2VsaW5lU25hcHNob3QpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZtLmV2YWxDb2RlKHdvcmtmbG93Q29kZSwgd29ya2Zsb3dJZCB8fCAnd29ya2Zsb3cuanMnKS5kaXNwb3NlKCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIG1ha2VTZXR0bGVkU2Vzc2lvbihcbiAgICAgICAgICBleHRyYWN0RXJyb3Iodm0sIGVyciwgJ1dvcmtmbG93IGV2YWx1YXRpb24gZmFpbGVkJylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFeHRyYWN0IHdvcmtmbG93IGFyZ3VtZW50cy4gUHJlZmVyIHRoZSBydW5fY3JlYXRlZCBldmVudDsgZmFsbCBiYWNrXG4gICAgLy8gdG8gdGhlIHF1ZXVlIG1lc3NhZ2UncyBydW5JbnB1dCBpZiB0aGUgZXZlbnQgbG9nIGlzIGluY29tcGxldGVcbiAgICAvLyAoZXZlbnR1YWxseS1jb25zaXN0ZW50IHJlYWQgYWZ0ZXIgc3RhcnQoKSkuIEZhaWxpbmcgdG8gZmluZCBpbnB1dFxuICAgIC8vIGZvciBhIGZpcnN0IGludm9jYXRpb24gaXMgZmF0YWwg4oCUIHJ1bm5pbmcgdGhlIHdvcmtmbG93IGZ1bmN0aW9uXG4gICAgLy8gd2l0aCBubyBhcmdzIHdvdWxkIHNpbGVudGx5IHR1cm4gdHlwZWQgYXJndW1lbnRzIGludG8gYHVuZGVmaW5lZGBcbiAgICAvLyBhbmQsIGZvciByZWN1cnNpdmUgd29ya2Zsb3dzLCBwcm9kdWNlIGV4cG9uZW50aWFsIGZhbi1vdXQuXG4gICAgY29uc3QgcnVuQ3JlYXRlZEV2ZW50ID0gZXZlbnRzLmZpbmQoKGUpID0+IGUuZXZlbnRUeXBlID09PSAncnVuX2NyZWF0ZWQnKTtcbiAgICBjb25zdCBydW5DcmVhdGVkSW5wdXQgPVxuICAgICAgcnVuQ3JlYXRlZEV2ZW50ICYmICdldmVudERhdGEnIGluIHJ1bkNyZWF0ZWRFdmVudFxuICAgICAgICA/IChydW5DcmVhdGVkRXZlbnQuZXZlbnREYXRhIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KT8uaW5wdXRcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcnVuSW5wdXQ6IHVua25vd24gPVxuICAgICAgcnVuQ3JlYXRlZElucHV0ID8/IChvcHRpb25zLnJ1bklucHV0Py5pbnB1dCBhcyB1bmtub3duKTtcblxuICAgIGlmIChydW5JbnB1dCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgIGNvbnN0IGRlY3J5cHRlZElucHV0ID0gYXdhaXQgcHJlcGFyZUJ5dGVzRm9yVk0oXG4gICAgICAgIHJ1bklucHV0LFxuICAgICAgICBvcHRpb25zLmVuY3J5cHRpb25LZXlcbiAgICAgICk7XG4gICAgICBydW50aW1lTG9nZ2VyLmRlYnVnKCdRdWlja0pTIHJ1bnRpbWU6IHJ1biBpbnB1dCBmb3JtYXQnLCB7XG4gICAgICAgIHByZWZpeDogbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGRlY3J5cHRlZElucHV0LnN1YmFycmF5KDAsIDQpKSxcbiAgICAgICAgYnl0ZUxlbmd0aDogZGVjcnlwdGVkSW5wdXQuYnl0ZUxlbmd0aCxcbiAgICAgICAgc291cmNlOiBydW5DcmVhdGVkSW5wdXQgPyAncnVuX2NyZWF0ZWQnIDogJ3F1ZXVlTWVzc2FnZS5ydW5JbnB1dCcsXG4gICAgICB9KTtcbiAgICAgIC8vIEJ1aWxkIHRoZSBhcmd1bWVudCB2YWx1ZSBkaXJlY3RseSBpbiB0aGUgVk0gdmlhIHRoZSBob3N0LXNpZGVcbiAgICAgIC8vIHNlcmRlIChndWVzdCBjb2RlIG5ldmVyIHNlZXMgdGhlIHdpcmUgYnl0ZXMpLlxuICAgICAgY29uc3QgaW5wdXRIYW5kbGUgPSBzZXJkZS5kZXNlcmlhbGl6ZShkZWNyeXB0ZWRJbnB1dCk7XG4gICAgICB2bS5zZXRQcm9wKHZtLmdsb2JhbCwgJ19fd2RrX2lucHV0JywgaW5wdXRIYW5kbGUpO1xuICAgICAgaW5wdXRIYW5kbGUuZGlzcG9zZSgpO1xuICAgIH0gZWxzZSBpZiAocnVuSW5wdXQgPT09IHVuZGVmaW5lZCAmJiBldmVudHMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gVGhlIGV2ZW50IGxvZyBpcyBub24tZW1wdHkgKHdlIGdvdCBydW5fc3RhcnRlZCBvciBzaW1pbGFyKSBidXRcbiAgICAgIC8vIG5vIHJ1bl9jcmVhdGVkIGV2ZW50IHdhcyBmb3VuZCBhbmQgbm8gcXVldWUtcHJvdmlkZWQgcnVuSW5wdXQgaXNcbiAgICAgIC8vIGF2YWlsYWJsZS4gVGhpcyBpcyB0aGUgcmFjZSBjb25kaXRpb24gb2JzZXJ2ZWQgZHVyaW5nIHRoZSBmaWJcbiAgICAgIC8vIGluY2lkZW50IOKAlCBzaWxlbnRseSBkcm9wcGluZyBhcmd1bWVudHMgd291bGQgdHVybiBgbmAgaW50b1xuICAgICAgLy8gYHVuZGVmaW5lZGAgYW5kLCBmb3IgcmVjdXJzaXZlIHdvcmtmbG93cywgY2F1c2UgZXhwb25lbnRpYWxcbiAgICAgIC8vIGZhbi1vdXQuIEZhaWwgbG91ZDogdGhlIHRocm93IGVzY2FwZXMgdGhlIGVudHJ5cG9pbnQgaW50byB0aGVcbiAgICAgIC8vIHJlcGxheSBsb29wJ3MgY2F0Y2ggaW4gcnVudGltZS50cyAodGhlIFF1aWNrSlMgZGlzcGF0Y2ggcnVuc1xuICAgICAgLy8gaW5zaWRlIHRoYXQgbG9vcCdzIHRyeSksIHdoaWNoIHJlY29yZHMgcnVuX2ZhaWxlZC4gQSB2aXNpYmxlXG4gICAgICAvLyB0ZXJtaW5hbCBmYWlsdXJlIGlzXG4gICAgICAvLyBwcmVmZXJyZWQgb3ZlciBzaWxlbnRseSBleGVjdXRpbmcgd2l0aCB1bmRlZmluZWQgYXJndW1lbnRzIOKAlCB0aGVcbiAgICAgIC8vIHF1ZXVlLXByb3ZpZGVkIHJ1bklucHV0IGZhbGxiYWNrIGFib3ZlIG1ha2VzIHRoaXMgcGF0aCByYXJlLlxuICAgICAgLy8gRW1wdHkgYGV2ZW50c2AgaXMgYWxsb3dlZCBiZWNhdXNlIHRlc3RzIHRoYXQgYm9vdHN0cmFwIGEgd29ya2Zsb3dcbiAgICAgIC8vIHdpdGggbm8gYXJndW1lbnRzIHJlbHkgb24gdGhlIG9sZCBwZXJtaXNzaXZlIGJlaGF2aW9yLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQ2Fubm90IHN0YXJ0IHdvcmtmbG93IHJ1biBcIiR7d29ya2Zsb3dSdW4ucnVuSWR9XCI6IG5vIHJ1bl9jcmVhdGVkIGV2ZW50IGZvdW5kIGFuZCBubyBydW5JbnB1dCBpbiB0aGUgcXVldWUgcGF5bG9hZCwgYnV0IG90aGVyIGV2ZW50cyBhcmUgcHJlc2VudCAobGlrZWx5IGEgcmVhZC1hZnRlci13cml0ZSByYWNlIGR1cmluZyBzdGFydCgpKS5gXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFNldCB3b3JrZmxvdyBjb250ZXh0IG1ldGFkYXRhIChmb3IgZ2V0V29ya2Zsb3dNZXRhZGF0YSgpKS5cbiAgICAvLyBNdXN0IG1hdGNoIHRoZSBzaGFwZSB0aGF0IHRoZSBub2RlOnZtIGVuZ2luZSBwcm9kdWNlcyAoc2VlXG4gICAgLy8gcGFja2FnZXMvY29yZS9zcmMvd29ya2Zsb3cudHM6IHJ1bldvcmtmbG93IOKGkiBjdHgpIHNvIHVzZXIgY29kZVxuICAgIC8vIHRoYXQgY29tcGFyZXMgYGdldFdvcmtmbG93TWV0YWRhdGEoKWAgdmFsdWVzIGJldHdlZW4gYSBzdGVwXG4gICAgLy8gKHNlcnZlci1zaWRlKSBhbmQgdGhlIHdvcmtmbG93IChWTS1zaWRlKSBzZWVzIGlkZW50aWNhbCBvYmplY3RzLlxuICAgIHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0ge1xuICAgICAgICB3b3JrZmxvd05hbWU6IHdvcmtmbG93UnVuLndvcmtmbG93TmFtZSxcbiAgICAgICAgd29ya2Zsb3dSdW5JZDogd29ya2Zsb3dSdW4ucnVuSWQsXG4gICAgICAgIHdvcmtmbG93U3RhcnRlZEF0OiB3b3JrZmxvd1J1bi5zdGFydGVkQXRcbiAgICAgICAgICA/IG5ldyBEYXRlKCt3b3JrZmxvd1J1bi5zdGFydGVkQXQpXG4gICAgICAgICAgOiBuZXcgRGF0ZSgpLFxuICAgICAgICB1cmw6IHByb2Nlc3MuZW52LlZFUkNFTF9VUkxcbiAgICAgICAgICA/IGBodHRwczovLyR7cHJvY2Vzcy5lbnYuVkVSQ0VMX1VSTH1gXG4gICAgICAgICAgOiBgaHR0cDovL2xvY2FsaG9zdDoke29wdGlvbnMucG9ydCA/PyAzMDAwfWAsXG4gICAgICAgIGZlYXR1cmVzOiB7IGVuY3J5cHRpb246ICEhb3B0aW9ucy5lbmNyeXB0aW9uS2V5IH0sXG4gICAgICB9O1xuICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgIGBnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19DT05URVhUXCIpXSA9ICR7SlNPTi5zdHJpbmdpZnkobWV0YWRhdGEpfTtgICtcbiAgICAgICAgICBgZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiV09SS0ZMT1dfQ09OVEVYVFwiKV0ud29ya2Zsb3dTdGFydGVkQXQgPSBuZXcgRGF0ZSgke0pTT04uc3RyaW5naWZ5KG1ldGFkYXRhLndvcmtmbG93U3RhcnRlZEF0LnRvSVNPU3RyaW5nKCkpfSk7YFxuICAgICAgKS5kaXNwb3NlKCk7XG4gICAgfVxuXG4gICAgLy8gU3RhcnQgdGhlIHdvcmtmbG93IGZ1bmN0aW9uLiBJZiB0aGUgd29ya2Zsb3cgaXNuJ3QgcmVnaXN0ZXJlZCxcbiAgICAvLyB0aHJvdyBhbiBlcnJvciB0YWdnZWQgd2l0aCBgbmFtZSA9IFwiV29ya2Zsb3dOb3RSZWdpc3RlcmVkRXJyb3JcImBcbiAgICAvLyBzbyB0aGUgaG9zdC1zaWRlIGVudHJ5cG9pbnQgY2FuIHJlY29uc3RydWN0IGEgcmVhbFxuICAgIC8vIFdvcmtmbG93Tm90UmVnaXN0ZXJlZEVycm9yIChhIFdvcmtmbG93UnVudGltZUVycm9yIHN1YmNsYXNzIHRoYXRcbiAgICAvLyBjbGFzc2lmaWVzIGFzIFJVTlRJTUVfRVJST1IpIHJhdGhlciB0aGFuIGEgZ2VuZXJpYyB1c2VyIGVycm9yLlxuICAgIC8vIFNlZSBxdWlja2pzLWVudHJ5cG9pbnQudHMncyBydW5fZmFpbGVkIGJyYW5jaC5cbiAgICB0cnkge1xuICAgICAgdm0uZXZhbENvZGUoYFxuICAgICAgdmFyIF9fd2ZuID0gZ2xvYmFsVGhpcy5fX3ByaXZhdGVfd29ya2Zsb3dzLmdldCgke0pTT04uc3RyaW5naWZ5KHdvcmtmbG93SWQpfSk7XG4gICAgICBpZiAoIV9fd2ZuKSB7XG4gICAgICAgIHZhciBfX3dmbkVyciA9IG5ldyBFcnJvcihcIldvcmtmbG93IFxcXFxcIlwiICsgJHtKU09OLnN0cmluZ2lmeSh3b3JrZmxvd0lkKX0gKyBcIlxcXFxcIiBpcyBub3QgcmVnaXN0ZXJlZCBpbiB0aGUgY3VycmVudCBkZXBsb3ltZW50LlwiKTtcbiAgICAgICAgX193Zm5FcnIubmFtZSA9IFwiV29ya2Zsb3dOb3RSZWdpc3RlcmVkRXJyb3JcIjtcbiAgICAgICAgdGhyb3cgX193Zm5FcnI7XG4gICAgICB9XG4gICAgICB2YXIgX19hcmdzID0gZ2xvYmFsVGhpcy5fX3dka19pbnB1dCAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gZ2xvYmFsVGhpcy5fX3dka19pbnB1dFxuICAgICAgICA6IFtdO1xuICAgICAgZGVsZXRlIGdsb2JhbFRoaXMuX193ZGtfaW5wdXQ7XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoX19hcmdzKSkgX19hcmdzID0gW19fYXJnc107XG4gICAgICBfX3dmbi5hcHBseShudWxsLCBfX2FyZ3MpLnRoZW4oXG4gICAgICAgIGZ1bmN0aW9uKHJlc3VsdCkge1xuICAgICAgICAgIC8vIFN0b3JlIHRoZSBSQVcgcmVzdWx0OyB0aGUgaG9zdCBzZXJpYWxpemVzIGl0IHRocm91Z2ggYSBoYW5kbGUuXG4gICAgICAgICAgLy8gQSBzZXBhcmF0ZSBkb25lIGZsYWcgZGlzdGluZ3Vpc2hlcyBcImNvbXBsZXRlZCB3aXRoIHVuZGVmaW5lZFwiXG4gICAgICAgICAgLy8gZnJvbSBcIm5vdCBjb21wbGV0ZWRcIi5cbiAgICAgICAgICBnbG9iYWxUaGlzLl9fd29ya2Zsb3dEb25lID0gdHJ1ZTtcbiAgICAgICAgICBnbG9iYWxUaGlzLl9fd29ya2Zsb3dSZXN1bHQgPSByZXN1bHQ7XG4gICAgICAgIH0sXG4gICAgICAgIGZ1bmN0aW9uKGVycm9yKSB7XG4gICAgICAgICAgLy8gUHJlc2VydmUgZGlzcGxheSBpbmZvIG9uIHRoZSBob3N0LXNpZGUgZmFpbGVkIG9iamVjdFxuICAgICAgICAgIC8vIChtYXRjaGVzIHRoZSBsZWdhY3kgaG9zdC12aXNpYmxlIHNoYXBlKSBBTkQga2VlcCB0aGUgUkFXXG4gICAgICAgICAgLy8gdGhyb3duIHZhbHVlIHNvIHRoZSBob3N0IGNhbiBzZXJpYWxpemUgdGhlIG9yaWdpbmFsXG4gICAgICAgICAgLy8gdHlwZS1pZGVudGl0eSwgY2F1c2UgY2hhaW4sIG9yIG5vbi1FcnJvciB0aHJvd3MgdmVyYmF0aW1cbiAgICAgICAgICAvLyB0aHJvdWdoIHRoZSBzdGFuZGFyZCBlcnJvciBwaXBlbGluZS5cbiAgICAgICAgICBnbG9iYWxUaGlzLl9fd29ya2Zsb3dFcnJvciA9IHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yICYmIGVycm9yLm1lc3NhZ2UgIT0gbnVsbCA/IFN0cmluZyhlcnJvci5tZXNzYWdlKSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgICBzdGFjazogZXJyb3IgJiYgZXJyb3Iuc3RhY2sgPyBlcnJvci5zdGFjayA6IFwiXCIsXG4gICAgICAgICAgICBuYW1lOiBlcnJvciAmJiBlcnJvci5uYW1lID8gZXJyb3IubmFtZSA6IChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gXCJFcnJvclwiIDogdHlwZW9mIGVycm9yKSxcbiAgICAgICAgICAgIHZhbHVlOiBlcnJvcixcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICApO1xuICAgIGApLmRpc3Bvc2UoKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiBtYWtlU2V0dGxlZFNlc3Npb24oXG4gICAgICAgIGV4dHJhY3RFcnJvcih2bSwgZXJyLCAnRmFpbGVkIHRvIHN0YXJ0IHdvcmtmbG93JylcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gUHJvY2VzcyBldmVudHMgYW5kIGRyYWluIGpvYnMgaW4gYSBsb29wLiBFdmVudHMgbWF5IHJlc29sdmUgcHJvbWlzZXNcbiAgICAvLyB0aGF0IHVuYmxvY2sgd29ya2Zsb3cgY29kZSwgd2hpY2ggdGhlbiBjcmVhdGVzIE5FVyByZXNvbHZlcnMgZm9yXG4gICAgLy8gc3Vic2VxdWVudCBldmVudHMuIFJlLXByb2Nlc3NpbmcgZXZlbnRzIG1hdGNoZXMgdGhlc2UgbmV3IHJlc29sdmVyc1xuICAgIC8vIGFnYWluc3QgZXZlbnRzIHRoYXQgd2VyZSBhbHJlYWR5IGRlbGl2ZXJlZC5cbiAgICB7XG4gICAgICBsZXQgbWF4SXRlcmF0aW9ucyA9IDEwMDtcbiAgICAgIGxldCBtYWRlUHJvZ3Jlc3M6IGJvb2xlYW47XG4gICAgICBkbyB7XG4gICAgICAgIG1hZGVQcm9ncmVzcyA9IGF3YWl0IHByb2Nlc3NFdmVudHMoXG4gICAgICAgICAgdm0sXG4gICAgICAgICAgc2VyZGUsXG4gICAgICAgICAgZXZlbnRzLFxuICAgICAgICAgIGFkdmFuY2VDbG9jayxcbiAgICAgICAgICBvcHRpb25zLmVuY3J5cHRpb25LZXlcbiAgICAgICAgKTtcbiAgICAgICAgbGV0IGJhdGNoOiBudW1iZXI7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICBiYXRjaCA9IHZtLmV4ZWN1dGVQZW5kaW5nSm9icygpO1xuICAgICAgICAgIGlmIChiYXRjaCA+IDApIG1hZGVQcm9ncmVzcyA9IHRydWU7XG4gICAgICAgIH0gd2hpbGUgKGJhdGNoID4gMCk7XG4gICAgICB9IHdoaWxlIChtYWRlUHJvZ3Jlc3MgJiYgLS1tYXhJdGVyYXRpb25zID4gMCk7XG4gICAgICBpZiAobWFkZVByb2dyZXNzICYmIG1heEl0ZXJhdGlvbnMgPT09IDApIHtcbiAgICAgICAgLy8gVGhlIGRyYWluIGxvb3AgaGl0IGl0cyBib3VuZCB3aGlsZSBzdGlsbCBtYWtpbmcgcHJvZ3Jlc3Mg4oCUXG4gICAgICAgIC8vIHByb2NlZWRpbmcgYXMgaWYgaXQgY29udmVyZ2VkIHdvdWxkIHByZXNlbnQgYXMgYSBteXN0ZXJpb3VzXG4gICAgICAgIC8vIHN1c3BlbnNpb24gb3IgcmVwbGF5IGRpdmVyZ2VuY2UuIE1ha2UgdGhlIGdpdmluZy11cCB2aXNpYmxlIHNvXG4gICAgICAgIC8vIGEgd2VkZ2UgaXMgYXR0cmlidXRhYmxlIHRvIHRoaXMgYm91bmQgcmF0aGVyIHRoYW4gYSBteXN0ZXJ5LlxuICAgICAgICBydW50aW1lTG9nZ2VyLndhcm4oXG4gICAgICAgICAgJ1F1aWNrSlMgcnVudGltZTogZXZlbnQgZHJhaW4gbG9vcCBoaXQgaXRzIGl0ZXJhdGlvbiBib3VuZCBiZWZvcmUgcmVhY2hpbmcgYSBmaXhlZCBwb2ludCcsXG4gICAgICAgICAge1xuICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogd29ya2Zsb3dSdW4ucnVuSWQsXG4gICAgICAgICAgICBldmVudENvdW50OiBldmVudHMubGVuZ3RoLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAtLS0tIENoZWNrIHJlc3VsdCAtLS0tXG4gICAgcmV0dXJuIG1ha2VMaXZlU2Vzc2lvbihcbiAgICAgIHZtLFxuICAgICAgc2VyZGUsXG4gICAgICBpbnRlcnJ1cHRCdWRnZXQsXG4gICAgICBhZHZhbmNlQ2xvY2ssXG4gICAgICBvcHRpb25zLmVuY3J5cHRpb25LZXlcbiAgICApO1xuICB9XG59XG5cbi8qKiBTZXNzaW9uIHdyYXBwZXIgZm9yIGEgcmVzdWx0IHdob3NlIFZNIGlzIGFscmVhZHkgc2V0dGxlZC9kaXNwb3NlZC4gKi9cbmZ1bmN0aW9uIG1ha2VTZXR0bGVkU2Vzc2lvbihcbiAgcmVzdWx0OiBRdWlja0pTUnVudGltZVJlc3VsdFxuKTogUXVpY2tKU1dvcmtmbG93U2Vzc2lvbiB7XG4gIHJldHVybiB7XG4gICAgcmVzdWx0LFxuICAgIGNvbnRpbnVlV2l0aEV2ZW50czogKCkgPT4ge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnUXVpY2tKUyB3b3JrZmxvdyBzZXNzaW9uIGlzIHNldHRsZWQg4oCUIGNvbnRpbnVlV2l0aEV2ZW50cyBpcyBvbmx5IHZhbGlkIHdoaWxlIHN1c3BlbmRlZCdcbiAgICAgICk7XG4gICAgfSxcbiAgICBkaXNwb3NlOiAoKSA9PiB7fSxcbiAgfTtcbn1cblxuLyoqXG4gKiBFdmFsdWF0ZSB0aGUgVk0ncyBzdGF0ZSBhbmQgd3JhcCBpdCBpbiBhIGxpdmUgc2Vzc2lvbi4gV2hpbGUgc3VzcGVuZGVkLFxuICogdGhlIFZNIHN0YXlzIGFsaXZlIHNvIGBjb250aW51ZVdpdGhFdmVudHNgIGNhbiByZXN1bWUgaXQgaW4gcGxhY2U7XG4gKiB0ZXJtaW5hbCBzdGF0ZXMgZGlzcG9zZSB0aGUgVk0gaW1tZWRpYXRlbHkgKGluc2lkZSBjaGVja1dvcmtmbG93U3RhdGUpLlxuICovXG5mdW5jdGlvbiBtYWtlTGl2ZVNlc3Npb24oXG4gIHZtOiBRdWlja0pTLFxuICBzZXJkZTogUXVpY2tKU1NlcmRlLFxuICBpbnRlcnJ1cHRCdWRnZXQ6IEludGVycnVwdEJ1ZGdldCxcbiAgYWR2YW5jZUNsb2NrOiAobXM6IG51bWJlcikgPT4gdm9pZCxcbiAgZW5jcnlwdGlvbktleT86IERlY3J5cHRpb25LZXlcbik6IFF1aWNrSlNXb3JrZmxvd1Nlc3Npb24ge1xuICBjb25zdCByZXN1bHQgPSBjaGVja1dvcmtmbG93U3RhdGUodm0sIHNlcmRlLCB7IGtlZXBBbGl2ZU9uU3VzcGVuZDogdHJ1ZSB9KTtcbiAgbGV0IGFsaXZlID0gISFyZXN1bHQuc3VzcGVuZGVkO1xuXG4gIGNvbnN0IHNlc3Npb246IFF1aWNrSlNXb3JrZmxvd1Nlc3Npb24gPSB7XG4gICAgcmVzdWx0LFxuICAgIGFzeW5jIGNvbnRpbnVlV2l0aEV2ZW50cyhcbiAgICAgIG5ld0V2ZW50czogRXZlbnRbXVxuICAgICk6IFByb21pc2U8UXVpY2tKU1J1bnRpbWVSZXN1bHQ+IHtcbiAgICAgIGlmICghYWxpdmUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdRdWlja0pTIHdvcmtmbG93IHNlc3Npb24gaXMgbm90IGFsaXZlIOKAlCBjb250aW51ZVdpdGhFdmVudHMgaXMgb25seSB2YWxpZCB3aGlsZSBzdXNwZW5kZWQnXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICAvLyBGcmVzaCBleGVjdXRpb24gYnVyc3Qg4oCUIHRoZSBpbnRlcnJ1cHQgYnVkZ2V0IGJvdW5kcyBWTSBjb21wdXRlLFxuICAgICAgLy8gbm90IHdhbGwgdGltZSBzcGVudCB3YWl0aW5nIG9uIGlubGluZSBzdGVwcyBiZXR3ZWVuIGJ1cnN0cy5cbiAgICAgIGludGVycnVwdEJ1ZGdldC5zdGFydCA9IERhdGUubm93KCk7XG5cbiAgICAgIGxldCBtYXhJdGVyYXRpb25zID0gMTAwO1xuICAgICAgbGV0IG1hZGVQcm9ncmVzczogYm9vbGVhbjtcbiAgICAgIGRvIHtcbiAgICAgICAgbWFkZVByb2dyZXNzID0gYXdhaXQgcHJvY2Vzc0V2ZW50cyhcbiAgICAgICAgICB2bSxcbiAgICAgICAgICBzZXJkZSxcbiAgICAgICAgICBuZXdFdmVudHMsXG4gICAgICAgICAgYWR2YW5jZUNsb2NrLFxuICAgICAgICAgIGVuY3J5cHRpb25LZXlcbiAgICAgICAgKTtcbiAgICAgICAgbGV0IGJhdGNoOiBudW1iZXI7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICBiYXRjaCA9IHZtLmV4ZWN1dGVQZW5kaW5nSm9icygpO1xuICAgICAgICAgIGlmIChiYXRjaCA+IDApIG1hZGVQcm9ncmVzcyA9IHRydWU7XG4gICAgICAgIH0gd2hpbGUgKGJhdGNoID4gMCk7XG4gICAgICB9IHdoaWxlIChtYWRlUHJvZ3Jlc3MgJiYgLS1tYXhJdGVyYXRpb25zID4gMCk7XG5cbiAgICAgIGNvbnN0IG5leHQgPSBjaGVja1dvcmtmbG93U3RhdGUodm0sIHNlcmRlLCB7XG4gICAgICAgIGtlZXBBbGl2ZU9uU3VzcGVuZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgaWYgKCFuZXh0LnN1c3BlbmRlZCkgYWxpdmUgPSBmYWxzZTtcbiAgICAgIHNlc3Npb24ucmVzdWx0ID0gbmV4dDtcbiAgICAgIHJldHVybiBuZXh0O1xuICAgIH0sXG4gICAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgIGlmIChhbGl2ZSkge1xuICAgICAgICBhbGl2ZSA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHZtLmRpc3Bvc2UoKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgLy8gQWxyZWFkeSBkaXNwb3NlZCDigJQgaWdub3JlLlxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbiAgcmV0dXJuIHNlc3Npb247XG59XG5cbi8vIC0tLS0gRXZlbnQgUHJvY2Vzc2luZyAtLS0tXG5cbmFzeW5jIGZ1bmN0aW9uIHByb2Nlc3NFdmVudHMoXG4gIHZtOiBRdWlja0pTLFxuICBzZXJkZTogUXVpY2tKU1NlcmRlLFxuICBldmVudHM6IEV2ZW50W10sXG4gIGFkdmFuY2VDbG9jazogKG1zOiBudW1iZXIpID0+IHZvaWQsXG4gIGVuY3J5cHRpb25LZXk/OiBEZWNyeXB0aW9uS2V5XG4pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgbGV0IHJlc29sdmVkID0gZmFsc2U7XG4gIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgLy8gQWR2YW5jZSB0aGUgVk0ncyBkZXRlcm1pbmlzdGljIGNsb2NrIHRvIHRoaXMgZXZlbnQncyBjcmVhdGlvbiB0aW1lXG4gICAgLy8gQkVGT1JFIHJlc29sdmluZyBhbnl0aGluZywgc28gd29ya2Zsb3cgY29kZSB1bmJsb2NrZWQgYnkgdGhpcyBldmVudFxuICAgIC8vIG9ic2VydmVzIERhdGUubm93KCkgYXQgKG9yIGFmdGVyIOKAlCB0aGUgY2xvY2sgaXMgbW9ub3RvbmljKSB0aGUgdGltZVxuICAgIC8vIHRoZSBldmVudCB3YXMgcmVjb3JkZWQuIE1pcnJvcnMgdGhlIG5vZGU6dm0gZW5naW5lJ3NcbiAgICAvLyBgb25Db25zdW1lZEV2ZW50IOKGkiB1cGRhdGVUaW1lc3RhbXAoK2V2ZW50LmNyZWF0ZWRBdClgLlxuICAgIGFkdmFuY2VDbG9jaygrZXZlbnQuY3JlYXRlZEF0KTtcblxuICAgIGNvbnN0IGNpZCA9IGV2ZW50LmNvcnJlbGF0aW9uSWQ7XG4gICAgaWYgKCFjaWQpIGNvbnRpbnVlO1xuXG4gICAgLy8gSlNPTi5zdHJpbmdpZnkgaGFuZGxlcyBxdW90ZXMsIGJhY2tzbGFzaGVzIGFuZCBjb250cm9sIGNoYXJhY3RlcnM7XG4gICAgLy8gY29ycmVsYXRpb24gaWRzIGFyZSBob3N0LWdlbmVyYXRlZCBVTElEcyB0b2RheSwgYnV0IHRoZSBldmFsLXN0cmluZ1xuICAgIC8vIHNhZmV0eSBzaG91bGRuJ3QgZGVwZW5kIG9uIHRoYXQgaW52YXJpYW50IGJlaW5nIGFzc2VydGVkIG5vd2hlcmUuXG4gICAgY29uc3QgY2lkSnMgPSBKU09OLnN0cmluZ2lmeShjaWQpO1xuICAgIGNvbnN0IGV2ZW50RGF0YSA9XG4gICAgICAnZXZlbnREYXRhJyBpbiBldmVudFxuICAgICAgICA/IChldmVudC5ldmVudERhdGEgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pXG4gICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgLy8gTG9nIHRoZSBldmVudCBhbmQgd2hldGhlciB0aGUgcmVzb2x2ZXIgZXhpc3RzXG4gICAgc3dpdGNoIChldmVudC5ldmVudFR5cGUpIHtcbiAgICAgIGNhc2UgJ3N0ZXBfY29tcGxldGVkJzoge1xuICAgICAgICBjb25zdCBoYXNSZXNvbHZlciA9IHZtLmR1bXAoXG4gICAgICAgICAgdm0uZXZhbENvZGUoYCEhZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV1gKVxuICAgICAgICApO1xuICAgICAgICBjb25zdCByYXdPdXRwdXQgPSBldmVudERhdGE/LnJlc3VsdCA/PyBldmVudERhdGE/Lm91dHB1dDtcbiAgICAgICAgaWYgKGhhc1Jlc29sdmVyKSB7XG4gICAgICAgICAgaWYgKHJhd091dHB1dCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgICAgICAgIC8vIERlY3J5cHQgaWYgZW5jcnlwdGVkIOKAlCB0aGUgVk0gb25seSB1bmRlcnN0YW5kcyAnZGV2bCcgZm9ybWF0XG4gICAgICAgICAgICBydW50aW1lTG9nZ2VyLmRlYnVnKCdRdWlja0pTIHJ1bnRpbWU6IHN0ZXAgcmVzdWx0IHJhdycsIHtcbiAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogY2lkLFxuICAgICAgICAgICAgICByYXdQcmVmaXg6IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShyYXdPdXRwdXQuc3ViYXJyYXkoMCwgNCkpLFxuICAgICAgICAgICAgICByYXdCeXRlTGVuZ3RoOiByYXdPdXRwdXQuYnl0ZUxlbmd0aCxcbiAgICAgICAgICAgICAgaXNCdWZmZXI6IEJ1ZmZlci5pc0J1ZmZlcihyYXdPdXRwdXQpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCBkZWNyeXB0ZWRPdXRwdXQgPSBhd2FpdCBwcmVwYXJlQnl0ZXNGb3JWTShcbiAgICAgICAgICAgICAgcmF3T3V0cHV0LFxuICAgICAgICAgICAgICBlbmNyeXB0aW9uS2V5XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcnVudGltZUxvZ2dlci5kZWJ1ZygnUXVpY2tKUyBydW50aW1lOiBzdGVwIHJlc3VsdCBkZWNyeXB0ZWQnLCB7XG4gICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IGNpZCxcbiAgICAgICAgICAgICAgcHJlZml4OiBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoZGVjcnlwdGVkT3V0cHV0LnN1YmFycmF5KDAsIDQpKSxcbiAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogZGVjcnlwdGVkT3V0cHV0LmJ5dGVMZW5ndGgsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlSGFuZGxlID0gc2VyZGUuZGVzZXJpYWxpemUoZGVjcnlwdGVkT3V0cHV0KTtcbiAgICAgICAgICAgIHZtLnNldFByb3Aodm0uZ2xvYmFsLCAnX190bXBfcmVzdWx0JywgdmFsdWVIYW5kbGUpO1xuICAgICAgICAgICAgdmFsdWVIYW5kbGUuZGlzcG9zZSgpO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XS5yZXNvbHZlKGdsb2JhbFRoaXMuX190bXBfcmVzdWx0KTtgICtcbiAgICAgICAgICAgICAgICBgZGVsZXRlIGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dO2AgK1xuICAgICAgICAgICAgICAgIGBkZWxldGUgZ2xvYmFsVGhpcy5fX3RtcF9yZXN1bHQ7YFxuICAgICAgICAgICAgKS5kaXNwb3NlKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuZGVidWcoJ1F1aWNrSlMgcnVudGltZTogc3RlcCByZXN1bHQgbm9uLWJpbmFyeScsIHtcbiAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogY2lkLFxuICAgICAgICAgICAgICB0eXBlOiB0eXBlb2YgcmF3T3V0cHV0LFxuICAgICAgICAgICAgICBpc051bGw6IHJhd091dHB1dCA9PT0gbnVsbCxcbiAgICAgICAgICAgICAgaXNVbmRlZmluZWQ6IHJhd091dHB1dCA9PT0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBjb25zdHJ1Y3RvcjogcmF3T3V0cHV0Py5jb25zdHJ1Y3Rvcj8ubmFtZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3Qgc2VyaWFsaXplZCA9XG4gICAgICAgICAgICAgIHJhd091dHB1dCAhPT0gdW5kZWZpbmVkID8gSlNPTi5zdHJpbmdpZnkocmF3T3V0cHV0KSA6ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XS5yZXNvbHZlKCR7c2VyaWFsaXplZH0pO2AgK1xuICAgICAgICAgICAgICAgIGBkZWxldGUgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV07YFxuICAgICAgICAgICAgKS5kaXNwb3NlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIERyYWluIEFMTCBtaWNyb3Rhc2tzIGFmdGVyIHJlc29sdmVcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBsZXQgYjogbnVtYmVyO1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICBiID0gdm0uZXhlY3V0ZVBlbmRpbmdKb2JzKCk7XG4gICAgICAgICAgICB9IHdoaWxlIChiID4gMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5vIHJlc29sdmVyIHlldCDigJQgYnVmZmVyIHRoZSBwcmVwYXJlZCBvdXRjb21lIHNvIHRoZSBwcm9taXNlXG4gICAgICAgICAgLy8gc2V0dGxlcyB0aGUgbW9tZW50IHRoZSBWTSBjb25zdHJ1Y3RzIGl0IChzZWUgX190ZXJtaW5hbEJ1ZmZlclxuICAgICAgICAgIC8vIGluIHRoZSBib290c3RyYXApLiBXaXRob3V0IHRoaXMsIHRoZSBsaXZlLWNvbnRpbnVhdGlvbiBwYXRoXG4gICAgICAgICAgLy8gKHdoaWNoIHNjYW5zIGVhY2ggZGVsdGEgZXhhY3RseSBvbmNlKSBkcm9wcyB0aGUgdGVybWluYWwgYW5kXG4gICAgICAgICAgLy8gdGhlIGF3YWl0IG5ldmVyIHNldHRsZXMuXG4gICAgICAgICAgaWYgKHJhd091dHB1dCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZE91dHB1dCA9IGF3YWl0IHByZXBhcmVCeXRlc0ZvclZNKFxuICAgICAgICAgICAgICByYXdPdXRwdXQsXG4gICAgICAgICAgICAgIGVuY3J5cHRpb25LZXlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICAvLyBIb3N0IHNlcmRlOiBkZXNlcmlhbGl6ZSBpbnRvIGEgVk0gdmFsdWUgTk9XIChzYW1lIHBhdGggYXNcbiAgICAgICAgICAgIC8vIHRoZSByZXNvbHZlciBicmFuY2ggYWJvdmUpIGFuZCBidWZmZXIgdGhlIHZhbHVlIGl0c2VsZi5cbiAgICAgICAgICAgIGNvbnN0IHZhbHVlSGFuZGxlID0gc2VyZGUuZGVzZXJpYWxpemUoZGVjcnlwdGVkT3V0cHV0KTtcbiAgICAgICAgICAgIHZtLnNldFByb3Aodm0uZ2xvYmFsLCAnX190bXBfYnVmJywgdmFsdWVIYW5kbGUpO1xuICAgICAgICAgICAgdmFsdWVIYW5kbGUuZGlzcG9zZSgpO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fdGVybWluYWxCdWZmZXJbJHtjaWRKc31dID0geyBraW5kOiBcInJlc29sdmVfdmFsdWVcIiwgdmFsdWU6IGdsb2JhbFRoaXMuX190bXBfYnVmIH07YCArXG4gICAgICAgICAgICAgICAgYGRlbGV0ZSBnbG9iYWxUaGlzLl9fdG1wX2J1ZjtgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc2VyaWFsaXplZCA9XG4gICAgICAgICAgICAgIHJhd091dHB1dCAhPT0gdW5kZWZpbmVkID8gSlNPTi5zdHJpbmdpZnkocmF3T3V0cHV0KSA6ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fdGVybWluYWxCdWZmZXJbJHtjaWRKc31dID0geyBraW5kOiBcInJlc29sdmVfdmFsdWVcIiwgdmFsdWU6ICR7c2VyaWFsaXplZH0gfTtgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbWFya0NyZWF0ZWQodm0sIGNpZEpzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdzdGVwX2ZhaWxlZCc6IHtcbiAgICAgICAgY29uc3QgaGFzUmVzb2x2ZXIgPSB2bS5kdW1wKFxuICAgICAgICAgIHZtLmV2YWxDb2RlKGAhIWdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dYClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGhhc1Jlc29sdmVyKSB7XG4gICAgICAgICAgY29uc3QgZXJyb3JEYXRhID0gZXZlbnREYXRhPy5lcnJvcjtcbiAgICAgICAgICBpZiAoZXJyb3JEYXRhIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgICAgICAgLy8gTW9kZXJuIHBhdGggKHBvc3QtIzE4NTEpOiB0aGUgc3RlcCBoYW5kbGVyIGRlaHlkcmF0ZWQgdGhlXG4gICAgICAgICAgICAvLyB0aHJvd24gdmFsdWUgdGhyb3VnaCB0aGUgZmlyc3QtY2xhc3MgZXJyb3IgcGlwZWxpbmUuIERlY3J5cHRcbiAgICAgICAgICAgIC8vIChpZiBlbmNyeXB0ZWQpIGFuZCBwYXNzIHRoZSBieXRlcyB0byB0aGUgVk0tc2lkZSBkZXNlcmlhbGl6ZXJcbiAgICAgICAgICAgIC8vIHNvIHRoZSB3b3JrZmxvdyBjYXRjaCBzZWVzIGEgcHJvcGVybHkgdHlwZWQgRXJyb3Igc3ViY2xhc3NcbiAgICAgICAgICAgIC8vIChUeXBlRXJyb3IsIEZhdGFsRXJyb3Igd2l0aCBvcmlnaW5hbCBjYXVzZSBjaGFpbiwgZXRjLikgd2l0aFxuICAgICAgICAgICAgLy8gdGhlIG9yaWdpbmFsIG1lc3NhZ2UgYW5kIHN0YWNrIHByZXNlcnZlZC5cbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZCA9IGF3YWl0IHByZXBhcmVCeXRlc0ZvclZNKGVycm9yRGF0YSwgZW5jcnlwdGlvbktleSk7XG4gICAgICAgICAgICBjb25zdCBlcnJvckhhbmRsZSA9IHNlcmRlLmRlc2VyaWFsaXplKGRlY3J5cHRlZCk7XG4gICAgICAgICAgICB2bS5zZXRQcm9wKHZtLmdsb2JhbCwgJ19fdG1wX2Vycm9yJywgZXJyb3JIYW5kbGUpO1xuICAgICAgICAgICAgZXJyb3JIYW5kbGUuZGlzcG9zZSgpO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGAoZnVuY3Rpb24oKXtgICtcbiAgICAgICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV0ucmVqZWN0KGdsb2JhbFRoaXMuX190bXBfZXJyb3IpO2AgK1xuICAgICAgICAgICAgICAgIGBkZWxldGUgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV07YCArXG4gICAgICAgICAgICAgICAgYGRlbGV0ZSBnbG9iYWxUaGlzLl9fdG1wX2Vycm9yO2AgK1xuICAgICAgICAgICAgICAgIGB9KSgpYFxuICAgICAgICAgICAgKS5kaXNwb3NlKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIExlZ2FjeSBwYXRoOiBwcmUtcGlwZWxpbmUgZXZlbnRzIHN0b3JlZCBlcnJvciBhc1xuICAgICAgICAgICAgLy8gYHsgbWVzc2FnZSwgc3RhY2ssIGNvZGUgfWAuIFJlY29uc3RydWN0IGEgRmF0YWxFcnJvciBzb1xuICAgICAgICAgICAgLy8gd29ya2Zsb3cgY2F0Y2ggY2FuIGRldGVjdCBpdCB2aWEgRmF0YWxFcnJvci5pcygpLCBtYXRjaGluZ1xuICAgICAgICAgICAgLy8gdGhlIG9yaWdpbmFsIFYxIHN0ZXAgaGFuZGxlciBiZWhhdmlvci5cbiAgICAgICAgICAgIGNvbnN0IGlzRXJyb3JPYmplY3QgPVxuICAgICAgICAgICAgICB0eXBlb2YgZXJyb3JEYXRhID09PSAnb2JqZWN0JyAmJiBlcnJvckRhdGEgIT09IG51bGw7XG4gICAgICAgICAgICBjb25zdCBtc2cgPSBpc0Vycm9yT2JqZWN0XG4gICAgICAgICAgICAgID8gKCgoZXJyb3JEYXRhIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5tZXNzYWdlIGFzIHN0cmluZykgPz9cbiAgICAgICAgICAgICAgICAnU3RlcCBmYWlsZWQnKVxuICAgICAgICAgICAgICA6IHR5cGVvZiBlcnJvckRhdGEgPT09ICdzdHJpbmcnXG4gICAgICAgICAgICAgICAgPyBlcnJvckRhdGFcbiAgICAgICAgICAgICAgICA6ICdTdGVwIGZhaWxlZCc7XG4gICAgICAgICAgICBjb25zdCBlcnJvclN0YWNrID1cbiAgICAgICAgICAgICAgKGlzRXJyb3JPYmplY3RcbiAgICAgICAgICAgICAgICA/IChlcnJvckRhdGEgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLnN0YWNrXG4gICAgICAgICAgICAgICAgOiB1bmRlZmluZWQpID8/IChldmVudERhdGE/LnN0YWNrIGFzIHN0cmluZyB8IHVuZGVmaW5lZCk7XG4gICAgICAgICAgICBjb25zdCBzdGFja0Fzc2lnbm1lbnQgPSBlcnJvclN0YWNrXG4gICAgICAgICAgICAgID8gYGUuc3RhY2s9JHtKU09OLnN0cmluZ2lmeShlcnJvclN0YWNrKX07YFxuICAgICAgICAgICAgICA6ICcnO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGAoZnVuY3Rpb24oKXt2YXIgZT1uZXcgRXJyb3IoJHtKU09OLnN0cmluZ2lmeShtc2cpfSk7ZS5uYW1lPVwiRmF0YWxFcnJvclwiO2UuZmF0YWw9dHJ1ZTske3N0YWNrQXNzaWdubWVudH1gICtcbiAgICAgICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV0ucmVqZWN0KGUpO2AgK1xuICAgICAgICAgICAgICAgIGBkZWxldGUgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV07fSkoKWBcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBsZXQgYjogbnVtYmVyO1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICBiID0gdm0uZXhlY3V0ZVBlbmRpbmdKb2JzKCk7XG4gICAgICAgICAgICB9IHdoaWxlIChiID4gMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5vIHJlc29sdmVyIHlldCDigJQgYnVmZmVyIHRoZSBwcmVwYXJlZCByZWplY3Rpb24gKHNlZSB0aGVcbiAgICAgICAgICAvLyBzdGVwX2NvbXBsZXRlZCBicmFuY2ggYWJvdmUgZm9yIHRoZSByYXRpb25hbGUpLlxuICAgICAgICAgIGNvbnN0IGVycm9yRGF0YSA9IGV2ZW50RGF0YT8uZXJyb3I7XG4gICAgICAgICAgaWYgKGVycm9yRGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZCA9IGF3YWl0IHByZXBhcmVCeXRlc0ZvclZNKGVycm9yRGF0YSwgZW5jcnlwdGlvbktleSk7XG4gICAgICAgICAgICAvLyBIb3N0IHNlcmRlOiBkZXNlcmlhbGl6ZSBpbnRvIHRoZSBWTSBlcnJvciB2YWx1ZSBOT1cgKHNhbWVcbiAgICAgICAgICAgIC8vIHBhdGggYXMgdGhlIHJlc29sdmVyIGJyYW5jaCBhYm92ZSkgYW5kIGJ1ZmZlciBpdC5cbiAgICAgICAgICAgIGNvbnN0IGVycm9ySGFuZGxlID0gc2VyZGUuZGVzZXJpYWxpemUoZGVjcnlwdGVkKTtcbiAgICAgICAgICAgIHZtLnNldFByb3Aodm0uZ2xvYmFsLCAnX190bXBfYnVmJywgZXJyb3JIYW5kbGUpO1xuICAgICAgICAgICAgZXJyb3JIYW5kbGUuZGlzcG9zZSgpO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fdGVybWluYWxCdWZmZXJbJHtjaWRKc31dID0geyBraW5kOiBcInJlamVjdF92YWx1ZVwiLCB2YWx1ZTogZ2xvYmFsVGhpcy5fX3RtcF9idWYgfTtgICtcbiAgICAgICAgICAgICAgICBgZGVsZXRlIGdsb2JhbFRoaXMuX190bXBfYnVmO2BcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBpc0Vycm9yT2JqZWN0ID1cbiAgICAgICAgICAgICAgdHlwZW9mIGVycm9yRGF0YSA9PT0gJ29iamVjdCcgJiYgZXJyb3JEYXRhICE9PSBudWxsO1xuICAgICAgICAgICAgY29uc3QgbXNnID0gaXNFcnJvck9iamVjdFxuICAgICAgICAgICAgICA/ICgoKGVycm9yRGF0YSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikubWVzc2FnZSBhcyBzdHJpbmcpID8/XG4gICAgICAgICAgICAgICAgJ1N0ZXAgZmFpbGVkJylcbiAgICAgICAgICAgICAgOiB0eXBlb2YgZXJyb3JEYXRhID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgID8gZXJyb3JEYXRhXG4gICAgICAgICAgICAgICAgOiAnU3RlcCBmYWlsZWQnO1xuICAgICAgICAgICAgY29uc3QgZXJyb3JTdGFjayA9XG4gICAgICAgICAgICAgIChpc0Vycm9yT2JqZWN0XG4gICAgICAgICAgICAgICAgPyAoZXJyb3JEYXRhIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5zdGFja1xuICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkKSA/PyAoZXZlbnREYXRhPy5zdGFjayBhcyBzdHJpbmcgfCB1bmRlZmluZWQpO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fdGVybWluYWxCdWZmZXJbJHtjaWRKc31dID0geyBraW5kOiBcInJlamVjdF9lcnJvclwiLCBtZXNzYWdlOiAke0pTT04uc3RyaW5naWZ5KG1zZyl9LCBzdGFjazogJHtlcnJvclN0YWNrID8gSlNPTi5zdHJpbmdpZnkoZXJyb3JTdGFjaykgOiAndW5kZWZpbmVkJ30gfTtgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbWFya0NyZWF0ZWQodm0sIGNpZEpzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICd3YWl0X2NvbXBsZXRlZCc6IHtcbiAgICAgICAgY29uc3QgaGFzUmVzb2x2ZXIgPSB2bS5kdW1wKFxuICAgICAgICAgIHZtLmV2YWxDb2RlKGAhIWdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dYClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGhhc1Jlc29sdmVyKSB7XG4gICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV0ucmVzb2x2ZSgpO2AgK1xuICAgICAgICAgICAgICBgZGVsZXRlIGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dO2BcbiAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBsZXQgYjogbnVtYmVyO1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICBiID0gdm0uZXhlY3V0ZVBlbmRpbmdKb2JzKCk7XG4gICAgICAgICAgICB9IHdoaWxlIChiID4gMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5vIHJlc29sdmVyIHlldCDigJQgYnVmZmVyIChzZWUgc3RlcF9jb21wbGV0ZWQgYWJvdmUpLlxuICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgYGdsb2JhbFRoaXMuX190ZXJtaW5hbEJ1ZmZlclske2NpZEpzfV0gPSB7IGtpbmQ6IFwicmVzb2x2ZV91bmRlZmluZWRcIiB9O2BcbiAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgfVxuICAgICAgICBtYXJrQ3JlYXRlZCh2bSwgY2lkSnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2F0dHJfc2V0Jzoge1xuICAgICAgICAvLyBPbmx5IHdvcmtmbG93LXdyaXR0ZW4gYXR0cmlidXRlIGV2ZW50cyByZXNvbHZlIGEgcGVuZGluZ1xuICAgICAgICAvLyBzZXRBdHRyaWJ1dGVzKCkgcHJvbWlzZTsgc3RlcC9zeXN0ZW0gd3JpdGVycyBzaGFyZSBub1xuICAgICAgICAvLyBjb3JyZWxhdGlvbklkcyB3aXRoIFZNIHJlc29sdmVycywgc28gdGhlIGd1YXJkIGlzIGRlZmVuc2l2ZS5cbiAgICAgICAgY29uc3Qgd3JpdGVyID0gKGV2ZW50RGF0YT8ud3JpdGVyIGFzIHsgdHlwZT86IHN0cmluZyB9IHwgdW5kZWZpbmVkKVxuICAgICAgICAgID8udHlwZTtcbiAgICAgICAgaWYgKHdyaXRlciAhPT0gJ3dvcmtmbG93JykgYnJlYWs7XG4gICAgICAgIGNvbnN0IGhhc1Jlc29sdmVyID0gdm0uZHVtcChcbiAgICAgICAgICB2bS5ldmFsQ29kZShgISFnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XWApXG4gICAgICAgICk7XG4gICAgICAgIGlmICghaGFzUmVzb2x2ZXIpIHtcbiAgICAgICAgICAvLyBObyByZXNvbHZlciB5ZXQg4oCUIGJ1ZmZlciAoc2VlIHN0ZXBfY29tcGxldGVkIGFib3ZlKS5cbiAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9fdGVybWluYWxCdWZmZXJbJHtjaWRKc31dID0geyBraW5kOiBcInJlc29sdmVfdW5kZWZpbmVkXCIgfTtgXG4gICAgICAgICAgKS5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhhc1Jlc29sdmVyKSB7XG4gICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV0ucmVzb2x2ZSgpO2AgK1xuICAgICAgICAgICAgICBgZGVsZXRlIGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dO2BcbiAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBsZXQgYjogbnVtYmVyO1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICBiID0gdm0uZXhlY3V0ZVBlbmRpbmdKb2JzKCk7XG4gICAgICAgICAgICB9IHdoaWxlIChiID4gMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG1hcmtDcmVhdGVkKHZtLCBjaWRKcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnaG9va19yZWNlaXZlZCc6IHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBldmVudCB3YXMgYWxyZWFkeSBwcm9jZXNzZWQgKGRlbGl2ZXJlZCBvclxuICAgICAgICAvLyBidWZmZXJlZCkgd2l0aGluIHRoaXMgaW52b2NhdGlvbi4gUHJldmVudHMgZG91YmxlLWRlbGl2ZXJ5IHdoZW5cbiAgICAgICAgLy8gdGhlIG91dGVyIGxvb3AgcmUtc2NhbnMgZXZlbnRzLlxuICAgICAgICBjb25zdCBhbHJlYWR5UHJvY2Vzc2VkID0gZXZlbnQuZXZlbnRJZFxuICAgICAgICAgID8gdm0uZHVtcChcbiAgICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgICAgYCEhKGdsb2JhbFRoaXMuX19ob29rUGF5bG9hZEJ1ZmZlci5fX3Byb2Nlc3NlZEV2ZW50SWRzICYmIGdsb2JhbFRoaXMuX19ob29rUGF5bG9hZEJ1ZmZlci5fX3Byb2Nlc3NlZEV2ZW50SWRzWyR7SlNPTi5zdHJpbmdpZnkoZXZlbnQuZXZlbnRJZCl9XSlgXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IGZhbHNlO1xuICAgICAgICBpZiAoYWxyZWFkeVByb2Nlc3NlZCkge1xuICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuZGVidWcoXG4gICAgICAgICAgICAnUXVpY2tKUyBydW50aW1lOiBob29rX3JlY2VpdmVkIGFscmVhZHkgcHJvY2Vzc2VkJyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogY2lkLFxuICAgICAgICAgICAgICBldmVudElkOiBldmVudC5ldmVudElkLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgICAgbWFya0NyZWF0ZWQodm0sIGNpZEpzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlc2lsaWVudC1yZXN1bWUgZGVkdXAgKHBhcml0eSB3aXRoIHRoZSBub2RlIGVuZ2luZSdzXG4gICAgICAgIC8vIEV2ZW50c0NvbnN1bWVyIGluIHdvcmtmbG93L2hvb2sudHMpOiB0d28gaG9va19yZWNlaXZlZCByb3dzIGZvclxuICAgICAgICAvLyBPTkUgcmVzdW1lIGF0dGVtcHQgc2hhcmUgYSBjbGllbnQtbWludGVkIGByZXN1bWVJZGAgKGEgZHVwbGljYXRlXG4gICAgICAgIC8vIGNhbiBiZSBjb21taXR0ZWQgd2hlbiB0aGUgbWF0ZXJpYWxpemF0aW9uIGZhbGxiYWNrIHJhY2VzIGFcbiAgICAgICAgLy8gZGVsYXllZCBkaXJlY3Qgd3JpdGUg4oCUIGhvb2tfcmVjZWl2ZWQgaGFzIG5vIHN0b3JhZ2UgdW5pcXVlbmVzc1xuICAgICAgICAvLyBjb25zdHJhaW50KS4gRGVsaXZlciBvbmx5IHRoZSBmaXJzdC1pbi1sb2cgb2NjdXJyZW5jZS4gVGhlIHNlZW5cbiAgICAgICAgLy8gc2V0IGxpdmVzIGluIHRoZSBWTSBoZWFwIHNvIGl0IGlzIGRldGVybWluaXN0aWMgcGVyIHJlcGxheSBhbmRcbiAgICAgICAgLy8gc3Vydml2ZXMgZXZlbnQgcmUtc2NhbnMgd2l0aGluIHRoZSBpbnZvY2F0aW9uLiBFdmVudHMgd2l0aG91dCBhXG4gICAgICAgIC8vIHJlc3VtZUlkIChvbGRlciBTREtzKSBhcmUgbmV2ZXIgZGVkdXBlZC5cbiAgICAgICAge1xuICAgICAgICAgIC8vIFRvcC1sZXZlbCBldmVudC5yZXN1bWVJZCBpcyB0aGUgY2Fub25pY2FsIGxvY2F0aW9uICh0aGUgYmFja2VuZFxuICAgICAgICAgIC8vIGhvaXN0cyBpdCB0byBhIGZpcnN0LWNsYXNzIGNvbHVtbik7IHRoZSBuZXN0ZWRcbiAgICAgICAgICAvLyBldmVudERhdGEucmVzdW1lSWQgZm9ybSBpcyBhIGRlcHJlY2F0ZWQgbGVnYWN5IGZhbGxiYWNrIOKAlFxuICAgICAgICAgIC8vIG1pcnJvcnMgdGhlIG5vZGUgZW5naW5lJ3MgZGVkdXAgaW4gd29ya2Zsb3cvaG9vay50cy5cbiAgICAgICAgICBjb25zdCByZXN1bWVJZCA9XG4gICAgICAgICAgICAoZXZlbnQgYXMgeyByZXN1bWVJZD86IHVua25vd24gfSkucmVzdW1lSWQgPz9cbiAgICAgICAgICAgIChldmVudERhdGEgYXMgeyByZXN1bWVJZD86IHVua25vd24gfSB8IHVuZGVmaW5lZCk/LnJlc3VtZUlkO1xuICAgICAgICAgIGlmICh0eXBlb2YgcmVzdW1lSWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bWVJZEpzID0gSlNPTi5zdHJpbmdpZnkocmVzdW1lSWQpO1xuICAgICAgICAgICAgY29uc3QgZHVwbGljYXRlID0gdm0uZHVtcChcbiAgICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgICAgYChnbG9iYWxUaGlzLl9faG9va1NlZW5SZXN1bWVJZHMgPSBnbG9iYWxUaGlzLl9faG9va1NlZW5SZXN1bWVJZHMgfHwge30pWyR7cmVzdW1lSWRKc31dID09PSB0cnVlYFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgICAgICBydW50aW1lTG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgICAgICdRdWlja0pTIHJ1bnRpbWU6IGR1cGxpY2F0ZSBob29rX3JlY2VpdmVkIGZvciB0aGUgc2FtZSByZXN1bWUgYXR0ZW1wdCwgZHJvcHBpbmcnLFxuICAgICAgICAgICAgICAgIHsgY29ycmVsYXRpb25JZDogY2lkLCBldmVudElkOiBldmVudC5ldmVudElkLCByZXN1bWVJZCB9XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmIChldmVudC5ldmVudElkKSB7XG4gICAgICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgICAgICBgKGdsb2JhbFRoaXMuX19ob29rUGF5bG9hZEJ1ZmZlci5fX3Byb2Nlc3NlZEV2ZW50SWRzID0gZ2xvYmFsVGhpcy5fX2hvb2tQYXlsb2FkQnVmZmVyLl9fcHJvY2Vzc2VkRXZlbnRJZHMgfHwge30pWyR7SlNPTi5zdHJpbmdpZnkoZXZlbnQuZXZlbnRJZCl9XSA9IHRydWU7YFxuICAgICAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIG1hcmtDcmVhdGVkKHZtLCBjaWRKcyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGBnbG9iYWxUaGlzLl9faG9va1NlZW5SZXN1bWVJZHNbJHtyZXN1bWVJZEpzfV0gPSB0cnVlO2BcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFib3J0IGRlbGl2ZXJ5OiBob29rX3JlY2VpdmVkIGZvciBhbiBBYm9ydENvbnRyb2xsZXIncyBzeXN0ZW1cbiAgICAgICAgLy8gaG9vayBmbGlwcyB0aGUgcmVnaXN0ZXJlZCBzaWduYWwgaW5zdGVhZCBvZiByZXNvbHZpbmcgYSBwcm9taXNlLlxuICAgICAgICAvLyBUaGUgcGF5bG9hZCBpcyB0aGUgZGVoeWRyYXRlZCBgeyBhYm9ydGVkOiB0cnVlLCByZWFzb24gfWAgb2JqZWN0LlxuICAgICAgICBjb25zdCBpc0Fib3J0SG9vayA9IHZtLmR1bXAoXG4gICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICBgISEoZ2xvYmFsVGhpcy5fX2Fib3J0U2lnbmFscyAmJiBnbG9iYWxUaGlzLl9fYWJvcnRTaWduYWxzWyR7Y2lkSnN9XSlgXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICBpZiAoaXNBYm9ydEhvb2spIHtcbiAgICAgICAgICBjb25zdCByYXdBYm9ydFBheWxvYWQgPSBldmVudERhdGE/LnBheWxvYWQ7XG4gICAgICAgICAgaWYgKHJhd0Fib3J0UGF5bG9hZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZCA9IGF3YWl0IHByZXBhcmVCeXRlc0ZvclZNKFxuICAgICAgICAgICAgICByYXdBYm9ydFBheWxvYWQsXG4gICAgICAgICAgICAgIGVuY3J5cHRpb25LZXlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkSGFuZGxlID0gc2VyZGUuZGVzZXJpYWxpemUoZGVjcnlwdGVkKTtcbiAgICAgICAgICAgIHZtLnNldFByb3Aodm0uZ2xvYmFsLCAnX190bXBfYWJvcnQnLCBwYXlsb2FkSGFuZGxlKTtcbiAgICAgICAgICAgIHBheWxvYWRIYW5kbGUuZGlzcG9zZSgpO1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGAoZnVuY3Rpb24oKXtgICtcbiAgICAgICAgICAgICAgICBgdmFyIHA9Z2xvYmFsVGhpcy5fX3RtcF9hYm9ydDtgICtcbiAgICAgICAgICAgICAgICBgZGVsZXRlIGdsb2JhbFRoaXMuX190bXBfYWJvcnQ7YCArXG4gICAgICAgICAgICAgICAgYGdsb2JhbFRoaXMuX19hYm9ydFNpZ25hbHNbJHtjaWRKc31dLl9zZXRBYm9ydGVkKHAmJnR5cGVvZiBwPT09XCJvYmplY3RcIj9wLnJlYXNvbjp1bmRlZmluZWQpO2AgK1xuICAgICAgICAgICAgICAgIGB9KSgpYFxuICAgICAgICAgICAgKS5kaXNwb3NlKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX2Fib3J0U2lnbmFsc1ske2NpZEpzfV0uX3NldEFib3J0ZWQodW5kZWZpbmVkKTtgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gVGhlIGFib3J0IGlzIGR1cmFibHkgcmVjb3JkZWQg4oCUIGNsZWFyIHRoZSBwZW5kaW5nIG9wJ3NcbiAgICAgICAgICAvLyBhYm9ydFJlcXVlc3RlZCBtYXJrZXIgc28gdGhlIGhvc3QgZG9lc24ndCByZS1yZWNvcmQgaXQgKHRoZVxuICAgICAgICAgIC8vIHdvcmtmbG93J3Mgb3duIGFib3J0KCkgY2FsbCBjYW4gc2V0IHRoZSBmbGFnIGJlZm9yZSB0aGlzXG4gICAgICAgICAgLy8gZXZlbnQgaXMgcHJvY2Vzc2VkIHdoZW4gaXQgaGFwcGVucyBsYXRlciBpbiByZXBsYXkgb3JkZXIsXG4gICAgICAgICAgLy8gYW5kIGhvb2tfcmVjZWl2ZWQgZXZlbnRzIGFyZSBub3QgdW5pcXVlIHBlciBjb3JyZWxhdGlvbklkKS5cbiAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgIGAoZnVuY3Rpb24oKXtgICtcbiAgICAgICAgICAgICAgYHZhciBwPWdsb2JhbFRoaXMuX19wZW5kaW5nLmZpbmQoZnVuY3Rpb24ocSl7cmV0dXJuIHEuY29ycmVsYXRpb25JZD09PSR7SlNPTi5zdHJpbmdpZnkoY2lkKX0mJnEudHlwZT09PVwiaG9va1wiO30pO2AgK1xuICAgICAgICAgICAgICBgaWYocClwLmFib3J0UmVxdWVzdGVkPWZhbHNlO2AgK1xuICAgICAgICAgICAgICBgfSkoKWBcbiAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICBpZiAoZXZlbnQuZXZlbnRJZCkge1xuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGAoZ2xvYmFsVGhpcy5fX2hvb2tQYXlsb2FkQnVmZmVyLl9fcHJvY2Vzc2VkRXZlbnRJZHMgPSBnbG9iYWxUaGlzLl9faG9va1BheWxvYWRCdWZmZXIuX19wcm9jZXNzZWRFdmVudElkcyB8fCB7fSlbJHtKU09OLnN0cmluZ2lmeShldmVudC5ldmVudElkKX1dID0gdHJ1ZTtgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAge1xuICAgICAgICAgICAgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgbGV0IGI6IG51bWJlcjtcbiAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgYiA9IHZtLmV4ZWN1dGVQZW5kaW5nSm9icygpO1xuICAgICAgICAgICAgfSB3aGlsZSAoYiA+IDApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBtYXJrQ3JlYXRlZCh2bSwgY2lkSnMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaGFzUmVzb2x2ZXIgPSB2bS5kdW1wKFxuICAgICAgICAgIHZtLmV2YWxDb2RlKGAhIWdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dYClcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgcmF3UGF5bG9hZCA9IGV2ZW50RGF0YT8ucGF5bG9hZCA/PyBldmVudERhdGE/LnJlc3VsdDtcbiAgICAgICAgcnVudGltZUxvZ2dlci5kZWJ1ZygnUXVpY2tKUyBydW50aW1lOiBwcm9jZXNzaW5nIGhvb2tfcmVjZWl2ZWQnLCB7XG4gICAgICAgICAgY29ycmVsYXRpb25JZDogY2lkLFxuICAgICAgICAgIGV2ZW50SWQ6IGV2ZW50LmV2ZW50SWQsXG4gICAgICAgICAgaGFzUmVzb2x2ZXIsXG4gICAgICAgICAgcGF5bG9hZFR5cGU6IHR5cGVvZiByYXdQYXlsb2FkLFxuICAgICAgICAgIHBheWxvYWRJc1VpbnQ4QXJyYXk6IHJhd1BheWxvYWQgaW5zdGFuY2VvZiBVaW50OEFycmF5LFxuICAgICAgICAgIHBheWxvYWRLZXlzOlxuICAgICAgICAgICAgcmF3UGF5bG9hZCAmJiB0eXBlb2YgcmF3UGF5bG9hZCA9PT0gJ29iamVjdCdcbiAgICAgICAgICAgICAgPyBPYmplY3Qua2V5cyhyYXdQYXlsb2FkKVxuICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChoYXNSZXNvbHZlcikge1xuICAgICAgICAgIGlmIChyYXdQYXlsb2FkIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgICAgICAgLy8gRGVjcnlwdCBpZiBlbmNyeXB0ZWQg4oCUIHRoZSBWTSBvbmx5IHVuZGVyc3RhbmRzICdkZXZsJyBmb3JtYXRcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZFBheWxvYWQgPSBhd2FpdCBwcmVwYXJlQnl0ZXNGb3JWTShcbiAgICAgICAgICAgICAgcmF3UGF5bG9hZCxcbiAgICAgICAgICAgICAgZW5jcnlwdGlvbktleVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWRIYW5kbGUgPSBzZXJkZS5kZXNlcmlhbGl6ZShkZWNyeXB0ZWRQYXlsb2FkKTtcbiAgICAgICAgICAgIHZtLnNldFByb3Aodm0uZ2xvYmFsLCAnX190bXBfcmVzdWx0JywgcGF5bG9hZEhhbmRsZSk7XG4gICAgICAgICAgICBwYXlsb2FkSGFuZGxlLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgICBgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1ske2NpZEpzfV0ucmVzb2x2ZShnbG9iYWxUaGlzLl9fdG1wX3Jlc3VsdCk7YCArXG4gICAgICAgICAgICAgICAgYGRlbGV0ZSBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XTtgICtcbiAgICAgICAgICAgICAgICBgZGVsZXRlIGdsb2JhbFRoaXMuX190bXBfcmVzdWx0O2BcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzZXJpYWxpemVkID1cbiAgICAgICAgICAgICAgcmF3UGF5bG9hZCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyBKU09OLnN0cmluZ2lmeShyYXdQYXlsb2FkKVxuICAgICAgICAgICAgICAgIDogJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgICAgYGdsb2JhbFRoaXMuX19yZXNvbHZlcnNbJHtjaWRKc31dLnJlc29sdmUoJHtzZXJpYWxpemVkfSk7YCArXG4gICAgICAgICAgICAgICAgYGRlbGV0ZSBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzWyR7Y2lkSnN9XTtgXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gTWFyayB0aGlzIGV2ZW50IGFzIHByb2Nlc3NlZCBpbiB0aGUgVk0gaGVhcCB0byBwcmV2ZW50XG4gICAgICAgICAgLy8gZG91YmxlLWRlbGl2ZXJ5IHdoZW4gdGhlIG91dGVyIGxvb3AgcmUtc2NhbnMgZXZlbnRzLlxuICAgICAgICAgIGlmIChldmVudC5ldmVudElkKSB7XG4gICAgICAgICAgICB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgICAgYChnbG9iYWxUaGlzLl9faG9va1BheWxvYWRCdWZmZXIuX19wcm9jZXNzZWRFdmVudElkcyA9IGdsb2JhbFRoaXMuX19ob29rUGF5bG9hZEJ1ZmZlci5fX3Byb2Nlc3NlZEV2ZW50SWRzIHx8IHt9KVske0pTT04uc3RyaW5naWZ5KGV2ZW50LmV2ZW50SWQpfV0gPSB0cnVlO2BcbiAgICAgICAgICAgICkuZGlzcG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBsZXQgYjogbnVtYmVyO1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICBiID0gdm0uZXhlY3V0ZVBlbmRpbmdKb2JzKCk7XG4gICAgICAgICAgICB9IHdoaWxlIChiID4gMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5vIHJlc29sdmVyIHlldCDigJQgYnVmZmVyIHRoZSBwYXlsb2FkIGluIHRoZSBWTSBoZWFwLiBXaGVuXG4gICAgICAgICAgLy8gY3JlYXRlSG9va1Byb21pc2UoKSBpcyBjYWxsZWQgbGF0ZXIsIGl0IHdpbGwgZHJhaW4gdGhpcyBidWZmZXJcbiAgICAgICAgICAvLyBmaXJzdCAobWF0Y2hpbmcgdGhlIG5vZGU6dm0gZW5naW5lJ3MgcGF5bG9hZHNRdWV1ZSBiZWhhdmlvcikuXG4gICAgICAgICAgY29uc3QgZXZlbnRJZEpzID0gZXZlbnQuZXZlbnRJZFxuICAgICAgICAgICAgPyBKU09OLnN0cmluZ2lmeShldmVudC5ldmVudElkKVxuICAgICAgICAgICAgOiAnbnVsbCc7XG4gICAgICAgICAgY29uc3QgYnVmZmVyQW5kVHJhY2sgPVxuICAgICAgICAgICAgYChnbG9iYWxUaGlzLl9faG9va1BheWxvYWRCdWZmZXJbJHtjaWRKc31dID0gZ2xvYmFsVGhpcy5fX2hvb2tQYXlsb2FkQnVmZmVyWyR7Y2lkSnN9XSB8fCBbXSlgICtcbiAgICAgICAgICAgIGAucHVzaCglUEFZTE9BRCUpO2AgK1xuICAgICAgICAgICAgKGV2ZW50LmV2ZW50SWRcbiAgICAgICAgICAgICAgPyBgKGdsb2JhbFRoaXMuX19ob29rUGF5bG9hZEJ1ZmZlci5fX3Byb2Nlc3NlZEV2ZW50SWRzID0gZ2xvYmFsVGhpcy5fX2hvb2tQYXlsb2FkQnVmZmVyLl9fcHJvY2Vzc2VkRXZlbnRJZHMgfHwge30pWyR7ZXZlbnRJZEpzfV0gPSB0cnVlO2BcbiAgICAgICAgICAgICAgOiAnJyk7XG4gICAgICAgICAgaWYgKHJhd1BheWxvYWQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgICAvLyBEZWNyeXB0IGlmIGVuY3J5cHRlZCDigJQgdGhlIFZNIG9ubHkgdW5kZXJzdGFuZHMgJ2RldmwnIGZvcm1hdFxuICAgICAgICAgICAgY29uc3QgZGVjcnlwdGVkUGF5bG9hZCA9IGF3YWl0IHByZXBhcmVCeXRlc0ZvclZNKFxuICAgICAgICAgICAgICByYXdQYXlsb2FkLFxuICAgICAgICAgICAgICBlbmNyeXB0aW9uS2V5XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZEhhbmRsZSA9IHNlcmRlLmRlc2VyaWFsaXplKGRlY3J5cHRlZFBheWxvYWQpO1xuICAgICAgICAgICAgdm0uc2V0UHJvcCh2bS5nbG9iYWwsICdfX3RtcF9yZXN1bHQnLCBwYXlsb2FkSGFuZGxlKTtcbiAgICAgICAgICAgIHBheWxvYWRIYW5kbGUuZGlzcG9zZSgpO1xuICAgICAgICAgICAgLy8gTk9URTogcmVwbGFjZW1lbnQgaXMgYSBmdW5jdGlvbiBzbyBgJGAtc2VxdWVuY2VzIGluIHRoZVxuICAgICAgICAgICAgLy8gc3Vic3RpdHV0ZWQgSlMgbmV2ZXIgZ2V0IGludGVycHJldGVkIGFzIFN0cmluZy5yZXBsYWNlXG4gICAgICAgICAgICAvLyBzcGVjaWFsIHJlcGxhY2VtZW50IHBhdHRlcm5zLlxuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGJ1ZmZlckFuZFRyYWNrLnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgJyVQQVlMT0FEJScsXG4gICAgICAgICAgICAgICAgKCkgPT4gJ2dsb2JhbFRoaXMuX190bXBfcmVzdWx0J1xuICAgICAgICAgICAgICApICsgJ2RlbGV0ZSBnbG9iYWxUaGlzLl9fdG1wX3Jlc3VsdDsnXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc2VyaWFsaXplZCA9XG4gICAgICAgICAgICAgIHJhd1BheWxvYWQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgID8gSlNPTi5zdHJpbmdpZnkocmF3UGF5bG9hZClcbiAgICAgICAgICAgICAgICA6ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgLy8gRnVuY3Rpb24gcmVwbGFjZW1lbnQ6IGEgSlNPTi1zZXJpYWxpemVkIHBheWxvYWQgY2FuIGNvbnRhaW5cbiAgICAgICAgICAgIC8vIGAkJmAsIGAkJ2AsIGAkXFxgYCwgLi4uIHdoaWNoIFN0cmluZy5yZXBsYWNlIHdvdWxkIG90aGVyd2lzZVxuICAgICAgICAgICAgLy8gZXhwYW5kLCBzaWxlbnRseSBjb3JydXB0aW5nIHRoZSBpbmplY3RlZCBjb2RlLlxuICAgICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICAgIGJ1ZmZlckFuZFRyYWNrLnJlcGxhY2UoJyVQQVlMT0FEJScsICgpID0+IHNlcmlhbGl6ZWQpXG4gICAgICAgICAgICApLmRpc3Bvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbWFya0NyZWF0ZWQodm0sIGNpZEpzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdob29rX2NvbmZsaWN0Jzoge1xuICAgICAgICAvLyBBbm90aGVyIHdvcmtmbG93IG93bnMgdGhpcyBob29rIHRva2VuLiBQYXlsb2FkIGF3YWl0ZXJzIHJlamVjdFxuICAgICAgICAvLyB3aXRoIEhvb2tDb25mbGljdEVycm9yOyBnZXRDb25mbGljdCgpIGF3YWl0ZXJzIHJlc29sdmUgd2l0aCBhXG4gICAgICAgIC8vIFJ1biBoYW5kbGUgZm9yIHRoZSBjb25mbGljdGluZyBydW4gKHJldml2ZWQgdGhyb3VnaCB0aGUgVk0nc1xuICAgICAgICAvLyBjbGFzcyByZWdpc3RyeSBzbyBpdHMgbWV0aG9kcyBhcmUgZHVyYWJsZSBzdGVwIHByb3hpZXMpIG9yXG4gICAgICAgIC8vIHJlamVjdCB3aXRoIHRoZSBlcnJvciB3aGVuIG5vIGhhbmRsZSBjYW4gYmUgY29uc3RydWN0ZWQg4oCUXG4gICAgICAgIC8vIG1pcnJvcmluZyB0aGUgbm9kZTp2bSBlbmdpbmUncyBob29rLnRzIGhvb2tfY29uZmxpY3QgaGFuZGxpbmcuXG4gICAgICAgIGNvbnN0IGNvbmZsaWN0VG9rZW4gPSAoZXZlbnREYXRhPy50b2tlbiBhcyBzdHJpbmcpID8/ICd1bmtub3duJztcbiAgICAgICAgY29uc3QgY29uZmxpY3RpbmdSdW5JZCA9IGV2ZW50RGF0YT8uY29uZmxpY3RpbmdSdW5JZCBhc1xuICAgICAgICAgIHwgc3RyaW5nXG4gICAgICAgICAgfCB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IGRpZFNldHRsZSA9IHZtLmR1bXAoXG4gICAgICAgICAgdm0uZXZhbENvZGUoXG4gICAgICAgICAgICBgKGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICAgIHZhciBjaWQgPSAke0pTT04uc3RyaW5naWZ5KGNpZCl9O1xuICAgICAgICAgICAgICB2YXIgdG9rZW4gPSAke0pTT04uc3RyaW5naWZ5KGNvbmZsaWN0VG9rZW4pfTtcbiAgICAgICAgICAgICAgdmFyIGNvbmZsaWN0aW5nUnVuSWQgPSAke0pTT04uc3RyaW5naWZ5KGNvbmZsaWN0aW5nUnVuSWQgPz8gbnVsbCl9O1xuICAgICAgICAgICAgICB2YXIgRXJyQ2xzID0gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKCdAd29ya2Zsb3cvZXJyb3JzLy9Ib29rQ29uZmxpY3RFcnJvcicpXTtcbiAgICAgICAgICAgICAgdmFyIGVycjtcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBFcnJDbHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBlcnIgPSBuZXcgRXJyQ2xzKHRva2VuLCBjb25mbGljdGluZ1J1bklkIHx8IHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXJyID0gbmV3IEVycm9yKCdIb29rIHRva2VuIFwiJyArIHRva2VuICsgJ1wiIGlzIGFscmVhZHkgaW4gdXNlIGJ5IGFub3RoZXIgd29ya2Zsb3cnKTtcbiAgICAgICAgICAgICAgICBlcnIubmFtZSA9ICdIb29rQ29uZmxpY3RFcnJvcic7XG4gICAgICAgICAgICAgICAgZXJyLnRva2VuID0gdG9rZW47XG4gICAgICAgICAgICAgICAgaWYgKGNvbmZsaWN0aW5nUnVuSWQpIGVyci5jb25mbGljdGluZ1J1bklkID0gY29uZmxpY3RpbmdSdW5JZDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB2YXIgcnVuID0gbnVsbDtcbiAgICAgICAgICAgICAgaWYgKGNvbmZsaWN0aW5nUnVuSWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVnID0gZ2xvYmFsVGhpc1tTeW1ib2wuZm9yKCd3b3JrZmxvdy1jbGFzcy1yZWdpc3RyeScpXTtcbiAgICAgICAgICAgICAgICB2YXIgUnVuQ2xzID0gcmVnICYmIHJlZy5nZXQoJ2NsYXNzLy93b3JrZmxvdy8vUnVuJyk7XG4gICAgICAgICAgICAgICAgdmFyIGRlcyA9IFJ1bkNscyAmJiBSdW5DbHNbU3ltYm9sLmZvcignd29ya2Zsb3ctZGVzZXJpYWxpemUnKV07XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBkZXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgIHJ1biA9IGRlcy5jYWxsKFJ1bkNscywgeyBydW5JZDogY29uZmxpY3RpbmdSdW5JZCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdmFyIHNldHRsZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgdmFyIHN0YXRlID0gZ2xvYmFsVGhpcy5fX2hvb2tzICYmIGdsb2JhbFRoaXMuX19ob29rc1tjaWRdO1xuICAgICAgICAgICAgICBpZiAoc3RhdGUgJiYgIXN0YXRlLmNvbmZsaWN0KSB7XG4gICAgICAgICAgICAgICAgc3RhdGUuY29uZmxpY3QgPSB7IGVycm9yOiBlcnIsIHJ1bjogcnVuIH07XG4gICAgICAgICAgICAgICAgdmFyIGdjID0gc3RhdGUuZ2V0Q29uZmxpY3RSZXNvbHZlcnM7XG4gICAgICAgICAgICAgICAgc3RhdGUuZ2V0Q29uZmxpY3RSZXNvbHZlcnMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGdjLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICBpZiAocnVuKSB7IGdjW2ldLnJlc29sdmUocnVuKTsgfSBlbHNlIHsgZ2NbaV0ucmVqZWN0KGVycik7IH1cbiAgICAgICAgICAgICAgICAgIHNldHRsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1tjaWRdKSB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1tjaWRdLnJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBnbG9iYWxUaGlzLl9fcmVzb2x2ZXJzW2NpZF07XG4gICAgICAgICAgICAgICAgc2V0dGxlZCA9IHRydWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHNldHRsZWQ7XG4gICAgICAgICAgICB9KSgpYFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGRpZFNldHRsZSkge1xuICAgICAgICAgIHJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgICBsZXQgYjogbnVtYmVyO1xuICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgIGIgPSB2bS5leGVjdXRlUGVuZGluZ0pvYnMoKTtcbiAgICAgICAgICB9IHdoaWxlIChiID4gMCk7XG4gICAgICAgIH1cbiAgICAgICAgbWFya0NyZWF0ZWQodm0sIGNpZEpzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdzdGVwX2NyZWF0ZWQnOlxuICAgICAgY2FzZSAnc3RlcF9zdGFydGVkJzpcbiAgICAgIGNhc2UgJ3N0ZXBfcmV0cnlpbmcnOlxuICAgICAgY2FzZSAnd2FpdF9jcmVhdGVkJzoge1xuICAgICAgICBtYXJrQ3JlYXRlZCh2bSwgY2lkSnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2hvb2tfY3JlYXRlZCc6IHtcbiAgICAgICAgLy8gQ29uZmlybSBjcmVhdGlvbiBmb3IgZ2V0Q29uZmxpY3QoKSBhd2FpdGVyczogcmVzb2x2ZSB0aGVtIHdpdGhcbiAgICAgICAgLy8gbnVsbCAobm8gY29uZmxpY3QpIG9uY2UgdGhlIGV2ZW50IGxvZyBwcm92ZXMgdGhlIGhvb2sgZXhpc3RzLlxuICAgICAgICBjb25zdCBzZXR0bGVkR2V0Q29uZmxpY3QgPSB2bS5kdW1wKFxuICAgICAgICAgIHZtLmV2YWxDb2RlKFxuICAgICAgICAgICAgYChmdW5jdGlvbigpe1xuICAgICAgICAgICAgICB2YXIgc3RhdGUgPSBnbG9iYWxUaGlzLl9faG9va3MgJiYgZ2xvYmFsVGhpcy5fX2hvb2tzWyR7SlNPTi5zdHJpbmdpZnkoY2lkKX1dO1xuICAgICAgICAgICAgICBpZiAoIXN0YXRlKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgIHN0YXRlLmNyZWF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICB2YXIgZ2MgPSBzdGF0ZS5nZXRDb25mbGljdFJlc29sdmVycztcbiAgICAgICAgICAgICAgc3RhdGUuZ2V0Q29uZmxpY3RSZXNvbHZlcnMgPSBbXTtcbiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBnYy5sZW5ndGg7IGkrKykgZ2NbaV0ucmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGdjLmxlbmd0aCA+IDA7XG4gICAgICAgICAgICB9KSgpYFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHNldHRsZWRHZXRDb25mbGljdCkge1xuICAgICAgICAgIHJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgICBsZXQgYjogbnVtYmVyO1xuICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgIGIgPSB2bS5leGVjdXRlUGVuZGluZ0pvYnMoKTtcbiAgICAgICAgICB9IHdoaWxlIChiID4gMCk7XG4gICAgICAgIH1cbiAgICAgICAgbWFya0NyZWF0ZWQodm0sIGNpZEpzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdob29rX2Rpc3Bvc2VkJzoge1xuICAgICAgICAvLyBEaXNhbWJpZ3VhdGUgZnJvbSB0aGUgYGhvb2tgIHBlbmRpbmcgb3Agd2l0aCB0aGUgc2FtZVxuICAgICAgICAvLyBjb3JyZWxhdGlvbklkIOKAlCB3ZSB3YW50IHRvIG1hcmsgdGhlIGBob29rX2Rpc3Bvc2VgIGVudHJ5LlxuICAgICAgICBtYXJrQ3JlYXRlZCh2bSwgY2lkSnMsICdob29rX2Rpc3Bvc2UnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXNvbHZlZDtcbn1cblxuZnVuY3Rpb24gbWFya0NyZWF0ZWQodm06IFF1aWNrSlMsIGNpZEpzOiBzdHJpbmcsIG9wVHlwZT86IHN0cmluZyk6IHZvaWQge1xuICAvLyBgY2lkSnNgIGlzIHRoZSBKU09OLnN0cmluZ2lmeS1xdW90ZWQgY29ycmVsYXRpb24gaWQgKHNlZSBwcm9jZXNzRXZlbnRzKS5cbiAgLy8gYGhvb2tgIGFuZCBgaG9va19kaXNwb3NlYCBwZW5kaW5nIG9wcyBzaGFyZSB0aGUgc2FtZSBjb3JyZWxhdGlvbklkLFxuICAvLyBzbyB3aGVuIHByb2Nlc3NpbmcgYGhvb2tfZGlzcG9zZWRgIGV2ZW50cyB3ZSBtdXN0IGRpc2FtYmlndWF0ZSBieVxuICAvLyB0eXBlIOKAlCBvdGhlcndpc2UgYC5maW5kKClgIHJldHVybnMgdGhlIG9yaWdpbmFsIGBob29rYCBvcCBhbmQgdGhlXG4gIC8vIGBob29rX2Rpc3Bvc2VgIG9wIGlzIG5ldmVyIG1hcmtlZCwgY2F1c2luZyB0aGUgZW50cnlwb2ludCB0byBrZWVwXG4gIC8vIHJldHJ5aW5nIGEgaG9va19kaXNwb3NlZCBmb3IgYW4gYWxyZWFkeS1kZWxldGVkIGVudGl0eS5cbiAgY29uc3QgcHJlZGljYXRlID0gb3BUeXBlXG4gICAgPyBgZnVuY3Rpb24ocCl7cmV0dXJuIHAuY29ycmVsYXRpb25JZD09PSR7Y2lkSnN9JiZwLnR5cGU9PT0ke0pTT04uc3RyaW5naWZ5KG9wVHlwZSl9O31gXG4gICAgOiBgZnVuY3Rpb24ocCl7cmV0dXJuIHAuY29ycmVsYXRpb25JZD09PSR7Y2lkSnN9O31gO1xuICB2bS5ldmFsQ29kZShcbiAgICBgdmFyIF9fcD1nbG9iYWxUaGlzLl9fcGVuZGluZy5maW5kKCR7cHJlZGljYXRlfSk7YCArXG4gICAgICBgaWYoX19wKV9fcC5oYXNDcmVhdGVkRXZlbnQ9dHJ1ZTtgXG4gICkuZGlzcG9zZSgpO1xufVxuXG4vLyAtLS0tIFN0YXRlIENoZWNraW5nIC0tLS1cblxuLyoqXG4gKiBDb2xsZWN0IGxlZnRvdmVyIHBlbmRpbmcgb3BlcmF0aW9ucyB0aGF0IG5lZWQgZHVyYWJsZSBzaWRlIGVmZmVjdHMgd2hlblxuICogdGhlIHdvcmtmbG93IHJlYWNoZXMgYSB0ZXJtaW5hbCBzdGF0ZS4gTWlycm9ycyB0aGUgbm9kZTp2bSBlbmdpbmUnc1xuICogZHJhaW5QZW5kaW5nUXVldWVJdGVtcyAod29ya2Zsb3cudHMpOiBzdGlsbC1hbGl2ZSBzeXN0ZW0gaG9va3NcbiAqIChBYm9ydENvbnRyb2xsZXIpIHdpdGhvdXQgYW4gYWJvcnQgaW4gZmxpZ2h0IGFyZSBpbXBsaWNpdGx5IGRpc3Bvc2VkIHNvXG4gKiB0aGV5IGRvbid0IGxlYWsgaG9vayByb3dzOyBvcHMgd2l0aG91dCBjcmVhdGVkIGV2ZW50cyAoZmlyZS1hbmQtZm9yZ2V0XG4gKiBhdHRyaWJ1dGVzL2hvb2tzL3N0ZXBzL3dhaXRzKSBhbmQgcGVuZGluZyBhYm9ydCByZWNvcmRpbmdzIGFyZSBzdXJmYWNlZFxuICogZm9yIHRoZSBlbnRyeXBvaW50IHRvIGZsdXNoLlxuICovXG4vKipcbiAqIFBlci1WTSBjYWNoZSBvZiBzZXJpYWxpemVkIHBlbmRpbmctb3AgZmllbGQgYnl0ZXMsIGtleWVkXG4gKiBgY29ycmVsYXRpb25JZDpmaWVsZGAuIEEgc3RlcCdzIHJhdyBpbnB1dCBpcyBpbW11dGFibGUgb25jZSBwdXNoZWQsIHNvXG4gKiBpdHMgYnl0ZXMgYXJlIGNvbXB1dGVkIG9uY2UgZXZlbiB0aG91Z2ggdGhlIG9wIGlzIHJlLWNvbGxlY3RlZCBvbiBldmVyeVxuICogc3VzcGVuc2lvbiBpdCBzdGF5cyBwZW5kaW5nIHRocm91Z2guXG4gKi9cbmNvbnN0IHBlbmRpbmdCeXRlQ2FjaGUgPSBuZXcgV2Vha01hcDxRdWlja0pTLCBNYXA8c3RyaW5nLCBVaW50OEFycmF5Pj4oKTtcblxuZnVuY3Rpb24gZW5zdXJlUGVuZGluZ0J5dGVDYWNoZSh2bTogUXVpY2tKUyk6IE1hcDxzdHJpbmcsIFVpbnQ4QXJyYXk+IHtcbiAgbGV0IGNhY2hlID0gcGVuZGluZ0J5dGVDYWNoZS5nZXQodm0pO1xuICBpZiAoIWNhY2hlKSB7XG4gICAgY2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgcGVuZGluZ0J5dGVDYWNoZS5zZXQodm0sIGNhY2hlKTtcbiAgfVxuICByZXR1cm4gY2FjaGU7XG59XG5cbi8qKlxuICogVGhlIHBlbmRpbmctb3AgZmllbGRzIHRoYXQgaG9sZCBSQVcgZ3Vlc3QgdmFsdWVzICh0aGUgYm9vdHN0cmFwIG5vIGxvbmdlclxuICogc2VyaWFsaXplcyB0aGVtIGluIHRoZSBWTSkuIENvbGxlY3Rpb24gcHJvamVjdHMgdGhlbSBvdXQgb2YgdGhlIGR1bXBlZFxuICogcGxhaW4gbWV0YWRhdGEgYW5kIHNlcmlhbGl6ZXMgZWFjaCB0aHJvdWdoIGEgaGFuZGxlIHdpdGggdGhlIGhvc3Qgc2VyZGUuXG4gKi9cbmNvbnN0IFJBV19QRU5ESU5HX0ZJRUxEUyA9IFsnaW5wdXQnLCAnbWV0YWRhdGEnLCAnYWJvcnRQYXlsb2FkJ10gYXMgY29uc3Q7XG5cbi8qKlxuICogRHVtcCBhIGZpbHRlcmVkIHZpZXcgb2YgYGdsb2JhbFRoaXMuX19wZW5kaW5nYCB0byBob3N0IFBlbmRpbmdPcGVyYXRpb25cbiAqIG9iamVjdHMsIHNlcmlhbGl6aW5nIHRoZSByYXctdmFsdWUgZmllbGRzIGhvc3Qtc2lkZS4gYGZpbHRlckV4cHJgIGlzIGFcbiAqIGd1ZXN0IGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gdGhlIGFycmF5IG9mIG9wcyB0byBjb2xsZWN0LlxuICovXG5mdW5jdGlvbiBkdW1wUGVuZGluZ09wcyhcbiAgdm06IFF1aWNrSlMsXG4gIHNlcmRlOiBRdWlja0pTU2VyZGUsXG4gIGZpbHRlckV4cHI6IHN0cmluZyxcbiAgYnl0ZUNhY2hlPzogTWFwPHN0cmluZywgVWludDhBcnJheT5cbik6IFBlbmRpbmdPcGVyYXRpb25bXSB7XG4gIHVzaW5nIHByb2plY3RlZCA9IHZtLmV2YWxDb2RlKGAoZnVuY3Rpb24oKXtcbiAgICB2YXIgb3BzID0gJHtmaWx0ZXJFeHByfTtcbiAgICBnbG9iYWxUaGlzLl9fcmF3RmllbGRzID0gW107XG4gICAgLy8gU2V0dGxlZCBvcHMg4oCUIGNyZWF0ZWQsIHJlc29sdmVyLWxlc3MsIG5vIGFib3J0IGluIGZsaWdodCDigJQgYXJlXG4gICAgLy8gbmV2ZXIgY29sbGVjdGVkIGFnYWluIGJ5IGVpdGhlciB0aGUgc3VzcGVuc2lvbiBvciB0aGUgZHJhaW5cbiAgICAvLyBmaWx0ZXIsIHNvIHRoZWlyIGNhY2hlZCBieXRlcyBhcmUgZGVhZCB3ZWlnaHQ7IHN1cmZhY2UgdGhlaXIgY2lkc1xuICAgIC8vIHNvIHRoZSBob3N0IGNhbiBldmljdCB0aGVtIChzZWUgdGhlIGJ5dGUtY2FjaGUgZXZpY3Rpb24gYmVsb3cpLlxuICAgIHZhciBzZXR0bGVkID0gW107XG4gICAgZ2xvYmFsVGhpcy5fX3BlbmRpbmcuZm9yRWFjaChmdW5jdGlvbihwKXtcbiAgICAgIGlmIChwLmhhc0NyZWF0ZWRFdmVudCAmJiAhZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1twLmNvcnJlbGF0aW9uSWRdICYmICFwLmFib3J0UmVxdWVzdGVkKSB7XG4gICAgICAgIHNldHRsZWQucHVzaChwLmNvcnJlbGF0aW9uSWQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB7IHNldHRsZWQ6IHNldHRsZWQsIG9wczogb3BzLm1hcChmdW5jdGlvbihwKXtcbiAgICAgIHZhciBxID0ge307XG4gICAgICBmb3IgKHZhciBrIGluIHApIHtcbiAgICAgICAgaWYgKGsgPT09ICdpbnB1dCcgfHwgayA9PT0gJ21ldGFkYXRhJyB8fCBrID09PSAnYWJvcnRQYXlsb2FkJykgY29udGludWU7XG4gICAgICAgIHFba10gPSBwW2tdO1xuICAgICAgfVxuICAgICAgdmFyIHJhdyA9IHt9O1xuICAgICAgWydpbnB1dCcsICdtZXRhZGF0YScsICdhYm9ydFBheWxvYWQnXS5mb3JFYWNoKGZ1bmN0aW9uKGYpe1xuICAgICAgICBpZiAocFtmXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmF3W2ZdID0gZ2xvYmFsVGhpcy5fX3Jhd0ZpZWxkcy5sZW5ndGg7XG4gICAgICAgICAgZ2xvYmFsVGhpcy5fX3Jhd0ZpZWxkcy5wdXNoKHBbZl0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHEuX19yYXdJbmRpY2VzID0gcmF3O1xuICAgICAgcmV0dXJuIHE7XG4gICAgfSkgfTtcbiAgfSkoKWApO1xuICBjb25zdCBkdW1wZWQgPSB2bS5kdW1wKHByb2plY3RlZCkgYXMge1xuICAgIHNldHRsZWQ6IHN0cmluZ1tdO1xuICAgIG9wczogKFBlbmRpbmdPcGVyYXRpb24gJiB7XG4gICAgICBfX3Jhd0luZGljZXM/OiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+O1xuICAgIH0pW107XG4gIH07XG4gIGNvbnN0IHBsYWluT3BzID0gZHVtcGVkLm9wcztcbiAgLy8gQnl0ZS1jYWNoZSBldmljdGlvbjogZW50cmllcyBmb3Igc2V0dGxlZCBvcHMgY2FuIG5ldmVyIGJlIHJlYWQgYWdhaW5cbiAgLy8gKG5laXRoZXIgY29sbGVjdGlvbiBmaWx0ZXIgbWF0Y2hlcyBhIHNldHRsZWQgb3ApLCBzbyBkcm9wcGluZyB0aGVtXG4gIC8vIGJvdW5kcyB0aGUgY2FjaGUgYnkgdGhlIExJVkUgcGVuZGluZyBzZXQgaW5zdGVhZCBvZiBncm93aW5nXG4gIC8vIG1vbm90b25pY2FsbHkgZm9yIHRoZSBWTSdzIGxpZmV0aW1lIOKAlCB3aGljaCBtYXR0ZXJzIGZvciB0aGUgaW5saW5lXG4gIC8vIGxvb3AncyBsb25nLWxpdmVkIHNlc3Npb25zIGFuZCBzbmFwc2hvdC1yZXN0b3JlZCBWTXMuXG4gIGlmIChieXRlQ2FjaGUgJiYgZHVtcGVkLnNldHRsZWQubGVuZ3RoID4gMCkge1xuICAgIGZvciAoY29uc3QgY2lkIG9mIGR1bXBlZC5zZXR0bGVkKSB7XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIFJBV19QRU5ESU5HX0ZJRUxEUykge1xuICAgICAgICBieXRlQ2FjaGUuZGVsZXRlKGAke2NpZH06JHtmaWVsZH1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdXNpbmcgcmF3RmllbGRzID0gdm0uZXZhbENvZGUoJ2dsb2JhbFRoaXMuX19yYXdGaWVsZHMnKTtcbiAgZm9yIChjb25zdCBvcCBvZiBwbGFpbk9wcykge1xuICAgIGNvbnN0IHJhd0luZGljZXMgPSBvcC5fX3Jhd0luZGljZXMgPz8ge307XG4gICAgZGVsZXRlIG9wLl9fcmF3SW5kaWNlcztcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIFJBV19QRU5ESU5HX0ZJRUxEUykge1xuICAgICAgY29uc3QgaW5kZXggPSByYXdJbmRpY2VzW2ZpZWxkXTtcbiAgICAgIGlmIChpbmRleCA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IGNhY2hlS2V5ID0gYCR7b3AuY29ycmVsYXRpb25JZH06JHtmaWVsZH1gO1xuICAgICAgbGV0IGJ5dGVzID0gYnl0ZUNhY2hlPy5nZXQoY2FjaGVLZXkpO1xuICAgICAgaWYgKCFieXRlcykge1xuICAgICAgICB1c2luZyB2YWx1ZUhhbmRsZSA9IHJhd0ZpZWxkcy5nZXRQcm9wKFN0cmluZyhpbmRleCkpO1xuICAgICAgICBieXRlcyA9IHNlcmRlLnNlcmlhbGl6ZSh2YWx1ZUhhbmRsZSk7XG4gICAgICAgIGJ5dGVDYWNoZT8uc2V0KGNhY2hlS2V5LCBieXRlcyk7XG4gICAgICB9XG4gICAgICAob3AgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbZmllbGRdID0gYnl0ZXM7XG4gICAgfVxuICB9XG4gIHZtLmV2YWxDb2RlKCdkZWxldGUgZ2xvYmFsVGhpcy5fX3Jhd0ZpZWxkcycpLmRpc3Bvc2UoKTtcbiAgcmV0dXJuIHBsYWluT3BzO1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0RHJhaW5PcGVyYXRpb25zKFxuICB2bTogUXVpY2tKUyxcbiAgc2VyZGU6IFF1aWNrSlNTZXJkZVxuKTogUGVuZGluZ09wZXJhdGlvbltdIHtcbiAgLy8gU2hhcmUgdGhlIHBlci1WTSBieXRlIGNhY2hlIHdpdGggdGhlIHN1c3BlbnNpb24gcGF0aDogYW4gb3AgdGhhdCB3YXNcbiAgLy8gc2VyaWFsaXplZCBkdXJpbmcgYSBzdXNwZW5zaW9uIHBhc3MgbXVzdCByZXVzZSB0aG9zZSBleGFjdCBieXRlcyBhdFxuICAvLyB0ZXJtaW5hbCBkcmFpbiDigJQgcmUtc2VyaWFsaXppbmcgY2FuIGludm9rZSBnZXR0ZXJzIGFnYWluIGFuZCBwcm9kdWNlXG4gIC8vIGEgRElGRkVSRU5UIGJ5dGUgc2VxdWVuY2UgZm9yIHdoYXQgdGhlIGV2ZW50IGxvZyB0cmVhdHMgYXMgb25lIHZhbHVlLlxuICByZXR1cm4gZHVtcFBlbmRpbmdPcHMoXG4gICAgdm0sXG4gICAgc2VyZGUsXG4gICAgYChmdW5jdGlvbigpe1xuICAgIHZhciB0b0Rpc3Bvc2UgPSBbXTtcbiAgICBnbG9iYWxUaGlzLl9fcGVuZGluZy5mb3JFYWNoKGZ1bmN0aW9uKHApe1xuICAgICAgaWYgKHAudHlwZSA9PT0gXCJob29rXCIgJiYgcC5pc1N5c3RlbSAmJiAhcC5hYm9ydFJlcXVlc3RlZCAmJiAhcC5kaXNwb3NlZCkge1xuICAgICAgICBwLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgLy8gT25seSBkaXNwb3NlIGhvb2tzIHRoYXQgd2VyZSBkdXJhYmx5IGNyZWF0ZWQ7IGEgaG9vayB0aGF0IG5ldmVyXG4gICAgICAgIC8vIHJlYWNoZWQgc3RvcmFnZSBoYXMgbm90aGluZyB0byBjbGVhbiB1cC5cbiAgICAgICAgaWYgKHAuaGFzQ3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgdG9EaXNwb3NlLnB1c2goe1xuICAgICAgICAgICAgdHlwZTogXCJob29rX2Rpc3Bvc2VcIixcbiAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHAuY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgIGhhc0NyZWF0ZWRFdmVudDogZmFsc2UsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICB0b0Rpc3Bvc2UuZm9yRWFjaChmdW5jdGlvbihkKXsgZ2xvYmFsVGhpcy5fX3BlbmRpbmcucHVzaChkKTsgfSk7XG4gICAgcmV0dXJuIGdsb2JhbFRoaXMuX19wZW5kaW5nLmZpbHRlcihmdW5jdGlvbihwKXtcbiAgICAgIGlmIChwLmFib3J0UmVxdWVzdGVkKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGlmIChwLmhhc0NyZWF0ZWRFdmVudCkgcmV0dXJuIGZhbHNlO1xuICAgICAgLy8gU2tpcCBzeXN0ZW0gaG9va3MgdGhhdCB3ZXJlIGRpc3Bvc2VkIGJlZm9yZSBldmVyIGJlaW5nIGNyZWF0ZWQuXG4gICAgICBpZiAocC50eXBlID09PSBcImhvb2tcIiAmJiBwLmRpc3Bvc2VkKSByZXR1cm4gZmFsc2U7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcbiAgfSkoKWAsXG4gICAgZW5zdXJlUGVuZGluZ0J5dGVDYWNoZSh2bSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tXb3JrZmxvd1N0YXRlKFxuICB2bTogUXVpY2tKUyxcbiAgc2VyZGU6IFF1aWNrSlNTZXJkZSxcbiAgb3B0czogeyBrZWVwQWxpdmVPblN1c3BlbmQ/OiBib29sZWFuIH0gPSB7fVxuKTogUXVpY2tKU1J1bnRpbWVSZXN1bHQge1xuICAvLyBDaGVjayBjb21wbGV0ZWQg4oCUIF9fd29ya2Zsb3dSZXN1bHQgaG9sZHMgdGhlIFJBVyByZXR1cm4gdmFsdWUgKHdpdGggYVxuICAvLyBzZXBhcmF0ZSBkb25lIGZsYWcgc28gYHVuZGVmaW5lZGAgcmVzdWx0cyBhcmUgZGlzdGluZ3Vpc2hhYmxlKTsgdGhlXG4gIC8vIGhvc3Qgc2VyaWFsaXplcyBpdCB0aHJvdWdoIGEgaGFuZGxlLlxuICB7XG4gICAgdXNpbmcgZG9uZSA9IHZtLmV2YWxDb2RlKCdnbG9iYWxUaGlzLl9fd29ya2Zsb3dEb25lID09PSB0cnVlJyk7XG4gICAgaWYgKGRvbmUudG9Cb29sZWFuKCkpIHtcbiAgICAgIHVzaW5nIGggPSB2bS5ldmFsQ29kZSgnZ2xvYmFsVGhpcy5fX3dvcmtmbG93UmVzdWx0Jyk7XG4gICAgICBjb25zdCByZXN1bHRCeXRlcyA9IHNlcmRlLnNlcmlhbGl6ZShoKTtcbiAgICAgIGNvbnN0IGRyYWluT3BlcmF0aW9ucyA9IGNvbGxlY3REcmFpbk9wZXJhdGlvbnModm0sIHNlcmRlKTtcbiAgICAgIHZtLmRpc3Bvc2UoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbXBsZXRlZDoge1xuICAgICAgICAgIHJlc3VsdDogcmVzdWx0Qnl0ZXMsXG4gICAgICAgICAgLi4uKGRyYWluT3BlcmF0aW9ucy5sZW5ndGggPiAwID8geyBkcmFpbk9wZXJhdGlvbnMgfSA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgZmFpbGVkXG4gIHtcbiAgICB1c2luZyBoID0gdm0uZXZhbENvZGUoJ2dsb2JhbFRoaXMuX193b3JrZmxvd0Vycm9yJyk7XG4gICAgaWYgKCFoLmlzVW5kZWZpbmVkKSB7XG4gICAgICAvLyBUaGUgZGlzcGxheSBmaWVsZHMgYXJlIHBsYWluIHN0cmluZ3M7IHRoZSB0aHJvd24gdmFsdWUgaXRzZWxmIGlzXG4gICAgICAvLyBSQVcgYW5kIHNlcmlhbGl6ZWQgaG9zdC1zaWRlIHRocm91Z2ggYSBoYW5kbGUuXG4gICAgICBjb25zdCBlcnJvck9iaiA9IGguaXNTdHJpbmdcbiAgICAgICAgPyAoaC50b1N0cmluZygpIGFzIHN0cmluZylcbiAgICAgICAgOiAoKCkgPT4ge1xuICAgICAgICAgICAgdXNpbmcgcGxhaW4gPSB2bS5ldmFsQ29kZShcbiAgICAgICAgICAgICAgJyhmdW5jdGlvbihlKXtyZXR1cm4ge21lc3NhZ2U6IGUubWVzc2FnZSwgc3RhY2s6IGUuc3RhY2ssIG5hbWU6IGUubmFtZX07fSkoZ2xvYmFsVGhpcy5fX3dvcmtmbG93RXJyb3IpJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiB2bS5kdW1wKHBsYWluKSBhcyB7XG4gICAgICAgICAgICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICAgICAgICAgICAgc3RhY2s/OiBzdHJpbmc7XG4gICAgICAgICAgICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKCk7XG4gICAgICBsZXQgdmFsdWVCeXRlczogVWludDhBcnJheSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICghaC5pc1N0cmluZykge1xuICAgICAgICB1c2luZyByYXdWYWx1ZSA9IGguZ2V0UHJvcCgndmFsdWUnKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB2YWx1ZUJ5dGVzID0gc2VyZGUuc2VyaWFsaXplKHJhd1ZhbHVlKTtcbiAgICAgICAgfSBjYXRjaCAoc2VyaWFsaXplRXJyKSB7XG4gICAgICAgICAgLy8gQSB0aHJvd24gdmFsdWUgdGhlIGNvZGVjIGNhbm5vdCBzZXJpYWxpemUgbXVzdCBub3QgbWFzayB0aGVcbiAgICAgICAgICAvLyB3b3JrZmxvdyBmYWlsdXJlIGl0c2VsZiDigJQgZmFsbCBiYWNrIHRvIHRoZSBkaXNwbGF5IGZpZWxkcy5cbiAgICAgICAgICBydW50aW1lTG9nZ2VyLndhcm4oXG4gICAgICAgICAgICAnUXVpY2tKUyBydW50aW1lOiBmYWlsZWQgdG8gc2VyaWFsaXplIHRocm93biB3b3JrZmxvdyBlcnJvcicsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgICAgICAgc2VyaWFsaXplRXJyIGluc3RhbmNlb2YgRXJyb3JcbiAgICAgICAgICAgICAgICAgID8gc2VyaWFsaXplRXJyLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgIDogU3RyaW5nKHNlcmlhbGl6ZUVyciksXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgZmFpbGVkID1cbiAgICAgICAgdHlwZW9mIGVycm9yT2JqID09PSAnc3RyaW5nJ1xuICAgICAgICAgID8geyBtZXNzYWdlOiBlcnJvck9iaiB9XG4gICAgICAgICAgOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yT2JqLm1lc3NhZ2UsXG4gICAgICAgICAgICAgIHN0YWNrOiBlcnJvck9iai5zdGFjayB8fCB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIG5hbWU6IGVycm9yT2JqLm5hbWUgfHwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB2YWx1ZUJ5dGVzLFxuICAgICAgICAgICAgfTtcbiAgICAgIHJ1bnRpbWVMb2dnZXIuZXJyb3IoJ1F1aWNrSlMgcnVudGltZTogd29ya2Zsb3cgZmFpbGVkIGluIFZNJywge1xuICAgICAgICBlcnJvck1lc3NhZ2U6IGZhaWxlZC5tZXNzYWdlLFxuICAgICAgICBlcnJvck5hbWU6IGZhaWxlZC5uYW1lLFxuICAgICAgICBlcnJvclN0YWNrOiBmYWlsZWQuc3RhY2ssXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGRyYWluT3BlcmF0aW9ucyA9IGNvbGxlY3REcmFpbk9wZXJhdGlvbnModm0sIHNlcmRlKTtcbiAgICAgIHZtLmRpc3Bvc2UoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGZhaWxlZDoge1xuICAgICAgICAgIC4uLmZhaWxlZCxcbiAgICAgICAgICAuLi4oZHJhaW5PcGVyYXRpb25zLmxlbmd0aCA+IDAgPyB7IGRyYWluT3BlcmF0aW9ucyB9IDoge30pLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvLyBDaGVjayBzdXNwZW5kZWQg4oCUIHRoZSB3b3JrZmxvdyBpcyBzdXNwZW5kZWQgaWYgdGhlcmUgYXJlIGFjdGl2ZSByZXNvbHZlcnNcbiAgLy8gT1IgcGVuZGluZyBvcGVyYXRpb25zIHRoYXQgaGF2ZW4ndCBiZWVuIGNyZWF0ZWQgeWV0IChlLmcuIGhvb2tzIGNyZWF0ZWRcbiAgLy8gdXBmcm9udCBidXQgbm90IHlldCBhd2FpdGVkKVxuICB7XG4gICAgdXNpbmcgaCA9IHZtLmV2YWxDb2RlKFxuICAgICAgJ09iamVjdC5rZXlzKGdsb2JhbFRoaXMuX19yZXNvbHZlcnMpLmxlbmd0aCA+IDAgfHwgZ2xvYmFsVGhpcy5fX3BlbmRpbmcuc29tZShmdW5jdGlvbihwKXtyZXR1cm4hcC5oYXNDcmVhdGVkRXZlbnQ7fSknXG4gICAgKTtcbiAgICBpZiAodm0uZHVtcChoKSkge1xuICAgICAgLy8gT3BzIHdpdGggYW4gYWN0aXZlIHJlc29sdmVyIG9yIHdpdGhvdXQgYSBjcmVhdGVkIGV2ZW50IGFyZVxuICAgICAgLy8gcGVuZGluZzsgYWJvcnQtcmVxdWVzdGVkIGhvb2tzIGFyZSBhbHNvIHN1cmZhY2VkIChldmVuIHdoZW5cbiAgICAgIC8vIGFscmVhZHkgY3JlYXRlZCBhbmQgdW5hd2FpdGVkKSBzbyB0aGUgaG9zdCByZWNvcmRzIHRoZSBhYm9ydC5cbiAgICAgIGNvbnN0IHBlbmRpbmdPcHMgPSBkdW1wUGVuZGluZ09wcyhcbiAgICAgICAgdm0sXG4gICAgICAgIHNlcmRlLFxuICAgICAgICBgZ2xvYmFsVGhpcy5fX3BlbmRpbmcuZmlsdGVyKGZ1bmN0aW9uKHApe3JldHVybiEhZ2xvYmFsVGhpcy5fX3Jlc29sdmVyc1twLmNvcnJlbGF0aW9uSWRdIHx8ICFwLmhhc0NyZWF0ZWRFdmVudCB8fCBwLmFib3J0UmVxdWVzdGVkO30pYCxcbiAgICAgICAgZW5zdXJlUGVuZGluZ0J5dGVDYWNoZSh2bSlcbiAgICAgICk7XG4gICAgICBpZiAoIW9wdHMua2VlcEFsaXZlT25TdXNwZW5kKSB2bS5kaXNwb3NlKCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1c3BlbmRlZDoge1xuICAgICAgICAgIHBlbmRpbmdPcGVyYXRpb25zOiBwZW5kaW5nT3BzLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICB2bS5kaXNwb3NlKCk7XG4gIHJldHVybiB7IGZhaWxlZDogeyBtZXNzYWdlOiAnV29ya2Zsb3cgZW5kZWQgaW4gdW5rbm93biBzdGF0ZScgfSB9O1xufVxuXG4vLyAtLS0tIEhlbHBlcnMgLS0tLVxuXG5mdW5jdGlvbiBleHRyYWN0RXJyb3IoXG4gIHZtOiBRdWlja0pTLFxuICBlcnI6IHVua25vd24sXG4gIGZhbGxiYWNrTWVzc2FnZTogc3RyaW5nXG4pOiBRdWlja0pTUnVudGltZVJlc3VsdCB7XG4gIGxldCBtZXNzYWdlID0gZmFsbGJhY2tNZXNzYWdlO1xuICBsZXQgc3RhY2s6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgbGV0IG5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICBpZiAoZXJyIGluc3RhbmNlb2YgSlNFeGNlcHRpb24pIHtcbiAgICBjb25zdCBlcnJvciA9IHZtLmR1bXAoZXJyLmhhbmRsZSkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBudWxsO1xuICAgIGVyci5oYW5kbGUuZGlzcG9zZSgpO1xuICAgIG1lc3NhZ2UgPSAoZXJyb3I/Lm1lc3NhZ2UgYXMgc3RyaW5nKSA/PyBlcnIubWVzc2FnZSA/PyBmYWxsYmFja01lc3NhZ2U7XG4gICAgc3RhY2sgPSAoZXJyb3I/LnN0YWNrIGFzIHN0cmluZykgPz8gZXJyLnN0YWNrO1xuICAgIG5hbWUgPSAoZXJyb3I/Lm5hbWUgYXMgc3RyaW5nKSA/PyBlcnIubmFtZTtcbiAgfSBlbHNlIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgIG1lc3NhZ2UgPSBlcnIubWVzc2FnZSA/PyBmYWxsYmFja01lc3NhZ2U7XG4gICAgc3RhY2sgPSBlcnIuc3RhY2s7XG4gICAgbmFtZSA9IGVyci5uYW1lO1xuICB9XG5cbiAgdm0uZGlzcG9zZSgpO1xuICByZXR1cm4ge1xuICAgIGZhaWxlZDogeyBtZXNzYWdlLCBzdGFjaywgbmFtZSB9LFxuICB9O1xufVxuXG4vKipcbiAqIE11dGFibGUgaW50ZXJydXB0IGJ1ZGdldCBmb3IgYSBWTS4gUXVpY2tKUyBwb2xscyB0aGUgaW50ZXJydXB0IGhhbmRsZXJcbiAqIGR1cmluZyBKUyBleGVjdXRpb247IHdoZW4gaXQgcmV0dXJucyB0cnVlLCBleGVjdXRpb24gYWJvcnRzLiBUaGUgYnVkZ2V0XG4gKiBib3VuZHMgYSBzaW5nbGUgaG9zdC0+Vk0gZXhlY3V0aW9uIGJ1cnN0IChidW5kbGUgZXZhbCArIGV2ZW50XG4gKiBwcm9jZXNzaW5nKSwgbm90IHRvdGFsIFZNIGxpZmV0aW1lIOKAlCB0aGUgaW5saW5lLXN0ZXAgbG9vcCBrZWVwcyBhIFZNXG4gKiBhbGl2ZSBhY3Jvc3Mgc3RlcCBleGVjdXRpb25zIHRoYXQgY2FuIGxlZ2l0aW1hdGVseSB0YWtlIG1pbnV0ZXMsIHNvIHRoZVxuICogaG9zdCByZXNldHMgdGhlIGJ1ZGdldCBiZWZvcmUgZWFjaCByZS1lbnRyeSAoc2VlIHJlc2V0QnVkZ2V0IGNhbGxzKS5cbiAqXG4gKiBUaGUgcGVyLWJ1cnN0IGNlaWxpbmcgaXMgdGhlIHNhbWUgY29uZmlndXJhYmxlIGJ1ZGdldCBhcyB0aGUgbm9kZVxuICogZW5naW5lJ3MgUmVwbGF5QnVkZ2V0IChSRVBMQVlfVElNRU9VVF9NUywgZGVmYXVsdCAyNDBzKTogYSB3b3JrZmxvd1xuICogd2hvc2UgcmVwbGF5IHRoZSBub2RlIGVuZ2luZSBoYW5kbGVzIGZpbmUgbXVzdCBub3QgYmUgaW50ZXJydXB0ZWQgaGVyZVxuICogYnkgYSBsb3dlciBoYXJkY29kZWQgY2VpbGluZy4gVGhlIGludGVycnVwdCBlcnJvciBlc2NhcGVzXG4gKiBydW5RdWlja0pTV29ya2Zsb3cgYW5kIHJlYWNoZXMgdGhlIHJlcGxheSBsb29wJ3MgY2F0Y2ggaW4gcnVudGltZS50cyxcbiAqIHdoaWNoIHJlY29yZHMgcnVuX2ZhaWxlZC5cbiAqL1xuaW50ZXJmYWNlIEludGVycnVwdEJ1ZGdldCB7XG4gIHN0YXJ0OiBudW1iZXI7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUludGVycnVwdEhhbmRsZXIoYnVkZ2V0OiBJbnRlcnJ1cHRCdWRnZXQpOiAoKSA9PiBib29sZWFuIHtcbiAgY29uc3QgdGltZW91dCA9IGdldFJlcGxheVRpbWVvdXRNcygpO1xuICByZXR1cm4gKCkgPT4gRGF0ZS5ub3coKSAtIGJ1ZGdldC5zdGFydCA+IHRpbWVvdXQ7XG59XG4iXX0=