obsidian-integration-testing 8.2.1 → 8.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/lib/cjs/asar-fallback-detection.cjs +48 -0
  2. package/dist/lib/cjs/asar-fallback-detection.d.cts +75 -0
  3. package/dist/lib/cjs/compatibility-options.cjs +68 -0
  4. package/dist/lib/cjs/compatibility-options.d.cts +112 -0
  5. package/dist/lib/cjs/connect-to-cdp.cjs +19 -11
  6. package/dist/lib/cjs/connect-to-cdp.d.cts +64 -2
  7. package/dist/lib/cjs/ecmascript-version.cjs +63 -0
  8. package/dist/lib/cjs/ecmascript-version.d.cts +28 -0
  9. package/dist/lib/cjs/electron-compatibility.cjs +46 -0
  10. package/dist/lib/cjs/electron-compatibility.d.cts +74 -0
  11. package/dist/lib/cjs/index.cjs +10 -1
  12. package/dist/lib/cjs/index.d.cts +7 -1
  13. package/dist/lib/cjs/installer-asset.cjs +18 -3
  14. package/dist/lib/cjs/installer-asset.d.cts +26 -0
  15. package/dist/lib/cjs/installer-compatibility.cjs +1 -1
  16. package/dist/lib/cjs/installer-compatibility.d.cts +4 -1
  17. package/dist/lib/cjs/library.cjs +1 -1
  18. package/dist/lib/cjs/namespace-bootstrap.cjs +44 -7
  19. package/dist/lib/cjs/normalize-optional-properties.cjs +31 -0
  20. package/dist/lib/cjs/normalize-optional-properties.d.cts +26 -0
  21. package/dist/lib/cjs/obsidian-installer.cjs +6 -1
  22. package/dist/lib/cjs/obsidian-metadata.cjs +3775 -302
  23. package/dist/lib/cjs/obsidian-metadata.d.cts +71 -0
  24. package/dist/lib/cjs/obsidian-version-switch.cjs +5 -2
  25. package/dist/lib/cjs/owned-vault-seed.cjs +38 -0
  26. package/dist/lib/cjs/owned-vault-seed.d.cts +67 -0
  27. package/dist/lib/cjs/silent-asar-fallback-error.cjs +48 -0
  28. package/dist/lib/cjs/silent-asar-fallback-error.d.cts +40 -0
  29. package/dist/lib/cjs/transport-desktop-cdp.cjs +223 -45
  30. package/dist/lib/cjs/transport-desktop-cdp.d.cts +105 -1
  31. package/dist/lib/cjs/transport-factory.cjs +36 -16
  32. package/dist/lib/cjs/transport-options.cjs +1 -1
  33. package/dist/lib/cjs/transport-options.d.cts +48 -0
  34. package/dist/lib/esm/asar-fallback-detection.d.mts +75 -0
  35. package/dist/lib/esm/asar-fallback-detection.mjs +24 -0
  36. package/dist/lib/esm/compatibility-options.d.mts +112 -0
  37. package/dist/lib/esm/compatibility-options.mjs +40 -0
  38. package/dist/lib/esm/connect-to-cdp.d.mts +64 -2
  39. package/dist/lib/esm/connect-to-cdp.mjs +19 -11
  40. package/dist/lib/esm/ecmascript-version.d.mts +28 -0
  41. package/dist/lib/esm/ecmascript-version.mjs +39 -0
  42. package/dist/lib/esm/electron-compatibility.d.mts +74 -0
  43. package/dist/lib/esm/electron-compatibility.mjs +22 -0
  44. package/dist/lib/esm/index.d.mts +7 -1
  45. package/dist/lib/esm/index.mjs +7 -1
  46. package/dist/lib/esm/installer-asset.d.mts +26 -0
  47. package/dist/lib/esm/installer-asset.mjs +16 -2
  48. package/dist/lib/esm/installer-compatibility.d.mts +4 -1
  49. package/dist/lib/esm/installer-compatibility.mjs +1 -1
  50. package/dist/lib/esm/library.mjs +1 -1
  51. package/dist/lib/esm/namespace-bootstrap.mjs +44 -7
  52. package/dist/lib/esm/normalize-optional-properties.d.mts +26 -0
  53. package/dist/lib/esm/normalize-optional-properties.mjs +7 -0
  54. package/dist/lib/esm/obsidian-installer.mjs +8 -2
  55. package/dist/lib/esm/obsidian-metadata.d.mts +71 -0
  56. package/dist/lib/esm/obsidian-metadata.mjs +3775 -302
  57. package/dist/lib/esm/obsidian-version-switch.mjs +5 -2
  58. package/dist/lib/esm/owned-vault-seed.d.mts +67 -0
  59. package/dist/lib/esm/owned-vault-seed.mjs +14 -0
  60. package/dist/lib/esm/silent-asar-fallback-error.d.mts +40 -0
  61. package/dist/lib/esm/silent-asar-fallback-error.mjs +24 -0
  62. package/dist/lib/esm/transport-desktop-cdp.d.mts +105 -1
  63. package/dist/lib/esm/transport-desktop-cdp.mjs +223 -45
  64. package/dist/lib/esm/transport-factory.mjs +41 -16
  65. package/dist/lib/esm/transport-options.d.mts +48 -0
  66. package/dist/obsidian-integration-testing-8.4.0.tgz +0 -0
  67. package/package.json +3 -1
  68. package/dist/obsidian-integration-testing-8.2.1.tgz +0 -0
@@ -35,16 +35,22 @@ var import_node_crypto = require("node:crypto");
35
35
  var import_node_fs = require("node:fs");
36
36
  var import_node_path = require("node:path");
37
37
  var import_node_process = __toESM(require("node:process"), 1);
38
+ var import_asar_fallback_detection = require("./asar-fallback-detection.cjs");
39
+ var import_compatibility_options = require("./compatibility-options.cjs");
38
40
  var import_dismiss_trust_dialog = require("./dismiss-trust-dialog.cjs");
41
+ var import_electron_compatibility = require("./electron-compatibility.cjs");
39
42
  var import_exec = require("./exec.cjs");
40
43
  var import_log = require("./log.cjs");
41
44
  var import_namespace_bootstrap = require("./namespace-bootstrap.cjs");
42
45
  var import_obsidian_config = require("./obsidian-config.cjs");
43
46
  var import_obsidian_executable = require("./obsidian-executable.cjs");
44
47
  var import_obsidian_instance = require("./obsidian-instance.cjs");
48
+ var import_obsidian_metadata = require("./obsidian-metadata.cjs");
45
49
  var import_obsidian_version_switch = require("./obsidian-version-switch.cjs");
50
+ var import_owned_vault_seed = require("./owned-vault-seed.cjs");
46
51
  var import_renderer_boot_detection = require("./renderer-boot-detection.cjs");
47
52
  var import_renderer_failed_to_initialize_error = require("./renderer-failed-to-initialize-error.cjs");
53
+ var import_silent_asar_fallback_error = require("./silent-asar-fallback-error.cjs");
48
54
  var import_type_guards = require("./type-guards.cjs");
49
55
  var import_visibility = require("./visibility.cjs");
50
56
  const COMMAND_TIMEOUT_IN_MILLISECONDS = 3e4;
@@ -54,6 +60,8 @@ const USER_DATA_RM_RETRY_INTERVAL_IN_MILLISECONDS = 500;
54
60
  const NO_OUTPUT = "(no output)";
55
61
  const VAULT_POLL_INTERVAL_IN_MILLISECONDS = 500;
56
62
  const VAULT_POLL_TIMEOUT_IN_MILLISECONDS = 3e4;
63
+ const OWNED_LAUNCH_MAX_ATTEMPTS = 3;
64
+ const OWNED_RELAUNCH_SETTLE_IN_MILLISECONDS = 3e3;
57
65
  const VAULT_CLOSE_DELAY_IN_MILLISECONDS = 1e3;
58
66
  const AUTO_START_POLL_INTERVAL_IN_MILLISECONDS = 2e3;
59
67
  const AUTO_START_TIMEOUT_IN_MILLISECONDS = 3e4;
@@ -67,17 +75,21 @@ class DesktopCdpTransport {
67
75
  */
68
76
  isMobile = false;
69
77
  activeVaultPath = null;
78
+ asarFallback;
70
79
  cdpHost;
71
80
  cdpPort;
72
81
  cdpUrl;
73
82
  commandTimeoutInMilliseconds;
74
83
  deadBootGraceInMilliseconds;
84
+ electronCompatibility;
75
85
  isHarnessOwnedInstance;
76
86
  isObsidianAppVisible;
77
87
  messageId = 0;
78
88
  ownedConfig;
79
89
  ownedInstance;
80
90
  shouldDisableSandbox;
91
+ shouldThrowOnSilentAsarFallback;
92
+ shouldWarnOnCompatibilityIssues;
81
93
  ws = null;
82
94
  /**
83
95
  * Creates a new CDP transport.
@@ -85,15 +97,29 @@ class DesktopCdpTransport {
85
97
  * @param config - CDP connection configuration.
86
98
  */
87
99
  constructor(config) {
88
- this.cdpHost = config?.cdpHost ?? "localhost";
89
- this.commandTimeoutInMilliseconds = config?.commandTimeoutInMilliseconds ?? COMMAND_TIMEOUT_IN_MILLISECONDS;
90
- this.deadBootGraceInMilliseconds = config?.deadBootGraceInMilliseconds ?? import_renderer_boot_detection.DEFAULT_DEAD_BOOT_GRACE_IN_MILLISECONDS;
91
- this.isHarnessOwnedInstance = config?.isHarnessOwnedInstance ?? false;
92
- this.isObsidianAppVisible = config?.isObsidianAppVisible ?? true;
93
- this.ownedConfig = config?.ownedInstance;
94
- this.shouldDisableSandbox = config?.shouldDisableSandbox ?? false;
95
- this.cdpPort = config?.cdpPort ?? 0;
96
- this.cdpUrl = config?.cdpPort === void 0 ? "" : `http://${this.cdpHost}:${String(config.cdpPort)}`;
100
+ const {
101
+ cdpHost = "localhost",
102
+ cdpPort,
103
+ commandTimeoutInMilliseconds = COMMAND_TIMEOUT_IN_MILLISECONDS,
104
+ deadBootGraceInMilliseconds = import_renderer_boot_detection.DEFAULT_DEAD_BOOT_GRACE_IN_MILLISECONDS,
105
+ isHarnessOwnedInstance = false,
106
+ isObsidianAppVisible = true,
107
+ ownedInstance,
108
+ shouldDisableSandbox = false,
109
+ shouldThrowOnSilentAsarFallback = true,
110
+ shouldWarnOnCompatibilityIssues = true
111
+ } = config ?? {};
112
+ this.cdpHost = cdpHost;
113
+ this.commandTimeoutInMilliseconds = commandTimeoutInMilliseconds;
114
+ this.deadBootGraceInMilliseconds = deadBootGraceInMilliseconds;
115
+ this.isHarnessOwnedInstance = isHarnessOwnedInstance;
116
+ this.isObsidianAppVisible = isObsidianAppVisible;
117
+ this.ownedConfig = ownedInstance;
118
+ this.shouldDisableSandbox = shouldDisableSandbox;
119
+ this.shouldThrowOnSilentAsarFallback = shouldThrowOnSilentAsarFallback;
120
+ this.shouldWarnOnCompatibilityIssues = shouldWarnOnCompatibilityIssues;
121
+ this.cdpPort = cdpPort ?? 0;
122
+ this.cdpUrl = cdpPort === void 0 ? "" : `http://${cdpHost}:${String(cdpPort)}`;
97
123
  }
98
124
  /**
99
125
  * Disposes of the active WebSocket connection and, in owned-instance mode,
@@ -160,6 +186,21 @@ class DesktopCdpTransport {
160
186
  }
161
187
  return String(resultObj.value);
162
188
  }
189
+ /**
190
+ * Returns the silent-asar-fallback verdict for this owned instance — whether the
191
+ * app version it is actually running matches the swapped-in pin, or the installer
192
+ * silently reverted to its own bundled asar (read live post-boot). Returns
193
+ * `undefined` when this is not an owned instance, the instance has not booted
194
+ * yet, or the verdict could not be determined (no asar was swapped, or the live
195
+ * version was unreadable). A `'fallback'` verdict reaches this surface only when
196
+ * the throw is disabled ({@link DesktopCdpTransportConfig.shouldThrowOnSilentAsarFallback}
197
+ * `false`); otherwise it throws `SilentAsarFallbackError`.
198
+ *
199
+ * @returns The silent-asar-fallback verdict, or `undefined`.
200
+ */
201
+ getAsarFallback() {
202
+ return this.asarFallback;
203
+ }
163
204
  /**
164
205
  * Returns the resolved installer↔app compatibility verdict for this owned
165
206
  * instance, so callers can assert on it. Returns `undefined` when this is not
@@ -171,6 +212,19 @@ class DesktopCdpTransport {
171
212
  getCompatibility() {
172
213
  return this.ownedConfig?.compatibility;
173
214
  }
215
+ /**
216
+ * Returns the runtime Electron compatibility verdict for this owned instance —
217
+ * whether the Electron version it is actually running is new enough for the
218
+ * running app version (read live post-boot; see {@link ObsidianVersionMetadata.minRecommendedElectronVersion}).
219
+ * Returns `undefined` when this is not an owned instance, the instance has not
220
+ * booted yet, or the verdict could not be determined (the live version was
221
+ * unreadable, or the app version carries no recommended Electron version).
222
+ *
223
+ * @returns The runtime Electron compatibility verdict, or `undefined`.
224
+ */
225
+ getElectronCompatibility() {
226
+ return this.electronCompatibility;
227
+ }
174
228
  /**
175
229
  * Returns the CDP endpoint of the owned, launched instance so the global setup
176
230
  * can hand it to test workers (which then **attach** to it instead of
@@ -276,6 +330,92 @@ class DesktopCdpTransport {
276
330
  (0, import_obsidian_config.removeVaultFromConfig)(vaultPath);
277
331
  }
278
332
  }
333
+ /**
334
+ * Computes and stores the runtime-Electron compatibility verdict (on
335
+ * {@link getElectronCompatibility}) from an already-read version pair, warning
336
+ * when the live Electron is below the app's recommended minimum. Never throws; a
337
+ * boot whose running app version was unreadable is skipped (nothing to judge).
338
+ *
339
+ * @param appVersion - The live running app version, or `undefined` when unreadable.
340
+ * @param actualElectronVersion - The live Electron version, or `undefined` when unreadable.
341
+ */
342
+ applyElectronCompatibility(appVersion, actualElectronVersion) {
343
+ if (appVersion === void 0) {
344
+ return;
345
+ }
346
+ const verdict = (0, import_electron_compatibility.checkElectronCompatibility)({
347
+ actualElectronVersion,
348
+ appVersion,
349
+ metadata: (0, import_obsidian_metadata.getVersionMetadata)(appVersion)
350
+ });
351
+ this.electronCompatibility = verdict;
352
+ if (verdict.tier === "nagged" && this.shouldWarnOnCompatibilityIssues) {
353
+ (0, import_log.log)(`[cdp-transport] ${(0, import_type_guards.ensureNonNullable)(verdict.message)}`);
354
+ }
355
+ }
356
+ /**
357
+ * Verifies the running app (asar) version matches the swapped-in pin, storing the
358
+ * verdict on {@link getAsarFallback}. On a **silent fallback** (the installer ran
359
+ * its own bundled asar instead of the pin) it throws {@link SilentAsarFallbackError}
360
+ * when the throw is enabled, otherwise warns (when warnings are on) and lets the
361
+ * boot proceed. A boot with no swapped-in asar, or an unreadable running version,
362
+ * is `'unknown'` — nothing is thrown or warned. This is the healthy-UI companion to
363
+ * the black-screen {@link RendererFailedToInitializeError} dead-boot fast-fail.
364
+ *
365
+ * @param runningApiVersion - The live running app version, or `undefined` when unreadable.
366
+ */
367
+ checkRuntimeAsarFallback(runningApiVersion) {
368
+ const verdict = (0, import_asar_fallback_detection.checkAsarFallback)({
369
+ requestedVersion: this.ownedConfig?.asar?.version,
370
+ runningApiVersion
371
+ });
372
+ this.asarFallback = verdict;
373
+ const action = (0, import_compatibility_options.resolveAsarFallbackAction)({
374
+ shouldThrowOnSilentAsarFallback: this.shouldThrowOnSilentAsarFallback,
375
+ shouldWarnOnCompatibilityIssues: this.shouldWarnOnCompatibilityIssues,
376
+ tier: verdict.tier
377
+ });
378
+ if (action === "throw") {
379
+ throw new import_silent_asar_fallback_error.SilentAsarFallbackError({
380
+ requestedVersion: (0, import_type_guards.ensureNonNullable)(verdict.requestedVersion),
381
+ runningApiVersion: (0, import_type_guards.ensureNonNullable)(verdict.runningApiVersion)
382
+ });
383
+ }
384
+ if (action === "warn") {
385
+ (0, import_log.log)(`[cdp-transport] ${(0, import_type_guards.ensureNonNullable)(verdict.message)}`);
386
+ }
387
+ }
388
+ /**
389
+ * Runs the post-boot runtime compatibility checks for an owned instance, once the
390
+ * vault is ready. Reads the live running app version and Electron version **once**
391
+ * from the booted renderer's main process, then: (1) verifies the running app
392
+ * version matches the swapped-in pin — throwing {@link SilentAsarFallbackError} on
393
+ * a silent fallback (when enabled); and (2) runs the best-effort runtime-Electron
394
+ * nag. Only the asar-fallback check can throw, so this must run outside the
395
+ * readiness poll's try/catch (a swallowed throw would loop until timeout).
396
+ *
397
+ * Both are read at the renderer top level: `ipcRenderer.sendSync('version')` (the
398
+ * running app version, truthful even under a silent asar fallback) and
399
+ * `process.versions.electron` (the live shell Electron); neither uses
400
+ * `require('obsidian')`, which resolves only inside a plugin-load context. A read
401
+ * failure leaves both unknown (logged, non-fatal) — an unreadable running version
402
+ * cannot be judged a fallback, so the boot is not broken by a flaky read.
403
+ *
404
+ * @param vaultPath - The vault path to evaluate in.
405
+ */
406
+ async checkRuntimeCompatibility(vaultPath) {
407
+ let appVersion;
408
+ let actualElectronVersion;
409
+ try {
410
+ const rawAppVersion = await this.evaluate("String(window.electron.ipcRenderer.sendSync('version'))", { cwd: vaultPath });
411
+ appVersion = rawAppVersion === "" || rawAppVersion === "undefined" ? void 0 : rawAppVersion;
412
+ actualElectronVersion = await this.evaluate("String(process.versions.electron)", { cwd: vaultPath });
413
+ } catch (error) {
414
+ (0, import_log.log)(`[cdp-transport] Could not read runtime versions (non-fatal): ${String(error)}`);
415
+ }
416
+ this.checkRuntimeAsarFallback(appVersion);
417
+ this.applyElectronCompatibility(appVersion, actualElectronVersion);
418
+ }
279
419
  /**
280
420
  * Connects to a CDP target's WebSocket endpoint.
281
421
  *
@@ -425,6 +565,27 @@ class DesktopCdpTransport {
425
565
  const targets = await response.json();
426
566
  return targets.filter((t) => t.type === "page");
427
567
  }
568
+ /**
569
+ * Kills the currently-running owned instance (if any) and waits for it to exit,
570
+ * so the next launch gets a pristine single-window instance.
571
+ *
572
+ * Relaunching over a live instance is forwarded by Electron's single-instance
573
+ * lock on the shared user-data dir and surfaces the vault picker, and opening a
574
+ * second window via IPC leaves stale windows that break vault-target routing —
575
+ * hence a full kill + wait-for-exit (releasing the lock) between launches. A
576
+ * no-op on the first attempt, when no instance is running yet.
577
+ */
578
+ async killRunningOwnedInstance() {
579
+ if (!this.ownedInstance) {
580
+ return;
581
+ }
582
+ (0, import_log.log)("[cdp-transport] Killing running owned instance before (re)launch.");
583
+ this.disconnect();
584
+ const previousCdpUrl = this.cdpUrl;
585
+ this.ownedInstance.kill();
586
+ this.ownedInstance = void 0;
587
+ await this.waitForInstanceExit(previousCdpUrl);
588
+ }
428
589
  /**
429
590
  * Moves the owned instance's window off-screen so a hidden run never steals
430
591
  * focus. Uses Electron's remote bridge (`window.electron.remote`) — the only
@@ -440,8 +601,13 @@ class DesktopCdpTransport {
440
601
  */
441
602
  async moveOwnedWindowOffscreen() {
442
603
  const moveExpr = `(() => {
443
- const remote = window.electron && window.electron.remote;
444
- if (!remote || typeof remote.getCurrentWindow !== 'function') { return 'no-bridge'; }
604
+ let remote = (window.electron && window.electron.remote) || null;
605
+ if (!remote) {
606
+ try { remote = require('electron').remote || null; } catch (requireError) { remote = null; }
607
+ }
608
+ if (!remote || typeof remote.getCurrentWindow !== 'function') {
609
+ return (typeof window.app === 'undefined') ? 'not-ready' : 'no-bridge';
610
+ }
445
611
  const win = remote.getCurrentWindow();
446
612
  const displays = remote.screen.getAllDisplays();
447
613
  const maxRight = Math.max(...displays.map((display) => display.bounds.x + display.bounds.width));
@@ -571,7 +737,9 @@ class DesktopCdpTransport {
571
737
  const ws = await this.connectToTarget(target);
572
738
  try {
573
739
  const response = await this.sendCommand(ws, "Runtime.evaluate", {
574
- expression: "app.vault.adapter.getBasePath()",
740
+ // Old Obsidian versions (e.g. 0.6.x) predate the `getBasePath()` method but
741
+ // Expose the `basePath` property; the method exists from ~0.9.20 onward.
742
+ expression: "app.vault.adapter.getBasePath ? app.vault.adapter.getBasePath() : app.vault.adapter.basePath",
575
743
  returnByValue: true
576
744
  });
577
745
  return String(response.result?.result?.value);
@@ -589,42 +757,46 @@ class DesktopCdpTransport {
589
757
  */
590
758
  async registerVaultInOwnedInstance(vaultPath) {
591
759
  const config = (0, import_type_guards.ensureNonNullable)(this.ownedConfig);
592
- if (this.ownedInstance) {
593
- (0, import_log.log)(`[cdp-transport] Relaunching owned instance for new vault: ${vaultPath}`);
594
- this.disconnect();
595
- const previousCdpUrl = this.cdpUrl;
596
- this.ownedInstance.kill();
597
- this.ownedInstance = void 0;
598
- await this.waitForInstanceExit(previousCdpUrl);
599
- } else {
600
- (0, import_log.log)(`[cdp-transport] Launching owned Obsidian instance for vault: ${vaultPath}`);
601
- }
602
760
  (0, import_node_fs.mkdirSync)(config.userDataDir, { recursive: true });
603
761
  if (config.asar) {
604
762
  (0, import_obsidian_version_switch.copyAsarIntoUserData)(config.asar.path, config.asar.version, config.userDataDir);
605
763
  }
606
764
  const vaultId = (0, import_node_crypto.randomBytes)(VAULT_ID_BYTE_LENGTH).toString("hex");
607
- const obsidianJson = {
608
- updateDisabled: true,
609
- vaults: { [vaultId]: { open: true, path: vaultPath, ts: Date.now() } }
610
- };
765
+ const obsidianJson = (0, import_owned_vault_seed.buildOwnedObsidianJson)({ ts: Date.now(), vaultId, vaultPath });
611
766
  (0, import_node_fs.writeFileSync)((0, import_node_path.join)(config.userDataDir, "obsidian.json"), JSON.stringify(obsidianJson));
612
- const instance = await (0, import_obsidian_instance.launchOwnedObsidianInstance)({
613
- cdpHost: this.cdpHost,
614
- exePath: config.exePath,
615
- extraArgs: [
616
- ...(0, import_visibility.resolveOwnedHiddenLaunchArgs)(this.isObsidianAppVisible),
617
- ...(0, import_visibility.resolveSandboxLaunchArgs)(this.shouldDisableSandbox)
618
- ],
619
- userDataDir: config.userDataDir
620
- });
621
- this.ownedInstance = instance;
622
- this.cdpPort = instance.port;
623
- this.cdpUrl = instance.cdpUrl;
624
- if ((0, import_visibility.shouldHideObsidianApp)(this.isObsidianAppVisible)) {
625
- await this.moveOwnedWindowOffscreen();
767
+ let lastError;
768
+ for (let attempt = 1; attempt <= OWNED_LAUNCH_MAX_ATTEMPTS; attempt++) {
769
+ await this.killRunningOwnedInstance();
770
+ if (attempt > 1) {
771
+ await delay(OWNED_RELAUNCH_SETTLE_IN_MILLISECONDS);
772
+ }
773
+ const instance = await (0, import_obsidian_instance.launchOwnedObsidianInstance)({
774
+ cdpHost: this.cdpHost,
775
+ exePath: config.exePath,
776
+ extraArgs: [
777
+ ...(0, import_visibility.resolveOwnedHiddenLaunchArgs)(this.isObsidianAppVisible),
778
+ ...(0, import_visibility.resolveSandboxLaunchArgs)(this.shouldDisableSandbox)
779
+ ],
780
+ userDataDir: config.userDataDir
781
+ });
782
+ this.ownedInstance = instance;
783
+ this.cdpPort = instance.port;
784
+ this.cdpUrl = instance.cdpUrl;
785
+ if ((0, import_visibility.shouldHideObsidianApp)(this.isObsidianAppVisible)) {
786
+ await this.moveOwnedWindowOffscreen();
787
+ }
788
+ try {
789
+ await this.waitForOwnedVaultReady(vaultPath);
790
+ return;
791
+ } catch (error) {
792
+ if (error instanceof import_renderer_failed_to_initialize_error.RendererFailedToInitializeError || error instanceof import_silent_asar_fallback_error.SilentAsarFallbackError) {
793
+ throw error;
794
+ }
795
+ lastError = error;
796
+ (0, import_log.log)(`[cdp-transport] Owned vault not ready (attempt ${String(attempt)}/${String(OWNED_LAUNCH_MAX_ATTEMPTS)}): ${String(error)}`);
797
+ }
626
798
  }
627
- await this.waitForOwnedVaultReady(vaultPath);
799
+ throw lastError instanceof Error ? lastError : new Error(`Owned vault at ${vaultPath} did not become ready`);
628
800
  }
629
801
  /**
630
802
  * Sends a CDP command over WebSocket and waits for the response.
@@ -710,14 +882,16 @@ class DesktopCdpTransport {
710
882
  (0, import_log.log)(`[cdp-transport] Waiting for owned vault to become ready (timeout=${String(VAULT_POLL_TIMEOUT_IN_MILLISECONDS)}ms)...`);
711
883
  const deadline = Date.now() + VAULT_POLL_TIMEOUT_IN_MILLISECONDS;
712
884
  let documentCompleteSince = null;
885
+ let isReady = false;
713
886
  while (Date.now() < deadline) {
714
887
  try {
715
888
  await this.findTargetForVault(vaultPath);
716
889
  await this.waitForLayoutReady(vaultPath);
717
890
  await this.dismissTrustDialog(vaultPath);
718
- (0, import_log.log)("[cdp-transport] Owned vault is ready.");
719
- return;
891
+ isReady = true;
892
+ break;
720
893
  } catch {
894
+ this.disconnect();
721
895
  }
722
896
  if (this.deadBootGraceInMilliseconds > 0) {
723
897
  const observation = await this.probeRendererBootState();
@@ -734,7 +908,11 @@ class DesktopCdpTransport {
734
908
  }
735
909
  await delay(VAULT_POLL_INTERVAL_IN_MILLISECONDS);
736
910
  }
737
- throw new Error(`Owned vault at ${vaultPath} did not become ready within ${String(VAULT_POLL_TIMEOUT_IN_MILLISECONDS)}ms`);
911
+ if (!isReady) {
912
+ throw new Error(`Owned vault at ${vaultPath} did not become ready within ${String(VAULT_POLL_TIMEOUT_IN_MILLISECONDS)}ms`);
913
+ }
914
+ await this.checkRuntimeCompatibility(vaultPath);
915
+ (0, import_log.log)("[cdp-transport] Owned vault is ready.");
738
916
  }
739
917
  }
740
918
  function delay(ms) {
@@ -762,4 +940,4 @@ function tryRemoveDir(dir) {
762
940
  0 && (module.exports = {
763
941
  DesktopCdpTransport
764
942
  });
765
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1kZXNrdG9wLWNkcC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIERlc2t0b3AgQ0RQIHRyYW5zcG9ydCBcdTIwMTQgZXZhbHVhdGVzIGV4cHJlc3Npb25zIHZpYSBDaHJvbWUgRGV2VG9vbHMgUHJvdG9jb2xcbiAqIG92ZXIgV2ViU29ja2V0IGFuZCBtYW5hZ2VzIHZhdWx0cyB2aWEgRWxlY3Ryb24gSVBDLlxuICpcbiAqIFR3byBtb2RlczpcbiAqIC0gKipPd25lZCAoZGVmYXVsdCkqKjogdGhlIHRyYW5zcG9ydCBsYXVuY2hlcyBhbmQgb3ducyBhbiBpc29sYXRlZCBPYnNpZGlhblxuICogICBpbnN0YW5jZSBhZ2FpbnN0IGEgdGVtcG9yYXJ5IGAtLXVzZXItZGF0YS1kaXJgIG9uIGEgZnJlZSBgLS1yZW1vdGUtZGVidWdnaW5nLXBvcnRgLFxuICogICBuZXZlciB0b3VjaGluZyB0aGUgdXNlcidzIE9ic2lkaWFuLiBTdXBwb3J0cyB2ZXJzaW9uIHBpbm5pbmcgdmlhIHRoZSB1c2VyLWRhdGEgYXNhci5cbiAqIC0gKipBdHRhY2gqKjogd2hlbiBhbiBleHBsaWNpdCBDRFAgcG9ydCBpcyBjb25maWd1cmVkLCB0aGUgdHJhbnNwb3J0IGNvbm5lY3RzXG4gKiAgIHRvIGFuIGFscmVhZHktcnVubmluZyBPYnNpZGlhbiBvbiB0aGF0IHBvcnQuXG4gKlxuICogSXQgY29ubmVjdHMgdG8gcGFnZSB0YXJnZXRzLCBzZW5kcyBgUnVudGltZS5ldmFsdWF0ZWAgY29tbWFuZHMsIGFuZCByb3V0ZXMgdG9cbiAqIHRoZSBjb3JyZWN0IHZhdWx0IHRhcmdldCB1c2luZyBgZ2V0QmFzZVBhdGgoKWAgcHJvYmluZy5cbiAqXG4gKiBSZXF1aXJlbWVudHM6IE5vZGUuanMgMjIrICh1c2VzIGJ1aWx0LWluIGBXZWJTb2NrZXRgIGFuZCBgZmV0Y2hgIGdsb2JhbHMpLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGNvZGUgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtcbiAgbWtkaXJTeW5jLFxuICBybVN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbmltcG9ydCB0eXBlIHsgSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSB9IGZyb20gJy4vaW5zdGFsbGVyLWNvbXBhdGliaWxpdHkuY2pzJztcbmltcG9ydCB0eXBlIHsgT3duZWRPYnNpZGlhbkluc3RhbmNlIH0gZnJvbSAnLi9vYnNpZGlhbi1pbnN0YW5jZS5janMnO1xuaW1wb3J0IHR5cGUgeyBSZW5kZXJlckJvb3RPYnNlcnZhdGlvbiB9IGZyb20gJy4vcmVuZGVyZXItYm9vdC1kZXRlY3Rpb24uY2pzJztcbmltcG9ydCB0eXBlIHtcbiAgT2JzaWRpYW5UcmFuc3BvcnQsXG4gIFRyYW5zcG9ydEV2YWxPcHRpb25zXG59IGZyb20gJy4vdHJhbnNwb3J0LmNqcyc7XG5cbmltcG9ydCB7IERJU01JU1NfVFJVU1RfRElBTE9HX0VYUFIgfSBmcm9tICcuL2Rpc21pc3MtdHJ1c3QtZGlhbG9nLmNqcyc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAnLi9leGVjLmNqcyc7XG5pbXBvcnQgeyBsb2cgfSBmcm9tICcuL2xvZy5janMnO1xuaW1wb3J0IHsgZW5zdXJlTmFtZXNwYWNlQm9vdHN0cmFwcGVkIH0gZnJvbSAnLi9uYW1lc3BhY2UtYm9vdHN0cmFwLmNqcyc7XG5pbXBvcnQge1xuICBnZXRWYXVsdElkLFxuICBpc1ZhdWx0UmVnaXN0ZXJlZCxcbiAgcmVtb3ZlVmF1bHRGcm9tQ29uZmlnXG59IGZyb20gJy4vb2JzaWRpYW4tY29uZmlnLmNqcyc7XG5pbXBvcnQgeyByZXNvbHZlT2JzaWRpYW5FeGVjdXRhYmxlIH0gZnJvbSAnLi9vYnNpZGlhbi1leGVjdXRhYmxlLmNqcyc7XG5pbXBvcnQgeyBsYXVuY2hPd25lZE9ic2lkaWFuSW5zdGFuY2UgfSBmcm9tICcuL29ic2lkaWFuLWluc3RhbmNlLmNqcyc7XG5pbXBvcnQgeyBjb3B5QXNhckludG9Vc2VyRGF0YSB9IGZyb20gJy4vb2JzaWRpYW4tdmVyc2lvbi1zd2l0Y2guY2pzJztcbmltcG9ydCB7XG4gIGNoZWNrUmVuZGVyZXJCb290U3RhdGUsXG4gIERFRkFVTFRfREVBRF9CT09UX0dSQUNFX0lOX01JTExJU0VDT05EU1xufSBmcm9tICcuL3JlbmRlcmVyLWJvb3QtZGV0ZWN0aW9uLmNqcyc7XG5pbXBvcnQgeyBSZW5kZXJlckZhaWxlZFRvSW5pdGlhbGl6ZUVycm9yIH0gZnJvbSAnLi9yZW5kZXJlci1mYWlsZWQtdG8taW5pdGlhbGl6ZS1lcnJvci5janMnO1xuaW1wb3J0IHsgZW5zdXJlTm9uTnVsbGFibGUgfSBmcm9tICcuL3R5cGUtZ3VhcmRzLmNqcyc7XG5pbXBvcnQge1xuICByZXNvbHZlT3duZWRIaWRkZW5MYXVuY2hBcmdzLFxuICByZXNvbHZlU2FuZGJveExhdW5jaEFyZ3MsXG4gIHNob3VsZEhpZGVPYnNpZGlhbkFwcFxufSBmcm9tICcuL3Zpc2liaWxpdHkuY2pzJztcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciB0aGUgQ0RQIHRyYW5zcG9ydC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZXNrdG9wQ2RwVHJhbnNwb3J0Q29uZmlnIHtcbiAgLyoqXG4gICAqIENEUCBob3N0LiBEZWZhdWx0cyB0byBgJ2xvY2FsaG9zdCdgLlxuICAgKi9cbiAgY2RwSG9zdD86IHN0cmluZztcblxuICAvKipcbiAgICogQ0RQIHBvcnQgZm9yICoqYXR0YWNoKiogbW9kZSAodGhlIGAtLXJlbW90ZS1kZWJ1Z2dpbmctcG9ydGAgdGhlIHJ1bm5pbmdcbiAgICogT2JzaWRpYW4gd2FzIGxhdW5jaGVkIHdpdGgpLiBJbiBvd25lZC1pbnN0YW5jZSBtb2RlIHRoaXMgaXMgaWdub3JlZCBcdTIwMTQgYVxuICAgKiBmcmVlIHBvcnQgaXMgY2hvc2VuIGF0IGxhdW5jaC5cbiAgICovXG4gIGNkcFBvcnQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciBpbmRpdmlkdWFsIENEUCBjb21tYW5kcy5cbiAgICogRGVmYXVsdHMgdG8gYDMwMDAwYC5cbiAgICovXG4gIGNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEdyYWNlIHdpbmRvdyBpbiBtaWxsaXNlY29uZHMgZm9yIGZhc3QtZmFpbGluZyBhIGRlYWQgYm9vdCBvZiB0aGUgb3duZWRcbiAgICogaW5zdGFuY2UgKGVtcHR5IGA8Ym9keT5gIHdpdGggbm8gYHdpbmRvdy5hcHBgIGFmdGVyIHRoZSByZW5kZXJlciByZWFjaGVkXG4gICAqIGBkb2N1bWVudC5yZWFkeVN0YXRlYCBgJ2NvbXBsZXRlJ2ApLiBEZWZhdWx0cyB0b1xuICAgKiB7QGxpbmsgREVGQVVMVF9ERUFEX0JPT1RfR1JBQ0VfSU5fTUlMTElTRUNPTkRTfS4gYDBgIGRpc2FibGVzIGZhc3QtZmFpbC5cbiAgICovXG4gIGRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogV2hlbiBhdHRhY2hpbmcgKGkuZS4ge0BsaW5rIGNkcFBvcnR9IGlzIHNldCksIG1hcmtzIHRoZSB0YXJnZXQgYXMgYVxuICAgKiAqKmhhcm5lc3Mtb3duZWQsIGFscmVhZHktcHJlcGFyZWQqKiBpbnN0YW5jZS4gU3VwcHJlc3NlcyB0aGUgdXNlci1zY29wZVxuICAgKiB2YXVsdC1yZWdpc3RyYXRpb24gcHJlZmxpZ2h0LCBzaW5jZSB0aGUgb3duZWQgaW5zdGFuY2UncyB2YXVsdCBsaXZlcyBpbiBhblxuICAgKiBpc29sYXRlZCB1c2VyLWRhdGEgY29uZmlnIHJhdGhlciB0aGFuIHRoZSB1c2VyLXNjb3BlIHJlZ2lzdHJ5LlxuICAgKi9cbiAgaXNIYXJuZXNzT3duZWRJbnN0YW5jZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIG93bmVkIE9ic2lkaWFuIHdpbmRvdyBpcyBzaG93biBvbiBzY3JlZW4uIFdoZW4gYGZhbHNlYCAodGhlXG4gICAqIGRlZmF1bHQpLCB0aGUgb3duZWQgaW5zdGFuY2UgaXMgbGF1bmNoZWQgd2l0aCBrZWVwLWFsaXZlIENocm9taXVtIGZsYWdzIGFuZFxuICAgKiBpdHMgd2luZG93IGlzIG1vdmVkIG9mZi1zY3JlZW4gYWZ0ZXIgbGF1bmNoLiBPbmx5IG1lYW5pbmdmdWwgaW4gb3duZWQgbW9kZTtcbiAgICogYXR0YWNoIG1vZGUgbmV2ZXIgdG91Y2hlcyB0aGUgKHVzZXIncykgd2luZG93LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdHJ1ZWBcbiAgICovXG4gIGlzT2JzaWRpYW5BcHBWaXNpYmxlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hlbiBzZXQsIHRoZSB0cmFuc3BvcnQgbGF1bmNoZXMgYW5kIG93bnMgYW4gaXNvbGF0ZWQgT2JzaWRpYW4gaW5zdGFuY2VcbiAgICogaW5zdGVhZCBvZiBhdHRhY2hpbmcgdG8gYSBydW5uaW5nIG9uZS4gVGhpcyBpcyB0aGUgZGVmYXVsdCBkZXNrdG9wIG1vZGUuXG4gICAqL1xuICBvd25lZEluc3RhbmNlPzogT3duZWRJbnN0YW5jZUNvbmZpZztcblxuICAvKipcbiAgICogV2hldGhlciB0byBsYXVuY2ggdGhlIG93bmVkIGluc3RhbmNlIHdpdGggQ2hyb21pdW0ncyBzYW5kYm94IGRpc2FibGVkXG4gICAqIChgLS1uby1zYW5kYm94YCkuIE5lZWRlZCB0byBib290IG9uIExpbnV4IHdpdGhvdXQgYSBjb3JyZWN0bHktY29uZmlndXJlZFxuICAgKiBzZXR1aWQgYGNocm9tZS1zYW5kYm94YCBoZWxwZXIgKGUuZy4gYW4gZXh0cmFjdGVkIHBvcnRhYmxlIHNoZWxsLCBvciBDSSBhcyBhXG4gICAqIG5vbi1yb290IHVzZXIpOyBoYXJtbGVzcyBvbiBXaW5kb3dzL21hY09TLiBPbmx5IG1lYW5pbmdmdWwgaW4gb3duZWQgbW9kZS5cbiAgICpcbiAgICogQGRlZmF1bHQgYGZhbHNlYFxuICAgKi9cbiAgc2hvdWxkRGlzYWJsZVNhbmRib3g/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEFuIGFzYXIgdG8gcHJvdmlzaW9uIGludG8gYSBoYXJuZXNzLW93bmVkIGluc3RhbmNlJ3MgdXNlci1kYXRhIGRpciBiZWZvcmUgbGF1bmNoLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE93bmVkSW5zdGFuY2VBc2FyIHtcbiAgLyoqIEFic29sdXRlIHBhdGggdG8gdGhlIGNhY2hlZC9zb3VyY2UgYXNhciBmaWxlLiAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSBhc2FyJ3MgYHgueS56YCB2ZXJzaW9uLiAqL1xuICByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgYSBoYXJuZXNzLW93bmVkLCBpc29sYXRlZCBPYnNpZGlhbiBpbnN0YW5jZS5cbiAqXG4gKiBXaGVuIHByZXNlbnQsIHRoZSB0cmFuc3BvcnQgbGF1bmNoZXMgYW5kIG93bnMgaXRzIG93biBPYnNpZGlhbiBwcm9jZXNzXG4gKiBhZ2FpbnN0IGFuIGlzb2xhdGVkIHVzZXItZGF0YSBkaXIgaW5zdGVhZCBvZiBhdHRhY2hpbmcgdG8gYSBydW5uaW5nIGluc3RhbmNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE93bmVkSW5zdGFuY2VDb25maWcge1xuICAvKiogT3B0aW9uYWwgYXNhciB0byBwcm92aXNpb24gaW50byB7QGxpbmsgdXNlckRhdGFEaXJ9IGJlZm9yZSBsYXVuY2guICovXG4gIHJlYWRvbmx5IGFzYXI/OiBPd25lZEluc3RhbmNlQXNhciB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIHJlc29sdmVkIGluc3RhbGxlclx1MjE5NGFwcCBjb21wYXRpYmlsaXR5IHZlcmRpY3QsIHdoZW4gaXQgY291bGQgYmUgZGV0ZXJtaW5lZFxuICAgKiAoYW4gYXNhci1zd2FwIG9udG8gYSBrbm93biBzaGVsbCB2ZXJzaW9uKS4gU3VyZmFjZWQgYnlcbiAgICoge0BsaW5rIERlc2t0b3BDZHBUcmFuc3BvcnQuZ2V0Q29tcGF0aWJpbGl0eX0uXG4gICAqL1xuICByZWFkb25seSBjb21wYXRpYmlsaXR5PzogSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSB8IHVuZGVmaW5lZDtcblxuICAvKiogQWJzb2x1dGUgcGF0aCB0byB0aGUgT2JzaWRpYW4gc2hlbGwgZXhlY3V0YWJsZSB0byBsYXVuY2guICovXG4gIHJlYWRvbmx5IGV4ZVBhdGg6IHN0cmluZztcblxuICAvKipcbiAgICogQWJzb2x1dGUgcGF0aCB0byB0aGUgaXNvbGF0ZWQgdXNlci1kYXRhIGRpci4gQ3JlYXRlZCBhbmQgb3duZWQgYnkgdGhlXG4gICAqIHRyYW5zcG9ydCwgYW5kIGRlbGV0ZWQgb24gZGlzcG9zZS5cbiAgICovXG4gIHJlYWRvbmx5IHVzZXJEYXRhRGlyOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBDZHBFeGNlcHRpb25EZXRhaWxzIHtcbiAgZXhjZXB0aW9uPzogQ2RwRXhjZXB0aW9uT2JqZWN0O1xuICB0ZXh0OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBDZHBFeGNlcHRpb25PYmplY3Qge1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIENkcFJlc3BvbnNlIHtcbiAgaWQ6IG51bWJlcjtcbiAgcmVzdWx0PzogQ2RwUmVzcG9uc2VSZXN1bHQ7XG59XG5cbmludGVyZmFjZSBDZHBSZXNwb25zZVJlc3VsdCB7XG4gIHJlYWRvbmx5IGV4Y2VwdGlvbkRldGFpbHM/OiBDZHBFeGNlcHRpb25EZXRhaWxzO1xuICByZWFkb25seSByZXN1bHQ/OiBDZHBWYWx1ZTtcbn1cblxuaW50ZXJmYWNlIENkcFRhcmdldCB7XG4gIGlkOiBzdHJpbmc7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIHR5cGU6IHN0cmluZztcbiAgdXJsOiBzdHJpbmc7XG4gIHdlYlNvY2tldERlYnVnZ2VyVXJsOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBDZHBWYWx1ZSB7XG4gIHR5cGU6IHN0cmluZztcbiAgdmFsdWU/OiB1bmtub3duO1xufVxuXG4vKipcbiAqIFRoZSBDRFAgZW5kcG9pbnQgb2YgYSBsYXVuY2hlZCwgaGFybmVzcy1vd25lZCBpbnN0YW5jZS5cbiAqL1xuaW50ZXJmYWNlIE93bmVkSW5zdGFuY2VFbmRwb2ludCB7XG4gIC8qKiBDRFAgaG9zdCAoZS5nLiBgJ2xvY2FsaG9zdCdgKS4gKi9cbiAgcmVhZG9ubHkgaG9zdDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgZnJlZSBDRFAgcG9ydCB0aGUgb3duZWQgaW5zdGFuY2Ugd2FzIGxhdW5jaGVkIG9uLiAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG59XG5cbmNvbnN0IENPTU1BTkRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAzMDAwMDtcbmNvbnN0IFZBVUxUX0lEX0JZVEVfTEVOR1RIID0gODtcbmNvbnN0IFVTRVJfREFUQV9STV9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDEwMDAwO1xuY29uc3QgVVNFUl9EQVRBX1JNX1JFVFJZX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IE5PX09VVFBVVCA9ICcobm8gb3V0cHV0KSc7XG5jb25zdCBWQVVMVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IFZBVUxUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAzMDAwMDtcbmNvbnN0IFZBVUxUX0NMT1NFX0RFTEFZX0lOX01JTExJU0VDT05EUyA9IDEwMDA7XG5jb25zdCBBVVRPX1NUQVJUX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gMjAwMDtcbmNvbnN0IEFVVE9fU1RBUlRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAzMDAwMDtcbmNvbnN0IElOU1RBTkNFX0VYSVRfU0VUVExFX0RFTEFZX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IE9XTkVEX1dJTkRPV19PRkZTQ1JFRU5fTUFSR0lOX0lOX1BJWEVMUyA9IDIwMDtcbmNvbnN0IE9XTkVEX1dJTkRPV19ISURFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMjAwMDA7XG5jb25zdCBPV05FRF9XSU5ET1dfSElERV9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDI1MDtcblxuLyoqXG4gKiBUcmFuc3BvcnQgdGhhdCBjb21tdW5pY2F0ZXMgd2l0aCBEZXNrdG9wIE9ic2lkaWFuIHZpYSBDaHJvbWUgRGV2VG9vbHMgUHJvdG9jb2wuXG4gKlxuICogQ29ubmVjdHMgdG8gT2JzaWRpYW4ncyBDRFAgV2ViU29ja2V0IGVuZHBvaW50LCBzZW5kcyBgUnVudGltZS5ldmFsdWF0ZWBcbiAqIGNvbW1hbmRzLCBhbmQgcm91dGVzIGV4cHJlc3Npb25zIHRvIHRoZSBjb3JyZWN0IHZhdWx0IHRhcmdldC5cbiAqL1xuZXhwb3J0IGNsYXNzIERlc2t0b3BDZHBUcmFuc3BvcnQgaW1wbGVtZW50cyBPYnNpZGlhblRyYW5zcG9ydCB7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHRyYW5zcG9ydCBpcyBmb3IgYSBtb2JpbGUgcGxhdGZvcm0uIEFsd2F5cyBgZmFsc2VgIGZvciB0aGlzIHRyYW5zcG9ydC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpc01vYmlsZSA9IGZhbHNlO1xuICBwcml2YXRlIGFjdGl2ZVZhdWx0UGF0aDogbnVsbCB8IHN0cmluZyA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2RwSG9zdDogc3RyaW5nO1xuICBwcml2YXRlIGNkcFBvcnQ6IG51bWJlcjtcbiAgcHJpdmF0ZSBjZHBVcmw6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBjb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVhZEJvb3RHcmFjZUluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgaXNIYXJuZXNzT3duZWRJbnN0YW5jZTogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSBpc09ic2lkaWFuQXBwVmlzaWJsZTogYm9vbGVhbjtcbiAgcHJpdmF0ZSBtZXNzYWdlSWQgPSAwO1xuICBwcml2YXRlIHJlYWRvbmx5IG93bmVkQ29uZmlnOiBPd25lZEluc3RhbmNlQ29uZmlnIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIG93bmVkSW5zdGFuY2U6IE93bmVkT2JzaWRpYW5JbnN0YW5jZSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBzaG91bGREaXNhYmxlU2FuZGJveDogYm9vbGVhbjtcbiAgcHJpdmF0ZSB3czogbnVsbCB8IFdlYlNvY2tldCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgQ0RQIHRyYW5zcG9ydC5cbiAgICpcbiAgICogQHBhcmFtIGNvbmZpZyAtIENEUCBjb25uZWN0aW9uIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IoY29uZmlnPzogRGVza3RvcENkcFRyYW5zcG9ydENvbmZpZykge1xuICAgIHRoaXMuY2RwSG9zdCA9IGNvbmZpZz8uY2RwSG9zdCA/PyAnbG9jYWxob3N0JztcbiAgICB0aGlzLmNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHMgPSBjb25maWc/LmNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHMgPz8gQ09NTUFORF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgICB0aGlzLmRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kcyA9IGNvbmZpZz8uZGVhZEJvb3RHcmFjZUluTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfREVBRF9CT09UX0dSQUNFX0lOX01JTExJU0VDT05EUztcbiAgICB0aGlzLmlzSGFybmVzc093bmVkSW5zdGFuY2UgPSBjb25maWc/LmlzSGFybmVzc093bmVkSW5zdGFuY2UgPz8gZmFsc2U7XG4gICAgdGhpcy5pc09ic2lkaWFuQXBwVmlzaWJsZSA9IGNvbmZpZz8uaXNPYnNpZGlhbkFwcFZpc2libGUgPz8gdHJ1ZTtcbiAgICB0aGlzLm93bmVkQ29uZmlnID0gY29uZmlnPy5vd25lZEluc3RhbmNlO1xuICAgIHRoaXMuc2hvdWxkRGlzYWJsZVNhbmRib3ggPSBjb25maWc/LnNob3VsZERpc2FibGVTYW5kYm94ID8/IGZhbHNlO1xuICAgIC8vIE93bmVkIG1vZGUgcGlja3MgYSBmcmVlIHBvcnQgYXQgbGF1bmNoIChhc3NpZ25lZCBpbiByZWdpc3RlclZhdWx0KS5cbiAgICAvLyBBdHRhY2ggbW9kZSBjb25uZWN0cyB0byB0aGUgY29uZmlndXJlZCBwb3J0OyBubyBwb3J0IGlzIGhhcmRjb2RlZC5cbiAgICB0aGlzLmNkcFBvcnQgPSBjb25maWc/LmNkcFBvcnQgPz8gMDtcbiAgICB0aGlzLmNkcFVybCA9IGNvbmZpZz8uY2RwUG9ydCA9PT0gdW5kZWZpbmVkID8gJycgOiBgaHR0cDovLyR7dGhpcy5jZHBIb3N0fToke1N0cmluZyhjb25maWcuY2RwUG9ydCl9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwb3NlcyBvZiB0aGUgYWN0aXZlIFdlYlNvY2tldCBjb25uZWN0aW9uIGFuZCwgaW4gb3duZWQtaW5zdGFuY2UgbW9kZSxcbiAgICoga2lsbHMgdGhlIG93bmVkIE9ic2lkaWFuIHByb2Nlc3MgYW5kIHJlbW92ZXMgaXRzIGlzb2xhdGVkIHVzZXItZGF0YSBkaXIuXG4gICAqXG4gICAqIFRoZSByZW1vdmFsIGlzIHJldHJpZWQgYmVjYXVzZSBXaW5kb3dzIGJyaWVmbHkgaG9sZHMgdGhlIGp1c3Qta2lsbGVkXG4gICAqIHByb2Nlc3MncyBmaWxlIGhhbmRsZXMsIHdoaWNoIHdvdWxkIG90aGVyd2lzZSBmYWlsIGBybVN5bmNgIHdpdGggYEVQRVJNYC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIGlmICghdGhpcy5vd25lZENvbmZpZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMub3duZWRJbnN0YW5jZT8ua2lsbCgpO1xuICAgIGNvbnN0IHsgdXNlckRhdGFEaXIgfSA9IHRoaXMub3duZWRDb25maWc7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgVVNFUl9EQVRBX1JNX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGlmICh0cnlSZW1vdmVEaXIodXNlckRhdGFEaXIpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGRlbGF5KFVTRVJfREFUQV9STV9SRVRSWV9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cbiAgICBpZiAoIXRyeVJlbW92ZURpcih1c2VyRGF0YURpcikpIHtcbiAgICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIENvdWxkIG5vdCByZW1vdmUgb3duZWQgdXNlci1kYXRhIGRpciB3aXRoaW4gJHtTdHJpbmcoVVNFUl9EQVRBX1JNX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcyAobm9uLWZhdGFsKTogJHt1c2VyRGF0YURpcn1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3luY2hyb25vdXMgZGlzcG9zYWwgXHUyMDE0IGtpbGxzIHRoZSBvd25lZCBpbnN0YW5jZSBhbmQgbWFrZXMgYSBiZXN0LWVmZm9ydFxuICAgKiByZW1vdmFsIG9mIGl0cyB1c2VyLWRhdGEgZGlyLiBTYWZlIHRvIGNhbGwgZnJvbSBhIHByb2Nlc3MgYGV4aXRgIGhhbmRsZXJcbiAgICogKHdoZXJlIGFzeW5jIHJldHJpZXMgYXJlIGltcG9zc2libGU7IGEgbGVmdG92ZXIgdGVtcCBkaXIgaXMgYWNjZXB0YWJsZSkuXG4gICAqL1xuICBwdWJsaWMgZGlzcG9zZVN5bmMoKTogdm9pZCB7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgaWYgKHRoaXMub3duZWRDb25maWcpIHtcbiAgICAgIHRoaXMub3duZWRJbnN0YW5jZT8ua2lsbCgpO1xuICAgICAgaWYgKCF0cnlSZW1vdmVEaXIodGhpcy5vd25lZENvbmZpZy51c2VyRGF0YURpcikpIHtcbiAgICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gT3duZWQgdXNlci1kYXRhIGRpciBub3QgcmVtb3ZlZCBzeW5jaHJvbm91c2x5IChwcm9jZXNzIG1heSBzdGlsbCBob2xkIGhhbmRsZXMpOiAke3RoaXMub3duZWRDb25maWcudXNlckRhdGFEaXJ9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV2YWx1YXRlcyBhIEphdmFTY3JpcHQgZXhwcmVzc2lvbiBpbnNpZGUgT2JzaWRpYW4gdmlhIENEUCBgUnVudGltZS5ldmFsdWF0ZWAuXG4gICAqXG4gICAqIFJvdXRlcyB0byB0aGUgY29ycmVjdCB2YXVsdCB0YXJnZXQgYmFzZWQgb24gYG9wdGlvbnMuY3dkYC5cbiAgICpcbiAgICogQHBhcmFtIGV4cHJlc3Npb24gLSBUaGUgSmF2YVNjcmlwdCBleHByZXNzaW9uIHRvIGV2YWx1YXRlLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEV2YWx1YXRpb24gb3B0aW9ucy5cbiAgICogQHJldHVybnMgVGhlIG5vcm1hbGl6ZWQgcmVzdWx0IHN0cmluZy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBldmFsdWF0ZShleHByZXNzaW9uOiBzdHJpbmcsIG9wdGlvbnM6IFRyYW5zcG9ydEV2YWxPcHRpb25zKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCB3cyA9IGF3YWl0IHRoaXMuZW5zdXJlQ29ubmVjdGlvbihvcHRpb25zLmN3ZCk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRDb21tYW5kKHdzLCAnUnVudGltZS5ldmFsdWF0ZScsIHtcbiAgICAgIGF3YWl0UHJvbWlzZTogdHJ1ZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgfSk7XG5cbiAgICBpZiAocmVzcG9uc2UucmVzdWx0Py5leGNlcHRpb25EZXRhaWxzKSB7XG4gICAgICBjb25zdCBkZXNjID0gcmVzcG9uc2UucmVzdWx0LmV4Y2VwdGlvbkRldGFpbHMuZXhjZXB0aW9uPy5kZXNjcmlwdGlvblxuICAgICAgICA/PyByZXNwb25zZS5yZXN1bHQuZXhjZXB0aW9uRGV0YWlscy50ZXh0O1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDRFAgZXZhbHVhdGlvbiBlcnJvcjogJHtkZXNjfWApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdE9iaiA9IHJlc3BvbnNlLnJlc3VsdD8ucmVzdWx0O1xuICAgIGlmICghcmVzdWx0T2JqIHx8IHJlc3VsdE9iai50eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIE5PX09VVFBVVDtcbiAgICB9XG5cbiAgICByZXR1cm4gU3RyaW5nKHJlc3VsdE9iai52YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgcmVzb2x2ZWQgaW5zdGFsbGVyXHUyMTk0YXBwIGNvbXBhdGliaWxpdHkgdmVyZGljdCBmb3IgdGhpcyBvd25lZFxuICAgKiBpbnN0YW5jZSwgc28gY2FsbGVycyBjYW4gYXNzZXJ0IG9uIGl0LiBSZXR1cm5zIGB1bmRlZmluZWRgIHdoZW4gdGhpcyBpcyBub3RcbiAgICogYW4gb3duZWQgaW5zdGFuY2UsIG9yIHRoZSB2ZXJkaWN0IGNvdWxkIG5vdCBiZSBkZXRlcm1pbmVkIChlLmcuIGFuXG4gICAqIHVuZGV0ZWN0YWJsZSBzaGVsbCB2ZXJzaW9uLCBvciB0aGUgYXBwIHZlcnNpb24gaXMgYWJzZW50IGZyb20gdGhlIHRhYmxlKS5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGNvbXBhdGliaWxpdHkgdmVyZGljdCwgb3IgYHVuZGVmaW5lZGAuXG4gICAqL1xuICBwdWJsaWMgZ2V0Q29tcGF0aWJpbGl0eSgpOiBJbnN0YWxsZXJDb21wYXRpYmlsaXR5IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5vd25lZENvbmZpZz8uY29tcGF0aWJpbGl0eTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBDRFAgZW5kcG9pbnQgb2YgdGhlIG93bmVkLCBsYXVuY2hlZCBpbnN0YW5jZSBzbyB0aGUgZ2xvYmFsIHNldHVwXG4gICAqIGNhbiBoYW5kIGl0IHRvIHRlc3Qgd29ya2VycyAod2hpY2ggdGhlbiAqKmF0dGFjaCoqIHRvIGl0IGluc3RlYWQgb2ZcbiAgICogbGF1bmNoaW5nIHRoZWlyIG93bikuIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB0aGlzIHRyYW5zcG9ydCBpcyBub3QgYW5cbiAgICogb3duZWQgaW5zdGFuY2UsIG9yIGl0cyBpbnN0YW5jZSBoYXMgbm90IGJlZW4gbGF1bmNoZWQgeWV0LlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgb3duZWQgaW5zdGFuY2UncyBDRFAgaG9zdCBhbmQgcG9ydCwgb3IgYHVuZGVmaW5lZGAuXG4gICAqL1xuICBwdWJsaWMgZ2V0T3duZWRJbnN0YW5jZUVuZHBvaW50KCk6IE93bmVkSW5zdGFuY2VFbmRwb2ludCB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF0aGlzLm93bmVkQ29uZmlnIHx8ICF0aGlzLm93bmVkSW5zdGFuY2UpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB7IGhvc3Q6IHRoaXMuY2RwSG9zdCwgcG9ydDogdGhpcy5jZHBQb3J0IH07XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZpZXMgdGhhdCB0aGUgQ0RQIGVuZHBvaW50IGlzIHJlYWNoYWJsZSBhbmQgaGFzIE9ic2lkaWFuIHRhcmdldHMuXG4gICAqXG4gICAqIElmIE9ic2lkaWFuIGlzIG5vdCBydW5uaW5nLCBhdHRlbXB0cyB0byBhdXRvLXN0YXJ0IGl0IHZpYSBVUkkgcHJvdG9jb2xcbiAgICogYW5kIHBvbGxzIHVudGlsIENEUCBiZWNvbWVzIGF2YWlsYWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoICh1c2VkIGZvciB2YXVsdCByZWdpc3RyYXRpb24gY2hlY2spLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHByZWZsaWdodENoZWNrKHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMub3duZWRDb25maWcgfHwgdGhpcy5pc0hhcm5lc3NPd25lZEluc3RhbmNlKSB7XG4gICAgICAvLyBPd25lZCBpbnN0YW5jZSAobGF1bmNoZWQgaGVyZSkgb3IgYSB3b3JrZXIgYXR0YWNoZWQgdG8gb25lOiByZWFkaW5lc3MgaXNcbiAgICAgIC8vIEd1YXJhbnRlZWQgYnkgdGhlIGdsb2JhbCBzZXR1cCdzIHJlZ2lzdGVyVmF1bHQsIGFuZCB0aGUgdmF1bHQgbGl2ZXMgaW5cbiAgICAgIC8vIFRoZSBpc29sYXRlZCBjb25maWcgXHUyMDE0IHRoZXJlIGlzIG5vdGhpbmcgdG8gdmVyaWZ5IGFnYWluc3QgdGhlIHVzZXItc2NvcGVcbiAgICAgIC8vIFJlZ2lzdHJ5LlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIFJ1bm5pbmcgcHJlZmxpZ2h0IGNoZWNrIGZvciB2YXVsdDogJHt2YXVsdFBhdGh9YCk7XG4gICAgaWYgKCFpc1ZhdWx0UmVnaXN0ZXJlZCh2YXVsdFBhdGgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBWYXVsdCBpcyBub3QgcmVnaXN0ZXJlZCBpbiBPYnNpZGlhbjogJHt2YXVsdFBhdGh9LiBSZWdpc3RlciB0aGUgdmF1bHQgZmlyc3Qgd2l0aCByZWdpc3RlclZhdWx0KCkgb3IgVGVtcFZhdWx0LnJlZ2lzdGVyKCkuYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdGFyZ2V0cyA9IGF3YWl0IHRoaXMuZ2V0UGFnZVRhcmdldHMoKTtcbiAgICAgIGlmICh0YXJnZXRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHBhZ2UgdGFyZ2V0cycpO1xuICAgICAgfVxuICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gQ0RQIHJlYWNoYWJsZSwgJHtTdHJpbmcodGFyZ2V0cy5sZW5ndGgpfSB0YXJnZXQocykgZm91bmQuYCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBhd2FpdCB0aGlzLmVuc3VyZU9ic2lkaWFuUnVubmluZygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSB2YXVsdCB2aWEgRWxlY3Ryb24gSVBDIGV2YWx1YXRlZCB0aHJvdWdoIENEUC5cbiAgICpcbiAgICogVXNlcyBhbiBleGlzdGluZyBPYnNpZGlhbiB0YXJnZXQgdG8gc2VuZCB0aGUgYHZhdWx0LW9wZW5gIElQQyBjb21tYW5kLFxuICAgKiB0aGVuIHBvbGxzIHVudGlsIHRoZSBuZXcgdmF1bHQncyB0YXJnZXQgYXBwZWFycy5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBmb2xkZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVnaXN0ZXJWYXVsdCh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLm93bmVkQ29uZmlnKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyVmF1bHRJbk93bmVkSW5zdGFuY2UodmF1bHRQYXRoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLm9wZW5WYXVsdEluUnVubmluZ0luc3RhbmNlKHZhdWx0UGF0aCk7XG4gIH1cblxuICAvKipcbiAgICogVW5yZWdpc3RlcnMgYSB2YXVsdCBieSBkZXN0cm95aW5nIGl0cyB3aW5kb3cgYW5kIHJlbW92aW5nIGl0IGZyb20gdGhlIHJlZ2lzdHJ5LlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IGZvbGRlci5cbiAgICovXG4gIHB1YmxpYyBhc3luYyB1bnJlZ2lzdGVyVmF1bHQodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5vd25lZENvbmZpZykge1xuICAgICAgLy8gVGhlIG93bmVkIGluc3RhbmNlIGlzIGtpbGxlZCB3aG9sZXNhbGUgb24gZGlzcG9zZTsgbm8gcGVyLXZhdWx0XG4gICAgICAvLyBVbnJlZ2lzdGVyIGlzIG5lZWRlZCAoYW5kIHRoZSByZWdpc3RyeSBsaXZlcyBpbiB0aGUgaXNvbGF0ZWQgY29uZmlnKS5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgZW5zdXJlTmFtZXNwYWNlQm9vdHN0cmFwcGVkKHRoaXMsIHZhdWx0UGF0aCk7XG4gICAgICBjb25zdCB0YXJnZXQgPSBhd2FpdCB0aGlzLmZpbmRUYXJnZXRGb3JWYXVsdCh2YXVsdFBhdGgpO1xuICAgICAgY29uc3Qgd3MgPSBhd2FpdCB0aGlzLmNvbm5lY3RUb1RhcmdldCh0YXJnZXQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGVzdHJveUV4cHIgPSAnd2luZG93Ll9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcuZGVzdHJveUN1cnJlbnRXaW5kb3coKSc7XG4gICAgICAgIGF3YWl0IHRoaXMuc2VuZENvbW1hbmQod3MsICdSdW50aW1lLmV2YWx1YXRlJywge1xuICAgICAgICAgIGF3YWl0UHJvbWlzZTogdHJ1ZSxcbiAgICAgICAgICBleHByZXNzaW9uOiBkZXN0cm95RXhwcixcbiAgICAgICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgd3MuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFdpbmRvdyBtYXkgYWxyZWFkeSBiZSBjbG9zZWQuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYWN0aXZlVmF1bHRQYXRoID09PSB2YXVsdFBhdGgpIHtcbiAgICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIH1cblxuICAgIGF3YWl0IGRlbGF5KFZBVUxUX0NMT1NFX0RFTEFZX0lOX01JTExJU0VDT05EUyk7XG5cbiAgICBjb25zdCB0YXJnZXRzID0gYXdhaXQgdGhpcy5nZXRQYWdlVGFyZ2V0cygpO1xuICAgIGlmICh0YXJnZXRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHdzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQoZW5zdXJlTm9uTnVsbGFibGUodGFyZ2V0c1swXSkpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZW5zdXJlTmFtZXNwYWNlQm9vdHN0cmFwcGVkKHRoaXMsIHZhdWx0UGF0aCk7XG4gICAgICAgIGNvbnN0IHJlbW92ZUV4cHIgPSBgd2luZG93Ll9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcuaXBjU2VuZFN5bmMoJHtKU09OLnN0cmluZ2lmeSh7IGFyZ3M6IFt2YXVsdFBhdGhdLCBjaGFubmVsOiAndmF1bHQtcmVtb3ZlJyB9KX0pYDtcbiAgICAgICAgYXdhaXQgdGhpcy5zZW5kQ29tbWFuZCh3cywgJ1J1bnRpbWUuZXZhbHVhdGUnLCB7XG4gICAgICAgICAgYXdhaXRQcm9taXNlOiB0cnVlLFxuICAgICAgICAgIGV4cHJlc3Npb246IHJlbW92ZUV4cHIsXG4gICAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIE5vIENEUCB0YXJnZXRzIGZvciByZW1vdmFsIElQQyBcdTIwMTQgcmVtb3ZpbmcgZGlyZWN0bHkgZnJvbSBvYnNpZGlhbi5qc29uLicpO1xuICAgICAgcmVtb3ZlVmF1bHRGcm9tQ29uZmlnKHZhdWx0UGF0aCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbm5lY3RzIHRvIGEgQ0RQIHRhcmdldCdzIFdlYlNvY2tldCBlbmRwb2ludC5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldCAtIFRoZSBDRFAgdGFyZ2V0IHRvIGNvbm5lY3QgdG8uXG4gICAqIEByZXR1cm5zIFRoZSBvcGVuIFdlYlNvY2tldCBjb25uZWN0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjb25uZWN0VG9UYXJnZXQodGFyZ2V0OiBDZHBUYXJnZXQpOiBQcm9taXNlPFdlYlNvY2tldD4ge1xuICAgIGNvbnN0IHdzID0gbmV3IFdlYlNvY2tldCh0YXJnZXQud2ViU29ja2V0RGVidWdnZXJVcmwpO1xuICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHdzLm9ub3BlbiA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfTtcbiAgICAgIHdzLm9uZXJyb3IgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBjb25uZWN0IHRvIENEUCB0YXJnZXQ6ICR7dGFyZ2V0LndlYlNvY2tldERlYnVnZ2VyVXJsfWApKTtcbiAgICAgIH07XG4gICAgfSk7XG4gICAgcmV0dXJuIHdzO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc2Nvbm5lY3RzIHRoZSBhY3RpdmUgV2ViU29ja2V0IGNvbm5lY3Rpb24uXG4gICAqL1xuICBwcml2YXRlIGRpc2Nvbm5lY3QoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMud3M/LnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOKSB7XG4gICAgICB0aGlzLndzLmNsb3NlKCk7XG4gICAgfVxuICAgIHRoaXMud3MgPSBudWxsO1xuICAgIHRoaXMuYWN0aXZlVmF1bHRQYXRoID0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNtaXNzZXMgdGhlIFwiRG8geW91IHRydXN0IHRoZSBhdXRob3Igb2YgdGhpcyB2YXVsdD9cIiBkaWFsb2cgaWYgcHJlc2VudC5cbiAgICpcbiAgICogQWN0cyBhcyBhIHNhZmV0eSBuZXQgd2hlbiBgZW5hYmxlLXBsdWdpbi08aWQ+YCBpcyB3cml0dGVuIGluIG9uZSByZW5kZXJlclxuICAgKiBidXQgbm90IHlldCB2aXNpYmxlIHRvIHRoZSBuZXdseS1vcGVuZWQgdmF1bHQncyByZW5kZXJlciAocmFjZSBvYnNlcnZlZFxuICAgKiBpbiBPYnNpZGlhbiAxLjEzLjApLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIHZhdWx0IHBhdGggdG8gZXZhbHVhdGUgaW4uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRpc21pc3NUcnVzdERpYWxvZyh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZXZhbHVhdGUoRElTTUlTU19UUlVTVF9ESUFMT0dfRVhQUiwgeyBjd2Q6IHZhdWx0UGF0aCB9KTtcbiAgICBpZiAocmVzdWx0ID09PSAndHJ1ZScpIHtcbiAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIERpc21pc3NlZCBcIkRvIHlvdSB0cnVzdCB0aGUgYXV0aG9yXCIgZGlhbG9nLicpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGBlbmFibGUtcGx1Z2luLTx2YXVsdElkPmAgaW4gT2JzaWRpYW4ncyBsb2NhbFN0b3JhZ2UgdG8gcHJldmVudFxuICAgKiB0aGUgXCJEbyB5b3UgdHJ1c3QgdGhlIGF1dGhvciBvZiB0aGlzIHZhdWx0P1wiIGRpYWxvZyBmcm9tIGFwcGVhcmluZ1xuICAgKiB3aGVuIGEgdmF1bHQgd2l0aCBjb21tdW5pdHkgcGx1Z2lucyBpcyBvcGVuZWQgZm9yIHRoZSBmaXJzdCB0aW1lLlxuICAgKlxuICAgKiBNdXN0IGJlIGNhbGxlZCBhZnRlciB0aGUgYHZhdWx0LW9wZW5gIElQQyAoc28gdGhlIHZhdWx0IElEIGV4aXN0cyBpblxuICAgKiBgb2JzaWRpYW4uanNvbmApIGFuZCBiZWZvcmUgdGhlIG5ldyB2YXVsdCB3aW5kb3cgZmluaXNoZXMgbG9hZGluZy5cbiAgICpcbiAgICogQHBhcmFtIHdzIC0gQW4gb3BlbiBXZWJTb2NrZXQgdG8gYW4gZXhpc3RpbmcgT2JzaWRpYW4gdGFyZ2V0LlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IGZvbGRlci5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5hYmxlUGx1Z2luc0luTG9jYWxTdG9yYWdlKHdzOiBXZWJTb2NrZXQsIHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdmF1bHRJZCA9IGdldFZhdWx0SWQodmF1bHRQYXRoKTtcbiAgICBpZiAoIXZhdWx0SWQpIHtcbiAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIENvdWxkIG5vdCBmaW5kIHZhdWx0IElEIFx1MjAxNCBza2lwcGluZyBsb2NhbFN0b3JhZ2UgdHJ1c3QgZmxhZy4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnNlbmRDb21tYW5kKHdzLCAnUnVudGltZS5ldmFsdWF0ZScsIHtcbiAgICAgIGV4cHJlc3Npb246IGBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgke0pTT04uc3RyaW5naWZ5KGBlbmFibGUtcGx1Z2luLSR7dmF1bHRJZH1gKX0sICd0cnVlJyk7YCxcbiAgICAgIHJldHVybkJ5VmFsdWU6IHRydWVcbiAgICB9KTtcbiAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBTZXQgZW5hYmxlLXBsdWdpbi0ke3ZhdWx0SWR9IGluIGxvY2FsU3RvcmFnZS5gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIHRoZXJlIGlzIGFuIGFjdGl2ZSBXZWJTb2NrZXQgY29ubmVjdGlvbiB0byB0aGUgY29ycmVjdCB2YXVsdCB0YXJnZXQuXG4gICAqXG4gICAqIFJldXNlcyB0aGUgZXhpc3RpbmcgY29ubmVjdGlvbiBpZiBpdCB0YXJnZXRzIHRoZSByZXF1ZXN0ZWQgdmF1bHQuXG4gICAqIE90aGVyd2lzZSwgZmluZHMgdGhlIGNvcnJlY3QgdGFyZ2V0IGFuZCByZWNvbm5lY3RzLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIHZhdWx0IHBhdGggdG8gdGFyZ2V0LlxuICAgKiBAcmV0dXJucyBUaGUgYWN0aXZlIFdlYlNvY2tldCBjb25uZWN0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVDb25uZWN0aW9uKHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTxXZWJTb2NrZXQ+IHtcbiAgICBpZiAodGhpcy53cz8ucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0Lk9QRU4gJiYgdGhpcy5hY3RpdmVWYXVsdFBhdGggPT09IHZhdWx0UGF0aCkge1xuICAgICAgcmV0dXJuIHRoaXMud3M7XG4gICAgfVxuXG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG5cbiAgICBjb25zdCB0YXJnZXQgPSBhd2FpdCB0aGlzLmZpbmRUYXJnZXRGb3JWYXVsdCh2YXVsdFBhdGgpO1xuICAgIHRoaXMud3MgPSBhd2FpdCB0aGlzLmNvbm5lY3RUb1RhcmdldCh0YXJnZXQpO1xuICAgIHRoaXMuYWN0aXZlVmF1bHRQYXRoID0gdmF1bHRQYXRoO1xuICAgIHJldHVybiB0aGlzLndzO1xuICB9XG5cbiAgLyoqXG4gICAqIExhdW5jaGVzIE9ic2lkaWFuIHdpdGggYC0tcmVtb3RlLWRlYnVnZ2luZy1wb3J0YCBhbmQgcG9sbHMgdW50aWwgQ0RQIGJlY29tZXMgYXZhaWxhYmxlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVPYnNpZGlhblJ1bm5pbmcoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gT2JzaWRpYW4gQ0RQIG5vdCByZWFjaGFibGUuIFN0YXJ0aW5nIE9ic2lkaWFuIHdpdGggcmVtb3RlIGRlYnVnZ2luZy4uLicpO1xuXG4gICAgY29uc3QgbGF1bmNoQ29tbWFuZCA9IGF3YWl0IGdldE9ic2lkaWFuTGF1bmNoQ29tbWFuZCh0aGlzLmNkcFBvcnQpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBleGVjKGxhdW5jaENvbW1hbmQsIHsgaXNRdWlldDogdHJ1ZSB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFRoZSBsYXVuY2ggY29tbWFuZCBtYXkgZmFpbCBvbiBzb21lIHN5c3RlbXMgXHUyMDE0IHdlJ2xsIHN0aWxsIHRyeSBwb2xsaW5nLlxuICAgIH1cblxuICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIFBvbGxpbmcgZm9yIENEUCBlbmRwb2ludCBhdCAke3RoaXMuY2RwVXJsfSAodGltZW91dD0ke1N0cmluZyhBVVRPX1NUQVJUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcykuLi5gKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBBVVRPX1NUQVJUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGF3YWl0IGRlbGF5KEFVVE9fU1RBUlRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0cyA9IGF3YWl0IHRoaXMuZ2V0UGFnZVRhcmdldHMoKTtcbiAgICAgICAgaWYgKHRhcmdldHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIE9ic2lkaWFuIENEUCByZWFkeSwgJHtTdHJpbmcodGFyZ2V0cy5sZW5ndGgpfSB0YXJnZXQocykgZm91bmQuYCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gQ0RQIG5vdCByZWFkeSB5ZXQsIHJldHJ5aW5nLi4uJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGBPYnNpZGlhbiBkaWQgbm90IHN0YXJ0IHdpdGhpbiAke1N0cmluZyhBVVRPX1NUQVJUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcy4gRW5zdXJlIE9ic2lkaWFuIGlzIGluc3RhbGxlZCBhbmQgYWNjZXNzaWJsZS5gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyB0aGUgQ0RQIHRhcmdldCB0aGF0IGhhcyB0aGUgZ2l2ZW4gdmF1bHQgb3Blbi5cbiAgICpcbiAgICogRm9yIGEgc2luZ2xlIHRhcmdldCwgcmV0dXJucyBpdCBkaXJlY3RseS4gRm9yIG11bHRpcGxlIHRhcmdldHMsXG4gICAqIHByb2JlcyBlYWNoIGJ5IGV2YWx1YXRpbmcgYGdldEJhc2VQYXRoKClgIHRvIGZpbmQgdGhlIG1hdGNoLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIHZhdWx0IHBhdGggdG8gbWF0Y2guXG4gICAqIEByZXR1cm5zIFRoZSBtYXRjaGluZyBDRFAgdGFyZ2V0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBmaW5kVGFyZ2V0Rm9yVmF1bHQodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPENkcFRhcmdldD4ge1xuICAgIGNvbnN0IHRhcmdldHMgPSBhd2FpdCB0aGlzLmdldFBhZ2VUYXJnZXRzKCk7XG5cbiAgICBpZiAodGFyZ2V0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gT2JzaWRpYW4gQ0RQIHRhcmdldHMgZm91bmQnKTtcbiAgICB9XG5cbiAgICBpZiAodGFyZ2V0cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0YXJnZXRzWzBdKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHRhcmdldCBvZiB0YXJnZXRzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBiYXNlUGF0aCA9IGF3YWl0IHRoaXMucHJvYmVWYXVsdFBhdGgodGFyZ2V0KTtcbiAgICAgICAgaWYgKGJhc2VQYXRoID09PSB2YXVsdFBhdGgpIHtcbiAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gTm90IGEgdmF1bHQgdGFyZ2V0IG9yIG5vdCByZWFkeS5cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIENEUCB0YXJnZXQgZm91bmQgZm9yIHZhdWx0OiAke3ZhdWx0UGF0aH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaGVzIHRoZSBsaXN0IG9mIHBhZ2UtdHlwZSB0YXJnZXRzIGZyb20gdGhlIENEUCBgL2pzb25gIGVuZHBvaW50LlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgbGlzdCBvZiBwYWdlIHRhcmdldHMuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldFBhZ2VUYXJnZXRzKCk6IFByb21pc2U8Q2RwVGFyZ2V0W10+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke3RoaXMuY2RwVXJsfS9qc29uYCk7XG4gICAgY29uc3QgdGFyZ2V0cyA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyBDZHBUYXJnZXRbXTtcbiAgICByZXR1cm4gdGFyZ2V0cy5maWx0ZXIoKHQpID0+IHQudHlwZSA9PT0gJ3BhZ2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlcyB0aGUgb3duZWQgaW5zdGFuY2UncyB3aW5kb3cgb2ZmLXNjcmVlbiBzbyBhIGhpZGRlbiBydW4gbmV2ZXIgc3RlYWxzXG4gICAqIGZvY3VzLiBVc2VzIEVsZWN0cm9uJ3MgcmVtb3RlIGJyaWRnZSAoYHdpbmRvdy5lbGVjdHJvbi5yZW1vdGVgKSBcdTIwMTQgdGhlIG9ubHlcbiAgICogY3Jvc3MtcGxhdGZvcm0gd2F5IHRvIHJlcG9zaXRpb24gdGhlIHdpbmRvdyBcdTIwMTQgcGxhY2luZyBpdCBqdXN0IGJleW9uZCB0aGVcbiAgICogcmlnaHQgZWRnZSBvZiBhbGwgZGlzcGxheXMuIFRoZSB3aW5kb3cgc3RheXMgXCJ2aXNpYmxlXCIgdG8gQ2hyb21pdW0gKHNvXG4gICAqIHRpbWVycywgYHJlcXVlc3RBbmltYXRpb25GcmFtZWAsIGA6aG92ZXJgLCBhbmQgdHJ1c3RlZCBpbnB1dCBrZWVwIHdvcmtpbmcpLFxuICAgKiB1bmxpa2UgbWluaW1pemluZywgd2hpY2ggd291bGQgZnJlZXplIGByZXF1ZXN0QW5pbWF0aW9uRnJhbWVgLlxuICAgKlxuICAgKiBUaGUgcmVtb3RlIGJyaWRnZSBpcyBub3QgYXZhaWxhYmxlIHRoZSBpbnN0YW50IENEUCBzdGFydHMgc2VydmluZywgc28gdGhpc1xuICAgKiBwb2xscyB1bnRpbCB0aGUgbW92ZSBzdWNjZWVkcy4gQmVzdC1lZmZvcnQ6IGlmIHRoZSB3aW5kb3cgY2Fubm90IGJlIG1vdmVkXG4gICAqIHdpdGhpbiB0aGUgdGltZW91dCwgdGhlIGtlZXAtYWxpdmUgbGF1bmNoIGZsYWdzIHN0aWxsIGFwcGx5IGFuZCB0aGUgcnVuXG4gICAqIHByb2NlZWRzICh3b3JzdCBjYXNlIHRoZSB3aW5kb3cgaXMgYnJpZWZseSB2aXNpYmxlKS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgbW92ZU93bmVkV2luZG93T2Zmc2NyZWVuKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG1vdmVFeHByID0gYCgoKSA9PiB7XG4gICAgICBjb25zdCByZW1vdGUgPSB3aW5kb3cuZWxlY3Ryb24gJiYgd2luZG93LmVsZWN0cm9uLnJlbW90ZTtcbiAgICAgIGlmICghcmVtb3RlIHx8IHR5cGVvZiByZW1vdGUuZ2V0Q3VycmVudFdpbmRvdyAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gJ25vLWJyaWRnZSc7IH1cbiAgICAgIGNvbnN0IHdpbiA9IHJlbW90ZS5nZXRDdXJyZW50V2luZG93KCk7XG4gICAgICBjb25zdCBkaXNwbGF5cyA9IHJlbW90ZS5zY3JlZW4uZ2V0QWxsRGlzcGxheXMoKTtcbiAgICAgIGNvbnN0IG1heFJpZ2h0ID0gTWF0aC5tYXgoLi4uZGlzcGxheXMubWFwKChkaXNwbGF5KSA9PiBkaXNwbGF5LmJvdW5kcy54ICsgZGlzcGxheS5ib3VuZHMud2lkdGgpKTtcbiAgICAgIHdpbi5zZXRQb3NpdGlvbihtYXhSaWdodCArICR7U3RyaW5nKE9XTkVEX1dJTkRPV19PRkZTQ1JFRU5fTUFSR0lOX0lOX1BJWEVMUyl9LCAwKTtcbiAgICAgIHJldHVybiAnbW92ZWQnO1xuICAgIH0pKClgO1xuXG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgT1dORURfV0lORE9XX0hJREVfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gKGF3YWl0IHRoaXMuZ2V0UGFnZVRhcmdldHMoKSlbMF07XG4gICAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgICBjb25zdCB3cyA9IGF3YWl0IHRoaXMuY29ubmVjdFRvVGFyZ2V0KHRhcmdldCk7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5zZW5kQ29tbWFuZCh3cywgJ1J1bnRpbWUuZXZhbHVhdGUnLCB7XG4gICAgICAgICAgICAgIGV4cHJlc3Npb246IG1vdmVFeHByLFxuICAgICAgICAgICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5yZXN1bHQ/LnJlc3VsdD8udmFsdWUgPT09ICdtb3ZlZCcpIHtcbiAgICAgICAgICAgICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gTW92ZWQgb3duZWQgT2JzaWRpYW4gd2luZG93IG9mZi1zY3JlZW4gKGhpZGRlbiBtb2RlKS4nKTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB3cy5jbG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIENEUCBlbmRwb2ludCAvIHRhcmdldCAvIHJlbW90ZSBicmlkZ2Ugbm90IHJlYWR5IHlldCBcdTIwMTQga2VlcCBwb2xsaW5nLlxuICAgICAgfVxuICAgICAgYXdhaXQgZGVsYXkoT1dORURfV0lORE9XX0hJREVfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cbiAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBDb3VsZCBub3QgbW92ZSBvd25lZCB3aW5kb3cgb2ZmLXNjcmVlbiB3aXRoaW4gJHtTdHJpbmcoT1dORURfV0lORE9XX0hJREVfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMpfW1zIChub24tZmF0YWw7IGtlZXAtYWxpdmUgZmxhZ3Mgc3RpbGwgYXBwbGllZCkuYCk7XG4gIH1cblxuICAvKipcbiAgICogT3BlbnMgYSB2YXVsdCBpbiBhbiBhbHJlYWR5LXJ1bm5pbmcgT2JzaWRpYW4gaW5zdGFuY2UgdmlhIHRoZSBgdmF1bHQtb3BlbmBcbiAgICogRWxlY3Ryb24gSVBDIChldmFsdWF0ZWQgdGhyb3VnaCBDRFAgb24gYW4gZXhpc3RpbmcgdGFyZ2V0KSwgdGhlbiBwb2xscyB1bnRpbFxuICAgKiB0aGUgbmV3IHZhdWx0J3Mgd2luZG93IHRhcmdldCBhcHBlYXJzLCBpcyBsYXlvdXQtcmVhZHksIGFuZCBpdHMgdHJ1c3QgZGlhbG9nXG4gICAqIChpZiBhbnkpIGhhcyBiZWVuIGRpc21pc3NlZC5cbiAgICpcbiAgICogU2hhcmVkIGJ5IHRoZSBhdHRhY2gtbW9kZSB7QGxpbmsgcmVnaXN0ZXJWYXVsdH0gYW5kIHRoZSBvd25lZC1tb2RlXG4gICAqIFwiaW5zdGFuY2UgYWxyZWFkeSBsYXVuY2hlZFwiIHBhdGgsIHNvIG9wZW5pbmcgYW4gYWRkaXRpb25hbCB2YXVsdCBuZXZlclxuICAgKiByZWxhdW5jaGVzIHRoZSBwcm9jZXNzICh3aGljaCB3b3VsZCBzdXJmYWNlIHRoZSB2YXVsdCBwaWNrZXIpLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IGZvbGRlci5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgb3BlblZhdWx0SW5SdW5uaW5nSW5zdGFuY2UodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBSZWdpc3RlcmluZyB2YXVsdDogJHt2YXVsdFBhdGh9YCk7XG4gICAgY29uc3QgdGFyZ2V0cyA9IGF3YWl0IHRoaXMuZ2V0UGFnZVRhcmdldHMoKTtcbiAgICBpZiAodGFyZ2V0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gT2JzaWRpYW4gQ0RQIHRhcmdldHMgYXZhaWxhYmxlLiBJcyBPYnNpZGlhbiBydW5uaW5nPycpO1xuICAgIH1cblxuICAgIGNvbnN0IGlwY1dzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQoZW5zdXJlTm9uTnVsbGFibGUodGFyZ2V0c1swXSkpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBlbnN1cmVOYW1lc3BhY2VCb290c3RyYXBwZWQodGhpcywgdmF1bHRQYXRoKTtcbiAgICAgIGNvbnN0IGlwY0V4cHIgPSBgd2luZG93Ll9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcuaXBjU2VuZFN5bmMoJHtKU09OLnN0cmluZ2lmeSh7IGFyZ3M6IFt2YXVsdFBhdGgsIGZhbHNlXSwgY2hhbm5lbDogJ3ZhdWx0LW9wZW4nIH0pfSlgO1xuICAgICAgYXdhaXQgdGhpcy5zZW5kQ29tbWFuZChpcGNXcywgJ1J1bnRpbWUuZXZhbHVhdGUnLCB7XG4gICAgICAgIGF3YWl0UHJvbWlzZTogdHJ1ZSxcbiAgICAgICAgZXhwcmVzc2lvbjogaXBjRXhwcixcbiAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHRoaXMuZW5hYmxlUGx1Z2luc0luTG9jYWxTdG9yYWdlKGlwY1dzLCB2YXVsdFBhdGgpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpcGNXcy5jbG9zZSgpO1xuICAgIH1cblxuICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIFBvbGxpbmcgZm9yIHZhdWx0IHRhcmdldCAodGltZW91dD0ke1N0cmluZyhWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcykuLi5gKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZmluZFRhcmdldEZvclZhdWx0KHZhdWx0UGF0aCk7XG4gICAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIFZhdWx0IHRhcmdldCBmb3VuZC4nKTtcbiAgICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yTGF5b3V0UmVhZHkodmF1bHRQYXRoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5kaXNtaXNzVHJ1c3REaWFsb2codmF1bHRQYXRoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIFZhdWx0IHRhcmdldCBub3QgcmVhZHkgeWV0LlxuICAgICAgfVxuICAgICAgYXdhaXQgZGVsYXkoVkFVTFRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYFZhdWx0IGF0ICR7dmF1bHRQYXRofSBkaWQgbm90IGJlY29tZSByZWFkeSB3aXRoaW4gJHtTdHJpbmcoVkFVTFRfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXNgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTYW1wbGVzIHRoZSB2YXVsdCByZW5kZXJlcidzIGJvb3RzdHJhcCBzdGF0ZSBcdTIwMTQgd2hldGhlciB0aGUgZG9jdW1lbnQgaXNcbiAgICogYGNvbXBsZXRlYCwgd2hldGhlciBgd2luZG93LmFwcGAgZXhpc3RzLCBhbmQgdGhlIGA8Ym9keT5gIGNoaWxkIGNvdW50IFx1MjAxNCBmcm9tXG4gICAqIHRoZSBmaXJzdCBwYWdlIHRhcmdldCwgZm9yIGRlYWQtYm9vdCBkZXRlY3Rpb24uIFRoaXMgd29ya3MgZXZlbiB3aGVuIHRoZSBhcHBcbiAgICogbmV2ZXIgYm9vdHN0cmFwcGVkICh0aGUgcmVuZGVyZXIgcGFnZSB0YXJnZXQgc3RpbGwgZXhpc3RzKSwgd2hpY2ggaXMgZXhhY3RseVxuICAgKiB0aGUgc3RhdGUgaXQgbXVzdCBvYnNlcnZlLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgc2FtcGxlZCBvYnNlcnZhdGlvbiwgb3IgYHVuZGVmaW5lZGAgd2hlbiBubyB0YXJnZXQgaXMgcmVhY2hhYmxlXG4gICAqICAgb3IgdGhlIHByb2JlIGZhaWxlZCAoc28gdGhlIGNhbGxlciBrZWVwcyBwb2xsaW5nIHJhdGhlciB0aGFuIGZhc3QtZmFpbGluZykuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHByb2JlUmVuZGVyZXJCb290U3RhdGUoKTogUHJvbWlzZTxSZW5kZXJlckJvb3RPYnNlcnZhdGlvbiB8IHVuZGVmaW5lZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSAoYXdhaXQgdGhpcy5nZXRQYWdlVGFyZ2V0cygpKVswXTtcbiAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHdzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQodGFyZ2V0KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHByb2JlRXhwciA9IGBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgYm9keUNoaWxkRWxlbWVudENvdW50OiBkb2N1bWVudC5ib2R5ID8gZG9jdW1lbnQuYm9keS5jaGlsZEVsZW1lbnRDb3VudCA6IDAsXG4gICAgICAgICAgaGFzV2luZG93QXBwOiB0eXBlb2Ygd2luZG93LmFwcCAhPT0gJ3VuZGVmaW5lZCcsXG4gICAgICAgICAgaXNEb2N1bWVudENvbXBsZXRlOiBkb2N1bWVudC5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnXG4gICAgICAgIH0pYDtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRDb21tYW5kKHdzLCAnUnVudGltZS5ldmFsdWF0ZScsIHtcbiAgICAgICAgICBleHByZXNzaW9uOiBwcm9iZUV4cHIsXG4gICAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSByZXNwb25zZS5yZXN1bHQ/LnJlc3VsdD8udmFsdWU7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZSh2YWx1ZSkgYXMgUmVuZGVyZXJCb290T2JzZXJ2YXRpb247XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB3cy5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHJvYmVzIGEgdGFyZ2V0IHRvIGRpc2NvdmVyIHdoaWNoIHZhdWx0IHBhdGggaXQgaGFzIG9wZW4uXG4gICAqXG4gICAqIENyZWF0ZXMgYSB0ZW1wb3JhcnkgV2ViU29ja2V0IGNvbm5lY3Rpb24sIGV2YWx1YXRlcyBgZ2V0QmFzZVBhdGgoKWAsXG4gICAqIGFuZCByZXR1cm5zIHRoZSByZXN1bHQuXG4gICAqXG4gICAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgQ0RQIHRhcmdldCB0byBwcm9iZS5cbiAgICogQHJldHVybnMgVGhlIHZhdWx0J3MgYmFzZSBwYXRoLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9iZVZhdWx0UGF0aCh0YXJnZXQ6IENkcFRhcmdldCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3Qgd3MgPSBhd2FpdCB0aGlzLmNvbm5lY3RUb1RhcmdldCh0YXJnZXQpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuc2VuZENvbW1hbmQod3MsICdSdW50aW1lLmV2YWx1YXRlJywge1xuICAgICAgICBleHByZXNzaW9uOiAnYXBwLnZhdWx0LmFkYXB0ZXIuZ2V0QmFzZVBhdGgoKScsXG4gICAgICAgIHJldHVybkJ5VmFsdWU6IHRydWVcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIFN0cmluZyhyZXNwb25zZS5yZXN1bHQ/LnJlc3VsdD8udmFsdWUpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB3cy5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMYXVuY2hlcyBhbmQgY29ubmVjdHMgdG8gYSBoYXJuZXNzLW93bmVkLCBpc29sYXRlZCBPYnNpZGlhbiBpbnN0YW5jZSBmb3IgYVxuICAgKiB2YXVsdDogcHJvdmlzaW9ucyB0aGUgYXNhciAoaWYgYW55KSwgcHJlLXNlZWRzIHRoZSBpc29sYXRlZCBgb2JzaWRpYW4uanNvbmBcbiAgICogc28gdGhlIHZhdWx0IG9wZW5zIGRpcmVjdGx5LCBsYXVuY2hlcyB0aGUgaW5zdGFuY2Ugb24gYSBmcmVlIENEUCBwb3J0LCB0aGVuXG4gICAqIHdhaXRzIHVudGlsIHRoZSB2YXVsdCB3aW5kb3cgaXMgcmVhZHkgYW5kIGRpc21pc3NlcyB0aGUgdHJ1c3QgZGlhbG9nLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IGZvbGRlci5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVnaXN0ZXJWYXVsdEluT3duZWRJbnN0YW5jZSh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IGVuc3VyZU5vbk51bGxhYmxlKHRoaXMub3duZWRDb25maWcpO1xuXG4gICAgaWYgKHRoaXMub3duZWRJbnN0YW5jZSkge1xuICAgICAgLy8gQSBwcmlvciB2YXVsdCdzIGluc3RhbmNlIGlzIHN0aWxsIHJ1bm5pbmcgaW4gdGhpcyAocGVyLXdvcmtlciBjYWNoZWQpXG4gICAgICAvLyBUcmFuc3BvcnQuIFJlbGF1bmNoIGZyZXNoIGZvciB0aGUgbmV3IHZhdWx0OiByZWxhdW5jaGluZyBvdmVyIHRoZSBsaXZlXG4gICAgICAvLyBJbnN0YW5jZSBpcyBmb3J3YXJkZWQgYnkgRWxlY3Ryb24ncyBzaW5nbGUtaW5zdGFuY2UgbG9jayBvbiB0aGUgc2hhcmVkXG4gICAgICAvLyBVc2VyLWRhdGEgZGlyIGFuZCBzdXJmYWNlcyB0aGUgdmF1bHQgcGlja2VyLCBhbmQgb3BlbmluZyBhIHNlY29uZCB3aW5kb3dcbiAgICAgIC8vIFZpYSBJUEMgbGVhdmVzIHN0YWxlIHdpbmRvd3MgdGhhdCBicmVhayB2YXVsdC10YXJnZXQgcm91dGluZy4gU28ga2lsbCB0aGVcbiAgICAgIC8vIFJ1bm5pbmcgaW5zdGFuY2UsIHdhaXQgZm9yIGl0IHRvIGV4aXQgKHJlbGVhc2luZyB0aGUgbG9jayksIHRoZW4gbGF1bmNoXG4gICAgICAvLyBBZ2FpbiBiZWxvdyB3aXRoIHRoZSBuZXcgdmF1bHQgcHJlLXNlZWRlZCBcdTIwMTQgZWFjaCB2YXVsdCBnZXRzIGEgcHJpc3RpbmVcbiAgICAgIC8vIFNpbmdsZS13aW5kb3cgaW5zdGFuY2Ugb3BlbmVkIGRpcmVjdGx5LCBuZXZlciB0aGUgc2VsZWN0b3IuXG4gICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBSZWxhdW5jaGluZyBvd25lZCBpbnN0YW5jZSBmb3IgbmV3IHZhdWx0OiAke3ZhdWx0UGF0aH1gKTtcbiAgICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgICAgY29uc3QgcHJldmlvdXNDZHBVcmwgPSB0aGlzLmNkcFVybDtcbiAgICAgIHRoaXMub3duZWRJbnN0YW5jZS5raWxsKCk7XG4gICAgICB0aGlzLm93bmVkSW5zdGFuY2UgPSB1bmRlZmluZWQ7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JJbnN0YW5jZUV4aXQocHJldmlvdXNDZHBVcmwpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBMYXVuY2hpbmcgb3duZWQgT2JzaWRpYW4gaW5zdGFuY2UgZm9yIHZhdWx0OiAke3ZhdWx0UGF0aH1gKTtcbiAgICB9XG5cbiAgICBta2RpclN5bmMoY29uZmlnLnVzZXJEYXRhRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBpZiAoY29uZmlnLmFzYXIpIHtcbiAgICAgIGNvcHlBc2FySW50b1VzZXJEYXRhKGNvbmZpZy5hc2FyLnBhdGgsIGNvbmZpZy5hc2FyLnZlcnNpb24sIGNvbmZpZy51c2VyRGF0YURpcik7XG4gICAgfVxuXG4gICAgY29uc3QgdmF1bHRJZCA9IHJhbmRvbUJ5dGVzKFZBVUxUX0lEX0JZVEVfTEVOR1RIKS50b1N0cmluZygnaGV4Jyk7XG4gICAgY29uc3Qgb2JzaWRpYW5Kc29uID0ge1xuICAgICAgdXBkYXRlRGlzYWJsZWQ6IHRydWUsXG4gICAgICB2YXVsdHM6IHsgW3ZhdWx0SWRdOiB7IG9wZW46IHRydWUsIHBhdGg6IHZhdWx0UGF0aCwgdHM6IERhdGUubm93KCkgfSB9XG4gICAgfTtcbiAgICB3cml0ZUZpbGVTeW5jKGpvaW4oY29uZmlnLnVzZXJEYXRhRGlyLCAnb2JzaWRpYW4uanNvbicpLCBKU09OLnN0cmluZ2lmeShvYnNpZGlhbkpzb24pKTtcblxuICAgIGNvbnN0IGluc3RhbmNlID0gYXdhaXQgbGF1bmNoT3duZWRPYnNpZGlhbkluc3RhbmNlKHtcbiAgICAgIGNkcEhvc3Q6IHRoaXMuY2RwSG9zdCxcbiAgICAgIGV4ZVBhdGg6IGNvbmZpZy5leGVQYXRoLFxuICAgICAgZXh0cmFBcmdzOiBbXG4gICAgICAgIC4uLnJlc29sdmVPd25lZEhpZGRlbkxhdW5jaEFyZ3ModGhpcy5pc09ic2lkaWFuQXBwVmlzaWJsZSksXG4gICAgICAgIC4uLnJlc29sdmVTYW5kYm94TGF1bmNoQXJncyh0aGlzLnNob3VsZERpc2FibGVTYW5kYm94KVxuICAgICAgXSxcbiAgICAgIHVzZXJEYXRhRGlyOiBjb25maWcudXNlckRhdGFEaXJcbiAgICB9KTtcbiAgICB0aGlzLm93bmVkSW5zdGFuY2UgPSBpbnN0YW5jZTtcbiAgICB0aGlzLmNkcFBvcnQgPSBpbnN0YW5jZS5wb3J0O1xuICAgIHRoaXMuY2RwVXJsID0gaW5zdGFuY2UuY2RwVXJsO1xuXG4gICAgaWYgKHNob3VsZEhpZGVPYnNpZGlhbkFwcCh0aGlzLmlzT2JzaWRpYW5BcHBWaXNpYmxlKSkge1xuICAgICAgYXdhaXQgdGhpcy5tb3ZlT3duZWRXaW5kb3dPZmZzY3JlZW4oKTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLndhaXRGb3JPd25lZFZhdWx0UmVhZHkodmF1bHRQYXRoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBhIENEUCBjb21tYW5kIG92ZXIgV2ViU29ja2V0IGFuZCB3YWl0cyBmb3IgdGhlIHJlc3BvbnNlLlxuICAgKlxuICAgKiBAcGFyYW0gd3MgLSBUaGUgV2ViU29ja2V0IGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSBtZXRob2QgLSBUaGUgQ0RQIG1ldGhvZCBuYW1lLlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIENEUCBtZXRob2QgcGFyYW1ldGVycy5cbiAgICogQHJldHVybnMgVGhlIENEUCByZXNwb25zZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2VuZENvbW1hbmQod3M6IFdlYlNvY2tldCwgbWV0aG9kOiBzdHJpbmcsIHBhcmFtczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBQcm9taXNlPENkcFJlc3BvbnNlPiB7XG4gICAgY29uc3QgaWQgPSArK3RoaXMubWVzc2FnZUlkO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPENkcFJlc3BvbnNlPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHdzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBoYW5kbGVyKTtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgQ0RQIGNvbW1hbmQgdGltZWQgb3V0IGFmdGVyICR7U3RyaW5nKHRoaXMuY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXM6ICR7bWV0aG9kfWApKTtcbiAgICAgIH0sIHRoaXMuY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyk7XG5cbiAgICAgIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IE1lc3NhZ2VFdmVudCk6IHZvaWQge1xuICAgICAgICBjb25zdCBtc2cgPSBKU09OLnBhcnNlKFN0cmluZyhldmVudC5kYXRhKSkgYXMgQ2RwUmVzcG9uc2U7XG4gICAgICAgIGlmIChtc2cuaWQgPT09IGlkKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICAgIHdzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBoYW5kbGVyKTtcbiAgICAgICAgICByZXNvbHZlKG1zZyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgd3MuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGhhbmRsZXIpO1xuICAgICAgd3Muc2VuZChKU09OLnN0cmluZ2lmeSh7IGlkLCBtZXRob2QsIHBhcmFtcyB9KSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUG9sbHMgYSBraWxsZWQgb3duZWQgaW5zdGFuY2UncyBDRFAgZW5kcG9pbnQgdW50aWwgaXQgc3RvcHMgcmVzcG9uZGluZyxcbiAgICogY29uZmlybWluZyB0aGUgcHJvY2VzcyBoYXMgZXhpdGVkIGFuZCByZWxlYXNlZCBFbGVjdHJvbidzIHNpbmdsZS1pbnN0YW5jZVxuICAgKiBsb2NrIG9uIHRoZSBzaGFyZWQgdXNlci1kYXRhIGRpciBiZWZvcmUgYSBmcmVzaCBpbnN0YW5jZSBpcyBsYXVuY2hlZCBpbnRvIGl0LlxuICAgKlxuICAgKiBAcGFyYW0gY2RwVXJsIC0gVGhlIENEUCBVUkwgb2YgdGhlIGluc3RhbmNlIHRoYXQgd2FzIGp1c3Qga2lsbGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9ySW5zdGFuY2VFeGl0KGNkcFVybDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gV2FpdGluZyBmb3IgcHJldmlvdXMgb3duZWQgaW5zdGFuY2UgYXQgJHtjZHBVcmx9IHRvIGV4aXQuLi5gKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYCR7Y2RwVXJsfS9qc29uYCk7XG4gICAgICAgIGF3YWl0IHJlc3BvbnNlLmJvZHk/LmNhbmNlbCgpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIFRoZSBlbmRwb2ludCBpcyBnb25lOiB0aGUgcHJvY2VzcyBoYXMgZXhpdGVkIGFuZCByZWxlYXNlZCB0aGUgbG9jay5cbiAgICAgICAgYXdhaXQgZGVsYXkoSU5TVEFOQ0VfRVhJVF9TRVRUTEVfREVMQVlfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYXdhaXQgZGVsYXkoVkFVTFRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cbiAgICBsb2coJ1tjZHAtdHJhbnNwb3J0XSBQcmV2aW91cyBpbnN0YW5jZSBzdGlsbCByZXNwb25kZWQgYmVmb3JlIHRpbWVvdXQ7IHJlbGF1bmNoaW5nIGFueXdheS4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXYWl0cyBmb3IgdGhlIHZhdWx0J3MgYGFwcC53b3Jrc3BhY2VgIHRvIHJlYWNoIGxheW91dC1yZWFkeSBzdGF0ZS5cbiAgICpcbiAgICogYGZpbmRUYXJnZXRGb3JWYXVsdGAgcmV0dXJucyBhcyBzb29uIGFzIGBhcHAudmF1bHQuYWRhcHRlci5nZXRCYXNlUGF0aCgpYFxuICAgKiBtYXRjaGVzIFx1MjAxNCB3aGljaCBpcyB0cnVlIHNob3J0bHkgYWZ0ZXIgdGhlIGBBcHBgIGNvbnN0cnVjdG9yIHJ1bnMsIGJlZm9yZVxuICAgKiBgcGx1Z2lucy5pbml0aWFsaXplKClgIChhbmQgYW55IHRydXN0IGRpYWxvZykgaGFzIGV4ZWN1dGVkLiBCb290c3RyYXBwaW5nXG4gICAqIHRoZSBuYW1lc3BhY2UgYW5kIGNhbGxpbmcgYHBvbGxWYXVsdEJhc2VQYXRoKClgIGF3YWl0cyBgbGF5b3V0UmVhZHlgLCBzb1xuICAgKiBieSB0aGUgdGltZSB0aGlzIHJldHVybnMgdGhlIGRpYWxvZyBoYXMgZWl0aGVyIHJlbmRlcmVkIG9yIGlzIG5vdCBnb2luZ1xuICAgKiB0byByZW5kZXIuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgdmF1bHQgcGF0aCB0byBldmFsdWF0ZSBpbi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvckxheW91dFJlYWR5KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgZW5zdXJlTmFtZXNwYWNlQm9vdHN0cmFwcGVkKHRoaXMsIHZhdWx0UGF0aCk7XG4gICAgYXdhaXQgdGhpcy5ldmFsdWF0ZSgnd2luZG93Ll9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcucG9sbFZhdWx0QmFzZVBhdGgoKScsIHsgY3dkOiB2YXVsdFBhdGggfSk7XG4gIH1cblxuICAvKipcbiAgICogUG9sbHMgdGhlIG93bmVkIGluc3RhbmNlIHVudGlsIHRoZSB2YXVsdCB0YXJnZXQgZXhpc3RzLCBsYXlvdXQgaXMgcmVhZHksIGFuZFxuICAgKiB0aGUgdHJ1c3QgZGlhbG9nIChpZiBhbnkpIGhhcyBiZWVuIGRpc21pc3NlZC5cbiAgICpcbiAgICogQmV0d2VlbiByZWFkaW5lc3MgYXR0ZW1wdHMgaXQgYWxzbyBjaGVja3MgZm9yIGEgKipkZWFkIGJvb3QqKiBcdTIwMTQgdGhlIHJlbmRlcmVyXG4gICAqIGxvYWRlZCAoYGRvY3VtZW50LnJlYWR5U3RhdGVgIGAnY29tcGxldGUnYCkgYnV0IHRoZSBhcHAgbmV2ZXIgYm9vdHN0cmFwcGVkXG4gICAqIChlbXB0eSBgPGJvZHk+YCwgbm8gYHdpbmRvdy5hcHBgKSwgdGhlIHRlcm1pbmFsIHN0YXRlIHdoZW4gdGhlIGFzYXIgY2Fubm90XG4gICAqIHJ1biBvbiB0aGUgbGF1bmNoZWQgRWxlY3Ryb24gc2hlbGwuIE9uY2UgdGhhdCBzdGF0ZSBoYXMgaGVsZCBmb3IgdGhlXG4gICAqIGNvbmZpZ3VyZWQgZ3JhY2Ugd2luZG93IGl0IHRocm93cyBhIHtAbGluayBSZW5kZXJlckZhaWxlZFRvSW5pdGlhbGl6ZUVycm9yfVxuICAgKiBpbW1lZGlhdGVseSBpbnN0ZWFkIG9mIHdhaXRpbmcgb3V0IHRoZSBmdWxsIHJlYWRpbmVzcyB0aW1lb3V0LiBBIGdyYWNlIG9mXG4gICAqIGAwYCBkaXNhYmxlcyB0aGUgZmFzdC1mYWlsLiBUaGUgZ3JhY2UgY2xvY2sgc3RhcnRzIHdoZW4gdGhlIHJlbmRlcmVyIGZpcnN0XG4gICAqIHJlcG9ydHMgYGNvbXBsZXRlYCwgc28gYSBzbG93IGxvYWQgYmVmb3JlIHRoZW4gaXMgbmV2ZXIgY291bnRlZCBhZ2FpbnN0IGl0LlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IGZvbGRlci5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvck93bmVkVmF1bHRSZWFkeSh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIFdhaXRpbmcgZm9yIG93bmVkIHZhdWx0IHRvIGJlY29tZSByZWFkeSAodGltZW91dD0ke1N0cmluZyhWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcykuLi5gKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIGxldCBkb2N1bWVudENvbXBsZXRlU2luY2U6IG51bGwgfCBudW1iZXIgPSBudWxsO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZmluZFRhcmdldEZvclZhdWx0KHZhdWx0UGF0aCk7XG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvckxheW91dFJlYWR5KHZhdWx0UGF0aCk7XG4gICAgICAgIGF3YWl0IHRoaXMuZGlzbWlzc1RydXN0RGlhbG9nKHZhdWx0UGF0aCk7XG4gICAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIE93bmVkIHZhdWx0IGlzIHJlYWR5LicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gVmF1bHQgdGFyZ2V0IG5vdCByZWFkeSB5ZXQuXG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kcyA+IDApIHtcbiAgICAgICAgY29uc3Qgb2JzZXJ2YXRpb24gPSBhd2FpdCB0aGlzLnByb2JlUmVuZGVyZXJCb290U3RhdGUoKTtcbiAgICAgICAgaWYgKG9ic2VydmF0aW9uKSB7XG4gICAgICAgICAgaWYgKG9ic2VydmF0aW9uLmlzRG9jdW1lbnRDb21wbGV0ZSAmJiBkb2N1bWVudENvbXBsZXRlU2luY2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGRvY3VtZW50Q29tcGxldGVTaW5jZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGhhc0dyYWNlRWxhcHNlZCA9IGRvY3VtZW50Q29tcGxldGVTaW5jZSAhPT0gbnVsbFxuICAgICAgICAgICAgJiYgRGF0ZS5ub3coKSAtIGRvY3VtZW50Q29tcGxldGVTaW5jZSA+PSB0aGlzLmRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kcztcbiAgICAgICAgICBpZiAoY2hlY2tSZW5kZXJlckJvb3RTdGF0ZSh7IC4uLm9ic2VydmF0aW9uLCBoYXNHcmFjZUVsYXBzZWQgfSkgPT09ICdkZWFkJykge1xuICAgICAgICAgICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gT3duZWQgcmVuZGVyZXIgZmFpbGVkIHRvIGluaXRpYWxpemUgKGRlYWQgYm9vdCk7IGZhaWxpbmcgZmFzdC4nKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBSZW5kZXJlckZhaWxlZFRvSW5pdGlhbGl6ZUVycm9yKHZhdWx0UGF0aCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGRlbGF5KFZBVUxUX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBPd25lZCB2YXVsdCBhdCAke3ZhdWx0UGF0aH0gZGlkIG5vdCBiZWNvbWUgcmVhZHkgd2l0aGluICR7U3RyaW5nKFZBVUxUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMpfW1zYCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIHRoZSBnaXZlbiBkZWxheS5cbiAqXG4gKiBAcGFyYW0gbXMgLSBUaGUgZGVsYXkgaW4gbWlsbGlzZWNvbmRzLlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIGRlbGF5LlxuICovXG5mdW5jdGlvbiBkZWxheShtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBwbGF0Zm9ybS1zcGVjaWZpYyBjb21tYW5kIHRvIGxhdW5jaCBPYnNpZGlhbiB3aXRoIHJlbW90ZSBkZWJ1Z2dpbmcgZW5hYmxlZC5cbiAqXG4gKiBSZXNvbHZlcyB0aGUgYWN0dWFsIGluc3RhbGxlZCBPYnNpZGlhbiBleGVjdXRhYmxlIChjb3ZlcmluZyBpbnN0YWxsZXItYmFzZWRcbiAqIGFuZCBgUEFUSGAtYmFzZWQgaW5zdGFsbHMgc3VjaCBhcyBgc2Nvb3BgKSBhbmQgdmVyaWZpZXMgaXQgZXhpc3RzIGJlZm9yZVxuICogcmV0dXJuaW5nIGEgY29tbWFuZC4gVGhyb3dzIGlmIE9ic2lkaWFuIGlzIG5vdCBpbnN0YWxsZWQuXG4gKlxuICogQHBhcmFtIHBvcnQgLSBUaGUgQ0RQIHBvcnQgdG8gdXNlLlxuICogQHJldHVybnMgVGhlIHNoZWxsIGNvbW1hbmQgc3RyaW5nLlxuICogQHRocm93cyBFcnJvciBpZiBPYnNpZGlhbiBjYW5ub3QgYmUgbG9jYXRlZC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZ2V0T2JzaWRpYW5MYXVuY2hDb21tYW5kKHBvcnQ6IG51bWJlcik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGV4ZVBhdGggPSBhd2FpdCByZXNvbHZlT2JzaWRpYW5FeGVjdXRhYmxlKCk7XG4gIGNvbnN0IGZsYWcgPSBgLS1yZW1vdGUtZGVidWdnaW5nLXBvcnQ9JHtTdHJpbmcocG9ydCl9YDtcblxuICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJykge1xuICAgIHJldHVybiBgc3RhcnQgXCJcIiBcIiR7ZXhlUGF0aH1cIiAke2ZsYWd9YDtcbiAgfVxuXG4gIHJldHVybiBgXCIke2V4ZVBhdGh9XCIgJHtmbGFnfSAmYDtcbn1cblxuLyoqXG4gKiBBdHRlbXB0cyB0byByZW1vdmUgYSBkaXJlY3RvcnkgcmVjdXJzaXZlbHksIHJldHVybmluZyB3aGV0aGVyIGl0IHN1Y2NlZWRlZC5cbiAqXG4gKiBAcGFyYW0gZGlyIC0gVGhlIGRpcmVjdG9yeSB0byByZW1vdmUuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgcmVtb3ZlZCwgYGZhbHNlYCBpZiB0aGUgcmVtb3ZhbCB0aHJldyAoZS5nLiBoYW5kbGVzIGhlbGQpLlxuICovXG5mdW5jdGlvbiB0cnlSZW1vdmVEaXIoZGlyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICBybVN5bmMoZGlyLCB7IGZvcmNlOiB0cnVlLCByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFxQkEseUJBQTRCO0FBQzVCLHFCQUlPO0FBQ1AsdUJBQXFCO0FBQ3JCLDBCQUFvQjtBQVVwQixrQ0FBMEM7QUFDMUMsa0JBQXFCO0FBQ3JCLGlCQUFvQjtBQUNwQixpQ0FBNEM7QUFDNUMsNkJBSU87QUFDUCxpQ0FBMEM7QUFDMUMsK0JBQTRDO0FBQzVDLHFDQUFxQztBQUNyQyxxQ0FHTztBQUNQLGlEQUFnRDtBQUNoRCx5QkFBa0M7QUFDbEMsd0JBSU87QUFvSlAsTUFBTSxrQ0FBa0M7QUFDeEMsTUFBTSx1QkFBdUI7QUFDN0IsTUFBTSx1Q0FBdUM7QUFDN0MsTUFBTSw4Q0FBOEM7QUFDcEQsTUFBTSxZQUFZO0FBQ2xCLE1BQU0sc0NBQXNDO0FBQzVDLE1BQU0scUNBQXFDO0FBQzNDLE1BQU0sb0NBQW9DO0FBQzFDLE1BQU0sMkNBQTJDO0FBQ2pELE1BQU0scUNBQXFDO0FBQzNDLE1BQU0sNkNBQTZDO0FBQ25ELE1BQU0sMENBQTBDO0FBQ2hELE1BQU0sNENBQTRDO0FBQ2xELE1BQU0sa0RBQWtEO0FBUWpELE1BQU0sb0JBQWlEO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFJNUMsV0FBVztBQUFBLEVBQ25CLGtCQUFpQztBQUFBLEVBQ3hCO0FBQUEsRUFDVDtBQUFBLEVBQ0E7QUFBQSxFQUNTO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDVCxZQUFZO0FBQUEsRUFDSDtBQUFBLEVBQ1Q7QUFBQSxFQUNTO0FBQUEsRUFDVCxLQUF1QjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU94QixZQUFZLFFBQW9DO0FBQ3JELFNBQUssVUFBVSxRQUFRLFdBQVc7QUFDbEMsU0FBSywrQkFBK0IsUUFBUSxnQ0FBZ0M7QUFDNUUsU0FB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
943
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1kZXNrdG9wLWNkcC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIERlc2t0b3AgQ0RQIHRyYW5zcG9ydCBcdTIwMTQgZXZhbHVhdGVzIGV4cHJlc3Npb25zIHZpYSBDaHJvbWUgRGV2VG9vbHMgUHJvdG9jb2xcbiAqIG92ZXIgV2ViU29ja2V0IGFuZCBtYW5hZ2VzIHZhdWx0cyB2aWEgRWxlY3Ryb24gSVBDLlxuICpcbiAqIFR3byBtb2RlczpcbiAqIC0gKipPd25lZCAoZGVmYXVsdCkqKjogdGhlIHRyYW5zcG9ydCBsYXVuY2hlcyBhbmQgb3ducyBhbiBpc29sYXRlZCBPYnNpZGlhblxuICogICBpbnN0YW5jZSBhZ2FpbnN0IGEgdGVtcG9yYXJ5IGAtLXVzZXItZGF0YS1kaXJgIG9uIGEgZnJlZSBgLS1yZW1vdGUtZGVidWdnaW5nLXBvcnRgLFxuICogICBuZXZlciB0b3VjaGluZyB0aGUgdXNlcidzIE9ic2lkaWFuLiBTdXBwb3J0cyB2ZXJzaW9uIHBpbm5pbmcgdmlhIHRoZSB1c2VyLWRhdGEgYXNhci5cbiAqIC0gKipBdHRhY2gqKjogd2hlbiBhbiBleHBsaWNpdCBDRFAgcG9ydCBpcyBjb25maWd1cmVkLCB0aGUgdHJhbnNwb3J0IGNvbm5lY3RzXG4gKiAgIHRvIGFuIGFscmVhZHktcnVubmluZyBPYnNpZGlhbiBvbiB0aGF0IHBvcnQuXG4gKlxuICogSXQgY29ubmVjdHMgdG8gcGFnZSB0YXJnZXRzLCBzZW5kcyBgUnVudGltZS5ldmFsdWF0ZWAgY29tbWFuZHMsIGFuZCByb3V0ZXMgdG9cbiAqIHRoZSBjb3JyZWN0IHZhdWx0IHRhcmdldCB1c2luZyBgZ2V0QmFzZVBhdGgoKWAgcHJvYmluZy5cbiAqXG4gKiBSZXF1aXJlbWVudHM6IE5vZGUuanMgMjIrICh1c2VzIGJ1aWx0LWluIGBXZWJTb2NrZXRgIGFuZCBgZmV0Y2hgIGdsb2JhbHMpLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGNvZGUgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtcbiAgbWtkaXJTeW5jLFxuICBybVN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbmltcG9ydCB0eXBlIHsgQXNhckZhbGxiYWNrIH0gZnJvbSAnLi9hc2FyLWZhbGxiYWNrLWRldGVjdGlvbi5janMnO1xuaW1wb3J0IHR5cGUgeyBFbGVjdHJvbkNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2VsZWN0cm9uLWNvbXBhdGliaWxpdHkuY2pzJztcbmltcG9ydCB0eXBlIHsgSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSB9IGZyb20gJy4vaW5zdGFsbGVyLWNvbXBhdGliaWxpdHkuY2pzJztcbmltcG9ydCB0eXBlIHsgT3duZWRPYnNpZGlhbkluc3RhbmNlIH0gZnJvbSAnLi9vYnNpZGlhbi1pbnN0YW5jZS5janMnO1xuaW1wb3J0IHR5cGUgeyBSZW5kZXJlckJvb3RPYnNlcnZhdGlvbiB9IGZyb20gJy4vcmVuZGVyZXItYm9vdC1kZXRlY3Rpb24uY2pzJztcbmltcG9ydCB0eXBlIHtcbiAgT2JzaWRpYW5UcmFuc3BvcnQsXG4gIFRyYW5zcG9ydEV2YWxPcHRpb25zXG59IGZyb20gJy4vdHJhbnNwb3J0LmNqcyc7XG5cbmltcG9ydCB7IGNoZWNrQXNhckZhbGxiYWNrIH0gZnJvbSAnLi9hc2FyLWZhbGxiYWNrLWRldGVjdGlvbi5janMnO1xuaW1wb3J0IHsgcmVzb2x2ZUFzYXJGYWxsYmFja0FjdGlvbiB9IGZyb20gJy4vY29tcGF0aWJpbGl0eS1vcHRpb25zLmNqcyc7XG5pbXBvcnQgeyBESVNNSVNTX1RSVVNUX0RJQUxPR19FWFBSIH0gZnJvbSAnLi9kaXNtaXNzLXRydXN0LWRpYWxvZy5janMnO1xuaW1wb3J0IHsgY2hlY2tFbGVjdHJvbkNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2VsZWN0cm9uLWNvbXBhdGliaWxpdHkuY2pzJztcbmltcG9ydCB7IGV4ZWMgfSBmcm9tICcuL2V4ZWMuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5pbXBvcnQgeyBlbnN1cmVOYW1lc3BhY2VCb290c3RyYXBwZWQgfSBmcm9tICcuL25hbWVzcGFjZS1ib290c3RyYXAuY2pzJztcbmltcG9ydCB7XG4gIGdldFZhdWx0SWQsXG4gIGlzVmF1bHRSZWdpc3RlcmVkLFxuICByZW1vdmVWYXVsdEZyb21Db25maWdcbn0gZnJvbSAnLi9vYnNpZGlhbi1jb25maWcuY2pzJztcbmltcG9ydCB7IHJlc29sdmVPYnNpZGlhbkV4ZWN1dGFibGUgfSBmcm9tICcuL29ic2lkaWFuLWV4ZWN1dGFibGUuY2pzJztcbmltcG9ydCB7IGxhdW5jaE93bmVkT2JzaWRpYW5JbnN0YW5jZSB9IGZyb20gJy4vb2JzaWRpYW4taW5zdGFuY2UuY2pzJztcbmltcG9ydCB7IGdldFZlcnNpb25NZXRhZGF0YSB9IGZyb20gJy4vb2JzaWRpYW4tbWV0YWRhdGEuY2pzJztcbmltcG9ydCB7IGNvcHlBc2FySW50b1VzZXJEYXRhIH0gZnJvbSAnLi9vYnNpZGlhbi12ZXJzaW9uLXN3aXRjaC5janMnO1xuaW1wb3J0IHsgYnVpbGRPd25lZE9ic2lkaWFuSnNvbiB9IGZyb20gJy4vb3duZWQtdmF1bHQtc2VlZC5janMnO1xuaW1wb3J0IHtcbiAgY2hlY2tSZW5kZXJlckJvb3RTdGF0ZSxcbiAgREVGQVVMVF9ERUFEX0JPT1RfR1JBQ0VfSU5fTUlMTElTRUNPTkRTXG59IGZyb20gJy4vcmVuZGVyZXItYm9vdC1kZXRlY3Rpb24uY2pzJztcbmltcG9ydCB7IFJlbmRlcmVyRmFpbGVkVG9Jbml0aWFsaXplRXJyb3IgfSBmcm9tICcuL3JlbmRlcmVyLWZhaWxlZC10by1pbml0aWFsaXplLWVycm9yLmNqcyc7XG5pbXBvcnQgeyBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvciB9IGZyb20gJy4vc2lsZW50LWFzYXItZmFsbGJhY2stZXJyb3IuY2pzJztcbmltcG9ydCB7IGVuc3VyZU5vbk51bGxhYmxlIH0gZnJvbSAnLi90eXBlLWd1YXJkcy5janMnO1xuaW1wb3J0IHtcbiAgcmVzb2x2ZU93bmVkSGlkZGVuTGF1bmNoQXJncyxcbiAgcmVzb2x2ZVNhbmRib3hMYXVuY2hBcmdzLFxuICBzaG91bGRIaWRlT2JzaWRpYW5BcHBcbn0gZnJvbSAnLi92aXNpYmlsaXR5LmNqcyc7XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIENEUCB0cmFuc3BvcnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGVza3RvcENkcFRyYW5zcG9ydENvbmZpZyB7XG4gIC8qKlxuICAgKiBDRFAgaG9zdC4gRGVmYXVsdHMgdG8gYCdsb2NhbGhvc3QnYC5cbiAgICovXG4gIGNkcEhvc3Q/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENEUCBwb3J0IGZvciAqKmF0dGFjaCoqIG1vZGUgKHRoZSBgLS1yZW1vdGUtZGVidWdnaW5nLXBvcnRgIHRoZSBydW5uaW5nXG4gICAqIE9ic2lkaWFuIHdhcyBsYXVuY2hlZCB3aXRoKS4gSW4gb3duZWQtaW5zdGFuY2UgbW9kZSB0aGlzIGlzIGlnbm9yZWQgXHUyMDE0IGFcbiAgICogZnJlZSBwb3J0IGlzIGNob3NlbiBhdCBsYXVuY2guXG4gICAqL1xuICBjZHBQb3J0PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3IgaW5kaXZpZHVhbCBDRFAgY29tbWFuZHMuXG4gICAqIERlZmF1bHRzIHRvIGAzMDAwMGAuXG4gICAqL1xuICBjb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBHcmFjZSB3aW5kb3cgaW4gbWlsbGlzZWNvbmRzIGZvciBmYXN0LWZhaWxpbmcgYSBkZWFkIGJvb3Qgb2YgdGhlIG93bmVkXG4gICAqIGluc3RhbmNlIChlbXB0eSBgPGJvZHk+YCB3aXRoIG5vIGB3aW5kb3cuYXBwYCBhZnRlciB0aGUgcmVuZGVyZXIgcmVhY2hlZFxuICAgKiBgZG9jdW1lbnQucmVhZHlTdGF0ZWAgYCdjb21wbGV0ZSdgKS4gRGVmYXVsdHMgdG9cbiAgICoge0BsaW5rIERFRkFVTFRfREVBRF9CT09UX0dSQUNFX0lOX01JTExJU0VDT05EU30uIGAwYCBkaXNhYmxlcyBmYXN0LWZhaWwuXG4gICAqL1xuICBkZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFdoZW4gYXR0YWNoaW5nIChpLmUuIHtAbGluayBjZHBQb3J0fSBpcyBzZXQpLCBtYXJrcyB0aGUgdGFyZ2V0IGFzIGFcbiAgICogKipoYXJuZXNzLW93bmVkLCBhbHJlYWR5LXByZXBhcmVkKiogaW5zdGFuY2UuIFN1cHByZXNzZXMgdGhlIHVzZXItc2NvcGVcbiAgICogdmF1bHQtcmVnaXN0cmF0aW9uIHByZWZsaWdodCwgc2luY2UgdGhlIG93bmVkIGluc3RhbmNlJ3MgdmF1bHQgbGl2ZXMgaW4gYW5cbiAgICogaXNvbGF0ZWQgdXNlci1kYXRhIGNvbmZpZyByYXRoZXIgdGhhbiB0aGUgdXNlci1zY29wZSByZWdpc3RyeS5cbiAgICovXG4gIGlzSGFybmVzc093bmVkSW5zdGFuY2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBvd25lZCBPYnNpZGlhbiB3aW5kb3cgaXMgc2hvd24gb24gc2NyZWVuLiBXaGVuIGBmYWxzZWAgKHRoZVxuICAgKiBkZWZhdWx0KSwgdGhlIG93bmVkIGluc3RhbmNlIGlzIGxhdW5jaGVkIHdpdGgga2VlcC1hbGl2ZSBDaHJvbWl1bSBmbGFncyBhbmRcbiAgICogaXRzIHdpbmRvdyBpcyBtb3ZlZCBvZmYtc2NyZWVuIGFmdGVyIGxhdW5jaC4gT25seSBtZWFuaW5nZnVsIGluIG93bmVkIG1vZGU7XG4gICAqIGF0dGFjaCBtb2RlIG5ldmVyIHRvdWNoZXMgdGhlICh1c2VyJ3MpIHdpbmRvdy5cbiAgICpcbiAgICogQGRlZmF1bHQgYHRydWVgXG4gICAqL1xuICBpc09ic2lkaWFuQXBwVmlzaWJsZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZW4gc2V0LCB0aGUgdHJhbnNwb3J0IGxhdW5jaGVzIGFuZCBvd25zIGFuIGlzb2xhdGVkIE9ic2lkaWFuIGluc3RhbmNlXG4gICAqIGluc3RlYWQgb2YgYXR0YWNoaW5nIHRvIGEgcnVubmluZyBvbmUuIFRoaXMgaXMgdGhlIGRlZmF1bHQgZGVza3RvcCBtb2RlLlxuICAgKi9cbiAgb3duZWRJbnN0YW5jZT86IE93bmVkSW5zdGFuY2VDb25maWc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gbGF1bmNoIHRoZSBvd25lZCBpbnN0YW5jZSB3aXRoIENocm9taXVtJ3Mgc2FuZGJveCBkaXNhYmxlZFxuICAgKiAoYC0tbm8tc2FuZGJveGApLiBOZWVkZWQgdG8gYm9vdCBvbiBMaW51eCB3aXRob3V0IGEgY29ycmVjdGx5LWNvbmZpZ3VyZWRcbiAgICogc2V0dWlkIGBjaHJvbWUtc2FuZGJveGAgaGVscGVyIChlLmcuIGFuIGV4dHJhY3RlZCBwb3J0YWJsZSBzaGVsbCwgb3IgQ0kgYXMgYVxuICAgKiBub24tcm9vdCB1c2VyKTsgaGFybWxlc3Mgb24gV2luZG93cy9tYWNPUy4gT25seSBtZWFuaW5nZnVsIGluIG93bmVkIG1vZGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IGBmYWxzZWBcbiAgICovXG4gIHNob3VsZERpc2FibGVTYW5kYm94PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciBhIHBvc3QtYm9vdCAqKnNpbGVudCBhc2FyIGZhbGxiYWNrKiogKHRoZSBydW5uaW5nIGFwcCB2ZXJzaW9uIGRpZmZlcnNcbiAgICogZnJvbSB0aGUgc3dhcHBlZC1pbiBwaW4pIGZhaWxzIGZhc3Qgd2l0aCB7QGxpbmsgU2lsZW50QXNhckZhbGxiYWNrRXJyb3J9LiBUaGVcbiAgICogdmVyZGljdCBpcyBhbHdheXMgY29tcHV0ZWQgYW5kIHN1cmZhY2VkIHZpYVxuICAgKiB7QGxpbmsgRGVza3RvcENkcFRyYW5zcG9ydC5nZXRBc2FyRmFsbGJhY2t9OyB0aGlzIGdhdGVzIG9ubHkgdGhlIHRocm93LiBPbmx5XG4gICAqIG1lYW5pbmdmdWwgaW4gb3duZWQgbW9kZSBydW5uaW5nIGEgc3dhcHBlZC1pbiBhc2FyLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdHJ1ZWBcbiAgICovXG4gIHNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2s/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBwb3N0LWJvb3QgcnVudGltZS1FbGVjdHJvbiBjb21wYXRpYmlsaXR5IG5hZyB3YXJuaW5nIGlzIGVtaXR0ZWRcbiAgICogd2hlbiB0aGUgbGl2ZSBFbGVjdHJvbiBpcyBiZWxvdyB0aGUgYXBwJ3MgcmVjb21tZW5kZWQgbWluaW11bS4gVGhlIHZlcmRpY3QgaXNcbiAgICogYWx3YXlzIGNvbXB1dGVkIGFuZCBzdXJmYWNlZCB2aWEge0BsaW5rIERlc2t0b3BDZHBUcmFuc3BvcnQuZ2V0RWxlY3Ryb25Db21wYXRpYmlsaXR5fTtcbiAgICogdGhpcyBvbmx5IGdhdGVzIHRoZSBsb2cuIE9ubHkgbWVhbmluZ2Z1bCBpbiBvd25lZCBtb2RlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdHJ1ZWBcbiAgICovXG4gIHNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXM/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEFuIGFzYXIgdG8gcHJvdmlzaW9uIGludG8gYSBoYXJuZXNzLW93bmVkIGluc3RhbmNlJ3MgdXNlci1kYXRhIGRpciBiZWZvcmUgbGF1bmNoLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE93bmVkSW5zdGFuY2VBc2FyIHtcbiAgLyoqIEFic29sdXRlIHBhdGggdG8gdGhlIGNhY2hlZC9zb3VyY2UgYXNhciBmaWxlLiAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSBhc2FyJ3MgYHgueS56YCB2ZXJzaW9uLiAqL1xuICByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgYSBoYXJuZXNzLW93bmVkLCBpc29sYXRlZCBPYnNpZGlhbiBpbnN0YW5jZS5cbiAqXG4gKiBXaGVuIHByZXNlbnQsIHRoZSB0cmFuc3BvcnQgbGF1bmNoZXMgYW5kIG93bnMgaXRzIG93biBPYnNpZGlhbiBwcm9jZXNzXG4gKiBhZ2FpbnN0IGFuIGlzb2xhdGVkIHVzZXItZGF0YSBkaXIgaW5zdGVhZCBvZiBhdHRhY2hpbmcgdG8gYSBydW5uaW5nIGluc3RhbmNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE93bmVkSW5zdGFuY2VDb25maWcge1xuICAvKiogT3B0aW9uYWwgYXNhciB0byBwcm92aXNpb24gaW50byB7QGxpbmsgdXNlckRhdGFEaXJ9IGJlZm9yZSBsYXVuY2guICovXG4gIHJlYWRvbmx5IGFzYXI/OiBPd25lZEluc3RhbmNlQXNhciB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIHJlc29sdmVkIGluc3RhbGxlclx1MjE5NGFwcCBjb21wYXRpYmlsaXR5IHZlcmRpY3QsIHdoZW4gaXQgY291bGQgYmUgZGV0ZXJtaW5lZFxuICAgKiAoYW4gYXNhci1zd2FwIG9udG8gYSBrbm93biBzaGVsbCB2ZXJzaW9uKS4gU3VyZmFjZWQgYnlcbiAgICoge0BsaW5rIERlc2t0b3BDZHBUcmFuc3BvcnQuZ2V0Q29tcGF0aWJpbGl0eX0uIEFuIGAndW5ydW5uYWJsZSdgIHZlcmRpY3QgcmVhY2hlc1xuICAgKiB0aGlzIHN1cmZhY2Ugb25seSB3aGVuIHRoZSBwcm9hY3RpdmUgdGhyb3cgaXMgZGlzYWJsZWRcbiAgICogKGBzaG91bGRUaHJvd09uSW5jb21wYXRpYmxlSW5zdGFsbGVyOiBmYWxzZWApOyBvdGhlcndpc2UgaXQgdGhyb3dzXG4gICAqIGBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3JgIGJlZm9yZSB0aGUgY29uZmlnIGlzIGJ1aWx0LlxuICAgKi9cbiAgcmVhZG9ubHkgY29tcGF0aWJpbGl0eT86IEluc3RhbGxlckNvbXBhdGliaWxpdHkgfCB1bmRlZmluZWQ7XG5cbiAgLyoqIEFic29sdXRlIHBhdGggdG8gdGhlIE9ic2lkaWFuIHNoZWxsIGV4ZWN1dGFibGUgdG8gbGF1bmNoLiAqL1xuICByZWFkb25seSBleGVQYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFic29sdXRlIHBhdGggdG8gdGhlIGlzb2xhdGVkIHVzZXItZGF0YSBkaXIuIENyZWF0ZWQgYW5kIG93bmVkIGJ5IHRoZVxuICAgKiB0cmFuc3BvcnQsIGFuZCBkZWxldGVkIG9uIGRpc3Bvc2UuXG4gICAqL1xuICByZWFkb25seSB1c2VyRGF0YURpcjogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgQ2RwRXhjZXB0aW9uRGV0YWlscyB7XG4gIGV4Y2VwdGlvbj86IENkcEV4Y2VwdGlvbk9iamVjdDtcbiAgdGV4dDogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgQ2RwRXhjZXB0aW9uT2JqZWN0IHtcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBDZHBSZXNwb25zZSB7XG4gIGlkOiBudW1iZXI7XG4gIHJlc3VsdD86IENkcFJlc3BvbnNlUmVzdWx0O1xufVxuXG5pbnRlcmZhY2UgQ2RwUmVzcG9uc2VSZXN1bHQge1xuICByZWFkb25seSBleGNlcHRpb25EZXRhaWxzPzogQ2RwRXhjZXB0aW9uRGV0YWlscztcbiAgcmVhZG9ubHkgcmVzdWx0PzogQ2RwVmFsdWU7XG59XG5cbmludGVyZmFjZSBDZHBUYXJnZXQge1xuICBpZDogc3RyaW5nO1xuICB0aXRsZTogc3RyaW5nO1xuICB0eXBlOiBzdHJpbmc7XG4gIHVybDogc3RyaW5nO1xuICB3ZWJTb2NrZXREZWJ1Z2dlclVybDogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgQ2RwVmFsdWUge1xuICB0eXBlOiBzdHJpbmc7XG4gIHZhbHVlPzogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBUaGUgQ0RQIGVuZHBvaW50IG9mIGEgbGF1bmNoZWQsIGhhcm5lc3Mtb3duZWQgaW5zdGFuY2UuXG4gKi9cbmludGVyZmFjZSBPd25lZEluc3RhbmNlRW5kcG9pbnQge1xuICAvKiogQ0RQIGhvc3QgKGUuZy4gYCdsb2NhbGhvc3QnYCkuICovXG4gIHJlYWRvbmx5IGhvc3Q6IHN0cmluZztcblxuICAvKiogVGhlIGZyZWUgQ0RQIHBvcnQgdGhlIG93bmVkIGluc3RhbmNlIHdhcyBsYXVuY2hlZCBvbi4gKi9cbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xufVxuXG5jb25zdCBDT01NQU5EX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMzAwMDA7XG5jb25zdCBWQVVMVF9JRF9CWVRFX0xFTkdUSCA9IDg7XG5jb25zdCBVU0VSX0RBVEFfUk1fVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAxMDAwMDtcbmNvbnN0IFVTRVJfREFUQV9STV9SRVRSWV9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSA1MDA7XG5jb25zdCBOT19PVVRQVVQgPSAnKG5vIG91dHB1dCknO1xuY29uc3QgVkFVTFRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSA1MDA7XG5jb25zdCBWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMzAwMDA7XG4vLyBPbGQgKEVsZWN0cm9uIDEwLWVyYSkgT2JzaWRpYW4gb2NjYXNpb25hbGx5IGJvb3RzIHdpdGhvdXQgdGhlIHdvcmtzcGFjZSBldmVyXG4vLyBJbml0aWFsaXppbmcsIHNvIHRoZSB2YXVsdCBuZXZlciBiZWNvbWVzIHJlYWR5LiBBIGZyZXNoIGluc3RhbmNlIGlzIGFuXG4vLyBJbmRlcGVuZGVudCBjaGFuY2U7IHJlbGF1bmNoIHVwIHRvIHRoaXMgbWFueSB0aW1lcyBiZWZvcmUgZ2l2aW5nIHVwLlxuY29uc3QgT1dORURfTEFVTkNIX01BWF9BVFRFTVBUUyA9IDM7XG4vLyBCcmllZiBzZXR0bGUgYmVmb3JlIGEgcmVsYXVuY2ggc28gdGhlIGtpbGxlZCBpbnN0YW5jZSdzIG1lbW9yeS9oYW5kbGVzIGFyZVxuLy8gUmVjbGFpbWVkIGJlZm9yZSB0aGUgbmV4dCBib290IFx1MjAxNCBpbXByb3ZlcyB0aGUgb2RkcyBvbiBhIGxvYWRlZCBtYWNoaW5lLlxuY29uc3QgT1dORURfUkVMQVVOQ0hfU0VUVExFX0lOX01JTExJU0VDT05EUyA9IDMwMDA7XG5jb25zdCBWQVVMVF9DTE9TRV9ERUxBWV9JTl9NSUxMSVNFQ09ORFMgPSAxMDAwO1xuY29uc3QgQVVUT19TVEFSVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDIwMDA7XG5jb25zdCBBVVRPX1NUQVJUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMzAwMDA7XG5jb25zdCBJTlNUQU5DRV9FWElUX1NFVFRMRV9ERUxBWV9JTl9NSUxMSVNFQ09ORFMgPSA1MDA7XG5jb25zdCBPV05FRF9XSU5ET1dfT0ZGU0NSRUVOX01BUkdJTl9JTl9QSVhFTFMgPSAyMDA7XG5jb25zdCBPV05FRF9XSU5ET1dfSElERV9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDIwMDAwO1xuY29uc3QgT1dORURfV0lORE9XX0hJREVfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSAyNTA7XG5cbi8qKlxuICogVHJhbnNwb3J0IHRoYXQgY29tbXVuaWNhdGVzIHdpdGggRGVza3RvcCBPYnNpZGlhbiB2aWEgQ2hyb21lIERldlRvb2xzIFByb3RvY29sLlxuICpcbiAqIENvbm5lY3RzIHRvIE9ic2lkaWFuJ3MgQ0RQIFdlYlNvY2tldCBlbmRwb2ludCwgc2VuZHMgYFJ1bnRpbWUuZXZhbHVhdGVgXG4gKiBjb21tYW5kcywgYW5kIHJvdXRlcyBleHByZXNzaW9ucyB0byB0aGUgY29ycmVjdCB2YXVsdCB0YXJnZXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBEZXNrdG9wQ2RwVHJhbnNwb3J0IGltcGxlbWVudHMgT2JzaWRpYW5UcmFuc3BvcnQge1xuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyB0cmFuc3BvcnQgaXMgZm9yIGEgbW9iaWxlIHBsYXRmb3JtLiBBbHdheXMgYGZhbHNlYCBmb3IgdGhpcyB0cmFuc3BvcnQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaXNNb2JpbGUgPSBmYWxzZTtcbiAgcHJpdmF0ZSBhY3RpdmVWYXVsdFBhdGg6IG51bGwgfCBzdHJpbmcgPSBudWxsO1xuICBwcml2YXRlIGFzYXJGYWxsYmFjazogQXNhckZhbGxiYWNrIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkcEhvc3Q6IHN0cmluZztcbiAgcHJpdmF0ZSBjZHBQb3J0OiBudW1iZXI7XG4gIHByaXZhdGUgY2RwVXJsOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuICBwcml2YXRlIGVsZWN0cm9uQ29tcGF0aWJpbGl0eTogRWxlY3Ryb25Db21wYXRpYmlsaXR5IHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IGlzSGFybmVzc093bmVkSW5zdGFuY2U6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgaXNPYnNpZGlhbkFwcFZpc2libGU6IGJvb2xlYW47XG4gIHByaXZhdGUgbWVzc2FnZUlkID0gMDtcbiAgcHJpdmF0ZSByZWFkb25seSBvd25lZENvbmZpZzogT3duZWRJbnN0YW5jZUNvbmZpZyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBvd25lZEluc3RhbmNlOiBPd25lZE9ic2lkaWFuSW5zdGFuY2UgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2hvdWxkRGlzYWJsZVNhbmRib3g6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgc2hvdWxkVGhyb3dPblNpbGVudEFzYXJGYWxsYmFjazogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSBzaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzOiBib29sZWFuO1xuICBwcml2YXRlIHdzOiBudWxsIHwgV2ViU29ja2V0ID0gbnVsbDtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBDRFAgdHJhbnNwb3J0LlxuICAgKlxuICAgKiBAcGFyYW0gY29uZmlnIC0gQ0RQIGNvbm5lY3Rpb24gY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihjb25maWc/OiBEZXNrdG9wQ2RwVHJhbnNwb3J0Q29uZmlnKSB7XG4gICAgLy8gRGVzdHJ1Y3R1cmUgd2l0aCBwZXItZmllbGQgZGVmYXVsdHMgKGVhY2ggYXBwbGllcyB3aGVuIHRoZSBmaWVsZCBpcyBvbWl0dGVkLFxuICAgIC8vIEV4YWN0bHkgbGlrZSB0aGUgZm9ybWVyIGBjb25maWc/LnggPz8gZGVmYXVsdGApIHNvIHRoZSBjb25zdHJ1Y3RvciBzdGF5c1xuICAgIC8vIFVuZGVyIHRoZSBjeWNsb21hdGljLWNvbXBsZXhpdHkgbGltaXQgYXMgZmllbGRzIGFyZSBhZGRlZC5cbiAgICBjb25zdCB7XG4gICAgICBjZHBIb3N0ID0gJ2xvY2FsaG9zdCcsXG4gICAgICBjZHBQb3J0LFxuICAgICAgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IENPTU1BTkRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMsXG4gICAgICBkZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHMgPSBERUZBVUxUX0RFQURfQk9PVF9HUkFDRV9JTl9NSUxMSVNFQ09ORFMsXG4gICAgICBpc0hhcm5lc3NPd25lZEluc3RhbmNlID0gZmFsc2UsXG4gICAgICBpc09ic2lkaWFuQXBwVmlzaWJsZSA9IHRydWUsXG4gICAgICBvd25lZEluc3RhbmNlLFxuICAgICAgc2hvdWxkRGlzYWJsZVNhbmRib3ggPSBmYWxzZSxcbiAgICAgIHNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2sgPSB0cnVlLFxuICAgICAgc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlcyA9IHRydWVcbiAgICB9ID0gY29uZmlnID8/IHt9O1xuICAgIHRoaXMuY2RwSG9zdCA9IGNkcEhvc3Q7XG4gICAgdGhpcy5jb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzID0gY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcztcbiAgICB0aGlzLmRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kcyA9IGRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kcztcbiAgICB0aGlzLmlzSGFybmVzc093bmVkSW5zdGFuY2UgPSBpc0hhcm5lc3NPd25lZEluc3RhbmNlO1xuICAgIHRoaXMuaXNPYnNpZGlhbkFwcFZpc2libGUgPSBpc09ic2lkaWFuQXBwVmlzaWJsZTtcbiAgICB0aGlzLm93bmVkQ29uZmlnID0gb3duZWRJbnN0YW5jZTtcbiAgICB0aGlzLnNob3VsZERpc2FibGVTYW5kYm94ID0gc2hvdWxkRGlzYWJsZVNhbmRib3g7XG4gICAgdGhpcy5zaG91bGRUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrID0gc2hvdWxkVGhyb3dPblNpbGVudEFzYXJGYWxsYmFjaztcbiAgICB0aGlzLnNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXMgPSBzaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzO1xuICAgIC8vIE93bmVkIG1vZGUgcGlja3MgYSBmcmVlIHBvcnQgYXQgbGF1bmNoIChhc3NpZ25lZCBpbiByZWdpc3RlclZhdWx0KS5cbiAgICAvLyBBdHRhY2ggbW9kZSBjb25uZWN0cyB0byB0aGUgY29uZmlndXJlZCBwb3J0OyBubyBwb3J0IGlzIGhhcmRjb2RlZC5cbiAgICB0aGlzLmNkcFBvcnQgPSBjZHBQb3J0ID8/IDA7XG4gICAgdGhpcy5jZHBVcmwgPSBjZHBQb3J0ID09PSB1bmRlZmluZWQgPyAnJyA6IGBodHRwOi8vJHtjZHBIb3N0fToke1N0cmluZyhjZHBQb3J0KX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3Bvc2VzIG9mIHRoZSBhY3RpdmUgV2ViU29ja2V0IGNvbm5lY3Rpb24gYW5kLCBpbiBvd25lZC1pbnN0YW5jZSBtb2RlLFxuICAgKiBraWxscyB0aGUgb3duZWQgT2JzaWRpYW4gcHJvY2VzcyBhbmQgcmVtb3ZlcyBpdHMgaXNvbGF0ZWQgdXNlci1kYXRhIGRpci5cbiAgICpcbiAgICogVGhlIHJlbW92YWwgaXMgcmV0cmllZCBiZWNhdXNlIFdpbmRvd3MgYnJpZWZseSBob2xkcyB0aGUganVzdC1raWxsZWRcbiAgICogcHJvY2VzcydzIGZpbGUgaGFuZGxlcywgd2hpY2ggd291bGQgb3RoZXJ3aXNlIGZhaWwgYHJtU3luY2Agd2l0aCBgRVBFUk1gLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgaWYgKCF0aGlzLm93bmVkQ29uZmlnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5vd25lZEluc3RhbmNlPy5raWxsKCk7XG4gICAgY29uc3QgeyB1c2VyRGF0YURpciB9ID0gdGhpcy5vd25lZENvbmZpZztcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBVU0VSX0RBVEFfUk1fVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgaWYgKHRyeVJlbW92ZURpcih1c2VyRGF0YURpcikpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYXdhaXQgZGVsYXkoVVNFUl9EQVRBX1JNX1JFVFJZX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgfVxuICAgIGlmICghdHJ5UmVtb3ZlRGlyKHVzZXJEYXRhRGlyKSkge1xuICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gQ291bGQgbm90IHJlbW92ZSBvd25lZCB1c2VyLWRhdGEgZGlyIHdpdGhpbiAke1N0cmluZyhVU0VSX0RBVEFfUk1fVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMpfW1zIChub24tZmF0YWwpOiAke3VzZXJEYXRhRGlyfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTeW5jaHJvbm91cyBkaXNwb3NhbCBcdTIwMTQga2lsbHMgdGhlIG93bmVkIGluc3RhbmNlIGFuZCBtYWtlcyBhIGJlc3QtZWZmb3J0XG4gICAqIHJlbW92YWwgb2YgaXRzIHVzZXItZGF0YSBkaXIuIFNhZmUgdG8gY2FsbCBmcm9tIGEgcHJvY2VzcyBgZXhpdGAgaGFuZGxlclxuICAgKiAod2hlcmUgYXN5bmMgcmV0cmllcyBhcmUgaW1wb3NzaWJsZTsgYSBsZWZ0b3ZlciB0ZW1wIGRpciBpcyBhY2NlcHRhYmxlKS5cbiAgICovXG4gIHB1YmxpYyBkaXNwb3NlU3luYygpOiB2b2lkIHtcbiAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcbiAgICBpZiAodGhpcy5vd25lZENvbmZpZykge1xuICAgICAgdGhpcy5vd25lZEluc3RhbmNlPy5raWxsKCk7XG4gICAgICBpZiAoIXRyeVJlbW92ZURpcih0aGlzLm93bmVkQ29uZmlnLnVzZXJEYXRhRGlyKSkge1xuICAgICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBPd25lZCB1c2VyLWRhdGEgZGlyIG5vdCByZW1vdmVkIHN5bmNocm9ub3VzbHkgKHByb2Nlc3MgbWF5IHN0aWxsIGhvbGQgaGFuZGxlcyk6ICR7dGhpcy5vd25lZENvbmZpZy51c2VyRGF0YURpcn1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXZhbHVhdGVzIGEgSmF2YVNjcmlwdCBleHByZXNzaW9uIGluc2lkZSBPYnNpZGlhbiB2aWEgQ0RQIGBSdW50aW1lLmV2YWx1YXRlYC5cbiAgICpcbiAgICogUm91dGVzIHRvIHRoZSBjb3JyZWN0IHZhdWx0IHRhcmdldCBiYXNlZCBvbiBgb3B0aW9ucy5jd2RgLlxuICAgKlxuICAgKiBAcGFyYW0gZXhwcmVzc2lvbiAtIFRoZSBKYXZhU2NyaXB0IGV4cHJlc3Npb24gdG8gZXZhbHVhdGUuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gRXZhbHVhdGlvbiBvcHRpb25zLlxuICAgKiBAcmV0dXJucyBUaGUgbm9ybWFsaXplZCByZXN1bHQgc3RyaW5nLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGV2YWx1YXRlKGV4cHJlc3Npb246IHN0cmluZywgb3B0aW9uczogVHJhbnNwb3J0RXZhbE9wdGlvbnMpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHdzID0gYXdhaXQgdGhpcy5lbnN1cmVDb25uZWN0aW9uKG9wdGlvbnMuY3dkKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuc2VuZENvbW1hbmQod3MsICdSdW50aW1lLmV2YWx1YXRlJywge1xuICAgICAgYXdhaXRQcm9taXNlOiB0cnVlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIHJldHVybkJ5VmFsdWU6IHRydWVcbiAgICB9KTtcblxuICAgIGlmIChyZXNwb25zZS5yZXN1bHQ/LmV4Y2VwdGlvbkRldGFpbHMpIHtcbiAgICAgIGNvbnN0IGRlc2MgPSByZXNwb25zZS5yZXN1bHQuZXhjZXB0aW9uRGV0YWlscy5leGNlcHRpb24/LmRlc2NyaXB0aW9uXG4gICAgICAgID8/IHJlc3BvbnNlLnJlc3VsdC5leGNlcHRpb25EZXRhaWxzLnRleHQ7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENEUCBldmFsdWF0aW9uIGVycm9yOiAke2Rlc2N9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0T2JqID0gcmVzcG9uc2UucmVzdWx0Py5yZXN1bHQ7XG4gICAgaWYgKCFyZXN1bHRPYmogfHwgcmVzdWx0T2JqLnR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gTk9fT1VUUFVUO1xuICAgIH1cblxuICAgIHJldHVybiBTdHJpbmcocmVzdWx0T2JqLnZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBzaWxlbnQtYXNhci1mYWxsYmFjayB2ZXJkaWN0IGZvciB0aGlzIG93bmVkIGluc3RhbmNlIFx1MjAxNCB3aGV0aGVyIHRoZVxuICAgKiBhcHAgdmVyc2lvbiBpdCBpcyBhY3R1YWxseSBydW5uaW5nIG1hdGNoZXMgdGhlIHN3YXBwZWQtaW4gcGluLCBvciB0aGUgaW5zdGFsbGVyXG4gICAqIHNpbGVudGx5IHJldmVydGVkIHRvIGl0cyBvd24gYnVuZGxlZCBhc2FyIChyZWFkIGxpdmUgcG9zdC1ib290KS4gUmV0dXJuc1xuICAgKiBgdW5kZWZpbmVkYCB3aGVuIHRoaXMgaXMgbm90IGFuIG93bmVkIGluc3RhbmNlLCB0aGUgaW5zdGFuY2UgaGFzIG5vdCBib290ZWRcbiAgICogeWV0LCBvciB0aGUgdmVyZGljdCBjb3VsZCBub3QgYmUgZGV0ZXJtaW5lZCAobm8gYXNhciB3YXMgc3dhcHBlZCwgb3IgdGhlIGxpdmVcbiAgICogdmVyc2lvbiB3YXMgdW5yZWFkYWJsZSkuIEEgYCdmYWxsYmFjaydgIHZlcmRpY3QgcmVhY2hlcyB0aGlzIHN1cmZhY2Ugb25seSB3aGVuXG4gICAqIHRoZSB0aHJvdyBpcyBkaXNhYmxlZCAoe0BsaW5rIERlc2t0b3BDZHBUcmFuc3BvcnRDb25maWcuc2hvdWxkVGhyb3dPblNpbGVudEFzYXJGYWxsYmFja31cbiAgICogYGZhbHNlYCk7IG90aGVyd2lzZSBpdCB0aHJvd3MgYFNpbGVudEFzYXJGYWxsYmFja0Vycm9yYC5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIHNpbGVudC1hc2FyLWZhbGxiYWNrIHZlcmRpY3QsIG9yIGB1bmRlZmluZWRgLlxuICAgKi9cbiAgcHVibGljIGdldEFzYXJGYWxsYmFjaygpOiBBc2FyRmFsbGJhY2sgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmFzYXJGYWxsYmFjaztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSByZXNvbHZlZCBpbnN0YWxsZXJcdTIxOTRhcHAgY29tcGF0aWJpbGl0eSB2ZXJkaWN0IGZvciB0aGlzIG93bmVkXG4gICAqIGluc3RhbmNlLCBzbyBjYWxsZXJzIGNhbiBhc3NlcnQgb24gaXQuIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB0aGlzIGlzIG5vdFxuICAgKiBhbiBvd25lZCBpbnN0YW5jZSwgb3IgdGhlIHZlcmRpY3QgY291bGQgbm90IGJlIGRldGVybWluZWQgKGUuZy4gYW5cbiAgICogdW5kZXRlY3RhYmxlIHNoZWxsIHZlcnNpb24sIG9yIHRoZSBhcHAgdmVyc2lvbiBpcyBhYnNlbnQgZnJvbSB0aGUgdGFibGUpLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgY29tcGF0aWJpbGl0eSB2ZXJkaWN0LCBvciBgdW5kZWZpbmVkYC5cbiAgICovXG4gIHB1YmxpYyBnZXRDb21wYXRpYmlsaXR5KCk6IEluc3RhbGxlckNvbXBhdGliaWxpdHkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLm93bmVkQ29uZmlnPy5jb21wYXRpYmlsaXR5O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHJ1bnRpbWUgRWxlY3Ryb24gY29tcGF0aWJpbGl0eSB2ZXJkaWN0IGZvciB0aGlzIG93bmVkIGluc3RhbmNlIFx1MjAxNFxuICAgKiB3aGV0aGVyIHRoZSBFbGVjdHJvbiB2ZXJzaW9uIGl0IGlzIGFjdHVhbGx5IHJ1bm5pbmcgaXMgbmV3IGVub3VnaCBmb3IgdGhlXG4gICAqIHJ1bm5pbmcgYXBwIHZlcnNpb24gKHJlYWQgbGl2ZSBwb3N0LWJvb3Q7IHNlZSB7QGxpbmsgT2JzaWRpYW5WZXJzaW9uTWV0YWRhdGEubWluUmVjb21tZW5kZWRFbGVjdHJvblZlcnNpb259KS5cbiAgICogUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIHRoaXMgaXMgbm90IGFuIG93bmVkIGluc3RhbmNlLCB0aGUgaW5zdGFuY2UgaGFzIG5vdFxuICAgKiBib290ZWQgeWV0LCBvciB0aGUgdmVyZGljdCBjb3VsZCBub3QgYmUgZGV0ZXJtaW5lZCAodGhlIGxpdmUgdmVyc2lvbiB3YXNcbiAgICogdW5yZWFkYWJsZSwgb3IgdGhlIGFwcCB2ZXJzaW9uIGNhcnJpZXMgbm8gcmVjb21tZW5kZWQgRWxlY3Ryb24gdmVyc2lvbikuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBydW50aW1lIEVsZWN0cm9uIGNvbXBhdGliaWxpdHkgdmVyZGljdCwgb3IgYHVuZGVmaW5lZGAuXG4gICAqL1xuICBwdWJsaWMgZ2V0RWxlY3Ryb25Db21wYXRpYmlsaXR5KCk6IEVsZWN0cm9uQ29tcGF0aWJpbGl0eSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZWxlY3Ryb25Db21wYXRpYmlsaXR5O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIENEUCBlbmRwb2ludCBvZiB0aGUgb3duZWQsIGxhdW5jaGVkIGluc3RhbmNlIHNvIHRoZSBnbG9iYWwgc2V0dXBcbiAgICogY2FuIGhhbmQgaXQgdG8gdGVzdCB3b3JrZXJzICh3aGljaCB0aGVuICoqYXR0YWNoKiogdG8gaXQgaW5zdGVhZCBvZlxuICAgKiBsYXVuY2hpbmcgdGhlaXIgb3duKS4gUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIHRoaXMgdHJhbnNwb3J0IGlzIG5vdCBhblxuICAgKiBvd25lZCBpbnN0YW5jZSwgb3IgaXRzIGluc3RhbmNlIGhhcyBub3QgYmVlbiBsYXVuY2hlZCB5ZXQuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBvd25lZCBpbnN0YW5jZSdzIENEUCBob3N0IGFuZCBwb3J0LCBvciBgdW5kZWZpbmVkYC5cbiAgICovXG4gIHB1YmxpYyBnZXRPd25lZEluc3RhbmNlRW5kcG9pbnQoKTogT3duZWRJbnN0YW5jZUVuZHBvaW50IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXRoaXMub3duZWRDb25maWcgfHwgIXRoaXMub3duZWRJbnN0YW5jZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHsgaG9zdDogdGhpcy5jZHBIb3N0LCBwb3J0OiB0aGlzLmNkcFBvcnQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyB0aGF0IHRoZSBDRFAgZW5kcG9pbnQgaXMgcmVhY2hhYmxlIGFuZCBoYXMgT2JzaWRpYW4gdGFyZ2V0cy5cbiAgICpcbiAgICogSWYgT2JzaWRpYW4gaXMgbm90IHJ1bm5pbmcsIGF0dGVtcHRzIHRvIGF1dG8tc3RhcnQgaXQgdmlhIFVSSSBwcm90b2NvbFxuICAgKiBhbmQgcG9sbHMgdW50aWwgQ0RQIGJlY29tZXMgYXZhaWxhYmxlLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIHZhdWx0IHBhdGggKHVzZWQgZm9yIHZhdWx0IHJlZ2lzdHJhdGlvbiBjaGVjaykuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcHJlZmxpZ2h0Q2hlY2sodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5vd25lZENvbmZpZyB8fCB0aGlzLmlzSGFybmVzc093bmVkSW5zdGFuY2UpIHtcbiAgICAgIC8vIE93bmVkIGluc3RhbmNlIChsYXVuY2hlZCBoZXJlKSBvciBhIHdvcmtlciBhdHRhY2hlZCB0byBvbmU6IHJlYWRpbmVzcyBpc1xuICAgICAgLy8gR3VhcmFudGVlZCBieSB0aGUgZ2xvYmFsIHNldHVwJ3MgcmVnaXN0ZXJWYXVsdCwgYW5kIHRoZSB2YXVsdCBsaXZlcyBpblxuICAgICAgLy8gVGhlIGlzb2xhdGVkIGNvbmZpZyBcdTIwMTQgdGhlcmUgaXMgbm90aGluZyB0byB2ZXJpZnkgYWdhaW5zdCB0aGUgdXNlci1zY29wZVxuICAgICAgLy8gUmVnaXN0cnkuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gUnVubmluZyBwcmVmbGlnaHQgY2hlY2sgZm9yIHZhdWx0OiAke3ZhdWx0UGF0aH1gKTtcbiAgICBpZiAoIWlzVmF1bHRSZWdpc3RlcmVkKHZhdWx0UGF0aCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFZhdWx0IGlzIG5vdCByZWdpc3RlcmVkIGluIE9ic2lkaWFuOiAke3ZhdWx0UGF0aH0uIFJlZ2lzdGVyIHRoZSB2YXVsdCBmaXJzdCB3aXRoIHJlZ2lzdGVyVmF1bHQoKSBvciBUZW1wVmF1bHQucmVnaXN0ZXIoKS5gXG4gICAgICApO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB0YXJnZXRzID0gYXdhaXQgdGhpcy5nZXRQYWdlVGFyZ2V0cygpO1xuICAgICAgaWYgKHRhcmdldHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gcGFnZSB0YXJnZXRzJyk7XG4gICAgICB9XG4gICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBDRFAgcmVhY2hhYmxlLCAke1N0cmluZyh0YXJnZXRzLmxlbmd0aCl9IHRhcmdldChzKSBmb3VuZC5gKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlT2JzaWRpYW5SdW5uaW5nKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIHZhdWx0IHZpYSBFbGVjdHJvbiBJUEMgZXZhbHVhdGVkIHRocm91Z2ggQ0RQLlxuICAgKlxuICAgKiBVc2VzIGFuIGV4aXN0aW5nIE9ic2lkaWFuIHRhcmdldCB0byBzZW5kIHRoZSBgdmF1bHQtb3BlbmAgSVBDIGNvbW1hbmQsXG4gICAqIHRoZW4gcG9sbHMgdW50aWwgdGhlIG5ldyB2YXVsdCdzIHRhcmdldCBhcHBlYXJzLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IGZvbGRlci5cbiAgICovXG4gIHB1YmxpYyBhc3luYyByZWdpc3RlclZhdWx0KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMub3duZWRDb25maWcpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJWYXVsdEluT3duZWRJbnN0YW5jZSh2YXVsdFBhdGgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMub3BlblZhdWx0SW5SdW5uaW5nSW5zdGFuY2UodmF1bHRQYXRoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVycyBhIHZhdWx0IGJ5IGRlc3Ryb3lpbmcgaXRzIHdpbmRvdyBhbmQgcmVtb3ZpbmcgaXQgZnJvbSB0aGUgcmVnaXN0cnkuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdmF1bHQgZm9sZGVyLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHVucmVnaXN0ZXJWYXVsdCh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLm93bmVkQ29uZmlnKSB7XG4gICAgICAvLyBUaGUgb3duZWQgaW5zdGFuY2UgaXMga2lsbGVkIHdob2xlc2FsZSBvbiBkaXNwb3NlOyBubyBwZXItdmF1bHRcbiAgICAgIC8vIFVucmVnaXN0ZXIgaXMgbmVlZGVkIChhbmQgdGhlIHJlZ2lzdHJ5IGxpdmVzIGluIHRoZSBpc29sYXRlZCBjb25maWcpLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBlbnN1cmVOYW1lc3BhY2VCb290c3RyYXBwZWQodGhpcywgdmF1bHRQYXRoKTtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGF3YWl0IHRoaXMuZmluZFRhcmdldEZvclZhdWx0KHZhdWx0UGF0aCk7XG4gICAgICBjb25zdCB3cyA9IGF3YWl0IHRoaXMuY29ubmVjdFRvVGFyZ2V0KHRhcmdldCk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkZXN0cm95RXhwciA9ICd3aW5kb3cuX19vYnNpZGlhbkludGVncmF0aW9uVGVzdGluZy5kZXN0cm95Q3VycmVudFdpbmRvdygpJztcbiAgICAgICAgYXdhaXQgdGhpcy5zZW5kQ29tbWFuZCh3cywgJ1J1bnRpbWUuZXZhbHVhdGUnLCB7XG4gICAgICAgICAgYXdhaXRQcm9taXNlOiB0cnVlLFxuICAgICAgICAgIGV4cHJlc3Npb246IGRlc3Ryb3lFeHByLFxuICAgICAgICAgIHJldHVybkJ5VmFsdWU6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB3cy5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gV2luZG93IG1heSBhbHJlYWR5IGJlIGNsb3NlZC5cbiAgICB9XG5cbiAgICBpZiAodGhpcy5hY3RpdmVWYXVsdFBhdGggPT09IHZhdWx0UGF0aCkge1xuICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgfVxuXG4gICAgYXdhaXQgZGVsYXkoVkFVTFRfQ0xPU0VfREVMQVlfSU5fTUlMTElTRUNPTkRTKTtcblxuICAgIGNvbnN0IHRhcmdldHMgPSBhd2FpdCB0aGlzLmdldFBhZ2VUYXJnZXRzKCk7XG4gICAgaWYgKHRhcmdldHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3Qgd3MgPSBhd2FpdCB0aGlzLmNvbm5lY3RUb1RhcmdldChlbnN1cmVOb25OdWxsYWJsZSh0YXJnZXRzWzBdKSk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBlbnN1cmVOYW1lc3BhY2VCb290c3RyYXBwZWQodGhpcywgdmF1bHRQYXRoKTtcbiAgICAgICAgY29uc3QgcmVtb3ZlRXhwciA9IGB3aW5kb3cuX19vYnNpZGlhbkludGVncmF0aW9uVGVzdGluZy5pcGNTZW5kU3luYygke0pTT04uc3RyaW5naWZ5KHsgYXJnczogW3ZhdWx0UGF0aF0sIGNoYW5uZWw6ICd2YXVsdC1yZW1vdmUnIH0pfSlgO1xuICAgICAgICBhd2FpdCB0aGlzLnNlbmRDb21tYW5kKHdzLCAnUnVudGltZS5ldmFsdWF0ZScsIHtcbiAgICAgICAgICBhd2FpdFByb21pc2U6IHRydWUsXG4gICAgICAgICAgZXhwcmVzc2lvbjogcmVtb3ZlRXhwcixcbiAgICAgICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgd3MuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gTm8gQ0RQIHRhcmdldHMgZm9yIHJlbW92YWwgSVBDIFx1MjAxNCByZW1vdmluZyBkaXJlY3RseSBmcm9tIG9ic2lkaWFuLmpzb24uJyk7XG4gICAgICByZW1vdmVWYXVsdEZyb21Db25maWcodmF1bHRQYXRoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZXMgYW5kIHN0b3JlcyB0aGUgcnVudGltZS1FbGVjdHJvbiBjb21wYXRpYmlsaXR5IHZlcmRpY3QgKG9uXG4gICAqIHtAbGluayBnZXRFbGVjdHJvbkNvbXBhdGliaWxpdHl9KSBmcm9tIGFuIGFscmVhZHktcmVhZCB2ZXJzaW9uIHBhaXIsIHdhcm5pbmdcbiAgICogd2hlbiB0aGUgbGl2ZSBFbGVjdHJvbiBpcyBiZWxvdyB0aGUgYXBwJ3MgcmVjb21tZW5kZWQgbWluaW11bS4gTmV2ZXIgdGhyb3dzOyBhXG4gICAqIGJvb3Qgd2hvc2UgcnVubmluZyBhcHAgdmVyc2lvbiB3YXMgdW5yZWFkYWJsZSBpcyBza2lwcGVkIChub3RoaW5nIHRvIGp1ZGdlKS5cbiAgICpcbiAgICogQHBhcmFtIGFwcFZlcnNpb24gLSBUaGUgbGl2ZSBydW5uaW5nIGFwcCB2ZXJzaW9uLCBvciBgdW5kZWZpbmVkYCB3aGVuIHVucmVhZGFibGUuXG4gICAqIEBwYXJhbSBhY3R1YWxFbGVjdHJvblZlcnNpb24gLSBUaGUgbGl2ZSBFbGVjdHJvbiB2ZXJzaW9uLCBvciBgdW5kZWZpbmVkYCB3aGVuIHVucmVhZGFibGUuXG4gICAqL1xuICBwcml2YXRlIGFwcGx5RWxlY3Ryb25Db21wYXRpYmlsaXR5KGFwcFZlcnNpb246IHN0cmluZyB8IHVuZGVmaW5lZCwgYWN0dWFsRWxlY3Ryb25WZXJzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgICBpZiAoYXBwVmVyc2lvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdmVyZGljdCA9IGNoZWNrRWxlY3Ryb25Db21wYXRpYmlsaXR5KHtcbiAgICAgIGFjdHVhbEVsZWN0cm9uVmVyc2lvbixcbiAgICAgIGFwcFZlcnNpb24sXG4gICAgICBtZXRhZGF0YTogZ2V0VmVyc2lvbk1ldGFkYXRhKGFwcFZlcnNpb24pXG4gICAgfSk7XG4gICAgdGhpcy5lbGVjdHJvbkNvbXBhdGliaWxpdHkgPSB2ZXJkaWN0O1xuICAgIGlmICh2ZXJkaWN0LnRpZXIgPT09ICduYWdnZWQnICYmIHRoaXMuc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3Vlcykge1xuICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gJHtlbnN1cmVOb25OdWxsYWJsZSh2ZXJkaWN0Lm1lc3NhZ2UpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyB0aGUgcnVubmluZyBhcHAgKGFzYXIpIHZlcnNpb24gbWF0Y2hlcyB0aGUgc3dhcHBlZC1pbiBwaW4sIHN0b3JpbmcgdGhlXG4gICAqIHZlcmRpY3Qgb24ge0BsaW5rIGdldEFzYXJGYWxsYmFja30uIE9uIGEgKipzaWxlbnQgZmFsbGJhY2sqKiAodGhlIGluc3RhbGxlciByYW5cbiAgICogaXRzIG93biBidW5kbGVkIGFzYXIgaW5zdGVhZCBvZiB0aGUgcGluKSBpdCB0aHJvd3Mge0BsaW5rIFNpbGVudEFzYXJGYWxsYmFja0Vycm9yfVxuICAgKiB3aGVuIHRoZSB0aHJvdyBpcyBlbmFibGVkLCBvdGhlcndpc2Ugd2FybnMgKHdoZW4gd2FybmluZ3MgYXJlIG9uKSBhbmQgbGV0cyB0aGVcbiAgICogYm9vdCBwcm9jZWVkLiBBIGJvb3Qgd2l0aCBubyBzd2FwcGVkLWluIGFzYXIsIG9yIGFuIHVucmVhZGFibGUgcnVubmluZyB2ZXJzaW9uLFxuICAgKiBpcyBgJ3Vua25vd24nYCBcdTIwMTQgbm90aGluZyBpcyB0aHJvd24gb3Igd2FybmVkLiBUaGlzIGlzIHRoZSBoZWFsdGh5LVVJIGNvbXBhbmlvbiB0b1xuICAgKiB0aGUgYmxhY2stc2NyZWVuIHtAbGluayBSZW5kZXJlckZhaWxlZFRvSW5pdGlhbGl6ZUVycm9yfSBkZWFkLWJvb3QgZmFzdC1mYWlsLlxuICAgKlxuICAgKiBAcGFyYW0gcnVubmluZ0FwaVZlcnNpb24gLSBUaGUgbGl2ZSBydW5uaW5nIGFwcCB2ZXJzaW9uLCBvciBgdW5kZWZpbmVkYCB3aGVuIHVucmVhZGFibGUuXG4gICAqL1xuICBwcml2YXRlIGNoZWNrUnVudGltZUFzYXJGYWxsYmFjayhydW5uaW5nQXBpVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gICAgY29uc3QgdmVyZGljdCA9IGNoZWNrQXNhckZhbGxiYWNrKHtcbiAgICAgIHJlcXVlc3RlZFZlcnNpb246IHRoaXMub3duZWRDb25maWc/LmFzYXI/LnZlcnNpb24sXG4gICAgICBydW5uaW5nQXBpVmVyc2lvblxuICAgIH0pO1xuICAgIHRoaXMuYXNhckZhbGxiYWNrID0gdmVyZGljdDtcblxuICAgIGNvbnN0IGFjdGlvbiA9IHJlc29sdmVBc2FyRmFsbGJhY2tBY3Rpb24oe1xuICAgICAgc2hvdWxkVGhyb3dPblNpbGVudEFzYXJGYWxsYmFjazogdGhpcy5zaG91bGRUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrLFxuICAgICAgc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlczogdGhpcy5zaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzLFxuICAgICAgdGllcjogdmVyZGljdC50aWVyXG4gICAgfSk7XG4gICAgaWYgKGFjdGlvbiA9PT0gJ3Rocm93Jykge1xuICAgICAgdGhyb3cgbmV3IFNpbGVudEFzYXJGYWxsYmFja0Vycm9yKHtcbiAgICAgICAgcmVxdWVzdGVkVmVyc2lvbjogZW5zdXJlTm9uTnVsbGFibGUodmVyZGljdC5yZXF1ZXN0ZWRWZXJzaW9uKSxcbiAgICAgICAgcnVubmluZ0FwaVZlcnNpb246IGVuc3VyZU5vbk51bGxhYmxlKHZlcmRpY3QucnVubmluZ0FwaVZlcnNpb24pXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKGFjdGlvbiA9PT0gJ3dhcm4nKSB7XG4gICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSAke2Vuc3VyZU5vbk51bGxhYmxlKHZlcmRpY3QubWVzc2FnZSl9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdGhlIHBvc3QtYm9vdCBydW50aW1lIGNvbXBhdGliaWxpdHkgY2hlY2tzIGZvciBhbiBvd25lZCBpbnN0YW5jZSwgb25jZSB0aGVcbiAgICogdmF1bHQgaXMgcmVhZHkuIFJlYWRzIHRoZSBsaXZlIHJ1bm5pbmcgYXBwIHZlcnNpb24gYW5kIEVsZWN0cm9uIHZlcnNpb24gKipvbmNlKipcbiAgICogZnJvbSB0aGUgYm9vdGVkIHJlbmRlcmVyJ3MgbWFpbiBwcm9jZXNzLCB0aGVuOiAoMSkgdmVyaWZpZXMgdGhlIHJ1bm5pbmcgYXBwXG4gICAqIHZlcnNpb24gbWF0Y2hlcyB0aGUgc3dhcHBlZC1pbiBwaW4gXHUyMDE0IHRocm93aW5nIHtAbGluayBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvcn0gb25cbiAgICogYSBzaWxlbnQgZmFsbGJhY2sgKHdoZW4gZW5hYmxlZCk7IGFuZCAoMikgcnVucyB0aGUgYmVzdC1lZmZvcnQgcnVudGltZS1FbGVjdHJvblxuICAgKiBuYWcuIE9ubHkgdGhlIGFzYXItZmFsbGJhY2sgY2hlY2sgY2FuIHRocm93LCBzbyB0aGlzIG11c3QgcnVuIG91dHNpZGUgdGhlXG4gICAqIHJlYWRpbmVzcyBwb2xsJ3MgdHJ5L2NhdGNoIChhIHN3YWxsb3dlZCB0aHJvdyB3b3VsZCBsb29wIHVudGlsIHRpbWVvdXQpLlxuICAgKlxuICAgKiBCb3RoIGFyZSByZWFkIGF0IHRoZSByZW5kZXJlciB0b3AgbGV2ZWw6IGBpcGNSZW5kZXJlci5zZW5kU3luYygndmVyc2lvbicpYCAodGhlXG4gICAqIHJ1bm5pbmcgYXBwIHZlcnNpb24sIHRydXRoZnVsIGV2ZW4gdW5kZXIgYSBzaWxlbnQgYXNhciBmYWxsYmFjaykgYW5kXG4gICAqIGBwcm9jZXNzLnZlcnNpb25zLmVsZWN0cm9uYCAodGhlIGxpdmUgc2hlbGwgRWxlY3Ryb24pOyBuZWl0aGVyIHVzZXNcbiAgICogYHJlcXVpcmUoJ29ic2lkaWFuJylgLCB3aGljaCByZXNvbHZlcyBvbmx5IGluc2lkZSBhIHBsdWdpbi1sb2FkIGNvbnRleHQuIEEgcmVhZFxuICAgKiBmYWlsdXJlIGxlYXZlcyBib3RoIHVua25vd24gKGxvZ2dlZCwgbm9uLWZhdGFsKSBcdTIwMTQgYW4gdW5yZWFkYWJsZSBydW5uaW5nIHZlcnNpb25cbiAgICogY2Fubm90IGJlIGp1ZGdlZCBhIGZhbGxiYWNrLCBzbyB0aGUgYm9vdCBpcyBub3QgYnJva2VuIGJ5IGEgZmxha3kgcmVhZC5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoIHRvIGV2YWx1YXRlIGluLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjaGVja1J1bnRpbWVDb21wYXRpYmlsaXR5KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbGV0IGFwcFZlcnNpb246IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgYWN0dWFsRWxlY3Ryb25WZXJzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhd0FwcFZlcnNpb24gPSBhd2FpdCB0aGlzLmV2YWx1YXRlKCdTdHJpbmcod2luZG93LmVsZWN0cm9uLmlwY1JlbmRlcmVyLnNlbmRTeW5jKFxcJ3ZlcnNpb25cXCcpKScsIHsgY3dkOiB2YXVsdFBhdGggfSk7XG4gICAgICBhcHBWZXJzaW9uID0gcmF3QXBwVmVyc2lvbiA9PT0gJycgfHwgcmF3QXBwVmVyc2lvbiA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiByYXdBcHBWZXJzaW9uO1xuICAgICAgYWN0dWFsRWxlY3Ryb25WZXJzaW9uID0gYXdhaXQgdGhpcy5ldmFsdWF0ZSgnU3RyaW5nKHByb2Nlc3MudmVyc2lvbnMuZWxlY3Ryb24pJywgeyBjd2Q6IHZhdWx0UGF0aCB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gQ291bGQgbm90IHJlYWQgcnVudGltZSB2ZXJzaW9ucyAobm9uLWZhdGFsKTogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgIH1cblxuICAgIC8vIEZhaWxzIGZhc3QgKHdoZW4gZW5hYmxlZCkgb24gYSBzaWxlbnQgYXNhciBmYWxsYmFjayBcdTIwMTQgTVVTVCBydW4gYmVmb3JlIHRoZVxuICAgIC8vIEJlc3QtZWZmb3J0IG5hZyBhbmQgb3V0c2lkZSBhbnkgdHJ5L2NhdGNoIHNvIHRoZSB0aHJvdyBlc2NhcGVzIHRoZSBwb2xsLlxuICAgIHRoaXMuY2hlY2tSdW50aW1lQXNhckZhbGxiYWNrKGFwcFZlcnNpb24pO1xuICAgIHRoaXMuYXBwbHlFbGVjdHJvbkNvbXBhdGliaWxpdHkoYXBwVmVyc2lvbiwgYWN0dWFsRWxlY3Ryb25WZXJzaW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25uZWN0cyB0byBhIENEUCB0YXJnZXQncyBXZWJTb2NrZXQgZW5kcG9pbnQuXG4gICAqXG4gICAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgQ0RQIHRhcmdldCB0byBjb25uZWN0IHRvLlxuICAgKiBAcmV0dXJucyBUaGUgb3BlbiBXZWJTb2NrZXQgY29ubmVjdGlvbi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY29ubmVjdFRvVGFyZ2V0KHRhcmdldDogQ2RwVGFyZ2V0KTogUHJvbWlzZTxXZWJTb2NrZXQ+IHtcbiAgICBjb25zdCB3cyA9IG5ldyBXZWJTb2NrZXQodGFyZ2V0LndlYlNvY2tldERlYnVnZ2VyVXJsKTtcbiAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB3cy5vbm9wZW4gPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH07XG4gICAgICB3cy5vbmVycm9yID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gY29ubmVjdCB0byBDRFAgdGFyZ2V0OiAke3RhcmdldC53ZWJTb2NrZXREZWJ1Z2dlclVybH1gKSk7XG4gICAgICB9O1xuICAgIH0pO1xuICAgIHJldHVybiB3cztcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyB0aGUgYWN0aXZlIFdlYlNvY2tldCBjb25uZWN0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBkaXNjb25uZWN0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLndzPy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTikge1xuICAgICAgdGhpcy53cy5jbG9zZSgpO1xuICAgIH1cbiAgICB0aGlzLndzID0gbnVsbDtcbiAgICB0aGlzLmFjdGl2ZVZhdWx0UGF0aCA9IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogRGlzbWlzc2VzIHRoZSBcIkRvIHlvdSB0cnVzdCB0aGUgYXV0aG9yIG9mIHRoaXMgdmF1bHQ/XCIgZGlhbG9nIGlmIHByZXNlbnQuXG4gICAqXG4gICAqIEFjdHMgYXMgYSBzYWZldHkgbmV0IHdoZW4gYGVuYWJsZS1wbHVnaW4tPGlkPmAgaXMgd3JpdHRlbiBpbiBvbmUgcmVuZGVyZXJcbiAgICogYnV0IG5vdCB5ZXQgdmlzaWJsZSB0byB0aGUgbmV3bHktb3BlbmVkIHZhdWx0J3MgcmVuZGVyZXIgKHJhY2Ugb2JzZXJ2ZWRcbiAgICogaW4gT2JzaWRpYW4gMS4xMy4wKS5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoIHRvIGV2YWx1YXRlIGluLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBkaXNtaXNzVHJ1c3REaWFsb2codmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmV2YWx1YXRlKERJU01JU1NfVFJVU1RfRElBTE9HX0VYUFIsIHsgY3dkOiB2YXVsdFBhdGggfSk7XG4gICAgaWYgKHJlc3VsdCA9PT0gJ3RydWUnKSB7XG4gICAgICBsb2coJ1tjZHAtdHJhbnNwb3J0XSBEaXNtaXNzZWQgXCJEbyB5b3UgdHJ1c3QgdGhlIGF1dGhvclwiIGRpYWxvZy4nKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBgZW5hYmxlLXBsdWdpbi08dmF1bHRJZD5gIGluIE9ic2lkaWFuJ3MgbG9jYWxTdG9yYWdlIHRvIHByZXZlbnRcbiAgICogdGhlIFwiRG8geW91IHRydXN0IHRoZSBhdXRob3Igb2YgdGhpcyB2YXVsdD9cIiBkaWFsb2cgZnJvbSBhcHBlYXJpbmdcbiAgICogd2hlbiBhIHZhdWx0IHdpdGggY29tbXVuaXR5IHBsdWdpbnMgaXMgb3BlbmVkIGZvciB0aGUgZmlyc3QgdGltZS5cbiAgICpcbiAgICogTXVzdCBiZSBjYWxsZWQgYWZ0ZXIgdGhlIGB2YXVsdC1vcGVuYCBJUEMgKHNvIHRoZSB2YXVsdCBJRCBleGlzdHMgaW5cbiAgICogYG9ic2lkaWFuLmpzb25gKSBhbmQgYmVmb3JlIHRoZSBuZXcgdmF1bHQgd2luZG93IGZpbmlzaGVzIGxvYWRpbmcuXG4gICAqXG4gICAqIEBwYXJhbSB3cyAtIEFuIG9wZW4gV2ViU29ja2V0IHRvIGFuIGV4aXN0aW5nIE9ic2lkaWFuIHRhcmdldC5cbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBmb2xkZXIuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGVuYWJsZVBsdWdpbnNJbkxvY2FsU3RvcmFnZSh3czogV2ViU29ja2V0LCB2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHZhdWx0SWQgPSBnZXRWYXVsdElkKHZhdWx0UGF0aCk7XG4gICAgaWYgKCF2YXVsdElkKSB7XG4gICAgICBsb2coJ1tjZHAtdHJhbnNwb3J0XSBDb3VsZCBub3QgZmluZCB2YXVsdCBJRCBcdTIwMTQgc2tpcHBpbmcgbG9jYWxTdG9yYWdlIHRydXN0IGZsYWcuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5zZW5kQ29tbWFuZCh3cywgJ1J1bnRpbWUuZXZhbHVhdGUnLCB7XG4gICAgICBleHByZXNzaW9uOiBgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJHtKU09OLnN0cmluZ2lmeShgZW5hYmxlLXBsdWdpbi0ke3ZhdWx0SWR9YCl9LCAndHJ1ZScpO2AsXG4gICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgfSk7XG4gICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gU2V0IGVuYWJsZS1wbHVnaW4tJHt2YXVsdElkfSBpbiBsb2NhbFN0b3JhZ2UuYCk7XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyB0aGVyZSBpcyBhbiBhY3RpdmUgV2ViU29ja2V0IGNvbm5lY3Rpb24gdG8gdGhlIGNvcnJlY3QgdmF1bHQgdGFyZ2V0LlxuICAgKlxuICAgKiBSZXVzZXMgdGhlIGV4aXN0aW5nIGNvbm5lY3Rpb24gaWYgaXQgdGFyZ2V0cyB0aGUgcmVxdWVzdGVkIHZhdWx0LlxuICAgKiBPdGhlcndpc2UsIGZpbmRzIHRoZSBjb3JyZWN0IHRhcmdldCBhbmQgcmVjb25uZWN0cy5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoIHRvIHRhcmdldC5cbiAgICogQHJldHVybnMgVGhlIGFjdGl2ZSBXZWJTb2NrZXQgY29ubmVjdGlvbi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlQ29ubmVjdGlvbih2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8V2ViU29ja2V0PiB7XG4gICAgaWYgKHRoaXMud3M/LnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOICYmIHRoaXMuYWN0aXZlVmF1bHRQYXRoID09PSB2YXVsdFBhdGgpIHtcbiAgICAgIHJldHVybiB0aGlzLndzO1xuICAgIH1cblxuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuXG4gICAgY29uc3QgdGFyZ2V0ID0gYXdhaXQgdGhpcy5maW5kVGFyZ2V0Rm9yVmF1bHQodmF1bHRQYXRoKTtcbiAgICB0aGlzLndzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQodGFyZ2V0KTtcbiAgICB0aGlzLmFjdGl2ZVZhdWx0UGF0aCA9IHZhdWx0UGF0aDtcbiAgICByZXR1cm4gdGhpcy53cztcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXVuY2hlcyBPYnNpZGlhbiB3aXRoIGAtLXJlbW90ZS1kZWJ1Z2dpbmctcG9ydGAgYW5kIHBvbGxzIHVudGlsIENEUCBiZWNvbWVzIGF2YWlsYWJsZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlT2JzaWRpYW5SdW5uaW5nKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIE9ic2lkaWFuIENEUCBub3QgcmVhY2hhYmxlLiBTdGFydGluZyBPYnNpZGlhbiB3aXRoIHJlbW90ZSBkZWJ1Z2dpbmcuLi4nKTtcblxuICAgIGNvbnN0IGxhdW5jaENvbW1hbmQgPSBhd2FpdCBnZXRPYnNpZGlhbkxhdW5jaENvbW1hbmQodGhpcy5jZHBQb3J0KTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZXhlYyhsYXVuY2hDb21tYW5kLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBUaGUgbGF1bmNoIGNvbW1hbmQgbWF5IGZhaWwgb24gc29tZSBzeXN0ZW1zIFx1MjAxNCB3ZSdsbCBzdGlsbCB0cnkgcG9sbGluZy5cbiAgICB9XG5cbiAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBQb2xsaW5nIGZvciBDRFAgZW5kcG9pbnQgYXQgJHt0aGlzLmNkcFVybH0gKHRpbWVvdXQ9JHtTdHJpbmcoQVVUT19TVEFSVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXMpLi4uYCk7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgQVVUT19TVEFSVF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICBhd2FpdCBkZWxheShBVVRPX1NUQVJUX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHRhcmdldHMgPSBhd2FpdCB0aGlzLmdldFBhZ2VUYXJnZXRzKCk7XG4gICAgICAgIGlmICh0YXJnZXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBPYnNpZGlhbiBDRFAgcmVhZHksICR7U3RyaW5nKHRhcmdldHMubGVuZ3RoKX0gdGFyZ2V0KHMpIGZvdW5kLmApO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIENEUCBub3QgcmVhZHkgeWV0LCByZXRyeWluZy4uLicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgT2JzaWRpYW4gZGlkIG5vdCBzdGFydCB3aXRoaW4gJHtTdHJpbmcoQVVUT19TVEFSVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXMuIEVuc3VyZSBPYnNpZGlhbiBpcyBpbnN0YWxsZWQgYW5kIGFjY2Vzc2libGUuYCk7XG4gIH1cblxuICAvKipcbiAgICogRmluZHMgdGhlIENEUCB0YXJnZXQgdGhhdCBoYXMgdGhlIGdpdmVuIHZhdWx0IG9wZW4uXG4gICAqXG4gICAqIEZvciBhIHNpbmdsZSB0YXJnZXQsIHJldHVybnMgaXQgZGlyZWN0bHkuIEZvciBtdWx0aXBsZSB0YXJnZXRzLFxuICAgKiBwcm9iZXMgZWFjaCBieSBldmFsdWF0aW5nIGBnZXRCYXNlUGF0aCgpYCB0byBmaW5kIHRoZSBtYXRjaC5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoIHRvIG1hdGNoLlxuICAgKiBAcmV0dXJucyBUaGUgbWF0Y2hpbmcgQ0RQIHRhcmdldC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmluZFRhcmdldEZvclZhdWx0KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTxDZHBUYXJnZXQ+IHtcbiAgICBjb25zdCB0YXJnZXRzID0gYXdhaXQgdGhpcy5nZXRQYWdlVGFyZ2V0cygpO1xuXG4gICAgaWYgKHRhcmdldHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIE9ic2lkaWFuIENEUCB0YXJnZXRzIGZvdW5kJyk7XG4gICAgfVxuXG4gICAgaWYgKHRhcmdldHMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUodGFyZ2V0c1swXSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCB0YXJnZXQgb2YgdGFyZ2V0cykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYmFzZVBhdGggPSBhd2FpdCB0aGlzLnByb2JlVmF1bHRQYXRoKHRhcmdldCk7XG4gICAgICAgIGlmIChiYXNlUGF0aCA9PT0gdmF1bHRQYXRoKSB7XG4gICAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIE5vdCBhIHZhdWx0IHRhcmdldCBvciBub3QgcmVhZHkuXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGBObyBDRFAgdGFyZ2V0IGZvdW5kIGZvciB2YXVsdDogJHt2YXVsdFBhdGh9YCk7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2hlcyB0aGUgbGlzdCBvZiBwYWdlLXR5cGUgdGFyZ2V0cyBmcm9tIHRoZSBDRFAgYC9qc29uYCBlbmRwb2ludC5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGxpc3Qgb2YgcGFnZSB0YXJnZXRzLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRQYWdlVGFyZ2V0cygpOiBQcm9taXNlPENkcFRhcmdldFtdPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgJHt0aGlzLmNkcFVybH0vanNvbmApO1xuICAgIGNvbnN0IHRhcmdldHMgPSBhd2FpdCByZXNwb25zZS5qc29uKCkgYXMgQ2RwVGFyZ2V0W107XG4gICAgcmV0dXJuIHRhcmdldHMuZmlsdGVyKCh0KSA9PiB0LnR5cGUgPT09ICdwYWdlJyk7XG4gIH1cblxuICAvKipcbiAgICogS2lsbHMgdGhlIGN1cnJlbnRseS1ydW5uaW5nIG93bmVkIGluc3RhbmNlIChpZiBhbnkpIGFuZCB3YWl0cyBmb3IgaXQgdG8gZXhpdCxcbiAgICogc28gdGhlIG5leHQgbGF1bmNoIGdldHMgYSBwcmlzdGluZSBzaW5nbGUtd2luZG93IGluc3RhbmNlLlxuICAgKlxuICAgKiBSZWxhdW5jaGluZyBvdmVyIGEgbGl2ZSBpbnN0YW5jZSBpcyBmb3J3YXJkZWQgYnkgRWxlY3Ryb24ncyBzaW5nbGUtaW5zdGFuY2VcbiAgICogbG9jayBvbiB0aGUgc2hhcmVkIHVzZXItZGF0YSBkaXIgYW5kIHN1cmZhY2VzIHRoZSB2YXVsdCBwaWNrZXIsIGFuZCBvcGVuaW5nIGFcbiAgICogc2Vjb25kIHdpbmRvdyB2aWEgSVBDIGxlYXZlcyBzdGFsZSB3aW5kb3dzIHRoYXQgYnJlYWsgdmF1bHQtdGFyZ2V0IHJvdXRpbmcgXHUyMDE0XG4gICAqIGhlbmNlIGEgZnVsbCBraWxsICsgd2FpdC1mb3ItZXhpdCAocmVsZWFzaW5nIHRoZSBsb2NrKSBiZXR3ZWVuIGxhdW5jaGVzLiBBXG4gICAqIG5vLW9wIG9uIHRoZSBmaXJzdCBhdHRlbXB0LCB3aGVuIG5vIGluc3RhbmNlIGlzIHJ1bm5pbmcgeWV0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBraWxsUnVubmluZ093bmVkSW5zdGFuY2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLm93bmVkSW5zdGFuY2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gS2lsbGluZyBydW5uaW5nIG93bmVkIGluc3RhbmNlIGJlZm9yZSAocmUpbGF1bmNoLicpO1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIGNvbnN0IHByZXZpb3VzQ2RwVXJsID0gdGhpcy5jZHBVcmw7XG4gICAgdGhpcy5vd25lZEluc3RhbmNlLmtpbGwoKTtcbiAgICB0aGlzLm93bmVkSW5zdGFuY2UgPSB1bmRlZmluZWQ7XG4gICAgYXdhaXQgdGhpcy53YWl0Rm9ySW5zdGFuY2VFeGl0KHByZXZpb3VzQ2RwVXJsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlcyB0aGUgb3duZWQgaW5zdGFuY2UncyB3aW5kb3cgb2ZmLXNjcmVlbiBzbyBhIGhpZGRlbiBydW4gbmV2ZXIgc3RlYWxzXG4gICAqIGZvY3VzLiBVc2VzIEVsZWN0cm9uJ3MgcmVtb3RlIGJyaWRnZSAoYHdpbmRvdy5lbGVjdHJvbi5yZW1vdGVgKSBcdTIwMTQgdGhlIG9ubHlcbiAgICogY3Jvc3MtcGxhdGZvcm0gd2F5IHRvIHJlcG9zaXRpb24gdGhlIHdpbmRvdyBcdTIwMTQgcGxhY2luZyBpdCBqdXN0IGJleW9uZCB0aGVcbiAgICogcmlnaHQgZWRnZSBvZiBhbGwgZGlzcGxheXMuIFRoZSB3aW5kb3cgc3RheXMgXCJ2aXNpYmxlXCIgdG8gQ2hyb21pdW0gKHNvXG4gICAqIHRpbWVycywgYHJlcXVlc3RBbmltYXRpb25GcmFtZWAsIGA6aG92ZXJgLCBhbmQgdHJ1c3RlZCBpbnB1dCBrZWVwIHdvcmtpbmcpLFxuICAgKiB1bmxpa2UgbWluaW1pemluZywgd2hpY2ggd291bGQgZnJlZXplIGByZXF1ZXN0QW5pbWF0aW9uRnJhbWVgLlxuICAgKlxuICAgKiBUaGUgcmVtb3RlIGJyaWRnZSBpcyBub3QgYXZhaWxhYmxlIHRoZSBpbnN0YW50IENEUCBzdGFydHMgc2VydmluZywgc28gdGhpc1xuICAgKiBwb2xscyB1bnRpbCB0aGUgbW92ZSBzdWNjZWVkcy4gQmVzdC1lZmZvcnQ6IGlmIHRoZSB3aW5kb3cgY2Fubm90IGJlIG1vdmVkXG4gICAqIHdpdGhpbiB0aGUgdGltZW91dCwgdGhlIGtlZXAtYWxpdmUgbGF1bmNoIGZsYWdzIHN0aWxsIGFwcGx5IGFuZCB0aGUgcnVuXG4gICAqIHByb2NlZWRzICh3b3JzdCBjYXNlIHRoZSB3aW5kb3cgaXMgYnJpZWZseSB2aXNpYmxlKS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgbW92ZU93bmVkV2luZG93T2Zmc2NyZWVuKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIFJlc29sdmUgdGhlIEVsZWN0cm9uIHJlbW90ZSBicmlkZ2UgdHdvIHdheXMgc28gQk9USCBtb2Rlcm4gYW5kIG9sZCBPYnNpZGlhblxuICAgIC8vIENhbiBiZSBtb3ZlZCBvZmYtc2NyZWVuOiBtb2Rlcm4gaW5qZWN0cyBgd2luZG93LmVsZWN0cm9uLnJlbW90ZWA7IG9sZFxuICAgIC8vIFZlcnNpb25zIChubyBgd2luZG93LmVsZWN0cm9uYCkgc3RpbGwgZXhwb3NlIHRoZSBidWlsdC1pbiBgcmVtb3RlYCBtb2R1bGUgdmlhXG4gICAgLy8gYHJlcXVpcmUoJ2VsZWN0cm9uJylgIGluIHRoZSBub2RlLWludGVncmF0ZWQgcmVuZGVyZXIgKHJlbW92ZWQgZnJvbSBFbGVjdHJvblxuICAgIC8vIDE0KywgYnV0IHByZXNlbnQgb24gdGhlIEVsZWN0cm9uIDgtMTMgc2hlbGxzIG9sZCBPYnNpZGlhbiBzaGlwcykuIFJldHVybmluZ1xuICAgIC8vIGBtb3ZlZGAgb24gdGhlIGZpcnN0IHN1Y2Nlc3MgaXMgaW1wb3J0YW50IG9uIEVsZWN0cm9uIDEwLWVyYSBidWlsZHM6IHBvbGxpbmdcbiAgICAvLyBPbiB3aXRob3V0IGEgcmVzb2x2YWJsZSBicmlkZ2UgaGFtbWVycyB0aGUgcmVuZGVyZXIgd2l0aCBDRFAgcm91bmQtdHJpcHNcbiAgICAvLyBEdXJpbmcgYm9vdCBhbmQgaW50ZXJtaXR0ZW50bHkgcHJldmVudHMgdGhlIHdvcmtzcGFjZSBmcm9tIGluaXRpYWxpemluZy5cbiAgICBjb25zdCBtb3ZlRXhwciA9IGAoKCkgPT4ge1xuICAgICAgbGV0IHJlbW90ZSA9ICh3aW5kb3cuZWxlY3Ryb24gJiYgd2luZG93LmVsZWN0cm9uLnJlbW90ZSkgfHwgbnVsbDtcbiAgICAgIGlmICghcmVtb3RlKSB7XG4gICAgICAgIHRyeSB7IHJlbW90ZSA9IHJlcXVpcmUoJ2VsZWN0cm9uJykucmVtb3RlIHx8IG51bGw7IH0gY2F0Y2ggKHJlcXVpcmVFcnJvcikgeyByZW1vdGUgPSBudWxsOyB9XG4gICAgICB9XG4gICAgICBpZiAoIXJlbW90ZSB8fCB0eXBlb2YgcmVtb3RlLmdldEN1cnJlbnRXaW5kb3cgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuICh0eXBlb2Ygd2luZG93LmFwcCA9PT0gJ3VuZGVmaW5lZCcpID8gJ25vdC1yZWFkeScgOiAnbm8tYnJpZGdlJztcbiAgICAgIH1cbiAgICAgIGNvbnN0IHdpbiA9IHJlbW90ZS5nZXRDdXJyZW50V2luZG93KCk7XG4gICAgICBjb25zdCBkaXNwbGF5cyA9IHJlbW90ZS5zY3JlZW4uZ2V0QWxsRGlzcGxheXMoKTtcbiAgICAgIGNvbnN0IG1heFJpZ2h0ID0gTWF0aC5tYXgoLi4uZGlzcGxheXMubWFwKChkaXNwbGF5KSA9PiBkaXNwbGF5LmJvdW5kcy54ICsgZGlzcGxheS5ib3VuZHMud2lkdGgpKTtcbiAgICAgIHdpbi5zZXRQb3NpdGlvbihtYXhSaWdodCArICR7U3RyaW5nKE9XTkVEX1dJTkRPV19PRkZTQ1JFRU5fTUFSR0lOX0lOX1BJWEVMUyl9LCAwKTtcbiAgICAgIHJldHVybiAnbW92ZWQnO1xuICAgIH0pKClgO1xuXG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgT1dORURfV0lORE9XX0hJREVfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gKGF3YWl0IHRoaXMuZ2V0UGFnZVRhcmdldHMoKSlbMF07XG4gICAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgICBjb25zdCB3cyA9IGF3YWl0IHRoaXMuY29ubmVjdFRvVGFyZ2V0KHRhcmdldCk7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5zZW5kQ29tbWFuZCh3cywgJ1J1bnRpbWUuZXZhbHVhdGUnLCB7XG4gICAgICAgICAgICAgIGV4cHJlc3Npb246IG1vdmVFeHByLFxuICAgICAgICAgICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5yZXN1bHQ/LnJlc3VsdD8udmFsdWUgPT09ICdtb3ZlZCcpIHtcbiAgICAgICAgICAgICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gTW92ZWQgb3duZWQgT2JzaWRpYW4gd2luZG93IG9mZi1zY3JlZW4gKGhpZGRlbiBtb2RlKS4nKTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB3cy5jbG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIENEUCBlbmRwb2ludCAvIHRhcmdldCAvIHJlbW90ZSBicmlkZ2Ugbm90IHJlYWR5IHlldCBcdTIwMTQga2VlcCBwb2xsaW5nLlxuICAgICAgfVxuICAgICAgYXdhaXQgZGVsYXkoT1dORURfV0lORE9XX0hJREVfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cbiAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBDb3VsZCBub3QgbW92ZSBvd25lZCB3aW5kb3cgb2ZmLXNjcmVlbiB3aXRoaW4gJHtTdHJpbmcoT1dORURfV0lORE9XX0hJREVfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMpfW1zIChub24tZmF0YWw7IGtlZXAtYWxpdmUgZmxhZ3Mgc3RpbGwgYXBwbGllZCkuYCk7XG4gIH1cblxuICAvKipcbiAgICogT3BlbnMgYSB2YXVsdCBpbiBhbiBhbHJlYWR5LXJ1bm5pbmcgT2JzaWRpYW4gaW5zdGFuY2UgdmlhIHRoZSBgdmF1bHQtb3BlbmBcbiAgICogRWxlY3Ryb24gSVBDIChldmFsdWF0ZWQgdGhyb3VnaCBDRFAgb24gYW4gZXhpc3RpbmcgdGFyZ2V0KSwgdGhlbiBwb2xscyB1bnRpbFxuICAgKiB0aGUgbmV3IHZhdWx0J3Mgd2luZG93IHRhcmdldCBhcHBlYXJzLCBpcyBsYXlvdXQtcmVhZHksIGFuZCBpdHMgdHJ1c3QgZGlhbG9nXG4gICAqIChpZiBhbnkpIGhhcyBiZWVuIGRpc21pc3NlZC5cbiAgICpcbiAgICogU2hhcmVkIGJ5IHRoZSBhdHRhY2gtbW9kZSB7QGxpbmsgcmVnaXN0ZXJWYXVsdH0gYW5kIHRoZSBvd25lZC1tb2RlXG4gICAqIFwiaW5zdGFuY2UgYWxyZWFkeSBsYXVuY2hlZFwiIHBhdGgsIHNvIG9wZW5pbmcgYW4gYWRkaXRpb25hbCB2YXVsdCBuZXZlclxuICAgKiByZWxhdW5jaGVzIHRoZSBwcm9jZXNzICh3aGljaCB3b3VsZCBzdXJmYWNlIHRoZSB2YXVsdCBwaWNrZXIpLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IGZvbGRlci5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgb3BlblZhdWx0SW5SdW5uaW5nSW5zdGFuY2UodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBSZWdpc3RlcmluZyB2YXVsdDogJHt2YXVsdFBhdGh9YCk7XG4gICAgY29uc3QgdGFyZ2V0cyA9IGF3YWl0IHRoaXMuZ2V0UGFnZVRhcmdldHMoKTtcbiAgICBpZiAodGFyZ2V0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gT2JzaWRpYW4gQ0RQIHRhcmdldHMgYXZhaWxhYmxlLiBJcyBPYnNpZGlhbiBydW5uaW5nPycpO1xuICAgIH1cblxuICAgIGNvbnN0IGlwY1dzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQoZW5zdXJlTm9uTnVsbGFibGUodGFyZ2V0c1swXSkpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBlbnN1cmVOYW1lc3BhY2VCb290c3RyYXBwZWQodGhpcywgdmF1bHRQYXRoKTtcbiAgICAgIGNvbnN0IGlwY0V4cHIgPSBgd2luZG93Ll9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcuaXBjU2VuZFN5bmMoJHtKU09OLnN0cmluZ2lmeSh7IGFyZ3M6IFt2YXVsdFBhdGgsIGZhbHNlXSwgY2hhbm5lbDogJ3ZhdWx0LW9wZW4nIH0pfSlgO1xuICAgICAgYXdhaXQgdGhpcy5zZW5kQ29tbWFuZChpcGNXcywgJ1J1bnRpbWUuZXZhbHVhdGUnLCB7XG4gICAgICAgIGF3YWl0UHJvbWlzZTogdHJ1ZSxcbiAgICAgICAgZXhwcmVzc2lvbjogaXBjRXhwcixcbiAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHRoaXMuZW5hYmxlUGx1Z2luc0luTG9jYWxTdG9yYWdlKGlwY1dzLCB2YXVsdFBhdGgpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpcGNXcy5jbG9zZSgpO1xuICAgIH1cblxuICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIFBvbGxpbmcgZm9yIHZhdWx0IHRhcmdldCAodGltZW91dD0ke1N0cmluZyhWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcykuLi5gKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZmluZFRhcmdldEZvclZhdWx0KHZhdWx0UGF0aCk7XG4gICAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIFZhdWx0IHRhcmdldCBmb3VuZC4nKTtcbiAgICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yTGF5b3V0UmVhZHkodmF1bHRQYXRoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5kaXNtaXNzVHJ1c3REaWFsb2codmF1bHRQYXRoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIFZhdWx0IHRhcmdldCBub3QgcmVhZHkgeWV0LlxuICAgICAgfVxuICAgICAgYXdhaXQgZGVsYXkoVkFVTFRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYFZhdWx0IGF0ICR7dmF1bHRQYXRofSBkaWQgbm90IGJlY29tZSByZWFkeSB3aXRoaW4gJHtTdHJpbmcoVkFVTFRfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXNgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTYW1wbGVzIHRoZSB2YXVsdCByZW5kZXJlcidzIGJvb3RzdHJhcCBzdGF0ZSBcdTIwMTQgd2hldGhlciB0aGUgZG9jdW1lbnQgaXNcbiAgICogYGNvbXBsZXRlYCwgd2hldGhlciBgd2luZG93LmFwcGAgZXhpc3RzLCBhbmQgdGhlIGA8Ym9keT5gIGNoaWxkIGNvdW50IFx1MjAxNCBmcm9tXG4gICAqIHRoZSBmaXJzdCBwYWdlIHRhcmdldCwgZm9yIGRlYWQtYm9vdCBkZXRlY3Rpb24uIFRoaXMgd29ya3MgZXZlbiB3aGVuIHRoZSBhcHBcbiAgICogbmV2ZXIgYm9vdHN0cmFwcGVkICh0aGUgcmVuZGVyZXIgcGFnZSB0YXJnZXQgc3RpbGwgZXhpc3RzKSwgd2hpY2ggaXMgZXhhY3RseVxuICAgKiB0aGUgc3RhdGUgaXQgbXVzdCBvYnNlcnZlLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgc2FtcGxlZCBvYnNlcnZhdGlvbiwgb3IgYHVuZGVmaW5lZGAgd2hlbiBubyB0YXJnZXQgaXMgcmVhY2hhYmxlXG4gICAqICAgb3IgdGhlIHByb2JlIGZhaWxlZCAoc28gdGhlIGNhbGxlciBrZWVwcyBwb2xsaW5nIHJhdGhlciB0aGFuIGZhc3QtZmFpbGluZykuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHByb2JlUmVuZGVyZXJCb290U3RhdGUoKTogUHJvbWlzZTxSZW5kZXJlckJvb3RPYnNlcnZhdGlvbiB8IHVuZGVmaW5lZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSAoYXdhaXQgdGhpcy5nZXRQYWdlVGFyZ2V0cygpKVswXTtcbiAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHdzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQodGFyZ2V0KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHByb2JlRXhwciA9IGBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgYm9keUNoaWxkRWxlbWVudENvdW50OiBkb2N1bWVudC5ib2R5ID8gZG9jdW1lbnQuYm9keS5jaGlsZEVsZW1lbnRDb3VudCA6IDAsXG4gICAgICAgICAgaGFzV2luZG93QXBwOiB0eXBlb2Ygd2luZG93LmFwcCAhPT0gJ3VuZGVmaW5lZCcsXG4gICAgICAgICAgaXNEb2N1bWVudENvbXBsZXRlOiBkb2N1bWVudC5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnXG4gICAgICAgIH0pYDtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRDb21tYW5kKHdzLCAnUnVudGltZS5ldmFsdWF0ZScsIHtcbiAgICAgICAgICBleHByZXNzaW9uOiBwcm9iZUV4cHIsXG4gICAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSByZXNwb25zZS5yZXN1bHQ/LnJlc3VsdD8udmFsdWU7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZSh2YWx1ZSkgYXMgUmVuZGVyZXJCb290T2JzZXJ2YXRpb247XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB3cy5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHJvYmVzIGEgdGFyZ2V0IHRvIGRpc2NvdmVyIHdoaWNoIHZhdWx0IHBhdGggaXQgaGFzIG9wZW4uXG4gICAqXG4gICAqIENyZWF0ZXMgYSB0ZW1wb3JhcnkgV2ViU29ja2V0IGNvbm5lY3Rpb24sIGV2YWx1YXRlcyBgZ2V0QmFzZVBhdGgoKWAsXG4gICAqIGFuZCByZXR1cm5zIHRoZSByZXN1bHQuXG4gICAqXG4gICAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgQ0RQIHRhcmdldCB0byBwcm9iZS5cbiAgICogQHJldHVybnMgVGhlIHZhdWx0J3MgYmFzZSBwYXRoLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9iZVZhdWx0UGF0aCh0YXJnZXQ6IENkcFRhcmdldCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3Qgd3MgPSBhd2FpdCB0aGlzLmNvbm5lY3RUb1RhcmdldCh0YXJnZXQpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuc2VuZENvbW1hbmQod3MsICdSdW50aW1lLmV2YWx1YXRlJywge1xuICAgICAgICAvLyBPbGQgT2JzaWRpYW4gdmVyc2lvbnMgKGUuZy4gMC42LngpIHByZWRhdGUgdGhlIGBnZXRCYXNlUGF0aCgpYCBtZXRob2QgYnV0XG4gICAgICAgIC8vIEV4cG9zZSB0aGUgYGJhc2VQYXRoYCBwcm9wZXJ0eTsgdGhlIG1ldGhvZCBleGlzdHMgZnJvbSB+MC45LjIwIG9ud2FyZC5cbiAgICAgICAgZXhwcmVzc2lvbjogJ2FwcC52YXVsdC5hZGFwdGVyLmdldEJhc2VQYXRoID8gYXBwLnZhdWx0LmFkYXB0ZXIuZ2V0QmFzZVBhdGgoKSA6IGFwcC52YXVsdC5hZGFwdGVyLmJhc2VQYXRoJyxcbiAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gU3RyaW5nKHJlc3BvbnNlLnJlc3VsdD8ucmVzdWx0Py52YWx1ZSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHdzLmNsb3NlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExhdW5jaGVzIGFuZCBjb25uZWN0cyB0byBhIGhhcm5lc3Mtb3duZWQsIGlzb2xhdGVkIE9ic2lkaWFuIGluc3RhbmNlIGZvciBhXG4gICAqIHZhdWx0OiBwcm92aXNpb25zIHRoZSBhc2FyIChpZiBhbnkpLCBwcmUtc2VlZHMgdGhlIGlzb2xhdGVkIGBvYnNpZGlhbi5qc29uYFxuICAgKiBzbyB0aGUgdmF1bHQgb3BlbnMgZGlyZWN0bHksIGxhdW5jaGVzIHRoZSBpbnN0YW5jZSBvbiBhIGZyZWUgQ0RQIHBvcnQsIHRoZW5cbiAgICogd2FpdHMgdW50aWwgdGhlIHZhdWx0IHdpbmRvdyBpcyByZWFkeSBhbmQgZGlzbWlzc2VzIHRoZSB0cnVzdCBkaWFsb2cuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdmF1bHQgZm9sZGVyLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWdpc3RlclZhdWx0SW5Pd25lZEluc3RhbmNlKHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY29uZmlnID0gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5vd25lZENvbmZpZyk7XG5cbiAgICBta2RpclN5bmMoY29uZmlnLnVzZXJEYXRhRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBpZiAoY29uZmlnLmFzYXIpIHtcbiAgICAgIGNvcHlBc2FySW50b1VzZXJEYXRhKGNvbmZpZy5hc2FyLnBhdGgsIGNvbmZpZy5hc2FyLnZlcnNpb24sIGNvbmZpZy51c2VyRGF0YURpcik7XG4gICAgfVxuXG4gICAgY29uc3QgdmF1bHRJZCA9IHJhbmRvbUJ5dGVzKFZBVUxUX0lEX0JZVEVfTEVOR1RIKS50b1N0cmluZygnaGV4Jyk7XG4gICAgY29uc3Qgb2JzaWRpYW5Kc29uID0gYnVpbGRPd25lZE9ic2lkaWFuSnNvbih7IHRzOiBEYXRlLm5vdygpLCB2YXVsdElkLCB2YXVsdFBhdGggfSk7XG4gICAgd3JpdGVGaWxlU3luYyhqb2luKGNvbmZpZy51c2VyRGF0YURpciwgJ29ic2lkaWFuLmpzb24nKSwgSlNPTi5zdHJpbmdpZnkob2JzaWRpYW5Kc29uKSk7XG5cbiAgICAvLyBSZWxhdW5jaC1yZXRyeTogc29tZSBvbGQgKEVsZWN0cm9uIDEwLWVyYSkgT2JzaWRpYW4gYnVpbGRzIGludGVybWl0dGVudGx5XG4gICAgLy8gQm9vdCB3aXRoIGB3aW5kb3cuYXBwYCBwcmVzZW50IGJ1dCB0aGUgd29ya3NwYWNlIG5ldmVyIGluaXRpYWxpemluZywgc28gdGhlXG4gICAgLy8gVmF1bHQgbmV2ZXIgYmVjb21lcyByZWFkeS4gQSBmcmVzaCBpbnN0YW5jZSBpcyBhbiBpbmRlcGVuZGVudCBjaGFuY2UuIEFcbiAgICAvLyBEZXRlcm1pbmlzdGljIGZhaWx1cmUgKGRlYWQgYm9vdCwgc2lsZW50IGFzYXIgZmFsbGJhY2spIGlzIHJlLXRocm93biBhdCBvbmNlIFx1MjAxNFxuICAgIC8vIFJldHJ5aW5nIGl0IG9ubHkgd2FzdGVzIHRoZSByZWFkaW5lc3MgdGltZW91dC5cbiAgICBsZXQgbGFzdEVycm9yOiB1bmtub3duO1xuICAgIGZvciAobGV0IGF0dGVtcHQgPSAxOyBhdHRlbXB0IDw9IE9XTkVEX0xBVU5DSF9NQVhfQVRURU1QVFM7IGF0dGVtcHQrKykge1xuICAgICAgYXdhaXQgdGhpcy5raWxsUnVubmluZ093bmVkSW5zdGFuY2UoKTtcbiAgICAgIGlmIChhdHRlbXB0ID4gMSkge1xuICAgICAgICBhd2FpdCBkZWxheShPV05FRF9SRUxBVU5DSF9TRVRUTEVfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBsYXVuY2hPd25lZE9ic2lkaWFuSW5zdGFuY2Uoe1xuICAgICAgICBjZHBIb3N0OiB0aGlzLmNkcEhvc3QsXG4gICAgICAgIGV4ZVBhdGg6IGNvbmZpZy5leGVQYXRoLFxuICAgICAgICBleHRyYUFyZ3M6IFtcbiAgICAgICAgICAuLi5yZXNvbHZlT3duZWRIaWRkZW5MYXVuY2hBcmdzKHRoaXMuaXNPYnNpZGlhbkFwcFZpc2libGUpLFxuICAgICAgICAgIC4uLnJlc29sdmVTYW5kYm94TGF1bmNoQXJncyh0aGlzLnNob3VsZERpc2FibGVTYW5kYm94KVxuICAgICAgICBdLFxuICAgICAgICB1c2VyRGF0YURpcjogY29uZmlnLnVzZXJEYXRhRGlyXG4gICAgICB9KTtcbiAgICAgIHRoaXMub3duZWRJbnN0YW5jZSA9IGluc3RhbmNlO1xuICAgICAgdGhpcy5jZHBQb3J0ID0gaW5zdGFuY2UucG9ydDtcbiAgICAgIHRoaXMuY2RwVXJsID0gaW5zdGFuY2UuY2RwVXJsO1xuXG4gICAgICBpZiAoc2hvdWxkSGlkZU9ic2lkaWFuQXBwKHRoaXMuaXNPYnNpZGlhbkFwcFZpc2libGUpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMubW92ZU93bmVkV2luZG93T2Zmc2NyZWVuKCk7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvck93bmVkVmF1bHRSZWFkeSh2YXVsdFBhdGgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBSZW5kZXJlckZhaWxlZFRvSW5pdGlhbGl6ZUVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgU2lsZW50QXNhckZhbGxiYWNrRXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBsYXN0RXJyb3IgPSBlcnJvcjtcbiAgICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gT3duZWQgdmF1bHQgbm90IHJlYWR5IChhdHRlbXB0ICR7U3RyaW5nKGF0dGVtcHQpfS8ke1N0cmluZyhPV05FRF9MQVVOQ0hfTUFYX0FUVEVNUFRTKX0pOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRocm93IGxhc3RFcnJvciBpbnN0YW5jZW9mIEVycm9yID8gbGFzdEVycm9yIDogbmV3IEVycm9yKGBPd25lZCB2YXVsdCBhdCAke3ZhdWx0UGF0aH0gZGlkIG5vdCBiZWNvbWUgcmVhZHlgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBhIENEUCBjb21tYW5kIG92ZXIgV2ViU29ja2V0IGFuZCB3YWl0cyBmb3IgdGhlIHJlc3BvbnNlLlxuICAgKlxuICAgKiBAcGFyYW0gd3MgLSBUaGUgV2ViU29ja2V0IGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSBtZXRob2QgLSBUaGUgQ0RQIG1ldGhvZCBuYW1lLlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIENEUCBtZXRob2QgcGFyYW1ldGVycy5cbiAgICogQHJldHVybnMgVGhlIENEUCByZXNwb25zZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2VuZENvbW1hbmQod3M6IFdlYlNvY2tldCwgbWV0aG9kOiBzdHJpbmcsIHBhcmFtczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBQcm9taXNlPENkcFJlc3BvbnNlPiB7XG4gICAgY29uc3QgaWQgPSArK3RoaXMubWVzc2FnZUlkO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPENkcFJlc3BvbnNlPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHdzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBoYW5kbGVyKTtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgQ0RQIGNvbW1hbmQgdGltZWQgb3V0IGFmdGVyICR7U3RyaW5nKHRoaXMuY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXM6ICR7bWV0aG9kfWApKTtcbiAgICAgIH0sIHRoaXMuY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyk7XG5cbiAgICAgIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IE1lc3NhZ2VFdmVudCk6IHZvaWQge1xuICAgICAgICBjb25zdCBtc2cgPSBKU09OLnBhcnNlKFN0cmluZyhldmVudC5kYXRhKSkgYXMgQ2RwUmVzcG9uc2U7XG4gICAgICAgIGlmIChtc2cuaWQgPT09IGlkKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICAgIHdzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBoYW5kbGVyKTtcbiAgICAgICAgICByZXNvbHZlKG1zZyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgd3MuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGhhbmRsZXIpO1xuICAgICAgd3Muc2VuZChKU09OLnN0cmluZ2lmeSh7IGlkLCBtZXRob2QsIHBhcmFtcyB9KSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUG9sbHMgYSBraWxsZWQgb3duZWQgaW5zdGFuY2UncyBDRFAgZW5kcG9pbnQgdW50aWwgaXQgc3RvcHMgcmVzcG9uZGluZyxcbiAgICogY29uZmlybWluZyB0aGUgcHJvY2VzcyBoYXMgZXhpdGVkIGFuZCByZWxlYXNlZCBFbGVjdHJvbidzIHNpbmdsZS1pbnN0YW5jZVxuICAgKiBsb2NrIG9uIHRoZSBzaGFyZWQgdXNlci1kYXRhIGRpciBiZWZvcmUgYSBmcmVzaCBpbnN0YW5jZSBpcyBsYXVuY2hlZCBpbnRvIGl0LlxuICAgKlxuICAgKiBAcGFyYW0gY2RwVXJsIC0gVGhlIENEUCBVUkwgb2YgdGhlIGluc3RhbmNlIHRoYXQgd2FzIGp1c3Qga2lsbGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9ySW5zdGFuY2VFeGl0KGNkcFVybDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gV2FpdGluZyBmb3IgcHJldmlvdXMgb3duZWQgaW5zdGFuY2UgYXQgJHtjZHBVcmx9IHRvIGV4aXQuLi5gKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYCR7Y2RwVXJsfS9qc29uYCk7XG4gICAgICAgIGF3YWl0IHJlc3BvbnNlLmJvZHk/LmNhbmNlbCgpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIFRoZSBlbmRwb2ludCBpcyBnb25lOiB0aGUgcHJvY2VzcyBoYXMgZXhpdGVkIGFuZCByZWxlYXNlZCB0aGUgbG9jay5cbiAgICAgICAgYXdhaXQgZGVsYXkoSU5TVEFOQ0VfRVhJVF9TRVRUTEVfREVMQVlfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYXdhaXQgZGVsYXkoVkFVTFRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cbiAgICBsb2coJ1tjZHAtdHJhbnNwb3J0XSBQcmV2aW91cyBpbnN0YW5jZSBzdGlsbCByZXNwb25kZWQgYmVmb3JlIHRpbWVvdXQ7IHJlbGF1bmNoaW5nIGFueXdheS4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXYWl0cyBmb3IgdGhlIHZhdWx0J3MgYGFwcC53b3Jrc3BhY2VgIHRvIHJlYWNoIGxheW91dC1yZWFkeSBzdGF0ZS5cbiAgICpcbiAgICogYGZpbmRUYXJnZXRGb3JWYXVsdGAgcmV0dXJucyBhcyBzb29uIGFzIGBhcHAudmF1bHQuYWRhcHRlci5nZXRCYXNlUGF0aCgpYFxuICAgKiBtYXRjaGVzIFx1MjAxNCB3aGljaCBpcyB0cnVlIHNob3J0bHkgYWZ0ZXIgdGhlIGBBcHBgIGNvbnN0cnVjdG9yIHJ1bnMsIGJlZm9yZVxuICAgKiBgcGx1Z2lucy5pbml0aWFsaXplKClgIChhbmQgYW55IHRydXN0IGRpYWxvZykgaGFzIGV4ZWN1dGVkLiBCb290c3RyYXBwaW5nXG4gICAqIHRoZSBuYW1lc3BhY2UgYW5kIGNhbGxpbmcgYHBvbGxWYXVsdEJhc2VQYXRoKClgIGF3YWl0cyBgbGF5b3V0UmVhZHlgLCBzb1xuICAgKiBieSB0aGUgdGltZSB0aGlzIHJldHVybnMgdGhlIGRpYWxvZyBoYXMgZWl0aGVyIHJlbmRlcmVkIG9yIGlzIG5vdCBnb2luZ1xuICAgKiB0byByZW5kZXIuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgdmF1bHQgcGF0aCB0byBldmFsdWF0ZSBpbi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvckxheW91dFJlYWR5KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgZW5zdXJlTmFtZXNwYWNlQm9vdHN0cmFwcGVkKHRoaXMsIHZhdWx0UGF0aCk7XG4gICAgYXdhaXQgdGhpcy5ldmFsdWF0ZSgnd2luZG93Ll9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcucG9sbFZhdWx0QmFzZVBhdGgoKScsIHsgY3dkOiB2YXVsdFBhdGggfSk7XG4gIH1cblxuICAvKipcbiAgICogUG9sbHMgdGhlIG93bmVkIGluc3RhbmNlIHVudGlsIHRoZSB2YXVsdCB0YXJnZXQgZXhpc3RzLCBsYXlvdXQgaXMgcmVhZHksIGFuZFxuICAgKiB0aGUgdHJ1c3QgZGlhbG9nIChpZiBhbnkpIGhhcyBiZWVuIGRpc21pc3NlZC5cbiAgICpcbiAgICogQmV0d2VlbiByZWFkaW5lc3MgYXR0ZW1wdHMgaXQgYWxzbyBjaGVja3MgZm9yIGEgKipkZWFkIGJvb3QqKiBcdTIwMTQgdGhlIHJlbmRlcmVyXG4gICAqIGxvYWRlZCAoYGRvY3VtZW50LnJlYWR5U3RhdGVgIGAnY29tcGxldGUnYCkgYnV0IHRoZSBhcHAgbmV2ZXIgYm9vdHN0cmFwcGVkXG4gICAqIChlbXB0eSBgPGJvZHk+YCwgbm8gYHdpbmRvdy5hcHBgKSwgdGhlIHRlcm1pbmFsIHN0YXRlIHdoZW4gdGhlIGFzYXIgY2Fubm90XG4gICAqIHJ1biBvbiB0aGUgbGF1bmNoZWQgRWxlY3Ryb24gc2hlbGwuIE9uY2UgdGhhdCBzdGF0ZSBoYXMgaGVsZCBmb3IgdGhlXG4gICAqIGNvbmZpZ3VyZWQgZ3JhY2Ugd2luZG93IGl0IHRocm93cyBhIHtAbGluayBSZW5kZXJlckZhaWxlZFRvSW5pdGlhbGl6ZUVycm9yfVxuICAgKiBpbW1lZGlhdGVseSBpbnN0ZWFkIG9mIHdhaXRpbmcgb3V0IHRoZSBmdWxsIHJlYWRpbmVzcyB0aW1lb3V0LiBBIGdyYWNlIG9mXG4gICAqIGAwYCBkaXNhYmxlcyB0aGUgZmFzdC1mYWlsLiBUaGUgZ3JhY2UgY2xvY2sgc3RhcnRzIHdoZW4gdGhlIHJlbmRlcmVyIGZpcnN0XG4gICAqIHJlcG9ydHMgYGNvbXBsZXRlYCwgc28gYSBzbG93IGxvYWQgYmVmb3JlIHRoZW4gaXMgbmV2ZXIgY291bnRlZCBhZ2FpbnN0IGl0LlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IGZvbGRlci5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvck93bmVkVmF1bHRSZWFkeSh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIFdhaXRpbmcgZm9yIG93bmVkIHZhdWx0IHRvIGJlY29tZSByZWFkeSAodGltZW91dD0ke1N0cmluZyhWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcykuLi5gKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIGxldCBkb2N1bWVudENvbXBsZXRlU2luY2U6IG51bGwgfCBudW1iZXIgPSBudWxsO1xuICAgIGxldCBpc1JlYWR5ID0gZmFsc2U7XG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5maW5kVGFyZ2V0Rm9yVmF1bHQodmF1bHRQYXRoKTtcbiAgICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yTGF5b3V0UmVhZHkodmF1bHRQYXRoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5kaXNtaXNzVHJ1c3REaWFsb2codmF1bHRQYXRoKTtcbiAgICAgICAgaXNSZWFkeSA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIFRoZSB2YXVsdCBpcyBub3QgcmVhZHkgeWV0IFx1MjAxNCBhbHNvIGRyb3AgdGhlIGNhY2hlZCBDRFAgY29ubmVjdGlvbiBiZWZvcmVcbiAgICAgICAgLy8gUmV0cnlpbmcuIE9sZCAoRWxlY3Ryb24gMTAtZXJhKSBPYnNpZGlhbiByZWxvYWRzIHRoZSBvd25lZCB3aW5kb3cgZHVyaW5nXG4gICAgICAgIC8vIEJvb3QsIHdoaWNoIGNhbiBsZWF2ZSB0aGUgY2FjaGVkIFdlYlNvY2tldCBwaW5uZWQgdG8gYSBzdGFsZSBleGVjdXRpb25cbiAgICAgICAgLy8gQ29udGV4dDsgcmVjb25uZWN0aW5nIGVhY2ggYXR0ZW1wdCByZS1iaW5kcyB0byB0aGUgbGl2ZSBjb250ZXh0LlxuICAgICAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuZGVhZEJvb3RHcmFjZUluTWlsbGlzZWNvbmRzID4gMCkge1xuICAgICAgICBjb25zdCBvYnNlcnZhdGlvbiA9IGF3YWl0IHRoaXMucHJvYmVSZW5kZXJlckJvb3RTdGF0ZSgpO1xuICAgICAgICBpZiAob2JzZXJ2YXRpb24pIHtcbiAgICAgICAgICBpZiAob2JzZXJ2YXRpb24uaXNEb2N1bWVudENvbXBsZXRlICYmIGRvY3VtZW50Q29tcGxldGVTaW5jZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgZG9jdW1lbnRDb21wbGV0ZVNpbmNlID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgaGFzR3JhY2VFbGFwc2VkID0gZG9jdW1lbnRDb21wbGV0ZVNpbmNlICE9PSBudWxsXG4gICAgICAgICAgICAmJiBEYXRlLm5vdygpIC0gZG9jdW1lbnRDb21wbGV0ZVNpbmNlID49IHRoaXMuZGVhZEJvb3RHcmFjZUluTWlsbGlzZWNvbmRzO1xuICAgICAgICAgIGlmIChjaGVja1JlbmRlcmVyQm9vdFN0YXRlKHsgLi4ub2JzZXJ2YXRpb24sIGhhc0dyYWNlRWxhcHNlZCB9KSA9PT0gJ2RlYWQnKSB7XG4gICAgICAgICAgICBsb2coJ1tjZHAtdHJhbnNwb3J0XSBPd25lZCByZW5kZXJlciBmYWlsZWQgdG8gaW5pdGlhbGl6ZSAoZGVhZCBib290KTsgZmFpbGluZyBmYXN0LicpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJlbmRlcmVyRmFpbGVkVG9Jbml0aWFsaXplRXJyb3IodmF1bHRQYXRoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYXdhaXQgZGVsYXkoVkFVTFRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cblxuICAgIGlmICghaXNSZWFkeSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBPd25lZCB2YXVsdCBhdCAke3ZhdWx0UGF0aH0gZGlkIG5vdCBiZWNvbWUgcmVhZHkgd2l0aGluICR7U3RyaW5nKFZBVUxUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMpfW1zYCk7XG4gICAgfVxuXG4gICAgLy8gVGhlIHZhdWx0IGlzIHJlYWR5LiBSdW4gdGhlIHBvc3QtYm9vdCBjb21wYXRpYmlsaXR5IGNoZWNrcyBoZXJlIFx1MjAxNCBPVVRTSURFIHRoZVxuICAgIC8vIFBvbGwncyB0cnkvY2F0Y2ggXHUyMDE0IHNvIGEgU2lsZW50QXNhckZhbGxiYWNrRXJyb3IgZmFpbHMgZmFzdCBpbnN0ZWFkIG9mIGJlaW5nXG4gICAgLy8gU3dhbGxvd2VkIGFzIFwibm90IHJlYWR5IHlldFwiIGFuZCBsb29waW5nIHVudGlsIHRoZSByZWFkaW5lc3MgdGltZW91dC5cbiAgICBhd2FpdCB0aGlzLmNoZWNrUnVudGltZUNvbXBhdGliaWxpdHkodmF1bHRQYXRoKTtcbiAgICBsb2coJ1tjZHAtdHJhbnNwb3J0XSBPd25lZCB2YXVsdCBpcyByZWFkeS4nKTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIGdpdmVuIGRlbGF5LlxuICpcbiAqIEBwYXJhbSBtcyAtIFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgZGVsYXkuXG4gKi9cbmZ1bmN0aW9uIGRlbGF5KG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgc2V0VGltZW91dChyZXNvbHZlLCBtcyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHBsYXRmb3JtLXNwZWNpZmljIGNvbW1hbmQgdG8gbGF1bmNoIE9ic2lkaWFuIHdpdGggcmVtb3RlIGRlYnVnZ2luZyBlbmFibGVkLlxuICpcbiAqIFJlc29sdmVzIHRoZSBhY3R1YWwgaW5zdGFsbGVkIE9ic2lkaWFuIGV4ZWN1dGFibGUgKGNvdmVyaW5nIGluc3RhbGxlci1iYXNlZFxuICogYW5kIGBQQVRIYC1iYXNlZCBpbnN0YWxscyBzdWNoIGFzIGBzY29vcGApIGFuZCB2ZXJpZmllcyBpdCBleGlzdHMgYmVmb3JlXG4gKiByZXR1cm5pbmcgYSBjb21tYW5kLiBUaHJvd3MgaWYgT2JzaWRpYW4gaXMgbm90IGluc3RhbGxlZC5cbiAqXG4gKiBAcGFyYW0gcG9ydCAtIFRoZSBDRFAgcG9ydCB0byB1c2UuXG4gKiBAcmV0dXJucyBUaGUgc2hlbGwgY29tbWFuZCBzdHJpbmcuXG4gKiBAdGhyb3dzIEVycm9yIGlmIE9ic2lkaWFuIGNhbm5vdCBiZSBsb2NhdGVkLlxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRPYnNpZGlhbkxhdW5jaENvbW1hbmQocG9ydDogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgZXhlUGF0aCA9IGF3YWl0IHJlc29sdmVPYnNpZGlhbkV4ZWN1dGFibGUoKTtcbiAgY29uc3QgZmxhZyA9IGAtLXJlbW90ZS1kZWJ1Z2dpbmctcG9ydD0ke1N0cmluZyhwb3J0KX1gO1xuXG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKSB7XG4gICAgcmV0dXJuIGBzdGFydCBcIlwiIFwiJHtleGVQYXRofVwiICR7ZmxhZ31gO1xuICB9XG5cbiAgcmV0dXJuIGBcIiR7ZXhlUGF0aH1cIiAke2ZsYWd9ICZgO1xufVxuXG4vKipcbiAqIEF0dGVtcHRzIHRvIHJlbW92ZSBhIGRpcmVjdG9yeSByZWN1cnNpdmVseSwgcmV0dXJuaW5nIHdoZXRoZXIgaXQgc3VjY2VlZGVkLlxuICpcbiAqIEBwYXJhbSBkaXIgLSBUaGUgZGlyZWN0b3J5IHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiByZW1vdmVkLCBgZmFsc2VgIGlmIHRoZSByZW1vdmFsIHRocmV3IChlLmcuIGhhbmRsZXMgaGVsZCkuXG4gKi9cbmZ1bmN0aW9uIHRyeVJlbW92ZURpcihkaXI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIHJtU3luYyhkaXIsIHsgZm9yY2U6IHRydWUsIHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qIHY4IGlnbm9yZSBzdG9wICovXG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQXFCQSx5QkFBNEI7QUFDNUIscUJBSU87QUFDUCx1QkFBcUI7QUFDckIsMEJBQW9CO0FBWXBCLHFDQUFrQztBQUNsQyxtQ0FBMEM7QUFDMUMsa0NBQTBDO0FBQzFDLG9DQUEyQztBQUMzQyxrQkFBcUI7QUFDckIsaUJBQW9CO0FBQ3BCLGlDQUE0QztBQUM1Qyw2QkFJTztBQUNQLGlDQUEwQztBQUMxQywrQkFBNEM7QUFDNUMsK0JBQW1DO0FBQ25DLHFDQUFxQztBQUNyQyw4QkFBdUM7QUFDdkMscUNBR087QUFDUCxpREFBZ0Q7QUFDaEQsd0NBQXdDO0FBQ3hDLHlC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