obsidian-integration-testing 9.2.2 → 10.0.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.
- package/README.md +45 -45
- package/dist/lib/cjs/appium-dependencies.cjs +5 -5
- package/dist/lib/cjs/appium-dependencies.d.cts +4 -2
- package/dist/lib/cjs/appium-session-config.cjs +1 -1
- package/dist/lib/cjs/asar-fallback-detection.cjs +4 -4
- package/dist/lib/cjs/asar-fallback-detection.d.cts +15 -7
- package/dist/lib/cjs/avd-list.cjs +1 -1
- package/dist/lib/cjs/avd-list.d.cts +6 -2
- package/dist/lib/cjs/cli.cjs +4 -4
- package/dist/lib/cjs/compatibility-options.cjs +13 -13
- package/dist/lib/cjs/compatibility-options.d.cts +24 -12
- package/dist/lib/cjs/connect-to-cdp.cjs +4 -4
- package/dist/lib/cjs/connect-to-cdp.d.cts +6 -6
- package/dist/lib/cjs/context-id.cjs +5 -5
- package/dist/lib/cjs/context-id.d.cts +1 -1
- package/dist/lib/cjs/context-provider.cjs +5 -5
- package/dist/lib/cjs/context-provider.d.cts +4 -4
- package/dist/lib/cjs/demo-vault-populate.cjs +5 -5
- package/dist/lib/cjs/demo-vault-populate.d.cts +4 -4
- package/dist/lib/cjs/demo-vault-tree.cjs +4 -4
- package/dist/lib/cjs/demo-vault-tree.d.cts +3 -3
- package/dist/lib/cjs/device-readiness.cjs +3 -3
- package/dist/lib/cjs/device-readiness.d.cts +7 -3
- package/dist/lib/cjs/ecmascript-version.cjs +1 -1
- package/dist/lib/cjs/electron-compatibility.cjs +4 -4
- package/dist/lib/cjs/electron-compatibility.d.cts +33 -17
- package/dist/lib/cjs/emulator-arguments.cjs +36 -0
- package/dist/lib/{esm/emulator-args.d.mts → cjs/emulator-arguments.d.cts} +6 -4
- package/dist/lib/cjs/enable-plugin.cjs +29 -29
- package/dist/lib/cjs/enable-plugin.d.cts +6 -6
- package/dist/lib/cjs/eval-in-obsidian.cjs +9 -9
- package/dist/lib/cjs/eval-in-obsidian.d.cts +23 -23
- package/dist/lib/cjs/exec.cjs +49 -53
- package/dist/lib/cjs/exec.d.cts +9 -9
- package/dist/lib/cjs/function-expression.cjs +8 -8
- package/dist/lib/cjs/function-expression.d.cts +4 -4
- package/dist/lib/cjs/generate-function-call.cjs +6 -6
- package/dist/lib/cjs/generate-function-call.d.cts +15 -9
- package/dist/lib/cjs/global-setup-core.cjs +43 -43
- package/dist/lib/cjs/global-setup-core.d.cts +19 -9
- package/dist/lib/cjs/incompatible-installer-version-error.cjs +10 -4
- package/dist/lib/cjs/incompatible-installer-version-error.d.cts +18 -6
- package/dist/lib/cjs/index.cjs +10 -10
- package/dist/lib/cjs/index.d.cts +8 -8
- package/dist/lib/cjs/installer-asset.cjs +4 -4
- package/dist/lib/cjs/installer-asset.d.cts +21 -7
- package/dist/lib/cjs/installer-compatibility.cjs +4 -4
- package/dist/lib/cjs/installer-compatibility.d.cts +36 -18
- package/dist/lib/cjs/jest/global-setup-no-plugin.cjs +3 -3
- package/dist/lib/cjs/jest/global-setup-no-plugin.d.cts +1 -1
- package/dist/lib/cjs/jest/global-setup.cjs +11 -11
- package/dist/lib/cjs/jest/global-setup.d.cts +12 -8
- package/dist/lib/cjs/jest/global-teardown-no-plugin.cjs +2 -3
- package/dist/lib/cjs/jest/global-teardown-no-plugin.d.cts +1 -2
- package/dist/lib/cjs/jest/global-teardown.cjs +2 -3
- package/dist/lib/cjs/jest/global-teardown.d.cts +1 -2
- package/dist/lib/cjs/jest/setup.cjs +2 -2
- package/dist/lib/cjs/jest/setup.d.cts +1 -1
- package/dist/lib/cjs/json-with-functions.cjs +7 -7
- package/dist/lib/cjs/leftover-cleanup.cjs +14 -14
- package/dist/lib/cjs/leftover-cleanup.d.cts +42 -20
- package/dist/lib/cjs/library.cjs +2 -2
- package/dist/lib/cjs/namespace-bootstrap.cjs +46 -40
- package/dist/lib/cjs/native-dialog-monitor.cjs +15 -13
- package/dist/lib/cjs/normalize-optional-properties.cjs +3 -3
- package/dist/lib/cjs/normalize-optional-properties.d.cts +2 -2
- package/dist/lib/cjs/obsidian-config.cjs +30 -31
- package/dist/lib/cjs/obsidian-config.d.cts +8 -8
- package/dist/lib/cjs/obsidian-executable.cjs +2 -2
- package/dist/lib/cjs/obsidian-installer.cjs +37 -37
- package/dist/lib/cjs/obsidian-installer.d.cts +7 -3
- package/dist/lib/cjs/obsidian-instance.cjs +3 -3
- package/dist/lib/cjs/obsidian-instance.d.cts +18 -8
- package/dist/lib/cjs/obsidian-metadata.cjs +1 -1
- package/dist/lib/cjs/obsidian-metadata.d.cts +36 -12
- package/dist/lib/cjs/obsidian-namespace.cjs +1 -1
- package/dist/lib/cjs/obsidian-namespace.d.cts +25 -11
- package/dist/lib/cjs/obsidian-version-switch.cjs +9 -9
- package/dist/lib/cjs/obsidian-version-switch.d.cts +14 -10
- package/dist/lib/cjs/obsidian-version.cjs +3 -3
- package/dist/lib/cjs/obsidian-version.d.cts +15 -5
- package/dist/lib/cjs/owned-vault-seed.cjs +1 -1
- package/dist/lib/cjs/owned-vault-seed.d.cts +24 -8
- package/dist/lib/cjs/parent-liveness.cjs +4 -4
- package/dist/lib/cjs/parent-liveness.d.cts +7 -3
- package/dist/lib/cjs/poll-in-obsidian.cjs +5 -5
- package/dist/lib/cjs/poll-in-obsidian.d.cts +12 -12
- package/dist/lib/cjs/poll-until.cjs +1 -1
- package/dist/lib/cjs/poll-until.d.cts +21 -7
- package/dist/lib/cjs/process-exit-message.cjs +1 -1
- package/dist/lib/cjs/process-exit-message.d.cts +21 -7
- package/dist/lib/cjs/renderer-boot-detection.cjs +9 -9
- package/dist/lib/cjs/renderer-boot-detection.d.cts +31 -27
- package/dist/lib/cjs/renderer-failed-to-initialize-error.cjs +1 -1
- package/dist/lib/cjs/renderer-failed-to-initialize-error.d.cts +1 -1
- package/dist/lib/cjs/setup-lock.cjs +26 -26
- package/dist/lib/cjs/setup-lock.d.cts +6 -2
- package/dist/lib/cjs/silent-asar-fallback-error.cjs +7 -3
- package/dist/lib/cjs/silent-asar-fallback-error.d.cts +12 -4
- package/dist/lib/cjs/spawn-options.cjs +1 -1
- package/dist/lib/cjs/spawn-options.d.cts +3 -1
- package/dist/lib/cjs/strict-proxy.cjs +25 -25
- package/dist/lib/cjs/strict-proxy.d.cts +3 -3
- package/dist/lib/cjs/temporary-vault.cjs +166 -0
- package/dist/lib/cjs/{temp-vault.d.cts → temporary-vault.d.cts} +3 -3
- package/dist/lib/cjs/transport-appium.cjs +7 -7
- package/dist/lib/cjs/transport-appium.d.cts +7 -3
- package/dist/lib/cjs/transport-desktop-cdp.cjs +57 -57
- package/dist/lib/cjs/transport-desktop-cdp.d.cts +29 -17
- package/dist/lib/cjs/transport-factory.cjs +62 -63
- package/dist/lib/cjs/type-guards.cjs +3 -3
- package/dist/lib/cjs/type-guards.d.cts +2 -2
- package/dist/lib/cjs/vault-path-match.cjs +9 -9
- package/dist/lib/cjs/vault-path-match.d.cts +11 -11
- package/dist/lib/cjs/version-matrix.cjs +1 -1
- package/dist/lib/cjs/version-matrix.d.cts +51 -17
- package/dist/lib/cjs/visibility.cjs +7 -7
- package/dist/lib/cjs/visibility.d.cts +5 -5
- package/dist/lib/cjs/vitest/global-setup-no-plugin.cjs +3 -3
- package/dist/lib/cjs/vitest/global-setup-no-plugin.d.cts +2 -2
- package/dist/lib/cjs/vitest/global-setup.cjs +9 -9
- package/dist/lib/cjs/vitest/global-setup.d.cts +4 -4
- package/dist/lib/cjs/vitest/setup.cjs +2 -2
- package/dist/lib/cjs/vitest/typings.d.cts +2 -2
- package/dist/lib/esm/appium-dependencies.d.mts +4 -2
- package/dist/lib/esm/appium-dependencies.mjs +4 -4
- package/dist/lib/esm/appium-session-config.mjs +1 -1
- package/dist/lib/esm/asar-fallback-detection.d.mts +15 -7
- package/dist/lib/esm/asar-fallback-detection.mjs +3 -3
- package/dist/lib/esm/avd-list.d.mts +6 -2
- package/dist/lib/esm/avd-list.mjs +1 -1
- package/dist/lib/esm/cli.mjs +4 -4
- package/dist/lib/esm/compatibility-options.d.mts +24 -12
- package/dist/lib/esm/compatibility-options.mjs +10 -10
- package/dist/lib/esm/connect-to-cdp.d.mts +6 -6
- package/dist/lib/esm/connect-to-cdp.mjs +6 -6
- package/dist/lib/esm/context-id.d.mts +1 -1
- package/dist/lib/esm/context-id.mjs +5 -5
- package/dist/lib/esm/context-provider.d.mts +4 -4
- package/dist/lib/esm/context-provider.mjs +5 -5
- package/dist/lib/esm/demo-vault-populate.d.mts +4 -4
- package/dist/lib/esm/demo-vault-populate.mjs +5 -5
- package/dist/lib/esm/demo-vault-tree.d.mts +3 -3
- package/dist/lib/esm/demo-vault-tree.mjs +4 -4
- package/dist/lib/esm/device-readiness.d.mts +7 -3
- package/dist/lib/esm/device-readiness.mjs +3 -3
- package/dist/lib/esm/ecmascript-version.mjs +1 -1
- package/dist/lib/esm/electron-compatibility.d.mts +33 -17
- package/dist/lib/esm/electron-compatibility.mjs +3 -3
- package/dist/lib/{cjs/emulator-args.d.cts → esm/emulator-arguments.d.mts} +6 -4
- package/dist/lib/esm/emulator-arguments.mjs +12 -0
- package/dist/lib/esm/enable-plugin.d.mts +6 -6
- package/dist/lib/esm/enable-plugin.mjs +29 -29
- package/dist/lib/esm/eval-in-obsidian.d.mts +23 -23
- package/dist/lib/esm/eval-in-obsidian.mjs +9 -9
- package/dist/lib/esm/exec.d.mts +9 -9
- package/dist/lib/esm/exec.mjs +49 -53
- package/dist/lib/esm/function-expression.d.mts +4 -4
- package/dist/lib/esm/function-expression.mjs +8 -8
- package/dist/lib/esm/generate-function-call.d.mts +15 -9
- package/dist/lib/esm/generate-function-call.mjs +6 -6
- package/dist/lib/esm/global-setup-core.d.mts +19 -9
- package/dist/lib/esm/global-setup-core.mjs +45 -45
- package/dist/lib/esm/incompatible-installer-version-error.d.mts +18 -6
- package/dist/lib/esm/incompatible-installer-version-error.mjs +10 -4
- package/dist/lib/esm/index.d.mts +8 -8
- package/dist/lib/esm/index.mjs +9 -9
- package/dist/lib/esm/installer-asset.d.mts +21 -7
- package/dist/lib/esm/installer-asset.mjs +4 -4
- package/dist/lib/esm/installer-compatibility.d.mts +36 -18
- package/dist/lib/esm/installer-compatibility.mjs +3 -3
- package/dist/lib/esm/jest/global-setup-no-plugin.d.mts +1 -1
- package/dist/lib/esm/jest/global-setup-no-plugin.mjs +3 -3
- package/dist/lib/esm/jest/global-setup.d.mts +12 -8
- package/dist/lib/esm/jest/global-setup.mjs +10 -10
- package/dist/lib/esm/jest/global-teardown-no-plugin.d.mts +1 -2
- package/dist/lib/esm/jest/global-teardown-no-plugin.mjs +2 -3
- package/dist/lib/esm/jest/global-teardown.d.mts +1 -2
- package/dist/lib/esm/jest/global-teardown.mjs +2 -3
- package/dist/lib/esm/jest/setup.d.mts +1 -1
- package/dist/lib/esm/jest/setup.mjs +2 -2
- package/dist/lib/esm/json-with-functions.mjs +7 -7
- package/dist/lib/esm/leftover-cleanup.d.mts +42 -20
- package/dist/lib/esm/leftover-cleanup.mjs +12 -12
- package/dist/lib/esm/library.mjs +2 -2
- package/dist/lib/esm/namespace-bootstrap.mjs +46 -40
- package/dist/lib/esm/native-dialog-monitor.mjs +15 -13
- package/dist/lib/esm/normalize-optional-properties.d.mts +2 -2
- package/dist/lib/esm/normalize-optional-properties.mjs +3 -3
- package/dist/lib/esm/obsidian-config.d.mts +8 -8
- package/dist/lib/esm/obsidian-config.mjs +27 -28
- package/dist/lib/esm/obsidian-executable.mjs +2 -2
- package/dist/lib/esm/obsidian-installer.d.mts +7 -3
- package/dist/lib/esm/obsidian-installer.mjs +36 -36
- package/dist/lib/esm/obsidian-instance.d.mts +18 -8
- package/dist/lib/esm/obsidian-instance.mjs +3 -3
- package/dist/lib/esm/obsidian-metadata.d.mts +36 -12
- package/dist/lib/esm/obsidian-metadata.mjs +1 -1
- package/dist/lib/esm/obsidian-namespace.d.mts +25 -11
- package/dist/lib/esm/obsidian-version-switch.d.mts +14 -10
- package/dist/lib/esm/obsidian-version-switch.mjs +9 -9
- package/dist/lib/esm/obsidian-version.d.mts +15 -5
- package/dist/lib/esm/obsidian-version.mjs +3 -3
- package/dist/lib/esm/owned-vault-seed.d.mts +24 -8
- package/dist/lib/esm/owned-vault-seed.mjs +1 -1
- package/dist/lib/esm/parent-liveness.d.mts +7 -3
- package/dist/lib/esm/parent-liveness.mjs +3 -3
- package/dist/lib/esm/poll-in-obsidian.d.mts +12 -12
- package/dist/lib/esm/poll-in-obsidian.mjs +5 -5
- package/dist/lib/esm/poll-until.d.mts +21 -7
- package/dist/lib/esm/poll-until.mjs +1 -1
- package/dist/lib/esm/process-exit-message.d.mts +21 -7
- package/dist/lib/esm/process-exit-message.mjs +1 -1
- package/dist/lib/esm/renderer-boot-detection.d.mts +31 -27
- package/dist/lib/esm/renderer-boot-detection.mjs +7 -7
- package/dist/lib/esm/renderer-failed-to-initialize-error.d.mts +1 -1
- package/dist/lib/esm/renderer-failed-to-initialize-error.mjs +1 -1
- package/dist/lib/esm/setup-lock.d.mts +6 -2
- package/dist/lib/esm/setup-lock.mjs +26 -26
- package/dist/lib/esm/silent-asar-fallback-error.d.mts +12 -4
- package/dist/lib/esm/silent-asar-fallback-error.mjs +7 -3
- package/dist/lib/esm/spawn-options.d.mts +3 -1
- package/dist/lib/esm/spawn-options.mjs +1 -1
- package/dist/lib/esm/strict-proxy.d.mts +3 -3
- package/dist/lib/esm/strict-proxy.mjs +25 -25
- package/dist/lib/esm/{temp-vault.d.mts → temporary-vault.d.mts} +3 -3
- package/dist/lib/esm/temporary-vault.mjs +157 -0
- package/dist/lib/esm/transport-appium.d.mts +7 -3
- package/dist/lib/esm/transport-appium.mjs +7 -7
- package/dist/lib/esm/transport-desktop-cdp.d.mts +29 -17
- package/dist/lib/esm/transport-desktop-cdp.mjs +67 -67
- package/dist/lib/esm/transport-factory.mjs +71 -72
- package/dist/lib/esm/type-guards.d.mts +2 -2
- package/dist/lib/esm/type-guards.mjs +3 -3
- package/dist/lib/esm/vault-path-match.d.mts +11 -11
- package/dist/lib/esm/vault-path-match.mjs +7 -7
- package/dist/lib/esm/version-matrix.d.mts +51 -17
- package/dist/lib/esm/version-matrix.mjs +1 -1
- package/dist/lib/esm/visibility.d.mts +5 -5
- package/dist/lib/esm/visibility.mjs +5 -5
- package/dist/lib/esm/vitest/global-setup-no-plugin.d.mts +2 -2
- package/dist/lib/esm/vitest/global-setup-no-plugin.mjs +3 -3
- package/dist/lib/esm/vitest/global-setup.d.mts +4 -4
- package/dist/lib/esm/vitest/global-setup.mjs +8 -8
- package/dist/lib/esm/vitest/setup.mjs +2 -2
- package/dist/lib/esm/vitest/typings.d.mts +2 -2
- package/dist/obsidian-integration-testing-10.0.0.tgz +0 -0
- package/package.json +15 -13
- package/dist/lib/cjs/emulator-args.cjs +0 -36
- package/dist/lib/cjs/temp-vault.cjs +0 -166
- package/dist/lib/esm/emulator-args.mjs +0 -12
- package/dist/lib/esm/temp-vault.mjs +0 -157
- package/dist/obsidian-integration-testing-9.2.2.tgz +0 -0
|
@@ -6,35 +6,35 @@ import {
|
|
|
6
6
|
} from "node:fs";
|
|
7
7
|
import { join } from "node:path";
|
|
8
8
|
import process from "node:process";
|
|
9
|
-
import {
|
|
9
|
+
import { resolveAsarFallback } from "./asar-fallback-detection.mjs";
|
|
10
10
|
import { resolveAsarFallbackAction } from "./compatibility-options.mjs";
|
|
11
11
|
import { DISMISS_TRUST_DIALOG_EXPR } from "./dismiss-trust-dialog.mjs";
|
|
12
|
-
import {
|
|
12
|
+
import { resolveElectronCompatibility } from "./electron-compatibility.mjs";
|
|
13
13
|
import { exec } from "./exec.mjs";
|
|
14
14
|
import { log } from "./log.mjs";
|
|
15
15
|
import { ensureNamespaceBootstrapped } from "./namespace-bootstrap.mjs";
|
|
16
16
|
import {
|
|
17
|
+
didRemoveVaultFromConfig,
|
|
17
18
|
getVaultId,
|
|
18
|
-
isVaultRegistered
|
|
19
|
-
removeVaultFromConfig
|
|
19
|
+
isVaultRegistered
|
|
20
20
|
} from "./obsidian-config.mjs";
|
|
21
21
|
import { resolveObsidianExecutable } from "./obsidian-executable.mjs";
|
|
22
22
|
import { launchOwnedObsidianInstance } from "./obsidian-instance.mjs";
|
|
23
23
|
import { getVersionMetadata } from "./obsidian-metadata.mjs";
|
|
24
24
|
import { copyAsarIntoUserData } from "./obsidian-version-switch.mjs";
|
|
25
25
|
import { buildOwnedObsidianJson } from "./owned-vault-seed.mjs";
|
|
26
|
-
import {
|
|
26
|
+
import { buildParentLivenessWatchdogExpression } from "./parent-liveness.mjs";
|
|
27
27
|
import {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
DEFAULT_DEAD_BOOT_GRACE_IN_MILLISECONDS,
|
|
29
|
+
resolveRendererBootState
|
|
30
30
|
} from "./renderer-boot-detection.mjs";
|
|
31
31
|
import { RendererFailedToInitializeError } from "./renderer-failed-to-initialize-error.mjs";
|
|
32
32
|
import { SilentAsarFallbackError } from "./silent-asar-fallback-error.mjs";
|
|
33
33
|
import { ensureNonNullable } from "./type-guards.mjs";
|
|
34
|
-
import {
|
|
34
|
+
import { areVaultPathsMatching } from "./vault-path-match.mjs";
|
|
35
35
|
import {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
resolveOwnedHiddenLaunchArguments,
|
|
37
|
+
resolveSandboxLaunchArguments,
|
|
38
38
|
shouldHideObsidianApp
|
|
39
39
|
} from "./visibility.mjs";
|
|
40
40
|
const COMMAND_TIMEOUT_IN_MILLISECONDS = 3e4;
|
|
@@ -107,7 +107,7 @@ class DesktopCdpTransport {
|
|
|
107
107
|
}
|
|
108
108
|
/**
|
|
109
109
|
* Disposes of the active WebSocket connection and, in owned-instance mode,
|
|
110
|
-
* kills the owned Obsidian process and removes its isolated user-data
|
|
110
|
+
* kills the owned Obsidian process and removes its isolated user-data directory.
|
|
111
111
|
*
|
|
112
112
|
* The removal is retried because Windows briefly holds the just-killed
|
|
113
113
|
* process's file handles, which would otherwise fail `rmSync` with `EPERM`.
|
|
@@ -118,29 +118,29 @@ class DesktopCdpTransport {
|
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
120
|
this.ownedInstance?.kill();
|
|
121
|
-
const {
|
|
121
|
+
const { userDataDirectory } = this.ownedConfig;
|
|
122
122
|
const deadline = Date.now() + USER_DATA_RM_TIMEOUT_IN_MILLISECONDS;
|
|
123
123
|
while (Date.now() < deadline) {
|
|
124
|
-
if (
|
|
124
|
+
if (didRemoveDirectory(userDataDirectory)) {
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
127
|
await delay(USER_DATA_RM_RETRY_INTERVAL_IN_MILLISECONDS);
|
|
128
128
|
}
|
|
129
|
-
if (!
|
|
130
|
-
log(`[cdp-transport] Could not remove owned user-data
|
|
129
|
+
if (!didRemoveDirectory(userDataDirectory)) {
|
|
130
|
+
log(`[cdp-transport] Could not remove owned user-data directory within ${String(USER_DATA_RM_TIMEOUT_IN_MILLISECONDS)}ms (non-fatal): ${userDataDirectory}`);
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
/**
|
|
134
134
|
* Synchronous disposal — kills the owned instance and makes a best-effort
|
|
135
|
-
* removal of its user-data
|
|
136
|
-
* (where async retries are impossible; a leftover temp
|
|
135
|
+
* removal of its user-data directory. Safe to call from a process `exit` handler
|
|
136
|
+
* (where async retries are impossible; a leftover temp directory is acceptable).
|
|
137
137
|
*/
|
|
138
138
|
disposeSync() {
|
|
139
139
|
this.disconnect();
|
|
140
140
|
if (this.ownedConfig) {
|
|
141
141
|
this.ownedInstance?.kill();
|
|
142
|
-
if (!
|
|
143
|
-
log(`[cdp-transport] Owned user-data
|
|
142
|
+
if (!didRemoveDirectory(this.ownedConfig.userDataDirectory)) {
|
|
143
|
+
log(`[cdp-transport] Owned user-data directory not removed synchronously (process may still hold handles): ${this.ownedConfig.userDataDirectory}`);
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
}
|
|
@@ -164,11 +164,11 @@ class DesktopCdpTransport {
|
|
|
164
164
|
const desc = response.result.exceptionDetails.exception?.description ?? response.result.exceptionDetails.text;
|
|
165
165
|
throw new Error(`CDP evaluation error: ${desc}`);
|
|
166
166
|
}
|
|
167
|
-
const
|
|
168
|
-
if (!
|
|
167
|
+
const resultObject = response.result?.result;
|
|
168
|
+
if (!resultObject || resultObject.type === "undefined") {
|
|
169
169
|
return NO_OUTPUT;
|
|
170
170
|
}
|
|
171
|
-
return String(
|
|
171
|
+
return String(resultObject.value);
|
|
172
172
|
}
|
|
173
173
|
/**
|
|
174
174
|
* Returns the silent-asar-fallback verdict for this owned instance — whether the
|
|
@@ -238,7 +238,7 @@ class DesktopCdpTransport {
|
|
|
238
238
|
log(`[cdp-transport] Running preflight check for vault: ${vaultPath}`);
|
|
239
239
|
if (!isVaultRegistered(vaultPath)) {
|
|
240
240
|
throw new Error(
|
|
241
|
-
`Vault is not registered in Obsidian: ${vaultPath}. Register the vault first with registerVault() or
|
|
241
|
+
`Vault is not registered in Obsidian: ${vaultPath}. Register the vault first with registerVault() or TemporaryVault.register().`
|
|
242
242
|
);
|
|
243
243
|
}
|
|
244
244
|
try {
|
|
@@ -280,10 +280,10 @@ class DesktopCdpTransport {
|
|
|
280
280
|
const target = await this.findTargetForVault(vaultPath);
|
|
281
281
|
const ws = await this.connectToTarget(target);
|
|
282
282
|
try {
|
|
283
|
-
const
|
|
283
|
+
const windowDestroyExpression = "window.__obsidianIntegrationTesting.destroyCurrentWindow()";
|
|
284
284
|
await this.sendCommand(ws, "Runtime.evaluate", {
|
|
285
285
|
awaitPromise: true,
|
|
286
|
-
expression:
|
|
286
|
+
expression: windowDestroyExpression,
|
|
287
287
|
returnByValue: true
|
|
288
288
|
});
|
|
289
289
|
} finally {
|
|
@@ -302,10 +302,10 @@ class DesktopCdpTransport {
|
|
|
302
302
|
const ws = await this.connectToTarget(removalTarget);
|
|
303
303
|
try {
|
|
304
304
|
await ensureNamespaceBootstrapped(this, removalBasePath);
|
|
305
|
-
const
|
|
305
|
+
const vaultRemoveExpression = `window.__obsidianIntegrationTesting.ipcSendSync(${JSON.stringify({ channel: "vault-remove", channelArguments: [vaultPath] })})`;
|
|
306
306
|
await this.sendCommand(ws, "Runtime.evaluate", {
|
|
307
307
|
awaitPromise: true,
|
|
308
|
-
expression:
|
|
308
|
+
expression: vaultRemoveExpression,
|
|
309
309
|
returnByValue: true
|
|
310
310
|
});
|
|
311
311
|
} finally {
|
|
@@ -313,7 +313,7 @@ class DesktopCdpTransport {
|
|
|
313
313
|
}
|
|
314
314
|
} else {
|
|
315
315
|
log("[cdp-transport] No CDP targets for removal IPC \u2014 removing directly from obsidian.json.");
|
|
316
|
-
|
|
316
|
+
didRemoveVaultFromConfig(vaultPath);
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
319
|
/**
|
|
@@ -329,7 +329,7 @@ class DesktopCdpTransport {
|
|
|
329
329
|
if (appVersion === void 0) {
|
|
330
330
|
return;
|
|
331
331
|
}
|
|
332
|
-
const verdict =
|
|
332
|
+
const verdict = resolveElectronCompatibility({
|
|
333
333
|
actualElectronVersion,
|
|
334
334
|
appVersion,
|
|
335
335
|
metadata: getVersionMetadata(appVersion)
|
|
@@ -352,7 +352,7 @@ class DesktopCdpTransport {
|
|
|
352
352
|
*/
|
|
353
353
|
async armParentLivenessWatchdog(vaultPath, parentLivenessPort) {
|
|
354
354
|
try {
|
|
355
|
-
const result = await this.evaluate(
|
|
355
|
+
const result = await this.evaluate(buildParentLivenessWatchdogExpression(parentLivenessPort), { cwd: vaultPath });
|
|
356
356
|
log(`[cdp-transport] Parent-liveness watchdog on port ${String(parentLivenessPort)}: ${result}.`);
|
|
357
357
|
} catch (error) {
|
|
358
358
|
log(`[cdp-transport] Could not arm the parent-liveness watchdog (instance may outlive a killed harness): ${String(error)}`);
|
|
@@ -370,7 +370,7 @@ class DesktopCdpTransport {
|
|
|
370
370
|
* @param runningApiVersion - The live running app version, or `undefined` when unreadable.
|
|
371
371
|
*/
|
|
372
372
|
checkRuntimeAsarFallback(runningApiVersion) {
|
|
373
|
-
const verdict =
|
|
373
|
+
const verdict = resolveAsarFallback({
|
|
374
374
|
requestedVersion: this.ownedConfig?.asar?.version,
|
|
375
375
|
runningApiVersion
|
|
376
376
|
});
|
|
@@ -430,12 +430,12 @@ class DesktopCdpTransport {
|
|
|
430
430
|
async connectToTarget(target) {
|
|
431
431
|
const ws = new WebSocket(target.webSocketDebuggerUrl);
|
|
432
432
|
await new Promise((resolve, reject) => {
|
|
433
|
-
ws.
|
|
433
|
+
ws.addEventListener("open", () => {
|
|
434
434
|
resolve();
|
|
435
|
-
};
|
|
436
|
-
ws.
|
|
435
|
+
});
|
|
436
|
+
ws.addEventListener("error", () => {
|
|
437
437
|
reject(new Error(`Failed to connect to CDP target: ${target.webSocketDebuggerUrl}`));
|
|
438
|
-
};
|
|
438
|
+
});
|
|
439
439
|
});
|
|
440
440
|
return ws;
|
|
441
441
|
}
|
|
@@ -536,7 +536,7 @@ class DesktopCdpTransport {
|
|
|
536
536
|
* Finds the CDP target that has the given vault open.
|
|
537
537
|
*
|
|
538
538
|
* Probes every target by evaluating `getBasePath()` and returns the one whose
|
|
539
|
-
* base path matches `vaultPath` (via {@link
|
|
539
|
+
* base path matches `vaultPath` (via {@link areVaultPathsMatching}, tolerant of
|
|
540
540
|
* separator/case differences). A single target is **not** returned blindly: with
|
|
541
541
|
* more than one vault open (attach mode's shared instance), the sole-target
|
|
542
542
|
* shortcut would return whichever window happens to be open regardless of which
|
|
@@ -556,7 +556,7 @@ class DesktopCdpTransport {
|
|
|
556
556
|
for (const target of targets) {
|
|
557
557
|
try {
|
|
558
558
|
const basePath = await this.probeVaultPath(target);
|
|
559
|
-
if (
|
|
559
|
+
if (areVaultPathsMatching(basePath, vaultPath)) {
|
|
560
560
|
return target;
|
|
561
561
|
}
|
|
562
562
|
} catch {
|
|
@@ -579,7 +579,7 @@ class DesktopCdpTransport {
|
|
|
579
579
|
* so the next launch gets a pristine single-window instance.
|
|
580
580
|
*
|
|
581
581
|
* Relaunching over a live instance is forwarded by Electron's single-instance
|
|
582
|
-
* lock on the shared user-data
|
|
582
|
+
* lock on the shared user-data directory and surfaces the vault picker, and opening a
|
|
583
583
|
* second window via IPC leaves stale windows that break vault-target routing —
|
|
584
584
|
* hence a full kill + wait-for-exit (releasing the lock) between launches. A
|
|
585
585
|
* no-op on the first attempt, when no instance is running yet.
|
|
@@ -609,7 +609,7 @@ class DesktopCdpTransport {
|
|
|
609
609
|
* proceeds (worst case the window is briefly visible).
|
|
610
610
|
*/
|
|
611
611
|
async moveOwnedWindowOffscreen() {
|
|
612
|
-
const
|
|
612
|
+
const moveExpression = `(() => {
|
|
613
613
|
let remote = (window.electron && window.electron.remote) || null;
|
|
614
614
|
if (!remote) {
|
|
615
615
|
try { remote = require('electron').remote || null; } catch (requireError) { remote = null; }
|
|
@@ -626,12 +626,12 @@ class DesktopCdpTransport {
|
|
|
626
626
|
const deadline = Date.now() + OWNED_WINDOW_HIDE_TIMEOUT_IN_MILLISECONDS;
|
|
627
627
|
while (Date.now() < deadline) {
|
|
628
628
|
try {
|
|
629
|
-
const target =
|
|
629
|
+
const [target] = await this.getPageTargets();
|
|
630
630
|
if (target) {
|
|
631
631
|
const ws = await this.connectToTarget(target);
|
|
632
632
|
try {
|
|
633
633
|
const response = await this.sendCommand(ws, "Runtime.evaluate", {
|
|
634
|
-
expression:
|
|
634
|
+
expression: moveExpression,
|
|
635
635
|
returnByValue: true
|
|
636
636
|
});
|
|
637
637
|
if (response.result?.result?.value === "moved") {
|
|
@@ -671,10 +671,10 @@ class DesktopCdpTransport {
|
|
|
671
671
|
const ipcWs = await this.connectToTarget(existingTarget);
|
|
672
672
|
try {
|
|
673
673
|
await ensureNamespaceBootstrapped(this, existingVaultPath);
|
|
674
|
-
const
|
|
674
|
+
const ipcExpression = `window.__obsidianIntegrationTesting.ipcSendSync(${JSON.stringify({ channel: "vault-open", channelArguments: [vaultPath, false] })})`;
|
|
675
675
|
await this.sendCommand(ipcWs, "Runtime.evaluate", {
|
|
676
676
|
awaitPromise: true,
|
|
677
|
-
expression:
|
|
677
|
+
expression: ipcExpression,
|
|
678
678
|
returnByValue: true
|
|
679
679
|
});
|
|
680
680
|
await this.enablePluginsInLocalStorage(ipcWs, vaultPath);
|
|
@@ -708,19 +708,19 @@ class DesktopCdpTransport {
|
|
|
708
708
|
*/
|
|
709
709
|
async probeRendererBootState() {
|
|
710
710
|
try {
|
|
711
|
-
const target =
|
|
711
|
+
const [target] = await this.getPageTargets();
|
|
712
712
|
if (!target) {
|
|
713
713
|
return void 0;
|
|
714
714
|
}
|
|
715
715
|
const ws = await this.connectToTarget(target);
|
|
716
716
|
try {
|
|
717
|
-
const
|
|
717
|
+
const probeExpression = `JSON.stringify({
|
|
718
718
|
bodyChildElementCount: document.body ? document.body.childElementCount : 0,
|
|
719
719
|
hasWindowApp: typeof window.app !== 'undefined',
|
|
720
720
|
isDocumentComplete: document.readyState === 'complete'
|
|
721
721
|
})`;
|
|
722
722
|
const response = await this.sendCommand(ws, "Runtime.evaluate", {
|
|
723
|
-
expression:
|
|
723
|
+
expression: probeExpression,
|
|
724
724
|
returnByValue: true
|
|
725
725
|
});
|
|
726
726
|
const value = response.result?.result?.value;
|
|
@@ -768,13 +768,13 @@ class DesktopCdpTransport {
|
|
|
768
768
|
*/
|
|
769
769
|
async registerVaultInOwnedInstance(vaultPath) {
|
|
770
770
|
const config = ensureNonNullable(this.ownedConfig);
|
|
771
|
-
mkdirSync(config.
|
|
771
|
+
mkdirSync(config.userDataDirectory, { recursive: true });
|
|
772
772
|
if (config.asar) {
|
|
773
|
-
copyAsarIntoUserData(config.asar.path, config.asar.version, config.
|
|
773
|
+
copyAsarIntoUserData(config.asar.path, config.asar.version, config.userDataDirectory);
|
|
774
774
|
}
|
|
775
775
|
const vaultId = randomBytes(VAULT_ID_BYTE_LENGTH).toString("hex");
|
|
776
776
|
const obsidianJson = buildOwnedObsidianJson({ ts: Date.now(), vaultId, vaultPath });
|
|
777
|
-
writeFileSync(join(config.
|
|
777
|
+
writeFileSync(join(config.userDataDirectory, "obsidian.json"), JSON.stringify(obsidianJson));
|
|
778
778
|
let lastError;
|
|
779
779
|
for (let attempt = 1; attempt <= OWNED_LAUNCH_MAX_ATTEMPTS; attempt++) {
|
|
780
780
|
await this.killRunningOwnedInstance();
|
|
@@ -784,11 +784,11 @@ class DesktopCdpTransport {
|
|
|
784
784
|
const instance = await launchOwnedObsidianInstance({
|
|
785
785
|
cdpHost: this.cdpHost,
|
|
786
786
|
exePath: config.exePath,
|
|
787
|
-
|
|
788
|
-
...
|
|
789
|
-
...
|
|
787
|
+
extraArguments: [
|
|
788
|
+
...resolveOwnedHiddenLaunchArguments(this.isObsidianAppVisible),
|
|
789
|
+
...resolveSandboxLaunchArguments(this.shouldDisableSandbox)
|
|
790
790
|
],
|
|
791
|
-
|
|
791
|
+
userDataDirectory: config.userDataDirectory
|
|
792
792
|
});
|
|
793
793
|
this.ownedInstance = instance;
|
|
794
794
|
this.cdpPort = instance.port;
|
|
@@ -826,11 +826,11 @@ class DesktopCdpTransport {
|
|
|
826
826
|
reject(new Error(`CDP command timed out after ${String(this.commandTimeoutInMilliseconds)}ms: ${method}`));
|
|
827
827
|
}, this.commandTimeoutInMilliseconds);
|
|
828
828
|
function handler(event) {
|
|
829
|
-
const
|
|
830
|
-
if (
|
|
829
|
+
const message = JSON.parse(String(event.data));
|
|
830
|
+
if (message.id === id) {
|
|
831
831
|
clearTimeout(timeout);
|
|
832
832
|
ws.removeEventListener("message", handler);
|
|
833
|
-
resolve(
|
|
833
|
+
resolve(message);
|
|
834
834
|
}
|
|
835
835
|
}
|
|
836
836
|
ws.addEventListener("message", handler);
|
|
@@ -840,7 +840,7 @@ class DesktopCdpTransport {
|
|
|
840
840
|
/**
|
|
841
841
|
* Polls a killed owned instance's CDP endpoint until it stops responding,
|
|
842
842
|
* confirming the process has exited and released Electron's single-instance
|
|
843
|
-
* lock on the shared user-data
|
|
843
|
+
* lock on the shared user-data directory before a fresh instance is launched into it.
|
|
844
844
|
*
|
|
845
845
|
* @param cdpUrl - The CDP URL of the instance that was just killed.
|
|
846
846
|
*/
|
|
@@ -912,7 +912,7 @@ class DesktopCdpTransport {
|
|
|
912
912
|
documentCompleteSince = Date.now();
|
|
913
913
|
}
|
|
914
914
|
const hasGraceElapsed = documentCompleteSince !== null && Date.now() - documentCompleteSince >= this.deadBootGraceInMilliseconds;
|
|
915
|
-
if (
|
|
915
|
+
if (resolveRendererBootState({ ...observation, hasGraceElapsed }) === "dead") {
|
|
916
916
|
log("[cdp-transport] Owned renderer failed to initialize (dead boot); failing fast.");
|
|
917
917
|
throw new RendererFailedToInitializeError(vaultPath);
|
|
918
918
|
}
|
|
@@ -932,6 +932,14 @@ function delay(ms) {
|
|
|
932
932
|
setTimeout(resolve, ms);
|
|
933
933
|
});
|
|
934
934
|
}
|
|
935
|
+
function didRemoveDirectory(directory) {
|
|
936
|
+
try {
|
|
937
|
+
rmSync(directory, { force: true, recursive: true });
|
|
938
|
+
return true;
|
|
939
|
+
} catch {
|
|
940
|
+
return false;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
935
943
|
async function getObsidianLaunchCommand(port) {
|
|
936
944
|
const exePath = await resolveObsidianExecutable();
|
|
937
945
|
const flag = `--remote-debugging-port=${String(port)}`;
|
|
@@ -940,15 +948,7 @@ async function getObsidianLaunchCommand(port) {
|
|
|
940
948
|
}
|
|
941
949
|
return `"${exePath}" ${flag} &`;
|
|
942
950
|
}
|
|
943
|
-
function tryRemoveDir(dir) {
|
|
944
|
-
try {
|
|
945
|
-
rmSync(dir, { force: true, recursive: true });
|
|
946
|
-
return true;
|
|
947
|
-
} catch {
|
|
948
|
-
return false;
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
951
|
export {
|
|
952
952
|
DesktopCdpTransport
|
|
953
953
|
};
|
|
954
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1kZXNrdG9wLWNkcC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIERlc2t0b3AgQ0RQIHRyYW5zcG9ydCBcdTIwMTQgZXZhbHVhdGVzIGV4cHJlc3Npb25zIHZpYSBDaHJvbWUgRGV2VG9vbHMgUHJvdG9jb2xcbiAqIG92ZXIgV2ViU29ja2V0IGFuZCBtYW5hZ2VzIHZhdWx0cyB2aWEgRWxlY3Ryb24gSVBDLlxuICpcbiAqIFR3byBtb2RlczpcbiAqIC0gKipPd25lZCAoZGVmYXVsdCkqKjogdGhlIHRyYW5zcG9ydCBsYXVuY2hlcyBhbmQgb3ducyBhbiBpc29sYXRlZCBPYnNpZGlhblxuICogICBpbnN0YW5jZSBhZ2FpbnN0IGEgdGVtcG9yYXJ5IGAtLXVzZXItZGF0YS1kaXJgIG9uIGEgZnJlZSBgLS1yZW1vdGUtZGVidWdnaW5nLXBvcnRgLFxuICogICBuZXZlciB0b3VjaGluZyB0aGUgdXNlcidzIE9ic2lkaWFuLiBTdXBwb3J0cyB2ZXJzaW9uIHBpbm5pbmcgdmlhIHRoZSB1c2VyLWRhdGEgYXNhci5cbiAqIC0gKipBdHRhY2gqKjogd2hlbiBhbiBleHBsaWNpdCBDRFAgcG9ydCBpcyBjb25maWd1cmVkLCB0aGUgdHJhbnNwb3J0IGNvbm5lY3RzXG4gKiAgIHRvIGFuIGFscmVhZHktcnVubmluZyBPYnNpZGlhbiBvbiB0aGF0IHBvcnQuXG4gKlxuICogSXQgY29ubmVjdHMgdG8gcGFnZSB0YXJnZXRzLCBzZW5kcyBgUnVudGltZS5ldmFsdWF0ZWAgY29tbWFuZHMsIGFuZCByb3V0ZXMgdG9cbiAqIHRoZSBjb3JyZWN0IHZhdWx0IHRhcmdldCB1c2luZyBgZ2V0QmFzZVBhdGgoKWAgcHJvYmluZy5cbiAqXG4gKiBSZXF1aXJlbWVudHM6IE5vZGUuanMgMjIrICh1c2VzIGJ1aWx0LWluIGBXZWJTb2NrZXRgIGFuZCBgZmV0Y2hgIGdsb2JhbHMpLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGNvZGUgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtcbiAgbWtkaXJTeW5jLFxuICBybVN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbmltcG9ydCB0eXBlIHsgQXNhckZhbGxiYWNrIH0gZnJvbSAnLi9hc2FyLWZhbGxiYWNrLWRldGVjdGlvbi5tanMnO1xuaW1wb3J0IHR5cGUgeyBFbGVjdHJvbkNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2VsZWN0cm9uLWNvbXBhdGliaWxpdHkubWpzJztcbmltcG9ydCB0eXBlIHsgSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSB9IGZyb20gJy4vaW5zdGFsbGVyLWNvbXBhdGliaWxpdHkubWpzJztcbmltcG9ydCB0eXBlIHsgT3duZWRPYnNpZGlhbkluc3RhbmNlIH0gZnJvbSAnLi9vYnNpZGlhbi1pbnN0YW5jZS5tanMnO1xuaW1wb3J0IHR5cGUgeyBSZW5kZXJlckJvb3RPYnNlcnZhdGlvbiB9IGZyb20gJy4vcmVuZGVyZXItYm9vdC1kZXRlY3Rpb24ubWpzJztcbmltcG9ydCB0eXBlIHtcbiAgT2JzaWRpYW5UcmFuc3BvcnQsXG4gIFRyYW5zcG9ydEV2YWxPcHRpb25zXG59IGZyb20gJy4vdHJhbnNwb3J0Lm1qcyc7XG5cbmltcG9ydCB7IGNoZWNrQXNhckZhbGxiYWNrIH0gZnJvbSAnLi9hc2FyLWZhbGxiYWNrLWRldGVjdGlvbi5tanMnO1xuaW1wb3J0IHsgcmVzb2x2ZUFzYXJGYWxsYmFja0FjdGlvbiB9IGZyb20gJy4vY29tcGF0aWJpbGl0eS1vcHRpb25zLm1qcyc7XG5pbXBvcnQgeyBESVNNSVNTX1RSVVNUX0RJQUxPR19FWFBSIH0gZnJvbSAnLi9kaXNtaXNzLXRydXN0LWRpYWxvZy5tanMnO1xuaW1wb3J0IHsgY2hlY2tFbGVjdHJvbkNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2VsZWN0cm9uLWNvbXBhdGliaWxpdHkubWpzJztcbmltcG9ydCB7IGV4ZWMgfSBmcm9tICcuL2V4ZWMubWpzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLm1qcyc7XG5pbXBvcnQgeyBlbnN1cmVOYW1lc3BhY2VCb290c3RyYXBwZWQgfSBmcm9tICcuL25hbWVzcGFjZS1ib290c3RyYXAubWpzJztcbmltcG9ydCB7XG4gIGdldFZhdWx0SWQsXG4gIGlzVmF1bHRSZWdpc3RlcmVkLFxuICByZW1vdmVWYXVsdEZyb21Db25maWdcbn0gZnJvbSAnLi9vYnNpZGlhbi1jb25maWcubWpzJztcbmltcG9ydCB7IHJlc29sdmVPYnNpZGlhbkV4ZWN1dGFibGUgfSBmcm9tICcuL29ic2lkaWFuLWV4ZWN1dGFibGUubWpzJztcbmltcG9ydCB7IGxhdW5jaE93bmVkT2JzaWRpYW5JbnN0YW5jZSB9IGZyb20gJy4vb2JzaWRpYW4taW5zdGFuY2UubWpzJztcbmltcG9ydCB7IGdldFZlcnNpb25NZXRhZGF0YSB9IGZyb20gJy4vb2JzaWRpYW4tbWV0YWRhdGEubWpzJztcbmltcG9ydCB7IGNvcHlBc2FySW50b1VzZXJEYXRhIH0gZnJvbSAnLi9vYnNpZGlhbi12ZXJzaW9uLXN3aXRjaC5tanMnO1xuaW1wb3J0IHsgYnVpbGRPd25lZE9ic2lkaWFuSnNvbiB9IGZyb20gJy4vb3duZWQtdmF1bHQtc2VlZC5tanMnO1xuaW1wb3J0IHsgYnVpbGRQYXJlbnRMaXZlbmVzc1dhdGNoZG9nRXhwciB9IGZyb20gJy4vcGFyZW50LWxpdmVuZXNzLm1qcyc7XG5pbXBvcnQge1xuICBjaGVja1JlbmRlcmVyQm9vdFN0YXRlLFxuICBERUZBVUxUX0RFQURfQk9PVF9HUkFDRV9JTl9NSUxMSVNFQ09ORFNcbn0gZnJvbSAnLi9yZW5kZXJlci1ib290LWRldGVjdGlvbi5tanMnO1xuaW1wb3J0IHsgUmVuZGVyZXJGYWlsZWRUb0luaXRpYWxpemVFcnJvciB9IGZyb20gJy4vcmVuZGVyZXItZmFpbGVkLXRvLWluaXRpYWxpemUtZXJyb3IubWpzJztcbmltcG9ydCB7IFNpbGVudEFzYXJGYWxsYmFja0Vycm9yIH0gZnJvbSAnLi9zaWxlbnQtYXNhci1mYWxsYmFjay1lcnJvci5tanMnO1xuaW1wb3J0IHsgZW5zdXJlTm9uTnVsbGFibGUgfSBmcm9tICcuL3R5cGUtZ3VhcmRzLm1qcyc7XG5pbXBvcnQgeyB2YXVsdFBhdGhzTWF0Y2ggfSBmcm9tICcuL3ZhdWx0LXBhdGgtbWF0Y2gubWpzJztcbmltcG9ydCB7XG4gIHJlc29sdmVPd25lZEhpZGRlbkxhdW5jaEFyZ3MsXG4gIHJlc29sdmVTYW5kYm94TGF1bmNoQXJncyxcbiAgc2hvdWxkSGlkZU9ic2lkaWFuQXBwXG59IGZyb20gJy4vdmlzaWJpbGl0eS5tanMnO1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBDRFAgdHJhbnNwb3J0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERlc2t0b3BDZHBUcmFuc3BvcnRDb25maWcge1xuICAvKipcbiAgICogQ0RQIGhvc3QuIERlZmF1bHRzIHRvIGAnbG9jYWxob3N0J2AuXG4gICAqL1xuICBjZHBIb3N0Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDRFAgcG9ydCBmb3IgKiphdHRhY2gqKiBtb2RlICh0aGUgYC0tcmVtb3RlLWRlYnVnZ2luZy1wb3J0YCB0aGUgcnVubmluZ1xuICAgKiBPYnNpZGlhbiB3YXMgbGF1bmNoZWQgd2l0aCkuIEluIG93bmVkLWluc3RhbmNlIG1vZGUgdGhpcyBpcyBpZ25vcmVkIFx1MjAxNCBhXG4gICAqIGZyZWUgcG9ydCBpcyBjaG9zZW4gYXQgbGF1bmNoLlxuICAgKi9cbiAgY2RwUG9ydD86IG51bWJlcjtcblxuICAvKipcbiAgICogVGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIGluZGl2aWR1YWwgQ0RQIGNvbW1hbmRzLlxuICAgKiBEZWZhdWx0cyB0byBgMzAwMDBgLlxuICAgKi9cbiAgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogR3JhY2Ugd2luZG93IGluIG1pbGxpc2Vjb25kcyBmb3IgZmFzdC1mYWlsaW5nIGEgZGVhZCBib290IG9mIHRoZSBvd25lZFxuICAgKiBpbnN0YW5jZSAoZW1wdHkgYDxib2R5PmAgd2l0aCBubyBgd2luZG93LmFwcGAgYWZ0ZXIgdGhlIHJlbmRlcmVyIHJlYWNoZWRcbiAgICogYGRvY3VtZW50LnJlYWR5U3RhdGVgIGAnY29tcGxldGUnYCkuIERlZmF1bHRzIHRvXG4gICAqIHtAbGluayBERUZBVUxUX0RFQURfQk9PVF9HUkFDRV9JTl9NSUxMSVNFQ09ORFN9LiBgMGAgZGlzYWJsZXMgZmFzdC1mYWlsLlxuICAgKi9cbiAgZGVhZEJvb3RHcmFjZUluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGVuIGF0dGFjaGluZyAoaS5lLiB7QGxpbmsgY2RwUG9ydH0gaXMgc2V0KSwgbWFya3MgdGhlIHRhcmdldCBhcyBhXG4gICAqICoqaGFybmVzcy1vd25lZCwgYWxyZWFkeS1wcmVwYXJlZCoqIGluc3RhbmNlLiBTdXBwcmVzc2VzIHRoZSB1c2VyLXNjb3BlXG4gICAqIHZhdWx0LXJlZ2lzdHJhdGlvbiBwcmVmbGlnaHQsIHNpbmNlIHRoZSBvd25lZCBpbnN0YW5jZSdzIHZhdWx0IGxpdmVzIGluIGFuXG4gICAqIGlzb2xhdGVkIHVzZXItZGF0YSBjb25maWcgcmF0aGVyIHRoYW4gdGhlIHVzZXItc2NvcGUgcmVnaXN0cnkuXG4gICAqL1xuICBpc0hhcm5lc3NPd25lZEluc3RhbmNlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgb3duZWQgT2JzaWRpYW4gd2luZG93IGlzIHNob3duIG9uIHNjcmVlbi4gV2hlbiBgZmFsc2VgICh0aGVcbiAgICogZGVmYXVsdCksIHRoZSBvd25lZCBpbnN0YW5jZSBpcyBsYXVuY2hlZCB3aXRoIGtlZXAtYWxpdmUgQ2hyb21pdW0gZmxhZ3MgYW5kXG4gICAqIGl0cyB3aW5kb3cgaXMgbW92ZWQgb2ZmLXNjcmVlbiBhZnRlciBsYXVuY2guIE9ubHkgbWVhbmluZ2Z1bCBpbiBvd25lZCBtb2RlO1xuICAgKiBhdHRhY2ggbW9kZSBuZXZlciB0b3VjaGVzIHRoZSAodXNlcidzKSB3aW5kb3cuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgaXNPYnNpZGlhbkFwcFZpc2libGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGVuIHNldCwgdGhlIHRyYW5zcG9ydCBsYXVuY2hlcyBhbmQgb3ducyBhbiBpc29sYXRlZCBPYnNpZGlhbiBpbnN0YW5jZVxuICAgKiBpbnN0ZWFkIG9mIGF0dGFjaGluZyB0byBhIHJ1bm5pbmcgb25lLiBUaGlzIGlzIHRoZSBkZWZhdWx0IGRlc2t0b3AgbW9kZS5cbiAgICovXG4gIG93bmVkSW5zdGFuY2U/OiBPd25lZEluc3RhbmNlQ29uZmlnO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGxhdW5jaCB0aGUgb3duZWQgaW5zdGFuY2Ugd2l0aCBDaHJvbWl1bSdzIHNhbmRib3ggZGlzYWJsZWRcbiAgICogKGAtLW5vLXNhbmRib3hgKS4gTmVlZGVkIHRvIGJvb3Qgb24gTGludXggd2l0aG91dCBhIGNvcnJlY3RseS1jb25maWd1cmVkXG4gICAqIHNldHVpZCBgY2hyb21lLXNhbmRib3hgIGhlbHBlciAoZS5nLiBhbiBleHRyYWN0ZWQgcG9ydGFibGUgc2hlbGwsIG9yIENJIGFzIGFcbiAgICogbm9uLXJvb3QgdXNlcik7IGhhcm1sZXNzIG9uIFdpbmRvd3MvbWFjT1MuIE9ubHkgbWVhbmluZ2Z1bCBpbiBvd25lZCBtb2RlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZmFsc2VgXG4gICAqL1xuICBzaG91bGREaXNhYmxlU2FuZGJveD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgYSBwb3N0LWJvb3QgKipzaWxlbnQgYXNhciBmYWxsYmFjayoqICh0aGUgcnVubmluZyBhcHAgdmVyc2lvbiBkaWZmZXJzXG4gICAqIGZyb20gdGhlIHN3YXBwZWQtaW4gcGluKSBmYWlscyBmYXN0IHdpdGgge0BsaW5rIFNpbGVudEFzYXJGYWxsYmFja0Vycm9yfS4gVGhlXG4gICAqIHZlcmRpY3QgaXMgYWx3YXlzIGNvbXB1dGVkIGFuZCBzdXJmYWNlZCB2aWFcbiAgICoge0BsaW5rIERlc2t0b3BDZHBUcmFuc3BvcnQuZ2V0QXNhckZhbGxiYWNrfTsgdGhpcyBnYXRlcyBvbmx5IHRoZSB0aHJvdy4gT25seVxuICAgKiBtZWFuaW5nZnVsIGluIG93bmVkIG1vZGUgcnVubmluZyBhIHN3YXBwZWQtaW4gYXNhci5cbiAgICpcbiAgICogQGRlZmF1bHQgYHRydWVgXG4gICAqL1xuICBzaG91bGRUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgcG9zdC1ib290IHJ1bnRpbWUtRWxlY3Ryb24gY29tcGF0aWJpbGl0eSBuYWcgd2FybmluZyBpcyBlbWl0dGVkXG4gICAqIHdoZW4gdGhlIGxpdmUgRWxlY3Ryb24gaXMgYmVsb3cgdGhlIGFwcCdzIHJlY29tbWVuZGVkIG1pbmltdW0uIFRoZSB2ZXJkaWN0IGlzXG4gICAqIGFsd2F5cyBjb21wdXRlZCBhbmQgc3VyZmFjZWQgdmlhIHtAbGluayBEZXNrdG9wQ2RwVHJhbnNwb3J0LmdldEVsZWN0cm9uQ29tcGF0aWJpbGl0eX07XG4gICAqIHRoaXMgb25seSBnYXRlcyB0aGUgbG9nLiBPbmx5IG1lYW5pbmdmdWwgaW4gb3duZWQgbW9kZS5cbiAgICpcbiAgICogQGRlZmF1bHQgYHRydWVgXG4gICAqL1xuICBzaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBbiBhc2FyIHRvIHByb3Zpc2lvbiBpbnRvIGEgaGFybmVzcy1vd25lZCBpbnN0YW5jZSdzIHVzZXItZGF0YSBkaXIgYmVmb3JlIGxhdW5jaC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPd25lZEluc3RhbmNlQXNhciB7XG4gIC8qKiBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBjYWNoZWQvc291cmNlIGFzYXIgZmlsZS4gKi9cbiAgcmVhZG9ubHkgcGF0aDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgYXNhcidzIGB4LnkuemAgdmVyc2lvbi4gKi9cbiAgcmVhZG9ubHkgdmVyc2lvbjogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIGEgaGFybmVzcy1vd25lZCwgaXNvbGF0ZWQgT2JzaWRpYW4gaW5zdGFuY2UuXG4gKlxuICogV2hlbiBwcmVzZW50LCB0aGUgdHJhbnNwb3J0IGxhdW5jaGVzIGFuZCBvd25zIGl0cyBvd24gT2JzaWRpYW4gcHJvY2Vzc1xuICogYWdhaW5zdCBhbiBpc29sYXRlZCB1c2VyLWRhdGEgZGlyIGluc3RlYWQgb2YgYXR0YWNoaW5nIHRvIGEgcnVubmluZyBpbnN0YW5jZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPd25lZEluc3RhbmNlQ29uZmlnIHtcbiAgLyoqIE9wdGlvbmFsIGFzYXIgdG8gcHJvdmlzaW9uIGludG8ge0BsaW5rIHVzZXJEYXRhRGlyfSBiZWZvcmUgbGF1bmNoLiAqL1xuICByZWFkb25seSBhc2FyPzogT3duZWRJbnN0YW5jZUFzYXIgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSByZXNvbHZlZCBpbnN0YWxsZXJcdTIxOTRhcHAgY29tcGF0aWJpbGl0eSB2ZXJkaWN0LCB3aGVuIGl0IGNvdWxkIGJlIGRldGVybWluZWRcbiAgICogKGFuIGFzYXItc3dhcCBvbnRvIGEga25vd24gc2hlbGwgdmVyc2lvbikuIFN1cmZhY2VkIGJ5XG4gICAqIHtAbGluayBEZXNrdG9wQ2RwVHJhbnNwb3J0LmdldENvbXBhdGliaWxpdHl9LiBBbiBgJ3VucnVubmFibGUnYCB2ZXJkaWN0IHJlYWNoZXNcbiAgICogdGhpcyBzdXJmYWNlIG9ubHkgd2hlbiB0aGUgcHJvYWN0aXZlIHRocm93IGlzIGRpc2FibGVkXG4gICAqIChgc2hvdWxkVGhyb3dPbkluY29tcGF0aWJsZUluc3RhbGxlcjogZmFsc2VgKTsgb3RoZXJ3aXNlIGl0IHRocm93c1xuICAgKiBgSW5jb21wYXRpYmxlSW5zdGFsbGVyVmVyc2lvbkVycm9yYCBiZWZvcmUgdGhlIGNvbmZpZyBpcyBidWlsdC5cbiAgICovXG4gIHJlYWRvbmx5IGNvbXBhdGliaWxpdHk/OiBJbnN0YWxsZXJDb21wYXRpYmlsaXR5IHwgdW5kZWZpbmVkO1xuXG4gIC8qKiBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBPYnNpZGlhbiBzaGVsbCBleGVjdXRhYmxlIHRvIGxhdW5jaC4gKi9cbiAgcmVhZG9ubHkgZXhlUGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBpc29sYXRlZCB1c2VyLWRhdGEgZGlyLiBDcmVhdGVkIGFuZCBvd25lZCBieSB0aGVcbiAgICogdHJhbnNwb3J0LCBhbmQgZGVsZXRlZCBvbiBkaXNwb3NlLlxuICAgKi9cbiAgcmVhZG9ubHkgdXNlckRhdGFEaXI6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIENkcEV4Y2VwdGlvbkRldGFpbHMge1xuICBleGNlcHRpb24/OiBDZHBFeGNlcHRpb25PYmplY3Q7XG4gIHRleHQ6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIENkcEV4Y2VwdGlvbk9iamVjdCB7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgQ2RwUmVzcG9uc2Uge1xuICBpZDogbnVtYmVyO1xuICByZXN1bHQ/OiBDZHBSZXNwb25zZVJlc3VsdDtcbn1cblxuaW50ZXJmYWNlIENkcFJlc3BvbnNlUmVzdWx0IHtcbiAgcmVhZG9ubHkgZXhjZXB0aW9uRGV0YWlscz86IENkcEV4Y2VwdGlvbkRldGFpbHM7XG4gIHJlYWRvbmx5IHJlc3VsdD86IENkcFZhbHVlO1xufVxuXG5pbnRlcmZhY2UgQ2RwVGFyZ2V0IHtcbiAgaWQ6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICB1cmw6IHN0cmluZztcbiAgd2ViU29ja2V0RGVidWdnZXJVcmw6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIENkcFZhbHVlIHtcbiAgdHlwZTogc3RyaW5nO1xuICB2YWx1ZT86IHVua25vd247XG59XG5cbi8qKlxuICogVGhlIENEUCBlbmRwb2ludCBvZiBhIGxhdW5jaGVkLCBoYXJuZXNzLW93bmVkIGluc3RhbmNlLlxuICovXG5pbnRlcmZhY2UgT3duZWRJbnN0YW5jZUVuZHBvaW50IHtcbiAgLyoqIENEUCBob3N0IChlLmcuIGAnbG9jYWxob3N0J2ApLiAqL1xuICByZWFkb25seSBob3N0OiBzdHJpbmc7XG5cbiAgLyoqIFRoZSBmcmVlIENEUCBwb3J0IHRoZSBvd25lZCBpbnN0YW5jZSB3YXMgbGF1bmNoZWQgb24uICovXG4gIHJlYWRvbmx5IHBvcnQ6IG51bWJlcjtcbn1cblxuY29uc3QgQ09NTUFORF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDMwMDAwO1xuY29uc3QgVkFVTFRfSURfQllURV9MRU5HVEggPSA4O1xuY29uc3QgVVNFUl9EQVRBX1JNX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTAwMDA7XG5jb25zdCBVU0VSX0RBVEFfUk1fUkVUUllfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgTk9fT1VUUFVUID0gJyhubyBvdXRwdXQpJztcbmNvbnN0IFZBVUxUX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgVkFVTFRfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDMwMDAwO1xuLy8gT2xkIChFbGVjdHJvbiAxMC1lcmEpIE9ic2lkaWFuIG9jY2FzaW9uYWxseSBib290cyB3aXRob3V0IHRoZSB3b3Jrc3BhY2UgZXZlclxuLy8gSW5pdGlhbGl6aW5nLCBzbyB0aGUgdmF1bHQgbmV2ZXIgYmVjb21lcyByZWFkeS4gQSBmcmVzaCBpbnN0YW5jZSBpcyBhblxuLy8gSW5kZXBlbmRlbnQgY2hhbmNlOyByZWxhdW5jaCB1cCB0byB0aGlzIG1hbnkgdGltZXMgYmVmb3JlIGdpdmluZyB1cC5cbmNvbnN0IE9XTkVEX0xBVU5DSF9NQVhfQVRURU1QVFMgPSAzO1xuLy8gQnJpZWYgc2V0dGxlIGJlZm9yZSBhIHJlbGF1bmNoIHNvIHRoZSBraWxsZWQgaW5zdGFuY2UncyBtZW1vcnkvaGFuZGxlcyBhcmVcbi8vIFJlY2xhaW1lZCBiZWZvcmUgdGhlIG5leHQgYm9vdCBcdTIwMTQgaW1wcm92ZXMgdGhlIG9kZHMgb24gYSBsb2FkZWQgbWFjaGluZS5cbmNvbnN0IE9XTkVEX1JFTEFVTkNIX1NFVFRMRV9JTl9NSUxMSVNFQ09ORFMgPSAzMDAwO1xuY29uc3QgVkFVTFRfQ0xPU0VfREVMQVlfSU5fTUlMTElTRUNPTkRTID0gMTAwMDtcbmNvbnN0IEFVVE9fU1RBUlRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSAyMDAwO1xuY29uc3QgQVVUT19TVEFSVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDMwMDAwO1xuY29uc3QgSU5TVEFOQ0VfRVhJVF9TRVRUTEVfREVMQVlfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgT1dORURfV0lORE9XX09GRlNDUkVFTl9NQVJHSU5fSU5fUElYRUxTID0gMjAwO1xuY29uc3QgT1dORURfV0lORE9XX0hJREVfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAyMDAwMDtcbmNvbnN0IE9XTkVEX1dJTkRPV19ISURFX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gMjUwO1xuXG4vKipcbiAqIFRyYW5zcG9ydCB0aGF0IGNvbW11bmljYXRlcyB3aXRoIERlc2t0b3AgT2JzaWRpYW4gdmlhIENocm9tZSBEZXZUb29scyBQcm90b2NvbC5cbiAqXG4gKiBDb25uZWN0cyB0byBPYnNpZGlhbidzIENEUCBXZWJTb2NrZXQgZW5kcG9pbnQsIHNlbmRzIGBSdW50aW1lLmV2YWx1YXRlYFxuICogY29tbWFuZHMsIGFuZCByb3V0ZXMgZXhwcmVzc2lvbnMgdG8gdGhlIGNvcnJlY3QgdmF1bHQgdGFyZ2V0LlxuICovXG5leHBvcnQgY2xhc3MgRGVza3RvcENkcFRyYW5zcG9ydCBpbXBsZW1lbnRzIE9ic2lkaWFuVHJhbnNwb3J0IHtcbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgdHJhbnNwb3J0IGlzIGZvciBhIG1vYmlsZSBwbGF0Zm9ybS4gQWx3YXlzIGBmYWxzZWAgZm9yIHRoaXMgdHJhbnNwb3J0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlzTW9iaWxlID0gZmFsc2U7XG4gIHByaXZhdGUgYWN0aXZlVmF1bHRQYXRoOiBudWxsIHwgc3RyaW5nID0gbnVsbDtcbiAgcHJpdmF0ZSBhc2FyRmFsbGJhY2s6IEFzYXJGYWxsYmFjayB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBjZHBIb3N0OiBzdHJpbmc7XG4gIHByaXZhdGUgY2RwUG9ydDogbnVtYmVyO1xuICBwcml2YXRlIGNkcFVybDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbiAgcHJpdmF0ZSBlbGVjdHJvbkNvbXBhdGliaWxpdHk6IEVsZWN0cm9uQ29tcGF0aWJpbGl0eSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBpc0hhcm5lc3NPd25lZEluc3RhbmNlOiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IGlzT2JzaWRpYW5BcHBWaXNpYmxlOiBib29sZWFuO1xuICBwcml2YXRlIG1lc3NhZ2VJZCA9IDA7XG4gIHByaXZhdGUgcmVhZG9ubHkgb3duZWRDb25maWc6IE93bmVkSW5zdGFuY2VDb25maWcgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgb3duZWRJbnN0YW5jZTogT3duZWRPYnNpZGlhbkluc3RhbmNlIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IHNob3VsZERpc2FibGVTYW5kYm94OiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IHNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2s6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlczogYm9vbGVhbjtcbiAgcHJpdmF0ZSB3czogbnVsbCB8IFdlYlNvY2tldCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgQ0RQIHRyYW5zcG9ydC5cbiAgICpcbiAgICogQHBhcmFtIGNvbmZpZyAtIENEUCBjb25uZWN0aW9uIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IoY29uZmlnPzogRGVza3RvcENkcFRyYW5zcG9ydENvbmZpZykge1xuICAgIC8vIERlc3RydWN0dXJlIHdpdGggcGVyLWZpZWxkIGRlZmF1bHRzIChlYWNoIGFwcGxpZXMgd2hlbiB0aGUgZmllbGQgaXMgb21pdHRlZCxcbiAgICAvLyBFeGFjdGx5IGxpa2UgdGhlIGZvcm1lciBgY29uZmlnPy54ID8/IGRlZmF1bHRgKSBzbyB0aGUgY29uc3RydWN0b3Igc3RheXNcbiAgICAvLyBVbmRlciB0aGUgY3ljbG9tYXRpYy1jb21wbGV4aXR5IGxpbWl0IGFzIGZpZWxkcyBhcmUgYWRkZWQuXG4gICAgY29uc3Qge1xuICAgICAgY2RwSG9zdCA9ICdsb2NhbGhvc3QnLFxuICAgICAgY2RwUG9ydCxcbiAgICAgIGNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHMgPSBDT01NQU5EX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTLFxuICAgICAgZGVhZEJvb3RHcmFjZUluTWlsbGlzZWNvbmRzID0gREVGQVVMVF9ERUFEX0JPT1RfR1JBQ0VfSU5fTUlMTElTRUNPTkRTLFxuICAgICAgaXNIYXJuZXNzT3duZWRJbnN0YW5jZSA9IGZhbHNlLFxuICAgICAgaXNPYnNpZGlhbkFwcFZpc2libGUgPSB0cnVlLFxuICAgICAgb3duZWRJbnN0YW5jZSxcbiAgICAgIHNob3VsZERpc2FibGVTYW5kYm94ID0gZmFsc2UsXG4gICAgICBzaG91bGRUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrID0gdHJ1ZSxcbiAgICAgIHNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXMgPSB0cnVlXG4gICAgfSA9IGNvbmZpZyA/PyB7fTtcbiAgICB0aGlzLmNkcEhvc3QgPSBjZHBIb3N0O1xuICAgIHRoaXMuY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IGNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHM7XG4gICAgdGhpcy5kZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHMgPSBkZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHM7XG4gICAgdGhpcy5pc0hhcm5lc3NPd25lZEluc3RhbmNlID0gaXNIYXJuZXNzT3duZWRJbnN0YW5jZTtcbiAgICB0aGlzLmlzT2JzaWRpYW5BcHBWaXNpYmxlID0gaXNPYnNpZGlhbkFwcFZpc2libGU7XG4gICAgdGhpcy5vd25lZENvbmZpZyA9IG93bmVkSW5zdGFuY2U7XG4gICAgdGhpcy5zaG91bGREaXNhYmxlU2FuZGJveCA9IHNob3VsZERpc2FibGVTYW5kYm94O1xuICAgIHRoaXMuc2hvdWxkVGhyb3dPblNpbGVudEFzYXJGYWxsYmFjayA9IHNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2s7XG4gICAgdGhpcy5zaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzID0gc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlcztcbiAgICAvLyBPd25lZCBtb2RlIHBpY2tzIGEgZnJlZSBwb3J0IGF0IGxhdW5jaCAoYXNzaWduZWQgaW4gcmVnaXN0ZXJWYXVsdCkuXG4gICAgLy8gQXR0YWNoIG1vZGUgY29ubmVjdHMgdG8gdGhlIGNvbmZpZ3VyZWQgcG9ydDsgbm8gcG9ydCBpcyBoYXJkY29kZWQuXG4gICAgdGhpcy5jZHBQb3J0ID0gY2RwUG9ydCA/PyAwO1xuICAgIHRoaXMuY2RwVXJsID0gY2RwUG9ydCA9PT0gdW5kZWZpbmVkID8gJycgOiBgaHR0cDovLyR7Y2RwSG9zdH06JHtTdHJpbmcoY2RwUG9ydCl9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwb3NlcyBvZiB0aGUgYWN0aXZlIFdlYlNvY2tldCBjb25uZWN0aW9uIGFuZCwgaW4gb3duZWQtaW5zdGFuY2UgbW9kZSxcbiAgICoga2lsbHMgdGhlIG93bmVkIE9ic2lkaWFuIHByb2Nlc3MgYW5kIHJlbW92ZXMgaXRzIGlzb2xhdGVkIHVzZXItZGF0YSBkaXIuXG4gICAqXG4gICAqIFRoZSByZW1vdmFsIGlzIHJldHJpZWQgYmVjYXVzZSBXaW5kb3dzIGJyaWVmbHkgaG9sZHMgdGhlIGp1c3Qta2lsbGVkXG4gICAqIHByb2Nlc3MncyBmaWxlIGhhbmRsZXMsIHdoaWNoIHdvdWxkIG90aGVyd2lzZSBmYWlsIGBybVN5bmNgIHdpdGggYEVQRVJNYC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIGlmICghdGhpcy5vd25lZENvbmZpZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMub3duZWRJbnN0YW5jZT8ua2lsbCgpO1xuICAgIGNvbnN0IHsgdXNlckRhdGFEaXIgfSA9IHRoaXMub3duZWRDb25maWc7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgVVNFUl9EQVRBX1JNX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGlmICh0cnlSZW1vdmVEaXIodXNlckRhdGFEaXIpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGRlbGF5KFVTRVJfREFUQV9STV9SRVRSWV9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cbiAgICBpZiAoIXRyeVJlbW92ZURpcih1c2VyRGF0YURpcikpIHtcbiAgICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIENvdWxkIG5vdCByZW1vdmUgb3duZWQgdXNlci1kYXRhIGRpciB3aXRoaW4gJHtTdHJpbmcoVVNFUl9EQVRBX1JNX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcyAobm9uLWZhdGFsKTogJHt1c2VyRGF0YURpcn1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3luY2hyb25vdXMgZGlzcG9zYWwgXHUyMDE0IGtpbGxzIHRoZSBvd25lZCBpbnN0YW5jZSBhbmQgbWFrZXMgYSBiZXN0LWVmZm9ydFxuICAgKiByZW1vdmFsIG9mIGl0cyB1c2VyLWRhdGEgZGlyLiBTYWZlIHRvIGNhbGwgZnJvbSBhIHByb2Nlc3MgYGV4aXRgIGhhbmRsZXJcbiAgICogKHdoZXJlIGFzeW5jIHJldHJpZXMgYXJlIGltcG9zc2libGU7IGEgbGVmdG92ZXIgdGVtcCBkaXIgaXMgYWNjZXB0YWJsZSkuXG4gICAqL1xuICBwdWJsaWMgZGlzcG9zZVN5bmMoKTogdm9pZCB7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgaWYgKHRoaXMub3duZWRDb25maWcpIHtcbiAgICAgIHRoaXMub3duZWRJbnN0YW5jZT8ua2lsbCgpO1xuICAgICAgaWYgKCF0cnlSZW1vdmVEaXIodGhpcy5vd25lZENvbmZpZy51c2VyRGF0YURpcikpIHtcbiAgICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gT3duZWQgdXNlci1kYXRhIGRpciBub3QgcmVtb3ZlZCBzeW5jaHJvbm91c2x5IChwcm9jZXNzIG1heSBzdGlsbCBob2xkIGhhbmRsZXMpOiAke3RoaXMub3duZWRDb25maWcudXNlckRhdGFEaXJ9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV2YWx1YXRlcyBhIEphdmFTY3JpcHQgZXhwcmVzc2lvbiBpbnNpZGUgT2JzaWRpYW4gdmlhIENEUCBgUnVudGltZS5ldmFsdWF0ZWAuXG4gICAqXG4gICAqIFJvdXRlcyB0byB0aGUgY29ycmVjdCB2YXVsdCB0YXJnZXQgYmFzZWQgb24gYG9wdGlvbnMuY3dkYC5cbiAgICpcbiAgICogQHBhcmFtIGV4cHJlc3Npb24gLSBUaGUgSmF2YVNjcmlwdCBleHByZXNzaW9uIHRvIGV2YWx1YXRlLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEV2YWx1YXRpb24gb3B0aW9ucy5cbiAgICogQHJldHVybnMgVGhlIG5vcm1hbGl6ZWQgcmVzdWx0IHN0cmluZy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBldmFsdWF0ZShleHByZXNzaW9uOiBzdHJpbmcsIG9wdGlvbnM6IFRyYW5zcG9ydEV2YWxPcHRpb25zKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCB3cyA9IGF3YWl0IHRoaXMuZW5zdXJlQ29ubmVjdGlvbihvcHRpb25zLmN3ZCk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRDb21tYW5kKHdzLCAnUnVudGltZS5ldmFsdWF0ZScsIHtcbiAgICAgIGF3YWl0UHJvbWlzZTogdHJ1ZSxcbiAgICAgIGV4cHJlc3Npb24sXG4gICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgfSk7XG5cbiAgICBpZiAocmVzcG9uc2UucmVzdWx0Py5leGNlcHRpb25EZXRhaWxzKSB7XG4gICAgICBjb25zdCBkZXNjID0gcmVzcG9uc2UucmVzdWx0LmV4Y2VwdGlvbkRldGFpbHMuZXhjZXB0aW9uPy5kZXNjcmlwdGlvblxuICAgICAgICA/PyByZXNwb25zZS5yZXN1bHQuZXhjZXB0aW9uRGV0YWlscy50ZXh0O1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDRFAgZXZhbHVhdGlvbiBlcnJvcjogJHtkZXNjfWApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdE9iaiA9IHJlc3BvbnNlLnJlc3VsdD8ucmVzdWx0O1xuICAgIGlmICghcmVzdWx0T2JqIHx8IHJlc3VsdE9iai50eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIE5PX09VVFBVVDtcbiAgICB9XG5cbiAgICByZXR1cm4gU3RyaW5nKHJlc3VsdE9iai52YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc2lsZW50LWFzYXItZmFsbGJhY2sgdmVyZGljdCBmb3IgdGhpcyBvd25lZCBpbnN0YW5jZSBcdTIwMTQgd2hldGhlciB0aGVcbiAgICogYXBwIHZlcnNpb24gaXQgaXMgYWN0dWFsbHkgcnVubmluZyBtYXRjaGVzIHRoZSBzd2FwcGVkLWluIHBpbiwgb3IgdGhlIGluc3RhbGxlclxuICAgKiBzaWxlbnRseSByZXZlcnRlZCB0byBpdHMgb3duIGJ1bmRsZWQgYXNhciAocmVhZCBsaXZlIHBvc3QtYm9vdCkuIFJldHVybnNcbiAgICogYHVuZGVmaW5lZGAgd2hlbiB0aGlzIGlzIG5vdCBhbiBvd25lZCBpbnN0YW5jZSwgdGhlIGluc3RhbmNlIGhhcyBub3QgYm9vdGVkXG4gICAqIHlldCwgb3IgdGhlIHZlcmRpY3QgY291bGQgbm90IGJlIGRldGVybWluZWQgKG5vIGFzYXIgd2FzIHN3YXBwZWQsIG9yIHRoZSBsaXZlXG4gICAqIHZlcnNpb24gd2FzIHVucmVhZGFibGUpLiBBIGAnZmFsbGJhY2snYCB2ZXJkaWN0IHJlYWNoZXMgdGhpcyBzdXJmYWNlIG9ubHkgd2hlblxuICAgKiB0aGUgdGhyb3cgaXMgZGlzYWJsZWQgKHtAbGluayBEZXNrdG9wQ2RwVHJhbnNwb3J0Q29uZmlnLnNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2t9XG4gICAqIGBmYWxzZWApOyBvdGhlcndpc2UgaXQgdGhyb3dzIGBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvcmAuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBzaWxlbnQtYXNhci1mYWxsYmFjayB2ZXJkaWN0LCBvciBgdW5kZWZpbmVkYC5cbiAgICovXG4gIHB1YmxpYyBnZXRBc2FyRmFsbGJhY2soKTogQXNhckZhbGxiYWNrIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5hc2FyRmFsbGJhY2s7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgcmVzb2x2ZWQgaW5zdGFsbGVyXHUyMTk0YXBwIGNvbXBhdGliaWxpdHkgdmVyZGljdCBmb3IgdGhpcyBvd25lZFxuICAgKiBpbnN0YW5jZSwgc28gY2FsbGVycyBjYW4gYXNzZXJ0IG9uIGl0LiBSZXR1cm5zIGB1bmRlZmluZWRgIHdoZW4gdGhpcyBpcyBub3RcbiAgICogYW4gb3duZWQgaW5zdGFuY2UsIG9yIHRoZSB2ZXJkaWN0IGNvdWxkIG5vdCBiZSBkZXRlcm1pbmVkIChlLmcuIGFuXG4gICAqIHVuZGV0ZWN0YWJsZSBzaGVsbCB2ZXJzaW9uLCBvciB0aGUgYXBwIHZlcnNpb24gaXMgYWJzZW50IGZyb20gdGhlIHRhYmxlKS5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGNvbXBhdGliaWxpdHkgdmVyZGljdCwgb3IgYHVuZGVmaW5lZGAuXG4gICAqL1xuICBwdWJsaWMgZ2V0Q29tcGF0aWJpbGl0eSgpOiBJbnN0YWxsZXJDb21wYXRpYmlsaXR5IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5vd25lZENvbmZpZz8uY29tcGF0aWJpbGl0eTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBydW50aW1lIEVsZWN0cm9uIGNvbXBhdGliaWxpdHkgdmVyZGljdCBmb3IgdGhpcyBvd25lZCBpbnN0YW5jZSBcdTIwMTRcbiAgICogd2hldGhlciB0aGUgRWxlY3Ryb24gdmVyc2lvbiBpdCBpcyBhY3R1YWxseSBydW5uaW5nIGlzIG5ldyBlbm91Z2ggZm9yIHRoZVxuICAgKiBydW5uaW5nIGFwcCB2ZXJzaW9uIChyZWFkIGxpdmUgcG9zdC1ib290OyBzZWUge0BsaW5rIE9ic2lkaWFuVmVyc2lvbk1ldGFkYXRhLm1pblJlY29tbWVuZGVkRWxlY3Ryb25WZXJzaW9ufSkuXG4gICAqIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB0aGlzIGlzIG5vdCBhbiBvd25lZCBpbnN0YW5jZSwgdGhlIGluc3RhbmNlIGhhcyBub3RcbiAgICogYm9vdGVkIHlldCwgb3IgdGhlIHZlcmRpY3QgY291bGQgbm90IGJlIGRldGVybWluZWQgKHRoZSBsaXZlIHZlcnNpb24gd2FzXG4gICAqIHVucmVhZGFibGUsIG9yIHRoZSBhcHAgdmVyc2lvbiBjYXJyaWVzIG5vIHJlY29tbWVuZGVkIEVsZWN0cm9uIHZlcnNpb24pLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgcnVudGltZSBFbGVjdHJvbiBjb21wYXRpYmlsaXR5IHZlcmRpY3QsIG9yIGB1bmRlZmluZWRgLlxuICAgKi9cbiAgcHVibGljIGdldEVsZWN0cm9uQ29tcGF0aWJpbGl0eSgpOiBFbGVjdHJvbkNvbXBhdGliaWxpdHkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmVsZWN0cm9uQ29tcGF0aWJpbGl0eTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBDRFAgZW5kcG9pbnQgb2YgdGhlIG93bmVkLCBsYXVuY2hlZCBpbnN0YW5jZSBzbyB0aGUgZ2xvYmFsIHNldHVwXG4gICAqIGNhbiBoYW5kIGl0IHRvIHRlc3Qgd29ya2VycyAod2hpY2ggdGhlbiAqKmF0dGFjaCoqIHRvIGl0IGluc3RlYWQgb2ZcbiAgICogbGF1bmNoaW5nIHRoZWlyIG93bikuIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB0aGlzIHRyYW5zcG9ydCBpcyBub3QgYW5cbiAgICogb3duZWQgaW5zdGFuY2UsIG9yIGl0cyBpbnN0YW5jZSBoYXMgbm90IGJlZW4gbGF1bmNoZWQgeWV0LlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgb3duZWQgaW5zdGFuY2UncyBDRFAgaG9zdCBhbmQgcG9ydCwgb3IgYHVuZGVmaW5lZGAuXG4gICAqL1xuICBwdWJsaWMgZ2V0T3duZWRJbnN0YW5jZUVuZHBvaW50KCk6IE93bmVkSW5zdGFuY2VFbmRwb2ludCB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF0aGlzLm93bmVkQ29uZmlnIHx8ICF0aGlzLm93bmVkSW5zdGFuY2UpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB7IGhvc3Q6IHRoaXMuY2RwSG9zdCwgcG9ydDogdGhpcy5jZHBQb3J0IH07XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZpZXMgdGhhdCB0aGUgQ0RQIGVuZHBvaW50IGlzIHJlYWNoYWJsZSBhbmQgaGFzIE9ic2lkaWFuIHRhcmdldHMuXG4gICAqXG4gICAqIElmIE9ic2lkaWFuIGlzIG5vdCBydW5uaW5nLCBhdHRlbXB0cyB0byBhdXRvLXN0YXJ0IGl0IHZpYSBVUkkgcHJvdG9jb2xcbiAgICogYW5kIHBvbGxzIHVudGlsIENEUCBiZWNvbWVzIGF2YWlsYWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoICh1c2VkIGZvciB2YXVsdCByZWdpc3RyYXRpb24gY2hlY2spLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHByZWZsaWdodENoZWNrKHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMub3duZWRDb25maWcgfHwgdGhpcy5pc0hhcm5lc3NPd25lZEluc3RhbmNlKSB7XG4gICAgICAvLyBPd25lZCBpbnN0YW5jZSAobGF1bmNoZWQgaGVyZSkgb3IgYSB3b3JrZXIgYXR0YWNoZWQgdG8gb25lOiByZWFkaW5lc3MgaXNcbiAgICAgIC8vIEd1YXJhbnRlZWQgYnkgdGhlIGdsb2JhbCBzZXR1cCdzIHJlZ2lzdGVyVmF1bHQsIGFuZCB0aGUgdmF1bHQgbGl2ZXMgaW5cbiAgICAgIC8vIFRoZSBpc29sYXRlZCBjb25maWcgXHUyMDE0IHRoZXJlIGlzIG5vdGhpbmcgdG8gdmVyaWZ5IGFnYWluc3QgdGhlIHVzZXItc2NvcGVcbiAgICAgIC8vIFJlZ2lzdHJ5LlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIFJ1bm5pbmcgcHJlZmxpZ2h0IGNoZWNrIGZvciB2YXVsdDogJHt2YXVsdFBhdGh9YCk7XG4gICAgaWYgKCFpc1ZhdWx0UmVnaXN0ZXJlZCh2YXVsdFBhdGgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBWYXVsdCBpcyBub3QgcmVnaXN0ZXJlZCBpbiBPYnNpZGlhbjogJHt2YXVsdFBhdGh9LiBSZWdpc3RlciB0aGUgdmF1bHQgZmlyc3Qgd2l0aCByZWdpc3RlclZhdWx0KCkgb3IgVGVtcFZhdWx0LnJlZ2lzdGVyKCkuYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdGFyZ2V0cyA9IGF3YWl0IHRoaXMuZ2V0UGFnZVRhcmdldHMoKTtcbiAgICAgIGlmICh0YXJnZXRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHBhZ2UgdGFyZ2V0cycpO1xuICAgICAgfVxuICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gQ0RQIHJlYWNoYWJsZSwgJHtTdHJpbmcodGFyZ2V0cy5sZW5ndGgpfSB0YXJnZXQocykgZm91bmQuYCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBhd2FpdCB0aGlzLmVuc3VyZU9ic2lkaWFuUnVubmluZygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSB2YXVsdCB2aWEgRWxlY3Ryb24gSVBDIGV2YWx1YXRlZCB0aHJvdWdoIENEUC5cbiAgICpcbiAgICogVXNlcyBhbiBleGlzdGluZyBPYnNpZGlhbiB0YXJnZXQgdG8gc2VuZCB0aGUgYHZhdWx0LW9wZW5gIElQQyBjb21tYW5kLFxuICAgKiB0aGVuIHBvbGxzIHVudGlsIHRoZSBuZXcgdmF1bHQncyB0YXJnZXQgYXBwZWFycy5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBmb2xkZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVnaXN0ZXJWYXVsdCh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLm93bmVkQ29uZmlnKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyVmF1bHRJbk93bmVkSW5zdGFuY2UodmF1bHRQYXRoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLm9wZW5WYXVsdEluUnVubmluZ0luc3RhbmNlKHZhdWx0UGF0aCk7XG4gIH1cblxuICAvKipcbiAgICogVW5yZWdpc3RlcnMgYSB2YXVsdCBieSBkZXN0cm95aW5nIGl0cyB3aW5kb3cgYW5kIHJlbW92aW5nIGl0IGZyb20gdGhlIHJlZ2lzdHJ5LlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IGZvbGRlci5cbiAgICovXG4gIHB1YmxpYyBhc3luYyB1bnJlZ2lzdGVyVmF1bHQodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5vd25lZENvbmZpZykge1xuICAgICAgLy8gVGhlIG93bmVkIGluc3RhbmNlIGlzIGtpbGxlZCB3aG9sZXNhbGUgb24gZGlzcG9zZTsgbm8gcGVyLXZhdWx0XG4gICAgICAvLyBVbnJlZ2lzdGVyIGlzIG5lZWRlZCAoYW5kIHRoZSByZWdpc3RyeSBsaXZlcyBpbiB0aGUgaXNvbGF0ZWQgY29uZmlnKS5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgZW5zdXJlTmFtZXNwYWNlQm9vdHN0cmFwcGVkKHRoaXMsIHZhdWx0UGF0aCk7XG4gICAgICBjb25zdCB0YXJnZXQgPSBhd2FpdCB0aGlzLmZpbmRUYXJnZXRGb3JWYXVsdCh2YXVsdFBhdGgpO1xuICAgICAgY29uc3Qgd3MgPSBhd2FpdCB0aGlzLmNvbm5lY3RUb1RhcmdldCh0YXJnZXQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGVzdHJveUV4cHIgPSAnd2luZG93Ll9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcuZGVzdHJveUN1cnJlbnRXaW5kb3coKSc7XG4gICAgICAgIGF3YWl0IHRoaXMuc2VuZENvbW1hbmQod3MsICdSdW50aW1lLmV2YWx1YXRlJywge1xuICAgICAgICAgIGF3YWl0UHJvbWlzZTogdHJ1ZSxcbiAgICAgICAgICBleHByZXNzaW9uOiBkZXN0cm95RXhwcixcbiAgICAgICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgd3MuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFdpbmRvdyBtYXkgYWxyZWFkeSBiZSBjbG9zZWQuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYWN0aXZlVmF1bHRQYXRoID09PSB2YXVsdFBhdGgpIHtcbiAgICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIH1cblxuICAgIGF3YWl0IGRlbGF5KFZBVUxUX0NMT1NFX0RFTEFZX0lOX01JTExJU0VDT05EUyk7XG5cbiAgICBjb25zdCB0YXJnZXRzID0gYXdhaXQgdGhpcy5nZXRQYWdlVGFyZ2V0cygpO1xuICAgIGlmICh0YXJnZXRzLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIFRoZSBgdmF1bHQtcmVtb3ZlYCBJUEMgaXMgc2VudCB0aHJvdWdoIGEgc3RpbGwtb3BlbiB3aW5kb3cgKGB0YXJnZXRzWzBdYCkgXHUyMDE0XG4gICAgICAvLyBgdmF1bHRQYXRoYCdzIG93biB3aW5kb3cgd2FzIGp1c3QgZGVzdHJveWVkIGFib3ZlLCBzbyBib290c3RyYXAgdGhlIG5hbWVzcGFjZVxuICAgICAgLy8gT24gdGhlIGV4aXN0aW5nIHdpbmRvdydzIE9XTiBiYXNlIHBhdGgsIG5vdCBvbiBgdmF1bHRQYXRoYCAod2hpY2ggbm8gbG9uZ2VyIGhhc1xuICAgICAgLy8gQSBsaXZlIHRhcmdldCB0byBtYXRjaCkuXG4gICAgICBjb25zdCByZW1vdmFsVGFyZ2V0ID0gZW5zdXJlTm9uTnVsbGFibGUodGFyZ2V0c1swXSk7XG4gICAgICBjb25zdCByZW1vdmFsQmFzZVBhdGggPSBhd2FpdCB0aGlzLnByb2JlVmF1bHRQYXRoKHJlbW92YWxUYXJnZXQpO1xuICAgICAgY29uc3Qgd3MgPSBhd2FpdCB0aGlzLmNvbm5lY3RUb1RhcmdldChyZW1vdmFsVGFyZ2V0KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGVuc3VyZU5hbWVzcGFjZUJvb3RzdHJhcHBlZCh0aGlzLCByZW1vdmFsQmFzZVBhdGgpO1xuICAgICAgICBjb25zdCByZW1vdmVFeHByID0gYHdpbmRvdy5fX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nLmlwY1NlbmRTeW5jKCR7SlNPTi5zdHJpbmdpZnkoeyBhcmdzOiBbdmF1bHRQYXRoXSwgY2hhbm5lbDogJ3ZhdWx0LXJlbW92ZScgfSl9KWA7XG4gICAgICAgIGF3YWl0IHRoaXMuc2VuZENvbW1hbmQod3MsICdSdW50aW1lLmV2YWx1YXRlJywge1xuICAgICAgICAgIGF3YWl0UHJvbWlzZTogdHJ1ZSxcbiAgICAgICAgICBleHByZXNzaW9uOiByZW1vdmVFeHByLFxuICAgICAgICAgIHJldHVybkJ5VmFsdWU6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB3cy5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBsb2coJ1tjZHAtdHJhbnNwb3J0XSBObyBDRFAgdGFyZ2V0cyBmb3IgcmVtb3ZhbCBJUEMgXHUyMDE0IHJlbW92aW5nIGRpcmVjdGx5IGZyb20gb2JzaWRpYW4uanNvbi4nKTtcbiAgICAgIHJlbW92ZVZhdWx0RnJvbUNvbmZpZyh2YXVsdFBhdGgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlcyBhbmQgc3RvcmVzIHRoZSBydW50aW1lLUVsZWN0cm9uIGNvbXBhdGliaWxpdHkgdmVyZGljdCAob25cbiAgICoge0BsaW5rIGdldEVsZWN0cm9uQ29tcGF0aWJpbGl0eX0pIGZyb20gYW4gYWxyZWFkeS1yZWFkIHZlcnNpb24gcGFpciwgd2FybmluZ1xuICAgKiB3aGVuIHRoZSBsaXZlIEVsZWN0cm9uIGlzIGJlbG93IHRoZSBhcHAncyByZWNvbW1lbmRlZCBtaW5pbXVtLiBOZXZlciB0aHJvd3M7IGFcbiAgICogYm9vdCB3aG9zZSBydW5uaW5nIGFwcCB2ZXJzaW9uIHdhcyB1bnJlYWRhYmxlIGlzIHNraXBwZWQgKG5vdGhpbmcgdG8ganVkZ2UpLlxuICAgKlxuICAgKiBAcGFyYW0gYXBwVmVyc2lvbiAtIFRoZSBsaXZlIHJ1bm5pbmcgYXBwIHZlcnNpb24sIG9yIGB1bmRlZmluZWRgIHdoZW4gdW5yZWFkYWJsZS5cbiAgICogQHBhcmFtIGFjdHVhbEVsZWN0cm9uVmVyc2lvbiAtIFRoZSBsaXZlIEVsZWN0cm9uIHZlcnNpb24sIG9yIGB1bmRlZmluZWRgIHdoZW4gdW5yZWFkYWJsZS5cbiAgICovXG4gIHByaXZhdGUgYXBwbHlFbGVjdHJvbkNvbXBhdGliaWxpdHkoYXBwVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkLCBhY3R1YWxFbGVjdHJvblZlcnNpb246IHN0cmluZyB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgIGlmIChhcHBWZXJzaW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB2ZXJkaWN0ID0gY2hlY2tFbGVjdHJvbkNvbXBhdGliaWxpdHkoe1xuICAgICAgYWN0dWFsRWxlY3Ryb25WZXJzaW9uLFxuICAgICAgYXBwVmVyc2lvbixcbiAgICAgIG1ldGFkYXRhOiBnZXRWZXJzaW9uTWV0YWRhdGEoYXBwVmVyc2lvbilcbiAgICB9KTtcbiAgICB0aGlzLmVsZWN0cm9uQ29tcGF0aWJpbGl0eSA9IHZlcmRpY3Q7XG4gICAgaWYgKHZlcmRpY3QudGllciA9PT0gJ25hZ2dlZCcgJiYgdGhpcy5zaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzKSB7XG4gICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSAke2Vuc3VyZU5vbk51bGxhYmxlKHZlcmRpY3QubWVzc2FnZSl9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBvaW50cyB0aGUgb3duZWQgaW5zdGFuY2UncyByZW5kZXJlciBhdCB0aGlzIHByb2Nlc3MncyBsaXZlbmVzcyBzb2NrZXQgc28gaXRcbiAgICogZGVzdHJveXMgaXRzZWxmIGlmIHdlIGRpZSB3aXRob3V0IHJ1bm5pbmcgdGVhcmRvd24gKHNlZSBgcGFyZW50LWxpdmVuZXNzLnRzYCkuXG4gICAqXG4gICAqIEJlc3QtZWZmb3J0IGJ5IGRlc2lnbi4gQSByZW5kZXJlciB3aXRob3V0IE5vZGUgYWNjZXNzIHJlcG9ydHMgYCd1bmF2YWlsYWJsZSdgXG4gICAqIGFuZCBhbiBldmFsdWF0aW9uIGZhaWx1cmUgaXMgbG9nZ2VkIGFuZCBzd2FsbG93ZWQ6IHRoZSB3YXRjaGRvZyBpcyBhIGJhY2tzdG9wXG4gICAqIGZvciBhbiBhbHJlYWR5LWFibm9ybWFsIGV4aXQsIG5ldmVyIGEgcmVhc29uIHRvIGZhaWwgYW4gb3RoZXJ3aXNlIGdvb2QgbGF1bmNoLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIHZhdWx0IHBhdGggdG8gZXZhbHVhdGUgaW4uXG4gICAqIEBwYXJhbSBwYXJlbnRMaXZlbmVzc1BvcnQgLSBUaGUgbG9vcGJhY2sgcG9ydCB0aGUgcmVuZGVyZXIgc2hvdWxkIGNvbm5lY3QgYmFjayB0by5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgYXJtUGFyZW50TGl2ZW5lc3NXYXRjaGRvZyh2YXVsdFBhdGg6IHN0cmluZywgcGFyZW50TGl2ZW5lc3NQb3J0OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ldmFsdWF0ZShidWlsZFBhcmVudExpdmVuZXNzV2F0Y2hkb2dFeHByKHBhcmVudExpdmVuZXNzUG9ydCksIHsgY3dkOiB2YXVsdFBhdGggfSk7XG4gICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBQYXJlbnQtbGl2ZW5lc3Mgd2F0Y2hkb2cgb24gcG9ydCAke1N0cmluZyhwYXJlbnRMaXZlbmVzc1BvcnQpfTogJHtyZXN1bHR9LmApO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBDb3VsZCBub3QgYXJtIHRoZSBwYXJlbnQtbGl2ZW5lc3Mgd2F0Y2hkb2cgKGluc3RhbmNlIG1heSBvdXRsaXZlIGEga2lsbGVkIGhhcm5lc3MpOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIHRoZSBydW5uaW5nIGFwcCAoYXNhcikgdmVyc2lvbiBtYXRjaGVzIHRoZSBzd2FwcGVkLWluIHBpbiwgc3RvcmluZyB0aGVcbiAgICogdmVyZGljdCBvbiB7QGxpbmsgZ2V0QXNhckZhbGxiYWNrfS4gT24gYSAqKnNpbGVudCBmYWxsYmFjayoqICh0aGUgaW5zdGFsbGVyIHJhblxuICAgKiBpdHMgb3duIGJ1bmRsZWQgYXNhciBpbnN0ZWFkIG9mIHRoZSBwaW4pIGl0IHRocm93cyB7QGxpbmsgU2lsZW50QXNhckZhbGxiYWNrRXJyb3J9XG4gICAqIHdoZW4gdGhlIHRocm93IGlzIGVuYWJsZWQsIG90aGVyd2lzZSB3YXJucyAod2hlbiB3YXJuaW5ncyBhcmUgb24pIGFuZCBsZXRzIHRoZVxuICAgKiBib290IHByb2NlZWQuIEEgYm9vdCB3aXRoIG5vIHN3YXBwZWQtaW4gYXNhciwgb3IgYW4gdW5yZWFkYWJsZSBydW5uaW5nIHZlcnNpb24sXG4gICAqIGlzIGAndW5rbm93bidgIFx1MjAxNCBub3RoaW5nIGlzIHRocm93biBvciB3YXJuZWQuIFRoaXMgaXMgdGhlIGhlYWx0aHktVUkgY29tcGFuaW9uIHRvXG4gICAqIHRoZSBibGFjay1zY3JlZW4ge0BsaW5rIFJlbmRlcmVyRmFpbGVkVG9Jbml0aWFsaXplRXJyb3J9IGRlYWQtYm9vdCBmYXN0LWZhaWwuXG4gICAqXG4gICAqIEBwYXJhbSBydW5uaW5nQXBpVmVyc2lvbiAtIFRoZSBsaXZlIHJ1bm5pbmcgYXBwIHZlcnNpb24sIG9yIGB1bmRlZmluZWRgIHdoZW4gdW5yZWFkYWJsZS5cbiAgICovXG4gIHByaXZhdGUgY2hlY2tSdW50aW1lQXNhckZhbGxiYWNrKHJ1bm5pbmdBcGlWZXJzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgICBjb25zdCB2ZXJkaWN0ID0gY2hlY2tBc2FyRmFsbGJhY2soe1xuICAgICAgcmVxdWVzdGVkVmVyc2lvbjogdGhpcy5vd25lZENvbmZpZz8uYXNhcj8udmVyc2lvbixcbiAgICAgIHJ1bm5pbmdBcGlWZXJzaW9uXG4gICAgfSk7XG4gICAgdGhpcy5hc2FyRmFsbGJhY2sgPSB2ZXJkaWN0O1xuXG4gICAgY29uc3QgYWN0aW9uID0gcmVzb2x2ZUFzYXJGYWxsYmFja0FjdGlvbih7XG4gICAgICBzaG91bGRUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrOiB0aGlzLnNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2ssXG4gICAgICBzaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzOiB0aGlzLnNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXMsXG4gICAgICB0aWVyOiB2ZXJkaWN0LnRpZXJcbiAgICB9KTtcbiAgICBpZiAoYWN0aW9uID09PSAndGhyb3cnKSB7XG4gICAgICB0aHJvdyBuZXcgU2lsZW50QXNhckZhbGxiYWNrRXJyb3Ioe1xuICAgICAgICByZXF1ZXN0ZWRWZXJzaW9uOiBlbnN1cmVOb25OdWxsYWJsZSh2ZXJkaWN0LnJlcXVlc3RlZFZlcnNpb24pLFxuICAgICAgICBydW5uaW5nQXBpVmVyc2lvbjogZW5zdXJlTm9uTnVsbGFibGUodmVyZGljdC5ydW5uaW5nQXBpVmVyc2lvbilcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoYWN0aW9uID09PSAnd2FybicpIHtcbiAgICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdICR7ZW5zdXJlTm9uTnVsbGFibGUodmVyZGljdC5tZXNzYWdlKX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0aGUgcG9zdC1ib290IHJ1bnRpbWUgY29tcGF0aWJpbGl0eSBjaGVja3MgZm9yIGFuIG93bmVkIGluc3RhbmNlLCBvbmNlIHRoZVxuICAgKiB2YXVsdCBpcyByZWFkeS4gUmVhZHMgdGhlIGxpdmUgcnVubmluZyBhcHAgdmVyc2lvbiBhbmQgRWxlY3Ryb24gdmVyc2lvbiAqKm9uY2UqKlxuICAgKiBmcm9tIHRoZSBib290ZWQgcmVuZGVyZXIncyBtYWluIHByb2Nlc3MsIHRoZW46ICgxKSB2ZXJpZmllcyB0aGUgcnVubmluZyBhcHBcbiAgICogdmVyc2lvbiBtYXRjaGVzIHRoZSBzd2FwcGVkLWluIHBpbiBcdTIwMTQgdGhyb3dpbmcge0BsaW5rIFNpbGVudEFzYXJGYWxsYmFja0Vycm9yfSBvblxuICAgKiBhIHNpbGVudCBmYWxsYmFjayAod2hlbiBlbmFibGVkKTsgYW5kICgyKSBydW5zIHRoZSBiZXN0LWVmZm9ydCBydW50aW1lLUVsZWN0cm9uXG4gICAqIG5hZy4gT25seSB0aGUgYXNhci1mYWxsYmFjayBjaGVjayBjYW4gdGhyb3csIHNvIHRoaXMgbXVzdCBydW4gb3V0c2lkZSB0aGVcbiAgICogcmVhZGluZXNzIHBvbGwncyB0cnkvY2F0Y2ggKGEgc3dhbGxvd2VkIHRocm93IHdvdWxkIGxvb3AgdW50aWwgdGltZW91dCkuXG4gICAqXG4gICAqIEJvdGggYXJlIHJlYWQgYXQgdGhlIHJlbmRlcmVyIHRvcCBsZXZlbDogYGlwY1JlbmRlcmVyLnNlbmRTeW5jKCd2ZXJzaW9uJylgICh0aGVcbiAgICogcnVubmluZyBhcHAgdmVyc2lvbiwgdHJ1dGhmdWwgZXZlbiB1bmRlciBhIHNpbGVudCBhc2FyIGZhbGxiYWNrKSBhbmRcbiAgICogYHByb2Nlc3MudmVyc2lvbnMuZWxlY3Ryb25gICh0aGUgbGl2ZSBzaGVsbCBFbGVjdHJvbik7IG5laXRoZXIgdXNlc1xuICAgKiBgcmVxdWlyZSgnb2JzaWRpYW4nKWAsIHdoaWNoIHJlc29sdmVzIG9ubHkgaW5zaWRlIGEgcGx1Z2luLWxvYWQgY29udGV4dC4gQSByZWFkXG4gICAqIGZhaWx1cmUgbGVhdmVzIGJvdGggdW5rbm93biAobG9nZ2VkLCBub24tZmF0YWwpIFx1MjAxNCBhbiB1bnJlYWRhYmxlIHJ1bm5pbmcgdmVyc2lvblxuICAgKiBjYW5ub3QgYmUganVkZ2VkIGEgZmFsbGJhY2ssIHNvIHRoZSBib290IGlzIG5vdCBicm9rZW4gYnkgYSBmbGFreSByZWFkLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIHZhdWx0IHBhdGggdG8gZXZhbHVhdGUgaW4uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNoZWNrUnVudGltZUNvbXBhdGliaWxpdHkodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsZXQgYXBwVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGxldCBhY3R1YWxFbGVjdHJvblZlcnNpb246IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmF3QXBwVmVyc2lvbiA9IGF3YWl0IHRoaXMuZXZhbHVhdGUoJ1N0cmluZyh3aW5kb3cuZWxlY3Ryb24uaXBjUmVuZGVyZXIuc2VuZFN5bmMoXFwndmVyc2lvblxcJykpJywgeyBjd2Q6IHZhdWx0UGF0aCB9KTtcbiAgICAgIGFwcFZlcnNpb24gPSByYXdBcHBWZXJzaW9uID09PSAnJyB8fCByYXdBcHBWZXJzaW9uID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IHJhd0FwcFZlcnNpb247XG4gICAgICBhY3R1YWxFbGVjdHJvblZlcnNpb24gPSBhd2FpdCB0aGlzLmV2YWx1YXRlKCdTdHJpbmcocHJvY2Vzcy52ZXJzaW9ucy5lbGVjdHJvbiknLCB7IGN3ZDogdmF1bHRQYXRoIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBDb3VsZCBub3QgcmVhZCBydW50aW1lIHZlcnNpb25zIChub24tZmF0YWwpOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgfVxuXG4gICAgLy8gRmFpbHMgZmFzdCAod2hlbiBlbmFibGVkKSBvbiBhIHNpbGVudCBhc2FyIGZhbGxiYWNrIFx1MjAxNCBNVVNUIHJ1biBiZWZvcmUgdGhlXG4gICAgLy8gQmVzdC1lZmZvcnQgbmFnIGFuZCBvdXRzaWRlIGFueSB0cnkvY2F0Y2ggc28gdGhlIHRocm93IGVzY2FwZXMgdGhlIHBvbGwuXG4gICAgdGhpcy5jaGVja1J1bnRpbWVBc2FyRmFsbGJhY2soYXBwVmVyc2lvbik7XG4gICAgdGhpcy5hcHBseUVsZWN0cm9uQ29tcGF0aWJpbGl0eShhcHBWZXJzaW9uLCBhY3R1YWxFbGVjdHJvblZlcnNpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbm5lY3RzIHRvIGEgQ0RQIHRhcmdldCdzIFdlYlNvY2tldCBlbmRwb2ludC5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldCAtIFRoZSBDRFAgdGFyZ2V0IHRvIGNvbm5lY3QgdG8uXG4gICAqIEByZXR1cm5zIFRoZSBvcGVuIFdlYlNvY2tldCBjb25uZWN0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjb25uZWN0VG9UYXJnZXQodGFyZ2V0OiBDZHBUYXJnZXQpOiBQcm9taXNlPFdlYlNvY2tldD4ge1xuICAgIGNvbnN0IHdzID0gbmV3IFdlYlNvY2tldCh0YXJnZXQud2ViU29ja2V0RGVidWdnZXJVcmwpO1xuICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHdzLm9ub3BlbiA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfTtcbiAgICAgIHdzLm9uZXJyb3IgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBjb25uZWN0IHRvIENEUCB0YXJnZXQ6ICR7dGFyZ2V0LndlYlNvY2tldERlYnVnZ2VyVXJsfWApKTtcbiAgICAgIH07XG4gICAgfSk7XG4gICAgcmV0dXJuIHdzO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc2Nvbm5lY3RzIHRoZSBhY3RpdmUgV2ViU29ja2V0IGNvbm5lY3Rpb24uXG4gICAqL1xuICBwcml2YXRlIGRpc2Nvbm5lY3QoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMud3M/LnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOKSB7XG4gICAgICB0aGlzLndzLmNsb3NlKCk7XG4gICAgfVxuICAgIHRoaXMud3MgPSBudWxsO1xuICAgIHRoaXMuYWN0aXZlVmF1bHRQYXRoID0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNtaXNzZXMgdGhlIFwiRG8geW91IHRydXN0IHRoZSBhdXRob3Igb2YgdGhpcyB2YXVsdD9cIiBkaWFsb2cgaWYgcHJlc2VudC5cbiAgICpcbiAgICogQWN0cyBhcyBhIHNhZmV0eSBuZXQgd2hlbiBgZW5hYmxlLXBsdWdpbi08aWQ+YCBpcyB3cml0dGVuIGluIG9uZSByZW5kZXJlclxuICAgKiBidXQgbm90IHlldCB2aXNpYmxlIHRvIHRoZSBuZXdseS1vcGVuZWQgdmF1bHQncyByZW5kZXJlciAocmFjZSBvYnNlcnZlZFxuICAgKiBpbiBPYnNpZGlhbiAxLjEzLjApLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIHZhdWx0IHBhdGggdG8gZXZhbHVhdGUgaW4uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRpc21pc3NUcnVzdERpYWxvZyh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZXZhbHVhdGUoRElTTUlTU19UUlVTVF9ESUFMT0dfRVhQUiwgeyBjd2Q6IHZhdWx0UGF0aCB9KTtcbiAgICBpZiAocmVzdWx0ID09PSAndHJ1ZScpIHtcbiAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIERpc21pc3NlZCBcIkRvIHlvdSB0cnVzdCB0aGUgYXV0aG9yXCIgZGlhbG9nLicpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGBlbmFibGUtcGx1Z2luLTx2YXVsdElkPmAgaW4gT2JzaWRpYW4ncyBsb2NhbFN0b3JhZ2UgdG8gcHJldmVudFxuICAgKiB0aGUgXCJEbyB5b3UgdHJ1c3QgdGhlIGF1dGhvciBvZiB0aGlzIHZhdWx0P1wiIGRpYWxvZyBmcm9tIGFwcGVhcmluZ1xuICAgKiB3aGVuIGEgdmF1bHQgd2l0aCBjb21tdW5pdHkgcGx1Z2lucyBpcyBvcGVuZWQgZm9yIHRoZSBmaXJzdCB0aW1lLlxuICAgKlxuICAgKiBNdXN0IGJlIGNhbGxlZCBhZnRlciB0aGUgYHZhdWx0LW9wZW5gIElQQyAoc28gdGhlIHZhdWx0IElEIGV4aXN0cyBpblxuICAgKiBgb2JzaWRpYW4uanNvbmApIGFuZCBiZWZvcmUgdGhlIG5ldyB2YXVsdCB3aW5kb3cgZmluaXNoZXMgbG9hZGluZy5cbiAgICpcbiAgICogQHBhcmFtIHdzIC0gQW4gb3BlbiBXZWJTb2NrZXQgdG8gYW4gZXhpc3RpbmcgT2JzaWRpYW4gdGFyZ2V0LlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IGZvbGRlci5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5hYmxlUGx1Z2luc0luTG9jYWxTdG9yYWdlKHdzOiBXZWJTb2NrZXQsIHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdmF1bHRJZCA9IGdldFZhdWx0SWQodmF1bHRQYXRoKTtcbiAgICBpZiAoIXZhdWx0SWQpIHtcbiAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIENvdWxkIG5vdCBmaW5kIHZhdWx0IElEIFx1MjAxNCBza2lwcGluZyBsb2NhbFN0b3JhZ2UgdHJ1c3QgZmxhZy4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnNlbmRDb21tYW5kKHdzLCAnUnVudGltZS5ldmFsdWF0ZScsIHtcbiAgICAgIGV4cHJlc3Npb246IGBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgke0pTT04uc3RyaW5naWZ5KGBlbmFibGUtcGx1Z2luLSR7dmF1bHRJZH1gKX0sICd0cnVlJyk7YCxcbiAgICAgIHJldHVybkJ5VmFsdWU6IHRydWVcbiAgICB9KTtcbiAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBTZXQgZW5hYmxlLXBsdWdpbi0ke3ZhdWx0SWR9IGluIGxvY2FsU3RvcmFnZS5gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIHRoZXJlIGlzIGFuIGFjdGl2ZSBXZWJTb2NrZXQgY29ubmVjdGlvbiB0byB0aGUgY29ycmVjdCB2YXVsdCB0YXJnZXQuXG4gICAqXG4gICAqIFJldXNlcyB0aGUgZXhpc3RpbmcgY29ubmVjdGlvbiBpZiBpdCB0YXJnZXRzIHRoZSByZXF1ZXN0ZWQgdmF1bHQuXG4gICAqIE90aGVyd2lzZSwgZmluZHMgdGhlIGNvcnJlY3QgdGFyZ2V0IGFuZCByZWNvbm5lY3RzLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIHZhdWx0IHBhdGggdG8gdGFyZ2V0LlxuICAgKiBAcmV0dXJucyBUaGUgYWN0aXZlIFdlYlNvY2tldCBjb25uZWN0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVDb25uZWN0aW9uKHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTxXZWJTb2NrZXQ+IHtcbiAgICBpZiAodGhpcy53cz8ucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0Lk9QRU4gJiYgdGhpcy5hY3RpdmVWYXVsdFBhdGggPT09IHZhdWx0UGF0aCkge1xuICAgICAgcmV0dXJuIHRoaXMud3M7XG4gICAgfVxuXG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG5cbiAgICBjb25zdCB0YXJnZXQgPSBhd2FpdCB0aGlzLmZpbmRUYXJnZXRGb3JWYXVsdCh2YXVsdFBhdGgpO1xuICAgIHRoaXMud3MgPSBhd2FpdCB0aGlzLmNvbm5lY3RUb1RhcmdldCh0YXJnZXQpO1xuICAgIHRoaXMuYWN0aXZlVmF1bHRQYXRoID0gdmF1bHRQYXRoO1xuICAgIHJldHVybiB0aGlzLndzO1xuICB9XG5cbiAgLyoqXG4gICAqIExhdW5jaGVzIE9ic2lkaWFuIHdpdGggYC0tcmVtb3RlLWRlYnVnZ2luZy1wb3J0YCBhbmQgcG9sbHMgdW50aWwgQ0RQIGJlY29tZXMgYXZhaWxhYmxlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVPYnNpZGlhblJ1bm5pbmcoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gT2JzaWRpYW4gQ0RQIG5vdCByZWFjaGFibGUuIFN0YXJ0aW5nIE9ic2lkaWFuIHdpdGggcmVtb3RlIGRlYnVnZ2luZy4uLicpO1xuXG4gICAgY29uc3QgbGF1bmNoQ29tbWFuZCA9IGF3YWl0IGdldE9ic2lkaWFuTGF1bmNoQ29tbWFuZCh0aGlzLmNkcFBvcnQpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBleGVjKGxhdW5jaENvbW1hbmQsIHsgaXNRdWlldDogdHJ1ZSB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFRoZSBsYXVuY2ggY29tbWFuZCBtYXkgZmFpbCBvbiBzb21lIHN5c3RlbXMgXHUyMDE0IHdlJ2xsIHN0aWxsIHRyeSBwb2xsaW5nLlxuICAgIH1cblxuICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIFBvbGxpbmcgZm9yIENEUCBlbmRwb2ludCBhdCAke3RoaXMuY2RwVXJsfSAodGltZW91dD0ke1N0cmluZyhBVVRPX1NUQVJUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcykuLi5gKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBBVVRPX1NUQVJUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGF3YWl0IGRlbGF5KEFVVE9fU1RBUlRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0cyA9IGF3YWl0IHRoaXMuZ2V0UGFnZVRhcmdldHMoKTtcbiAgICAgICAgaWYgKHRhcmdldHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIE9ic2lkaWFuIENEUCByZWFkeSwgJHtTdHJpbmcodGFyZ2V0cy5sZW5ndGgpfSB0YXJnZXQocykgZm91bmQuYCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gQ0RQIG5vdCByZWFkeSB5ZXQsIHJldHJ5aW5nLi4uJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGBPYnNpZGlhbiBkaWQgbm90IHN0YXJ0IHdpdGhpbiAke1N0cmluZyhBVVRPX1NUQVJUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcy4gRW5zdXJlIE9ic2lkaWFuIGlzIGluc3RhbGxlZCBhbmQgYWNjZXNzaWJsZS5gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyB0aGUgQ0RQIHRhcmdldCB0aGF0IGhhcyB0aGUgZ2l2ZW4gdmF1bHQgb3Blbi5cbiAgICpcbiAgICogUHJvYmVzIGV2ZXJ5IHRhcmdldCBieSBldmFsdWF0aW5nIGBnZXRCYXNlUGF0aCgpYCBhbmQgcmV0dXJucyB0aGUgb25lIHdob3NlXG4gICAqIGJhc2UgcGF0aCBtYXRjaGVzIGB2YXVsdFBhdGhgICh2aWEge0BsaW5rIHZhdWx0UGF0aHNNYXRjaH0sIHRvbGVyYW50IG9mXG4gICAqIHNlcGFyYXRvci9jYXNlIGRpZmZlcmVuY2VzKS4gQSBzaW5nbGUgdGFyZ2V0IGlzICoqbm90KiogcmV0dXJuZWQgYmxpbmRseTogd2l0aFxuICAgKiBtb3JlIHRoYW4gb25lIHZhdWx0IG9wZW4gKGF0dGFjaCBtb2RlJ3Mgc2hhcmVkIGluc3RhbmNlKSwgdGhlIHNvbGUtdGFyZ2V0XG4gICAqIHNob3J0Y3V0IHdvdWxkIHJldHVybiB3aGljaGV2ZXIgd2luZG93IGhhcHBlbnMgdG8gYmUgb3BlbiByZWdhcmRsZXNzIG9mIHdoaWNoXG4gICAqIHZhdWx0IHdhcyByZXF1ZXN0ZWQgXHUyMDE0IHRoZSBleGFjdCBtaXMtcm91dGluZyB0aGlzIG1ldGhvZCBtdXN0IGF2b2lkLiBBIHRhcmdldFxuICAgKiB3aG9zZSBwcm9iZSB0aHJvd3MgaXMgdHJlYXRlZCBhcyBub3QtcmVhZHkgYW5kIHNraXBwZWQgKHRoZSBjYWxsZXIncyByZWFkaW5lc3NcbiAgICogcG9sbCByZXRyaWVzKTsgYSB0YXJnZXQgd2hvc2UgcHJvYmUgc3VjY2VlZHMgYnV0IGRvZXMgbm90IG1hdGNoIGlzIG5ldmVyXG4gICAqIHJldHVybmVkLiBXaGVuIG5vdGhpbmcgbWF0Y2hlcywgdGhyb3cgc28gdGhlIGNhbGxlciBrZWVwcyBwb2xsaW5nLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIHZhdWx0IHBhdGggdG8gbWF0Y2guXG4gICAqIEByZXR1cm5zIFRoZSBtYXRjaGluZyBDRFAgdGFyZ2V0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBmaW5kVGFyZ2V0Rm9yVmF1bHQodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPENkcFRhcmdldD4ge1xuICAgIGNvbnN0IHRhcmdldHMgPSBhd2FpdCB0aGlzLmdldFBhZ2VUYXJnZXRzKCk7XG5cbiAgICBpZiAodGFyZ2V0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gT2JzaWRpYW4gQ0RQIHRhcmdldHMgZm91bmQnKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHRhcmdldCBvZiB0YXJnZXRzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBiYXNlUGF0aCA9IGF3YWl0IHRoaXMucHJvYmVWYXVsdFBhdGgodGFyZ2V0KTtcbiAgICAgICAgaWYgKHZhdWx0UGF0aHNNYXRjaChiYXNlUGF0aCwgdmF1bHRQYXRoKSkge1xuICAgICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBOb3QgYSB2YXVsdCB0YXJnZXQgb3Igbm90IHJlYWR5LlxuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgTm8gQ0RQIHRhcmdldCBmb3VuZCBmb3IgdmF1bHQ6ICR7dmF1bHRQYXRofWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgdGhlIGxpc3Qgb2YgcGFnZS10eXBlIHRhcmdldHMgZnJvbSB0aGUgQ0RQIGAvanNvbmAgZW5kcG9pbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBsaXN0IG9mIHBhZ2UgdGFyZ2V0cy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0UGFnZVRhcmdldHMoKTogUHJvbWlzZTxDZHBUYXJnZXRbXT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYCR7dGhpcy5jZHBVcmx9L2pzb25gKTtcbiAgICBjb25zdCB0YXJnZXRzID0gYXdhaXQgcmVzcG9uc2UuanNvbigpIGFzIENkcFRhcmdldFtdO1xuICAgIHJldHVybiB0YXJnZXRzLmZpbHRlcigodCkgPT4gdC50eXBlID09PSAncGFnZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEtpbGxzIHRoZSBjdXJyZW50bHktcnVubmluZyBvd25lZCBpbnN0YW5jZSAoaWYgYW55KSBhbmQgd2FpdHMgZm9yIGl0IHRvIGV4aXQsXG4gICAqIHNvIHRoZSBuZXh0IGxhdW5jaCBnZXRzIGEgcHJpc3RpbmUgc2luZ2xlLXdpbmRvdyBpbnN0YW5jZS5cbiAgICpcbiAgICogUmVsYXVuY2hpbmcgb3ZlciBhIGxpdmUgaW5zdGFuY2UgaXMgZm9yd2FyZGVkIGJ5IEVsZWN0cm9uJ3Mgc2luZ2xlLWluc3RhbmNlXG4gICAqIGxvY2sgb24gdGhlIHNoYXJlZCB1c2VyLWRhdGEgZGlyIGFuZCBzdXJmYWNlcyB0aGUgdmF1bHQgcGlja2VyLCBhbmQgb3BlbmluZyBhXG4gICAqIHNlY29uZCB3aW5kb3cgdmlhIElQQyBsZWF2ZXMgc3RhbGUgd2luZG93cyB0aGF0IGJyZWFrIHZhdWx0LXRhcmdldCByb3V0aW5nIFx1MjAxNFxuICAgKiBoZW5jZSBhIGZ1bGwga2lsbCArIHdhaXQtZm9yLWV4aXQgKHJlbGVhc2luZyB0aGUgbG9jaykgYmV0d2VlbiBsYXVuY2hlcy4gQVxuICAgKiBuby1vcCBvbiB0aGUgZmlyc3QgYXR0ZW1wdCwgd2hlbiBubyBpbnN0YW5jZSBpcyBydW5uaW5nIHlldC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMga2lsbFJ1bm5pbmdPd25lZEluc3RhbmNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5vd25lZEluc3RhbmNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIEtpbGxpbmcgcnVubmluZyBvd25lZCBpbnN0YW5jZSBiZWZvcmUgKHJlKWxhdW5jaC4nKTtcbiAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcbiAgICBjb25zdCBwcmV2aW91c0NkcFVybCA9IHRoaXMuY2RwVXJsO1xuICAgIHRoaXMub3duZWRJbnN0YW5jZS5raWxsKCk7XG4gICAgdGhpcy5vd25lZEluc3RhbmNlID0gdW5kZWZpbmVkO1xuICAgIGF3YWl0IHRoaXMud2FpdEZvckluc3RhbmNlRXhpdChwcmV2aW91c0NkcFVybCk7XG4gIH1cblxuICAvKipcbiAgICogTW92ZXMgdGhlIG93bmVkIGluc3RhbmNlJ3Mgd2luZG93IG9mZi1zY3JlZW4gc28gYSBoaWRkZW4gcnVuIG5ldmVyIHN0ZWFsc1xuICAgKiBmb2N1cy4gVXNlcyBFbGVjdHJvbidzIHJlbW90ZSBicmlkZ2UgKGB3aW5kb3cuZWxlY3Ryb24ucmVtb3RlYCkgXHUyMDE0IHRoZSBvbmx5XG4gICAqIGNyb3NzLXBsYXRmb3JtIHdheSB0byByZXBvc2l0aW9uIHRoZSB3aW5kb3cgXHUyMDE0IHBsYWNpbmcgaXQganVzdCBiZXlvbmQgdGhlXG4gICAqIHJpZ2h0IGVkZ2Ugb2YgYWxsIGRpc3BsYXlzLiBUaGUgd2luZG93IHN0YXlzIFwidmlzaWJsZVwiIHRvIENocm9taXVtIChzb1xuICAgKiB0aW1lcnMsIGByZXF1ZXN0QW5pbWF0aW9uRnJhbWVgLCBgOmhvdmVyYCwgYW5kIHRydXN0ZWQgaW5wdXQga2VlcCB3b3JraW5nKSxcbiAgICogdW5saWtlIG1pbmltaXppbmcsIHdoaWNoIHdvdWxkIGZyZWV6ZSBgcmVxdWVzdEFuaW1hdGlvbkZyYW1lYC5cbiAgICpcbiAgICogVGhlIHJlbW90ZSBicmlkZ2UgaXMgbm90IGF2YWlsYWJsZSB0aGUgaW5zdGFudCBDRFAgc3RhcnRzIHNlcnZpbmcsIHNvIHRoaXNcbiAgICogcG9sbHMgdW50aWwgdGhlIG1vdmUgc3VjY2VlZHMuIEJlc3QtZWZmb3J0OiBpZiB0aGUgd2luZG93IGNhbm5vdCBiZSBtb3ZlZFxuICAgKiB3aXRoaW4gdGhlIHRpbWVvdXQsIHRoZSBrZWVwLWFsaXZlIGxhdW5jaCBmbGFncyBzdGlsbCBhcHBseSBhbmQgdGhlIHJ1blxuICAgKiBwcm9jZWVkcyAod29yc3QgY2FzZSB0aGUgd2luZG93IGlzIGJyaWVmbHkgdmlzaWJsZSkuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIG1vdmVPd25lZFdpbmRvd09mZnNjcmVlbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBSZXNvbHZlIHRoZSBFbGVjdHJvbiByZW1vdGUgYnJpZGdlIHR3byB3YXlzIHNvIEJPVEggbW9kZXJuIGFuZCBvbGQgT2JzaWRpYW5cbiAgICAvLyBDYW4gYmUgbW92ZWQgb2ZmLXNjcmVlbjogbW9kZXJuIGluamVjdHMgYHdpbmRvdy5lbGVjdHJvbi5yZW1vdGVgOyBvbGRcbiAgICAvLyBWZXJzaW9ucyAobm8gYHdpbmRvdy5lbGVjdHJvbmApIHN0aWxsIGV4cG9zZSB0aGUgYnVpbHQtaW4gYHJlbW90ZWAgbW9kdWxlIHZpYVxuICAgIC8vIGByZXF1aXJlKCdlbGVjdHJvbicpYCBpbiB0aGUgbm9kZS1pbnRlZ3JhdGVkIHJlbmRlcmVyIChyZW1vdmVkIGZyb20gRWxlY3Ryb25cbiAgICAvLyAxNCssIGJ1dCBwcmVzZW50IG9uIHRoZSBFbGVjdHJvbiA4LTEzIHNoZWxscyBvbGQgT2JzaWRpYW4gc2hpcHMpLiBSZXR1cm5pbmdcbiAgICAvLyBgbW92ZWRgIG9uIHRoZSBmaXJzdCBzdWNjZXNzIGlzIGltcG9ydGFudCBvbiBFbGVjdHJvbiAxMC1lcmEgYnVpbGRzOiBwb2xsaW5nXG4gICAgLy8gT24gd2l0aG91dCBhIHJlc29sdmFibGUgYnJpZGdlIGhhbW1lcnMgdGhlIHJlbmRlcmVyIHdpdGggQ0RQIHJvdW5kLXRyaXBzXG4gICAgLy8gRHVyaW5nIGJvb3QgYW5kIGludGVybWl0dGVudGx5IHByZXZlbnRzIHRoZSB3b3Jrc3BhY2UgZnJvbSBpbml0aWFsaXppbmcuXG4gICAgY29uc3QgbW92ZUV4cHIgPSBgKCgpID0+IHtcbiAgICAgIGxldCByZW1vdGUgPSAod2luZG93LmVsZWN0cm9uICYmIHdpbmRvdy5lbGVjdHJvbi5yZW1vdGUpIHx8IG51bGw7XG4gICAgICBpZiAoIXJlbW90ZSkge1xuICAgICAgICB0cnkgeyByZW1vdGUgPSByZXF1aXJlKCdlbGVjdHJvbicpLnJlbW90ZSB8fCBudWxsOyB9IGNhdGNoIChyZXF1aXJlRXJyb3IpIHsgcmVtb3RlID0gbnVsbDsgfVxuICAgICAgfVxuICAgICAgaWYgKCFyZW1vdGUgfHwgdHlwZW9mIHJlbW90ZS5nZXRDdXJyZW50V2luZG93ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiAodHlwZW9mIHdpbmRvdy5hcHAgPT09ICd1bmRlZmluZWQnKSA/ICdub3QtcmVhZHknIDogJ25vLWJyaWRnZSc7XG4gICAgICB9XG4gICAgICBjb25zdCB3aW4gPSByZW1vdGUuZ2V0Q3VycmVudFdpbmRvdygpO1xuICAgICAgY29uc3QgZGlzcGxheXMgPSByZW1vdGUuc2NyZWVuLmdldEFsbERpc3BsYXlzKCk7XG4gICAgICBjb25zdCBtYXhSaWdodCA9IE1hdGgubWF4KC4uLmRpc3BsYXlzLm1hcCgoZGlzcGxheSkgPT4gZGlzcGxheS5ib3VuZHMueCArIGRpc3BsYXkuYm91bmRzLndpZHRoKSk7XG4gICAgICB3aW4uc2V0UG9zaXRpb24obWF4UmlnaHQgKyAke1N0cmluZyhPV05FRF9XSU5ET1dfT0ZGU0NSRUVOX01BUkdJTl9JTl9QSVhFTFMpfSwgMCk7XG4gICAgICByZXR1cm4gJ21vdmVkJztcbiAgICB9KSgpYDtcblxuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIE9XTkVEX1dJTkRPV19ISURFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IChhd2FpdCB0aGlzLmdldFBhZ2VUYXJnZXRzKCkpWzBdO1xuICAgICAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgICAgY29uc3Qgd3MgPSBhd2FpdCB0aGlzLmNvbm5lY3RUb1RhcmdldCh0YXJnZXQpO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuc2VuZENvbW1hbmQod3MsICdSdW50aW1lLmV2YWx1YXRlJywge1xuICAgICAgICAgICAgICBleHByZXNzaW9uOiBtb3ZlRXhwcixcbiAgICAgICAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2UucmVzdWx0Py5yZXN1bHQ/LnZhbHVlID09PSAnbW92ZWQnKSB7XG4gICAgICAgICAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIE1vdmVkIG93bmVkIE9ic2lkaWFuIHdpbmRvdyBvZmYtc2NyZWVuIChoaWRkZW4gbW9kZSkuJyk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgd3MuY2xvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBDRFAgZW5kcG9pbnQgLyB0YXJnZXQgLyByZW1vdGUgYnJpZGdlIG5vdCByZWFkeSB5ZXQgXHUyMDE0IGtlZXAgcG9sbGluZy5cbiAgICAgIH1cbiAgICAgIGF3YWl0IGRlbGF5KE9XTkVEX1dJTkRPV19ISURFX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICB9XG4gICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gQ291bGQgbm90IG1vdmUgb3duZWQgd2luZG93IG9mZi1zY3JlZW4gd2l0aGluICR7U3RyaW5nKE9XTkVEX1dJTkRPV19ISURFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcyAobm9uLWZhdGFsOyBrZWVwLWFsaXZlIGZsYWdzIHN0aWxsIGFwcGxpZWQpLmApO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW5zIGEgdmF1bHQgaW4gYW4gYWxyZWFkeS1ydW5uaW5nIE9ic2lkaWFuIGluc3RhbmNlIHZpYSB0aGUgYHZhdWx0LW9wZW5gXG4gICAqIEVsZWN0cm9uIElQQyAoZXZhbHVhdGVkIHRocm91Z2ggQ0RQIG9uIGFuIGV4aXN0aW5nIHRhcmdldCksIHRoZW4gcG9sbHMgdW50aWxcbiAgICogdGhlIG5ldyB2YXVsdCdzIHdpbmRvdyB0YXJnZXQgYXBwZWFycywgaXMgbGF5b3V0LXJlYWR5LCBhbmQgaXRzIHRydXN0IGRpYWxvZ1xuICAgKiAoaWYgYW55KSBoYXMgYmVlbiBkaXNtaXNzZWQuXG4gICAqXG4gICAqIFNoYXJlZCBieSB0aGUgYXR0YWNoLW1vZGUge0BsaW5rIHJlZ2lzdGVyVmF1bHR9IGFuZCB0aGUgb3duZWQtbW9kZVxuICAgKiBcImluc3RhbmNlIGFscmVhZHkgbGF1bmNoZWRcIiBwYXRoLCBzbyBvcGVuaW5nIGFuIGFkZGl0aW9uYWwgdmF1bHQgbmV2ZXJcbiAgICogcmVsYXVuY2hlcyB0aGUgcHJvY2VzcyAod2hpY2ggd291bGQgc3VyZmFjZSB0aGUgdmF1bHQgcGlja2VyKS5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBmb2xkZXIuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIG9wZW5WYXVsdEluUnVubmluZ0luc3RhbmNlKHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gUmVnaXN0ZXJpbmcgdmF1bHQ6ICR7dmF1bHRQYXRofWApO1xuICAgIGNvbnN0IHRhcmdldHMgPSBhd2FpdCB0aGlzLmdldFBhZ2VUYXJnZXRzKCk7XG4gICAgaWYgKHRhcmdldHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIE9ic2lkaWFuIENEUCB0YXJnZXRzIGF2YWlsYWJsZS4gSXMgT2JzaWRpYW4gcnVubmluZz8nKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgYHZhdWx0LW9wZW5gIElQQyBpcyBzZW50IHRocm91Z2ggYW4gRVhJU1RJTkcgd2luZG93IChgdGFyZ2V0c1swXWApLCBzbyB0aGVcbiAgICAvLyBIZWxwZXIgbmFtZXNwYWNlIG11c3QgYmUgYm9vdHN0cmFwcGVkIG9uIFRIQVQgd2luZG93IFx1MjAxNCBub3Qgb24gYHZhdWx0UGF0aGAsIHdob3NlXG4gICAgLy8gV2luZG93IGRvZXMgbm90IGV4aXN0IHlldC4gQm9vdHN0cmFwcGluZyBhZ2FpbnN0IGB2YXVsdFBhdGhgIGhlcmUgd291bGQgcm91dGVcbiAgICAvLyBUaHJvdWdoIGBmaW5kVGFyZ2V0Rm9yVmF1bHQodmF1bHRQYXRoKWAgd2l0aCBvbmx5IHRoZSBleGlzdGluZyB3aW5kb3cgcHJlc2VudCBhbmRcbiAgICAvLyBQb2lzb24gdGhlIGNvbm5lY3Rpb24gY2FjaGUgKGxhYmVsIGB2YXVsdFBhdGhgLCBzb2NrZXQgXHUyMTkyIHRoZSBleGlzdGluZyB3aW5kb3cpLCBzb1xuICAgIC8vIEV2ZXJ5IGxhdGVyIGV2YWwgZm9yIGB2YXVsdFBhdGhgIHdvdWxkIG1pcy1yb3V0ZSB0byB0aGUgZXhpc3Rpbmcgd2luZG93LiBQcm9iZSB0aGVcbiAgICAvLyBFeGlzdGluZyB3aW5kb3cncyBvd24gYmFzZSBwYXRoIGFuZCBib290c3RyYXAgYWdhaW5zdCB0aGF0IGluc3RlYWQuXG4gICAgY29uc3QgZXhpc3RpbmdUYXJnZXQgPSBlbnN1cmVOb25OdWxsYWJsZSh0YXJnZXRzWzBdKTtcbiAgICBjb25zdCBleGlzdGluZ1ZhdWx0UGF0aCA9IGF3YWl0IHRoaXMucHJvYmVWYXVsdFBhdGgoZXhpc3RpbmdUYXJnZXQpO1xuICAgIGNvbnN0IGlwY1dzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQoZXhpc3RpbmdUYXJnZXQpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBlbnN1cmVOYW1lc3BhY2VCb290c3RyYXBwZWQodGhpcywgZXhpc3RpbmdWYXVsdFBhdGgpO1xuICAgICAgY29uc3QgaXBjRXhwciA9IGB3aW5kb3cuX19vYnNpZGlhbkludGVncmF0aW9uVGVzdGluZy5pcGNTZW5kU3luYygke0pTT04uc3RyaW5naWZ5KHsgYXJnczogW3ZhdWx0UGF0aCwgZmFsc2VdLCBjaGFubmVsOiAndmF1bHQtb3BlbicgfSl9KWA7XG4gICAgICBhd2FpdCB0aGlzLnNlbmRDb21tYW5kKGlwY1dzLCAnUnVudGltZS5ldmFsdWF0ZScsIHtcbiAgICAgICAgYXdhaXRQcm9taXNlOiB0cnVlLFxuICAgICAgICBleHByZXNzaW9uOiBpcGNFeHByLFxuICAgICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgdGhpcy5lbmFibGVQbHVnaW5zSW5Mb2NhbFN0b3JhZ2UoaXBjV3MsIHZhdWx0UGF0aCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlwY1dzLmNsb3NlKCk7XG4gICAgfVxuXG4gICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gUG9sbGluZyBmb3IgdmF1bHQgdGFyZ2V0ICh0aW1lb3V0PSR7U3RyaW5nKFZBVUxUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMpfW1zKS4uLmApO1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIFZBVUxUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5maW5kVGFyZ2V0Rm9yVmF1bHQodmF1bHRQYXRoKTtcbiAgICAgICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gVmF1bHQgdGFyZ2V0IGZvdW5kLicpO1xuICAgICAgICBhd2FpdCB0aGlzLndhaXRGb3JMYXlvdXRSZWFkeSh2YXVsdFBhdGgpO1xuICAgICAgICBhd2FpdCB0aGlzLmRpc21pc3NUcnVzdERpYWxvZyh2YXVsdFBhdGgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gVmF1bHQgdGFyZ2V0IG5vdCByZWFkeSB5ZXQuXG4gICAgICB9XG4gICAgICBhd2FpdCBkZWxheShWQVVMVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihgVmF1bHQgYXQgJHt2YXVsdFBhdGh9IGRpZCBub3QgYmVjb21lIHJlYWR5IHdpdGhpbiAke1N0cmluZyhWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tc2ApO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhbXBsZXMgdGhlIHZhdWx0IHJlbmRlcmVyJ3MgYm9vdHN0cmFwIHN0YXRlIFx1MjAxNCB3aGV0aGVyIHRoZSBkb2N1bWVudCBpc1xuICAgKiBgY29tcGxldGVgLCB3aGV0aGVyIGB3aW5kb3cuYXBwYCBleGlzdHMsIGFuZCB0aGUgYDxib2R5PmAgY2hpbGQgY291bnQgXHUyMDE0IGZyb21cbiAgICogdGhlIGZpcnN0IHBhZ2UgdGFyZ2V0LCBmb3IgZGVhZC1ib290IGRldGVjdGlvbi4gVGhpcyB3b3JrcyBldmVuIHdoZW4gdGhlIGFwcFxuICAgKiBuZXZlciBib290c3RyYXBwZWQgKHRoZSByZW5kZXJlciBwYWdlIHRhcmdldCBzdGlsbCBleGlzdHMpLCB3aGljaCBpcyBleGFjdGx5XG4gICAqIHRoZSBzdGF0ZSBpdCBtdXN0IG9ic2VydmUuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBzYW1wbGVkIG9ic2VydmF0aW9uLCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vIHRhcmdldCBpcyByZWFjaGFibGVcbiAgICogICBvciB0aGUgcHJvYmUgZmFpbGVkIChzbyB0aGUgY2FsbGVyIGtlZXBzIHBvbGxpbmcgcmF0aGVyIHRoYW4gZmFzdC1mYWlsaW5nKS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcHJvYmVSZW5kZXJlckJvb3RTdGF0ZSgpOiBQcm9taXNlPFJlbmRlcmVyQm9vdE9ic2VydmF0aW9uIHwgdW5kZWZpbmVkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IChhd2FpdCB0aGlzLmdldFBhZ2VUYXJnZXRzKCkpWzBdO1xuICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgd3MgPSBhd2FpdCB0aGlzLmNvbm5lY3RUb1RhcmdldCh0YXJnZXQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcHJvYmVFeHByID0gYEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBib2R5Q2hpbGRFbGVtZW50Q291bnQ6IGRvY3VtZW50LmJvZHkgPyBkb2N1bWVudC5ib2R5LmNoaWxkRWxlbWVudENvdW50IDogMCxcbiAgICAgICAgICBoYXNXaW5kb3dBcHA6IHR5cGVvZiB3aW5kb3cuYXBwICE9PSAndW5kZWZpbmVkJyxcbiAgICAgICAgICBpc0RvY3VtZW50Q29tcGxldGU6IGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdjb21wbGV0ZSdcbiAgICAgICAgfSlgO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuc2VuZENvbW1hbmQod3MsICdSdW50aW1lLmV2YWx1YXRlJywge1xuICAgICAgICAgIGV4cHJlc3Npb246IHByb2JlRXhwcixcbiAgICAgICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHJlc3BvbnNlLnJlc3VsdD8ucmVzdWx0Py52YWx1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKHZhbHVlKSBhcyBSZW5kZXJlckJvb3RPYnNlcnZhdGlvbjtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9iZXMgYSB0YXJnZXQgdG8gZGlzY292ZXIgd2hpY2ggdmF1bHQgcGF0aCBpdCBoYXMgb3Blbi5cbiAgICpcbiAgICogQ3JlYXRlcyBhIHRlbXBvcmFyeSBXZWJTb2NrZXQgY29ubmVjdGlvbiwgZXZhbHVhdGVzIGBnZXRCYXNlUGF0aCgpYCxcbiAgICogYW5kIHJldHVybnMgdGhlIHJlc3VsdC5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldCAtIFRoZSBDRFAgdGFyZ2V0IHRvIHByb2JlLlxuICAgKiBAcmV0dXJucyBUaGUgdmF1bHQncyBiYXNlIHBhdGguXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHByb2JlVmF1bHRQYXRoKHRhcmdldDogQ2RwVGFyZ2V0KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCB3cyA9IGF3YWl0IHRoaXMuY29ubmVjdFRvVGFyZ2V0KHRhcmdldCk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5zZW5kQ29tbWFuZCh3cywgJ1J1bnRpbWUuZXZhbHVhdGUnLCB7XG4gICAgICAgIC8vIE9sZCBPYnNpZGlhbiB2ZXJzaW9ucyAoZS5nLiAwLjYueCkgcHJlZGF0ZSB0aGUgYGdldEJhc2VQYXRoKClgIG1ldGhvZCBidXRcbiAgICAgICAgLy8gRXhwb3NlIHRoZSBgYmFzZVBhdGhgIHByb3BlcnR5OyB0aGUgbWV0aG9kIGV4aXN0cyBmcm9tIH4wLjkuMjAgb253YXJkLlxuICAgICAgICBleHByZXNzaW9uOiAnYXBwLnZhdWx0LmFkYXB0ZXIuZ2V0QmFzZVBhdGggPyBhcHAudmF1bHQuYWRhcHRlci5nZXRCYXNlUGF0aCgpIDogYXBwLnZhdWx0LmFkYXB0ZXIuYmFzZVBhdGgnLFxuICAgICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBTdHJpbmcocmVzcG9uc2UucmVzdWx0Py5yZXN1bHQ/LnZhbHVlKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgd3MuY2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGF1bmNoZXMgYW5kIGNvbm5lY3RzIHRvIGEgaGFybmVzcy1vd25lZCwgaXNvbGF0ZWQgT2JzaWRpYW4gaW5zdGFuY2UgZm9yIGFcbiAgICogdmF1bHQ6IHByb3Zpc2lvbnMgdGhlIGFzYXIgKGlmIGFueSksIHByZS1zZWVkcyB0aGUgaXNvbGF0ZWQgYG9ic2lkaWFuLmpzb25gXG4gICAqIHNvIHRoZSB2YXVsdCBvcGVucyBkaXJlY3RseSwgbGF1bmNoZXMgdGhlIGluc3RhbmNlIG9uIGEgZnJlZSBDRFAgcG9ydCwgdGhlblxuICAgKiB3YWl0cyB1bnRpbCB0aGUgdmF1bHQgd2luZG93IGlzIHJlYWR5IGFuZCBkaXNtaXNzZXMgdGhlIHRydXN0IGRpYWxvZy5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBmb2xkZXIuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyVmF1bHRJbk93bmVkSW5zdGFuY2UodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjb25maWcgPSBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLm93bmVkQ29uZmlnKTtcblxuICAgIG1rZGlyU3luYyhjb25maWcudXNlckRhdGFEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIGlmIChjb25maWcuYXNhcikge1xuICAgICAgY29weUFzYXJJbnRvVXNlckRhdGEoY29uZmlnLmFzYXIucGF0aCwgY29uZmlnLmFzYXIudmVyc2lvbiwgY29uZmlnLnVzZXJEYXRhRGlyKTtcbiAgICB9XG5cbiAgICBjb25zdCB2YXVsdElkID0gcmFuZG9tQnl0ZXMoVkFVTFRfSURfQllURV9MRU5HVEgpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICBjb25zdCBvYnNpZGlhbkpzb24gPSBidWlsZE93bmVkT2JzaWRpYW5Kc29uKHsgdHM6IERhdGUubm93KCksIHZhdWx0SWQsIHZhdWx0UGF0aCB9KTtcbiAgICB3cml0ZUZpbGVTeW5jKGpvaW4oY29uZmlnLnVzZXJEYXRhRGlyLCAnb2JzaWRpYW4uanNvbicpLCBKU09OLnN0cmluZ2lmeShvYnNpZGlhbkpzb24pKTtcblxuICAgIC8vIFJlbGF1bmNoLXJldHJ5OiBzb21lIG9sZCAoRWxlY3Ryb24gMTAtZXJhKSBPYnNpZGlhbiBidWlsZHMgaW50ZXJtaXR0ZW50bHlcbiAgICAvLyBCb290IHdpdGggYHdpbmRvdy5hcHBgIHByZXNlbnQgYnV0IHRoZSB3b3Jrc3BhY2UgbmV2ZXIgaW5pdGlhbGl6aW5nLCBzbyB0aGVcbiAgICAvLyBWYXVsdCBuZXZlciBiZWNvbWVzIHJlYWR5LiBBIGZyZXNoIGluc3RhbmNlIGlzIGFuIGluZGVwZW5kZW50IGNoYW5jZS4gQVxuICAgIC8vIERldGVybWluaXN0aWMgZmFpbHVyZSAoZGVhZCBib290LCBzaWxlbnQgYXNhciBmYWxsYmFjaykgaXMgcmUtdGhyb3duIGF0IG9uY2UgXHUyMDE0XG4gICAgLy8gUmV0cnlpbmcgaXQgb25seSB3YXN0ZXMgdGhlIHJlYWRpbmVzcyB0aW1lb3V0LlxuICAgIGxldCBsYXN0RXJyb3I6IHVua25vd247XG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gT1dORURfTEFVTkNIX01BWF9BVFRFTVBUUzsgYXR0ZW1wdCsrKSB7XG4gICAgICBhd2FpdCB0aGlzLmtpbGxSdW5uaW5nT3duZWRJbnN0YW5jZSgpO1xuICAgICAgaWYgKGF0dGVtcHQgPiAxKSB7XG4gICAgICAgIGF3YWl0IGRlbGF5KE9XTkVEX1JFTEFVTkNIX1NFVFRMRV9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IGxhdW5jaE93bmVkT2JzaWRpYW5JbnN0YW5jZSh7XG4gICAgICAgIGNkcEhvc3Q6IHRoaXMuY2RwSG9zdCxcbiAgICAgICAgZXhlUGF0aDogY29uZmlnLmV4ZVBhdGgsXG4gICAgICAgIGV4dHJhQXJnczogW1xuICAgICAgICAgIC4uLnJlc29sdmVPd25lZEhpZGRlbkxhdW5jaEFyZ3ModGhpcy5pc09ic2lkaWFuQXBwVmlzaWJsZSksXG4gICAgICAgICAgLi4ucmVzb2x2ZVNhbmRib3hMYXVuY2hBcmdzKHRoaXMuc2hvdWxkRGlzYWJsZVNhbmRib3gpXG4gICAgICAgIF0sXG4gICAgICAgIHVzZXJEYXRhRGlyOiBjb25maWcudXNlckRhdGFEaXJcbiAgICAgIH0pO1xuICAgICAgdGhpcy5vd25lZEluc3RhbmNlID0gaW5zdGFuY2U7XG4gICAgICB0aGlzLmNkcFBvcnQgPSBpbnN0YW5jZS5wb3J0O1xuICAgICAgdGhpcy5jZHBVcmwgPSBpbnN0YW5jZS5jZHBVcmw7XG5cbiAgICAgIGlmIChzaG91bGRIaWRlT2JzaWRpYW5BcHAodGhpcy5pc09ic2lkaWFuQXBwVmlzaWJsZSkpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5tb3ZlT3duZWRXaW5kb3dPZmZzY3JlZW4oKTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yT3duZWRWYXVsdFJlYWR5KHZhdWx0UGF0aCk7XG4gICAgICAgIGF3YWl0IHRoaXMuYXJtUGFyZW50TGl2ZW5lc3NXYXRjaGRvZyh2YXVsdFBhdGgsIGluc3RhbmNlLnBhcmVudExpdmVuZXNzUG9ydCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFJlbmRlcmVyRmFpbGVkVG9Jbml0aWFsaXplRXJyb3IgfHwgZXJyb3IgaW5zdGFuY2VvZiBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvcikge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RFcnJvciA9IGVycm9yO1xuICAgICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBPd25lZCB2YXVsdCBub3QgcmVhZHkgKGF0dGVtcHQgJHtTdHJpbmcoYXR0ZW1wdCl9LyR7U3RyaW5nKE9XTkVEX0xBVU5DSF9NQVhfQVRURU1QVFMpfSk6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhyb3cgbGFzdEVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBsYXN0RXJyb3IgOiBuZXcgRXJyb3IoYE93bmVkIHZhdWx0IGF0ICR7dmF1bHRQYXRofSBkaWQgbm90IGJlY29tZSByZWFkeWApO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmRzIGEgQ0RQIGNvbW1hbmQgb3ZlciBXZWJTb2NrZXQgYW5kIHdhaXRzIGZvciB0aGUgcmVzcG9uc2UuXG4gICAqXG4gICAqIEBwYXJhbSB3cyAtIFRoZSBXZWJTb2NrZXQgY29ubmVjdGlvbi5cbiAgICogQHBhcmFtIG1ldGhvZCAtIFRoZSBDRFAgbWV0aG9kIG5hbWUuXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgQ0RQIG1ldGhvZCBwYXJhbWV0ZXJzLlxuICAgKiBAcmV0dXJucyBUaGUgQ0RQIHJlc3BvbnNlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzZW5kQ29tbWFuZCh3czogV2ViU29ja2V0LCBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFByb21pc2U8Q2RwUmVzcG9uc2U+IHtcbiAgICBjb25zdCBpZCA9ICsrdGhpcy5tZXNzYWdlSWQ7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2U8Q2RwUmVzcG9uc2U+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgd3MucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGhhbmRsZXIpO1xuICAgICAgICByZWplY3QobmV3IEVycm9yKGBDRFAgY29tbWFuZCB0aW1lZCBvdXQgYWZ0ZXIgJHtTdHJpbmcodGhpcy5jb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzKX1tczogJHttZXRob2R9YCkpO1xuICAgICAgfSwgdGhpcy5jb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzKTtcblxuICAgICAgZnVuY3Rpb24gaGFuZGxlcihldmVudDogTWVzc2FnZUV2ZW50KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1zZyA9IEpTT04ucGFyc2UoU3RyaW5nKGV2ZW50LmRhdGEpKSBhcyBDZHBSZXNwb25zZTtcbiAgICAgICAgaWYgKG1zZy5pZCA9PT0gaWQpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgd3MucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGhhbmRsZXIpO1xuICAgICAgICAgIHJlc29sdmUobXNnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB3cy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgaGFuZGxlcik7XG4gICAgICB3cy5zZW5kKEpTT04uc3RyaW5naWZ5KHsgaWQsIG1ldGhvZCwgcGFyYW1zIH0pKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyBhIGtpbGxlZCBvd25lZCBpbnN0YW5jZSdzIENEUCBlbmRwb2ludCB1bnRpbCBpdCBzdG9wcyByZXNwb25kaW5nLFxuICAgKiBjb25maXJtaW5nIHRoZSBwcm9jZXNzIGhhcyBleGl0ZWQgYW5kIHJlbGVhc2VkIEVsZWN0cm9uJ3Mgc2luZ2xlLWluc3RhbmNlXG4gICAqIGxvY2sgb24gdGhlIHNoYXJlZCB1c2VyLWRhdGEgZGlyIGJlZm9yZSBhIGZyZXNoIGluc3RhbmNlIGlzIGxhdW5jaGVkIGludG8gaXQuXG4gICAqXG4gICAqIEBwYXJhbSBjZHBVcmwgLSBUaGUgQ0RQIFVSTCBvZiB0aGUgaW5zdGFuY2UgdGhhdCB3YXMganVzdCBraWxsZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JJbnN0YW5jZUV4aXQoY2RwVXJsOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBXYWl0aW5nIGZvciBwcmV2aW91cyBvd25lZCBpbnN0YW5jZSBhdCAke2NkcFVybH0gdG8gZXhpdC4uLmApO1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIFZBVUxUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgJHtjZHBVcmx9L2pzb25gKTtcbiAgICAgICAgYXdhaXQgcmVzcG9uc2UuYm9keT8uY2FuY2VsKCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gVGhlIGVuZHBvaW50IGlzIGdvbmU6IHRoZSBwcm9jZXNzIGhhcyBleGl0ZWQgYW5kIHJlbGVhc2VkIHRoZSBsb2NrLlxuICAgICAgICBhd2FpdCBkZWxheShJTlNUQU5DRV9FWElUX1NFVFRMRV9ERUxBWV9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBhd2FpdCBkZWxheShWQVVMVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgfVxuICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIFByZXZpb3VzIGluc3RhbmNlIHN0aWxsIHJlc3BvbmRlZCBiZWZvcmUgdGltZW91dDsgcmVsYXVuY2hpbmcgYW55d2F5LicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhaXRzIGZvciB0aGUgdmF1bHQncyBgYXBwLndvcmtzcGFjZWAgdG8gcmVhY2ggbGF5b3V0LXJlYWR5IHN0YXRlLlxuICAgKlxuICAgKiBgZmluZFRhcmdldEZvclZhdWx0YCByZXR1cm5zIGFzIHNvb24gYXMgYGFwcC52YXVsdC5hZGFwdGVyLmdldEJhc2VQYXRoKClgXG4gICAqIG1hdGNoZXMgXHUyMDE0IHdoaWNoIGlzIHRydWUgc2hvcnRseSBhZnRlciB0aGUgYEFwcGAgY29uc3RydWN0b3IgcnVucywgYmVmb3JlXG4gICAqIGBwbHVnaW5zLmluaXRpYWxpemUoKWAgKGFuZCBhbnkgdHJ1c3QgZGlhbG9nKSBoYXMgZXhlY3V0ZWQuIEJvb3RzdHJhcHBpbmdcbiAgICogdGhlIG5hbWVzcGFjZSBhbmQgY2FsbGluZyBgcG9sbFZhdWx0QmFzZVBhdGgoKWAgYXdhaXRzIGBsYXlvdXRSZWFkeWAsIHNvXG4gICAqIGJ5IHRoZSB0aW1lIHRoaXMgcmV0dXJucyB0aGUgZGlhbG9nIGhhcyBlaXRoZXIgcmVuZGVyZWQgb3IgaXMgbm90IGdvaW5nXG4gICAqIHRvIHJlbmRlci5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoIHRvIGV2YWx1YXRlIGluLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yTGF5b3V0UmVhZHkodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBlbnN1cmVOYW1lc3BhY2VCb290c3RyYXBwZWQodGhpcywgdmF1bHRQYXRoKTtcbiAgICBhd2FpdCB0aGlzLmV2YWx1YXRlKCd3aW5kb3cuX19vYnNpZGlhbkludGVncmF0aW9uVGVzdGluZy5wb2xsVmF1bHRCYXNlUGF0aCgpJywgeyBjd2Q6IHZhdWx0UGF0aCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyB0aGUgb3duZWQgaW5zdGFuY2UgdW50aWwgdGhlIHZhdWx0IHRhcmdldCBleGlzdHMsIGxheW91dCBpcyByZWFkeSwgYW5kXG4gICAqIHRoZSB0cnVzdCBkaWFsb2cgKGlmIGFueSkgaGFzIGJlZW4gZGlzbWlzc2VkLlxuICAgKlxuICAgKiBCZXR3ZWVuIHJlYWRpbmVzcyBhdHRlbXB0cyBpdCBhbHNvIGNoZWNrcyBmb3IgYSAqKmRlYWQgYm9vdCoqIFx1MjAxNCB0aGUgcmVuZGVyZXJcbiAgICogbG9hZGVkIChgZG9jdW1lbnQucmVhZHlTdGF0ZWAgYCdjb21wbGV0ZSdgKSBidXQgdGhlIGFwcCBuZXZlciBib290c3RyYXBwZWRcbiAgICogKGVtcHR5IGA8Ym9keT5gLCBubyBgd2luZG93LmFwcGApLCB0aGUgdGVybWluYWwgc3RhdGUgd2hlbiB0aGUgYXNhciBjYW5ub3RcbiAgICogcnVuIG9uIHRoZSBsYXVuY2hlZCBFbGVjdHJvbiBzaGVsbC4gT25jZSB0aGF0IHN0YXRlIGhhcyBoZWxkIGZvciB0aGVcbiAgICogY29uZmlndXJlZCBncmFjZSB3aW5kb3cgaXQgdGhyb3dzIGEge0BsaW5rIFJlbmRlcmVyRmFpbGVkVG9Jbml0aWFsaXplRXJyb3J9XG4gICAqIGltbWVkaWF0ZWx5IGluc3RlYWQgb2Ygd2FpdGluZyBvdXQgdGhlIGZ1bGwgcmVhZGluZXNzIHRpbWVvdXQuIEEgZ3JhY2Ugb2ZcbiAgICogYDBgIGRpc2FibGVzIHRoZSBmYXN0LWZhaWwuIFRoZSBncmFjZSBjbG9jayBzdGFydHMgd2hlbiB0aGUgcmVuZGVyZXIgZmlyc3RcbiAgICogcmVwb3J0cyBgY29tcGxldGVgLCBzbyBhIHNsb3cgbG9hZCBiZWZvcmUgdGhlbiBpcyBuZXZlciBjb3VudGVkIGFnYWluc3QgaXQuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdmF1bHQgZm9sZGVyLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yT3duZWRWYXVsdFJlYWR5KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gV2FpdGluZyBmb3Igb3duZWQgdmF1bHQgdG8gYmVjb21lIHJlYWR5ICh0aW1lb3V0PSR7U3RyaW5nKFZBVUxUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMpfW1zKS4uLmApO1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIFZBVUxUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgbGV0IGRvY3VtZW50Q29tcGxldGVTaW5jZTogbnVsbCB8IG51bWJlciA9IG51bGw7XG4gICAgbGV0IGlzUmVhZHkgPSBmYWxzZTtcbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLmZpbmRUYXJnZXRGb3JWYXVsdCh2YXVsdFBhdGgpO1xuICAgICAgICBhd2FpdCB0aGlzLndhaXRGb3JMYXlvdXRSZWFkeSh2YXVsdFBhdGgpO1xuICAgICAgICBhd2FpdCB0aGlzLmRpc21pc3NUcnVzdERpYWxvZyh2YXVsdFBhdGgpO1xuICAgICAgICBpc1JlYWR5ID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gVGhlIHZhdWx0IGlzIG5vdCByZWFkeSB5ZXQgXHUyMDE0IGFsc28gZHJvcCB0aGUgY2FjaGVkIENEUCBjb25uZWN0aW9uIGJlZm9yZVxuICAgICAgICAvLyBSZXRyeWluZy4gT2xkIChFbGVjdHJvbiAxMC1lcmEpIE9ic2lkaWFuIHJlbG9hZHMgdGhlIG93bmVkIHdpbmRvdyBkdXJpbmdcbiAgICAgICAgLy8gQm9vdCwgd2hpY2ggY2FuIGxlYXZlIHRoZSBjYWNoZWQgV2ViU29ja2V0IHBpbm5lZCB0byBhIHN0YWxlIGV4ZWN1dGlvblxuICAgICAgICAvLyBDb250ZXh0OyByZWNvbm5lY3RpbmcgZWFjaCBhdHRlbXB0IHJlLWJpbmRzIHRvIHRoZSBsaXZlIGNvbnRleHQuXG4gICAgICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5kZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHMgPiAwKSB7XG4gICAgICAgIGNvbnN0IG9ic2VydmF0aW9uID0gYXdhaXQgdGhpcy5wcm9iZVJlbmRlcmVyQm9vdFN0YXRlKCk7XG4gICAgICAgIGlmIChvYnNlcnZhdGlvbikge1xuICAgICAgICAgIGlmIChvYnNlcnZhdGlvbi5pc0RvY3VtZW50Q29tcGxldGUgJiYgZG9jdW1lbnRDb21wbGV0ZVNpbmNlID09PSBudWxsKSB7XG4gICAgICAgICAgICBkb2N1bWVudENvbXBsZXRlU2luY2UgPSBEYXRlLm5vdygpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBoYXNHcmFjZUVsYXBzZWQgPSBkb2N1bWVudENvbXBsZXRlU2luY2UgIT09IG51bGxcbiAgICAgICAgICAgICYmIERhdGUubm93KCkgLSBkb2N1bWVudENvbXBsZXRlU2luY2UgPj0gdGhpcy5kZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHM7XG4gICAgICAgICAgaWYgKGNoZWNrUmVuZGVyZXJCb290U3RhdGUoeyAuLi5vYnNlcnZhdGlvbiwgaGFzR3JhY2VFbGFwc2VkIH0pID09PSAnZGVhZCcpIHtcbiAgICAgICAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIE93bmVkIHJlbmRlcmVyIGZhaWxlZCB0byBpbml0aWFsaXplIChkZWFkIGJvb3QpOyBmYWlsaW5nIGZhc3QuJyk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmVuZGVyZXJGYWlsZWRUb0luaXRpYWxpemVFcnJvcih2YXVsdFBhdGgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhd2FpdCBkZWxheShWQVVMVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgfVxuXG4gICAgaWYgKCFpc1JlYWR5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE93bmVkIHZhdWx0IGF0ICR7dmF1bHRQYXRofSBkaWQgbm90IGJlY29tZSByZWFkeSB3aXRoaW4gJHtTdHJpbmcoVkFVTFRfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXNgKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgdmF1bHQgaXMgcmVhZHkuIFJ1biB0aGUgcG9zdC1ib290IGNvbXBhdGliaWxpdHkgY2hlY2tzIGhlcmUgXHUyMDE0IE9VVFNJREUgdGhlXG4gICAgLy8gUG9sbCdzIHRyeS9jYXRjaCBcdTIwMTQgc28gYSBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvciBmYWlscyBmYXN0IGluc3RlYWQgb2YgYmVpbmdcbiAgICAvLyBTd2FsbG93ZWQgYXMgXCJub3QgcmVhZHkgeWV0XCIgYW5kIGxvb3BpbmcgdW50aWwgdGhlIHJlYWRpbmVzcyB0aW1lb3V0LlxuICAgIGF3YWl0IHRoaXMuY2hlY2tSdW50aW1lQ29tcGF0aWJpbGl0eSh2YXVsdFBhdGgpO1xuICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIE93bmVkIHZhdWx0IGlzIHJlYWR5LicpO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgZ2l2ZW4gZGVsYXkuXG4gKlxuICogQHBhcmFtIG1zIC0gVGhlIGRlbGF5IGluIG1pbGxpc2Vjb25kcy5cbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIHRoZSBkZWxheS5cbiAqL1xuZnVuY3Rpb24gZGVsYXkobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgcGxhdGZvcm0tc3BlY2lmaWMgY29tbWFuZCB0byBsYXVuY2ggT2JzaWRpYW4gd2l0aCByZW1vdGUgZGVidWdnaW5nIGVuYWJsZWQuXG4gKlxuICogUmVzb2x2ZXMgdGhlIGFjdHVhbCBpbnN0YWxsZWQgT2JzaWRpYW4gZXhlY3V0YWJsZSAoY292ZXJpbmcgaW5zdGFsbGVyLWJhc2VkXG4gKiBhbmQgYFBBVEhgLWJhc2VkIGluc3RhbGxzIHN1Y2ggYXMgYHNjb29wYCkgYW5kIHZlcmlmaWVzIGl0IGV4aXN0cyBiZWZvcmVcbiAqIHJldHVybmluZyBhIGNvbW1hbmQuIFRocm93cyBpZiBPYnNpZGlhbiBpcyBub3QgaW5zdGFsbGVkLlxuICpcbiAqIEBwYXJhbSBwb3J0IC0gVGhlIENEUCBwb3J0IHRvIHVzZS5cbiAqIEByZXR1cm5zIFRoZSBzaGVsbCBjb21tYW5kIHN0cmluZy5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgT2JzaWRpYW4gY2Fubm90IGJlIGxvY2F0ZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldE9ic2lkaWFuTGF1bmNoQ29tbWFuZChwb3J0OiBudW1iZXIpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBleGVQYXRoID0gYXdhaXQgcmVzb2x2ZU9ic2lkaWFuRXhlY3V0YWJsZSgpO1xuICBjb25zdCBmbGFnID0gYC0tcmVtb3RlLWRlYnVnZ2luZy1wb3J0PSR7U3RyaW5nKHBvcnQpfWA7XG5cbiAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicpIHtcbiAgICByZXR1cm4gYHN0YXJ0IFwiXCIgXCIke2V4ZVBhdGh9XCIgJHtmbGFnfWA7XG4gIH1cblxuICByZXR1cm4gYFwiJHtleGVQYXRofVwiICR7ZmxhZ30gJmA7XG59XG5cbi8qKlxuICogQXR0ZW1wdHMgdG8gcmVtb3ZlIGEgZGlyZWN0b3J5IHJlY3Vyc2l2ZWx5LCByZXR1cm5pbmcgd2hldGhlciBpdCBzdWNjZWVkZWQuXG4gKlxuICogQHBhcmFtIGRpciAtIFRoZSBkaXJlY3RvcnkgdG8gcmVtb3ZlLlxuICogQHJldHVybnMgYHRydWVgIGlmIHJlbW92ZWQsIGBmYWxzZWAgaWYgdGhlIHJlbW92YWwgdGhyZXcgKGUuZy4gaGFuZGxlcyBoZWxkKS5cbiAqL1xuZnVuY3Rpb24gdHJ5UmVtb3ZlRGlyKGRpcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgcm1TeW5jKGRpciwgeyBmb3JjZTogdHJ1ZSwgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJt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
|
|
954
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1kZXNrdG9wLWNkcC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIERlc2t0b3AgQ0RQIHRyYW5zcG9ydCBcdTIwMTQgZXZhbHVhdGVzIGV4cHJlc3Npb25zIHZpYSBDaHJvbWUgRGV2VG9vbHMgUHJvdG9jb2xcbiAqIG92ZXIgV2ViU29ja2V0IGFuZCBtYW5hZ2VzIHZhdWx0cyB2aWEgRWxlY3Ryb24gSVBDLlxuICpcbiAqIFR3byBtb2RlczpcbiAqIC0gKipPd25lZCAoZGVmYXVsdCkqKjogdGhlIHRyYW5zcG9ydCBsYXVuY2hlcyBhbmQgb3ducyBhbiBpc29sYXRlZCBPYnNpZGlhblxuICogICBpbnN0YW5jZSBhZ2FpbnN0IGEgdGVtcG9yYXJ5IGAtLXVzZXItZGF0YS1kaXJlY3RvcnlgIG9uIGEgZnJlZSBgLS1yZW1vdGUtZGVidWdnaW5nLXBvcnRgLFxuICogICBuZXZlciB0b3VjaGluZyB0aGUgdXNlcidzIE9ic2lkaWFuLiBTdXBwb3J0cyB2ZXJzaW9uIHBpbm5pbmcgdmlhIHRoZSB1c2VyLWRhdGEgYXNhci5cbiAqIC0gKipBdHRhY2gqKjogd2hlbiBhbiBleHBsaWNpdCBDRFAgcG9ydCBpcyBjb25maWd1cmVkLCB0aGUgdHJhbnNwb3J0IGNvbm5lY3RzXG4gKiAgIHRvIGFuIGFscmVhZHktcnVubmluZyBPYnNpZGlhbiBvbiB0aGF0IHBvcnQuXG4gKlxuICogSXQgY29ubmVjdHMgdG8gcGFnZSB0YXJnZXRzLCBzZW5kcyBgUnVudGltZS5ldmFsdWF0ZWAgY29tbWFuZHMsIGFuZCByb3V0ZXMgdG9cbiAqIHRoZSBjb3JyZWN0IHZhdWx0IHRhcmdldCB1c2luZyBgZ2V0QmFzZVBhdGgoKWAgcHJvYmluZy5cbiAqXG4gKiBSZXF1aXJlbWVudHM6IE5vZGUuanMgMjIrICh1c2VzIGJ1aWx0LWluIGBXZWJTb2NrZXRgIGFuZCBgZmV0Y2hgIGdsb2JhbHMpLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGNvZGUgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtcbiAgbWtkaXJTeW5jLFxuICBybVN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbmltcG9ydCB0eXBlIHsgQXNhckZhbGxiYWNrIH0gZnJvbSAnLi9hc2FyLWZhbGxiYWNrLWRldGVjdGlvbi5tanMnO1xuaW1wb3J0IHR5cGUgeyBFbGVjdHJvbkNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2VsZWN0cm9uLWNvbXBhdGliaWxpdHkubWpzJztcbmltcG9ydCB0eXBlIHsgSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSB9IGZyb20gJy4vaW5zdGFsbGVyLWNvbXBhdGliaWxpdHkubWpzJztcbmltcG9ydCB0eXBlIHsgT3duZWRPYnNpZGlhbkluc3RhbmNlIH0gZnJvbSAnLi9vYnNpZGlhbi1pbnN0YW5jZS5tanMnO1xuaW1wb3J0IHR5cGUgeyBSZW5kZXJlckJvb3RPYnNlcnZhdGlvbiB9IGZyb20gJy4vcmVuZGVyZXItYm9vdC1kZXRlY3Rpb24ubWpzJztcbmltcG9ydCB0eXBlIHtcbiAgT2JzaWRpYW5UcmFuc3BvcnQsXG4gIFRyYW5zcG9ydEV2YWxPcHRpb25zXG59IGZyb20gJy4vdHJhbnNwb3J0Lm1qcyc7XG5cbmltcG9ydCB7IHJlc29sdmVBc2FyRmFsbGJhY2sgfSBmcm9tICcuL2FzYXItZmFsbGJhY2stZGV0ZWN0aW9uLm1qcyc7XG5pbXBvcnQgeyByZXNvbHZlQXNhckZhbGxiYWNrQWN0aW9uIH0gZnJvbSAnLi9jb21wYXRpYmlsaXR5LW9wdGlvbnMubWpzJztcbmltcG9ydCB7IERJU01JU1NfVFJVU1RfRElBTE9HX0VYUFIgfSBmcm9tICcuL2Rpc21pc3MtdHJ1c3QtZGlhbG9nLm1qcyc7XG5pbXBvcnQgeyByZXNvbHZlRWxlY3Ryb25Db21wYXRpYmlsaXR5IH0gZnJvbSAnLi9lbGVjdHJvbi1jb21wYXRpYmlsaXR5Lm1qcyc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAnLi9leGVjLm1qcyc7XG5pbXBvcnQgeyBsb2cgfSBmcm9tICcuL2xvZy5tanMnO1xuaW1wb3J0IHsgZW5zdXJlTmFtZXNwYWNlQm9vdHN0cmFwcGVkIH0gZnJvbSAnLi9uYW1lc3BhY2UtYm9vdHN0cmFwLm1qcyc7XG5pbXBvcnQge1xuICBkaWRSZW1vdmVWYXVsdEZyb21Db25maWcsXG4gIGdldFZhdWx0SWQsXG4gIGlzVmF1bHRSZWdpc3RlcmVkXG59IGZyb20gJy4vb2JzaWRpYW4tY29uZmlnLm1qcyc7XG5pbXBvcnQgeyByZXNvbHZlT2JzaWRpYW5FeGVjdXRhYmxlIH0gZnJvbSAnLi9vYnNpZGlhbi1leGVjdXRhYmxlLm1qcyc7XG5pbXBvcnQgeyBsYXVuY2hPd25lZE9ic2lkaWFuSW5zdGFuY2UgfSBmcm9tICcuL29ic2lkaWFuLWluc3RhbmNlLm1qcyc7XG5pbXBvcnQgeyBnZXRWZXJzaW9uTWV0YWRhdGEgfSBmcm9tICcuL29ic2lkaWFuLW1ldGFkYXRhLm1qcyc7XG5pbXBvcnQgeyBjb3B5QXNhckludG9Vc2VyRGF0YSB9IGZyb20gJy4vb2JzaWRpYW4tdmVyc2lvbi1zd2l0Y2gubWpzJztcbmltcG9ydCB7IGJ1aWxkT3duZWRPYnNpZGlhbkpzb24gfSBmcm9tICcuL293bmVkLXZhdWx0LXNlZWQubWpzJztcbmltcG9ydCB7IGJ1aWxkUGFyZW50TGl2ZW5lc3NXYXRjaGRvZ0V4cHJlc3Npb24gfSBmcm9tICcuL3BhcmVudC1saXZlbmVzcy5tanMnO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9ERUFEX0JPT1RfR1JBQ0VfSU5fTUlMTElTRUNPTkRTLFxuICByZXNvbHZlUmVuZGVyZXJCb290U3RhdGVcbn0gZnJvbSAnLi9yZW5kZXJlci1ib290LWRldGVjdGlvbi5tanMnO1xuaW1wb3J0IHsgUmVuZGVyZXJGYWlsZWRUb0luaXRpYWxpemVFcnJvciB9IGZyb20gJy4vcmVuZGVyZXItZmFpbGVkLXRvLWluaXRpYWxpemUtZXJyb3IubWpzJztcbmltcG9ydCB7IFNpbGVudEFzYXJGYWxsYmFja0Vycm9yIH0gZnJvbSAnLi9zaWxlbnQtYXNhci1mYWxsYmFjay1lcnJvci5tanMnO1xuaW1wb3J0IHsgZW5zdXJlTm9uTnVsbGFibGUgfSBmcm9tICcuL3R5cGUtZ3VhcmRzLm1qcyc7XG5pbXBvcnQgeyBhcmVWYXVsdFBhdGhzTWF0Y2hpbmcgfSBmcm9tICcuL3ZhdWx0LXBhdGgtbWF0Y2gubWpzJztcbmltcG9ydCB7XG4gIHJlc29sdmVPd25lZEhpZGRlbkxhdW5jaEFyZ3VtZW50cyxcbiAgcmVzb2x2ZVNhbmRib3hMYXVuY2hBcmd1bWVudHMsXG4gIHNob3VsZEhpZGVPYnNpZGlhbkFwcFxufSBmcm9tICcuL3Zpc2liaWxpdHkubWpzJztcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciB0aGUgQ0RQIHRyYW5zcG9ydC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZXNrdG9wQ2RwVHJhbnNwb3J0Q29uZmlnIHtcbiAgLyoqXG4gICAqIENEUCBob3N0LiBEZWZhdWx0cyB0byBgJ2xvY2FsaG9zdCdgLlxuICAgKi9cbiAgY2RwSG9zdD86IHN0cmluZztcblxuICAvKipcbiAgICogQ0RQIHBvcnQgZm9yICoqYXR0YWNoKiogbW9kZSAodGhlIGAtLXJlbW90ZS1kZWJ1Z2dpbmctcG9ydGAgdGhlIHJ1bm5pbmdcbiAgICogT2JzaWRpYW4gd2FzIGxhdW5jaGVkIHdpdGgpLiBJbiBvd25lZC1pbnN0YW5jZSBtb2RlIHRoaXMgaXMgaWdub3JlZCBcdTIwMTQgYVxuICAgKiBmcmVlIHBvcnQgaXMgY2hvc2VuIGF0IGxhdW5jaC5cbiAgICovXG4gIGNkcFBvcnQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciBpbmRpdmlkdWFsIENEUCBjb21tYW5kcy5cbiAgICogRGVmYXVsdHMgdG8gYDMwMDAwYC5cbiAgICovXG4gIGNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEdyYWNlIHdpbmRvdyBpbiBtaWxsaXNlY29uZHMgZm9yIGZhc3QtZmFpbGluZyBhIGRlYWQgYm9vdCBvZiB0aGUgb3duZWRcbiAgICogaW5zdGFuY2UgKGVtcHR5IGA8Ym9keT5gIHdpdGggbm8gYHdpbmRvdy5hcHBgIGFmdGVyIHRoZSByZW5kZXJlciByZWFjaGVkXG4gICAqIGBkb2N1bWVudC5yZWFkeVN0YXRlYCBgJ2NvbXBsZXRlJ2ApLiBEZWZhdWx0cyB0b1xuICAgKiB7QGxpbmsgREVGQVVMVF9ERUFEX0JPT1RfR1JBQ0VfSU5fTUlMTElTRUNPTkRTfS4gYDBgIGRpc2FibGVzIGZhc3QtZmFpbC5cbiAgICovXG4gIGRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogV2hlbiBhdHRhY2hpbmcgKGkuZS4ge0BsaW5rIGNkcFBvcnR9IGlzIHNldCksIG1hcmtzIHRoZSB0YXJnZXQgYXMgYVxuICAgKiAqKmhhcm5lc3Mtb3duZWQsIGFscmVhZHktcHJlcGFyZWQqKiBpbnN0YW5jZS4gU3VwcHJlc3NlcyB0aGUgdXNlci1zY29wZVxuICAgKiB2YXVsdC1yZWdpc3RyYXRpb24gcHJlZmxpZ2h0LCBzaW5jZSB0aGUgb3duZWQgaW5zdGFuY2UncyB2YXVsdCBsaXZlcyBpbiBhblxuICAgKiBpc29sYXRlZCB1c2VyLWRhdGEgY29uZmlnIHJhdGhlciB0aGFuIHRoZSB1c2VyLXNjb3BlIHJlZ2lzdHJ5LlxuICAgKi9cbiAgaXNIYXJuZXNzT3duZWRJbnN0YW5jZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIG93bmVkIE9ic2lkaWFuIHdpbmRvdyBpcyBzaG93biBvbiBzY3JlZW4uIFdoZW4gYGZhbHNlYCAodGhlXG4gICAqIGRlZmF1bHQpLCB0aGUgb3duZWQgaW5zdGFuY2UgaXMgbGF1bmNoZWQgd2l0aCBrZWVwLWFsaXZlIENocm9taXVtIGZsYWdzIGFuZFxuICAgKiBpdHMgd2luZG93IGlzIG1vdmVkIG9mZi1zY3JlZW4gYWZ0ZXIgbGF1bmNoLiBPbmx5IG1lYW5pbmdmdWwgaW4gb3duZWQgbW9kZTtcbiAgICogYXR0YWNoIG1vZGUgbmV2ZXIgdG91Y2hlcyB0aGUgKHVzZXIncykgd2luZG93LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdHJ1ZWBcbiAgICovXG4gIGlzT2JzaWRpYW5BcHBWaXNpYmxlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hlbiBzZXQsIHRoZSB0cmFuc3BvcnQgbGF1bmNoZXMgYW5kIG93bnMgYW4gaXNvbGF0ZWQgT2JzaWRpYW4gaW5zdGFuY2VcbiAgICogaW5zdGVhZCBvZiBhdHRhY2hpbmcgdG8gYSBydW5uaW5nIG9uZS4gVGhpcyBpcyB0aGUgZGVmYXVsdCBkZXNrdG9wIG1vZGUuXG4gICAqL1xuICBvd25lZEluc3RhbmNlPzogT3duZWRJbnN0YW5jZUNvbmZpZztcblxuICAvKipcbiAgICogV2hldGhlciB0byBsYXVuY2ggdGhlIG93bmVkIGluc3RhbmNlIHdpdGggQ2hyb21pdW0ncyBzYW5kYm94IGRpc2FibGVkXG4gICAqIChgLS1uby1zYW5kYm94YCkuIE5lZWRlZCB0byBib290IG9uIExpbnV4IHdpdGhvdXQgYSBjb3JyZWN0bHktY29uZmlndXJlZFxuICAgKiBzZXR1aWQgYGNocm9tZS1zYW5kYm94YCBoZWxwZXIgKGUuZy4gYW4gZXh0cmFjdGVkIHBvcnRhYmxlIHNoZWxsLCBvciBDSSBhcyBhXG4gICAqIG5vbi1yb290IHVzZXIpOyBoYXJtbGVzcyBvbiBXaW5kb3dzL21hY09TLiBPbmx5IG1lYW5pbmdmdWwgaW4gb3duZWQgbW9kZS5cbiAgICpcbiAgICogQGRlZmF1bHQgYGZhbHNlYFxuICAgKi9cbiAgc2hvdWxkRGlzYWJsZVNhbmRib3g/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGEgcG9zdC1ib290ICoqc2lsZW50IGFzYXIgZmFsbGJhY2sqKiAodGhlIHJ1bm5pbmcgYXBwIHZlcnNpb24gZGlmZmVyc1xuICAgKiBmcm9tIHRoZSBzd2FwcGVkLWluIHBpbikgZmFpbHMgZmFzdCB3aXRoIHtAbGluayBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvcn0uIFRoZVxuICAgKiB2ZXJkaWN0IGlzIGFsd2F5cyBjb21wdXRlZCBhbmQgc3VyZmFjZWQgdmlhXG4gICAqIHtAbGluayBEZXNrdG9wQ2RwVHJhbnNwb3J0LmdldEFzYXJGYWxsYmFja307IHRoaXMgZ2F0ZXMgb25seSB0aGUgdGhyb3cuIE9ubHlcbiAgICogbWVhbmluZ2Z1bCBpbiBvd25lZCBtb2RlIHJ1bm5pbmcgYSBzd2FwcGVkLWluIGFzYXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgc2hvdWxkVGhyb3dPblNpbGVudEFzYXJGYWxsYmFjaz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHBvc3QtYm9vdCBydW50aW1lLUVsZWN0cm9uIGNvbXBhdGliaWxpdHkgbmFnIHdhcm5pbmcgaXMgZW1pdHRlZFxuICAgKiB3aGVuIHRoZSBsaXZlIEVsZWN0cm9uIGlzIGJlbG93IHRoZSBhcHAncyByZWNvbW1lbmRlZCBtaW5pbXVtLiBUaGUgdmVyZGljdCBpc1xuICAgKiBhbHdheXMgY29tcHV0ZWQgYW5kIHN1cmZhY2VkIHZpYSB7QGxpbmsgRGVza3RvcENkcFRyYW5zcG9ydC5nZXRFbGVjdHJvbkNvbXBhdGliaWxpdHl9O1xuICAgKiB0aGlzIG9ubHkgZ2F0ZXMgdGhlIGxvZy4gT25seSBtZWFuaW5nZnVsIGluIG93bmVkIG1vZGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3Vlcz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQW4gYXNhciB0byBwcm92aXNpb24gaW50byBhIGhhcm5lc3Mtb3duZWQgaW5zdGFuY2UncyB1c2VyLWRhdGEgZGlyZWN0b3J5IGJlZm9yZSBsYXVuY2guXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3duZWRJbnN0YW5jZUFzYXIge1xuICAvKipcbiAgQWJzb2x1dGUgcGF0aCB0byB0aGUgY2FjaGVkL3NvdXJjZSBhc2FyIGZpbGUuXG4gICAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBhc2FyJ3MgYHgueS56YCB2ZXJzaW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbjogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIGEgaGFybmVzcy1vd25lZCwgaXNvbGF0ZWQgT2JzaWRpYW4gaW5zdGFuY2UuXG4gKlxuICogV2hlbiBwcmVzZW50LCB0aGUgdHJhbnNwb3J0IGxhdW5jaGVzIGFuZCBvd25zIGl0cyBvd24gT2JzaWRpYW4gcHJvY2Vzc1xuICogYWdhaW5zdCBhbiBpc29sYXRlZCB1c2VyLWRhdGEgZGlyZWN0b3J5IGluc3RlYWQgb2YgYXR0YWNoaW5nIHRvIGEgcnVubmluZyBpbnN0YW5jZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPd25lZEluc3RhbmNlQ29uZmlnIHtcbiAgLyoqXG4gIE9wdGlvbmFsIGFzYXIgdG8gcHJvdmlzaW9uIGludG8ge0BsaW5rIHVzZXJEYXRhRGlyZWN0b3J5fSBiZWZvcmUgbGF1bmNoLlxuICAgKi9cbiAgcmVhZG9ubHkgYXNhcj86IE93bmVkSW5zdGFuY2VBc2FyIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVzb2x2ZWQgaW5zdGFsbGVyXHUyMTk0YXBwIGNvbXBhdGliaWxpdHkgdmVyZGljdCwgd2hlbiBpdCBjb3VsZCBiZSBkZXRlcm1pbmVkXG4gICAqIChhbiBhc2FyLXN3YXAgb250byBhIGtub3duIHNoZWxsIHZlcnNpb24pLiBTdXJmYWNlZCBieVxuICAgKiB7QGxpbmsgRGVza3RvcENkcFRyYW5zcG9ydC5nZXRDb21wYXRpYmlsaXR5fS4gQW4gYCd1bnJ1bm5hYmxlJ2AgdmVyZGljdCByZWFjaGVzXG4gICAqIHRoaXMgc3VyZmFjZSBvbmx5IHdoZW4gdGhlIHByb2FjdGl2ZSB0aHJvdyBpcyBkaXNhYmxlZFxuICAgKiAoYHNob3VsZFRocm93T25JbmNvbXBhdGlibGVJbnN0YWxsZXI6IGZhbHNlYCk7IG90aGVyd2lzZSBpdCB0aHJvd3NcbiAgICogYEluY29tcGF0aWJsZUluc3RhbGxlclZlcnNpb25FcnJvcmAgYmVmb3JlIHRoZSBjb25maWcgaXMgYnVpbHQuXG4gICAqL1xuICByZWFkb25seSBjb21wYXRpYmlsaXR5PzogSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgQWJzb2x1dGUgcGF0aCB0byB0aGUgT2JzaWRpYW4gc2hlbGwgZXhlY3V0YWJsZSB0byBsYXVuY2guXG4gICAqL1xuICByZWFkb25seSBleGVQYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFic29sdXRlIHBhdGggdG8gdGhlIGlzb2xhdGVkIHVzZXItZGF0YSBkaXJlY3RvcnkuIENyZWF0ZWQgYW5kIG93bmVkIGJ5IHRoZVxuICAgKiB0cmFuc3BvcnQsIGFuZCBkZWxldGVkIG9uIGRpc3Bvc2UuXG4gICAqL1xuXG4gIHJlYWRvbmx5IHVzZXJEYXRhRGlyZWN0b3J5OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBDZHBFeGNlcHRpb25EZXRhaWxzIHtcbiAgZXhjZXB0aW9uPzogQ2RwRXhjZXB0aW9uT2JqZWN0O1xuICB0ZXh0OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBDZHBFeGNlcHRpb25PYmplY3Qge1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIENkcFJlc3BvbnNlIHtcbiAgaWQ6IG51bWJlcjtcbiAgcmVzdWx0PzogQ2RwUmVzcG9uc2VSZXN1bHQ7XG59XG5cbmludGVyZmFjZSBDZHBSZXNwb25zZVJlc3VsdCB7XG4gIHJlYWRvbmx5IGV4Y2VwdGlvbkRldGFpbHM/OiBDZHBFeGNlcHRpb25EZXRhaWxzO1xuICByZWFkb25seSByZXN1bHQ/OiBDZHBWYWx1ZTtcbn1cblxuaW50ZXJmYWNlIENkcFRhcmdldCB7XG4gIGlkOiBzdHJpbmc7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIHR5cGU6IHN0cmluZztcbiAgdXJsOiBzdHJpbmc7XG4gIHdlYlNvY2tldERlYnVnZ2VyVXJsOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBDZHBWYWx1ZSB7XG4gIHR5cGU6IHN0cmluZztcbiAgdmFsdWU/OiB1bmtub3duO1xufVxuXG4vKipcbiAqIFRoZSBDRFAgZW5kcG9pbnQgb2YgYSBsYXVuY2hlZCwgaGFybmVzcy1vd25lZCBpbnN0YW5jZS5cbiAqL1xuaW50ZXJmYWNlIE93bmVkSW5zdGFuY2VFbmRwb2ludCB7XG4gIC8qKlxuICBDRFAgaG9zdCAoZS5nLiBgJ2xvY2FsaG9zdCdgKS5cbiAgICovXG4gIHJlYWRvbmx5IGhvc3Q6IHN0cmluZztcblxuICAvKipcbiAgVGhlIGZyZWUgQ0RQIHBvcnQgdGhlIG93bmVkIGluc3RhbmNlIHdhcyBsYXVuY2hlZCBvbi5cbiAgICovXG4gIHJlYWRvbmx5IHBvcnQ6IG51bWJlcjtcbn1cblxuY29uc3QgQ09NTUFORF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDMwXzAwMDtcbmNvbnN0IFZBVUxUX0lEX0JZVEVfTEVOR1RIID0gODtcbmNvbnN0IFVTRVJfREFUQV9STV9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDEwXzAwMDtcbmNvbnN0IFVTRVJfREFUQV9STV9SRVRSWV9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSA1MDA7XG5jb25zdCBOT19PVVRQVVQgPSAnKG5vIG91dHB1dCknO1xuY29uc3QgVkFVTFRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSA1MDA7XG5jb25zdCBWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMzBfMDAwO1xuLy8gT2xkIChFbGVjdHJvbiAxMC1lcmEpIE9ic2lkaWFuIG9jY2FzaW9uYWxseSBib290cyB3aXRob3V0IHRoZSB3b3Jrc3BhY2UgZXZlclxuLy8gSW5pdGlhbGl6aW5nLCBzbyB0aGUgdmF1bHQgbmV2ZXIgYmVjb21lcyByZWFkeS4gQSBmcmVzaCBpbnN0YW5jZSBpcyBhblxuLy8gSW5kZXBlbmRlbnQgY2hhbmNlOyByZWxhdW5jaCB1cCB0byB0aGlzIG1hbnkgdGltZXMgYmVmb3JlIGdpdmluZyB1cC5cbmNvbnN0IE9XTkVEX0xBVU5DSF9NQVhfQVRURU1QVFMgPSAzO1xuLy8gQnJpZWYgc2V0dGxlIGJlZm9yZSBhIHJlbGF1bmNoIHNvIHRoZSBraWxsZWQgaW5zdGFuY2UncyBtZW1vcnkvaGFuZGxlcyBhcmVcbi8vIFJlY2xhaW1lZCBiZWZvcmUgdGhlIG5leHQgYm9vdCBcdTIwMTQgaW1wcm92ZXMgdGhlIG9kZHMgb24gYSBsb2FkZWQgbWFjaGluZS5cbmNvbnN0IE9XTkVEX1JFTEFVTkNIX1NFVFRMRV9JTl9NSUxMSVNFQ09ORFMgPSAzMDAwO1xuY29uc3QgVkFVTFRfQ0xPU0VfREVMQVlfSU5fTUlMTElTRUNPTkRTID0gMTAwMDtcbmNvbnN0IEFVVE9fU1RBUlRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSAyMDAwO1xuY29uc3QgQVVUT19TVEFSVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDMwXzAwMDtcbmNvbnN0IElOU1RBTkNFX0VYSVRfU0VUVExFX0RFTEFZX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IE9XTkVEX1dJTkRPV19PRkZTQ1JFRU5fTUFSR0lOX0lOX1BJWEVMUyA9IDIwMDtcbmNvbnN0IE9XTkVEX1dJTkRPV19ISURFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMjBfMDAwO1xuY29uc3QgT1dORURfV0lORE9XX0hJREVfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSAyNTA7XG5cbi8qKlxuICogVHJhbnNwb3J0IHRoYXQgY29tbXVuaWNhdGVzIHdpdGggRGVza3RvcCBPYnNpZGlhbiB2aWEgQ2hyb21lIERldlRvb2xzIFByb3RvY29sLlxuICpcbiAqIENvbm5lY3RzIHRvIE9ic2lkaWFuJ3MgQ0RQIFdlYlNvY2tldCBlbmRwb2ludCwgc2VuZHMgYFJ1bnRpbWUuZXZhbHVhdGVgXG4gKiBjb21tYW5kcywgYW5kIHJvdXRlcyBleHByZXNzaW9ucyB0byB0aGUgY29ycmVjdCB2YXVsdCB0YXJnZXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBEZXNrdG9wQ2RwVHJhbnNwb3J0IGltcGxlbWVudHMgT2JzaWRpYW5UcmFuc3BvcnQge1xuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyB0cmFuc3BvcnQgaXMgZm9yIGEgbW9iaWxlIHBsYXRmb3JtLiBBbHdheXMgYGZhbHNlYCBmb3IgdGhpcyB0cmFuc3BvcnQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaXNNb2JpbGUgPSBmYWxzZTtcbiAgcHJpdmF0ZSBhY3RpdmVWYXVsdFBhdGg6IG51bGwgfCBzdHJpbmcgPSBudWxsO1xuICBwcml2YXRlIGFzYXJGYWxsYmFjazogQXNhckZhbGxiYWNrIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkcEhvc3Q6IHN0cmluZztcbiAgcHJpdmF0ZSBjZHBQb3J0OiBudW1iZXI7XG4gIHByaXZhdGUgY2RwVXJsOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuICBwcml2YXRlIGVsZWN0cm9uQ29tcGF0aWJpbGl0eTogRWxlY3Ryb25Db21wYXRpYmlsaXR5IHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IGlzSGFybmVzc093bmVkSW5zdGFuY2U6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgaXNPYnNpZGlhbkFwcFZpc2libGU6IGJvb2xlYW47XG4gIHByaXZhdGUgbWVzc2FnZUlkID0gMDtcbiAgcHJpdmF0ZSByZWFkb25seSBvd25lZENvbmZpZzogT3duZWRJbnN0YW5jZUNvbmZpZyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBvd25lZEluc3RhbmNlOiBPd25lZE9ic2lkaWFuSW5zdGFuY2UgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2hvdWxkRGlzYWJsZVNhbmRib3g6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgc2hvdWxkVGhyb3dPblNpbGVudEFzYXJGYWxsYmFjazogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSBzaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzOiBib29sZWFuO1xuICBwcml2YXRlIHdzOiBudWxsIHwgV2ViU29ja2V0ID0gbnVsbDtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBDRFAgdHJhbnNwb3J0LlxuICAgKlxuICAgKiBAcGFyYW0gY29uZmlnIC0gQ0RQIGNvbm5lY3Rpb24gY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihjb25maWc/OiBEZXNrdG9wQ2RwVHJhbnNwb3J0Q29uZmlnKSB7XG4gICAgLy8gRGVzdHJ1Y3R1cmUgd2l0aCBwZXItZmllbGQgZGVmYXVsdHMgKGVhY2ggYXBwbGllcyB3aGVuIHRoZSBmaWVsZCBpcyBvbWl0dGVkLFxuICAgIC8vIEV4YWN0bHkgbGlrZSB0aGUgZm9ybWVyIGBjb25maWc/LnggPz8gZGVmYXVsdGApIHNvIHRoZSBjb25zdHJ1Y3RvciBzdGF5c1xuICAgIC8vIFVuZGVyIHRoZSBjeWNsb21hdGljLWNvbXBsZXhpdHkgbGltaXQgYXMgZmllbGRzIGFyZSBhZGRlZC5cbiAgICBjb25zdCB7XG4gICAgICBjZHBIb3N0ID0gJ2xvY2FsaG9zdCcsXG4gICAgICBjZHBQb3J0LFxuICAgICAgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IENPTU1BTkRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMsXG4gICAgICBkZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHMgPSBERUZBVUxUX0RFQURfQk9PVF9HUkFDRV9JTl9NSUxMSVNFQ09ORFMsXG4gICAgICBpc0hhcm5lc3NPd25lZEluc3RhbmNlID0gZmFsc2UsXG4gICAgICBpc09ic2lkaWFuQXBwVmlzaWJsZSA9IHRydWUsXG4gICAgICBvd25lZEluc3RhbmNlLFxuICAgICAgc2hvdWxkRGlzYWJsZVNhbmRib3ggPSBmYWxzZSxcbiAgICAgIHNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2sgPSB0cnVlLFxuICAgICAgc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlcyA9IHRydWVcbiAgICB9ID0gY29uZmlnID8/IHt9O1xuICAgIHRoaXMuY2RwSG9zdCA9IGNkcEhvc3Q7XG4gICAgdGhpcy5jb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzID0gY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcztcbiAgICB0aGlzLmRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kcyA9IGRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kcztcbiAgICB0aGlzLmlzSGFybmVzc093bmVkSW5zdGFuY2UgPSBpc0hhcm5lc3NPd25lZEluc3RhbmNlO1xuICAgIHRoaXMuaXNPYnNpZGlhbkFwcFZpc2libGUgPSBpc09ic2lkaWFuQXBwVmlzaWJsZTtcbiAgICB0aGlzLm93bmVkQ29uZmlnID0gb3duZWRJbnN0YW5jZTtcbiAgICB0aGlzLnNob3VsZERpc2FibGVTYW5kYm94ID0gc2hvdWxkRGlzYWJsZVNhbmRib3g7XG4gICAgdGhpcy5zaG91bGRUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrID0gc2hvdWxkVGhyb3dPblNpbGVudEFzYXJGYWxsYmFjaztcbiAgICB0aGlzLnNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXMgPSBzaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzO1xuICAgIC8vIE93bmVkIG1vZGUgcGlja3MgYSBmcmVlIHBvcnQgYXQgbGF1bmNoIChhc3NpZ25lZCBpbiByZWdpc3RlclZhdWx0KS5cbiAgICAvLyBBdHRhY2ggbW9kZSBjb25uZWN0cyB0byB0aGUgY29uZmlndXJlZCBwb3J0OyBubyBwb3J0IGlzIGhhcmRjb2RlZC5cbiAgICB0aGlzLmNkcFBvcnQgPSBjZHBQb3J0ID8/IDA7XG4gICAgdGhpcy5jZHBVcmwgPSBjZHBQb3J0ID09PSB1bmRlZmluZWQgPyAnJyA6IGBodHRwOi8vJHtjZHBIb3N0fToke1N0cmluZyhjZHBQb3J0KX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3Bvc2VzIG9mIHRoZSBhY3RpdmUgV2ViU29ja2V0IGNvbm5lY3Rpb24gYW5kLCBpbiBvd25lZC1pbnN0YW5jZSBtb2RlLFxuICAgKiBraWxscyB0aGUgb3duZWQgT2JzaWRpYW4gcHJvY2VzcyBhbmQgcmVtb3ZlcyBpdHMgaXNvbGF0ZWQgdXNlci1kYXRhIGRpcmVjdG9yeS5cbiAgICpcbiAgICogVGhlIHJlbW92YWwgaXMgcmV0cmllZCBiZWNhdXNlIFdpbmRvd3MgYnJpZWZseSBob2xkcyB0aGUganVzdC1raWxsZWRcbiAgICogcHJvY2VzcydzIGZpbGUgaGFuZGxlcywgd2hpY2ggd291bGQgb3RoZXJ3aXNlIGZhaWwgYHJtU3luY2Agd2l0aCBgRVBFUk1gLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgaWYgKCF0aGlzLm93bmVkQ29uZmlnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5vd25lZEluc3RhbmNlPy5raWxsKCk7XG4gICAgY29uc3QgeyB1c2VyRGF0YURpcmVjdG9yeSB9ID0gdGhpcy5vd25lZENvbmZpZztcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBVU0VSX0RBVEFfUk1fVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgaWYgKGRpZFJlbW92ZURpcmVjdG9yeSh1c2VyRGF0YURpcmVjdG9yeSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYXdhaXQgZGVsYXkoVVNFUl9EQVRBX1JNX1JFVFJZX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgfVxuICAgIGlmICghZGlkUmVtb3ZlRGlyZWN0b3J5KHVzZXJEYXRhRGlyZWN0b3J5KSkge1xuICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gQ291bGQgbm90IHJlbW92ZSBvd25lZCB1c2VyLWRhdGEgZGlyZWN0b3J5IHdpdGhpbiAke1N0cmluZyhVU0VSX0RBVEFfUk1fVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMpfW1zIChub24tZmF0YWwpOiAke3VzZXJEYXRhRGlyZWN0b3J5fWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTeW5jaHJvbm91cyBkaXNwb3NhbCBcdTIwMTQga2lsbHMgdGhlIG93bmVkIGluc3RhbmNlIGFuZCBtYWtlcyBhIGJlc3QtZWZmb3J0XG4gICAqIHJlbW92YWwgb2YgaXRzIHVzZXItZGF0YSBkaXJlY3RvcnkuIFNhZmUgdG8gY2FsbCBmcm9tIGEgcHJvY2VzcyBgZXhpdGAgaGFuZGxlclxuICAgKiAod2hlcmUgYXN5bmMgcmV0cmllcyBhcmUgaW1wb3NzaWJsZTsgYSBsZWZ0b3ZlciB0ZW1wIGRpcmVjdG9yeSBpcyBhY2NlcHRhYmxlKS5cbiAgICovXG4gIHB1YmxpYyBkaXNwb3NlU3luYygpOiB2b2lkIHtcbiAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcbiAgICBpZiAodGhpcy5vd25lZENvbmZpZykge1xuICAgICAgdGhpcy5vd25lZEluc3RhbmNlPy5raWxsKCk7XG4gICAgICBpZiAoIWRpZFJlbW92ZURpcmVjdG9yeSh0aGlzLm93bmVkQ29uZmlnLnVzZXJEYXRhRGlyZWN0b3J5KSkge1xuICAgICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBPd25lZCB1c2VyLWRhdGEgZGlyZWN0b3J5IG5vdCByZW1vdmVkIHN5bmNocm9ub3VzbHkgKHByb2Nlc3MgbWF5IHN0aWxsIGhvbGQgaGFuZGxlcyk6ICR7dGhpcy5vd25lZENvbmZpZy51c2VyRGF0YURpcmVjdG9yeX1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXZhbHVhdGVzIGEgSmF2YVNjcmlwdCBleHByZXNzaW9uIGluc2lkZSBPYnNpZGlhbiB2aWEgQ0RQIGBSdW50aW1lLmV2YWx1YXRlYC5cbiAgICpcbiAgICogUm91dGVzIHRvIHRoZSBjb3JyZWN0IHZhdWx0IHRhcmdldCBiYXNlZCBvbiBgb3B0aW9ucy5jd2RgLlxuICAgKlxuICAgKiBAcGFyYW0gZXhwcmVzc2lvbiAtIFRoZSBKYXZhU2NyaXB0IGV4cHJlc3Npb24gdG8gZXZhbHVhdGUuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gRXZhbHVhdGlvbiBvcHRpb25zLlxuICAgKiBAcmV0dXJucyBUaGUgbm9ybWFsaXplZCByZXN1bHQgc3RyaW5nLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGV2YWx1YXRlKGV4cHJlc3Npb246IHN0cmluZywgb3B0aW9uczogVHJhbnNwb3J0RXZhbE9wdGlvbnMpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHdzID0gYXdhaXQgdGhpcy5lbnN1cmVDb25uZWN0aW9uKG9wdGlvbnMuY3dkKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuc2VuZENvbW1hbmQod3MsICdSdW50aW1lLmV2YWx1YXRlJywge1xuICAgICAgYXdhaXRQcm9taXNlOiB0cnVlLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIHJldHVybkJ5VmFsdWU6IHRydWVcbiAgICB9KTtcblxuICAgIGlmIChyZXNwb25zZS5yZXN1bHQ/LmV4Y2VwdGlvbkRldGFpbHMpIHtcbiAgICAgIGNvbnN0IGRlc2MgPSByZXNwb25zZS5yZXN1bHQuZXhjZXB0aW9uRGV0YWlscy5leGNlcHRpb24/LmRlc2NyaXB0aW9uXG4gICAgICAgID8/IHJlc3BvbnNlLnJlc3VsdC5leGNlcHRpb25EZXRhaWxzLnRleHQ7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENEUCBldmFsdWF0aW9uIGVycm9yOiAke2Rlc2N9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0T2JqZWN0ID0gcmVzcG9uc2UucmVzdWx0Py5yZXN1bHQ7XG4gICAgaWYgKCFyZXN1bHRPYmplY3QgfHwgcmVzdWx0T2JqZWN0LnR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gTk9fT1VUUFVUO1xuICAgIH1cblxuICAgIHJldHVybiBTdHJpbmcocmVzdWx0T2JqZWN0LnZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBzaWxlbnQtYXNhci1mYWxsYmFjayB2ZXJkaWN0IGZvciB0aGlzIG93bmVkIGluc3RhbmNlIFx1MjAxNCB3aGV0aGVyIHRoZVxuICAgKiBhcHAgdmVyc2lvbiBpdCBpcyBhY3R1YWxseSBydW5uaW5nIG1hdGNoZXMgdGhlIHN3YXBwZWQtaW4gcGluLCBvciB0aGUgaW5zdGFsbGVyXG4gICAqIHNpbGVudGx5IHJldmVydGVkIHRvIGl0cyBvd24gYnVuZGxlZCBhc2FyIChyZWFkIGxpdmUgcG9zdC1ib290KS4gUmV0dXJuc1xuICAgKiBgdW5kZWZpbmVkYCB3aGVuIHRoaXMgaXMgbm90IGFuIG93bmVkIGluc3RhbmNlLCB0aGUgaW5zdGFuY2UgaGFzIG5vdCBib290ZWRcbiAgICogeWV0LCBvciB0aGUgdmVyZGljdCBjb3VsZCBub3QgYmUgZGV0ZXJtaW5lZCAobm8gYXNhciB3YXMgc3dhcHBlZCwgb3IgdGhlIGxpdmVcbiAgICogdmVyc2lvbiB3YXMgdW5yZWFkYWJsZSkuIEEgYCdmYWxsYmFjaydgIHZlcmRpY3QgcmVhY2hlcyB0aGlzIHN1cmZhY2Ugb25seSB3aGVuXG4gICAqIHRoZSB0aHJvdyBpcyBkaXNhYmxlZCAoe0BsaW5rIERlc2t0b3BDZHBUcmFuc3BvcnRDb25maWcuc2hvdWxkVGhyb3dPblNpbGVudEFzYXJGYWxsYmFja31cbiAgICogYGZhbHNlYCk7IG90aGVyd2lzZSBpdCB0aHJvd3MgYFNpbGVudEFzYXJGYWxsYmFja0Vycm9yYC5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIHNpbGVudC1hc2FyLWZhbGxiYWNrIHZlcmRpY3QsIG9yIGB1bmRlZmluZWRgLlxuICAgKi9cbiAgcHVibGljIGdldEFzYXJGYWxsYmFjaygpOiBBc2FyRmFsbGJhY2sgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmFzYXJGYWxsYmFjaztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSByZXNvbHZlZCBpbnN0YWxsZXJcdTIxOTRhcHAgY29tcGF0aWJpbGl0eSB2ZXJkaWN0IGZvciB0aGlzIG93bmVkXG4gICAqIGluc3RhbmNlLCBzbyBjYWxsZXJzIGNhbiBhc3NlcnQgb24gaXQuIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB0aGlzIGlzIG5vdFxuICAgKiBhbiBvd25lZCBpbnN0YW5jZSwgb3IgdGhlIHZlcmRpY3QgY291bGQgbm90IGJlIGRldGVybWluZWQgKGUuZy4gYW5cbiAgICogdW5kZXRlY3RhYmxlIHNoZWxsIHZlcnNpb24sIG9yIHRoZSBhcHAgdmVyc2lvbiBpcyBhYnNlbnQgZnJvbSB0aGUgdGFibGUpLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgY29tcGF0aWJpbGl0eSB2ZXJkaWN0LCBvciBgdW5kZWZpbmVkYC5cbiAgICovXG4gIHB1YmxpYyBnZXRDb21wYXRpYmlsaXR5KCk6IEluc3RhbGxlckNvbXBhdGliaWxpdHkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLm93bmVkQ29uZmlnPy5jb21wYXRpYmlsaXR5O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHJ1bnRpbWUgRWxlY3Ryb24gY29tcGF0aWJpbGl0eSB2ZXJkaWN0IGZvciB0aGlzIG93bmVkIGluc3RhbmNlIFx1MjAxNFxuICAgKiB3aGV0aGVyIHRoZSBFbGVjdHJvbiB2ZXJzaW9uIGl0IGlzIGFjdHVhbGx5IHJ1bm5pbmcgaXMgbmV3IGVub3VnaCBmb3IgdGhlXG4gICAqIHJ1bm5pbmcgYXBwIHZlcnNpb24gKHJlYWQgbGl2ZSBwb3N0LWJvb3Q7IHNlZSB7QGxpbmsgT2JzaWRpYW5WZXJzaW9uTWV0YWRhdGEubWluUmVjb21tZW5kZWRFbGVjdHJvblZlcnNpb259KS5cbiAgICogUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIHRoaXMgaXMgbm90IGFuIG93bmVkIGluc3RhbmNlLCB0aGUgaW5zdGFuY2UgaGFzIG5vdFxuICAgKiBib290ZWQgeWV0LCBvciB0aGUgdmVyZGljdCBjb3VsZCBub3QgYmUgZGV0ZXJtaW5lZCAodGhlIGxpdmUgdmVyc2lvbiB3YXNcbiAgICogdW5yZWFkYWJsZSwgb3IgdGhlIGFwcCB2ZXJzaW9uIGNhcnJpZXMgbm8gcmVjb21tZW5kZWQgRWxlY3Ryb24gdmVyc2lvbikuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBydW50aW1lIEVsZWN0cm9uIGNvbXBhdGliaWxpdHkgdmVyZGljdCwgb3IgYHVuZGVmaW5lZGAuXG4gICAqL1xuICBwdWJsaWMgZ2V0RWxlY3Ryb25Db21wYXRpYmlsaXR5KCk6IEVsZWN0cm9uQ29tcGF0aWJpbGl0eSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZWxlY3Ryb25Db21wYXRpYmlsaXR5O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIENEUCBlbmRwb2ludCBvZiB0aGUgb3duZWQsIGxhdW5jaGVkIGluc3RhbmNlIHNvIHRoZSBnbG9iYWwgc2V0dXBcbiAgICogY2FuIGhhbmQgaXQgdG8gdGVzdCB3b3JrZXJzICh3aGljaCB0aGVuICoqYXR0YWNoKiogdG8gaXQgaW5zdGVhZCBvZlxuICAgKiBsYXVuY2hpbmcgdGhlaXIgb3duKS4gUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIHRoaXMgdHJhbnNwb3J0IGlzIG5vdCBhblxuICAgKiBvd25lZCBpbnN0YW5jZSwgb3IgaXRzIGluc3RhbmNlIGhhcyBub3QgYmVlbiBsYXVuY2hlZCB5ZXQuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBvd25lZCBpbnN0YW5jZSdzIENEUCBob3N0IGFuZCBwb3J0LCBvciBgdW5kZWZpbmVkYC5cbiAgICovXG4gIHB1YmxpYyBnZXRPd25lZEluc3RhbmNlRW5kcG9pbnQoKTogT3duZWRJbnN0YW5jZUVuZHBvaW50IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXRoaXMub3duZWRDb25maWcgfHwgIXRoaXMub3duZWRJbnN0YW5jZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHsgaG9zdDogdGhpcy5jZHBIb3N0LCBwb3J0OiB0aGlzLmNkcFBvcnQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyB0aGF0IHRoZSBDRFAgZW5kcG9pbnQgaXMgcmVhY2hhYmxlIGFuZCBoYXMgT2JzaWRpYW4gdGFyZ2V0cy5cbiAgICpcbiAgICogSWYgT2JzaWRpYW4gaXMgbm90IHJ1bm5pbmcsIGF0dGVtcHRzIHRvIGF1dG8tc3RhcnQgaXQgdmlhIFVSSSBwcm90b2NvbFxuICAgKiBhbmQgcG9sbHMgdW50aWwgQ0RQIGJlY29tZXMgYXZhaWxhYmxlLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIHZhdWx0IHBhdGggKHVzZWQgZm9yIHZhdWx0IHJlZ2lzdHJhdGlvbiBjaGVjaykuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcHJlZmxpZ2h0Q2hlY2sodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5vd25lZENvbmZpZyB8fCB0aGlzLmlzSGFybmVzc093bmVkSW5zdGFuY2UpIHtcbiAgICAgIC8vIE93bmVkIGluc3RhbmNlIChsYXVuY2hlZCBoZXJlKSBvciBhIHdvcmtlciBhdHRhY2hlZCB0byBvbmU6IHJlYWRpbmVzcyBpc1xuICAgICAgLy8gR3VhcmFudGVlZCBieSB0aGUgZ2xvYmFsIHNldHVwJ3MgcmVnaXN0ZXJWYXVsdCwgYW5kIHRoZSB2YXVsdCBsaXZlcyBpblxuICAgICAgLy8gVGhlIGlzb2xhdGVkIGNvbmZpZyBcdTIwMTQgdGhlcmUgaXMgbm90aGluZyB0byB2ZXJpZnkgYWdhaW5zdCB0aGUgdXNlci1zY29wZVxuICAgICAgLy8gUmVnaXN0cnkuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gUnVubmluZyBwcmVmbGlnaHQgY2hlY2sgZm9yIHZhdWx0OiAke3ZhdWx0UGF0aH1gKTtcbiAgICBpZiAoIWlzVmF1bHRSZWdpc3RlcmVkKHZhdWx0UGF0aCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFZhdWx0IGlzIG5vdCByZWdpc3RlcmVkIGluIE9ic2lkaWFuOiAke3ZhdWx0UGF0aH0uIFJlZ2lzdGVyIHRoZSB2YXVsdCBmaXJzdCB3aXRoIHJlZ2lzdGVyVmF1bHQoKSBvciBUZW1wb3JhcnlWYXVsdC5yZWdpc3RlcigpLmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRhcmdldHMgPSBhd2FpdCB0aGlzLmdldFBhZ2VUYXJnZXRzKCk7XG4gICAgICBpZiAodGFyZ2V0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBwYWdlIHRhcmdldHMnKTtcbiAgICAgIH1cbiAgICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIENEUCByZWFjaGFibGUsICR7U3RyaW5nKHRhcmdldHMubGVuZ3RoKX0gdGFyZ2V0KHMpIGZvdW5kLmApO1xuICAgIH0gY2F0Y2gge1xuICAgICAgYXdhaXQgdGhpcy5lbnN1cmVPYnNpZGlhblJ1bm5pbmcoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgdmF1bHQgdmlhIEVsZWN0cm9uIElQQyBldmFsdWF0ZWQgdGhyb3VnaCBDRFAuXG4gICAqXG4gICAqIFVzZXMgYW4gZXhpc3RpbmcgT2JzaWRpYW4gdGFyZ2V0IHRvIHNlbmQgdGhlIGB2YXVsdC1vcGVuYCBJUEMgY29tbWFuZCxcbiAgICogdGhlbiBwb2xscyB1bnRpbCB0aGUgbmV3IHZhdWx0J3MgdGFyZ2V0IGFwcGVhcnMuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdmF1bHQgZm9sZGVyLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHJlZ2lzdGVyVmF1bHQodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5vd25lZENvbmZpZykge1xuICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlclZhdWx0SW5Pd25lZEluc3RhbmNlKHZhdWx0UGF0aCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5vcGVuVmF1bHRJblJ1bm5pbmdJbnN0YW5jZSh2YXVsdFBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXJzIGEgdmF1bHQgYnkgZGVzdHJveWluZyBpdHMgd2luZG93IGFuZCByZW1vdmluZyBpdCBmcm9tIHRoZSByZWdpc3RyeS5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBmb2xkZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdW5yZWdpc3RlclZhdWx0KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMub3duZWRDb25maWcpIHtcbiAgICAgIC8vIFRoZSBvd25lZCBpbnN0YW5jZSBpcyBraWxsZWQgd2hvbGVzYWxlIG9uIGRpc3Bvc2U7IG5vIHBlci12YXVsdFxuICAgICAgLy8gVW5yZWdpc3RlciBpcyBuZWVkZWQgKGFuZCB0aGUgcmVnaXN0cnkgbGl2ZXMgaW4gdGhlIGlzb2xhdGVkIGNvbmZpZykuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGVuc3VyZU5hbWVzcGFjZUJvb3RzdHJhcHBlZCh0aGlzLCB2YXVsdFBhdGgpO1xuICAgICAgY29uc3QgdGFyZ2V0ID0gYXdhaXQgdGhpcy5maW5kVGFyZ2V0Rm9yVmF1bHQodmF1bHRQYXRoKTtcbiAgICAgIGNvbnN0IHdzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQodGFyZ2V0KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHdpbmRvd0Rlc3Ryb3lFeHByZXNzaW9uID0gJ3dpbmRvdy5fX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nLmRlc3Ryb3lDdXJyZW50V2luZG93KCknO1xuICAgICAgICBhd2FpdCB0aGlzLnNlbmRDb21tYW5kKHdzLCAnUnVudGltZS5ldmFsdWF0ZScsIHtcbiAgICAgICAgICBhd2FpdFByb21pc2U6IHRydWUsXG4gICAgICAgICAgZXhwcmVzc2lvbjogd2luZG93RGVzdHJveUV4cHJlc3Npb24sXG4gICAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBXaW5kb3cgbWF5IGFscmVhZHkgYmUgY2xvc2VkLlxuICAgIH1cblxuICAgIGlmICh0aGlzLmFjdGl2ZVZhdWx0UGF0aCA9PT0gdmF1bHRQYXRoKSB7XG4gICAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG5cbiAgICBhd2FpdCBkZWxheShWQVVMVF9DTE9TRV9ERUxBWV9JTl9NSUxMSVNFQ09ORFMpO1xuXG4gICAgY29uc3QgdGFyZ2V0cyA9IGF3YWl0IHRoaXMuZ2V0UGFnZVRhcmdldHMoKTtcbiAgICBpZiAodGFyZ2V0cy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBUaGUgYHZhdWx0LXJlbW92ZWAgSVBDIGlzIHNlbnQgdGhyb3VnaCBhIHN0aWxsLW9wZW4gd2luZG93IChgdGFyZ2V0c1swXWApIFx1MjAxNFxuICAgICAgLy8gYHZhdWx0UGF0aGAncyBvd24gd2luZG93IHdhcyBqdXN0IGRlc3Ryb3llZCBhYm92ZSwgc28gYm9vdHN0cmFwIHRoZSBuYW1lc3BhY2VcbiAgICAgIC8vIE9uIHRoZSBleGlzdGluZyB3aW5kb3cncyBPV04gYmFzZSBwYXRoLCBub3Qgb24gYHZhdWx0UGF0aGAgKHdoaWNoIG5vIGxvbmdlciBoYXNcbiAgICAgIC8vIEEgbGl2ZSB0YXJnZXQgdG8gbWF0Y2gpLlxuICAgICAgY29uc3QgcmVtb3ZhbFRhcmdldCA9IGVuc3VyZU5vbk51bGxhYmxlKHRhcmdldHNbMF0pO1xuICAgICAgY29uc3QgcmVtb3ZhbEJhc2VQYXRoID0gYXdhaXQgdGhpcy5wcm9iZVZhdWx0UGF0aChyZW1vdmFsVGFyZ2V0KTtcbiAgICAgIGNvbnN0IHdzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQocmVtb3ZhbFRhcmdldCk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBlbnN1cmVOYW1lc3BhY2VCb290c3RyYXBwZWQodGhpcywgcmVtb3ZhbEJhc2VQYXRoKTtcbiAgICAgICAgY29uc3QgdmF1bHRSZW1vdmVFeHByZXNzaW9uID0gYHdpbmRvdy5fX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nLmlwY1NlbmRTeW5jKCR7SlNPTi5zdHJpbmdpZnkoeyBjaGFubmVsOiAndmF1bHQtcmVtb3ZlJywgY2hhbm5lbEFyZ3VtZW50czogW3ZhdWx0UGF0aF0gfSl9KWA7XG4gICAgICAgIGF3YWl0IHRoaXMuc2VuZENvbW1hbmQod3MsICdSdW50aW1lLmV2YWx1YXRlJywge1xuICAgICAgICAgIGF3YWl0UHJvbWlzZTogdHJ1ZSxcbiAgICAgICAgICBleHByZXNzaW9uOiB2YXVsdFJlbW92ZUV4cHJlc3Npb24sXG4gICAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIE5vIENEUCB0YXJnZXRzIGZvciByZW1vdmFsIElQQyBcdTIwMTQgcmVtb3ZpbmcgZGlyZWN0bHkgZnJvbSBvYnNpZGlhbi5qc29uLicpO1xuICAgICAgZGlkUmVtb3ZlVmF1bHRGcm9tQ29uZmlnKHZhdWx0UGF0aCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGVzIGFuZCBzdG9yZXMgdGhlIHJ1bnRpbWUtRWxlY3Ryb24gY29tcGF0aWJpbGl0eSB2ZXJkaWN0IChvblxuICAgKiB7QGxpbmsgZ2V0RWxlY3Ryb25Db21wYXRpYmlsaXR5fSkgZnJvbSBhbiBhbHJlYWR5LXJlYWQgdmVyc2lvbiBwYWlyLCB3YXJuaW5nXG4gICAqIHdoZW4gdGhlIGxpdmUgRWxlY3Ryb24gaXMgYmVsb3cgdGhlIGFwcCdzIHJlY29tbWVuZGVkIG1pbmltdW0uIE5ldmVyIHRocm93czsgYVxuICAgKiBib290IHdob3NlIHJ1bm5pbmcgYXBwIHZlcnNpb24gd2FzIHVucmVhZGFibGUgaXMgc2tpcHBlZCAobm90aGluZyB0byBqdWRnZSkuXG4gICAqXG4gICAqIEBwYXJhbSBhcHBWZXJzaW9uIC0gVGhlIGxpdmUgcnVubmluZyBhcHAgdmVyc2lvbiwgb3IgYHVuZGVmaW5lZGAgd2hlbiB1bnJlYWRhYmxlLlxuICAgKiBAcGFyYW0gYWN0dWFsRWxlY3Ryb25WZXJzaW9uIC0gVGhlIGxpdmUgRWxlY3Ryb24gdmVyc2lvbiwgb3IgYHVuZGVmaW5lZGAgd2hlbiB1bnJlYWRhYmxlLlxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseUVsZWN0cm9uQ29tcGF0aWJpbGl0eShhcHBWZXJzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQsIGFjdHVhbEVsZWN0cm9uVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gICAgaWYgKGFwcFZlcnNpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHZlcmRpY3QgPSByZXNvbHZlRWxlY3Ryb25Db21wYXRpYmlsaXR5KHtcbiAgICAgIGFjdHVhbEVsZWN0cm9uVmVyc2lvbixcbiAgICAgIGFwcFZlcnNpb24sXG4gICAgICBtZXRhZGF0YTogZ2V0VmVyc2lvbk1ldGFkYXRhKGFwcFZlcnNpb24pXG4gICAgfSk7XG4gICAgdGhpcy5lbGVjdHJvbkNvbXBhdGliaWxpdHkgPSB2ZXJkaWN0O1xuICAgIGlmICh2ZXJkaWN0LnRpZXIgPT09ICduYWdnZWQnICYmIHRoaXMuc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3Vlcykge1xuICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gJHtlbnN1cmVOb25OdWxsYWJsZSh2ZXJkaWN0Lm1lc3NhZ2UpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQb2ludHMgdGhlIG93bmVkIGluc3RhbmNlJ3MgcmVuZGVyZXIgYXQgdGhpcyBwcm9jZXNzJ3MgbGl2ZW5lc3Mgc29ja2V0IHNvIGl0XG4gICAqIGRlc3Ryb3lzIGl0c2VsZiBpZiB3ZSBkaWUgd2l0aG91dCBydW5uaW5nIHRlYXJkb3duIChzZWUgYHBhcmVudC1saXZlbmVzcy50c2ApLlxuICAgKlxuICAgKiBCZXN0LWVmZm9ydCBieSBkZXNpZ24uIEEgcmVuZGVyZXIgd2l0aG91dCBOb2RlIGFjY2VzcyByZXBvcnRzIGAndW5hdmFpbGFibGUnYFxuICAgKiBhbmQgYW4gZXZhbHVhdGlvbiBmYWlsdXJlIGlzIGxvZ2dlZCBhbmQgc3dhbGxvd2VkOiB0aGUgd2F0Y2hkb2cgaXMgYSBiYWNrc3RvcFxuICAgKiBmb3IgYW4gYWxyZWFkeS1hYm5vcm1hbCBleGl0LCBuZXZlciBhIHJlYXNvbiB0byBmYWlsIGFuIG90aGVyd2lzZSBnb29kIGxhdW5jaC5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoIHRvIGV2YWx1YXRlIGluLlxuICAgKiBAcGFyYW0gcGFyZW50TGl2ZW5lc3NQb3J0IC0gVGhlIGxvb3BiYWNrIHBvcnQgdGhlIHJlbmRlcmVyIHNob3VsZCBjb25uZWN0IGJhY2sgdG8uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGFybVBhcmVudExpdmVuZXNzV2F0Y2hkb2codmF1bHRQYXRoOiBzdHJpbmcsIHBhcmVudExpdmVuZXNzUG9ydDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZXZhbHVhdGUoYnVpbGRQYXJlbnRMaXZlbmVzc1dhdGNoZG9nRXhwcmVzc2lvbihwYXJlbnRMaXZlbmVzc1BvcnQpLCB7IGN3ZDogdmF1bHRQYXRoIH0pO1xuICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gUGFyZW50LWxpdmVuZXNzIHdhdGNoZG9nIG9uIHBvcnQgJHtTdHJpbmcocGFyZW50TGl2ZW5lc3NQb3J0KX06ICR7cmVzdWx0fS5gKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gQ291bGQgbm90IGFybSB0aGUgcGFyZW50LWxpdmVuZXNzIHdhdGNoZG9nIChpbnN0YW5jZSBtYXkgb3V0bGl2ZSBhIGtpbGxlZCBoYXJuZXNzKTogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyB0aGUgcnVubmluZyBhcHAgKGFzYXIpIHZlcnNpb24gbWF0Y2hlcyB0aGUgc3dhcHBlZC1pbiBwaW4sIHN0b3JpbmcgdGhlXG4gICAqIHZlcmRpY3Qgb24ge0BsaW5rIGdldEFzYXJGYWxsYmFja30uIE9uIGEgKipzaWxlbnQgZmFsbGJhY2sqKiAodGhlIGluc3RhbGxlciByYW5cbiAgICogaXRzIG93biBidW5kbGVkIGFzYXIgaW5zdGVhZCBvZiB0aGUgcGluKSBpdCB0aHJvd3Mge0BsaW5rIFNpbGVudEFzYXJGYWxsYmFja0Vycm9yfVxuICAgKiB3aGVuIHRoZSB0aHJvdyBpcyBlbmFibGVkLCBvdGhlcndpc2Ugd2FybnMgKHdoZW4gd2FybmluZ3MgYXJlIG9uKSBhbmQgbGV0cyB0aGVcbiAgICogYm9vdCBwcm9jZWVkLiBBIGJvb3Qgd2l0aCBubyBzd2FwcGVkLWluIGFzYXIsIG9yIGFuIHVucmVhZGFibGUgcnVubmluZyB2ZXJzaW9uLFxuICAgKiBpcyBgJ3Vua25vd24nYCBcdTIwMTQgbm90aGluZyBpcyB0aHJvd24gb3Igd2FybmVkLiBUaGlzIGlzIHRoZSBoZWFsdGh5LVVJIGNvbXBhbmlvbiB0b1xuICAgKiB0aGUgYmxhY2stc2NyZWVuIHtAbGluayBSZW5kZXJlckZhaWxlZFRvSW5pdGlhbGl6ZUVycm9yfSBkZWFkLWJvb3QgZmFzdC1mYWlsLlxuICAgKlxuICAgKiBAcGFyYW0gcnVubmluZ0FwaVZlcnNpb24gLSBUaGUgbGl2ZSBydW5uaW5nIGFwcCB2ZXJzaW9uLCBvciBgdW5kZWZpbmVkYCB3aGVuIHVucmVhZGFibGUuXG4gICAqL1xuICBwcml2YXRlIGNoZWNrUnVudGltZUFzYXJGYWxsYmFjayhydW5uaW5nQXBpVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gICAgY29uc3QgdmVyZGljdCA9IHJlc29sdmVBc2FyRmFsbGJhY2soe1xuICAgICAgcmVxdWVzdGVkVmVyc2lvbjogdGhpcy5vd25lZENvbmZpZz8uYXNhcj8udmVyc2lvbixcbiAgICAgIHJ1bm5pbmdBcGlWZXJzaW9uXG4gICAgfSk7XG4gICAgdGhpcy5hc2FyRmFsbGJhY2sgPSB2ZXJkaWN0O1xuXG4gICAgY29uc3QgYWN0aW9uID0gcmVzb2x2ZUFzYXJGYWxsYmFja0FjdGlvbih7XG4gICAgICBzaG91bGRUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrOiB0aGlzLnNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2ssXG4gICAgICBzaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzOiB0aGlzLnNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXMsXG4gICAgICB0aWVyOiB2ZXJkaWN0LnRpZXJcbiAgICB9KTtcbiAgICBpZiAoYWN0aW9uID09PSAndGhyb3cnKSB7XG4gICAgICB0aHJvdyBuZXcgU2lsZW50QXNhckZhbGxiYWNrRXJyb3Ioe1xuICAgICAgICByZXF1ZXN0ZWRWZXJzaW9uOiBlbnN1cmVOb25OdWxsYWJsZSh2ZXJkaWN0LnJlcXVlc3RlZFZlcnNpb24pLFxuICAgICAgICBydW5uaW5nQXBpVmVyc2lvbjogZW5zdXJlTm9uTnVsbGFibGUodmVyZGljdC5ydW5uaW5nQXBpVmVyc2lvbilcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoYWN0aW9uID09PSAnd2FybicpIHtcbiAgICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdICR7ZW5zdXJlTm9uTnVsbGFibGUodmVyZGljdC5tZXNzYWdlKX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0aGUgcG9zdC1ib290IHJ1bnRpbWUgY29tcGF0aWJpbGl0eSBjaGVja3MgZm9yIGFuIG93bmVkIGluc3RhbmNlLCBvbmNlIHRoZVxuICAgKiB2YXVsdCBpcyByZWFkeS4gUmVhZHMgdGhlIGxpdmUgcnVubmluZyBhcHAgdmVyc2lvbiBhbmQgRWxlY3Ryb24gdmVyc2lvbiAqKm9uY2UqKlxuICAgKiBmcm9tIHRoZSBib290ZWQgcmVuZGVyZXIncyBtYWluIHByb2Nlc3MsIHRoZW46ICgxKSB2ZXJpZmllcyB0aGUgcnVubmluZyBhcHBcbiAgICogdmVyc2lvbiBtYXRjaGVzIHRoZSBzd2FwcGVkLWluIHBpbiBcdTIwMTQgdGhyb3dpbmcge0BsaW5rIFNpbGVudEFzYXJGYWxsYmFja0Vycm9yfSBvblxuICAgKiBhIHNpbGVudCBmYWxsYmFjayAod2hlbiBlbmFibGVkKTsgYW5kICgyKSBydW5zIHRoZSBiZXN0LWVmZm9ydCBydW50aW1lLUVsZWN0cm9uXG4gICAqIG5hZy4gT25seSB0aGUgYXNhci1mYWxsYmFjayBjaGVjayBjYW4gdGhyb3csIHNvIHRoaXMgbXVzdCBydW4gb3V0c2lkZSB0aGVcbiAgICogcmVhZGluZXNzIHBvbGwncyB0cnkvY2F0Y2ggKGEgc3dhbGxvd2VkIHRocm93IHdvdWxkIGxvb3AgdW50aWwgdGltZW91dCkuXG4gICAqXG4gICAqIEJvdGggYXJlIHJlYWQgYXQgdGhlIHJlbmRlcmVyIHRvcCBsZXZlbDogYGlwY1JlbmRlcmVyLnNlbmRTeW5jKCd2ZXJzaW9uJylgICh0aGVcbiAgICogcnVubmluZyBhcHAgdmVyc2lvbiwgdHJ1dGhmdWwgZXZlbiB1bmRlciBhIHNpbGVudCBhc2FyIGZhbGxiYWNrKSBhbmRcbiAgICogYHByb2Nlc3MudmVyc2lvbnMuZWxlY3Ryb25gICh0aGUgbGl2ZSBzaGVsbCBFbGVjdHJvbik7IG5laXRoZXIgdXNlc1xuICAgKiBgcmVxdWlyZSgnb2JzaWRpYW4nKWAsIHdoaWNoIHJlc29sdmVzIG9ubHkgaW5zaWRlIGEgcGx1Z2luLWxvYWQgY29udGV4dC4gQSByZWFkXG4gICAqIGZhaWx1cmUgbGVhdmVzIGJvdGggdW5rbm93biAobG9nZ2VkLCBub24tZmF0YWwpIFx1MjAxNCBhbiB1bnJlYWRhYmxlIHJ1bm5pbmcgdmVyc2lvblxuICAgKiBjYW5ub3QgYmUganVkZ2VkIGEgZmFsbGJhY2ssIHNvIHRoZSBib290IGlzIG5vdCBicm9rZW4gYnkgYSBmbGFreSByZWFkLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIHZhdWx0IHBhdGggdG8gZXZhbHVhdGUgaW4uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNoZWNrUnVudGltZUNvbXBhdGliaWxpdHkodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsZXQgYXBwVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGxldCBhY3R1YWxFbGVjdHJvblZlcnNpb246IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmF3QXBwVmVyc2lvbiA9IGF3YWl0IHRoaXMuZXZhbHVhdGUoJ1N0cmluZyh3aW5kb3cuZWxlY3Ryb24uaXBjUmVuZGVyZXIuc2VuZFN5bmMoXFwndmVyc2lvblxcJykpJywgeyBjd2Q6IHZhdWx0UGF0aCB9KTtcbiAgICAgIGFwcFZlcnNpb24gPSByYXdBcHBWZXJzaW9uID09PSAnJyB8fCByYXdBcHBWZXJzaW9uID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IHJhd0FwcFZlcnNpb247XG4gICAgICBhY3R1YWxFbGVjdHJvblZlcnNpb24gPSBhd2FpdCB0aGlzLmV2YWx1YXRlKCdTdHJpbmcocHJvY2Vzcy52ZXJzaW9ucy5lbGVjdHJvbiknLCB7IGN3ZDogdmF1bHRQYXRoIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBDb3VsZCBub3QgcmVhZCBydW50aW1lIHZlcnNpb25zIChub24tZmF0YWwpOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgfVxuXG4gICAgLy8gRmFpbHMgZmFzdCAod2hlbiBlbmFibGVkKSBvbiBhIHNpbGVudCBhc2FyIGZhbGxiYWNrIFx1MjAxNCBNVVNUIHJ1biBiZWZvcmUgdGhlXG4gICAgLy8gQmVzdC1lZmZvcnQgbmFnIGFuZCBvdXRzaWRlIGFueSB0cnkvY2F0Y2ggc28gdGhlIHRocm93IGVzY2FwZXMgdGhlIHBvbGwuXG4gICAgdGhpcy5jaGVja1J1bnRpbWVBc2FyRmFsbGJhY2soYXBwVmVyc2lvbik7XG4gICAgdGhpcy5hcHBseUVsZWN0cm9uQ29tcGF0aWJpbGl0eShhcHBWZXJzaW9uLCBhY3R1YWxFbGVjdHJvblZlcnNpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbm5lY3RzIHRvIGEgQ0RQIHRhcmdldCdzIFdlYlNvY2tldCBlbmRwb2ludC5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldCAtIFRoZSBDRFAgdGFyZ2V0IHRvIGNvbm5lY3QgdG8uXG4gICAqIEByZXR1cm5zIFRoZSBvcGVuIFdlYlNvY2tldCBjb25uZWN0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjb25uZWN0VG9UYXJnZXQodGFyZ2V0OiBDZHBUYXJnZXQpOiBQcm9taXNlPFdlYlNvY2tldD4ge1xuICAgIGNvbnN0IHdzID0gbmV3IFdlYlNvY2tldCh0YXJnZXQud2ViU29ja2V0RGVidWdnZXJVcmwpO1xuICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIoJ29wZW4nLCAoKTogdm9pZCA9PiB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0pO1xuICAgICAgd3MuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCAoKTogdm9pZCA9PiB7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBjb25uZWN0IHRvIENEUCB0YXJnZXQ6ICR7dGFyZ2V0LndlYlNvY2tldERlYnVnZ2VyVXJsfWApKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiB3cztcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyB0aGUgYWN0aXZlIFdlYlNvY2tldCBjb25uZWN0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBkaXNjb25uZWN0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLndzPy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTikge1xuICAgICAgdGhpcy53cy5jbG9zZSgpO1xuICAgIH1cbiAgICB0aGlzLndzID0gbnVsbDtcbiAgICB0aGlzLmFjdGl2ZVZhdWx0UGF0aCA9IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogRGlzbWlzc2VzIHRoZSBcIkRvIHlvdSB0cnVzdCB0aGUgYXV0aG9yIG9mIHRoaXMgdmF1bHQ/XCIgZGlhbG9nIGlmIHByZXNlbnQuXG4gICAqXG4gICAqIEFjdHMgYXMgYSBzYWZldHkgbmV0IHdoZW4gYGVuYWJsZS1wbHVnaW4tPGlkPmAgaXMgd3JpdHRlbiBpbiBvbmUgcmVuZGVyZXJcbiAgICogYnV0IG5vdCB5ZXQgdmlzaWJsZSB0byB0aGUgbmV3bHktb3BlbmVkIHZhdWx0J3MgcmVuZGVyZXIgKHJhY2Ugb2JzZXJ2ZWRcbiAgICogaW4gT2JzaWRpYW4gMS4xMy4wKS5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoIHRvIGV2YWx1YXRlIGluLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBkaXNtaXNzVHJ1c3REaWFsb2codmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmV2YWx1YXRlKERJU01JU1NfVFJVU1RfRElBTE9HX0VYUFIsIHsgY3dkOiB2YXVsdFBhdGggfSk7XG4gICAgaWYgKHJlc3VsdCA9PT0gJ3RydWUnKSB7XG4gICAgICBsb2coJ1tjZHAtdHJhbnNwb3J0XSBEaXNtaXNzZWQgXCJEbyB5b3UgdHJ1c3QgdGhlIGF1dGhvclwiIGRpYWxvZy4nKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBgZW5hYmxlLXBsdWdpbi08dmF1bHRJZD5gIGluIE9ic2lkaWFuJ3MgbG9jYWxTdG9yYWdlIHRvIHByZXZlbnRcbiAgICogdGhlIFwiRG8geW91IHRydXN0IHRoZSBhdXRob3Igb2YgdGhpcyB2YXVsdD9cIiBkaWFsb2cgZnJvbSBhcHBlYXJpbmdcbiAgICogd2hlbiBhIHZhdWx0IHdpdGggY29tbXVuaXR5IHBsdWdpbnMgaXMgb3BlbmVkIGZvciB0aGUgZmlyc3QgdGltZS5cbiAgICpcbiAgICogTXVzdCBiZSBjYWxsZWQgYWZ0ZXIgdGhlIGB2YXVsdC1vcGVuYCBJUEMgKHNvIHRoZSB2YXVsdCBJRCBleGlzdHMgaW5cbiAgICogYG9ic2lkaWFuLmpzb25gKSBhbmQgYmVmb3JlIHRoZSBuZXcgdmF1bHQgd2luZG93IGZpbmlzaGVzIGxvYWRpbmcuXG4gICAqXG4gICAqIEBwYXJhbSB3cyAtIEFuIG9wZW4gV2ViU29ja2V0IHRvIGFuIGV4aXN0aW5nIE9ic2lkaWFuIHRhcmdldC5cbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBmb2xkZXIuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGVuYWJsZVBsdWdpbnNJbkxvY2FsU3RvcmFnZSh3czogV2ViU29ja2V0LCB2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHZhdWx0SWQgPSBnZXRWYXVsdElkKHZhdWx0UGF0aCk7XG4gICAgaWYgKCF2YXVsdElkKSB7XG4gICAgICBsb2coJ1tjZHAtdHJhbnNwb3J0XSBDb3VsZCBub3QgZmluZCB2YXVsdCBJRCBcdTIwMTQgc2tpcHBpbmcgbG9jYWxTdG9yYWdlIHRydXN0IGZsYWcuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5zZW5kQ29tbWFuZCh3cywgJ1J1bnRpbWUuZXZhbHVhdGUnLCB7XG4gICAgICBleHByZXNzaW9uOiBgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJHtKU09OLnN0cmluZ2lmeShgZW5hYmxlLXBsdWdpbi0ke3ZhdWx0SWR9YCl9LCAndHJ1ZScpO2AsXG4gICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgfSk7XG4gICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gU2V0IGVuYWJsZS1wbHVnaW4tJHt2YXVsdElkfSBpbiBsb2NhbFN0b3JhZ2UuYCk7XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyB0aGVyZSBpcyBhbiBhY3RpdmUgV2ViU29ja2V0IGNvbm5lY3Rpb24gdG8gdGhlIGNvcnJlY3QgdmF1bHQgdGFyZ2V0LlxuICAgKlxuICAgKiBSZXVzZXMgdGhlIGV4aXN0aW5nIGNvbm5lY3Rpb24gaWYgaXQgdGFyZ2V0cyB0aGUgcmVxdWVzdGVkIHZhdWx0LlxuICAgKiBPdGhlcndpc2UsIGZpbmRzIHRoZSBjb3JyZWN0IHRhcmdldCBhbmQgcmVjb25uZWN0cy5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoIHRvIHRhcmdldC5cbiAgICogQHJldHVybnMgVGhlIGFjdGl2ZSBXZWJTb2NrZXQgY29ubmVjdGlvbi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlQ29ubmVjdGlvbih2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8V2ViU29ja2V0PiB7XG4gICAgaWYgKHRoaXMud3M/LnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOICYmIHRoaXMuYWN0aXZlVmF1bHRQYXRoID09PSB2YXVsdFBhdGgpIHtcbiAgICAgIHJldHVybiB0aGlzLndzO1xuICAgIH1cblxuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuXG4gICAgY29uc3QgdGFyZ2V0ID0gYXdhaXQgdGhpcy5maW5kVGFyZ2V0Rm9yVmF1bHQodmF1bHRQYXRoKTtcbiAgICB0aGlzLndzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQodGFyZ2V0KTtcbiAgICB0aGlzLmFjdGl2ZVZhdWx0UGF0aCA9IHZhdWx0UGF0aDtcbiAgICByZXR1cm4gdGhpcy53cztcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXVuY2hlcyBPYnNpZGlhbiB3aXRoIGAtLXJlbW90ZS1kZWJ1Z2dpbmctcG9ydGAgYW5kIHBvbGxzIHVudGlsIENEUCBiZWNvbWVzIGF2YWlsYWJsZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlT2JzaWRpYW5SdW5uaW5nKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIE9ic2lkaWFuIENEUCBub3QgcmVhY2hhYmxlLiBTdGFydGluZyBPYnNpZGlhbiB3aXRoIHJlbW90ZSBkZWJ1Z2dpbmcuLi4nKTtcblxuICAgIGNvbnN0IGxhdW5jaENvbW1hbmQgPSBhd2FpdCBnZXRPYnNpZGlhbkxhdW5jaENvbW1hbmQodGhpcy5jZHBQb3J0KTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZXhlYyhsYXVuY2hDb21tYW5kLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBUaGUgbGF1bmNoIGNvbW1hbmQgbWF5IGZhaWwgb24gc29tZSBzeXN0ZW1zIFx1MjAxNCB3ZSdsbCBzdGlsbCB0cnkgcG9sbGluZy5cbiAgICB9XG5cbiAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBQb2xsaW5nIGZvciBDRFAgZW5kcG9pbnQgYXQgJHt0aGlzLmNkcFVybH0gKHRpbWVvdXQ9JHtTdHJpbmcoQVVUT19TVEFSVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXMpLi4uYCk7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgQVVUT19TVEFSVF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICBhd2FpdCBkZWxheShBVVRPX1NUQVJUX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHRhcmdldHMgPSBhd2FpdCB0aGlzLmdldFBhZ2VUYXJnZXRzKCk7XG4gICAgICAgIGlmICh0YXJnZXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBPYnNpZGlhbiBDRFAgcmVhZHksICR7U3RyaW5nKHRhcmdldHMubGVuZ3RoKX0gdGFyZ2V0KHMpIGZvdW5kLmApO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIENEUCBub3QgcmVhZHkgeWV0LCByZXRyeWluZy4uLicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgT2JzaWRpYW4gZGlkIG5vdCBzdGFydCB3aXRoaW4gJHtTdHJpbmcoQVVUT19TVEFSVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXMuIEVuc3VyZSBPYnNpZGlhbiBpcyBpbnN0YWxsZWQgYW5kIGFjY2Vzc2libGUuYCk7XG4gIH1cblxuICAvKipcbiAgICogRmluZHMgdGhlIENEUCB0YXJnZXQgdGhhdCBoYXMgdGhlIGdpdmVuIHZhdWx0IG9wZW4uXG4gICAqXG4gICAqIFByb2JlcyBldmVyeSB0YXJnZXQgYnkgZXZhbHVhdGluZyBgZ2V0QmFzZVBhdGgoKWAgYW5kIHJldHVybnMgdGhlIG9uZSB3aG9zZVxuICAgKiBiYXNlIHBhdGggbWF0Y2hlcyBgdmF1bHRQYXRoYCAodmlhIHtAbGluayBhcmVWYXVsdFBhdGhzTWF0Y2hpbmd9LCB0b2xlcmFudCBvZlxuICAgKiBzZXBhcmF0b3IvY2FzZSBkaWZmZXJlbmNlcykuIEEgc2luZ2xlIHRhcmdldCBpcyAqKm5vdCoqIHJldHVybmVkIGJsaW5kbHk6IHdpdGhcbiAgICogbW9yZSB0aGFuIG9uZSB2YXVsdCBvcGVuIChhdHRhY2ggbW9kZSdzIHNoYXJlZCBpbnN0YW5jZSksIHRoZSBzb2xlLXRhcmdldFxuICAgKiBzaG9ydGN1dCB3b3VsZCByZXR1cm4gd2hpY2hldmVyIHdpbmRvdyBoYXBwZW5zIHRvIGJlIG9wZW4gcmVnYXJkbGVzcyBvZiB3aGljaFxuICAgKiB2YXVsdCB3YXMgcmVxdWVzdGVkIFx1MjAxNCB0aGUgZXhhY3QgbWlzLXJvdXRpbmcgdGhpcyBtZXRob2QgbXVzdCBhdm9pZC4gQSB0YXJnZXRcbiAgICogd2hvc2UgcHJvYmUgdGhyb3dzIGlzIHRyZWF0ZWQgYXMgbm90LXJlYWR5IGFuZCBza2lwcGVkICh0aGUgY2FsbGVyJ3MgcmVhZGluZXNzXG4gICAqIHBvbGwgcmV0cmllcyk7IGEgdGFyZ2V0IHdob3NlIHByb2JlIHN1Y2NlZWRzIGJ1dCBkb2VzIG5vdCBtYXRjaCBpcyBuZXZlclxuICAgKiByZXR1cm5lZC4gV2hlbiBub3RoaW5nIG1hdGNoZXMsIHRocm93IHNvIHRoZSBjYWxsZXIga2VlcHMgcG9sbGluZy5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoIHRvIG1hdGNoLlxuICAgKiBAcmV0dXJucyBUaGUgbWF0Y2hpbmcgQ0RQIHRhcmdldC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmluZFRhcmdldEZvclZhdWx0KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTxDZHBUYXJnZXQ+IHtcbiAgICBjb25zdCB0YXJnZXRzID0gYXdhaXQgdGhpcy5nZXRQYWdlVGFyZ2V0cygpO1xuXG4gICAgaWYgKHRhcmdldHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIE9ic2lkaWFuIENEUCB0YXJnZXRzIGZvdW5kJyk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCB0YXJnZXQgb2YgdGFyZ2V0cykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYmFzZVBhdGggPSBhd2FpdCB0aGlzLnByb2JlVmF1bHRQYXRoKHRhcmdldCk7XG4gICAgICAgIGlmIChhcmVWYXVsdFBhdGhzTWF0Y2hpbmcoYmFzZVBhdGgsIHZhdWx0UGF0aCkpIHtcbiAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gTm90IGEgdmF1bHQgdGFyZ2V0IG9yIG5vdCByZWFkeS5cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIENEUCB0YXJnZXQgZm91bmQgZm9yIHZhdWx0OiAke3ZhdWx0UGF0aH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaGVzIHRoZSBsaXN0IG9mIHBhZ2UtdHlwZSB0YXJnZXRzIGZyb20gdGhlIENEUCBgL2pzb25gIGVuZHBvaW50LlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgbGlzdCBvZiBwYWdlIHRhcmdldHMuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldFBhZ2VUYXJnZXRzKCk6IFByb21pc2U8Q2RwVGFyZ2V0W10+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke3RoaXMuY2RwVXJsfS9qc29uYCk7XG4gICAgY29uc3QgdGFyZ2V0cyA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyBDZHBUYXJnZXRbXTtcbiAgICByZXR1cm4gdGFyZ2V0cy5maWx0ZXIoKHQpID0+IHQudHlwZSA9PT0gJ3BhZ2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBLaWxscyB0aGUgY3VycmVudGx5LXJ1bm5pbmcgb3duZWQgaW5zdGFuY2UgKGlmIGFueSkgYW5kIHdhaXRzIGZvciBpdCB0byBleGl0LFxuICAgKiBzbyB0aGUgbmV4dCBsYXVuY2ggZ2V0cyBhIHByaXN0aW5lIHNpbmdsZS13aW5kb3cgaW5zdGFuY2UuXG4gICAqXG4gICAqIFJlbGF1bmNoaW5nIG92ZXIgYSBsaXZlIGluc3RhbmNlIGlzIGZvcndhcmRlZCBieSBFbGVjdHJvbidzIHNpbmdsZS1pbnN0YW5jZVxuICAgKiBsb2NrIG9uIHRoZSBzaGFyZWQgdXNlci1kYXRhIGRpcmVjdG9yeSBhbmQgc3VyZmFjZXMgdGhlIHZhdWx0IHBpY2tlciwgYW5kIG9wZW5pbmcgYVxuICAgKiBzZWNvbmQgd2luZG93IHZpYSBJUEMgbGVhdmVzIHN0YWxlIHdpbmRvd3MgdGhhdCBicmVhayB2YXVsdC10YXJnZXQgcm91dGluZyBcdTIwMTRcbiAgICogaGVuY2UgYSBmdWxsIGtpbGwgKyB3YWl0LWZvci1leGl0IChyZWxlYXNpbmcgdGhlIGxvY2spIGJldHdlZW4gbGF1bmNoZXMuIEFcbiAgICogbm8tb3Agb24gdGhlIGZpcnN0IGF0dGVtcHQsIHdoZW4gbm8gaW5zdGFuY2UgaXMgcnVubmluZyB5ZXQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGtpbGxSdW5uaW5nT3duZWRJbnN0YW5jZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMub3duZWRJbnN0YW5jZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsb2coJ1tjZHAtdHJhbnNwb3J0XSBLaWxsaW5nIHJ1bm5pbmcgb3duZWQgaW5zdGFuY2UgYmVmb3JlIChyZSlsYXVuY2guJyk7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgY29uc3QgcHJldmlvdXNDZHBVcmwgPSB0aGlzLmNkcFVybDtcbiAgICB0aGlzLm93bmVkSW5zdGFuY2Uua2lsbCgpO1xuICAgIHRoaXMub3duZWRJbnN0YW5jZSA9IHVuZGVmaW5lZDtcbiAgICBhd2FpdCB0aGlzLndhaXRGb3JJbnN0YW5jZUV4aXQocHJldmlvdXNDZHBVcmwpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmVzIHRoZSBvd25lZCBpbnN0YW5jZSdzIHdpbmRvdyBvZmYtc2NyZWVuIHNvIGEgaGlkZGVuIHJ1biBuZXZlciBzdGVhbHNcbiAgICogZm9jdXMuIFVzZXMgRWxlY3Ryb24ncyByZW1vdGUgYnJpZGdlIChgd2luZG93LmVsZWN0cm9uLnJlbW90ZWApIFx1MjAxNCB0aGUgb25seVxuICAgKiBjcm9zcy1wbGF0Zm9ybSB3YXkgdG8gcmVwb3NpdGlvbiB0aGUgd2luZG93IFx1MjAxNCBwbGFjaW5nIGl0IGp1c3QgYmV5b25kIHRoZVxuICAgKiByaWdodCBlZGdlIG9mIGFsbCBkaXNwbGF5cy4gVGhlIHdpbmRvdyBzdGF5cyBcInZpc2libGVcIiB0byBDaHJvbWl1bSAoc29cbiAgICogdGltZXJzLCBgcmVxdWVzdEFuaW1hdGlvbkZyYW1lYCwgYDpob3ZlcmAsIGFuZCB0cnVzdGVkIGlucHV0IGtlZXAgd29ya2luZyksXG4gICAqIHVubGlrZSBtaW5pbWl6aW5nLCB3aGljaCB3b3VsZCBmcmVlemUgYHJlcXVlc3RBbmltYXRpb25GcmFtZWAuXG4gICAqXG4gICAqIFRoZSByZW1vdGUgYnJpZGdlIGlzIG5vdCBhdmFpbGFibGUgdGhlIGluc3RhbnQgQ0RQIHN0YXJ0cyBzZXJ2aW5nLCBzbyB0aGlzXG4gICAqIHBvbGxzIHVudGlsIHRoZSBtb3ZlIHN1Y2NlZWRzLiBCZXN0LWVmZm9ydDogaWYgdGhlIHdpbmRvdyBjYW5ub3QgYmUgbW92ZWRcbiAgICogd2l0aGluIHRoZSB0aW1lb3V0LCB0aGUga2VlcC1hbGl2ZSBsYXVuY2ggZmxhZ3Mgc3RpbGwgYXBwbHkgYW5kIHRoZSBydW5cbiAgICogcHJvY2VlZHMgKHdvcnN0IGNhc2UgdGhlIHdpbmRvdyBpcyBicmllZmx5IHZpc2libGUpLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBtb3ZlT3duZWRXaW5kb3dPZmZzY3JlZW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gUmVzb2x2ZSB0aGUgRWxlY3Ryb24gcmVtb3RlIGJyaWRnZSB0d28gd2F5cyBzbyBCT1RIIG1vZGVybiBhbmQgb2xkIE9ic2lkaWFuXG4gICAgLy8gQ2FuIGJlIG1vdmVkIG9mZi1zY3JlZW46IG1vZGVybiBpbmplY3RzIGB3aW5kb3cuZWxlY3Ryb24ucmVtb3RlYDsgb2xkXG4gICAgLy8gVmVyc2lvbnMgKG5vIGB3aW5kb3cuZWxlY3Ryb25gKSBzdGlsbCBleHBvc2UgdGhlIGJ1aWx0LWluIGByZW1vdGVgIG1vZHVsZSB2aWFcbiAgICAvLyBgcmVxdWlyZSgnZWxlY3Ryb24nKWAgaW4gdGhlIG5vZGUtaW50ZWdyYXRlZCByZW5kZXJlciAocmVtb3ZlZCBmcm9tIEVsZWN0cm9uXG4gICAgLy8gMTQrLCBidXQgcHJlc2VudCBvbiB0aGUgRWxlY3Ryb24gOC0xMyBzaGVsbHMgb2xkIE9ic2lkaWFuIHNoaXBzKS4gUmV0dXJuaW5nXG4gICAgLy8gYG1vdmVkYCBvbiB0aGUgZmlyc3Qgc3VjY2VzcyBpcyBpbXBvcnRhbnQgb24gRWxlY3Ryb24gMTAtZXJhIGJ1aWxkczogcG9sbGluZ1xuICAgIC8vIE9uIHdpdGhvdXQgYSByZXNvbHZhYmxlIGJyaWRnZSBoYW1tZXJzIHRoZSByZW5kZXJlciB3aXRoIENEUCByb3VuZC10cmlwc1xuICAgIC8vIER1cmluZyBib290IGFuZCBpbnRlcm1pdHRlbnRseSBwcmV2ZW50cyB0aGUgd29ya3NwYWNlIGZyb20gaW5pdGlhbGl6aW5nLlxuICAgIGNvbnN0IG1vdmVFeHByZXNzaW9uID0gYCgoKSA9PiB7XG4gICAgICBsZXQgcmVtb3RlID0gKHdpbmRvdy5lbGVjdHJvbiAmJiB3aW5kb3cuZWxlY3Ryb24ucmVtb3RlKSB8fCBudWxsO1xuICAgICAgaWYgKCFyZW1vdGUpIHtcbiAgICAgICAgdHJ5IHsgcmVtb3RlID0gcmVxdWlyZSgnZWxlY3Ryb24nKS5yZW1vdGUgfHwgbnVsbDsgfSBjYXRjaCAocmVxdWlyZUVycm9yKSB7IHJlbW90ZSA9IG51bGw7IH1cbiAgICAgIH1cbiAgICAgIGlmICghcmVtb3RlIHx8IHR5cGVvZiByZW1vdGUuZ2V0Q3VycmVudFdpbmRvdyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gKHR5cGVvZiB3aW5kb3cuYXBwID09PSAndW5kZWZpbmVkJykgPyAnbm90LXJlYWR5JyA6ICduby1icmlkZ2UnO1xuICAgICAgfVxuICAgICAgY29uc3Qgd2luID0gcmVtb3RlLmdldEN1cnJlbnRXaW5kb3coKTtcbiAgICAgIGNvbnN0IGRpc3BsYXlzID0gcmVtb3RlLnNjcmVlbi5nZXRBbGxEaXNwbGF5cygpO1xuICAgICAgY29uc3QgbWF4UmlnaHQgPSBNYXRoLm1heCguLi5kaXNwbGF5cy5tYXAoKGRpc3BsYXkpID0+IGRpc3BsYXkuYm91bmRzLnggKyBkaXNwbGF5LmJvdW5kcy53aWR0aCkpO1xuICAgICAgd2luLnNldFBvc2l0aW9uKG1heFJpZ2h0ICsgJHtTdHJpbmcoT1dORURfV0lORE9XX09GRlNDUkVFTl9NQVJHSU5fSU5fUElYRUxTKX0sIDApO1xuICAgICAgcmV0dXJuICdtb3ZlZCc7XG4gICAgfSkoKWA7XG5cbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBPV05FRF9XSU5ET1dfSElERV9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBbdGFyZ2V0XSA9IGF3YWl0IHRoaXMuZ2V0UGFnZVRhcmdldHMoKTtcbiAgICAgICAgaWYgKHRhcmdldCkge1xuICAgICAgICAgIGNvbnN0IHdzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQodGFyZ2V0KTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRDb21tYW5kKHdzLCAnUnVudGltZS5ldmFsdWF0ZScsIHtcbiAgICAgICAgICAgICAgZXhwcmVzc2lvbjogbW92ZUV4cHJlc3Npb24sXG4gICAgICAgICAgICAgIHJldHVybkJ5VmFsdWU6IHRydWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLnJlc3VsdD8ucmVzdWx0Py52YWx1ZSA9PT0gJ21vdmVkJykge1xuICAgICAgICAgICAgICBsb2coJ1tjZHAtdHJhbnNwb3J0XSBNb3ZlZCBvd25lZCBPYnNpZGlhbiB3aW5kb3cgb2ZmLXNjcmVlbiAoaGlkZGVuIG1vZGUpLicpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHdzLmNsb3NlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gQ0RQIGVuZHBvaW50IC8gdGFyZ2V0IC8gcmVtb3RlIGJyaWRnZSBub3QgcmVhZHkgeWV0IFx1MjAxNCBrZWVwIHBvbGxpbmcuXG4gICAgICB9XG4gICAgICBhd2FpdCBkZWxheShPV05FRF9XSU5ET1dfSElERV9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgfVxuICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIENvdWxkIG5vdCBtb3ZlIG93bmVkIHdpbmRvdyBvZmYtc2NyZWVuIHdpdGhpbiAke1N0cmluZyhPV05FRF9XSU5ET1dfSElERV9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXMgKG5vbi1mYXRhbDsga2VlcC1hbGl2ZSBmbGFncyBzdGlsbCBhcHBsaWVkKS5gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVucyBhIHZhdWx0IGluIGFuIGFscmVhZHktcnVubmluZyBPYnNpZGlhbiBpbnN0YW5jZSB2aWEgdGhlIGB2YXVsdC1vcGVuYFxuICAgKiBFbGVjdHJvbiBJUEMgKGV2YWx1YXRlZCB0aHJvdWdoIENEUCBvbiBhbiBleGlzdGluZyB0YXJnZXQpLCB0aGVuIHBvbGxzIHVudGlsXG4gICAqIHRoZSBuZXcgdmF1bHQncyB3aW5kb3cgdGFyZ2V0IGFwcGVhcnMsIGlzIGxheW91dC1yZWFkeSwgYW5kIGl0cyB0cnVzdCBkaWFsb2dcbiAgICogKGlmIGFueSkgaGFzIGJlZW4gZGlzbWlzc2VkLlxuICAgKlxuICAgKiBTaGFyZWQgYnkgdGhlIGF0dGFjaC1tb2RlIHtAbGluayByZWdpc3RlclZhdWx0fSBhbmQgdGhlIG93bmVkLW1vZGVcbiAgICogXCJpbnN0YW5jZSBhbHJlYWR5IGxhdW5jaGVkXCIgcGF0aCwgc28gb3BlbmluZyBhbiBhZGRpdGlvbmFsIHZhdWx0IG5ldmVyXG4gICAqIHJlbGF1bmNoZXMgdGhlIHByb2Nlc3MgKHdoaWNoIHdvdWxkIHN1cmZhY2UgdGhlIHZhdWx0IHBpY2tlcikuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdmF1bHQgZm9sZGVyLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBvcGVuVmF1bHRJblJ1bm5pbmdJbnN0YW5jZSh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIFJlZ2lzdGVyaW5nIHZhdWx0OiAke3ZhdWx0UGF0aH1gKTtcbiAgICBjb25zdCB0YXJnZXRzID0gYXdhaXQgdGhpcy5nZXRQYWdlVGFyZ2V0cygpO1xuICAgIGlmICh0YXJnZXRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBPYnNpZGlhbiBDRFAgdGFyZ2V0cyBhdmFpbGFibGUuIElzIE9ic2lkaWFuIHJ1bm5pbmc/Jyk7XG4gICAgfVxuXG4gICAgLy8gVGhlIGB2YXVsdC1vcGVuYCBJUEMgaXMgc2VudCB0aHJvdWdoIGFuIEVYSVNUSU5HIHdpbmRvdyAoYHRhcmdldHNbMF1gKSwgc28gdGhlXG4gICAgLy8gSGVscGVyIG5hbWVzcGFjZSBtdXN0IGJlIGJvb3RzdHJhcHBlZCBvbiBUSEFUIHdpbmRvdyBcdTIwMTQgbm90IG9uIGB2YXVsdFBhdGhgLCB3aG9zZVxuICAgIC8vIFdpbmRvdyBkb2VzIG5vdCBleGlzdCB5ZXQuIEJvb3RzdHJhcHBpbmcgYWdhaW5zdCBgdmF1bHRQYXRoYCBoZXJlIHdvdWxkIHJvdXRlXG4gICAgLy8gVGhyb3VnaCBgZmluZFRhcmdldEZvclZhdWx0KHZhdWx0UGF0aClgIHdpdGggb25seSB0aGUgZXhpc3Rpbmcgd2luZG93IHByZXNlbnQgYW5kXG4gICAgLy8gUG9pc29uIHRoZSBjb25uZWN0aW9uIGNhY2hlIChsYWJlbCBgdmF1bHRQYXRoYCwgc29ja2V0IFx1MjE5MiB0aGUgZXhpc3Rpbmcgd2luZG93KSwgc29cbiAgICAvLyBFdmVyeSBsYXRlciBldmFsIGZvciBgdmF1bHRQYXRoYCB3b3VsZCBtaXMtcm91dGUgdG8gdGhlIGV4aXN0aW5nIHdpbmRvdy4gUHJvYmUgdGhlXG4gICAgLy8gRXhpc3Rpbmcgd2luZG93J3Mgb3duIGJhc2UgcGF0aCBhbmQgYm9vdHN0cmFwIGFnYWluc3QgdGhhdCBpbnN0ZWFkLlxuICAgIGNvbnN0IGV4aXN0aW5nVGFyZ2V0ID0gZW5zdXJlTm9uTnVsbGFibGUodGFyZ2V0c1swXSk7XG4gICAgY29uc3QgZXhpc3RpbmdWYXVsdFBhdGggPSBhd2FpdCB0aGlzLnByb2JlVmF1bHRQYXRoKGV4aXN0aW5nVGFyZ2V0KTtcbiAgICBjb25zdCBpcGNXcyA9IGF3YWl0IHRoaXMuY29ubmVjdFRvVGFyZ2V0KGV4aXN0aW5nVGFyZ2V0KTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZW5zdXJlTmFtZXNwYWNlQm9vdHN0cmFwcGVkKHRoaXMsIGV4aXN0aW5nVmF1bHRQYXRoKTtcbiAgICAgIGNvbnN0IGlwY0V4cHJlc3Npb24gPSBgd2luZG93Ll9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcuaXBjU2VuZFN5bmMoJHtKU09OLnN0cmluZ2lmeSh7IGNoYW5uZWw6ICd2YXVsdC1vcGVuJywgY2hhbm5lbEFyZ3VtZW50czogW3ZhdWx0UGF0aCwgZmFsc2VdIH0pfSlgO1xuICAgICAgYXdhaXQgdGhpcy5zZW5kQ29tbWFuZChpcGNXcywgJ1J1bnRpbWUuZXZhbHVhdGUnLCB7XG4gICAgICAgIGF3YWl0UHJvbWlzZTogdHJ1ZSxcbiAgICAgICAgZXhwcmVzc2lvbjogaXBjRXhwcmVzc2lvbixcbiAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHRoaXMuZW5hYmxlUGx1Z2luc0luTG9jYWxTdG9yYWdlKGlwY1dzLCB2YXVsdFBhdGgpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpcGNXcy5jbG9zZSgpO1xuICAgIH1cblxuICAgIGxvZyhgW2NkcC10cmFuc3BvcnRdIFBvbGxpbmcgZm9yIHZhdWx0IHRhcmdldCAodGltZW91dD0ke1N0cmluZyhWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcykuLi5gKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZmluZFRhcmdldEZvclZhdWx0KHZhdWx0UGF0aCk7XG4gICAgICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIFZhdWx0IHRhcmdldCBmb3VuZC4nKTtcbiAgICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yTGF5b3V0UmVhZHkodmF1bHRQYXRoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5kaXNtaXNzVHJ1c3REaWFsb2codmF1bHRQYXRoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIFZhdWx0IHRhcmdldCBub3QgcmVhZHkgeWV0LlxuICAgICAgfVxuICAgICAgYXdhaXQgZGVsYXkoVkFVTFRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYFZhdWx0IGF0ICR7dmF1bHRQYXRofSBkaWQgbm90IGJlY29tZSByZWFkeSB3aXRoaW4gJHtTdHJpbmcoVkFVTFRfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXNgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTYW1wbGVzIHRoZSB2YXVsdCByZW5kZXJlcidzIGJvb3RzdHJhcCBzdGF0ZSBcdTIwMTQgd2hldGhlciB0aGUgZG9jdW1lbnQgaXNcbiAgICogYGNvbXBsZXRlYCwgd2hldGhlciBgd2luZG93LmFwcGAgZXhpc3RzLCBhbmQgdGhlIGA8Ym9keT5gIGNoaWxkIGNvdW50IFx1MjAxNCBmcm9tXG4gICAqIHRoZSBmaXJzdCBwYWdlIHRhcmdldCwgZm9yIGRlYWQtYm9vdCBkZXRlY3Rpb24uIFRoaXMgd29ya3MgZXZlbiB3aGVuIHRoZSBhcHBcbiAgICogbmV2ZXIgYm9vdHN0cmFwcGVkICh0aGUgcmVuZGVyZXIgcGFnZSB0YXJnZXQgc3RpbGwgZXhpc3RzKSwgd2hpY2ggaXMgZXhhY3RseVxuICAgKiB0aGUgc3RhdGUgaXQgbXVzdCBvYnNlcnZlLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgc2FtcGxlZCBvYnNlcnZhdGlvbiwgb3IgYHVuZGVmaW5lZGAgd2hlbiBubyB0YXJnZXQgaXMgcmVhY2hhYmxlXG4gICAqICAgb3IgdGhlIHByb2JlIGZhaWxlZCAoc28gdGhlIGNhbGxlciBrZWVwcyBwb2xsaW5nIHJhdGhlciB0aGFuIGZhc3QtZmFpbGluZykuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHByb2JlUmVuZGVyZXJCb290U3RhdGUoKTogUHJvbWlzZTxSZW5kZXJlckJvb3RPYnNlcnZhdGlvbiB8IHVuZGVmaW5lZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBbdGFyZ2V0XSA9IGF3YWl0IHRoaXMuZ2V0UGFnZVRhcmdldHMoKTtcbiAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHdzID0gYXdhaXQgdGhpcy5jb25uZWN0VG9UYXJnZXQodGFyZ2V0KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHByb2JlRXhwcmVzc2lvbiA9IGBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgYm9keUNoaWxkRWxlbWVudENvdW50OiBkb2N1bWVudC5ib2R5ID8gZG9jdW1lbnQuYm9keS5jaGlsZEVsZW1lbnRDb3VudCA6IDAsXG4gICAgICAgICAgaGFzV2luZG93QXBwOiB0eXBlb2Ygd2luZG93LmFwcCAhPT0gJ3VuZGVmaW5lZCcsXG4gICAgICAgICAgaXNEb2N1bWVudENvbXBsZXRlOiBkb2N1bWVudC5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnXG4gICAgICAgIH0pYDtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRDb21tYW5kKHdzLCAnUnVudGltZS5ldmFsdWF0ZScsIHtcbiAgICAgICAgICBleHByZXNzaW9uOiBwcm9iZUV4cHJlc3Npb24sXG4gICAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSByZXNwb25zZS5yZXN1bHQ/LnJlc3VsdD8udmFsdWU7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZSh2YWx1ZSkgYXMgUmVuZGVyZXJCb290T2JzZXJ2YXRpb247XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB3cy5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHJvYmVzIGEgdGFyZ2V0IHRvIGRpc2NvdmVyIHdoaWNoIHZhdWx0IHBhdGggaXQgaGFzIG9wZW4uXG4gICAqXG4gICAqIENyZWF0ZXMgYSB0ZW1wb3JhcnkgV2ViU29ja2V0IGNvbm5lY3Rpb24sIGV2YWx1YXRlcyBgZ2V0QmFzZVBhdGgoKWAsXG4gICAqIGFuZCByZXR1cm5zIHRoZSByZXN1bHQuXG4gICAqXG4gICAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgQ0RQIHRhcmdldCB0byBwcm9iZS5cbiAgICogQHJldHVybnMgVGhlIHZhdWx0J3MgYmFzZSBwYXRoLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9iZVZhdWx0UGF0aCh0YXJnZXQ6IENkcFRhcmdldCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3Qgd3MgPSBhd2FpdCB0aGlzLmNvbm5lY3RUb1RhcmdldCh0YXJnZXQpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuc2VuZENvbW1hbmQod3MsICdSdW50aW1lLmV2YWx1YXRlJywge1xuICAgICAgICAvLyBPbGQgT2JzaWRpYW4gdmVyc2lvbnMgKGUuZy4gMC42LngpIHByZWRhdGUgdGhlIGBnZXRCYXNlUGF0aCgpYCBtZXRob2QgYnV0XG4gICAgICAgIC8vIEV4cG9zZSB0aGUgYGJhc2VQYXRoYCBwcm9wZXJ0eTsgdGhlIG1ldGhvZCBleGlzdHMgZnJvbSB+MC45LjIwIG9ud2FyZC5cbiAgICAgICAgZXhwcmVzc2lvbjogJ2FwcC52YXVsdC5hZGFwdGVyLmdldEJhc2VQYXRoID8gYXBwLnZhdWx0LmFkYXB0ZXIuZ2V0QmFzZVBhdGgoKSA6IGFwcC52YXVsdC5hZGFwdGVyLmJhc2VQYXRoJyxcbiAgICAgICAgcmV0dXJuQnlWYWx1ZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gU3RyaW5nKHJlc3BvbnNlLnJlc3VsdD8ucmVzdWx0Py52YWx1ZSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHdzLmNsb3NlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExhdW5jaGVzIGFuZCBjb25uZWN0cyB0byBhIGhhcm5lc3Mtb3duZWQsIGlzb2xhdGVkIE9ic2lkaWFuIGluc3RhbmNlIGZvciBhXG4gICAqIHZhdWx0OiBwcm92aXNpb25zIHRoZSBhc2FyIChpZiBhbnkpLCBwcmUtc2VlZHMgdGhlIGlzb2xhdGVkIGBvYnNpZGlhbi5qc29uYFxuICAgKiBzbyB0aGUgdmF1bHQgb3BlbnMgZGlyZWN0bHksIGxhdW5jaGVzIHRoZSBpbnN0YW5jZSBvbiBhIGZyZWUgQ0RQIHBvcnQsIHRoZW5cbiAgICogd2FpdHMgdW50aWwgdGhlIHZhdWx0IHdpbmRvdyBpcyByZWFkeSBhbmQgZGlzbWlzc2VzIHRoZSB0cnVzdCBkaWFsb2cuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdmF1bHQgZm9sZGVyLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWdpc3RlclZhdWx0SW5Pd25lZEluc3RhbmNlKHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY29uZmlnID0gZW5zdXJlTm9uTnVsbGFibGUodGhpcy5vd25lZENvbmZpZyk7XG5cbiAgICBta2RpclN5bmMoY29uZmlnLnVzZXJEYXRhRGlyZWN0b3J5LCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBpZiAoY29uZmlnLmFzYXIpIHtcbiAgICAgIGNvcHlBc2FySW50b1VzZXJEYXRhKGNvbmZpZy5hc2FyLnBhdGgsIGNvbmZpZy5hc2FyLnZlcnNpb24sIGNvbmZpZy51c2VyRGF0YURpcmVjdG9yeSk7XG4gICAgfVxuXG4gICAgY29uc3QgdmF1bHRJZCA9IHJhbmRvbUJ5dGVzKFZBVUxUX0lEX0JZVEVfTEVOR1RIKS50b1N0cmluZygnaGV4Jyk7XG4gICAgY29uc3Qgb2JzaWRpYW5Kc29uID0gYnVpbGRPd25lZE9ic2lkaWFuSnNvbih7IHRzOiBEYXRlLm5vdygpLCB2YXVsdElkLCB2YXVsdFBhdGggfSk7XG4gICAgd3JpdGVGaWxlU3luYyhqb2luKGNvbmZpZy51c2VyRGF0YURpcmVjdG9yeSwgJ29ic2lkaWFuLmpzb24nKSwgSlNPTi5zdHJpbmdpZnkob2JzaWRpYW5Kc29uKSk7XG5cbiAgICAvLyBSZWxhdW5jaC1yZXRyeTogc29tZSBvbGQgKEVsZWN0cm9uIDEwLWVyYSkgT2JzaWRpYW4gYnVpbGRzIGludGVybWl0dGVudGx5XG4gICAgLy8gQm9vdCB3aXRoIGB3aW5kb3cuYXBwYCBwcmVzZW50IGJ1dCB0aGUgd29ya3NwYWNlIG5ldmVyIGluaXRpYWxpemluZywgc28gdGhlXG4gICAgLy8gVmF1bHQgbmV2ZXIgYmVjb21lcyByZWFkeS4gQSBmcmVzaCBpbnN0YW5jZSBpcyBhbiBpbmRlcGVuZGVudCBjaGFuY2UuIEFcbiAgICAvLyBEZXRlcm1pbmlzdGljIGZhaWx1cmUgKGRlYWQgYm9vdCwgc2lsZW50IGFzYXIgZmFsbGJhY2spIGlzIHJlLXRocm93biBhdCBvbmNlIFx1MjAxNFxuICAgIC8vIFJldHJ5aW5nIGl0IG9ubHkgd2FzdGVzIHRoZSByZWFkaW5lc3MgdGltZW91dC5cbiAgICBsZXQgbGFzdEVycm9yOiB1bmtub3duO1xuICAgIGZvciAobGV0IGF0dGVtcHQgPSAxOyBhdHRlbXB0IDw9IE9XTkVEX0xBVU5DSF9NQVhfQVRURU1QVFM7IGF0dGVtcHQrKykge1xuICAgICAgYXdhaXQgdGhpcy5raWxsUnVubmluZ093bmVkSW5zdGFuY2UoKTtcbiAgICAgIGlmIChhdHRlbXB0ID4gMSkge1xuICAgICAgICBhd2FpdCBkZWxheShPV05FRF9SRUxBVU5DSF9TRVRUTEVfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBsYXVuY2hPd25lZE9ic2lkaWFuSW5zdGFuY2Uoe1xuICAgICAgICBjZHBIb3N0OiB0aGlzLmNkcEhvc3QsXG4gICAgICAgIGV4ZVBhdGg6IGNvbmZpZy5leGVQYXRoLFxuICAgICAgICBleHRyYUFyZ3VtZW50czogW1xuICAgICAgICAgIC4uLnJlc29sdmVPd25lZEhpZGRlbkxhdW5jaEFyZ3VtZW50cyh0aGlzLmlzT2JzaWRpYW5BcHBWaXNpYmxlKSxcbiAgICAgICAgICAuLi5yZXNvbHZlU2FuZGJveExhdW5jaEFyZ3VtZW50cyh0aGlzLnNob3VsZERpc2FibGVTYW5kYm94KVxuICAgICAgICBdLFxuXG4gICAgICAgIHVzZXJEYXRhRGlyZWN0b3J5OiBjb25maWcudXNlckRhdGFEaXJlY3RvcnlcbiAgICAgIH0pO1xuICAgICAgdGhpcy5vd25lZEluc3RhbmNlID0gaW5zdGFuY2U7XG4gICAgICB0aGlzLmNkcFBvcnQgPSBpbnN0YW5jZS5wb3J0O1xuICAgICAgdGhpcy5jZHBVcmwgPSBpbnN0YW5jZS5jZHBVcmw7XG5cbiAgICAgIGlmIChzaG91bGRIaWRlT2JzaWRpYW5BcHAodGhpcy5pc09ic2lkaWFuQXBwVmlzaWJsZSkpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5tb3ZlT3duZWRXaW5kb3dPZmZzY3JlZW4oKTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yT3duZWRWYXVsdFJlYWR5KHZhdWx0UGF0aCk7XG4gICAgICAgIGF3YWl0IHRoaXMuYXJtUGFyZW50TGl2ZW5lc3NXYXRjaGRvZyh2YXVsdFBhdGgsIGluc3RhbmNlLnBhcmVudExpdmVuZXNzUG9ydCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFJlbmRlcmVyRmFpbGVkVG9Jbml0aWFsaXplRXJyb3IgfHwgZXJyb3IgaW5zdGFuY2VvZiBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvcikge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RFcnJvciA9IGVycm9yO1xuICAgICAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBPd25lZCB2YXVsdCBub3QgcmVhZHkgKGF0dGVtcHQgJHtTdHJpbmcoYXR0ZW1wdCl9LyR7U3RyaW5nKE9XTkVEX0xBVU5DSF9NQVhfQVRURU1QVFMpfSk6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhyb3cgbGFzdEVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBsYXN0RXJyb3IgOiBuZXcgRXJyb3IoYE93bmVkIHZhdWx0IGF0ICR7dmF1bHRQYXRofSBkaWQgbm90IGJlY29tZSByZWFkeWApO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmRzIGEgQ0RQIGNvbW1hbmQgb3ZlciBXZWJTb2NrZXQgYW5kIHdhaXRzIGZvciB0aGUgcmVzcG9uc2UuXG4gICAqXG4gICAqIEBwYXJhbSB3cyAtIFRoZSBXZWJTb2NrZXQgY29ubmVjdGlvbi5cbiAgICogQHBhcmFtIG1ldGhvZCAtIFRoZSBDRFAgbWV0aG9kIG5hbWUuXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgQ0RQIG1ldGhvZCBwYXJhbWV0ZXJzLlxuICAgKiBAcmV0dXJucyBUaGUgQ0RQIHJlc3BvbnNlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzZW5kQ29tbWFuZCh3czogV2ViU29ja2V0LCBtZXRob2Q6IHN0cmluZywgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFByb21pc2U8Q2RwUmVzcG9uc2U+IHtcbiAgICBjb25zdCBpZCA9ICsrdGhpcy5tZXNzYWdlSWQ7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2U8Q2RwUmVzcG9uc2U+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgd3MucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGhhbmRsZXIpO1xuICAgICAgICByZWplY3QobmV3IEVycm9yKGBDRFAgY29tbWFuZCB0aW1lZCBvdXQgYWZ0ZXIgJHtTdHJpbmcodGhpcy5jb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzKX1tczogJHttZXRob2R9YCkpO1xuICAgICAgfSwgdGhpcy5jb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzKTtcblxuICAgICAgZnVuY3Rpb24gaGFuZGxlcihldmVudDogTWVzc2FnZUV2ZW50KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBKU09OLnBhcnNlKFN0cmluZyhldmVudC5kYXRhKSkgYXMgQ2RwUmVzcG9uc2U7XG4gICAgICAgIGlmIChtZXNzYWdlLmlkID09PSBpZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgICB3cy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgaGFuZGxlcik7XG4gICAgICAgICAgcmVzb2x2ZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB3cy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgaGFuZGxlcik7XG4gICAgICB3cy5zZW5kKEpTT04uc3RyaW5naWZ5KHsgaWQsIG1ldGhvZCwgcGFyYW1zIH0pKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyBhIGtpbGxlZCBvd25lZCBpbnN0YW5jZSdzIENEUCBlbmRwb2ludCB1bnRpbCBpdCBzdG9wcyByZXNwb25kaW5nLFxuICAgKiBjb25maXJtaW5nIHRoZSBwcm9jZXNzIGhhcyBleGl0ZWQgYW5kIHJlbGVhc2VkIEVsZWN0cm9uJ3Mgc2luZ2xlLWluc3RhbmNlXG4gICAqIGxvY2sgb24gdGhlIHNoYXJlZCB1c2VyLWRhdGEgZGlyZWN0b3J5IGJlZm9yZSBhIGZyZXNoIGluc3RhbmNlIGlzIGxhdW5jaGVkIGludG8gaXQuXG4gICAqXG4gICAqIEBwYXJhbSBjZHBVcmwgLSBUaGUgQ0RQIFVSTCBvZiB0aGUgaW5zdGFuY2UgdGhhdCB3YXMganVzdCBraWxsZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JJbnN0YW5jZUV4aXQoY2RwVXJsOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2coYFtjZHAtdHJhbnNwb3J0XSBXYWl0aW5nIGZvciBwcmV2aW91cyBvd25lZCBpbnN0YW5jZSBhdCAke2NkcFVybH0gdG8gZXhpdC4uLmApO1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIFZBVUxUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgJHtjZHBVcmx9L2pzb25gKTtcbiAgICAgICAgYXdhaXQgcmVzcG9uc2UuYm9keT8uY2FuY2VsKCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gVGhlIGVuZHBvaW50IGlzIGdvbmU6IHRoZSBwcm9jZXNzIGhhcyBleGl0ZWQgYW5kIHJlbGVhc2VkIHRoZSBsb2NrLlxuICAgICAgICBhd2FpdCBkZWxheShJTlNUQU5DRV9FWElUX1NFVFRMRV9ERUxBWV9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBhd2FpdCBkZWxheShWQVVMVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgfVxuICAgIGxvZygnW2NkcC10cmFuc3BvcnRdIFByZXZpb3VzIGluc3RhbmNlIHN0aWxsIHJlc3BvbmRlZCBiZWZvcmUgdGltZW91dDsgcmVsYXVuY2hpbmcgYW55d2F5LicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhaXRzIGZvciB0aGUgdmF1bHQncyBgYXBwLndvcmtzcGFjZWAgdG8gcmVhY2ggbGF5b3V0LXJlYWR5IHN0YXRlLlxuICAgKlxuICAgKiBgZmluZFRhcmdldEZvclZhdWx0YCByZXR1cm5zIGFzIHNvb24gYXMgYGFwcC52YXVsdC5hZGFwdGVyLmdldEJhc2VQYXRoKClgXG4gICAqIG1hdGNoZXMgXHUyMDE0IHdoaWNoIGlzIHRydWUgc2hvcnRseSBhZnRlciB0aGUgYEFwcGAgY29uc3RydWN0b3IgcnVucywgYmVmb3JlXG4gICAqIGBwbHVnaW5zLmluaXRpYWxpemUoKWAgKGFuZCBhbnkgdHJ1c3QgZGlhbG9nKSBoYXMgZXhlY3V0ZWQuIEJvb3RzdHJhcHBpbmdcbiAgICogdGhlIG5hbWVzcGFjZSBhbmQgY2FsbGluZyBgcG9sbFZhdWx0QmFzZVBhdGgoKWAgYXdhaXRzIGBsYXlvdXRSZWFkeWAsIHNvXG4gICAqIGJ5IHRoZSB0aW1lIHRoaXMgcmV0dXJucyB0aGUgZGlhbG9nIGhhcyBlaXRoZXIgcmVuZGVyZWQgb3IgaXMgbm90IGdvaW5nXG4gICAqIHRvIHJlbmRlci5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoIHRvIGV2YWx1YXRlIGluLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yTGF5b3V0UmVhZHkodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBlbnN1cmVOYW1lc3BhY2VCb290c3RyYXBwZWQodGhpcywgdmF1bHRQYXRoKTtcbiAgICBhd2FpdCB0aGlzLmV2YWx1YXRlKCd3aW5kb3cuX19vYnNpZGlhbkludGVncmF0aW9uVGVzdGluZy5wb2xsVmF1bHRCYXNlUGF0aCgpJywgeyBjd2Q6IHZhdWx0UGF0aCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyB0aGUgb3duZWQgaW5zdGFuY2UgdW50aWwgdGhlIHZhdWx0IHRhcmdldCBleGlzdHMsIGxheW91dCBpcyByZWFkeSwgYW5kXG4gICAqIHRoZSB0cnVzdCBkaWFsb2cgKGlmIGFueSkgaGFzIGJlZW4gZGlzbWlzc2VkLlxuICAgKlxuICAgKiBCZXR3ZWVuIHJlYWRpbmVzcyBhdHRlbXB0cyBpdCBhbHNvIGNoZWNrcyBmb3IgYSAqKmRlYWQgYm9vdCoqIFx1MjAxNCB0aGUgcmVuZGVyZXJcbiAgICogbG9hZGVkIChgZG9jdW1lbnQucmVhZHlTdGF0ZWAgYCdjb21wbGV0ZSdgKSBidXQgdGhlIGFwcCBuZXZlciBib290c3RyYXBwZWRcbiAgICogKGVtcHR5IGA8Ym9keT5gLCBubyBgd2luZG93LmFwcGApLCB0aGUgdGVybWluYWwgc3RhdGUgd2hlbiB0aGUgYXNhciBjYW5ub3RcbiAgICogcnVuIG9uIHRoZSBsYXVuY2hlZCBFbGVjdHJvbiBzaGVsbC4gT25jZSB0aGF0IHN0YXRlIGhhcyBoZWxkIGZvciB0aGVcbiAgICogY29uZmlndXJlZCBncmFjZSB3aW5kb3cgaXQgdGhyb3dzIGEge0BsaW5rIFJlbmRlcmVyRmFpbGVkVG9Jbml0aWFsaXplRXJyb3J9XG4gICAqIGltbWVkaWF0ZWx5IGluc3RlYWQgb2Ygd2FpdGluZyBvdXQgdGhlIGZ1bGwgcmVhZGluZXNzIHRpbWVvdXQuIEEgZ3JhY2Ugb2ZcbiAgICogYDBgIGRpc2FibGVzIHRoZSBmYXN0LWZhaWwuIFRoZSBncmFjZSBjbG9jayBzdGFydHMgd2hlbiB0aGUgcmVuZGVyZXIgZmlyc3RcbiAgICogcmVwb3J0cyBgY29tcGxldGVgLCBzbyBhIHNsb3cgbG9hZCBiZWZvcmUgdGhlbiBpcyBuZXZlciBjb3VudGVkIGFnYWluc3QgaXQuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdmF1bHQgZm9sZGVyLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yT3duZWRWYXVsdFJlYWR5KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKGBbY2RwLXRyYW5zcG9ydF0gV2FpdGluZyBmb3Igb3duZWQgdmF1bHQgdG8gYmVjb21lIHJlYWR5ICh0aW1lb3V0PSR7U3RyaW5nKFZBVUxUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMpfW1zKS4uLmApO1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIFZBVUxUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgbGV0IGRvY3VtZW50Q29tcGxldGVTaW5jZTogbnVsbCB8IG51bWJlciA9IG51bGw7XG4gICAgbGV0IGlzUmVhZHkgPSBmYWxzZTtcbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLmZpbmRUYXJnZXRGb3JWYXVsdCh2YXVsdFBhdGgpO1xuICAgICAgICBhd2FpdCB0aGlzLndhaXRGb3JMYXlvdXRSZWFkeSh2YXVsdFBhdGgpO1xuICAgICAgICBhd2FpdCB0aGlzLmRpc21pc3NUcnVzdERpYWxvZyh2YXVsdFBhdGgpO1xuICAgICAgICBpc1JlYWR5ID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gVGhlIHZhdWx0IGlzIG5vdCByZWFkeSB5ZXQgXHUyMDE0IGFsc28gZHJvcCB0aGUgY2FjaGVkIENEUCBjb25uZWN0aW9uIGJlZm9yZVxuICAgICAgICAvLyBSZXRyeWluZy4gT2xkIChFbGVjdHJvbiAxMC1lcmEpIE9ic2lkaWFuIHJlbG9hZHMgdGhlIG93bmVkIHdpbmRvdyBkdXJpbmdcbiAgICAgICAgLy8gQm9vdCwgd2hpY2ggY2FuIGxlYXZlIHRoZSBjYWNoZWQgV2ViU29ja2V0IHBpbm5lZCB0byBhIHN0YWxlIGV4ZWN1dGlvblxuICAgICAgICAvLyBDb250ZXh0OyByZWNvbm5lY3RpbmcgZWFjaCBhdHRlbXB0IHJlLWJpbmRzIHRvIHRoZSBsaXZlIGNvbnRleHQuXG4gICAgICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5kZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHMgPiAwKSB7XG4gICAgICAgIGNvbnN0IG9ic2VydmF0aW9uID0gYXdhaXQgdGhpcy5wcm9iZVJlbmRlcmVyQm9vdFN0YXRlKCk7XG4gICAgICAgIGlmIChvYnNlcnZhdGlvbikge1xuICAgICAgICAgIGlmIChvYnNlcnZhdGlvbi5pc0RvY3VtZW50Q29tcGxldGUgJiYgZG9jdW1lbnRDb21wbGV0ZVNpbmNlID09PSBudWxsKSB7XG4gICAgICAgICAgICBkb2N1bWVudENvbXBsZXRlU2luY2UgPSBEYXRlLm5vdygpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBoYXNHcmFjZUVsYXBzZWQgPSBkb2N1bWVudENvbXBsZXRlU2luY2UgIT09IG51bGxcbiAgICAgICAgICAgICYmIERhdGUubm93KCkgLSBkb2N1bWVudENvbXBsZXRlU2luY2UgPj0gdGhpcy5kZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHM7XG4gICAgICAgICAgaWYgKHJlc29sdmVSZW5kZXJlckJvb3RTdGF0ZSh7IC4uLm9ic2VydmF0aW9uLCBoYXNHcmFjZUVsYXBzZWQgfSkgPT09ICdkZWFkJykge1xuICAgICAgICAgICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gT3duZWQgcmVuZGVyZXIgZmFpbGVkIHRvIGluaXRpYWxpemUgKGRlYWQgYm9vdCk7IGZhaWxpbmcgZmFzdC4nKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBSZW5kZXJlckZhaWxlZFRvSW5pdGlhbGl6ZUVycm9yKHZhdWx0UGF0aCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGRlbGF5KFZBVUxUX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICB9XG5cbiAgICBpZiAoIWlzUmVhZHkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgT3duZWQgdmF1bHQgYXQgJHt2YXVsdFBhdGh9IGRpZCBub3QgYmVjb21lIHJlYWR5IHdpdGhpbiAke1N0cmluZyhWQVVMVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tc2ApO1xuICAgIH1cblxuICAgIC8vIFRoZSB2YXVsdCBpcyByZWFkeS4gUnVuIHRoZSBwb3N0LWJvb3QgY29tcGF0aWJpbGl0eSBjaGVja3MgaGVyZSBcdTIwMTQgT1VUU0lERSB0aGVcbiAgICAvLyBQb2xsJ3MgdHJ5L2NhdGNoIFx1MjAxNCBzbyBhIFNpbGVudEFzYXJGYWxsYmFja0Vycm9yIGZhaWxzIGZhc3QgaW5zdGVhZCBvZiBiZWluZ1xuICAgIC8vIFN3YWxsb3dlZCBhcyBcIm5vdCByZWFkeSB5ZXRcIiBhbmQgbG9vcGluZyB1bnRpbCB0aGUgcmVhZGluZXNzIHRpbWVvdXQuXG4gICAgYXdhaXQgdGhpcy5jaGVja1J1bnRpbWVDb21wYXRpYmlsaXR5KHZhdWx0UGF0aCk7XG4gICAgbG9nKCdbY2RwLXRyYW5zcG9ydF0gT3duZWQgdmF1bHQgaXMgcmVhZHkuJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIHRoZSBnaXZlbiBkZWxheS5cbiAqXG4gKiBAcGFyYW0gbXMgLSBUaGUgZGVsYXkgaW4gbWlsbGlzZWNvbmRzLlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIGRlbGF5LlxuICovXG5mdW5jdGlvbiBkZWxheShtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBBdHRlbXB0cyB0byByZW1vdmUgYSBkaXJlY3RvcnkgcmVjdXJzaXZlbHksIHJldHVybmluZyB3aGV0aGVyIGl0IHN1Y2NlZWRlZC5cbiAqXG4gKiBAcGFyYW0gZGlyZWN0b3J5IC0gVGhlIGRpcmVjdG9yeSB0byByZW1vdmUuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgcmVtb3ZlZCwgYGZhbHNlYCBpZiB0aGUgcmVtb3ZhbCB0aHJldyAoZS5nLiBoYW5kbGVzIGhlbGQpLlxuICovXG5mdW5jdGlvbiBkaWRSZW1vdmVEaXJlY3RvcnkoZGlyZWN0b3J5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICBybVN5bmMoZGlyZWN0b3J5LCB7IGZvcmNlOiB0cnVlLCByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHBsYXRmb3JtLXNwZWNpZmljIGNvbW1hbmQgdG8gbGF1bmNoIE9ic2lkaWFuIHdpdGggcmVtb3RlIGRlYnVnZ2luZyBlbmFibGVkLlxuICpcbiAqIFJlc29sdmVzIHRoZSBhY3R1YWwgaW5zdGFsbGVkIE9ic2lkaWFuIGV4ZWN1dGFibGUgKGNvdmVyaW5nIGluc3RhbGxlci1iYXNlZFxuICogYW5kIGBQQVRIYC1iYXNlZCBpbnN0YWxscyBzdWNoIGFzIGBzY29vcGApIGFuZCB2ZXJpZmllcyBpdCBleGlzdHMgYmVmb3JlXG4gKiByZXR1cm5pbmcgYSBjb21tYW5kLiBUaHJvd3MgaWYgT2JzaWRpYW4gaXMgbm90IGluc3RhbGxlZC5cbiAqXG4gKiBAcGFyYW0gcG9ydCAtIFRoZSBDRFAgcG9ydCB0byB1c2UuXG4gKiBAcmV0dXJucyBUaGUgc2hlbGwgY29tbWFuZCBzdHJpbmcuXG4gKiBAdGhyb3dzIEVycm9yIGlmIE9ic2lkaWFuIGNhbm5vdCBiZSBsb2NhdGVkLlxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRPYnNpZGlhbkxhdW5jaENvbW1hbmQocG9ydDogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgZXhlUGF0aCA9IGF3YWl0IHJlc29sdmVPYnNpZGlhbkV4ZWN1dGFibGUoKTtcbiAgY29uc3QgZmxhZyA9IGAtLXJlbW90ZS1kZWJ1Z2dpbmctcG9ydD0ke1N0cmluZyhwb3J0KX1gO1xuXG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKSB7XG4gICAgcmV0dXJuIGBzdGFydCBcIlwiIFwiJHtleGVQYXRofVwiICR7ZmxhZ31gO1xuICB9XG5cbiAgcmV0dXJuIGBcIiR7ZXhlUGF0aH1cIiAke2ZsYWd9ICZgO1xufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sCiAgIm1hcHBpbmdzIjogIkFBcUJBLFNBQVMsbUJBQW1CO0FBQzVCO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsWUFBWTtBQUNyQixPQUFPLGFBQWE7QUFZcEIsU0FBUywyQkFBMkI7QUFDcEMsU0FBUyxpQ0FBaUM7QUFDMUMsU0FBUyxpQ0FBaUM7QUFDMUMsU0FBUyxvQ0FBb0M7QUFDN0MsU0FBUyxZQUFZO0FBQ3JCLFNBQVMsV0FBVztBQUNwQixTQUFTLG1DQUFtQztBQUM1QztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUCxTQUFTLGlDQUFpQztBQUMxQyxTQUFTLG1DQUFtQztBQUM1QyxTQUFTLDBCQUEwQjtBQUNuQyxTQUFTLDRCQUE0QjtBQUNyQyxTQUFTLDhCQUE4QjtBQUN2QyxTQUFTLDZDQUE2QztBQUN0RDtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMs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
|