obsidian-integration-testing 9.1.1 → 9.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +106 -13
  2. package/dist/lib/cjs/connect-to-cdp.cjs +23 -2
  3. package/dist/lib/cjs/global-setup-core.cjs +28 -1
  4. package/dist/lib/cjs/index.cjs +12 -1
  5. package/dist/lib/cjs/index.d.cts +5 -0
  6. package/dist/lib/cjs/leftover-cleanup.cjs +116 -0
  7. package/dist/lib/cjs/leftover-cleanup.d.cts +163 -0
  8. package/dist/lib/cjs/library.cjs +1 -1
  9. package/dist/lib/cjs/obsidian-metadata.cjs +15 -1
  10. package/dist/lib/cjs/run-version-matrix.cjs +64 -0
  11. package/dist/lib/cjs/run-version-matrix.d.cts +49 -0
  12. package/dist/lib/cjs/setup-lock.cjs +145 -32
  13. package/dist/lib/cjs/setup-lock.d.cts +9 -3
  14. package/dist/lib/cjs/temp-vault.cjs +3 -2
  15. package/dist/lib/cjs/transport-appium.cjs +86 -30
  16. package/dist/lib/cjs/transport-appium.d.cts +43 -3
  17. package/dist/lib/cjs/transport-factory.cjs +52 -4
  18. package/dist/lib/cjs/transport-options.cjs +1 -1
  19. package/dist/lib/cjs/transport-options.d.cts +57 -0
  20. package/dist/lib/cjs/version-matrix.cjs +175 -0
  21. package/dist/lib/cjs/version-matrix.d.cts +224 -0
  22. package/dist/lib/esm/connect-to-cdp.mjs +27 -2
  23. package/dist/lib/esm/global-setup-core.mjs +36 -2
  24. package/dist/lib/esm/index.d.mts +5 -0
  25. package/dist/lib/esm/index.mjs +11 -1
  26. package/dist/lib/esm/leftover-cleanup.d.mts +163 -0
  27. package/dist/lib/esm/leftover-cleanup.mjs +88 -0
  28. package/dist/lib/esm/library.mjs +1 -1
  29. package/dist/lib/esm/obsidian-metadata.mjs +15 -1
  30. package/dist/lib/esm/run-version-matrix.d.mts +49 -0
  31. package/dist/lib/esm/run-version-matrix.mjs +48 -0
  32. package/dist/lib/esm/setup-lock.d.mts +9 -3
  33. package/dist/lib/esm/setup-lock.mjs +145 -32
  34. package/dist/lib/esm/temp-vault.mjs +3 -2
  35. package/dist/lib/esm/transport-appium.d.mts +43 -3
  36. package/dist/lib/esm/transport-appium.mjs +84 -29
  37. package/dist/lib/esm/transport-factory.mjs +62 -5
  38. package/dist/lib/esm/transport-options.d.mts +57 -0
  39. package/dist/lib/esm/version-matrix.d.mts +224 -0
  40. package/dist/lib/esm/version-matrix.mjs +147 -0
  41. package/dist/obsidian-integration-testing-9.2.0.tgz +0 -0
  42. package/package.json +18 -25
  43. package/dist/obsidian-integration-testing-9.1.1.tgz +0 -0
package/README.md CHANGED
@@ -667,6 +667,63 @@ environmentOptions: {
667
667
  - **`obsidianVersion`** pins the app code (asar). When omitted, the owned instance runs the same version your installed Obsidian currently runs.
668
668
  - **`obsidianInstallerVersion`** pins the Electron shell (installer build), downloaded and extracted from the matching GitHub release (Windows installers require [7-Zip](https://www.7-zip.org/) on `PATH`). Public releases only — catalyst/beta builds have no public installer, so a catalyst version can only be pinned at the asar level.
669
669
 
670
+ ##### Running against every supported version (`runObsidianVersionMatrix`)
671
+
672
+ Obsidian support is a **range** — `[latest public, latest catalyst]` — and both ends are expected to work. The two ends periodically **coincide**: when public catches up to catalyst, `public-latest` and `catalyst-latest` provision the same build, so running the suites twice re-runs the same build and verifies nothing extra. Worse, a project that runs both still reports "green on public **and** catalyst" — a two-end claim it never actually verified.
673
+
674
+ `runObsidianVersionMatrix` makes that decision once, in the harness:
675
+
676
+ ```ts
677
+ // scripts/test-integration-desktop.ts
678
+ import { runObsidianVersionMatrix } from 'obsidian-integration-testing';
679
+
680
+ await runObsidianVersionMatrix({
681
+ // Defaults to ['public-latest', 'catalyst-latest'].
682
+ // Accepts an array or a comma-separated string, so an env var passes straight through.
683
+ versions: process.env.OBSIDIAN_VERSION,
684
+ run: ({ version }) => {
685
+ const result = spawnSync('npx', ['vitest', 'run', '--project=integration-tests:desktop'], {
686
+ env: { ...process.env, OBSIDIAN_VERSION: version },
687
+ shell: true,
688
+ stdio: 'inherit',
689
+ });
690
+ if (result.status !== 0) {
691
+ throw new Error(`Exit code ${String(result.status)}`);
692
+ }
693
+ },
694
+ });
695
+ ```
696
+
697
+ Your test config keeps reading the version the same way it always did — the runner just decides how many times to invoke it:
698
+
699
+ ```ts
700
+ environmentOptions: {
701
+ obsidianTransport: {
702
+ type: 'obsidian-cdp',
703
+ obsidianVersion: process.env.OBSIDIAN_VERSION ?? 'public-latest',
704
+ },
705
+ }
706
+ ```
707
+
708
+ - **De-duplication is keyed on the *resolved* version, never the specifier string.** `['1.13.4', 'catalyst-latest']` collapses to a single run when catalyst *is* `1.13.4`, exactly as `['public-latest', 'catalyst-latest']` does when the channels converge.
709
+ - **The decision is always stated in the log**, so one run where you expected two is never ambiguous:
710
+
711
+ ```text
712
+ [version-matrix] public-latest -> 1.13.4
713
+ [version-matrix] catalyst-latest -> 1.13.4
714
+ [version-matrix] 2 requested specifiers resolve to 1 distinct version: 1.13.4 (public-latest, catalyst-latest). Running the suites once.
715
+ [version-matrix] Run 1 of 1: 1.13.4 (public-latest, catalyst-latest)
716
+ ```
717
+
718
+ - **Every version runs before anything is reported.** A failing end never hides the other: the summary names which concrete versions failed and which passed, and the thrown `AggregateError` carries each underlying failure.
719
+
720
+ ```text
721
+ AggregateError: Obsidian version matrix failed on 1 of 2 versions: 1.12.7 (public-latest). Passed: 1.13.4 (catalyst-latest).
722
+ ```
723
+
724
+ - **Only this runner defaults to both ends.** `obsidianVersion` with no explicit pin still means "whatever your installed Obsidian runs", so `connectToCdp()`, the CLI, and any suite not using the runner are unaffected.
725
+ - The runner never launches Obsidian itself — your `run` callback does — so it stays framework-agnostic and works for Vitest, Jest, and manual consumers alike.
726
+
670
727
  ##### Dead-boot fast-fail
671
728
 
672
729
  If you pin an app version that cannot run on the launched Electron shell — an `obsidianInstallerVersion` too old for the `obsidianVersion` — Obsidian loads a black screen: the renderer finishes loading but the app never bootstraps (empty `<body>`, no `window.app`). Rather than waiting out the full readiness timeout, the harness detects this terminal state and throws a **`RendererFailedToInitializeError`** as soon as it has held for a short grace window:
@@ -787,19 +844,21 @@ Runs tests against Obsidian Mobile on an Android emulator or real device via App
787
844
 
788
845
  Besides the required `appiumUrl` and `avdName`, the transport accepts these optional knobs (all with sensible defaults):
789
846
 
790
- | Option | Purpose | Default |
791
- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------- |
792
- | `appId` | App package (Android) or bundle ID (iOS). | `'md.obsidian'` |
793
- | `appiumStartTimeoutInMilliseconds` | Max wait for the auto-started Appium server to become ready; only when the harness auto-starts it. | `180000` |
794
- | `deviceIdleTimeoutInMilliseconds` | Max wait after boot for a started emulator to go idle before the session; avoids inflated cold setup. 0 skips. | `60000` |
795
- | `isAppiumConsoleVisible` | Show the auto-started Appium server console window and live output. Hidden and quiet by default. | `false` |
796
- | `isEmulatorVisible` | Show the auto-started emulator window. Hidden (`-no-window`, headless) by default so it never steals focus. | `false` |
797
- | `layoutReadyTimeoutInMilliseconds` | Max wait for `app.workspace.layoutReady` after the vault (re)opens; raise on slow emulators. | `90000` |
798
- | `sessionConnectionRetryTimeoutInMilliseconds` | Max wait to establish the Appium session (UiAutomator2 install + app launch); the dominant startup cost. | `180000` |
799
- | `shouldAutoInstallAppiumDependencies` | Auto-install missing Appium + the UiAutomator2 driver before auto-starting the server (global `npm install -g`). | `true` |
800
- | `shouldAutoStartAppium` | Auto-start the Appium server when it is not already reachable. | `true` |
801
- | `vaultBasePath` | Base device path where Obsidian stores vaults. | `'/sdcard/Documents/'` |
802
- | `webviewTimeoutInMilliseconds` | Max wait for the WebView context after the Appium session starts. | `60000` |
847
+ | Option | Purpose | Default |
848
+ | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------- |
849
+ | `appId` | App package (Android) or bundle ID (iOS). | `'md.obsidian'` |
850
+ | `appiumStartTimeoutInMilliseconds` | Max wait for the auto-started Appium server to become ready; only when the harness auto-starts it. | `180000` |
851
+ | `deviceIdleTimeoutInMilliseconds` | Max wait after boot for a started emulator to go idle before the session; avoids inflated cold setup. 0 skips. | `60000` |
852
+ | `isAppiumConsoleVisible` | Show the auto-started Appium server console window and live output. Hidden and quiet by default. | `false` |
853
+ | `isEmulatorVisible` | Show the auto-started emulator window. Hidden (`-no-window`, headless) by default so it never steals focus. | `false` |
854
+ | `layoutReadyTimeoutInMilliseconds` | Max wait for `app.workspace.layoutReady` after the vault (re)opens; raise on slow emulators. | `90000` |
855
+ | `leftoverMaxAgeInMilliseconds` | Age gate for the **host** leftover sweep; the device sweep is unconditional. See [Leftover cleanup](#leftover-cleanup). | `7200000` |
856
+ | `sessionConnectionRetryTimeoutInMilliseconds` | Max wait to establish the Appium session (UiAutomator2 install + app launch); the dominant startup cost. | `180000` |
857
+ | `shouldAutoInstallAppiumDependencies` | Auto-install missing Appium + the UiAutomator2 driver before auto-starting the server (global `npm install -g`). | `true` |
858
+ | `shouldAutoStartAppium` | Auto-start the Appium server when it is not already reachable. | `true` |
859
+ | `shouldSweepLeftovers` | Remove the temp vaults / instance profiles earlier runs leaked. See [Leftover cleanup](#leftover-cleanup). | `true` |
860
+ | `vaultBasePath` | Base device path where Obsidian stores vaults. | `'/sdcard/Documents/'` |
861
+ | `webviewTimeoutInMilliseconds` | Max wait for the WebView context after the Appium session starts. | `60000` |
803
862
 
804
863
  > [!NOTE]
805
864
  >
@@ -845,6 +904,40 @@ that can exceed the default `90000`ms budget and fail setup with
845
904
  if needed, raise the budget via `layoutReadyTimeoutInMilliseconds` in the transport options. It is
846
905
  headroom, not a substitute for adequate provisioning.
847
906
 
907
+ ### Leftover cleanup
908
+
909
+ A run that dies mid-flight cannot clean up after itself. On Android that is the normal case, not the
910
+ exception: teardown removes the vault through the WebView, and a dead WebView is exactly what most
911
+ failures are (`Vault cleanup error (non-fatal): no such window`). So every failure leaves a
912
+ `temp-vault-*` directory behind — and, worse, leaves it **registered**, which is work Obsidian has to
913
+ redo at every startup, inside the same WebView-readiness budget the run is already straining. Failures
914
+ therefore make the next failure likelier. One real emulator had accumulated **103 leftover vaults**.
915
+
916
+ Every run now sweeps at **both ends**, and the start sweep is the one that matters, because it runs
917
+ before anything that can die:
918
+
919
+ - **On the device (Android)** — before the Appium session launches Obsidian, every `temp-vault-*`
920
+ directory under `vaultBasePath` is removed over `adb`, and their stale entries are pruned from
921
+ Obsidian Mobile's `localStorage` vault registry when the run registers its own vault. Unregistering
922
+ a vault now removes its device directory over `adb` **whether or not the WebView answered**.
923
+ - **On the host** — leftover `temp-vault-*` staging directories and owned `userdata-*` instance
924
+ profiles in the system temp directory are removed.
925
+
926
+ The two halves gate differently, on purpose:
927
+
928
+ | Sweep | Gate | Why |
929
+ | ---------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
930
+ | **Device** | Unconditional | Android runs hold an exclusive lock, so no concurrent run can own a device vault — and an age gate would let a vault leaked minutes ago poison a rerun. |
931
+ | **Host** | Only older than `leftoverMaxAgeInMilliseconds` | Desktop runs are deliberately not serialized, and every project on the machine shares one temp directory, so a young directory may belong to a live run. |
932
+
933
+ Both knobs are available on either transport:
934
+
935
+ - **`shouldSweepLeftovers`** (default `true`) — set `false` to disable both sweeps entirely.
936
+ - **`leftoverMaxAgeInMilliseconds`** (default `7200000`, i.e. two hours) — the host age gate. Raise it
937
+ if a run of yours can outlive the default; `0` removes every host match regardless of age.
938
+
939
+ Sweeping is best-effort throughout: a directory another process still holds is skipped, never thrown.
940
+
848
941
  ### Running multiple platforms
849
942
 
850
943
  Use vitest projects to run the same tests on multiple platforms:
@@ -22,13 +22,17 @@ __export(connect_to_cdp_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(connect_to_cdp_exports);
24
24
  var import_eval_in_obsidian = require("./eval-in-obsidian.cjs");
25
+ var import_leftover_cleanup = require("./leftover-cleanup.cjs");
26
+ var import_log = require("./log.cjs");
25
27
  var import_normalize_optional_properties = require("./normalize-optional-properties.cjs");
26
28
  var import_temp_vault = require("./temp-vault.cjs");
27
29
  var import_transport_desktop_cdp = require("./transport-desktop-cdp.cjs");
28
30
  var import_transport_factory = require("./transport-factory.cjs");
29
31
  const DEFAULT_CDP_HOST = "localhost";
30
32
  async function connectToCdp(options) {
31
- const transport = await (0, import_transport_factory.createTransportFromOptions)(buildCdpTransportOptions(options));
33
+ const transportOptions = buildCdpTransportOptions(options);
34
+ await sweepLeftovers(transportOptions);
35
+ const transport = await (0, import_transport_factory.createTransportFromOptions)(transportOptions);
32
36
  const vault = new import_temp_vault.TempVault(options?.vault);
33
37
  const shouldRemoveVaultOnDispose = options?.shouldRemoveVaultOnDispose ?? options?.vault === void 0;
34
38
  await vault.register(transport);
@@ -95,8 +99,25 @@ function resolveEndpoint(transport, options) {
95
99
  }
96
100
  throw new Error("connectToCdp: could not determine the CDP port.");
97
101
  }
102
+ async function sweepLeftovers(transportOptions) {
103
+ if (!(0, import_leftover_cleanup.resolveShouldSweepLeftovers)(transportOptions)) {
104
+ return;
105
+ }
106
+ try {
107
+ const result = await (0, import_leftover_cleanup.sweepHostLeftovers)({
108
+ maxAgeInMilliseconds: (0, import_leftover_cleanup.resolveLeftoverMaxAgeInMilliseconds)(transportOptions)
109
+ });
110
+ if (result.removedCount > 0 || result.failedCount > 0) {
111
+ (0, import_log.log)(
112
+ `[connect-to-cdp] Swept ${String(result.removedCount)} leftover temp director(ies) from earlier runs (${String(result.failedCount)} still in use).`
113
+ );
114
+ }
115
+ } catch (error) {
116
+ (0, import_log.log)(`[connect-to-cdp] Leftover sweep error (non-fatal): ${String(error)}`);
117
+ }
118
+ }
98
119
  // Annotate the CommonJS export names for ESM import in node:
99
120
  0 && (module.exports = {
100
121
  connectToCdp
101
122
  });
102
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2Nvbm5lY3QtdG8tY2RwLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogUHJvZ3JhbW1hdGljIGhlbHBlciB0byBsYXVuY2ggKG9yIGF0dGFjaCB0bykgYSBDRFAtZW5hYmxlZCBPYnNpZGlhbiBpbnN0YW5jZVxuICogd2l0aCB0aGUgcnVudGltZSBoZWxwZXIgbmFtZXNwYWNlIGJvb3RzdHJhcHBlZCwgZm9yIGFkLWhvYyByZWFsLWFwcCBkZWJ1Z2dpbmcuXG4gKlxuICogQSBzaW5nbGUge0BsaW5rIGNvbm5lY3RUb0NkcH0gY2FsbCByZXNvbHZlcyB0aGUgb3duZWQtaW5zdGFuY2UgY29uZmlnLCBvcGVucyBhXG4gKiB2YXVsdCwgYW5kIGJvb3RzdHJhcHMgYHdpbmRvdy5fX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nYCAoc28gYGV2YWxXcmFwcGVyYCxcbiAqIHRoZSBiYXNlIGBsaWJgIGhlbHBlcnMsIGBlcnJvclRvU3RyaW5nYCwgYGdldE9ic2lkaWFuTW9kdWxlYCwgXHUyMDI2IGFyZSBhdmFpbGFibGUpLCB0aGVuXG4gKiBoYW5kcyBiYWNrIGEgZGlzcG9zYWJsZSB7QGxpbmsgQ2RwQ29ubmVjdGlvbn0gZXhwb3NpbmcgdGhlIGNob3NlbiBDRFAgcG9ydCwgYVxuICogcmF3IHtAbGluayBDZHBDb25uZWN0aW9uLmludm9rZX0gYW5kIHRoZSByaWNoIHtAbGluayBDZHBDb25uZWN0aW9uLmV2YWxJbk9ic2lkaWFufS5cbiAqL1xuXG4vKiB2OCBpZ25vcmUgc3RhcnQgLS0gSW50ZWdyYXRpb24tdGltZSBjb2RlIChsYXVuY2hlcyBPYnNpZGlhbiAvIENEUCkgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB0eXBlIHsgRXhjZXB0IH0gZnJvbSAndHlwZS1mZXN0JztcblxuaW1wb3J0IHR5cGUgeyBBc2FyRmFsbGJhY2sgfSBmcm9tICcuL2FzYXItZmFsbGJhY2stZGV0ZWN0aW9uLmNqcyc7XG5pbXBvcnQgdHlwZSB7IENvbnRleHRJZCB9IGZyb20gJy4vY29udGV4dC1pZC5janMnO1xuaW1wb3J0IHR5cGUgeyBFbGVjdHJvbkNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2VsZWN0cm9uLWNvbXBhdGliaWxpdHkuY2pzJztcbmltcG9ydCB0eXBlIHtcbiAgRXZhbEluT2JzaWRpYW5QYXJhbXMsXG4gIEdlbmVyaWNPYmplY3Rcbn0gZnJvbSAnLi9ldmFsLWluLW9ic2lkaWFuLmNqcyc7XG5pbXBvcnQgdHlwZSB7IEluc3RhbGxlckNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2luc3RhbGxlci1jb21wYXRpYmlsaXR5LmNqcyc7XG5pbXBvcnQgdHlwZSB7IE9ic2lkaWFuQ2RwVHJhbnNwb3J0T3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LW9wdGlvbnMuY2pzJztcblxuaW1wb3J0IHsgZXZhbEluT2JzaWRpYW4gfSBmcm9tICcuL2V2YWwtaW4tb2JzaWRpYW4uY2pzJztcbmltcG9ydCB7IG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllcyB9IGZyb20gJy4vbm9ybWFsaXplLW9wdGlvbmFsLXByb3BlcnRpZXMuY2pzJztcbmltcG9ydCB7IFRlbXBWYXVsdCB9IGZyb20gJy4vdGVtcC12YXVsdC5janMnO1xuaW1wb3J0IHsgRGVza3RvcENkcFRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWRlc2t0b3AtY2RwLmNqcyc7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LWZhY3RvcnkuY2pzJztcblxuY29uc3QgREVGQVVMVF9DRFBfSE9TVCA9ICdsb2NhbGhvc3QnO1xuXG4vKipcbiAqIEEgbGl2ZSBjb25uZWN0aW9uIHRvIGEgQ0RQLWVuYWJsZWQgT2JzaWRpYW4gaW5zdGFuY2Ugd2l0aCB0aGUgcnVudGltZSBoZWxwZXJcbiAqIG5hbWVzcGFjZSBib290c3RyYXBwZWQuXG4gKlxuICogSW1wbGVtZW50cyBgQXN5bmNEaXNwb3NhYmxlYCwgc28gYGF3YWl0IHVzaW5nIGNvbm4gPSBhd2FpdCBjb25uZWN0VG9DZHAoXHUyMDI2KWBcbiAqIGRpc3Bvc2VzIGl0IChraWxsaW5nIGFuIG93bmVkIGluc3RhbmNlIGFuZCBcdTIwMTQgZm9yIGEgdGhyb3ctYXdheSB0ZW1wIHZhdWx0IFx1MjAxNFxuICogcmVtb3ZpbmcgaXRzIGRpcmVjdG9yeSkgYXV0b21hdGljYWxseS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZHBDb25uZWN0aW9uIGV4dGVuZHMgQXN5bmNEaXNwb3NhYmxlIHtcbiAgLyoqXG4gICAqIFRoZSBzaWxlbnQtYXNhci1mYWxsYmFjayB2ZXJkaWN0IGZvciBhbiBvd25lZCBpbnN0YW5jZSwgcmVhZCBsaXZlIGFmdGVyIGJvb3Q6XG4gICAqIHdoZXRoZXIgdGhlIGFwcCB2ZXJzaW9uIGl0IGlzIGFjdHVhbGx5IHJ1bm5pbmcgbWF0Y2hlcyB0aGUgc3dhcHBlZC1pbiBwaW4sIG9yXG4gICAqIHRoZSBpbnN0YWxsZXIgc2lsZW50bHkgcmV2ZXJ0ZWQgdG8gaXRzIG93biBidW5kbGVkIGFzYXIuIGB1bmRlZmluZWRgIGluIGF0dGFjaFxuICAgKiBtb2RlLCB3aGVuIG5vIGFzYXIgd2FzIHN3YXBwZWQsIG9yIHdoZW4gdGhlIHJ1bm5pbmcgdmVyc2lvbiB3YXMgdW5yZWFkYWJsZS4gQVxuICAgKiBgJ2ZhbGxiYWNrJ2AgdmVyZGljdCByZWFjaGVzIGhlcmUgb25seSB3aGVuIHRoZSB0aHJvdyBpcyBkaXNhYmxlZFxuICAgKiAoe0BsaW5rIENvbm5lY3RUb0NkcE9wdGlvbnMuc2hvdWxkVGhyb3dPblNpbGVudEFzYXJGYWxsYmFja30gYGZhbHNlYCk7XG4gICAqIG90aGVyd2lzZSBpdCB0aHJvd3MgYFNpbGVudEFzYXJGYWxsYmFja0Vycm9yYCBiZWZvcmUgdGhlIGNvbm5lY3Rpb24gaXMgY3JlYXRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGFzYXJGYWxsYmFjaz86IEFzYXJGYWxsYmFjayB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIGJhc2UgQ0RQIFVSTCwgZS5nLiBgaHR0cDovL2xvY2FsaG9zdDo1MTg4OGAuXG4gICAqL1xuICByZWFkb25seSBjZHBVcmw6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlc29sdmVkIGluc3RhbGxlclx1MjE5NGFwcCBjb21wYXRpYmlsaXR5IHZlcmRpY3QgZm9yIGFuIG93bmVkIGluc3RhbmNlLCB3aGVuXG4gICAqIGl0IGNvdWxkIGJlIGRldGVybWluZWQuIGB1bmRlZmluZWRgIGluIGF0dGFjaCBtb2RlLCBvciB3aGVuIHRoZSB2ZXJkaWN0IGlzXG4gICAqIHVua25vd24gKHVuZGV0ZWN0YWJsZSBzaGVsbCB2ZXJzaW9uLCBvciB0aGUgYXBwIHZlcnNpb24gaXMgYWJzZW50IGZyb20gdGhlXG4gICAqIHRhYmxlKS4gQW4gYCd1bnJ1bm5hYmxlJ2AgdmVyZGljdCByZWFjaGVzIGhlcmUgb25seSB3aGVuIHRoZSBwcm9hY3RpdmUgdGhyb3dcbiAgICogaXMgZGlzYWJsZWQgKHtAbGluayBDb25uZWN0VG9DZHBPcHRpb25zLnNob3VsZFRocm93T25JbmNvbXBhdGlibGVJbnN0YWxsZXJ9XG4gICAqIGBmYWxzZWApOyBvdGhlcndpc2UgaXQgdGhyb3dzIGBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3JgIGJlZm9yZSB0aGVcbiAgICogY29ubmVjdGlvbiBpcyBjcmVhdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgY29tcGF0aWJpbGl0eT86IEluc3RhbGxlckNvbXBhdGliaWxpdHkgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIERpc3Bvc2VzIHRoZSBjb25uZWN0aW9uOiBraWxscyBhbiBvd25lZCBpbnN0YW5jZSBhbmQgcmVtb3ZlcyBpdHMgaXNvbGF0ZWRcbiAgICogdXNlci1kYXRhIGRpci4gVGhlIHZhdWx0IGRpcmVjdG9yeSBpcyByZW1vdmVkIG9ubHkgd2hlbiBpdCBpcyBhIHRocm93LWF3YXlcbiAgICogdGVtcCB2YXVsdCAoc2VlIHtAbGluayBDb25uZWN0VG9DZHBPcHRpb25zLnNob3VsZFJlbW92ZVZhdWx0T25EaXNwb3NlfSk7IGFcbiAgICogcmVhbCB2YXVsdCBwYXNzZWQgdmlhIHtAbGluayBDb25uZWN0VG9DZHBPcHRpb25zLnZhdWx0fSBpcyBuZXZlciBkZWxldGVkLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgZGlzcG9zYWwgY29tcGxldGVzLlxuICAgKi9cbiAgZGlzcG9zZSgpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBUaGUgcnVudGltZSBFbGVjdHJvbiBjb21wYXRpYmlsaXR5IHZlcmRpY3QgZm9yIGFuIG93bmVkIGluc3RhbmNlLCByZWFkIGxpdmVcbiAgICogYWZ0ZXIgYm9vdDogd2hldGhlciB0aGUgRWxlY3Ryb24gdmVyc2lvbiBpdCBpcyBhY3R1YWxseSBydW5uaW5nIGlzIG5ldyBlbm91Z2hcbiAgICogZm9yIHRoZSBydW5uaW5nIGFwcCB2ZXJzaW9uLiBgdW5kZWZpbmVkYCBpbiBhdHRhY2ggbW9kZSwgb3Igd2hlbiB0aGUgdmVyZGljdFxuICAgKiBpcyB1bmtub3duICh0aGUgbGl2ZSB2ZXJzaW9uIHdhcyB1bnJlYWRhYmxlLCBvciB0aGUgYXBwIHZlcnNpb24gY2FycmllcyBub1xuICAgKiByZWNvbW1lbmRlZCBFbGVjdHJvbiB2ZXJzaW9uKS4gQW4gb2xkIEVsZWN0cm9uIG5ldmVyIGJsb2NrcyBcdTIwMTQgaXQgb25seSB3YXJucyBcdTIwMTRcbiAgICogc28gdW5saWtlIHtAbGluayBjb21wYXRpYmlsaXR5fSB0aGVyZSBpcyBubyB0aHJvd2luZyB0aWVyLlxuICAgKi9cbiAgcmVhZG9ubHkgZWxlY3Ryb25Db21wYXRpYmlsaXR5PzogRWxlY3Ryb25Db21wYXRpYmlsaXR5IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBFdmFsdWF0ZXMgYSBzZWxmLWNvbnRhaW5lZCBmdW5jdGlvbiBpbnNpZGUgT2JzaWRpYW4gdmlhIHRoZSByaWNoIGhlbHBlclxuICAgKiBwYXRoLCByZWNlaXZpbmcgYHsgYXBwLCBsaWIsIG9ic2lkaWFuTW9kdWxlLCBjb250ZXh0IH1gIHBsdXMgYW55IGBhcmdzYFxuICAgKiAoc2hhcmVkIGhlbHBlcnMgbGlrZSBgdHlwZUludG9FZGl0b3JgIC8gYHdhaXRVbnRpbGAgbGl2ZSBvbiBgbGliYCkuIE1pcnJvcnNcbiAgICogdGhlIHRvcC1sZXZlbCBgZXZhbEluT2JzaWRpYW5gLCB3aXRoIHRoZSB0cmFuc3BvcnQgYW5kIHZhdWx0IHBhdGggcHJlLWJvdW5kXG4gICAqIHRvIHRoaXMgY29ubmVjdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBldmFsdWF0aW9uIHBhcmFtZXRlcnMgKGBmbmAsIG9wdGlvbmFsIGBhcmdzYC9gY29udGV4dElkYCkuXG4gICAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJldHVybiB2YWx1ZSBvZiBgZm5gLlxuICAgKi9cbiAgZXZhbEluT2JzaWRpYW48QXJncyBleHRlbmRzIEdlbmVyaWNPYmplY3QsIFJlc3VsdCwgVENvbnRleHRJZCBleHRlbmRzIENvbnRleHRJZDx1bmtub3duPiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZD4oXG4gICAgcGFyYW1zOiBFeGNlcHQ8RXZhbEluT2JzaWRpYW5QYXJhbXM8QXJncywgUmVzdWx0LCBUQ29udGV4dElkPiwgJ3RyYW5zcG9ydCcgfCAndmF1bHRQYXRoJz5cbiAgKTogUHJvbWlzZTxSZXN1bHQ+O1xuXG4gIC8qKlxuICAgKiBFdmFsdWF0ZXMgYSByYXcgSmF2YVNjcmlwdCBleHByZXNzaW9uIGluc2lkZSBPYnNpZGlhbiBhbmQgcmV0dXJucyB0aGVcbiAgICogbm9ybWFsaXplZCBzdHJpbmcgcmVzdWx0IChlLmcuIGAnNSdgLCBhIEpTT04gc3RyaW5nLCBvciBgJyhubyBvdXRwdXQpJ2ApLlxuICAgKlxuICAgKiBAcGFyYW0gZXhwcmVzc2lvbiAtIEEgc2VsZi1jb250YWluZWQgSmF2YVNjcmlwdCBleHByZXNzaW9uLlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHRvIHRoZSByYXcgcmVzdWx0IHN0cmluZy5cbiAgICovXG4gIGludm9rZShleHByZXNzaW9uOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz47XG5cbiAgLyoqXG4gICAqIFRoZSBDRFAgcG9ydCB0aGUgaW5zdGFuY2UgaXMgcmVhY2hhYmxlIG9uICh0aGUgZnJlZSBwb3J0IGNob3NlbiBmb3IgYW5cbiAgICogb3duZWQgaW5zdGFuY2UsIG9yIHRoZSBhdHRhY2hlZCB7QGxpbmsgQ29ubmVjdFRvQ2RwT3B0aW9ucy5wb3J0fSkuXG4gICAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBvcGVuZWQgdmF1bHQuIEV4cG9zZXMgYHBhdGhgIGFuZCBgcG9wdWxhdGUoLi4uKWAgZm9yIHNlZWRpbmcgZmlsZXMuXG4gICAqL1xuICByZWFkb25seSB2YXVsdDogVGVtcFZhdWx0O1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBjb25uZWN0VG9DZHB9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbm5lY3RUb0NkcE9wdGlvbnMge1xuICAvKipcbiAgICogVGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIGluZGl2aWR1YWwgQ0RQIGNvbW1hbmRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgMzAwMDBgXG4gICAqL1xuICByZWFkb25seSBjb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBHcmFjZSB3aW5kb3cgaW4gbWlsbGlzZWNvbmRzIGZvciBmYXN0LWZhaWxpbmcgYSBkZWFkIGJvb3Qgb2YgdGhlIG93bmVkXG4gICAqIGluc3RhbmNlIFx1MjAxNCB0aGUgcmVuZGVyZXIgbG9hZGVkIGJ1dCB0aGUgYXBwIG5ldmVyIGJvb3RzdHJhcHBlZCAoZW1wdHlcbiAgICogYDxib2R5PmAsIG5vIGB3aW5kb3cuYXBwYCksIHRoZSB0ZXJtaW5hbCBzdGF0ZSB3aGVuIHRoZSBhc2FyIGNhbm5vdCBydW4gb25cbiAgICogdGhlIGxhdW5jaGVkIEVsZWN0cm9uIHNoZWxsLiBPbmNlIGl0IGhhcyBoZWxkIHRoaXMgbG9uZyBhXG4gICAqIGBSZW5kZXJlckZhaWxlZFRvSW5pdGlhbGl6ZUVycm9yYCBpcyB0aHJvd24gaW5zdGVhZCBvZiB3YWl0aW5nIG91dCB0aGUgZnVsbFxuICAgKiByZWFkaW5lc3MgdGltZW91dC4gSWdub3JlZCBpbiBhdHRhY2ggbW9kZSAoe0BsaW5rIHBvcnR9IHNldCkuIFNldCBgMGAgdG9cbiAgICogZGlzYWJsZSBmYXN0LWZhaWwuXG4gICAqXG4gICAqIEBkZWZhdWx0IGAxMDAwMGBcbiAgICovXG4gIHJlYWRvbmx5IGRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogQ0RQIGhvc3QuXG4gICAqXG4gICAqIEBkZWZhdWx0IGAnbG9jYWxob3N0J2BcbiAgICovXG4gIHJlYWRvbmx5IGhvc3Q/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIE9ic2lkaWFuIHdpbmRvdyBpcyBzaG93biBvbiBzY3JlZW4uIERlZmF1bHRzIHRvIGB0cnVlYDsgc2V0XG4gICAqIGBmYWxzZWAgdG8gbGF1bmNoIGl0IG9mZi1zY3JlZW4uXG4gICAqIElnbm9yZWQgaW4gYXR0YWNoIG1vZGUgKHtAbGluayBwb3J0fSBzZXQpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdHJ1ZWBcbiAgICovXG4gIHJlYWRvbmx5IGlzT2JzaWRpYW5BcHBWaXNpYmxlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogUGlucyB0aGUgRWxlY3Ryb24gc2hlbGwgKGluc3RhbGxlciBidWlsZCkgdGhlIG93bmVkIGluc3RhbmNlIHJ1bnMuIEFjY2VwdHNcbiAgICogYCd4LnkueidgLCBgJ3B1YmxpYy1sYXRlc3QnYCwgb3IgYCdjYXRhbHlzdC1sYXRlc3QnYC4gSWdub3JlZCB3aGVuXG4gICAqIHtAbGluayBwb3J0fSAoYXR0YWNoIG1vZGUpIGlzIHNldC4gV2hlbiBvbWl0dGVkLCB0aGUgaW5zdGFsbGVkIHNoZWxsIGlzIHVzZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB1bmRlZmluZWRgXG4gICAqL1xuICByZWFkb25seSBvYnNpZGlhbkluc3RhbGxlclZlcnNpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFBpbnMgdGhlIE9ic2lkaWFuIGFwcCB2ZXJzaW9uIChhc2FyKSB0aGUgb3duZWQgaW5zdGFuY2UgcnVucy4gQWNjZXB0c1xuICAgKiBgJ3gueS56J2AsIGAncHVibGljLWxhdGVzdCdgLCBvciBgJ2NhdGFseXN0LWxhdGVzdCdgLiBJZ25vcmVkIHdoZW5cbiAgICoge0BsaW5rIHBvcnR9IChhdHRhY2ggbW9kZSkgaXMgc2V0LiBXaGVuIG9taXR0ZWQsIHRoZSBpbnN0YWxsZWQgdmVyc2lvbiBpcyB1c2VkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdW5kZWZpbmVkYFxuICAgKi9cbiAgcmVhZG9ubHkgb2JzaWRpYW5WZXJzaW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDRFAgcG9ydCBvZiBhbiBhbHJlYWR5LXJ1bm5pbmcgT2JzaWRpYW4gdG8gKiphdHRhY2gqKiB0by4gV2hlbiBvbWl0dGVkLCBhblxuICAgKiBpc29sYXRlZCBpbnN0YW5jZSBpcyBsYXVuY2hlZCBvbiBhbiBhdXRvbWF0aWNhbGx5IGNob3NlbiBmcmVlIHBvcnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB1bmRlZmluZWRgXG4gICAqL1xuICByZWFkb25seSBwb3J0PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGxhdW5jaCB0aGUgb3duZWQgaW5zdGFuY2Ugd2l0aCBDaHJvbWl1bSdzIHNhbmRib3ggZGlzYWJsZWRcbiAgICogKGAtLW5vLXNhbmRib3hgKS5cbiAgICpcbiAgICogTmVlZGVkIHRvIGJvb3Qgb24gTGludXggd2l0aG91dCBhIGNvcnJlY3RseS1jb25maWd1cmVkIHNldHVpZFxuICAgKiBgY2hyb21lLXNhbmRib3hgIGhlbHBlciAoZS5nLiBhbiBpbnN0YWxsZXItZXh0cmFjdGVkIHBvcnRhYmxlIHNoZWxsLCBvciBDSVxuICAgKiBydW5uaW5nIGFzIGEgbm9uLXJvb3QgdXNlcik7IGhhcm1sZXNzIG9uIFdpbmRvd3MvbWFjT1MuIElnbm9yZWQgaW4gYXR0YWNoXG4gICAqIG1vZGUgKHtAbGluayBwb3J0fSBzZXQpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZmFsc2VgXG4gICAqL1xuICByZWFkb25seSBzaG91bGREaXNhYmxlU2FuZGJveD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gcmVtb3ZlIHRoZSB2YXVsdCBkaXJlY3Rvcnkgb24ge0BsaW5rIENkcENvbm5lY3Rpb24uZGlzcG9zZX0uXG4gICAqXG4gICAqIFdoZW4gb21pdHRlZCwgZGVmYXVsdHMgdG8gYHRydWVgIGZvciBhbiBpbXBsaWNpdCB0aHJvdy1hd2F5IHRlbXAgdmF1bHRcbiAgICogKHtAbGluayB2YXVsdH0gbm90IGdpdmVuKSBhbmQgYGZhbHNlYCB3aGVuIGEge0BsaW5rIHZhdWx0fSBwYXRoIGlzIGdpdmVuLCBzb1xuICAgKiBhIHJlYWwgdmF1bHQgaXMgbmV2ZXIgZGVsZXRlZC4gU2V0IGV4cGxpY2l0bHkgdG8gb3ZlcnJpZGUuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRSZW1vdmVWYXVsdE9uRGlzcG9zZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgYW4gKip1bnJ1bm5hYmxlKiogaW5zdGFsbGVyXHUyMTk0YXBwIHZlcnNpb24gcGFpciBmYWlscyBmYXN0IGJlZm9yZSBsYXVuY2guXG4gICAqXG4gICAqIFdoZW4gYHRydWVgICh0aGUgZGVmYXVsdCksIGFuIGluc3RhbGxlciBiZWxvdyB0aGUgYXBwJ3MgcnVuIGZsb29yIHRocm93c1xuICAgKiBgSW5jb21wYXRpYmxlSW5zdGFsbGVyVmVyc2lvbkVycm9yYCBmcm9tIHZlcnNpb24gcmVzb2x1dGlvbiBiZWZvcmUgYW55dGhpbmcgaXNcbiAgICogZG93bmxvYWRlZCBvciBsYXVuY2hlZC4gU2V0IGBmYWxzZWAgdG8gbGV0IHRoZSBwaW4gcHJvY2VlZCB0byBsYXVuY2ggXHUyMDE0IHdoZXJlXG4gICAqIHRoZSByZWFjdGl2ZSBkZWFkLWJvb3QgZmFzdC1mYWlsIHN0aWxsIGNhdGNoZXMgdGhlIGJsYWNrLXNjcmVlbiBib290LCBhbmQgdGhlXG4gICAqIGAndW5ydW5uYWJsZSdgIHZlcmRpY3QgaXMgc3VyZmFjZWQgb24ge0BsaW5rIENkcENvbm5lY3Rpb24uY29tcGF0aWJpbGl0eX1cbiAgICogcmF0aGVyIHRoYW4gdGhyb3duLiBJZ25vcmVkIGluIGF0dGFjaCBtb2RlICh7QGxpbmsgcG9ydH0gc2V0KS5cbiAgICpcbiAgICogQGRlZmF1bHQgYHRydWVgXG4gICAqL1xuICByZWFkb25seSBzaG91bGRUaHJvd09uSW5jb21wYXRpYmxlSW5zdGFsbGVyPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciBhIHBvc3QtYm9vdCAqKnNpbGVudCBhc2FyIGZhbGxiYWNrKiogZmFpbHMgZmFzdC5cbiAgICpcbiAgICogV2hlbiBhbiBhc2FyIGlzIHN3YXBwZWQgb250byBhbiBpbnN0YWxsZXIgc2hlbGwgdG9vIG9sZCBmb3IgaXQsIHRoZSBpbnN0YW5jZVxuICAgKiBtYXkgc2lsZW50bHkgcmV2ZXJ0IHRvIHRoZSBpbnN0YWxsZXIncyBvd24gYnVuZGxlZCBhc2FyIGFuZCBydW4gdGhlICoqd3JvbmdcbiAgICogKG9sZGVyKSoqIHZlcnNpb24gYmVoaW5kIGEgaGVhbHRoeSBVSS4gV2hlbiBgdHJ1ZWAgKHRoZSBkZWZhdWx0KSwgdGhlIHJ1bm5pbmdcbiAgICogYXBwIHZlcnNpb24gaXMgdmVyaWZpZWQgYWdhaW5zdCB0aGUgcGluIHBvc3QtYm9vdCBhbmQgYSBtaXNtYXRjaCB0aHJvd3NcbiAgICogYFNpbGVudEFzYXJGYWxsYmFja0Vycm9yYC4gU2V0IGBmYWxzZWAgdG8gbGV0IHRoZSBib290IHByb2NlZWQgXHUyMDE0IHRoZSBtaXNtYXRjaFxuICAgKiBpcyB0aGVuIHN1cmZhY2VkIG9uIHtAbGluayBDZHBDb25uZWN0aW9uLmFzYXJGYWxsYmFja30gcmF0aGVyIHRoYW4gdGhyb3duLlxuICAgKiBJZ25vcmVkIGluIGF0dGFjaCBtb2RlICh7QGxpbmsgcG9ydH0gc2V0KSBhbmQgd2hlbiBubyBhc2FyIGlzIHN3YXBwZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkVGhyb3dPblNpbGVudEFzYXJGYWxsYmFjaz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIG93bmVkLWluc3RhbmNlIGNvbXBhdGliaWxpdHkgKipuYWcgd2FybmluZ3MqKiBhcmUgZW1pdHRlZC5cbiAgICpcbiAgICogQ292ZXJzIGJvdGggdGhlIG9mZmxpbmUgaW5zdGFsbGVyXHUyMTk0YXBwIHdhcm5pbmcgYW5kIHRoZSBwb3N0LWJvb3RcbiAgICogcnVudGltZS1FbGVjdHJvbiB3YXJuaW5nLiBXaGVuIGB0cnVlYCAodGhlIGRlZmF1bHQpIGVhY2ggZmlyZXMgdmlhIHRoZSBoYXJuZXNzXG4gICAqIGxvZzsgc2V0IGBmYWxzZWAgdG8gc2lsZW5jZSBib3RoIFx1MjAxNCB0aGUgdmVyZGljdHMgYXJlIHN0aWxsIHN1cmZhY2VkIG9uXG4gICAqIHtAbGluayBDZHBDb25uZWN0aW9uLmNvbXBhdGliaWxpdHl9IC8ge0BsaW5rIENkcENvbm5lY3Rpb24uZWxlY3Ryb25Db21wYXRpYmlsaXR5fSxcbiAgICogb25seSB0aGUgbG9nIGlzIHN1cHByZXNzZWQuIElnbm9yZWQgaW4gYXR0YWNoIG1vZGUgKHtAbGluayBwb3J0fSBzZXQpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdHJ1ZWBcbiAgICovXG4gIHJlYWRvbmx5IHNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBYnNvbHV0ZSBwYXRoIHRvIGFuIGV4aXN0aW5nIHZhdWx0IHRvIG9wZW4uIFdoZW4gb21pdHRlZCwgYW4gZW1wdHkgdGVtcG9yYXJ5XG4gICAqIHZhdWx0IGlzIGNyZWF0ZWQgKGFuZCByZW1vdmVkIG9uIGRpc3Bvc2UgdW5sZXNzXG4gICAqIHtAbGluayBzaG91bGRSZW1vdmVWYXVsdE9uRGlzcG9zZX0gc2F5cyBvdGhlcndpc2UpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdW5kZWZpbmVkYFxuICAgKi9cbiAgcmVhZG9ubHkgdmF1bHQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSByZXNvbHZlZCBDRFAgaG9zdC9wb3J0IHBhaXIuXG4gKi9cbmludGVyZmFjZSBSZXNvbHZlZEVuZHBvaW50IHtcbiAgaG9zdDogc3RyaW5nO1xuICBwb3J0OiBudW1iZXI7XG59XG5cbi8qKlxuICogTGF1bmNoZXMgKG9yIGF0dGFjaGVzIHRvKSBhIENEUC1lbmFibGVkIE9ic2lkaWFuIGluc3RhbmNlLCBvcGVucyBhIHZhdWx0LCBhbmRcbiAqIGJvb3RzdHJhcHMgdGhlIHJ1bnRpbWUgaGVscGVyIG5hbWVzcGFjZSwgcmV0dXJuaW5nIGEgZGlzcG9zYWJsZSBjb25uZWN0aW9uLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29ubmVjdGlvbiBvcHRpb25zLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB0byB0aGUgbGl2ZSB7QGxpbmsgQ2RwQ29ubmVjdGlvbn0uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb25uZWN0VG9DZHAob3B0aW9ucz86IENvbm5lY3RUb0NkcE9wdGlvbnMpOiBQcm9taXNlPENkcENvbm5lY3Rpb24+IHtcbiAgY29uc3QgdHJhbnNwb3J0ID0gYXdhaXQgY3JlYXRlVHJhbnNwb3J0RnJvbU9wdGlvbnMoYnVpbGRDZHBUcmFuc3BvcnRPcHRpb25zKG9wdGlvbnMpKTtcbiAgY29uc3QgdmF1bHQgPSBuZXcgVGVtcFZhdWx0KG9wdGlvbnM/LnZhdWx0KTtcbiAgY29uc3Qgc2hvdWxkUmVtb3ZlVmF1bHRPbkRpc3Bvc2UgPSBvcHRpb25zPy5zaG91bGRSZW1vdmVWYXVsdE9uRGlzcG9zZSA/PyAob3B0aW9ucz8udmF1bHQgPT09IHVuZGVmaW5lZCk7XG5cbiAgLy8gUmVnaXN0ZXJpbmcgdGhlIHZhdWx0IGlzIHdoYXQgbGF1bmNoZXMgdGhlIG93bmVkIGluc3RhbmNlIChwcm92aXNpb25zIHRoZVxuICAvLyBBc2FyLCBvcGVucyB0aGUgdmF1bHQsIGFuZCBib290c3RyYXBzIHRoZSBoZWxwZXIgbmFtZXNwYWNlKSwgb3Igb3BlbnMgdGhlXG4gIC8vIFZhdWx0IGluIHRoZSBhdHRhY2hlZCBpbnN0YW5jZS5cbiAgYXdhaXQgdmF1bHQucmVnaXN0ZXIodHJhbnNwb3J0KTtcblxuICBjb25zdCB7IGhvc3QsIHBvcnQgfSA9IHJlc29sdmVFbmRwb2ludCh0cmFuc3BvcnQsIG9wdGlvbnMpO1xuICBjb25zdCBjZHBVcmwgPSBgaHR0cDovLyR7aG9zdH06JHtTdHJpbmcocG9ydCl9YDtcbiAgY29uc3QgYXNhckZhbGxiYWNrID0gdHJhbnNwb3J0IGluc3RhbmNlb2YgRGVza3RvcENkcFRyYW5zcG9ydCA/IHRyYW5zcG9ydC5nZXRBc2FyRmFsbGJhY2soKSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgY29tcGF0aWJpbGl0eSA9IHRyYW5zcG9ydCBpbnN0YW5jZW9mIERlc2t0b3BDZHBUcmFuc3BvcnQgPyB0cmFuc3BvcnQuZ2V0Q29tcGF0aWJpbGl0eSgpIDogdW5kZWZpbmVkO1xuICBjb25zdCBlbGVjdHJvbkNvbXBhdGliaWxpdHkgPSB0cmFuc3BvcnQgaW5zdGFuY2VvZiBEZXNrdG9wQ2RwVHJhbnNwb3J0ID8gdHJhbnNwb3J0LmdldEVsZWN0cm9uQ29tcGF0aWJpbGl0eSgpIDogdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGNvbm5lY3Rpb246IENkcENvbm5lY3Rpb24gPSB7XG4gICAgY2RwVXJsLFxuICAgIC4uLihhc2FyRmFsbGJhY2sgJiYgeyBhc2FyRmFsbGJhY2sgfSksXG4gICAgLi4uKGNvbXBhdGliaWxpdHkgJiYgeyBjb21wYXRpYmlsaXR5IH0pLFxuICAgIC4uLihlbGVjdHJvbkNvbXBhdGliaWxpdHkgJiYgeyBlbGVjdHJvbkNvbXBhdGliaWxpdHkgfSksXG5cbiAgICBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHNob3VsZFJlbW92ZVZhdWx0T25EaXNwb3NlKSB7XG4gICAgICAgICAgYXdhaXQgdmF1bHQuZGlzcG9zZSh0cmFuc3BvcnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0IHRyYW5zcG9ydC51bnJlZ2lzdGVyVmF1bHQodmF1bHQucGF0aCk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHRyYW5zcG9ydC5kaXNwb3NlPy4oKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgZXZhbEluT2JzaWRpYW48QXJncyBleHRlbmRzIEdlbmVyaWNPYmplY3QsIFJlc3VsdCwgVENvbnRleHRJZCBleHRlbmRzIENvbnRleHRJZDx1bmtub3duPiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZD4oXG4gICAgICBwYXJhbXM6IEV4Y2VwdDxFdmFsSW5PYnNpZGlhblBhcmFtczxBcmdzLCBSZXN1bHQsIFRDb250ZXh0SWQ+LCAndHJhbnNwb3J0JyB8ICd2YXVsdFBhdGgnPlxuICAgICk6IFByb21pc2U8UmVzdWx0PiB7XG4gICAgICByZXR1cm4gZXZhbEluT2JzaWRpYW48QXJncywgUmVzdWx0LCBUQ29udGV4dElkPih7IC4uLnBhcmFtcywgdHJhbnNwb3J0LCB2YXVsdFBhdGg6IHZhdWx0LnBhdGggfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGludm9rZShleHByZXNzaW9uOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgcmV0dXJuIHRyYW5zcG9ydC5ldmFsdWF0ZShleHByZXNzaW9uLCB7IGN3ZDogdmF1bHQucGF0aCB9KTtcbiAgICB9LFxuXG4gICAgcG9ydCxcblxuICAgIGFzeW5jIFtTeW1ib2wuYXN5bmNEaXNwb3NlXSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24uZGlzcG9zZSgpO1xuICAgIH0sXG5cbiAgICB2YXVsdFxuICB9O1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUge0BsaW5rIE9ic2lkaWFuQ2RwVHJhbnNwb3J0T3B0aW9uc30gZm9yIGEgY29ubmVjdGlvbiwgdGhyZWFkaW5nIG9ubHlcbiAqIHRoZSBwcm92aWRlZCB7QGxpbmsgQ29ubmVjdFRvQ2RwT3B0aW9uc30gdGhyb3VnaCAob3duZWQtdmlzaWJsZSBkZWZhdWx0cyB0b1xuICogYHRydWVgLCB1bmxpa2UgdGhlIGhpZGRlbi1ieS1kZWZhdWx0IHRlc3QgdHJhbnNwb3J0cykuIFVuc2V0IGtub2JzIHBhc3MgdGhyb3VnaFxuICogYXMgYHVuZGVmaW5lZGAgYW5kIGFyZSByZWFkIHdpdGggYD8/IGRlZmF1bHRgIC8gYCE9PSB1bmRlZmluZWRgIGd1YXJkc1xuICogZG93bnN0cmVhbSwgc28gYW4gZXhwbGljaXQgYHVuZGVmaW5lZGAgaXMgaW5kaXN0aW5ndWlzaGFibGUgZnJvbSBhbiBhYnNlbnQga2V5LlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIGNvbm5lY3Rpb24gb3B0aW9ucy5cbiAqIEByZXR1cm5zIFRoZSB0cmFuc3BvcnQgb3B0aW9ucyB0byBjcmVhdGUgdGhlIGNvbm5lY3Rpb24ncyB0cmFuc3BvcnQgZnJvbS5cbiAqL1xuZnVuY3Rpb24gYnVpbGRDZHBUcmFuc3BvcnRPcHRpb25zKG9wdGlvbnM/OiBDb25uZWN0VG9DZHBPcHRpb25zKTogT2JzaWRpYW5DZHBUcmFuc3BvcnRPcHRpb25zIHtcbiAgcmV0dXJuIG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllczxPYnNpZGlhbkNkcFRyYW5zcG9ydE9wdGlvbnM+KHtcbiAgICBjb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzOiBvcHRpb25zPy5jb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzLFxuICAgIGRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kczogb3B0aW9ucz8uZGVhZEJvb3RHcmFjZUluTWlsbGlzZWNvbmRzLFxuICAgIGhvc3Q6IG9wdGlvbnM/Lmhvc3QsXG4gICAgaXNPYnNpZGlhbkFwcFZpc2libGU6IG9wdGlvbnM/LmlzT2JzaWRpYW5BcHBWaXNpYmxlID8/IHRydWUsXG4gICAgb2JzaWRpYW5JbnN0YWxsZXJWZXJzaW9uOiBvcHRpb25zPy5vYnNpZGlhbkluc3RhbGxlclZlcnNpb24sXG4gICAgb2JzaWRpYW5WZXJzaW9uOiBvcHRpb25zPy5vYnNpZGlhblZlcnNpb24sXG4gICAgcG9ydDogb3B0aW9ucz8ucG9ydCxcbiAgICBzaG91bGREaXNhYmxlU2FuZGJveDogb3B0aW9ucz8uc2hvdWxkRGlzYWJsZVNhbmRib3gsXG4gICAgc2hvdWxkVGhyb3dPbkluY29tcGF0aWJsZUluc3RhbGxlcjogb3B0aW9ucz8uc2hvdWxkVGhyb3dPbkluY29tcGF0aWJsZUluc3RhbGxlcixcbiAgICBzaG91bGRUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrOiBvcHRpb25zPy5zaG91bGRUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrLFxuICAgIHNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXM6IG9wdGlvbnM/LnNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXMsXG4gICAgdHlwZTogJ29ic2lkaWFuLWNkcCdcbiAgfSk7XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIENEUCBob3N0L3BvcnQgZm9yIHRoZSBjb25uZWN0aW9uOiBmcm9tIHRoZSBvd25lZCBpbnN0YW5jZSdzXG4gKiBsYXVuY2hlZCBlbmRwb2ludCB3aGVuIHByZXNlbnQsIG90aGVyd2lzZSBmcm9tIHRoZSBhdHRhY2ggb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0gdHJhbnNwb3J0IC0gVGhlIHRyYW5zcG9ydCBjcmVhdGVkIGZvciB0aGlzIGNvbm5lY3Rpb24uXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBjb25uZWN0aW9uIG9wdGlvbnMuXG4gKiBAcmV0dXJucyBUaGUgcmVzb2x2ZWQgaG9zdCBhbmQgcG9ydC5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIHBvcnQgY2Fubm90IGJlIGRldGVybWluZWQuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVFbmRwb2ludCh0cmFuc3BvcnQ6IHVua25vd24sIG9wdGlvbnM6IENvbm5lY3RUb0NkcE9wdGlvbnMgfCB1bmRlZmluZWQpOiBSZXNvbHZlZEVuZHBvaW50IHtcbiAgaWYgKHRyYW5zcG9ydCBpbnN0YW5jZW9mIERlc2t0b3BDZHBUcmFuc3BvcnQpIHtcbiAgICBjb25zdCBlbmRwb2ludCA9IHRyYW5zcG9ydC5nZXRPd25lZEluc3RhbmNlRW5kcG9pbnQoKTtcbiAgICBpZiAoZW5kcG9pbnQpIHtcbiAgICAgIHJldHVybiB7IGhvc3Q6IGVuZHBvaW50Lmhvc3QsIHBvcnQ6IGVuZHBvaW50LnBvcnQgfTtcbiAgICB9XG4gIH1cblxuICBpZiAob3B0aW9ucz8ucG9ydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHsgaG9zdDogb3B0aW9ucy5ob3N0ID8/IERFRkFVTFRfQ0RQX0hPU1QsIHBvcnQ6IG9wdGlvbnMucG9ydCB9O1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKCdjb25uZWN0VG9DZHA6IGNvdWxkIG5vdCBkZXRlcm1pbmUgdGhlIENEUCBwb3J0LicpO1xufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQTJCQSw4QkFBK0I7QUFDL0IsMkNBQTRDO0FBQzVDLHdCQUEwQjtBQUMxQixtQ0FBb0M7QUFDcEMsK0JBQTJDO0FBRTNDLE1BQU0sbUJBQW1CO0FBd1B6QixlQUFzQixhQUFhLFNBQXVEO0FBQ3hG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
123
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2Nvbm5lY3QtdG8tY2RwLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogUHJvZ3JhbW1hdGljIGhlbHBlciB0byBsYXVuY2ggKG9yIGF0dGFjaCB0bykgYSBDRFAtZW5hYmxlZCBPYnNpZGlhbiBpbnN0YW5jZVxuICogd2l0aCB0aGUgcnVudGltZSBoZWxwZXIgbmFtZXNwYWNlIGJvb3RzdHJhcHBlZCwgZm9yIGFkLWhvYyByZWFsLWFwcCBkZWJ1Z2dpbmcuXG4gKlxuICogQSBzaW5nbGUge0BsaW5rIGNvbm5lY3RUb0NkcH0gY2FsbCByZXNvbHZlcyB0aGUgb3duZWQtaW5zdGFuY2UgY29uZmlnLCBvcGVucyBhXG4gKiB2YXVsdCwgYW5kIGJvb3RzdHJhcHMgYHdpbmRvdy5fX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nYCAoc28gYGV2YWxXcmFwcGVyYCxcbiAqIHRoZSBiYXNlIGBsaWJgIGhlbHBlcnMsIGBlcnJvclRvU3RyaW5nYCwgYGdldE9ic2lkaWFuTW9kdWxlYCwgXHUyMDI2IGFyZSBhdmFpbGFibGUpLCB0aGVuXG4gKiBoYW5kcyBiYWNrIGEgZGlzcG9zYWJsZSB7QGxpbmsgQ2RwQ29ubmVjdGlvbn0gZXhwb3NpbmcgdGhlIGNob3NlbiBDRFAgcG9ydCwgYVxuICogcmF3IHtAbGluayBDZHBDb25uZWN0aW9uLmludm9rZX0gYW5kIHRoZSByaWNoIHtAbGluayBDZHBDb25uZWN0aW9uLmV2YWxJbk9ic2lkaWFufS5cbiAqL1xuXG4vKiB2OCBpZ25vcmUgc3RhcnQgLS0gSW50ZWdyYXRpb24tdGltZSBjb2RlIChsYXVuY2hlcyBPYnNpZGlhbiAvIENEUCkgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB0eXBlIHsgRXhjZXB0IH0gZnJvbSAndHlwZS1mZXN0JztcblxuaW1wb3J0IHR5cGUgeyBBc2FyRmFsbGJhY2sgfSBmcm9tICcuL2FzYXItZmFsbGJhY2stZGV0ZWN0aW9uLmNqcyc7XG5pbXBvcnQgdHlwZSB7IENvbnRleHRJZCB9IGZyb20gJy4vY29udGV4dC1pZC5janMnO1xuaW1wb3J0IHR5cGUgeyBFbGVjdHJvbkNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2VsZWN0cm9uLWNvbXBhdGliaWxpdHkuY2pzJztcbmltcG9ydCB0eXBlIHtcbiAgRXZhbEluT2JzaWRpYW5QYXJhbXMsXG4gIEdlbmVyaWNPYmplY3Rcbn0gZnJvbSAnLi9ldmFsLWluLW9ic2lkaWFuLmNqcyc7XG5pbXBvcnQgdHlwZSB7IEluc3RhbGxlckNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2luc3RhbGxlci1jb21wYXRpYmlsaXR5LmNqcyc7XG5pbXBvcnQgdHlwZSB7IE9ic2lkaWFuQ2RwVHJhbnNwb3J0T3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LW9wdGlvbnMuY2pzJztcblxuaW1wb3J0IHsgZXZhbEluT2JzaWRpYW4gfSBmcm9tICcuL2V2YWwtaW4tb2JzaWRpYW4uY2pzJztcbmltcG9ydCB7XG4gIHJlc29sdmVMZWZ0b3Zlck1heEFnZUluTWlsbGlzZWNvbmRzLFxuICByZXNvbHZlU2hvdWxkU3dlZXBMZWZ0b3ZlcnMsXG4gIHN3ZWVwSG9zdExlZnRvdmVyc1xufSBmcm9tICcuL2xlZnRvdmVyLWNsZWFudXAuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5pbXBvcnQgeyBub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXMgfSBmcm9tICcuL25vcm1hbGl6ZS1vcHRpb25hbC1wcm9wZXJ0aWVzLmNqcyc7XG5pbXBvcnQgeyBUZW1wVmF1bHQgfSBmcm9tICcuL3RlbXAtdmF1bHQuY2pzJztcbmltcG9ydCB7IERlc2t0b3BDZHBUcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC1kZXNrdG9wLWNkcC5janMnO1xuaW1wb3J0IHsgY3JlYXRlVHJhbnNwb3J0RnJvbU9wdGlvbnMgfSBmcm9tICcuL3RyYW5zcG9ydC1mYWN0b3J5LmNqcyc7XG5cbmNvbnN0IERFRkFVTFRfQ0RQX0hPU1QgPSAnbG9jYWxob3N0JztcblxuLyoqXG4gKiBBIGxpdmUgY29ubmVjdGlvbiB0byBhIENEUC1lbmFibGVkIE9ic2lkaWFuIGluc3RhbmNlIHdpdGggdGhlIHJ1bnRpbWUgaGVscGVyXG4gKiBuYW1lc3BhY2UgYm9vdHN0cmFwcGVkLlxuICpcbiAqIEltcGxlbWVudHMgYEFzeW5jRGlzcG9zYWJsZWAsIHNvIGBhd2FpdCB1c2luZyBjb25uID0gYXdhaXQgY29ubmVjdFRvQ2RwKFx1MjAyNilgXG4gKiBkaXNwb3NlcyBpdCAoa2lsbGluZyBhbiBvd25lZCBpbnN0YW5jZSBhbmQgXHUyMDE0IGZvciBhIHRocm93LWF3YXkgdGVtcCB2YXVsdCBcdTIwMTRcbiAqIHJlbW92aW5nIGl0cyBkaXJlY3RvcnkpIGF1dG9tYXRpY2FsbHkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2RwQ29ubmVjdGlvbiBleHRlbmRzIEFzeW5jRGlzcG9zYWJsZSB7XG4gIC8qKlxuICAgKiBUaGUgc2lsZW50LWFzYXItZmFsbGJhY2sgdmVyZGljdCBmb3IgYW4gb3duZWQgaW5zdGFuY2UsIHJlYWQgbGl2ZSBhZnRlciBib290OlxuICAgKiB3aGV0aGVyIHRoZSBhcHAgdmVyc2lvbiBpdCBpcyBhY3R1YWxseSBydW5uaW5nIG1hdGNoZXMgdGhlIHN3YXBwZWQtaW4gcGluLCBvclxuICAgKiB0aGUgaW5zdGFsbGVyIHNpbGVudGx5IHJldmVydGVkIHRvIGl0cyBvd24gYnVuZGxlZCBhc2FyLiBgdW5kZWZpbmVkYCBpbiBhdHRhY2hcbiAgICogbW9kZSwgd2hlbiBubyBhc2FyIHdhcyBzd2FwcGVkLCBvciB3aGVuIHRoZSBydW5uaW5nIHZlcnNpb24gd2FzIHVucmVhZGFibGUuIEFcbiAgICogYCdmYWxsYmFjaydgIHZlcmRpY3QgcmVhY2hlcyBoZXJlIG9ubHkgd2hlbiB0aGUgdGhyb3cgaXMgZGlzYWJsZWRcbiAgICogKHtAbGluayBDb25uZWN0VG9DZHBPcHRpb25zLnNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2t9IGBmYWxzZWApO1xuICAgKiBvdGhlcndpc2UgaXQgdGhyb3dzIGBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvcmAgYmVmb3JlIHRoZSBjb25uZWN0aW9uIGlzIGNyZWF0ZWQuXG4gICAqL1xuICByZWFkb25seSBhc2FyRmFsbGJhY2s/OiBBc2FyRmFsbGJhY2sgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIENEUCBVUkwsIGUuZy4gYGh0dHA6Ly9sb2NhbGhvc3Q6NTE4ODhgLlxuICAgKi9cbiAgcmVhZG9ubHkgY2RwVXJsOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSByZXNvbHZlZCBpbnN0YWxsZXJcdTIxOTRhcHAgY29tcGF0aWJpbGl0eSB2ZXJkaWN0IGZvciBhbiBvd25lZCBpbnN0YW5jZSwgd2hlblxuICAgKiBpdCBjb3VsZCBiZSBkZXRlcm1pbmVkLiBgdW5kZWZpbmVkYCBpbiBhdHRhY2ggbW9kZSwgb3Igd2hlbiB0aGUgdmVyZGljdCBpc1xuICAgKiB1bmtub3duICh1bmRldGVjdGFibGUgc2hlbGwgdmVyc2lvbiwgb3IgdGhlIGFwcCB2ZXJzaW9uIGlzIGFic2VudCBmcm9tIHRoZVxuICAgKiB0YWJsZSkuIEFuIGAndW5ydW5uYWJsZSdgIHZlcmRpY3QgcmVhY2hlcyBoZXJlIG9ubHkgd2hlbiB0aGUgcHJvYWN0aXZlIHRocm93XG4gICAqIGlzIGRpc2FibGVkICh7QGxpbmsgQ29ubmVjdFRvQ2RwT3B0aW9ucy5zaG91bGRUaHJvd09uSW5jb21wYXRpYmxlSW5zdGFsbGVyfVxuICAgKiBgZmFsc2VgKTsgb3RoZXJ3aXNlIGl0IHRocm93cyBgSW5jb21wYXRpYmxlSW5zdGFsbGVyVmVyc2lvbkVycm9yYCBiZWZvcmUgdGhlXG4gICAqIGNvbm5lY3Rpb24gaXMgY3JlYXRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGNvbXBhdGliaWxpdHk/OiBJbnN0YWxsZXJDb21wYXRpYmlsaXR5IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBEaXNwb3NlcyB0aGUgY29ubmVjdGlvbjoga2lsbHMgYW4gb3duZWQgaW5zdGFuY2UgYW5kIHJlbW92ZXMgaXRzIGlzb2xhdGVkXG4gICAqIHVzZXItZGF0YSBkaXIuIFRoZSB2YXVsdCBkaXJlY3RvcnkgaXMgcmVtb3ZlZCBvbmx5IHdoZW4gaXQgaXMgYSB0aHJvdy1hd2F5XG4gICAqIHRlbXAgdmF1bHQgKHNlZSB7QGxpbmsgQ29ubmVjdFRvQ2RwT3B0aW9ucy5zaG91bGRSZW1vdmVWYXVsdE9uRGlzcG9zZX0pOyBhXG4gICAqIHJlYWwgdmF1bHQgcGFzc2VkIHZpYSB7QGxpbmsgQ29ubmVjdFRvQ2RwT3B0aW9ucy52YXVsdH0gaXMgbmV2ZXIgZGVsZXRlZC5cbiAgICpcbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIGRpc3Bvc2FsIGNvbXBsZXRlcy5cbiAgICovXG4gIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogVGhlIHJ1bnRpbWUgRWxlY3Ryb24gY29tcGF0aWJpbGl0eSB2ZXJkaWN0IGZvciBhbiBvd25lZCBpbnN0YW5jZSwgcmVhZCBsaXZlXG4gICAqIGFmdGVyIGJvb3Q6IHdoZXRoZXIgdGhlIEVsZWN0cm9uIHZlcnNpb24gaXQgaXMgYWN0dWFsbHkgcnVubmluZyBpcyBuZXcgZW5vdWdoXG4gICAqIGZvciB0aGUgcnVubmluZyBhcHAgdmVyc2lvbi4gYHVuZGVmaW5lZGAgaW4gYXR0YWNoIG1vZGUsIG9yIHdoZW4gdGhlIHZlcmRpY3RcbiAgICogaXMgdW5rbm93biAodGhlIGxpdmUgdmVyc2lvbiB3YXMgdW5yZWFkYWJsZSwgb3IgdGhlIGFwcCB2ZXJzaW9uIGNhcnJpZXMgbm9cbiAgICogcmVjb21tZW5kZWQgRWxlY3Ryb24gdmVyc2lvbikuIEFuIG9sZCBFbGVjdHJvbiBuZXZlciBibG9ja3MgXHUyMDE0IGl0IG9ubHkgd2FybnMgXHUyMDE0XG4gICAqIHNvIHVubGlrZSB7QGxpbmsgY29tcGF0aWJpbGl0eX0gdGhlcmUgaXMgbm8gdGhyb3dpbmcgdGllci5cbiAgICovXG4gIHJlYWRvbmx5IGVsZWN0cm9uQ29tcGF0aWJpbGl0eT86IEVsZWN0cm9uQ29tcGF0aWJpbGl0eSB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogRXZhbHVhdGVzIGEgc2VsZi1jb250YWluZWQgZnVuY3Rpb24gaW5zaWRlIE9ic2lkaWFuIHZpYSB0aGUgcmljaCBoZWxwZXJcbiAgICogcGF0aCwgcmVjZWl2aW5nIGB7IGFwcCwgbGliLCBvYnNpZGlhbk1vZHVsZSwgY29udGV4dCB9YCBwbHVzIGFueSBgYXJnc2BcbiAgICogKHNoYXJlZCBoZWxwZXJzIGxpa2UgYHR5cGVJbnRvRWRpdG9yYCAvIGB3YWl0VW50aWxgIGxpdmUgb24gYGxpYmApLiBNaXJyb3JzXG4gICAqIHRoZSB0b3AtbGV2ZWwgYGV2YWxJbk9ic2lkaWFuYCwgd2l0aCB0aGUgdHJhbnNwb3J0IGFuZCB2YXVsdCBwYXRoIHByZS1ib3VuZFxuICAgKiB0byB0aGlzIGNvbm5lY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZXZhbHVhdGlvbiBwYXJhbWV0ZXJzIChgZm5gLCBvcHRpb25hbCBgYXJnc2AvYGNvbnRleHRJZGApLlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHRvIHRoZSByZXR1cm4gdmFsdWUgb2YgYGZuYC5cbiAgICovXG4gIGV2YWxJbk9ic2lkaWFuPEFyZ3MgZXh0ZW5kcyBHZW5lcmljT2JqZWN0LCBSZXN1bHQsIFRDb250ZXh0SWQgZXh0ZW5kcyBDb250ZXh0SWQ8dW5rbm93bj4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ+KFxuICAgIHBhcmFtczogRXhjZXB0PEV2YWxJbk9ic2lkaWFuUGFyYW1zPEFyZ3MsIFJlc3VsdCwgVENvbnRleHRJZD4sICd0cmFuc3BvcnQnIHwgJ3ZhdWx0UGF0aCc+XG4gICk6IFByb21pc2U8UmVzdWx0PjtcblxuICAvKipcbiAgICogRXZhbHVhdGVzIGEgcmF3IEphdmFTY3JpcHQgZXhwcmVzc2lvbiBpbnNpZGUgT2JzaWRpYW4gYW5kIHJldHVybnMgdGhlXG4gICAqIG5vcm1hbGl6ZWQgc3RyaW5nIHJlc3VsdCAoZS5nLiBgJzUnYCwgYSBKU09OIHN0cmluZywgb3IgYCcobm8gb3V0cHV0KSdgKS5cbiAgICpcbiAgICogQHBhcmFtIGV4cHJlc3Npb24gLSBBIHNlbGYtY29udGFpbmVkIEphdmFTY3JpcHQgZXhwcmVzc2lvbi5cbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB0byB0aGUgcmF3IHJlc3VsdCBzdHJpbmcuXG4gICAqL1xuICBpbnZva2UoZXhwcmVzc2lvbjogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBUaGUgQ0RQIHBvcnQgdGhlIGluc3RhbmNlIGlzIHJlYWNoYWJsZSBvbiAodGhlIGZyZWUgcG9ydCBjaG9zZW4gZm9yIGFuXG4gICAqIG93bmVkIGluc3RhbmNlLCBvciB0aGUgYXR0YWNoZWQge0BsaW5rIENvbm5lY3RUb0NkcE9wdGlvbnMucG9ydH0pLlxuICAgKi9cbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgb3BlbmVkIHZhdWx0LiBFeHBvc2VzIGBwYXRoYCBhbmQgYHBvcHVsYXRlKC4uLilgIGZvciBzZWVkaW5nIGZpbGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgdmF1bHQ6IFRlbXBWYXVsdDtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgY29ubmVjdFRvQ2RwfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb25uZWN0VG9DZHBPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciBpbmRpdmlkdWFsIENEUCBjb21tYW5kcy5cbiAgICpcbiAgICogQGRlZmF1bHQgYDMwMDAwYFxuICAgKi9cbiAgcmVhZG9ubHkgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogR3JhY2Ugd2luZG93IGluIG1pbGxpc2Vjb25kcyBmb3IgZmFzdC1mYWlsaW5nIGEgZGVhZCBib290IG9mIHRoZSBvd25lZFxuICAgKiBpbnN0YW5jZSBcdTIwMTQgdGhlIHJlbmRlcmVyIGxvYWRlZCBidXQgdGhlIGFwcCBuZXZlciBib290c3RyYXBwZWQgKGVtcHR5XG4gICAqIGA8Ym9keT5gLCBubyBgd2luZG93LmFwcGApLCB0aGUgdGVybWluYWwgc3RhdGUgd2hlbiB0aGUgYXNhciBjYW5ub3QgcnVuIG9uXG4gICAqIHRoZSBsYXVuY2hlZCBFbGVjdHJvbiBzaGVsbC4gT25jZSBpdCBoYXMgaGVsZCB0aGlzIGxvbmcgYVxuICAgKiBgUmVuZGVyZXJGYWlsZWRUb0luaXRpYWxpemVFcnJvcmAgaXMgdGhyb3duIGluc3RlYWQgb2Ygd2FpdGluZyBvdXQgdGhlIGZ1bGxcbiAgICogcmVhZGluZXNzIHRpbWVvdXQuIElnbm9yZWQgaW4gYXR0YWNoIG1vZGUgKHtAbGluayBwb3J0fSBzZXQpLiBTZXQgYDBgIHRvXG4gICAqIGRpc2FibGUgZmFzdC1mYWlsLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgMTAwMDBgXG4gICAqL1xuICByZWFkb25seSBkZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIENEUCBob3N0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgJ2xvY2FsaG9zdCdgXG4gICAqL1xuICByZWFkb25seSBob3N0Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBPYnNpZGlhbiB3aW5kb3cgaXMgc2hvd24gb24gc2NyZWVuLiBEZWZhdWx0cyB0byBgdHJ1ZWA7IHNldFxuICAgKiBgZmFsc2VgIHRvIGxhdW5jaCBpdCBvZmYtc2NyZWVuLlxuICAgKiBJZ25vcmVkIGluIGF0dGFjaCBtb2RlICh7QGxpbmsgcG9ydH0gc2V0KS5cbiAgICpcbiAgICogQGRlZmF1bHQgYHRydWVgXG4gICAqL1xuICByZWFkb25seSBpc09ic2lkaWFuQXBwVmlzaWJsZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFBpbnMgdGhlIEVsZWN0cm9uIHNoZWxsIChpbnN0YWxsZXIgYnVpbGQpIHRoZSBvd25lZCBpbnN0YW5jZSBydW5zLiBBY2NlcHRzXG4gICAqIGAneC55LnonYCwgYCdwdWJsaWMtbGF0ZXN0J2AsIG9yIGAnY2F0YWx5c3QtbGF0ZXN0J2AuIElnbm9yZWQgd2hlblxuICAgKiB7QGxpbmsgcG9ydH0gKGF0dGFjaCBtb2RlKSBpcyBzZXQuIFdoZW4gb21pdHRlZCwgdGhlIGluc3RhbGxlZCBzaGVsbCBpcyB1c2VkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdW5kZWZpbmVkYFxuICAgKi9cbiAgcmVhZG9ubHkgb2JzaWRpYW5JbnN0YWxsZXJWZXJzaW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQaW5zIHRoZSBPYnNpZGlhbiBhcHAgdmVyc2lvbiAoYXNhcikgdGhlIG93bmVkIGluc3RhbmNlIHJ1bnMuIEFjY2VwdHNcbiAgICogYCd4LnkueidgLCBgJ3B1YmxpYy1sYXRlc3QnYCwgb3IgYCdjYXRhbHlzdC1sYXRlc3QnYC4gSWdub3JlZCB3aGVuXG4gICAqIHtAbGluayBwb3J0fSAoYXR0YWNoIG1vZGUpIGlzIHNldC4gV2hlbiBvbWl0dGVkLCB0aGUgaW5zdGFsbGVkIHZlcnNpb24gaXMgdXNlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgYHVuZGVmaW5lZGBcbiAgICovXG4gIHJlYWRvbmx5IG9ic2lkaWFuVmVyc2lvbj86IHN0cmluZztcblxuICAvKipcbiAgICogQ0RQIHBvcnQgb2YgYW4gYWxyZWFkeS1ydW5uaW5nIE9ic2lkaWFuIHRvICoqYXR0YWNoKiogdG8uIFdoZW4gb21pdHRlZCwgYW5cbiAgICogaXNvbGF0ZWQgaW5zdGFuY2UgaXMgbGF1bmNoZWQgb24gYW4gYXV0b21hdGljYWxseSBjaG9zZW4gZnJlZSBwb3J0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdW5kZWZpbmVkYFxuICAgKi9cbiAgcmVhZG9ubHkgcG9ydD86IG51bWJlcjtcblxuICAvKipcbiAgICogV2hldGhlciB0byBsYXVuY2ggdGhlIG93bmVkIGluc3RhbmNlIHdpdGggQ2hyb21pdW0ncyBzYW5kYm94IGRpc2FibGVkXG4gICAqIChgLS1uby1zYW5kYm94YCkuXG4gICAqXG4gICAqIE5lZWRlZCB0byBib290IG9uIExpbnV4IHdpdGhvdXQgYSBjb3JyZWN0bHktY29uZmlndXJlZCBzZXR1aWRcbiAgICogYGNocm9tZS1zYW5kYm94YCBoZWxwZXIgKGUuZy4gYW4gaW5zdGFsbGVyLWV4dHJhY3RlZCBwb3J0YWJsZSBzaGVsbCwgb3IgQ0lcbiAgICogcnVubmluZyBhcyBhIG5vbi1yb290IHVzZXIpOyBoYXJtbGVzcyBvbiBXaW5kb3dzL21hY09TLiBJZ25vcmVkIGluIGF0dGFjaFxuICAgKiBtb2RlICh7QGxpbmsgcG9ydH0gc2V0KS5cbiAgICpcbiAgICogQGRlZmF1bHQgYGZhbHNlYFxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkRGlzYWJsZVNhbmRib3g/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHJlbW92ZSB0aGUgdmF1bHQgZGlyZWN0b3J5IG9uIHtAbGluayBDZHBDb25uZWN0aW9uLmRpc3Bvc2V9LlxuICAgKlxuICAgKiBXaGVuIG9taXR0ZWQsIGRlZmF1bHRzIHRvIGB0cnVlYCBmb3IgYW4gaW1wbGljaXQgdGhyb3ctYXdheSB0ZW1wIHZhdWx0XG4gICAqICh7QGxpbmsgdmF1bHR9IG5vdCBnaXZlbikgYW5kIGBmYWxzZWAgd2hlbiBhIHtAbGluayB2YXVsdH0gcGF0aCBpcyBnaXZlbiwgc29cbiAgICogYSByZWFsIHZhdWx0IGlzIG5ldmVyIGRlbGV0ZWQuIFNldCBleHBsaWNpdGx5IHRvIG92ZXJyaWRlLlxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkUmVtb3ZlVmF1bHRPbkRpc3Bvc2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGFuICoqdW5ydW5uYWJsZSoqIGluc3RhbGxlclx1MjE5NGFwcCB2ZXJzaW9uIHBhaXIgZmFpbHMgZmFzdCBiZWZvcmUgbGF1bmNoLlxuICAgKlxuICAgKiBXaGVuIGB0cnVlYCAodGhlIGRlZmF1bHQpLCBhbiBpbnN0YWxsZXIgYmVsb3cgdGhlIGFwcCdzIHJ1biBmbG9vciB0aHJvd3NcbiAgICogYEluY29tcGF0aWJsZUluc3RhbGxlclZlcnNpb25FcnJvcmAgZnJvbSB2ZXJzaW9uIHJlc29sdXRpb24gYmVmb3JlIGFueXRoaW5nIGlzXG4gICAqIGRvd25sb2FkZWQgb3IgbGF1bmNoZWQuIFNldCBgZmFsc2VgIHRvIGxldCB0aGUgcGluIHByb2NlZWQgdG8gbGF1bmNoIFx1MjAxNCB3aGVyZVxuICAgKiB0aGUgcmVhY3RpdmUgZGVhZC1ib290IGZhc3QtZmFpbCBzdGlsbCBjYXRjaGVzIHRoZSBibGFjay1zY3JlZW4gYm9vdCwgYW5kIHRoZVxuICAgKiBgJ3VucnVubmFibGUnYCB2ZXJkaWN0IGlzIHN1cmZhY2VkIG9uIHtAbGluayBDZHBDb25uZWN0aW9uLmNvbXBhdGliaWxpdHl9XG4gICAqIHJhdGhlciB0aGFuIHRocm93bi4gSWdub3JlZCBpbiBhdHRhY2ggbW9kZSAoe0BsaW5rIHBvcnR9IHNldCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkVGhyb3dPbkluY29tcGF0aWJsZUluc3RhbGxlcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgYSBwb3N0LWJvb3QgKipzaWxlbnQgYXNhciBmYWxsYmFjayoqIGZhaWxzIGZhc3QuXG4gICAqXG4gICAqIFdoZW4gYW4gYXNhciBpcyBzd2FwcGVkIG9udG8gYW4gaW5zdGFsbGVyIHNoZWxsIHRvbyBvbGQgZm9yIGl0LCB0aGUgaW5zdGFuY2VcbiAgICogbWF5IHNpbGVudGx5IHJldmVydCB0byB0aGUgaW5zdGFsbGVyJ3Mgb3duIGJ1bmRsZWQgYXNhciBhbmQgcnVuIHRoZSAqKndyb25nXG4gICAqIChvbGRlcikqKiB2ZXJzaW9uIGJlaGluZCBhIGhlYWx0aHkgVUkuIFdoZW4gYHRydWVgICh0aGUgZGVmYXVsdCksIHRoZSBydW5uaW5nXG4gICAqIGFwcCB2ZXJzaW9uIGlzIHZlcmlmaWVkIGFnYWluc3QgdGhlIHBpbiBwb3N0LWJvb3QgYW5kIGEgbWlzbWF0Y2ggdGhyb3dzXG4gICAqIGBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvcmAuIFNldCBgZmFsc2VgIHRvIGxldCB0aGUgYm9vdCBwcm9jZWVkIFx1MjAxNCB0aGUgbWlzbWF0Y2hcbiAgICogaXMgdGhlbiBzdXJmYWNlZCBvbiB7QGxpbmsgQ2RwQ29ubmVjdGlvbi5hc2FyRmFsbGJhY2t9IHJhdGhlciB0aGFuIHRocm93bi5cbiAgICogSWdub3JlZCBpbiBhdHRhY2ggbW9kZSAoe0BsaW5rIHBvcnR9IHNldCkgYW5kIHdoZW4gbm8gYXNhciBpcyBzd2FwcGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdHJ1ZWBcbiAgICovXG4gIHJlYWRvbmx5IHNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2s/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBvd25lZC1pbnN0YW5jZSBjb21wYXRpYmlsaXR5ICoqbmFnIHdhcm5pbmdzKiogYXJlIGVtaXR0ZWQuXG4gICAqXG4gICAqIENvdmVycyBib3RoIHRoZSBvZmZsaW5lIGluc3RhbGxlclx1MjE5NGFwcCB3YXJuaW5nIGFuZCB0aGUgcG9zdC1ib290XG4gICAqIHJ1bnRpbWUtRWxlY3Ryb24gd2FybmluZy4gV2hlbiBgdHJ1ZWAgKHRoZSBkZWZhdWx0KSBlYWNoIGZpcmVzIHZpYSB0aGUgaGFybmVzc1xuICAgKiBsb2c7IHNldCBgZmFsc2VgIHRvIHNpbGVuY2UgYm90aCBcdTIwMTQgdGhlIHZlcmRpY3RzIGFyZSBzdGlsbCBzdXJmYWNlZCBvblxuICAgKiB7QGxpbmsgQ2RwQ29ubmVjdGlvbi5jb21wYXRpYmlsaXR5fSAvIHtAbGluayBDZHBDb25uZWN0aW9uLmVsZWN0cm9uQ29tcGF0aWJpbGl0eX0sXG4gICAqIG9ubHkgdGhlIGxvZyBpcyBzdXBwcmVzc2VkLiBJZ25vcmVkIGluIGF0dGFjaCBtb2RlICh7QGxpbmsgcG9ydH0gc2V0KS5cbiAgICpcbiAgICogQGRlZmF1bHQgYHRydWVgXG4gICAqL1xuICByZWFkb25seSBzaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQWJzb2x1dGUgcGF0aCB0byBhbiBleGlzdGluZyB2YXVsdCB0byBvcGVuLiBXaGVuIG9taXR0ZWQsIGFuIGVtcHR5IHRlbXBvcmFyeVxuICAgKiB2YXVsdCBpcyBjcmVhdGVkIChhbmQgcmVtb3ZlZCBvbiBkaXNwb3NlIHVubGVzc1xuICAgKiB7QGxpbmsgc2hvdWxkUmVtb3ZlVmF1bHRPbkRpc3Bvc2V9IHNheXMgb3RoZXJ3aXNlKS5cbiAgICpcbiAgICogQGRlZmF1bHQgYHVuZGVmaW5lZGBcbiAgICovXG4gIHJlYWRvbmx5IHZhdWx0Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgcmVzb2x2ZWQgQ0RQIGhvc3QvcG9ydCBwYWlyLlxuICovXG5pbnRlcmZhY2UgUmVzb2x2ZWRFbmRwb2ludCB7XG4gIGhvc3Q6IHN0cmluZztcbiAgcG9ydDogbnVtYmVyO1xufVxuXG4vKipcbiAqIExhdW5jaGVzIChvciBhdHRhY2hlcyB0bykgYSBDRFAtZW5hYmxlZCBPYnNpZGlhbiBpbnN0YW5jZSwgb3BlbnMgYSB2YXVsdCwgYW5kXG4gKiBib290c3RyYXBzIHRoZSBydW50aW1lIGhlbHBlciBuYW1lc3BhY2UsIHJldHVybmluZyBhIGRpc3Bvc2FibGUgY29ubmVjdGlvbi5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIENvbm5lY3Rpb24gb3B0aW9ucy5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGxpdmUge0BsaW5rIENkcENvbm5lY3Rpb259LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29ubmVjdFRvQ2RwKG9wdGlvbnM/OiBDb25uZWN0VG9DZHBPcHRpb25zKTogUHJvbWlzZTxDZHBDb25uZWN0aW9uPiB7XG4gIGNvbnN0IHRyYW5zcG9ydE9wdGlvbnMgPSBidWlsZENkcFRyYW5zcG9ydE9wdGlvbnMob3B0aW9ucyk7XG4gIGF3YWl0IHN3ZWVwTGVmdG92ZXJzKHRyYW5zcG9ydE9wdGlvbnMpO1xuICBjb25zdCB0cmFuc3BvcnQgPSBhd2FpdCBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyh0cmFuc3BvcnRPcHRpb25zKTtcbiAgY29uc3QgdmF1bHQgPSBuZXcgVGVtcFZhdWx0KG9wdGlvbnM/LnZhdWx0KTtcbiAgY29uc3Qgc2hvdWxkUmVtb3ZlVmF1bHRPbkRpc3Bvc2UgPSBvcHRpb25zPy5zaG91bGRSZW1vdmVWYXVsdE9uRGlzcG9zZSA/PyAob3B0aW9ucz8udmF1bHQgPT09IHVuZGVmaW5lZCk7XG5cbiAgLy8gUmVnaXN0ZXJpbmcgdGhlIHZhdWx0IGlzIHdoYXQgbGF1bmNoZXMgdGhlIG93bmVkIGluc3RhbmNlIChwcm92aXNpb25zIHRoZVxuICAvLyBBc2FyLCBvcGVucyB0aGUgdmF1bHQsIGFuZCBib290c3RyYXBzIHRoZSBoZWxwZXIgbmFtZXNwYWNlKSwgb3Igb3BlbnMgdGhlXG4gIC8vIFZhdWx0IGluIHRoZSBhdHRhY2hlZCBpbnN0YW5jZS5cbiAgYXdhaXQgdmF1bHQucmVnaXN0ZXIodHJhbnNwb3J0KTtcblxuICBjb25zdCB7IGhvc3QsIHBvcnQgfSA9IHJlc29sdmVFbmRwb2ludCh0cmFuc3BvcnQsIG9wdGlvbnMpO1xuICBjb25zdCBjZHBVcmwgPSBgaHR0cDovLyR7aG9zdH06JHtTdHJpbmcocG9ydCl9YDtcbiAgY29uc3QgYXNhckZhbGxiYWNrID0gdHJhbnNwb3J0IGluc3RhbmNlb2YgRGVza3RvcENkcFRyYW5zcG9ydCA/IHRyYW5zcG9ydC5nZXRBc2FyRmFsbGJhY2soKSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgY29tcGF0aWJpbGl0eSA9IHRyYW5zcG9ydCBpbnN0YW5jZW9mIERlc2t0b3BDZHBUcmFuc3BvcnQgPyB0cmFuc3BvcnQuZ2V0Q29tcGF0aWJpbGl0eSgpIDogdW5kZWZpbmVkO1xuICBjb25zdCBlbGVjdHJvbkNvbXBhdGliaWxpdHkgPSB0cmFuc3BvcnQgaW5zdGFuY2VvZiBEZXNrdG9wQ2RwVHJhbnNwb3J0ID8gdHJhbnNwb3J0LmdldEVsZWN0cm9uQ29tcGF0aWJpbGl0eSgpIDogdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGNvbm5lY3Rpb246IENkcENvbm5lY3Rpb24gPSB7XG4gICAgY2RwVXJsLFxuICAgIC4uLihhc2FyRmFsbGJhY2sgJiYgeyBhc2FyRmFsbGJhY2sgfSksXG4gICAgLi4uKGNvbXBhdGliaWxpdHkgJiYgeyBjb21wYXRpYmlsaXR5IH0pLFxuICAgIC4uLihlbGVjdHJvbkNvbXBhdGliaWxpdHkgJiYgeyBlbGVjdHJvbkNvbXBhdGliaWxpdHkgfSksXG5cbiAgICBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHNob3VsZFJlbW92ZVZhdWx0T25EaXNwb3NlKSB7XG4gICAgICAgICAgYXdhaXQgdmF1bHQuZGlzcG9zZSh0cmFuc3BvcnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0IHRyYW5zcG9ydC51bnJlZ2lzdGVyVmF1bHQodmF1bHQucGF0aCk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHRyYW5zcG9ydC5kaXNwb3NlPy4oKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgZXZhbEluT2JzaWRpYW48QXJncyBleHRlbmRzIEdlbmVyaWNPYmplY3QsIFJlc3VsdCwgVENvbnRleHRJZCBleHRlbmRzIENvbnRleHRJZDx1bmtub3duPiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZD4oXG4gICAgICBwYXJhbXM6IEV4Y2VwdDxFdmFsSW5PYnNpZGlhblBhcmFtczxBcmdzLCBSZXN1bHQsIFRDb250ZXh0SWQ+LCAndHJhbnNwb3J0JyB8ICd2YXVsdFBhdGgnPlxuICAgICk6IFByb21pc2U8UmVzdWx0PiB7XG4gICAgICByZXR1cm4gZXZhbEluT2JzaWRpYW48QXJncywgUmVzdWx0LCBUQ29udGV4dElkPih7IC4uLnBhcmFtcywgdHJhbnNwb3J0LCB2YXVsdFBhdGg6IHZhdWx0LnBhdGggfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGludm9rZShleHByZXNzaW9uOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgcmV0dXJuIHRyYW5zcG9ydC5ldmFsdWF0ZShleHByZXNzaW9uLCB7IGN3ZDogdmF1bHQucGF0aCB9KTtcbiAgICB9LFxuXG4gICAgcG9ydCxcblxuICAgIGFzeW5jIFtTeW1ib2wuYXN5bmNEaXNwb3NlXSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24uZGlzcG9zZSgpO1xuICAgIH0sXG5cbiAgICB2YXVsdFxuICB9O1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUge0BsaW5rIE9ic2lkaWFuQ2RwVHJhbnNwb3J0T3B0aW9uc30gZm9yIGEgY29ubmVjdGlvbiwgdGhyZWFkaW5nIG9ubHlcbiAqIHRoZSBwcm92aWRlZCB7QGxpbmsgQ29ubmVjdFRvQ2RwT3B0aW9uc30gdGhyb3VnaCAob3duZWQtdmlzaWJsZSBkZWZhdWx0cyB0b1xuICogYHRydWVgLCB1bmxpa2UgdGhlIGhpZGRlbi1ieS1kZWZhdWx0IHRlc3QgdHJhbnNwb3J0cykuIFVuc2V0IGtub2JzIHBhc3MgdGhyb3VnaFxuICogYXMgYHVuZGVmaW5lZGAgYW5kIGFyZSByZWFkIHdpdGggYD8/IGRlZmF1bHRgIC8gYCE9PSB1bmRlZmluZWRgIGd1YXJkc1xuICogZG93bnN0cmVhbSwgc28gYW4gZXhwbGljaXQgYHVuZGVmaW5lZGAgaXMgaW5kaXN0aW5ndWlzaGFibGUgZnJvbSBhbiBhYnNlbnQga2V5LlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIGNvbm5lY3Rpb24gb3B0aW9ucy5cbiAqIEByZXR1cm5zIFRoZSB0cmFuc3BvcnQgb3B0aW9ucyB0byBjcmVhdGUgdGhlIGNvbm5lY3Rpb24ncyB0cmFuc3BvcnQgZnJvbS5cbiAqL1xuZnVuY3Rpb24gYnVpbGRDZHBUcmFuc3BvcnRPcHRpb25zKG9wdGlvbnM/OiBDb25uZWN0VG9DZHBPcHRpb25zKTogT2JzaWRpYW5DZHBUcmFuc3BvcnRPcHRpb25zIHtcbiAgcmV0dXJuIG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllczxPYnNpZGlhbkNkcFRyYW5zcG9ydE9wdGlvbnM+KHtcbiAgICBjb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzOiBvcHRpb25zPy5jb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzLFxuICAgIGRlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kczogb3B0aW9ucz8uZGVhZEJvb3RHcmFjZUluTWlsbGlzZWNvbmRzLFxuICAgIGhvc3Q6IG9wdGlvbnM/Lmhvc3QsXG4gICAgaXNPYnNpZGlhbkFwcFZpc2libGU6IG9wdGlvbnM/LmlzT2JzaWRpYW5BcHBWaXNpYmxlID8/IHRydWUsXG4gICAgb2JzaWRpYW5JbnN0YWxsZXJWZXJzaW9uOiBvcHRpb25zPy5vYnNpZGlhbkluc3RhbGxlclZlcnNpb24sXG4gICAgb2JzaWRpYW5WZXJzaW9uOiBvcHRpb25zPy5vYnNpZGlhblZlcnNpb24sXG4gICAgcG9ydDogb3B0aW9ucz8ucG9ydCxcbiAgICBzaG91bGREaXNhYmxlU2FuZGJveDogb3B0aW9ucz8uc2hvdWxkRGlzYWJsZVNhbmRib3gsXG4gICAgc2hvdWxkVGhyb3dPbkluY29tcGF0aWJsZUluc3RhbGxlcjogb3B0aW9ucz8uc2hvdWxkVGhyb3dPbkluY29tcGF0aWJsZUluc3RhbGxlcixcbiAgICBzaG91bGRUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrOiBvcHRpb25zPy5zaG91bGRUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrLFxuICAgIHNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXM6IG9wdGlvbnM/LnNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXMsXG4gICAgdHlwZTogJ29ic2lkaWFuLWNkcCdcbiAgfSk7XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIENEUCBob3N0L3BvcnQgZm9yIHRoZSBjb25uZWN0aW9uOiBmcm9tIHRoZSBvd25lZCBpbnN0YW5jZSdzXG4gKiBsYXVuY2hlZCBlbmRwb2ludCB3aGVuIHByZXNlbnQsIG90aGVyd2lzZSBmcm9tIHRoZSBhdHRhY2ggb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0gdHJhbnNwb3J0IC0gVGhlIHRyYW5zcG9ydCBjcmVhdGVkIGZvciB0aGlzIGNvbm5lY3Rpb24uXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBjb25uZWN0aW9uIG9wdGlvbnMuXG4gKiBAcmV0dXJucyBUaGUgcmVzb2x2ZWQgaG9zdCBhbmQgcG9ydC5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIHBvcnQgY2Fubm90IGJlIGRldGVybWluZWQuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVFbmRwb2ludCh0cmFuc3BvcnQ6IHVua25vd24sIG9wdGlvbnM6IENvbm5lY3RUb0NkcE9wdGlvbnMgfCB1bmRlZmluZWQpOiBSZXNvbHZlZEVuZHBvaW50IHtcbiAgaWYgKHRyYW5zcG9ydCBpbnN0YW5jZW9mIERlc2t0b3BDZHBUcmFuc3BvcnQpIHtcbiAgICBjb25zdCBlbmRwb2ludCA9IHRyYW5zcG9ydC5nZXRPd25lZEluc3RhbmNlRW5kcG9pbnQoKTtcbiAgICBpZiAoZW5kcG9pbnQpIHtcbiAgICAgIHJldHVybiB7IGhvc3Q6IGVuZHBvaW50Lmhvc3QsIHBvcnQ6IGVuZHBvaW50LnBvcnQgfTtcbiAgICB9XG4gIH1cblxuICBpZiAob3B0aW9ucz8ucG9ydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHsgaG9zdDogb3B0aW9ucy5ob3N0ID8/IERFRkFVTFRfQ0RQX0hPU1QsIHBvcnQ6IG9wdGlvbnMucG9ydCB9O1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKCdjb25uZWN0VG9DZHA6IGNvdWxkIG5vdCBkZXRlcm1pbmUgdGhlIENEUCBwb3J0LicpO1xufVxuXG4vKipcbiAqIFJlbW92ZXMgdGhlIGhvc3Qtc2lkZSB0ZW1wIGRpcmVjdG9yaWVzIGVhcmxpZXIgcnVucyBsZWFrZWQsIGJlZm9yZSB0aGlzXG4gKiBjb25uZWN0aW9uIGFkZHMgaXRzIG93bi5cbiAqXG4gKiBgY29ubmVjdFRvQ2RwYCBtaW50cyB0aGUgc2FtZSBgdGVtcC12YXVsdC0qYCAvIG93bmVkIGB1c2VyZGF0YS0qYCBkaXJlY3Rvcmllc1xuICogdGhlIHRlc3QgZ2xvYmFsIHNldHVwIGRvZXMsIGFuZCBhbiBhZC1ob2MgZGVidWdnaW5nIHNlc3Npb24gaXMgZXhhY3RseSB0aGVcbiAqIGtpbmQgdGhhdCBnZXRzIGtpbGxlZCB3aXRoIGEgbGVmdG92ZXIgYmVoaW5kIFx1MjAxNCBzbyBpdCBzd2VlcHMgdG9vLiBBZ2UtZ2F0ZWQgYW5kXG4gKiBiZXN0LWVmZm9ydDsgc2VlIHRoZSBjb3JlJ3MgYHN3ZWVwTGVmdG92ZXJzYC5cbiAqXG4gKiBAcGFyYW0gdHJhbnNwb3J0T3B0aW9ucyAtIFRoZSByZXNvbHZlZCB0cmFuc3BvcnQgb3B0aW9ucyAoc291cmNlIG9mIHRoZSBzd2VlcCBrbm9icykuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN3ZWVwTGVmdG92ZXJzKHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuQ2RwVHJhbnNwb3J0T3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIXJlc29sdmVTaG91bGRTd2VlcExlZnRvdmVycyh0cmFuc3BvcnRPcHRpb25zKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3dlZXBIb3N0TGVmdG92ZXJzKHtcbiAgICAgIG1heEFnZUluTWlsbGlzZWNvbmRzOiByZXNvbHZlTGVmdG92ZXJNYXhBZ2VJbk1pbGxpc2Vjb25kcyh0cmFuc3BvcnRPcHRpb25zKVxuICAgIH0pO1xuICAgIGlmIChyZXN1bHQucmVtb3ZlZENvdW50ID4gMCB8fCByZXN1bHQuZmFpbGVkQ291bnQgPiAwKSB7XG4gICAgICBsb2coXG4gICAgICAgIGBbY29ubmVjdC10by1jZHBdIFN3ZXB0ICR7U3RyaW5nKHJlc3VsdC5yZW1vdmVkQ291bnQpfSBsZWZ0b3ZlciB0ZW1wIGRpcmVjdG9yKGllcykgZnJvbSBlYXJsaWVyIHJ1bnMgYFxuICAgICAgICAgICsgYCgke1N0cmluZyhyZXN1bHQuZmFpbGVkQ291bnQpfSBzdGlsbCBpbiB1c2UpLmBcbiAgICAgICk7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2Nvbm5lY3QtdG8tY2RwXSBMZWZ0b3ZlciBzd2VlcCBlcnJvciAobm9uLWZhdGFsKTogJHtTdHJpbmcoZXJyb3IpfWApO1xuICB9XG59XG5cbi8qIHY4IGlnbm9yZSBzdG9wICovXG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBMkJBLDhCQUErQjtBQUMvQiw4QkFJTztBQUNQLGlCQUFvQjtBQUNwQiwyQ0FBNEM7QUFDNUMsd0JBQTBCO0FBQzFCLG1DQUFvQztBQUNwQywrQkFBMkM7QUFFM0MsTUFBTSxtQkFBbUI7QUF3UHpCLGVBQXNCLGFBQWEsU0FBdUQ7QUFDeEYsUUFBTSxtQkFBbUIseUJBQXlCLE9BQU87QUFDekQsUUFBTSxlQUFlLGdCQUFnQjtBQUNyQyxRQUFNLFlBQVksVUFBTSxxREFBMkIsZ0JBQWdCO0FBQ25FLFFBQU0sUUFBUSxJQUFJLDRCQUFVLFNBQVMsS0FBSztBQUMxQyxRQUFNLDZCQUE2QixTQUFTLDhCQUErQixTQUFTLFVBQVU7QUFLOUYsUUFBTSxNQUFNLFNBQVMsU0FBUztBQUU5QixRQUFNLEVBQUUsTUFBTSxLQUFLLElBQUksZ0JBQWdCLFdBQVcsT0FBTztBQUN6RCxRQUFNLFNBQVMsVUFBVSxJQUFJLElBQUksT0FBTyxJQUFJLENBQUM7QUFDN0MsUUFBTSxlQUFlLHFCQUFxQixtREFBc0IsVUFBVSxnQkFBZ0IsSUFBSTtBQUM5RixRQUFNLGdCQUFnQixxQkFBcUIsbURBQXNCLFVBQVUsaUJBQWlCLElBQUk7QUFDaEcsUUFBTSx3QkFBd0IscUJBQXFCLG1EQUFzQixVQUFVLHlCQUF5QixJQUFJO0FBRWhILFFBQU0sYUFBNEI7QUFBQSxJQUNoQztBQUFBLElBQ0EsR0FBSSxnQkFBZ0IsRUFBRSxhQUFhO0FBQUEsSUFDbkMsR0FBSSxpQkFBaUIsRUFBRSxjQUFjO0FBQUEsSUFDckMsR0FBSSx5QkFBeUIsRUFBRSxzQkFBc0I7QUFBQSxJQUVyRCxNQUFNLFVBQXlCO0FBQzdCLFVBQUk7QUFDRixZQUFJLDRCQUE0QjtBQUM5QixnQkFBTSxNQUFNLFFBQVEsU0FBUztBQUFBLFFBQy9CLE9BQU87QUFDTCxnQkFBTSxVQUFVLGdCQUFnQixNQUFNLElBQUk7QUFBQSxRQUM1QztBQUFBLE1BQ0YsVUFBRTtBQUNBLGNBQU0sVUFBVSxVQUFVO0FBQUEsTUFDNUI7QUFBQSxJQUNGO0FBQUEsSUFFQSxNQUFNLGVBQ0osUUFDaUI7QUFDakIsaUJBQU8sd0NBQXlDLEVBQUUsR0FBRyxRQUFRLFdBQVcsV0FBVyxNQUFNLEtBQUssQ0FBQztBQUFBLElBQ2pHO0FBQUEsSUFFQSxNQUFNLE9BQU8sWUFBcUM7QUFDaEQsYUFBTyxVQUFVLFNBQVMsWUFBWSxFQUFFLEtBQUssTUFBTSxLQUFLLENBQUM7QUFBQSxJQUMzRDtBQUFBLElBRUE7QUFBQSxJQUVBLE9BQU8sT0FBTyxZQUFZLElBQW1CO0FBQzNDLFlBQU0sV0FBVyxRQUFRO0FBQUEsSUFDM0I7QUFBQSxJQUVBO0FBQUEsRUFDRjtBQUVBLFNBQU87QUFDVDtBQVlBLFNBQVMseUJBQXlCLFNBQTREO0FBQzVGLGFBQU8sa0VBQXlEO0FBQUEsSUFDOUQsOEJBQThCLFNBQVM7QUFBQSxJQUN2Qyw2QkFBNkIsU0FBUztBQUFBLElBQ3RDLE1BQU0sU0FBUztBQUFBLElBQ2Ysc0JBQXNCLFNBQVMsd0JBQXdCO0FBQUEsSUFDdkQsMEJBQTBCLFNBQVM7QUFBQSxJQUNuQyxpQkFBaUIsU0FBUztBQUFBLElBQzFCLE1BQU0sU0FBUztBQUFBLElBQ2Ysc0JBQXNCLFNBQVM7QUFBQSxJQUMvQixvQ0FBb0MsU0FBUztBQUFBLElBQzdDLGlDQUFpQyxTQUFTO0FBQUEsSUFDMUMsaUNBQWlDLFNBQVM7QUFBQSxJQUMxQyxNQUFNO0FBQUEsRUFDUixDQUFDO0FBQ0g7QUFXQSxTQUFTLGdCQUFnQixXQUFvQixTQUE0RDtBQUN2RyxNQUFJLHFCQUFxQixrREFBcUI7QUFDNUMsVUFBTSxXQUFXLFVBQVUseUJBQXlCO0FBQ3BELFFBQUksVUFBVTtBQUNaLGFBQU8sRUFBRSxNQUFNLFNBQVMsTUFBTSxNQUFNLFNBQVMsS0FBSztBQUFBLElBQ3BEO0FBQUEsRUFDRjtBQUVBLE1BQUksU0FBUyxTQUFTLFFBQVc7QUFDL0IsV0FBTyxFQUFFLE1BQU0sUUFBUSxRQUFRLGtCQUFrQixNQUFNLFFBQVEsS0FBSztBQUFBLEVBQ3RFO0FBRUEsUUFBTSxJQUFJLE1BQU0saURBQWlEO0FBQ25FO0FBYUEsZUFBZSxlQUFlLGtCQUE4RDtBQUMxRixNQUFJLEtBQUMscURBQTRCLGdCQUFnQixHQUFHO0FBQ2xEO0FBQUEsRUFDRjtBQUVBLE1BQUk7QUFDRixVQUFNLFNBQVMsVUFBTSw0Q0FBbUI7QUFBQSxNQUN0QywwQkFBc0IsNkRBQW9DLGdCQUFnQjtBQUFBLElBQzVFLENBQUM7QUFDRCxRQUFJLE9BQU8sZUFBZSxLQUFLLE9BQU8sY0FBYyxHQUFHO0FBQ3JEO0FBQUEsUUFDRSwwQkFBMEIsT0FBTyxPQUFPLFlBQVksQ0FBQyxtREFDN0MsT0FBTyxPQUFPLFdBQVcsQ0FBQztBQUFBLE1BQ3BDO0FBQUEsSUFDRjtBQUFBLEVBQ0YsU0FBUyxPQUFnQjtBQUN2Qix3QkFBSSxzREFBc0QsT0FBTyxLQUFLLENBQUMsRUFBRTtBQUFBLEVBQzNFO0FBQ0Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -41,6 +41,7 @@ var import_promises2 = require("node:timers/promises");
41
41
  var import_enable_plugin = require("./enable-plugin.cjs");
42
42
  var import_error_to_string = require("./error-to-string.cjs");
43
43
  var import_eval_in_obsidian = require("./eval-in-obsidian.cjs");
44
+ var import_leftover_cleanup = require("./leftover-cleanup.cjs");
44
45
  var import_log = require("./log.cjs");
45
46
  var import_plugin_enable_retry = require("./plugin-enable-retry.cjs");
46
47
  var import_setup_lock = require("./setup-lock.cjs");
@@ -77,6 +78,7 @@ async function coreSetup(params) {
77
78
  lock = await (0, import_setup_lock.acquireSetupLock)({ label, scope: lockScope });
78
79
  (0, import_log.log)(`[integration-setup:${label}] Setup lock acquired.`);
79
80
  }
81
+ await sweepLeftovers({ label, phase: "setup", transportOptions });
80
82
  let transport;
81
83
  let tempVault;
82
84
  try {
@@ -155,6 +157,12 @@ async function coreTeardown(result) {
155
157
  activeSetups.delete(result);
156
158
  releaseSetupLock(result);
157
159
  }
160
+ await sweepLeftovers({
161
+ excludedNames: [...activeSetups].map((activeSetup) => (0, import_node_path.basename)(activeSetup.tempVault.path)),
162
+ label: result.transportLabel,
163
+ phase: "teardown",
164
+ transportOptions: result.transportOptions
165
+ });
158
166
  }
159
167
  function resolveIntegrationTransportOptions(options) {
160
168
  if (options?.type === "obsidian-android-appium") {
@@ -367,6 +375,25 @@ async function resolveDistPath(projectRoot) {
367
375
  }
368
376
  throw new Error("No build found. Run `npm run build` or `npm run dev` first.");
369
377
  }
378
+ async function sweepLeftovers(params) {
379
+ const { label, phase, transportOptions } = params;
380
+ if (!(0, import_leftover_cleanup.resolveShouldSweepLeftovers)(transportOptions)) {
381
+ return;
382
+ }
383
+ try {
384
+ const result = await (0, import_leftover_cleanup.sweepHostLeftovers)({
385
+ excludedNames: params.excludedNames,
386
+ maxAgeInMilliseconds: (0, import_leftover_cleanup.resolveLeftoverMaxAgeInMilliseconds)(transportOptions)
387
+ });
388
+ if (result.removedCount > 0 || result.failedCount > 0) {
389
+ (0, import_log.log)(
390
+ `[integration-${phase}:${label}] Swept ${String(result.removedCount)} leftover temp director(ies) from earlier runs (${String(result.failedCount)} still in use).`
391
+ );
392
+ }
393
+ } catch (error) {
394
+ (0, import_log.log)(`[integration-${phase}:${label}] Leftover sweep error (non-fatal): ${(0, import_error_to_string.errorToString)(error)}`);
395
+ }
396
+ }
370
397
  async function teardownAsync(result) {
371
398
  try {
372
399
  await result.tempVault.dispose(result.transport);
@@ -385,4 +412,4 @@ async function teardownAsync(result) {
385
412
  coreTeardown,
386
413
  resolveIntegrationTransportOptions
387
414
  });
388
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2dsb2JhbC1zZXR1cC1jb3JlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogRnJhbWV3b3JrLWFnbm9zdGljIGNvcmUgbG9naWMgZm9yIGludGVncmF0aW9uIHRlc3QgZ2xvYmFsIHNldHVwIGFuZCB0ZWFyZG93bi5cbiAqXG4gKiBWaXRlc3QgYW5kIEplc3QgYWRhcHRlcnMgZGVsZWdhdGUgdG8gdGhlc2UgZnVuY3Rpb25zLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIHNldHVwIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7IFBsdWdpbk1hbmlmZXN0IH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQge1xuICBleGlzdHNTeW5jLFxuICBybVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBjcCxcbiAgbWtkaXIsXG4gIHJlYWRGaWxlLFxuICBzdGF0LFxuICB3cml0ZUZpbGVcbn0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCBwcm9jZXNzLCB7IGxvYWRFbnZGaWxlIH0gZnJvbSAnbm9kZTpwcm9jZXNzJztcbmltcG9ydCB7IHNldFRpbWVvdXQgYXMgc2xlZXAgfSBmcm9tICdub2RlOnRpbWVycy9wcm9taXNlcyc7XG5cbmltcG9ydCB0eXBlIHsgRW5hYmxlUGx1Z2luUmVzdWx0IH0gZnJvbSAnLi9lbmFibGUtcGx1Z2luLmNqcyc7XG5pbXBvcnQgdHlwZSB7IFNldHVwTG9jayB9IGZyb20gJy4vc2V0dXAtbG9jay5janMnO1xuaW1wb3J0IHR5cGUgeyBQb3B1bGF0ZUZpbGVzUGFyYW1zIH0gZnJvbSAnLi90ZW1wLXZhdWx0LmNqcyc7XG5pbXBvcnQgdHlwZSB7IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LW9wdGlvbnMuY2pzJztcbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC5janMnO1xuXG5pbXBvcnQge1xuICBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlLFxuICBnZXRHZW5lcmljUGx1Z2luTG9hZEZhaWx1cmVNZXNzYWdlXG59IGZyb20gJy4vZW5hYmxlLXBsdWdpbi5janMnO1xuaW1wb3J0IHsgZXJyb3JUb1N0cmluZyB9IGZyb20gJy4vZXJyb3ItdG8tc3RyaW5nLmNqcyc7XG5pbXBvcnQgeyBldmFsSW5PYnNpZGlhbiB9IGZyb20gJy4vZXZhbC1pbi1vYnNpZGlhbi5janMnO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSAnLi9sb2cuY2pzJztcbmltcG9ydCB7XG4gIGNvbXB1dGVCYWNrb2ZmRGVsYXlJbk1pbGxpc2Vjb25kcyxcbiAgcmVzb2x2ZVBsdWdpbkVuYWJsZVJldHJ5Q291bnQsXG4gIHJlc29sdmVQbHVnaW5FbmFibGVSZXRyeURlbGF5SW5NaWxsaXNlY29uZHMsXG4gIHNob3VsZFJldHJ5UGx1Z2luRW5hYmxlXG59IGZyb20gJy4vcGx1Z2luLWVuYWJsZS1yZXRyeS5janMnO1xuaW1wb3J0IHsgYWNxdWlyZVNldHVwTG9jayB9IGZyb20gJy4vc2V0dXAtbG9jay5janMnO1xuaW1wb3J0IHsgVGVtcFZhdWx0IH0gZnJvbSAnLi90ZW1wLXZhdWx0LmNqcyc7XG5pbXBvcnQgeyBBcHBpdW1UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC1hcHBpdW0uY2pzJztcbmltcG9ydCB7IERlc2t0b3BDZHBUcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC1kZXNrdG9wLWNkcC5janMnO1xuaW1wb3J0IHsgY3JlYXRlVHJhbnNwb3J0RnJvbU9wdGlvbnMgfSBmcm9tICcuL3RyYW5zcG9ydC1mYWN0b3J5LmNqcyc7XG5cbmNvbnN0IERFRkFVTFRfVFJBTlNQT1JUX1RZUEUgPSAnb2JzaWRpYW4tY2RwJztcbmNvbnN0IERJU1RfREVWID0gJ2Rpc3QvZGV2JztcbmNvbnN0IERJU1RfQlVJTEQgPSAnZGlzdC9idWlsZCc7XG5jb25zdCBNQUlOX0pTID0gJ21haW4uanMnO1xuY29uc3QgT0JTSURJQU5fQ09ORklHX0RJUiA9ICcub2JzaWRpYW4nO1xuY29uc3QgUExVR0lOU19ESVIgPSAncGx1Z2lucyc7XG5jb25zdCBDT01NVU5JVFlfUExVR0lOU19KU09OID0gJ2NvbW11bml0eS1wbHVnaW5zLmpzb24nO1xuY29uc3QgQVBQX0pTT04gPSAnYXBwLmpzb24nO1xuY29uc3QgQVBQX0pTT05fSU5ERU5UID0gMjtcblxuLyoqXG4gKiBUcmFja3Mgc2V0dXBzIHRoYXQgY29tcGxldGVkIHN1Y2Nlc3NmdWxseSBidXQgaGF2ZW4ndCBiZWVuIHRvcm4gZG93biB5ZXQuXG4gKiBVc2VkIGJ5IHRoZSBgYmVmb3JlRXhpdGAgaGFuZGxlciB0byBjbGVhbiB1cCB3aGVuIGEgdGVzdCBydW5uZXIgZXhpdHNcbiAqIHdpdGhvdXQgY2FsbGluZyB0ZWFyZG93biAoZS5nLiwgd2hlbiBvbmUgcHJvamVjdCdzIHNldHVwIGZhaWxzIGFuZCB0aGVcbiAqIHJ1bm5lciBhYm9ydHMgYmVmb3JlIHRlYXJpbmcgZG93biBhbHJlYWR5LWluaXRpYWxpemVkIHByb2plY3RzKS5cbiAqL1xuY29uc3QgYWN0aXZlU2V0dXBzID0gbmV3IFNldDxDb3JlU2V0dXBSZXN1bHQ+KCk7XG5jb25zdCBkaXNwb3NlZFJlc3VsdHMgPSBuZXcgV2Vha1NldDxDb3JlU2V0dXBSZXN1bHQ+KCk7XG5sZXQgaXNDbGVhbnVwSGFuZGxlclJlZ2lzdGVyZWQgPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgY3Jvc3MtcHJvY2VzcyBzZXR1cCBsb2NrIGhlbGQgYnkgZWFjaCBhY3RpdmUgc2V0dXAuIFJlbGVhc2VkIHdoZW4gdGhlXG4gKiBzZXR1cCBpcyB0b3JuIGRvd24gKG9yIGJ5IHRoZSBwcm9jZXNzIGNsZWFudXAgaGFuZGxlcnMpLCBhbGxvd2luZyBhIGNvbXBldGluZ1xuICogcnVuIHRvIHByb2NlZWQuIFNlZSB7QGxpbmsgYWNxdWlyZVNldHVwTG9ja30uXG4gKi9cbmNvbnN0IHNldHVwTG9ja3MgPSBuZXcgTWFwPENvcmVTZXR1cFJlc3VsdCwgU2V0dXBMb2NrPigpO1xuXG5jb25zdCBBTkRST0lEX0xPQ0tfU0NPUEUgPSAnYW5kcm9pZCc7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNvcmVTZXR1cH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29yZVNldHVwUGFyYW1zIHtcbiAgLyoqXG4gICAqIENvbW11bml0eS1wbHVnaW4gaWRzIHRvIGVuYWJsZSBpbiB0aGUgdmF1bHQgKippbiBhZGRpdGlvbiB0byoqIHRoZVxuICAgKiBwbHVnaW4tdW5kZXItdGVzdCwgYWZ0ZXIgaXQgaXMgZW5hYmxlZC4gRWFjaCBpZCdzIGJ1aWx0IGZpbGVzIG11c3QgYWxyZWFkeSBiZVxuICAgKiBwcmVzZW50IHVuZGVyIGAub2JzaWRpYW4vcGx1Z2lucy88aWQ+L2AgXHUyMDE0IHNlZWQgdGhlbSB2aWEge0BsaW5rIENvcmVTZXR1cFBhcmFtcy5wb3B1bGF0ZX1cbiAgICogKGUuZy4gd2l0aCBgYnVpbGREZW1vVmF1bHRQb3B1bGF0ZWApLiBFbmFibGluZyBnb2VzIHRocm91Z2ggdGhlIHNhbWVcbiAgICogcmV0cnkvbG9hZC12ZXJpZnkgcGF0aCBhcyB0aGUgcGx1Z2luLXVuZGVyLXRlc3QuIENvbXBvc2VzIHdpdGhcbiAgICogYGluc3RhbGxQbHVnaW46IGZhbHNlYCAoZW5hYmxlIGV4dHJhcyBpbnRvIGFuIG90aGVyd2lzZSBwbHVnaW4tbGVzcyB2YXVsdCkuXG4gICAqL1xuICByZWFkb25seSBlbmFibGVDb21tdW5pdHlQbHVnaW5zPzogcmVhZG9ubHkgc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gaW5zdGFsbCBhbmQgZW5hYmxlIHRoZSBidWlsdCBwbHVnaW4gaW4gdGhlIHRlbXAgdmF1bHQuIERlZmF1bHRzXG4gICAqIHRvIGB0cnVlYC4gU2V0IHRvIGBmYWxzZWAgZm9yIGEgKipub24tcGx1Z2luKiogY29uc3VtZXIgKGUuZy4gYSB0eXBpbmdzXG4gICAqIGNyYXdsZXIpIHRoYXQgb25seSBuZWVkcyBhIHJlZ2lzdGVyZWQsIGVtcHR5IHZhdWx0IHRvIGBldmFsSW5PYnNpZGlhbmBcbiAgICogYWdhaW5zdDogdGhlIHBsdWdpbiBgZGlzdGAvYG1hbmlmZXN0Lmpzb25gIHJlYWQsIHRoZSBjb3B5IGludG9cbiAgICogYC5vYnNpZGlhbi9wbHVnaW5zYCwgdGhlIGBjb21tdW5pdHktcGx1Z2lucy5qc29uYCB3cml0ZSwgYW5kIHRoZSBlbmFibGUgc3RlcFxuICAgKiBhcmUgYWxsIHNraXBwZWQsIHdoaWxlIHRoZSB0cmFuc3BvcnQsIHRlbXAgdmF1bHQsIHJlZ2lzdHJhdGlvbiwgYW5kXG4gICAqIHdvcmtlci1mYWNpbmcgZW5kcG9pbnQgcHJvdmlzaW9uaW5nIHN0aWxsIHJ1biB1bmNoYW5nZWQuXG4gICAqL1xuICByZWFkb25seSBpbnN0YWxsUGx1Z2luPzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogRmlsZXMgYW5kIGZvbGRlcnMgdG8gd3JpdGUgaW50byB0aGUgdmF1bHQgKipiZWZvcmUqKiBPYnNpZGlhbiBvcGVucyBpdCwgc29cbiAgICogaXRzIHN0YXJ0dXAgc2NhbiBpbmRleGVzIHRoZW0gaW4gb25lIHBhc3MgKHNlZSB7QGxpbmsgVGVtcFZhdWx0LnBvcHVsYXRlfSkuXG4gICAqIFVzZSB0aGlzIGZvciBsYXJnZSBmaXh0dXJlcyBcdTIwMTQgd3JpdGluZyB0aG91c2FuZHMgb2Ygbm90ZXMgYWZ0ZXIgb3BlbiBhbmRcbiAgICogZm9yY2luZyBhIHJlLXNjYW4gaXMgZmFyIHNsb3dlciBhbmQgbGVzcyByZWxpYWJsZS5cbiAgICovXG4gIHJlYWRvbmx5IHBvcHVsYXRlPzogUG9wdWxhdGVGaWxlc1BhcmFtcyB8IHVuZGVmaW5lZDtcblxuICAvKiogVHJhbnNwb3J0IG9wdGlvbnMuIFdoZW4gb21pdHRlZCwgdXNlcyBhbiBvZmYtc2NyZWVuIG93bmVkIGRlc2t0b3AgaW5zdGFuY2UuICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM/OiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmVzdWx0IHJldHVybmVkIGJ5IHtAbGluayBjb3JlU2V0dXB9LCB1c2VkIGJ5IGZyYW1ld29yayBhZGFwdGVyc1xuICogdG8gcGFzcyBjb250ZXh0IHRvIHRlc3Qgd29ya2Vycy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb3JlU2V0dXBSZXN1bHQge1xuICAvKiogVGhlIHRlbXBvcmFyeSB2YXVsdCBjcmVhdGVkIGR1cmluZyBzZXR1cC4gKi9cbiAgcmVhZG9ubHkgdGVtcFZhdWx0OiBUZW1wVmF1bHQ7XG5cbiAgLyoqIFRoZSB0cmFuc3BvcnQgaW5zdGFuY2UgdXNlZCBkdXJpbmcgc2V0dXAuICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnQ7XG5cbiAgLyoqIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMgKGUuZy4gYFwib2JzaWRpYW4tY2RwXCJgKS4gKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0TGFiZWw6IHN0cmluZztcblxuICAvKiogVGhlIHRyYW5zcG9ydCBvcHRpb25zIHRoYXQgd2VyZSByZXNvbHZlZC4gKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBjb3B5UGx1Z2luSW50b1ZhdWx0fS5cbiAqL1xuaW50ZXJmYWNlIENvcHlQbHVnaW5JbnRvVmF1bHRQYXJhbXMge1xuICAvKiogU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcy4gKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKiogVGhlIHByb2plY3Qgcm9vdCB0byByZXNvbHZlIHRoZSBidWlsdCBwbHVnaW4gZnJvbS4gKi9cbiAgcmVhZG9ubHkgcHJvamVjdFJvb3Q6IHN0cmluZztcblxuICAvKiogVGhlIHRlbXAgdmF1bHQgdG8gY29weSB0aGUgcGx1Z2luIGludG8uICovXG4gIHJlYWRvbmx5IHRlbXBWYXVsdDogVGVtcFZhdWx0O1xuXG4gIC8qKiBUaGUgdHJhbnNwb3J0ICh1c2VkIGZvciB0aGUgbW9iaWxlL2Rlc2t0b3Atb25seSBjb21wYXRpYmlsaXR5IGNoZWNrKS4gKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydDtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgZW5hYmxlRXh0cmFDb21tdW5pdHlQbHVnaW5zfS5cbiAqL1xuaW50ZXJmYWNlIEVuYWJsZUV4dHJhQ29tbXVuaXR5UGx1Z2luc1BhcmFtcyB7XG4gIC8qKiBTaG9ydCBsYWJlbCBmb3IgbG9nIG1lc3NhZ2VzLiAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgaWRzIG9mIHRoZSBleHRyYSBjb21tdW5pdHkgcGx1Z2lucyB0byBlbmFibGUgKHRoZWlyIGJpbmFyaWVzIG11c3QgYWxyZWFkeSBiZSBpbiB0aGUgdmF1bHQpLiAqL1xuICByZWFkb25seSBwbHVnaW5JZHM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8qKiBUaGUgdGVtcCB2YXVsdCB0aGUgcGx1Z2lucyB3ZXJlIHNlZWRlZCBpbnRvLiAqL1xuICByZWFkb25seSB0ZW1wVmF1bHQ6IFRlbXBWYXVsdDtcblxuICAvKiogVGhlIHRyYW5zcG9ydCB0byBldmFsdWF0ZSBhZ2FpbnN0LiAqL1xuICByZWFkb25seSB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0O1xuXG4gIC8qKiBUaGUgcmVzb2x2ZWQgdHJhbnNwb3J0IG9wdGlvbnMgKHNvdXJjZSBvZiB0aGUgcGx1Z2luLWVuYWJsZSByZXRyeSBrbm9icykuICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM6IG51bGwgfCBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnM7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGVuYWJsZVBsdWdpbkluVmF1bHR9LlxuICovXG5pbnRlcmZhY2UgRW5hYmxlUGx1Z2luSW5WYXVsdFBhcmFtcyB7XG4gIC8qKiBTaG9ydCBsYWJlbCBmb3IgbG9nIG1lc3NhZ2VzLiAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgaWQgb2YgdGhlIHBsdWdpbiB0byBlbmFibGUuICovXG4gIHJlYWRvbmx5IHBsdWdpbklkOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSB0ZW1wIHZhdWx0IHRoZSBwbHVnaW4gd2FzIGNvcGllZCBpbnRvLiAqL1xuICByZWFkb25seSB0ZW1wVmF1bHQ6IFRlbXBWYXVsdDtcblxuICAvKiogVGhlIHRyYW5zcG9ydCB0byBldmFsdWF0ZSBhZ2FpbnN0LiAqL1xuICByZWFkb25seSB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0O1xuXG4gIC8qKiBUaGUgcmVzb2x2ZWQgdHJhbnNwb3J0IG9wdGlvbnMgKHNvdXJjZSBvZiB0aGUgcGx1Z2luLWVuYWJsZSByZXRyeSBrbm9icykuICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM6IG51bGwgfCBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnM7XG59XG5cbi8qKlxuICogRnJhbWV3b3JrLWFnbm9zdGljIGdsb2JhbCBzZXR1cCBsb2dpYy5cbiAqXG4gKiBMb2FkcyBgLmVudmAgZnJvbSB0aGUgcHJvamVjdCByb290LCBjcmVhdGVzIGEgdHJhbnNwb3J0LCBjcmVhdGVzIGFuZCByZWdpc3RlcnNcbiAqIGEgdGVtcG9yYXJ5IHZhdWx0IHdpdGggT2JzaWRpYW4sIGFuZCBcdTIwMTQgdW5sZXNzIHtAbGluayBDb3JlU2V0dXBQYXJhbXMuaW5zdGFsbFBsdWdpbn1cbiAqIGlzIGBmYWxzZWAgXHUyMDE0IGNvcGllcyB0aGUgYnVpbHQgcGx1Z2luIGludG8gdGhlIHZhdWx0IGFuZCBlbmFibGVzIGl0LiBUaGVcbiAqIHBsdWdpbi1sZXNzIG1vZGUgc3RpbGwgbGF1bmNoZXMgdGhlIG93bmVkIGluc3RhbmNlIGFuZCBwdWJsaXNoZXMgaXRzXG4gKiB3b3JrZXItZmFjaW5nIGVuZHBvaW50LCBzbyBhIG5vbi1wbHVnaW4gY29uc3VtZXIgcmV1c2VzIHRoZSBzYW1lIGF0dGFjaCB3aXJpbmcuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFNldHVwIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgc2V0dXAgcmVzdWx0IGNvbnRhaW5pbmcgdGhlIHRlbXAgdmF1bHQsIHRyYW5zcG9ydCwgYW5kIHJlc29sdmVkIG9wdGlvbnMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb3JlU2V0dXAocGFyYW1zPzogQ29yZVNldHVwUGFyYW1zKTogUHJvbWlzZTxDb3JlU2V0dXBSZXN1bHQ+IHtcbiAgY29uc3QgcHJvamVjdFJvb3QgPSBmaW5kUHJvamVjdFJvb3QoKTtcbiAgY29uc3QgZW52RmlsZVBhdGggPSBqb2luKHByb2plY3RSb290LCAnLmVudicpO1xuICBpZiAoZXhpc3RzU3luYyhlbnZGaWxlUGF0aCkpIHtcbiAgICBsb2FkRW52RmlsZShlbnZGaWxlUGF0aCk7XG4gIH1cblxuICBjb25zdCB0cmFuc3BvcnRPcHRpb25zID0gcmVzb2x2ZUludGVncmF0aW9uVHJhbnNwb3J0T3B0aW9ucyhwYXJhbXM/LnRyYW5zcG9ydE9wdGlvbnMpO1xuICBjb25zdCBsYWJlbCA9IHRyYW5zcG9ydE9wdGlvbnMudHlwZTtcbiAgY29uc3QgbG9ja1Njb3BlID0gZ2V0TG9ja1Njb3BlKHRyYW5zcG9ydE9wdGlvbnMpO1xuXG4gIGxldCBsb2NrOiBTZXR1cExvY2sgfCB1bmRlZmluZWQ7XG4gIGlmIChsb2NrU2NvcGUgIT09IHVuZGVmaW5lZCkge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBBY3F1aXJpbmcgJyR7bG9ja1Njb3BlfScgc2V0dXAgbG9jayAoc2VyaWFsaXplcyBhZ2FpbnN0IGFueSBjb25jdXJyZW50IGludGVncmF0aW9uLXRlc3QgcnVuKS4uLmApO1xuICAgIGxvY2sgPSBhd2FpdCBhY3F1aXJlU2V0dXBMb2NrKHsgbGFiZWwsIHNjb3BlOiBsb2NrU2NvcGUgfSk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFNldHVwIGxvY2sgYWNxdWlyZWQuYCk7XG4gIH1cblxuICBsZXQgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydCB8IHVuZGVmaW5lZDtcbiAgbGV0IHRlbXBWYXVsdDogVGVtcFZhdWx0IHwgdW5kZWZpbmVkO1xuXG4gIHRyeSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIENyZWF0aW5nIHRyYW5zcG9ydC4uLmApO1xuICAgIHRyYW5zcG9ydCA9IGF3YWl0IGNyZWF0ZVRyYW5zcG9ydEZyb21PcHRpb25zKHRyYW5zcG9ydE9wdGlvbnMpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBUcmFuc3BvcnQgY3JlYXRlZDogJHt0cmFuc3BvcnQuY29uc3RydWN0b3IubmFtZX1gKTtcblxuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBQcm9qZWN0IHJvb3Q6ICR7cHJvamVjdFJvb3R9YCk7XG4gICAgY29uc3Qgc2hvdWxkSW5zdGFsbFBsdWdpbiA9IHBhcmFtcz8uaW5zdGFsbFBsdWdpbiAhPT0gZmFsc2U7XG5cbiAgICB0ZW1wVmF1bHQgPSBuZXcgVGVtcFZhdWx0KCk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIENyZWF0ZWQgdGVtcCB2YXVsdDogJHt0ZW1wVmF1bHQucGF0aH1gKTtcblxuICAgIGxldCBwbHVnaW5JZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgaWYgKHNob3VsZEluc3RhbGxQbHVnaW4pIHtcbiAgICAgIHBsdWdpbklkID0gYXdhaXQgY29weVBsdWdpbkludG9WYXVsdCh7IGxhYmVsLCBwcm9qZWN0Um9vdCwgdGVtcFZhdWx0LCB0cmFuc3BvcnQgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBTa2lwcGluZyBwbHVnaW4gaW5zdGFsbCAoaW5zdGFsbFBsdWdpbjogZmFsc2UpIFx1MjAxNCByZWdpc3RlcmluZyBhbiBlbXB0eSB2YXVsdC5gKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zPy5wb3B1bGF0ZSkge1xuICAgICAgY29uc3QgZW50cnlDb3VudCA9IE9iamVjdC5rZXlzKHBhcmFtcy5wb3B1bGF0ZSkubGVuZ3RoO1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFBvcHVsYXRpbmcgdmF1bHQgd2l0aCAke1N0cmluZyhlbnRyeUNvdW50KX0gZW50cmllcyBiZWZvcmUgb3Blbi4uLmApO1xuICAgICAgdGVtcFZhdWx0LnBvcHVsYXRlKHBhcmFtcy5wb3B1bGF0ZSk7XG4gICAgfVxuXG4gICAgYXdhaXQgZW5zdXJlQWx3YXlzVXBkYXRlTGlua3ModGVtcFZhdWx0LCBsYWJlbCk7XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gU3luY2luZyB2YXVsdCB0byBkZXZpY2UuLi5gKTtcbiAgICBhd2FpdCB0ZW1wVmF1bHQuc3luY1RvRGV2aWNlKHRyYW5zcG9ydCk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFJlZ2lzdGVyaW5nIHZhdWx0Li4uYCk7XG4gICAgYXdhaXQgdGVtcFZhdWx0LnJlZ2lzdGVyKHRyYW5zcG9ydCk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFZhdWx0IHJlZ2lzdGVyZWQuYCk7XG5cbiAgICBpZiAocGx1Z2luSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYXdhaXQgZW5hYmxlUGx1Z2luSW5WYXVsdCh7IGxhYmVsLCBwbHVnaW5JZCwgdGVtcFZhdWx0LCB0cmFuc3BvcnQsIHRyYW5zcG9ydE9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgYXdhaXQgZW5hYmxlRXh0cmFDb21tdW5pdHlQbHVnaW5zKHtcbiAgICAgIGxhYmVsLFxuICAgICAgcGx1Z2luSWRzOiBwYXJhbXM/LmVuYWJsZUNvbW11bml0eVBsdWdpbnMgPz8gW10sXG4gICAgICB0ZW1wVmF1bHQsXG4gICAgICB0cmFuc3BvcnQsXG4gICAgICB0cmFuc3BvcnRPcHRpb25zXG4gICAgfSk7XG5cbiAgICBjb25zdCBhdWdtZW50ZWRPcHRpb25zID0gYXVnbWVudFRyYW5zcG9ydE9wdGlvbnModHJhbnNwb3J0T3B0aW9ucywgdHJhbnNwb3J0KTtcbiAgICBjb25zdCByZXN1bHQ6IENvcmVTZXR1cFJlc3VsdCA9IHsgdGVtcFZhdWx0LCB0cmFuc3BvcnQsIHRyYW5zcG9ydExhYmVsOiBsYWJlbCwgdHJhbnNwb3J0T3B0aW9uczogYXVnbWVudGVkT3B0aW9ucyB9O1xuICAgIGFjdGl2ZVNldHVwcy5hZGQocmVzdWx0KTtcbiAgICBpZiAobG9jaykge1xuICAgICAgc2V0dXBMb2Nrcy5zZXQocmVzdWx0LCBsb2NrKTtcbiAgICB9XG4gICAgcmVnaXN0ZXJQcm9jZXNzQ2xlYW51cEhhbmRsZXIoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBTZXR1cCBmYWlsZWQsIGNsZWFuaW5nIHVwLi4uYCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh0ZW1wVmF1bHQgJiYgdHJhbnNwb3J0KSB7XG4gICAgICAgIGF3YWl0IHRlbXBWYXVsdC5kaXNwb3NlKHRyYW5zcG9ydCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoY2xlYW51cEVycm9yOiB1bmtub3duKSB7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gVmF1bHQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGNsZWFudXBFcnJvcil9YCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0cmFuc3BvcnQ/LmRpc3Bvc2U/LigpO1xuICAgIH0gY2F0Y2ggKGNsZWFudXBFcnJvcjogdW5rbm93bikge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFRyYW5zcG9ydCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoY2xlYW51cEVycm9yKX1gKTtcbiAgICB9XG5cbiAgICAvLyBSZWxlYXNlIHRoZSBsb2NrIHNvIGEgd2FpdGluZyBydW4gY2FuIHByb2NlZWQgZXZlbiB0aG91Z2ggdGhpcyBydW4gZmFpbGVkLlxuICAgIGxvY2s/LnJlbGVhc2UoKTtcblxuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBOT1RFOiBJZiB0aGUgdGVzdCBydW5uZXIgcmVwb3J0cyBcIk5vIHRlc3QgZmlsZXMgZm91bmRcIiwgaWdub3JlIGl0IFx1MjAxNCBpdCBpcyBhIHNpZGUgZWZmZWN0IG9mIHRoZSBzZXR1cCBmYWlsdXJlIGFib3ZlLmApO1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbi8qKlxuICogRnJhbWV3b3JrLWFnbm9zdGljIGdsb2JhbCB0ZWFyZG93biBsb2dpYy5cbiAqXG4gKiBEaXNwb3NlcyBvZiB0aGUgdGVtcG9yYXJ5IHZhdWx0IGFuZCB0cmFuc3BvcnQgY3JlYXRlZCBkdXJpbmcgc2V0dXAuXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIFRoZSByZXN1bHQgZnJvbSB7QGxpbmsgY29yZVNldHVwfS4gV2hlbiBgdW5kZWZpbmVkYCwgZG9lcyBub3RoaW5nLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29yZVRlYXJkb3duKHJlc3VsdD86IENvcmVTZXR1cFJlc3VsdCk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIXJlc3VsdCB8fCBkaXNwb3NlZFJlc3VsdHMuaGFzKHJlc3VsdCkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgZGlzcG9zZWRSZXN1bHRzLmFkZChyZXN1bHQpO1xuXG4gIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gVGVhcmluZyBkb3duLi4uYCk7XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCB0ZWFyZG93bkFzeW5jKHJlc3VsdCk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBDbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICB9IGZpbmFsbHkge1xuICAgIGFjdGl2ZVNldHVwcy5kZWxldGUocmVzdWx0KTtcbiAgICByZWxlYXNlU2V0dXBMb2NrKHJlc3VsdCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0cmFuc3BvcnQgb3B0aW9ucyBmb3IgYW4gaW50ZWdyYXRpb24gcnVuLlxuICpcbiAqIERlc2t0b3AgbGF1bmNoZXMgYXJlIG5vcm1hbGx5IHZpc2libGUsIGJ1dCB0ZXN0IHNldHVwIGV4cGxpY2l0bHkga2VlcHMgaXRzXG4gKiBvd25lZCBpbnN0YW5jZSBvZmYtc2NyZWVuIHNvIGl0IGRvZXMgbm90IGludGVycnVwdCB0aGUgZGV2ZWxvcGVyLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uc3VtZXItcHJvdmlkZWQgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcmV0dXJucyBPcHRpb25zIHdpdGggdGhlIGRlc2t0b3AgaW50ZWdyYXRpb24gdmlzaWJpbGl0eSBkZWZhdWx0IGFwcGxpZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlSW50ZWdyYXRpb25UcmFuc3BvcnRPcHRpb25zKG9wdGlvbnM/OiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMpOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMge1xuICBpZiAob3B0aW9ucz8udHlwZSA9PT0gJ29ic2lkaWFuLWFuZHJvaWQtYXBwaXVtJykge1xuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGlzT2JzaWRpYW5BcHBWaXNpYmxlOiBvcHRpb25zPy5pc09ic2lkaWFuQXBwVmlzaWJsZSA/PyBmYWxzZSxcbiAgICB0eXBlOiAnb2JzaWRpYW4tY2RwJ1xuICB9O1xufVxuXG4vKipcbiAqIEF1Z21lbnRzIHRyYW5zcG9ydCBvcHRpb25zIHdpdGggcmV1c2UgaW5mbyBzbyB0ZXN0IHdvcmtlcnMgY2FuIHJlYXR0YWNoIHRvIHRoZVxuICogaW5zdGFuY2UgdGhlIGdsb2JhbCBzZXR1cCBhbHJlYWR5IGxhdW5jaGVkIGluc3RlYWQgb2YgY3JlYXRpbmcgdGhlaXIgb3duOlxuICpcbiAqIC0gKipBcHBpdW0qKiBcdTIwMTQgaW5qZWN0cyB0aGUgZXN0YWJsaXNoZWQgYHNlc3Npb25JZGAvYGRldmljZUlkYC5cbiAqIC0gKipPd25lZCBkZXNrdG9wIENEUCoqIFx1MjAxNCBpbmplY3RzIHRoZSBvd25lZCBpbnN0YW5jZSdzIGBob3N0YC9gcG9ydGAgKGNob3NlblxuICogICBhdCBsYXVuY2gpIHBsdXMgdGhlIGludGVybmFsIGBpc0hhcm5lc3NPd25lZEluc3RhbmNlYCBmbGFnLCBzbyBlYWNoIHdvcmtlclxuICogICAqKmF0dGFjaGVzKiogdG8gdGhhdCBpbnN0YW5jZSBvdmVyIENEUCByYXRoZXIgdGhhbiBsYXVuY2hpbmcgKGFuZCBuZXZlclxuICogICByZWdpc3RlcmluZykgaXRzIG93biBcdTIwMTQgdGhlIGJ1ZyB0aGF0IG90aGVyd2lzZSBsZWF2ZXMgYSB3b3JrZXIncyB0cmFuc3BvcnRcbiAqICAgd2l0aCBubyBDRFAgZW5kcG9pbnQuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgb3JpZ2luYWwgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcGFyYW0gdHJhbnNwb3J0IC0gVGhlIHRyYW5zcG9ydCBpbnN0YW5jZSBjcmVhdGVkIGR1cmluZyBzZXR1cC5cbiAqIEByZXR1cm5zIFRoZSBhdWdtZW50ZWQgb3B0aW9ucywgb3IgdGhlIG9yaWdpbmFsIG9wdGlvbnMgaWYgbm90IGFwcGxpY2FibGUuXG4gKi9cbmZ1bmN0aW9uIGF1Z21lbnRUcmFuc3BvcnRPcHRpb25zKFxuICBvcHRpb25zOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQsXG4gIHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnRcbik6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIGlmIChvcHRpb25zPy50eXBlID09PSAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nICYmIHRyYW5zcG9ydCBpbnN0YW5jZW9mIEFwcGl1bVRyYW5zcG9ydCkge1xuICAgIGNvbnN0IHNlc3Npb25JbmZvID0gdHJhbnNwb3J0LmdldFNlc3Npb25JbmZvKCk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtvcHRpb25zLnR5cGV9XSBTZXNzaW9uIHJldXNlIGluZm86IHNlc3Npb25JZD0ke3Nlc3Npb25JbmZvLnNlc3Npb25JZH0sIGRldmljZUlkPSR7c2Vzc2lvbkluZm8uZGV2aWNlSWR9YCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBkZXZpY2VJZDogc2Vzc2lvbkluZm8uZGV2aWNlSWQsXG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JbmZvLnNlc3Npb25JZFxuICAgIH07XG4gIH1cblxuICBpZiAoKG9wdGlvbnMgPT09IHVuZGVmaW5lZCB8fCBvcHRpb25zLnR5cGUgPT09ICdvYnNpZGlhbi1jZHAnKSAmJiB0cmFuc3BvcnQgaW5zdGFuY2VvZiBEZXNrdG9wQ2RwVHJhbnNwb3J0KSB7XG4gICAgY29uc3QgZW5kcG9pbnQgPSB0cmFuc3BvcnQuZ2V0T3duZWRJbnN0YW5jZUVuZHBvaW50KCk7XG4gICAgaWYgKGVuZHBvaW50KSB7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke0RFRkFVTFRfVFJBTlNQT1JUX1RZUEV9XSBPd25lZCBpbnN0YW5jZSByZXVzZSBpbmZvOiBob3N0PSR7ZW5kcG9pbnQuaG9zdH0sIHBvcnQ9JHtTdHJpbmcoZW5kcG9pbnQucG9ydCl9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICBob3N0OiBlbmRwb2ludC5ob3N0LFxuICAgICAgICBpc0hhcm5lc3NPd25lZEluc3RhbmNlOiB0cnVlLFxuICAgICAgICBwb3J0OiBlbmRwb2ludC5wb3J0LFxuICAgICAgICB0eXBlOiAnb2JzaWRpYW4tY2RwJ1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuLyoqXG4gKiBDb3BpZXMgdGhlIGJ1aWx0IHBsdWdpbiBpbnRvIHRoZSB0ZW1wIHZhdWx0IGFuZCBtYXJrcyBpdCBhcyBhIGNvbW11bml0eSBwbHVnaW4uXG4gKlxuICogUmVhZHMgYG1hbmlmZXN0Lmpzb25gIGZyb20gdGhlIG5ld2VyIG9mIGBkaXN0L2RldmAvYGRpc3QvYnVpbGRgLCByZWplY3RzIGFcbiAqIGRlc2t0b3Atb25seSBwbHVnaW4gb24gYSBtb2JpbGUgdHJhbnNwb3J0LCBjb3BpZXMgdGhlIGJ1aWxkIGludG9cbiAqIGAub2JzaWRpYW4vcGx1Z2lucy88aWQ+YCwgYW5kIHdyaXRlcyBgLm9ic2lkaWFuL2NvbW11bml0eS1wbHVnaW5zLmpzb25gLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgY29weSBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgVGhlIHBsdWdpbiBpZCByZWFkIGZyb20gdGhlIG1hbmlmZXN0LlxuICovXG5hc3luYyBmdW5jdGlvbiBjb3B5UGx1Z2luSW50b1ZhdWx0KHBhcmFtczogQ29weVBsdWdpbkludG9WYXVsdFBhcmFtcyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHsgbGFiZWwsIHByb2plY3RSb290LCB0ZW1wVmF1bHQsIHRyYW5zcG9ydCB9ID0gcGFyYW1zO1xuICBjb25zdCBkaXN0UGF0aCA9IGF3YWl0IHJlc29sdmVEaXN0UGF0aChwcm9qZWN0Um9vdCk7XG4gIGNvbnN0IG1hbmlmZXN0SnNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUoam9pbihkaXN0UGF0aCwgJ21hbmlmZXN0Lmpzb24nKSwgJ3V0Zi04JykpIGFzIFBsdWdpbk1hbmlmZXN0O1xuICBjb25zdCBwbHVnaW5JZCA9IG1hbmlmZXN0SnNvbi5pZDtcblxuICBpZiAodHJhbnNwb3J0LmlzTW9iaWxlICYmIG1hbmlmZXN0SnNvbi5pc0Rlc2t0b3BPbmx5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFBsdWdpbiBcIiR7cGx1Z2luSWR9XCIgaGFzIGlzRGVza3RvcE9ubHk6IHRydWUgaW4gbWFuaWZlc3QuanNvbi4gTW9iaWxlIGludGVncmF0aW9uIHRlc3RzIGNhbm5vdCBydW4gZm9yIGRlc2t0b3Atb25seSBwbHVnaW5zLmBcbiAgICApO1xuICB9XG5cbiAgY29uc3QgbWFpbkpzID0gam9pbihkaXN0UGF0aCwgTUFJTl9KUyk7XG4gIGNvbnN0IGJ1aWxkU3RhdCA9IGF3YWl0IHN0YXQobWFpbkpzKTtcbiAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFVzaW5nICR7ZGlzdFBhdGh9ICgke2J1aWxkU3RhdC5tdGltZS50b0lTT1N0cmluZygpfSkuIElmIG91dGRhdGVkLCByZWJ1aWxkLmApO1xuXG4gIGNvbnN0IHBsdWdpbkRpciA9IGpvaW4odGVtcFZhdWx0LnBhdGgsIE9CU0lESUFOX0NPTkZJR19ESVIsIFBMVUdJTlNfRElSLCBwbHVnaW5JZCk7XG4gIGF3YWl0IG1rZGlyKHBsdWdpbkRpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGF3YWl0IGNwKGRpc3RQYXRoLCBwbHVnaW5EaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICBhd2FpdCB3cml0ZUZpbGUoam9pbih0ZW1wVmF1bHQucGF0aCwgT0JTSURJQU5fQ09ORklHX0RJUiwgQ09NTVVOSVRZX1BMVUdJTlNfSlNPTiksIEpTT04uc3RyaW5naWZ5KFtwbHVnaW5JZF0pKTtcblxuICByZXR1cm4gcGx1Z2luSWQ7XG59XG5cbi8qKlxuICogRW5hYmxlcyBleHRyYSBjb21tdW5pdHkgcGx1Z2lucyAoYmV5b25kIHRoZSBwbHVnaW4tdW5kZXItdGVzdCkgaW4gdGhlIHJlZ2lzdGVyZWQgdmF1bHQsIGVhY2ggdGhyb3VnaCB0aGVcbiAqIHNhbWUge0BsaW5rIGVuYWJsZVBsdWdpbkluVmF1bHR9IHBhdGguIEVhY2ggcGx1Z2luJ3MgYnVpbHQgZmlsZXMgbXVzdCBhbHJlYWR5IGJlIHByZXNlbnQgaW4gdGhlIHZhdWx0IChzZWVkXG4gKiB0aGVtIHZpYSB7QGxpbmsgQ29yZVNldHVwUGFyYW1zLnBvcHVsYXRlfSkuIEEgbm8tb3Agd2hlbiB0aGUgbGlzdCBpcyBlbXB0eS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGVuYWJsZSBwYXJhbWV0ZXJzLlxuICovXG5hc3luYyBmdW5jdGlvbiBlbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnMocGFyYW1zOiBFbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcGx1Z2luSWRzLCB0ZW1wVmF1bHQsIHRyYW5zcG9ydCwgdHJhbnNwb3J0T3B0aW9ucyB9ID0gcGFyYW1zO1xuICBmb3IgKGNvbnN0IHBsdWdpbklkIG9mIHBsdWdpbklkcykge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBFbmFibGluZyBleHRyYSBjb21tdW5pdHkgcGx1Z2luIFwiJHtwbHVnaW5JZH1cIi4uLmApO1xuICAgIGF3YWl0IGVuYWJsZVBsdWdpbkluVmF1bHQoeyBsYWJlbCwgcGx1Z2luSWQsIHRlbXBWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRPcHRpb25zIH0pO1xuICB9XG59XG5cbi8qKlxuICogRW5hYmxlcyB0aGUgcGx1Z2luIGluIHRoZSByZWdpc3RlcmVkIHZhdWx0IGFuZCB2ZXJpZmllcyBpdCBsb2FkZWQuXG4gKlxuICogT2JzaWRpYW4ncyBgZW5hYmxlUGx1Z2luKClgIHdyYXBzIGBsb2FkUGx1Z2luKClgIGluIGEgdHJ5LWNhdGNoIHRoYXQgc3dhbGxvd3NcbiAqIGVycm9ycyBhbmQgcmV0dXJucyBmYWxzZSwgc28ge0BsaW5rIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmV9IG1vbmtleS1wYXRjaGVzXG4gKiBgbG9hZFBsdWdpbigpYCB0byBjYXB0dXJlIHRoZSBlcnJvciBiZWZvcmUgaXQncyBzd2FsbG93ZWQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBlbmFibGUgcGFyYW1ldGVycy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZW5hYmxlUGx1Z2luSW5WYXVsdChwYXJhbXM6IEVuYWJsZVBsdWdpbkluVmF1bHRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcGx1Z2luSWQsIHRlbXBWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRPcHRpb25zIH0gPSBwYXJhbXM7XG4gIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBFbmFibGluZyBwbHVnaW4gXCIke3BsdWdpbklkfVwiLi4uYCk7XG5cbiAgLypcbiAgICogT3BlbiBhIG5hdGl2ZSBjb25zb2xlLWNhcHR1cmUgd2luZG93IChMYXllciAyLCBBbmRyb2lkIG9ubHkpIGFyb3VuZCB0aGVcbiAgICogZW5hYmxlIHNvIHRoYXQgaWYgT2JzaWRpYW4gc3dhbGxvd3MgdGhlIGxvYWQgZXJyb3IgYmVmb3JlIHRoZSBtb25rZXktcGF0Y2hcbiAgICogYW5kIHRoZSByZW5kZXJlciBjb25zb2xlIChMYXllciAxKSBjYW1lIHVwIGVtcHR5LCB3ZSBjYW4gc3RpbGwgcmVjb3ZlciB0aGVcbiAgICogcmVhbCBjYXVzZSBmcm9tIGBhZGIgbG9nY2F0YC4gTm8tb3AgKHVuZGVmaW5lZCkgb24gdHJhbnNwb3J0cyB0aGF0IGRvbid0XG4gICAqIGltcGxlbWVudCBpdCAoZS5nLiBkZXNrdG9wKS5cbiAgICovXG4gIGNvbnN0IGNhcHR1cmVIYW5kbGUgPSBhd2FpdCB0cmFuc3BvcnQuYmVnaW5Db25zb2xlQ2FwdHVyZT8uKCk7XG5cbiAgLypcbiAgICogT24gYSBmcmVzaGx5IGNvbGQtYm9vdGVkIGVtdWxhdG9yIHRoZSBwbHVnaW4gc3Vic3lzdGVtIGNhbiBzdGlsbCBiZSBzZXR0bGluZ1xuICAgKiB3aGVuIHdlIGVuYWJsZSB0aGUgcGx1Z2luLCBzbyBhIHNpbmdsZS1zaG90IGVuYWJsZSByYWNlcyB0aGUgbG9hZCBhbmQgbG9zZXNcbiAgICogKHRoZSBwbHVnaW4gbGFuZHMgaW4gdGhlIGVuYWJsZWQgc2V0IGJ1dCBuZXZlciBsb2FkcykuIFJldHJ5IHRoZSBlbmFibGUgK1xuICAgKiBsb2FkLXZlcmlmaWNhdGlvbiBhIGZldyB0aW1lcyB3aXRoIGV4cG9uZW50aWFsIGJhY2tvZmYsIHdoaWNoIHJlY292ZXJzIHRoZVxuICAgKiB0cmFuc2llbnQgcmFjZS4gQSBjYXB0dXJlZCBsb2FkIGVycm9yIChgcmVhbEVycm9yYCkgaXMgYSBkZXRlcm1pbmlzdGljIGJ1ZyBcdTIwMTRcbiAgICogcmV0cnlpbmcgY2Fubm90IGZpeCBpdCwgc28gd2UgZmFpbCBmYXN0LiBOb24tQW5kcm9pZCB0cmFuc3BvcnRzIHJlc29sdmUgdG9cbiAgICogdGhlIHNhbWUgZGVmYXVsdHMgYnV0IG5ldmVyIGVudGVyIHRoZSByZXRyeSBwYXRoOiB0aGVpciBsb2FkIGVpdGhlciBzdWNjZWVkc1xuICAgKiBvbiB0aGUgZmlyc3QgYXR0ZW1wdCBvciB0aHJvd3MgYSBjYXB0dXJlZCBlcnJvci5cbiAgICovXG4gIGNvbnN0IG1heEF0dGVtcHRzID0gMSArIHJlc29sdmVQbHVnaW5FbmFibGVSZXRyeUNvdW50KHRyYW5zcG9ydE9wdGlvbnMpO1xuICBjb25zdCBiYXNlRGVsYXlJbk1pbGxpc2Vjb25kcyA9IHJlc29sdmVQbHVnaW5FbmFibGVSZXRyeURlbGF5SW5NaWxsaXNlY29uZHModHJhbnNwb3J0T3B0aW9ucyk7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gbWF4QXR0ZW1wdHM7IGF0dGVtcHQrKykge1xuICAgIGxldCByZXN1bHQ6IEVuYWJsZVBsdWdpblJlc3VsdDtcbiAgICB0cnkge1xuICAgICAgcmVzdWx0ID0gYXdhaXQgZXZhbEluT2JzaWRpYW4oe1xuICAgICAgICBhcmdzOiB7IHBsdWdpbklkIH0sXG4gICAgICAgIGZuOiBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlLFxuICAgICAgICBzaG91bGRTa2lwUHJlZmxpZ2h0Q2hlY2tzOiB0cnVlLFxuICAgICAgICB0cmFuc3BvcnQsXG4gICAgICAgIHZhdWx0UGF0aDogdGVtcFZhdWx0LnBhdGhcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvKlxuICAgICAgICogVGhlIGV2YWwgaXRzZWxmIHRocmV3IChlLmcuIHRoZSBXZWJWaWV3IGNvbnRleHQgd2FzIGxvc3QgbWlkLWV4ZWN1dGlvbiBvblxuICAgICAgICogYSBjaHVybmluZyBndWVzdCkgXHUyMDE0IGEgdHJhbnNwb3J0LWxldmVsIHRyYW5zaWVudC4gUmV0cnkgaWYgYXR0ZW1wdHMgcmVtYWluLlxuICAgICAgICovXG4gICAgICBpZiAoYXR0ZW1wdCA8IG1heEF0dGVtcHRzKSB7XG4gICAgICAgIGNvbnN0IGRlbGF5SW5NaWxsaXNlY29uZHMgPSBjb21wdXRlQmFja29mZkRlbGF5SW5NaWxsaXNlY29uZHMoYmFzZURlbGF5SW5NaWxsaXNlY29uZHMsIGF0dGVtcHQgLSAxKTtcbiAgICAgICAgbG9nKFxuICAgICAgICAgIGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEVuYWJsZSBhdHRlbXB0ICR7U3RyaW5nKGF0dGVtcHQpfS8ke1N0cmluZyhtYXhBdHRlbXB0cyl9IHRocmV3IGBcbiAgICAgICAgICAgICsgYCgke2Vycm9yVG9TdHJpbmcoZXJyb3IpfSk7IHJldHJ5aW5nIGluICR7U3RyaW5nKGRlbGF5SW5NaWxsaXNlY29uZHMpfW1zLi4uYFxuICAgICAgICApO1xuICAgICAgICBhd2FpdCBzbGVlcChkZWxheUluTWlsbGlzZWNvbmRzKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIGBlcnJvck1lc3NhZ2VgIGlzIHRoZSByZWFsIHRocm93IHNlZW4gYnkgdGhlIG1vbmtleS1wYXRjaDtcbiAgICAgKiBgcmVuZGVyZXJDb25zb2xlRXJyb3JzYCAoTGF5ZXIgMSkgaXMgdGhlIHJlYWwgY2F1c2UgY29uc29sZS1sb2dnZWQgaW4gdGhlIHJlbmRlcmVyLlxuICAgICAqL1xuICAgIGNvbnN0IHJlYWxFcnJvciA9IHJlc3VsdC5lcnJvck1lc3NhZ2UgPz8gcmVzdWx0LnJlbmRlcmVyQ29uc29sZUVycm9ycztcblxuICAgIGlmIChyZXN1bHQuaXNMb2FkZWQgJiYgIXJlYWxFcnJvcikge1xuICAgICAgY29uc3QgYXR0ZW1wdFN1ZmZpeCA9IGF0dGVtcHQgPiAxID8gYCAoYXR0ZW1wdCAke1N0cmluZyhhdHRlbXB0KX0vJHtTdHJpbmcobWF4QXR0ZW1wdHMpfSlgIDogJyc7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBlbmFibGVkIHN1Y2Nlc3NmdWxseSR7YXR0ZW1wdFN1ZmZpeH0uYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQSBjYXB0dXJlZCBsb2FkIGVycm9yIGlzIGRldGVybWluaXN0aWMgXHUyMDE0IGZhaWwgZmFzdCByYXRoZXIgdGhhbiByZXRyeS5cbiAgICBpZiAoIXNob3VsZFJldHJ5UGx1Z2luRW5hYmxlKHJlc3VsdCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBmYWlsZWQgdG8gbG9hZDogJHtyZWFsRXJyb3IgPz8gZ2V0R2VuZXJpY1BsdWdpbkxvYWRGYWlsdXJlTWVzc2FnZShwbHVnaW5JZCl9YCk7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNpZW50IGNvbGQtYm9vdCByYWNlIChlbmFibGVkIGJ1dCBub3QgbG9hZGVkLCBubyBjYXVzZSBjYXB0dXJlZCk6IHJldHJ5LlxuICAgIGlmIChhdHRlbXB0IDwgbWF4QXR0ZW1wdHMpIHtcbiAgICAgIGNvbnN0IGRlbGF5SW5NaWxsaXNlY29uZHMgPSBjb21wdXRlQmFja29mZkRlbGF5SW5NaWxsaXNlY29uZHMoYmFzZURlbGF5SW5NaWxsaXNlY29uZHMsIGF0dGVtcHQgLSAxKTtcbiAgICAgIGxvZyhcbiAgICAgICAgYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBlbmFibGVkIGJ1dCBub3QgbG9hZGVkIGBcbiAgICAgICAgICArIGAoYXR0ZW1wdCAke1N0cmluZyhhdHRlbXB0KX0vJHtTdHJpbmcobWF4QXR0ZW1wdHMpfSk7IHJldHJ5aW5nIGluICR7U3RyaW5nKGRlbGF5SW5NaWxsaXNlY29uZHMpfW1zLi4uYFxuICAgICAgKTtcbiAgICAgIGF3YWl0IHNsZWVwKGRlbGF5SW5NaWxsaXNlY29uZHMpO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICAqIEV4aGF1c3RlZCBldmVyeSBhdHRlbXB0IG9uIHRoZSB0cmFuc2llbnQgc2lnbmF0dXJlOiBjb21wb3NlIHRoZSBtb3N0XG4gICAqIHNwZWNpZmljIGRldGFpbCBhdmFpbGFibGUgKGBhZGIgbG9nY2F0YCB0YWlsIG9uIEFuZHJvaWQsIGVsc2UgdGhlIGdlbmVyaWNcbiAgICogbWVzc2FnZSkgXHUyMDE0IHVuY2hhbmdlZCBmcm9tIHRoZSBwcmUtcmV0cnkgc2luZ2xlLXNob3QgZmFpbHVyZS5cbiAgICovXG4gIGNvbnN0IGxvZ2NhdFRhaWwgPSBhd2FpdCB0cmFuc3BvcnQucmVhZENvbnNvbGVDYXB0dXJlU2luY2U/LihjYXB0dXJlSGFuZGxlKTtcbiAgY29uc3QgZGV0YWlsID0gbG9nY2F0VGFpbCA/PyBnZXRHZW5lcmljUGx1Z2luTG9hZEZhaWx1cmVNZXNzYWdlKHBsdWdpbklkKTtcbiAgdGhyb3cgbmV3IEVycm9yKGBQbHVnaW4gXCIke3BsdWdpbklkfVwiIGZhaWxlZCB0byBsb2FkOiAke2RldGFpbH1gKTtcbn1cblxuLyoqXG4gKiBFbmFibGVzIGBhbHdheXNVcGRhdGVMaW5rc2AgaW4gdGhlIG93bmVkIHZhdWx0J3MgYC5vYnNpZGlhbi9hcHAuanNvbmAuXG4gKlxuICogV2l0aG91dCBpdCwgYW55IHJlbmFtZSBvciBtb3ZlIHRoYXQgYWZmZWN0cyBsaW5rcyBtYWtlcyBPYnNpZGlhbidzXG4gKiBgRmlsZU1hbmFnZXIudXBkYXRlQWxsTGlua3NgIHBvcCBhbiBpbnRlcmFjdGl2ZSBcIlVwZGF0ZSBsaW5rcz9cIiBjb25maXJtYXRpb24gbW9kYWxcbiAqIChpdCBvbmx5IHNraXBzIHRoZSBtb2RhbCB3aGVuIGBhbHdheXNVcGRhdGVMaW5rc2AgaXMgb24pLiBIZWFkbGVzcyB0aGVyZSBpcyBubyB1c2VyXG4gKiB0byBhbnN3ZXIgaXQsIHNvIHRoZSBQcm9taXNlIG5ldmVyIHJlc29sdmVzIFx1MjAxNCB0aGUgcmVuYW1lJ3MgaW50ZXJuYWxcbiAqIGBGaWxlTWFuYWdlci51cGRhdGVRdWV1ZWAgdGFzayBoYW5ncyBmb3JldmVyLCBhbmQgYmVjYXVzZSB0aGF0IHF1ZXVlIGlzIGEgc2luZ2xldG9uXG4gKiBldmVyeSBzdWJzZXF1ZW50IGByZW5hbWVGaWxlYCBpbiB0aGUgc2hhcmVkIGluc3RhbmNlIGhhbmdzIHRvbyAodGhlIGxvbmctb2JzZXJ2ZWRcbiAqIFwicmVuYW1lIHdhbGxcIikuIEVuYWJsaW5nIHRoZSBzZXR0aW5nIG1ha2VzIHJlbmFtZXMgdXBkYXRlIGxpbmtzIG5vbi1pbnRlcmFjdGl2ZWx5LFxuICogc28gcmVuYW1lLWRyaXZlbiBpbnRlZ3JhdGlvbiB0ZXN0cyBydW4gaW4gaGVhZGxlc3MgbW9kZS5cbiAqXG4gKiBNZXJnZXMgaW50byBhbnkgZXhpc3RpbmcgYGFwcC5qc29uYCAoZS5nLiBvbmUgY2FycmllZCBpbiB2aWEgYHBvcHVsYXRlYCkgc28gb3RoZXJcbiAqIGNvbmZpZyBrZXlzIGFyZSBwcmVzZXJ2ZWQsIGFuZCBydW5zIGJlZm9yZSBgc3luY1RvRGV2aWNlYCBzbyB0aGUgdmFsdWUgcmVhY2hlc1xuICogbW9iaWxlIGRldmljZXMgdG9vLlxuICpcbiAqIEBwYXJhbSB0ZW1wVmF1bHQgLSBUaGUgb3duZWQgdGVtcCB2YXVsdCB0byBjb25maWd1cmUuXG4gKiBAcGFyYW0gbGFiZWwgLSBUaGUgdHJhbnNwb3J0IGxhYmVsLCBmb3IgbG9nZ2luZy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZW5zdXJlQWx3YXlzVXBkYXRlTGlua3ModGVtcFZhdWx0OiBUZW1wVmF1bHQsIGxhYmVsOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgY29uZmlnRGlyID0gam9pbih0ZW1wVmF1bHQucGF0aCwgT0JTSURJQU5fQ09ORklHX0RJUik7XG4gIGNvbnN0IGFwcEpzb25QYXRoID0gam9pbihjb25maWdEaXIsIEFQUF9KU09OKTtcbiAgbGV0IGFwcENvbmZpZzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgdHJ5IHtcbiAgICBhcHBDb25maWcgPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRGaWxlKGFwcEpzb25QYXRoLCAndXRmLTgnKSkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIH0gY2F0Y2gge1xuICAgIC8vIE5vIGV4aXN0aW5nIGFwcC5qc29uIChvciB1bnJlYWRhYmxlKSBcdTIwMTQgc3RhcnQgZnJvbSBhbiBlbXB0eSBjb25maWcuXG4gIH1cbiAgYXBwQ29uZmlnWydhbHdheXNVcGRhdGVMaW5rcyddID0gdHJ1ZTtcbiAgYXdhaXQgbWtkaXIoY29uZmlnRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgYXdhaXQgd3JpdGVGaWxlKGFwcEpzb25QYXRoLCBKU09OLnN0cmluZ2lmeShhcHBDb25maWcsIG51bGwsIEFQUF9KU09OX0lOREVOVCkpO1xuICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gRW5hYmxlZCBhbHdheXNVcGRhdGVMaW5rcyBpbiAke0FQUF9KU09OfSAoaGVhZGxlc3MgcmVuYW1lIHN1cHBvcnQpLmApO1xufVxuXG4vKipcbiAqIEZpbmRzIHRoZSBwcm9qZWN0IHJvb3QgYnkgd2Fsa2luZyB1cCBmcm9tIGBwcm9jZXNzLmN3ZCgpYCBsb29raW5nIGZvciBgcGFja2FnZS5qc29uYC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgcHJvamVjdCByb290LlxuICovXG5mdW5jdGlvbiBmaW5kUHJvamVjdFJvb3QoKTogc3RyaW5nIHtcbiAgbGV0IGRpciA9IHByb2Nlc3MuY3dkKCk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb24gLS0gTG9vcCB0ZXJtaW5hdGVzIGF0IGZpbGVzeXN0ZW0gcm9vdC5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoZXhpc3RzU3luYyhqb2luKGRpciwgJ3BhY2thZ2UuanNvbicpKSkge1xuICAgICAgcmV0dXJuIGRpcjtcbiAgICB9XG4gICAgY29uc3QgcGFyZW50ID0gam9pbihkaXIsICcuLicpO1xuICAgIGlmIChwYXJlbnQgPT09IGRpcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZmluZCBwcm9qZWN0IHJvb3QgKG5vIHBhY2thZ2UuanNvbiBmb3VuZCkuJyk7XG4gICAgfVxuICAgIGRpciA9IHBhcmVudDtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBjcm9zcy1wcm9jZXNzIGxvY2sgc2NvcGUgZm9yIGEgdHJhbnNwb3J0LCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vXG4gKiBsb2NrIGlzIG5lZWRlZC5cbiAqXG4gKiBEZXNrdG9wIHJ1bnMgdXNlIGhhcm5lc3Mtb3duZWQsIGlzb2xhdGVkIGluc3RhbmNlcyAodGhlaXIgb3duIHVzZXItZGF0YSBkaXJcbiAqIGFuZCBDRFAgcG9ydCksIHNvIHRoZXkgbm8gbG9uZ2VyIGNvbnRlbmQgYW5kIG5lZWQgbm8gbG9jay4gT25seSB0aGUgQW5kcm9pZFxuICogdHJhbnNwb3J0LCB3aGljaCBzaGFyZXMgdGhlIHNpbmdsZSBlbXVsYXRvciBhbmQgQXBwaXVtIHNlcnZlciwgbXVzdCBzZXJpYWxpemUuXG4gKlxuICogQHBhcmFtIHRyYW5zcG9ydE9wdGlvbnMgLSBUaGUgcmVzb2x2ZWQgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcmV0dXJucyBUaGUgbG9jayBzY29wZSBzdHJpbmcsIG9yIGB1bmRlZmluZWRgIGlmIG5vIGxvY2sgaXMgbmVlZGVkLlxuICovXG5mdW5jdGlvbiBnZXRMb2NrU2NvcGUodHJhbnNwb3J0T3B0aW9uczogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHRyYW5zcG9ydE9wdGlvbnM/LnR5cGUgPT09ICdvYnNpZGlhbi1hbmRyb2lkLWFwcGl1bScgPyBBTkRST0lEX0xPQ0tfU0NPUEUgOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIGNsZWFudXAgaGFuZGxlcnMgZm9yIG9ycGhhbmVkIHNldHVwcyB0aGF0IHdlcmUgbmV2ZXIgZXhwbGljaXRseVxuICogdG9ybiBkb3duLlxuICpcbiAqIFR3byBoYW5kbGVycyBjb3ZlciBkaWZmZXJlbnQgZXhpdCBzY2VuYXJpb3M6XG4gKlxuICogLSBgYmVmb3JlRXhpdGAgXHUyMDE0IGZpcmVzIHdoZW4gdGhlIGV2ZW50IGxvb3AgZHJhaW5zIG5hdHVyYWxseS4gQWxsb3dzIGZ1bGxcbiAqICAgYXN5bmMgdGVhcmRvd24gKHVucmVnaXN0ZXIgdmF1bHRzLCBkaXNwb3NlIHRyYW5zcG9ydHMpLiBEb2VzIE5PVCBmaXJlXG4gKiAgIHdoZW4gYHByb2Nlc3MuZXhpdCgpYCBpcyBjYWxsZWQgZGlyZWN0bHkuXG4gKlxuICogLSBgdW5oYW5kbGVkUmVqZWN0aW9uYCBcdTIwMTQgY2F0Y2hlcyBhc3luYyBlcnJvcnMgdGhhdCBieXBhc3MgYGNvcmVTZXR1cGAnc1xuICogICBjYXRjaCBibG9jay4gUGVyZm9ybXMgZnVsbCBhc3luYyB0ZWFyZG93biB3aGlsZSB3ZSBzdGlsbCBjYW4uXG4gKlxuICogLSBgZXhpdGAgXHUyMDE0IGZpcmVzIG9uIGV2ZXJ5IGV4aXQsIGluY2x1ZGluZyBgcHJvY2Vzcy5leGl0KClgLiBPbmx5IHN5bmNocm9ub3VzXG4gKiAgIHdvcmsgaXMgcG9zc2libGUsIHNvIHRoaXMgaGFuZGxlciBkb2VzIGJlc3QtZWZmb3J0IGNsZWFudXA6IGtpbGxzIGNoaWxkXG4gKiAgIHByb2Nlc3NlcyB2aWEgYGRpc3Bvc2VTeW5jKClgIGFuZCByZW1vdmVzIHRlbXAgdmF1bHQgZGlyZWN0b3JpZXMgd2l0aFxuICogICBgcm1TeW5jYC4gVW5yZWdpc3RlcmluZyB2YXVsdHMgKHdoaWNoIHJlcXVpcmVzIElQQyB3aXRoIE9ic2lkaWFuKSBpc1xuICogICBza2lwcGVkIFx1MjAxNCBhIHN0YWxlIHZhdWx0IGVudHJ5IGlzIGFuIGFjY2VwdGFibGUgdHJhZGUtb2ZmIHZzLiBsZWFrZWRcbiAqICAgcHJvY2Vzc2VzIGFuZCB0ZW1wIGRpcmVjdG9yaWVzLlxuICovXG5mdW5jdGlvbiByZWdpc3RlclByb2Nlc3NDbGVhbnVwSGFuZGxlcigpOiB2b2lkIHtcbiAgaWYgKGlzQ2xlYW51cEhhbmRsZXJSZWdpc3RlcmVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlzQ2xlYW51cEhhbmRsZXJSZWdpc3RlcmVkID0gdHJ1ZTtcblxuICBwcm9jZXNzLm9uKCdiZWZvcmVFeGl0JywgKCkgPT4ge1xuICAgIGlmIChhY3RpdmVTZXR1cHMuc2l6ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duXSBQcm9jZXNzIGV4aXRpbmcgd2l0aCAke1N0cmluZyhhY3RpdmVTZXR1cHMuc2l6ZSl9IHNldHVwKHMpIG5vdCB0b3JuIGRvd24uIENsZWFuaW5nIHVwLi4uYCk7XG5cbiAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiBbLi4uYWN0aXZlU2V0dXBzXSkge1xuICAgICAgY29yZVRlYXJkb3duKHJlc3VsdCkuY2F0Y2goKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gUHJvY2VzcyBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICBwcm9jZXNzLm9uKCd1bmhhbmRsZWRSZWplY3Rpb24nLCAoKSA9PiB7XG4gICAgaWYgKGFjdGl2ZVNldHVwcy5zaXplID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd25dIFVuaGFuZGxlZCByZWplY3Rpb24gZGV0ZWN0ZWQuIFRlYXJpbmcgZG93biAke1N0cmluZyhhY3RpdmVTZXR1cHMuc2l6ZSl9IGFjdGl2ZSBzZXR1cChzKS4uLmApO1xuICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIFsuLi5hY3RpdmVTZXR1cHNdKSB7XG4gICAgICBjb3JlVGVhcmRvd24ocmVzdWx0KS5jYXRjaCgoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBSZWplY3Rpb24gY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJvY2Vzcy5vbignZXhpdCcsICgpID0+IHtcbiAgICBpZiAoYWN0aXZlU2V0dXBzLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bl0gU3luYyBjbGVhbnVwOiAke1N0cmluZyhhY3RpdmVTZXR1cHMuc2l6ZSl9IG9ycGhhbmVkIHNldHVwKHMpLmApO1xuICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIFsuLi5hY3RpdmVTZXR1cHNdKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXN1bHQudHJhbnNwb3J0LmRpc3Bvc2VTeW5jPy4oKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gU3luYyB0cmFuc3BvcnQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIHJtU3luYyhyZXN1bHQudGVtcFZhdWx0LnBhdGgsIHsgZm9yY2U6IHRydWUsIHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gU3luYyB2YXVsdCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICAgcmVsZWFzZVNldHVwTG9jayhyZXN1bHQpO1xuICAgIH1cbiAgICBhY3RpdmVTZXR1cHMuY2xlYXIoKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmVsZWFzZXMgYW5kIGZvcmdldHMgdGhlIHNldHVwIGxvY2sgYXNzb2NpYXRlZCB3aXRoIGEgcmVzdWx0LCBpZiBhbnkuXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIFRoZSBzZXR1cCByZXN1bHQgd2hvc2UgbG9jayBzaG91bGQgYmUgcmVsZWFzZWQuXG4gKi9cbmZ1bmN0aW9uIHJlbGVhc2VTZXR1cExvY2socmVzdWx0OiBDb3JlU2V0dXBSZXN1bHQpOiB2b2lkIHtcbiAgY29uc3QgbG9jayA9IHNldHVwTG9ja3MuZ2V0KHJlc3VsdCk7XG4gIGlmIChsb2NrKSB7XG4gICAgbG9jay5yZWxlYXNlKCk7XG4gICAgc2V0dXBMb2Nrcy5kZWxldGUocmVzdWx0KTtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBkaXN0IHBhdGggdG8gdXNlIGZvciBpbnRlZ3JhdGlvbiB0ZXN0cy5cbiAqXG4gKiBQaWNrcyB3aGljaGV2ZXIgb2YgYGRpc3QvZGV2YCBhbmQgYGRpc3QvYnVpbGRgIGhhcyBhIG5ld2VyIGBtYWluLmpzYC5cbiAqIElmIG9ubHkgb25lIGV4aXN0cywgdGhhdCBvbmUgaXMgdXNlZC4gVGhyb3dzIGlmIG5laXRoZXIgZXhpc3RzLlxuICpcbiAqIEBwYXJhbSBwcm9qZWN0Um9vdCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBwcm9qZWN0IHJvb3QuXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgY2hvc2VuIGRpc3QgZm9sZGVyLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlRGlzdFBhdGgocHJvamVjdFJvb3Q6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGRldlBhdGggPSBqb2luKHByb2plY3RSb290LCBESVNUX0RFVik7XG4gIGNvbnN0IGJ1aWxkUGF0aCA9IGpvaW4ocHJvamVjdFJvb3QsIERJU1RfQlVJTEQpO1xuICBjb25zdCBkZXZNYWluSnMgPSBqb2luKGRldlBhdGgsIE1BSU5fSlMpO1xuICBjb25zdCBidWlsZE1haW5KcyA9IGpvaW4oYnVpbGRQYXRoLCBNQUlOX0pTKTtcbiAgY29uc3QgZGV2U3RhdCA9IGV4aXN0c1N5bmMoZGV2TWFpbkpzKSA/IGF3YWl0IHN0YXQoZGV2TWFpbkpzKSA6IG51bGw7XG4gIGNvbnN0IGJ1aWxkU3RhdCA9IGV4aXN0c1N5bmMoYnVpbGRNYWluSnMpID8gYXdhaXQgc3RhdChidWlsZE1haW5KcykgOiBudWxsO1xuXG4gIGlmIChkZXZTdGF0ICYmIGJ1aWxkU3RhdCkge1xuICAgIHJldHVybiBkZXZTdGF0Lm10aW1lID4gYnVpbGRTdGF0Lm10aW1lID8gZGV2UGF0aCA6IGJ1aWxkUGF0aDtcbiAgfVxuXG4gIGlmIChkZXZTdGF0KSB7XG4gICAgcmV0dXJuIGRldlBhdGg7XG4gIH1cblxuICBpZiAoYnVpbGRTdGF0KSB7XG4gICAgcmV0dXJuIGJ1aWxkUGF0aDtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignTm8gYnVpbGQgZm91bmQuIFJ1biBgbnBtIHJ1biBidWlsZGAgb3IgYG5wbSBydW4gZGV2YCBmaXJzdC4nKTtcbn1cblxuLyoqXG4gKiBQZXJmb3JtcyB0aGUgYXN5bmMgdGVhcmRvd24gd29yayAodmF1bHQgZGlzcG9zYWwgKyB0cmFuc3BvcnQgZGlzcG9zYWwpLlxuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBUaGUgc2V0dXAgcmVzdWx0IHRvIHRlYXIgZG93bi5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gdGVhcmRvd25Bc3luYyhyZXN1bHQ6IENvcmVTZXR1cFJlc3VsdCk6IFByb21pc2U8dm9pZD4ge1xuICB0cnkge1xuICAgIGF3YWl0IHJlc3VsdC50ZW1wVmF1bHQuZGlzcG9zZShyZXN1bHQudHJhbnNwb3J0KTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIFZhdWx0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gIH1cblxuICB0cnkge1xuICAgIGF3YWl0IHJlc3VsdC50cmFuc3BvcnQuZGlzcG9zZT8uKCk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBUcmFuc3BvcnQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfVxufVxuIl0sCiAg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QVMsT0FBZ0I7QUFDdkIsNEJBQUkseUJBQXlCLE9BQU8sY0FBYyxtREFBK0Msc0NBQWMsS0FBSyxDQUFDLEVBQUU7QUFBQSxNQUN6SDtBQUNBLFVBQUk7QUFDRixtQ0FBTyxPQUFPLFVBQVUsTUFBTSxFQUFFLE9BQU8sTUFBTSxXQUFXLEtBQUssQ0FBQztBQUFBLE1BQ2hFLFNBQVMsT0FBZ0I7QUFDdkIsNEJBQUkseUJBQXlCLE9BQU8sY0FBYywrQ0FBMkMsc0NBQWMsS0FBSyxDQUFDLEVBQUU7QUFBQSxNQUNySDtBQUNBLHVCQUFpQixNQUFNO0FBQUEsSUFDekI7QUFDQSxpQkFBYSxNQUFNO0FBQUEsRUFDckIsQ0FBQztBQUNIO0FBT0EsU0FBUyxpQkFBaUIsUUFBK0I7QUFDdkQsUUFBTSxPQUFPLFdBQVcsSUFBSSxNQUFNO0FBQ2xDLE1BQUksTUFBTTtBQUNSLFNBQUssUUFBUTtBQUNiLGVBQVcsT0FBTyxNQUFNO0FBQUEsRUFDMUI7QUFDRjtBQVdBLGVBQWUsZ0JBQWdCLGFBQXNDO0FBQ25FLFFBQU0sY0FBVSx1QkFBSyxhQUFhLFFBQVE7QUFDMUMsUUFBTSxnQkFBWSx1QkFBSyxhQUFhLFVBQVU7QUFDOUMsUUFBTSxnQkFBWSx1QkFBSyxTQUFTLE9BQU87QUFDdkMsUUFBTSxrQkFBYyx1QkFBSyxXQUFXLE9BQU87QUFDM0MsUUFBTSxjQUFVLDJCQUFXLFNBQVMsSUFBSSxVQUFNLHNCQUFLLFNBQVMsSUFBSTtBQUNoRSxRQUFNLGdCQUFZLDJCQUFXLFdBQVcsSUFBSSxVQUFNLHNCQUFLLFdBQVcsSUFBSTtBQUV0RSxNQUFJLFdBQVcsV0FBVztBQUN4QixXQUFPLFFBQVEsUUFBUSxVQUFVLFFBQVEsVUFBVTtBQUFBLEVBQ3JEO0FBRUEsTUFBSSxTQUFTO0FBQ1gsV0FBTztBQUFBLEVBQ1Q7QUFFQSxNQUFJLFdBQVc7QUFDYixXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sSUFBSSxNQUFNLDZEQUE2RDtBQUMvRTtBQU9BLGVBQWUsY0FBYyxRQUF3QztBQUNuRSxNQUFJO0FBQ0YsVUFBTSxPQUFPLFVBQVUsUUFBUSxPQUFPLFNBQVM7QUFBQSxFQUNqRCxTQUFTLE9BQWdCO0FBQ3ZCLHdCQUFJLHlCQUF5QixPQUFPLGNBQWMsMENBQXNDLHNDQUFjLEtBQUssQ0FBQyxFQUFFO0FBQUEsRUFDaEg7QUFFQSxNQUFJO0FBQ0YsVUFBTSxPQUFPLFVBQVUsVUFBVTtBQUFBLEVBQ25DLFNBQVMsT0FBZ0I7QUFDdkIsd0JBQUkseUJBQXlCLE9BQU8sY0FBYyw4Q0FBMEMsc0NBQWMsS0FBSyxDQUFDLEVBQUU7QUFBQSxFQUNwSDtBQUNGOyIsCiAgIm5hbWVzIjogWyJpbXBvcnRfcHJvbWlzZXMiLCAic2xlZXAiLCAicHJvY2VzcyJdCn0K
415
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2dsb2JhbC1zZXR1cC1jb3JlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogRnJhbWV3b3JrLWFnbm9zdGljIGNvcmUgbG9naWMgZm9yIGludGVncmF0aW9uIHRlc3QgZ2xvYmFsIHNldHVwIGFuZCB0ZWFyZG93bi5cbiAqXG4gKiBWaXRlc3QgYW5kIEplc3QgYWRhcHRlcnMgZGVsZWdhdGUgdG8gdGhlc2UgZnVuY3Rpb25zLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIHNldHVwIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7IFBsdWdpbk1hbmlmZXN0IH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQge1xuICBleGlzdHNTeW5jLFxuICBybVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBjcCxcbiAgbWtkaXIsXG4gIHJlYWRGaWxlLFxuICBzdGF0LFxuICB3cml0ZUZpbGVcbn0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQge1xuICBiYXNlbmFtZSxcbiAgam9pblxufSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHByb2Nlc3MsIHsgbG9hZEVudkZpbGUgfSBmcm9tICdub2RlOnByb2Nlc3MnO1xuaW1wb3J0IHsgc2V0VGltZW91dCBhcyBzbGVlcCB9IGZyb20gJ25vZGU6dGltZXJzL3Byb21pc2VzJztcblxuaW1wb3J0IHR5cGUgeyBFbmFibGVQbHVnaW5SZXN1bHQgfSBmcm9tICcuL2VuYWJsZS1wbHVnaW4uY2pzJztcbmltcG9ydCB0eXBlIHsgU2V0dXBMb2NrIH0gZnJvbSAnLi9zZXR1cC1sb2NrLmNqcyc7XG5pbXBvcnQgdHlwZSB7IFBvcHVsYXRlRmlsZXNQYXJhbXMgfSBmcm9tICcuL3RlbXAtdmF1bHQuY2pzJztcbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIH0gZnJvbSAnLi90cmFuc3BvcnQtb3B0aW9ucy5janMnO1xuaW1wb3J0IHR5cGUgeyBPYnNpZGlhblRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LmNqcyc7XG5cbmltcG9ydCB7XG4gIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmUsXG4gIGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2Vcbn0gZnJvbSAnLi9lbmFibGUtcGx1Z2luLmNqcyc7XG5pbXBvcnQgeyBlcnJvclRvU3RyaW5nIH0gZnJvbSAnLi9lcnJvci10by1zdHJpbmcuY2pzJztcbmltcG9ydCB7IGV2YWxJbk9ic2lkaWFuIH0gZnJvbSAnLi9ldmFsLWluLW9ic2lkaWFuLmNqcyc7XG5pbXBvcnQge1xuICByZXNvbHZlTGVmdG92ZXJNYXhBZ2VJbk1pbGxpc2Vjb25kcyxcbiAgcmVzb2x2ZVNob3VsZFN3ZWVwTGVmdG92ZXJzLFxuICBzd2VlcEhvc3RMZWZ0b3ZlcnNcbn0gZnJvbSAnLi9sZWZ0b3Zlci1jbGVhbnVwLmNqcyc7XG5pbXBvcnQgeyBsb2cgfSBmcm9tICcuL2xvZy5janMnO1xuaW1wb3J0IHtcbiAgY29tcHV0ZUJhY2tvZmZEZWxheUluTWlsbGlzZWNvbmRzLFxuICByZXNvbHZlUGx1Z2luRW5hYmxlUmV0cnlDb3VudCxcbiAgcmVzb2x2ZVBsdWdpbkVuYWJsZVJldHJ5RGVsYXlJbk1pbGxpc2Vjb25kcyxcbiAgc2hvdWxkUmV0cnlQbHVnaW5FbmFibGVcbn0gZnJvbSAnLi9wbHVnaW4tZW5hYmxlLXJldHJ5LmNqcyc7XG5pbXBvcnQgeyBhY3F1aXJlU2V0dXBMb2NrIH0gZnJvbSAnLi9zZXR1cC1sb2NrLmNqcyc7XG5pbXBvcnQgeyBUZW1wVmF1bHQgfSBmcm9tICcuL3RlbXAtdmF1bHQuY2pzJztcbmltcG9ydCB7IEFwcGl1bVRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWFwcGl1bS5janMnO1xuaW1wb3J0IHsgRGVza3RvcENkcFRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWRlc2t0b3AtY2RwLmNqcyc7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LWZhY3RvcnkuY2pzJztcblxuY29uc3QgREVGQVVMVF9UUkFOU1BPUlRfVFlQRSA9ICdvYnNpZGlhbi1jZHAnO1xuY29uc3QgRElTVF9ERVYgPSAnZGlzdC9kZXYnO1xuY29uc3QgRElTVF9CVUlMRCA9ICdkaXN0L2J1aWxkJztcbmNvbnN0IE1BSU5fSlMgPSAnbWFpbi5qcyc7XG5jb25zdCBPQlNJRElBTl9DT05GSUdfRElSID0gJy5vYnNpZGlhbic7XG5jb25zdCBQTFVHSU5TX0RJUiA9ICdwbHVnaW5zJztcbmNvbnN0IENPTU1VTklUWV9QTFVHSU5TX0pTT04gPSAnY29tbXVuaXR5LXBsdWdpbnMuanNvbic7XG5jb25zdCBBUFBfSlNPTiA9ICdhcHAuanNvbic7XG5jb25zdCBBUFBfSlNPTl9JTkRFTlQgPSAyO1xuXG4vKipcbiAqIFRyYWNrcyBzZXR1cHMgdGhhdCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5IGJ1dCBoYXZlbid0IGJlZW4gdG9ybiBkb3duIHlldC5cbiAqIFVzZWQgYnkgdGhlIGBiZWZvcmVFeGl0YCBoYW5kbGVyIHRvIGNsZWFuIHVwIHdoZW4gYSB0ZXN0IHJ1bm5lciBleGl0c1xuICogd2l0aG91dCBjYWxsaW5nIHRlYXJkb3duIChlLmcuLCB3aGVuIG9uZSBwcm9qZWN0J3Mgc2V0dXAgZmFpbHMgYW5kIHRoZVxuICogcnVubmVyIGFib3J0cyBiZWZvcmUgdGVhcmluZyBkb3duIGFscmVhZHktaW5pdGlhbGl6ZWQgcHJvamVjdHMpLlxuICovXG5jb25zdCBhY3RpdmVTZXR1cHMgPSBuZXcgU2V0PENvcmVTZXR1cFJlc3VsdD4oKTtcbmNvbnN0IGRpc3Bvc2VkUmVzdWx0cyA9IG5ldyBXZWFrU2V0PENvcmVTZXR1cFJlc3VsdD4oKTtcbmxldCBpc0NsZWFudXBIYW5kbGVyUmVnaXN0ZXJlZCA9IGZhbHNlO1xuXG4vKipcbiAqIFRoZSBjcm9zcy1wcm9jZXNzIHNldHVwIGxvY2sgaGVsZCBieSBlYWNoIGFjdGl2ZSBzZXR1cC4gUmVsZWFzZWQgd2hlbiB0aGVcbiAqIHNldHVwIGlzIHRvcm4gZG93biAob3IgYnkgdGhlIHByb2Nlc3MgY2xlYW51cCBoYW5kbGVycyksIGFsbG93aW5nIGEgY29tcGV0aW5nXG4gKiBydW4gdG8gcHJvY2VlZC4gU2VlIHtAbGluayBhY3F1aXJlU2V0dXBMb2NrfS5cbiAqL1xuY29uc3Qgc2V0dXBMb2NrcyA9IG5ldyBNYXA8Q29yZVNldHVwUmVzdWx0LCBTZXR1cExvY2s+KCk7XG5cbmNvbnN0IEFORFJPSURfTE9DS19TQ09QRSA9ICdhbmRyb2lkJztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgY29yZVNldHVwfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb3JlU2V0dXBQYXJhbXMge1xuICAvKipcbiAgICogQ29tbXVuaXR5LXBsdWdpbiBpZHMgdG8gZW5hYmxlIGluIHRoZSB2YXVsdCAqKmluIGFkZGl0aW9uIHRvKiogdGhlXG4gICAqIHBsdWdpbi11bmRlci10ZXN0LCBhZnRlciBpdCBpcyBlbmFibGVkLiBFYWNoIGlkJ3MgYnVpbHQgZmlsZXMgbXVzdCBhbHJlYWR5IGJlXG4gICAqIHByZXNlbnQgdW5kZXIgYC5vYnNpZGlhbi9wbHVnaW5zLzxpZD4vYCBcdTIwMTQgc2VlZCB0aGVtIHZpYSB7QGxpbmsgQ29yZVNldHVwUGFyYW1zLnBvcHVsYXRlfVxuICAgKiAoZS5nLiB3aXRoIGBidWlsZERlbW9WYXVsdFBvcHVsYXRlYCkuIEVuYWJsaW5nIGdvZXMgdGhyb3VnaCB0aGUgc2FtZVxuICAgKiByZXRyeS9sb2FkLXZlcmlmeSBwYXRoIGFzIHRoZSBwbHVnaW4tdW5kZXItdGVzdC4gQ29tcG9zZXMgd2l0aFxuICAgKiBgaW5zdGFsbFBsdWdpbjogZmFsc2VgIChlbmFibGUgZXh0cmFzIGludG8gYW4gb3RoZXJ3aXNlIHBsdWdpbi1sZXNzIHZhdWx0KS5cbiAgICovXG4gIHJlYWRvbmx5IGVuYWJsZUNvbW11bml0eVBsdWdpbnM/OiByZWFkb25seSBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogV2hldGhlciB0byBpbnN0YWxsIGFuZCBlbmFibGUgdGhlIGJ1aWx0IHBsdWdpbiBpbiB0aGUgdGVtcCB2YXVsdC4gRGVmYXVsdHNcbiAgICogdG8gYHRydWVgLiBTZXQgdG8gYGZhbHNlYCBmb3IgYSAqKm5vbi1wbHVnaW4qKiBjb25zdW1lciAoZS5nLiBhIHR5cGluZ3NcbiAgICogY3Jhd2xlcikgdGhhdCBvbmx5IG5lZWRzIGEgcmVnaXN0ZXJlZCwgZW1wdHkgdmF1bHQgdG8gYGV2YWxJbk9ic2lkaWFuYFxuICAgKiBhZ2FpbnN0OiB0aGUgcGx1Z2luIGBkaXN0YC9gbWFuaWZlc3QuanNvbmAgcmVhZCwgdGhlIGNvcHkgaW50b1xuICAgKiBgLm9ic2lkaWFuL3BsdWdpbnNgLCB0aGUgYGNvbW11bml0eS1wbHVnaW5zLmpzb25gIHdyaXRlLCBhbmQgdGhlIGVuYWJsZSBzdGVwXG4gICAqIGFyZSBhbGwgc2tpcHBlZCwgd2hpbGUgdGhlIHRyYW5zcG9ydCwgdGVtcCB2YXVsdCwgcmVnaXN0cmF0aW9uLCBhbmRcbiAgICogd29ya2VyLWZhY2luZyBlbmRwb2ludCBwcm92aXNpb25pbmcgc3RpbGwgcnVuIHVuY2hhbmdlZC5cbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbGxQbHVnaW4/OiBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBGaWxlcyBhbmQgZm9sZGVycyB0byB3cml0ZSBpbnRvIHRoZSB2YXVsdCAqKmJlZm9yZSoqIE9ic2lkaWFuIG9wZW5zIGl0LCBzb1xuICAgKiBpdHMgc3RhcnR1cCBzY2FuIGluZGV4ZXMgdGhlbSBpbiBvbmUgcGFzcyAoc2VlIHtAbGluayBUZW1wVmF1bHQucG9wdWxhdGV9KS5cbiAgICogVXNlIHRoaXMgZm9yIGxhcmdlIGZpeHR1cmVzIFx1MjAxNCB3cml0aW5nIHRob3VzYW5kcyBvZiBub3RlcyBhZnRlciBvcGVuIGFuZFxuICAgKiBmb3JjaW5nIGEgcmUtc2NhbiBpcyBmYXIgc2xvd2VyIGFuZCBsZXNzIHJlbGlhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcG9wdWxhdGU/OiBQb3B1bGF0ZUZpbGVzUGFyYW1zIHwgdW5kZWZpbmVkO1xuXG4gIC8qKiBUcmFuc3BvcnQgb3B0aW9ucy4gV2hlbiBvbWl0dGVkLCB1c2VzIGFuIG9mZi1zY3JlZW4gb3duZWQgZGVza3RvcCBpbnN0YW5jZS4gKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9ucz86IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXN1bHQgcmV0dXJuZWQgYnkge0BsaW5rIGNvcmVTZXR1cH0sIHVzZWQgYnkgZnJhbWV3b3JrIGFkYXB0ZXJzXG4gKiB0byBwYXNzIGNvbnRleHQgdG8gdGVzdCB3b3JrZXJzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvcmVTZXR1cFJlc3VsdCB7XG4gIC8qKiBUaGUgdGVtcG9yYXJ5IHZhdWx0IGNyZWF0ZWQgZHVyaW5nIHNldHVwLiAqL1xuICByZWFkb25seSB0ZW1wVmF1bHQ6IFRlbXBWYXVsdDtcblxuICAvKiogVGhlIHRyYW5zcG9ydCBpbnN0YW5jZSB1c2VkIGR1cmluZyBzZXR1cC4gKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydDtcblxuICAvKiogU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcyAoZS5nLiBgXCJvYnNpZGlhbi1jZHBcImApLiAqL1xuICByZWFkb25seSB0cmFuc3BvcnRMYWJlbDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgdHJhbnNwb3J0IG9wdGlvbnMgdGhhdCB3ZXJlIHJlc29sdmVkLiAqL1xuICByZWFkb25seSB0cmFuc3BvcnRPcHRpb25zOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNvcHlQbHVnaW5JbnRvVmF1bHR9LlxuICovXG5pbnRlcmZhY2UgQ29weVBsdWdpbkludG9WYXVsdFBhcmFtcyB7XG4gIC8qKiBTaG9ydCBsYWJlbCBmb3IgbG9nIG1lc3NhZ2VzLiAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgcHJvamVjdCByb290IHRvIHJlc29sdmUgdGhlIGJ1aWx0IHBsdWdpbiBmcm9tLiAqL1xuICByZWFkb25seSBwcm9qZWN0Um9vdDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgdGVtcCB2YXVsdCB0byBjb3B5IHRoZSBwbHVnaW4gaW50by4gKi9cbiAgcmVhZG9ubHkgdGVtcFZhdWx0OiBUZW1wVmF1bHQ7XG5cbiAgLyoqIFRoZSB0cmFuc3BvcnQgKHVzZWQgZm9yIHRoZSBtb2JpbGUvZGVza3RvcC1vbmx5IGNvbXBhdGliaWxpdHkgY2hlY2spLiAqL1xuICByZWFkb25seSB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0O1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBlbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnN9LlxuICovXG5pbnRlcmZhY2UgRW5hYmxlRXh0cmFDb21tdW5pdHlQbHVnaW5zUGFyYW1zIHtcbiAgLyoqIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMuICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSBpZHMgb2YgdGhlIGV4dHJhIGNvbW11bml0eSBwbHVnaW5zIHRvIGVuYWJsZSAodGhlaXIgYmluYXJpZXMgbXVzdCBhbHJlYWR5IGJlIGluIHRoZSB2YXVsdCkuICovXG4gIHJlYWRvbmx5IHBsdWdpbklkczogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgLyoqIFRoZSB0ZW1wIHZhdWx0IHRoZSBwbHVnaW5zIHdlcmUgc2VlZGVkIGludG8uICovXG4gIHJlYWRvbmx5IHRlbXBWYXVsdDogVGVtcFZhdWx0O1xuXG4gIC8qKiBUaGUgdHJhbnNwb3J0IHRvIGV2YWx1YXRlIGFnYWluc3QuICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnQ7XG5cbiAgLyoqIFRoZSByZXNvbHZlZCB0cmFuc3BvcnQgb3B0aW9ucyAoc291cmNlIG9mIHRoZSBwbHVnaW4tZW5hYmxlIHJldHJ5IGtub2JzKS4gKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogbnVsbCB8IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgZW5hYmxlUGx1Z2luSW5WYXVsdH0uXG4gKi9cbmludGVyZmFjZSBFbmFibGVQbHVnaW5JblZhdWx0UGFyYW1zIHtcbiAgLyoqIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMuICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSBpZCBvZiB0aGUgcGx1Z2luIHRvIGVuYWJsZS4gKi9cbiAgcmVhZG9ubHkgcGx1Z2luSWQ6IHN0cmluZztcblxuICAvKiogVGhlIHRlbXAgdmF1bHQgdGhlIHBsdWdpbiB3YXMgY29waWVkIGludG8uICovXG4gIHJlYWRvbmx5IHRlbXBWYXVsdDogVGVtcFZhdWx0O1xuXG4gIC8qKiBUaGUgdHJhbnNwb3J0IHRvIGV2YWx1YXRlIGFnYWluc3QuICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnQ7XG5cbiAgLyoqIFRoZSByZXNvbHZlZCB0cmFuc3BvcnQgb3B0aW9ucyAoc291cmNlIG9mIHRoZSBwbHVnaW4tZW5hYmxlIHJldHJ5IGtub2JzKS4gKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogbnVsbCB8IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgc3dlZXBMZWZ0b3ZlcnN9LlxuICovXG5pbnRlcmZhY2UgU3dlZXBMZWZ0b3ZlcnNQYXJhbXMge1xuICAvKiogRGlyZWN0b3J5IG5hbWVzIHRvIGtlZXAgcmVnYXJkbGVzcyBvZiBhZ2UgKGUuZy4gYSBjb25jdXJyZW50IHNldHVwJ3MgdmF1bHQpLiAqL1xuICByZWFkb25seSBleGNsdWRlZE5hbWVzPzogcmVhZG9ubHkgc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgLyoqIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMuICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqIFdoaWNoIGVuZCBvZiB0aGUgcnVuIGlzIHN3ZWVwaW5nLCBmb3IgdGhlIGxvZyBwcmVmaXguICovXG4gIHJlYWRvbmx5IHBoYXNlOiAnc2V0dXAnIHwgJ3RlYXJkb3duJztcblxuICAvKiogVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zIChzb3VyY2Ugb2YgdGhlIHN3ZWVwIGtub2JzKS4gKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEZyYW1ld29yay1hZ25vc3RpYyBnbG9iYWwgc2V0dXAgbG9naWMuXG4gKlxuICogTG9hZHMgYC5lbnZgIGZyb20gdGhlIHByb2plY3Qgcm9vdCwgY3JlYXRlcyBhIHRyYW5zcG9ydCwgY3JlYXRlcyBhbmQgcmVnaXN0ZXJzXG4gKiBhIHRlbXBvcmFyeSB2YXVsdCB3aXRoIE9ic2lkaWFuLCBhbmQgXHUyMDE0IHVubGVzcyB7QGxpbmsgQ29yZVNldHVwUGFyYW1zLmluc3RhbGxQbHVnaW59XG4gKiBpcyBgZmFsc2VgIFx1MjAxNCBjb3BpZXMgdGhlIGJ1aWx0IHBsdWdpbiBpbnRvIHRoZSB2YXVsdCBhbmQgZW5hYmxlcyBpdC4gVGhlXG4gKiBwbHVnaW4tbGVzcyBtb2RlIHN0aWxsIGxhdW5jaGVzIHRoZSBvd25lZCBpbnN0YW5jZSBhbmQgcHVibGlzaGVzIGl0c1xuICogd29ya2VyLWZhY2luZyBlbmRwb2ludCwgc28gYSBub24tcGx1Z2luIGNvbnN1bWVyIHJldXNlcyB0aGUgc2FtZSBhdHRhY2ggd2lyaW5nLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBTZXR1cCBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgVGhlIHNldHVwIHJlc3VsdCBjb250YWluaW5nIHRoZSB0ZW1wIHZhdWx0LCB0cmFuc3BvcnQsIGFuZCByZXNvbHZlZCBvcHRpb25zLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29yZVNldHVwKHBhcmFtcz86IENvcmVTZXR1cFBhcmFtcyk6IFByb21pc2U8Q29yZVNldHVwUmVzdWx0PiB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gZmluZFByb2plY3RSb290KCk7XG4gIGNvbnN0IGVudkZpbGVQYXRoID0gam9pbihwcm9qZWN0Um9vdCwgJy5lbnYnKTtcbiAgaWYgKGV4aXN0c1N5bmMoZW52RmlsZVBhdGgpKSB7XG4gICAgbG9hZEVudkZpbGUoZW52RmlsZVBhdGgpO1xuICB9XG5cbiAgY29uc3QgdHJhbnNwb3J0T3B0aW9ucyA9IHJlc29sdmVJbnRlZ3JhdGlvblRyYW5zcG9ydE9wdGlvbnMocGFyYW1zPy50cmFuc3BvcnRPcHRpb25zKTtcbiAgY29uc3QgbGFiZWwgPSB0cmFuc3BvcnRPcHRpb25zLnR5cGU7XG4gIGNvbnN0IGxvY2tTY29wZSA9IGdldExvY2tTY29wZSh0cmFuc3BvcnRPcHRpb25zKTtcblxuICBsZXQgbG9jazogU2V0dXBMb2NrIHwgdW5kZWZpbmVkO1xuICBpZiAobG9ja1Njb3BlICE9PSB1bmRlZmluZWQpIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gQWNxdWlyaW5nICcke2xvY2tTY29wZX0nIHNldHVwIGxvY2sgKHNlcmlhbGl6ZXMgYWdhaW5zdCBhbnkgY29uY3VycmVudCBpbnRlZ3JhdGlvbi10ZXN0IHJ1bikuLi5gKTtcbiAgICBsb2NrID0gYXdhaXQgYWNxdWlyZVNldHVwTG9jayh7IGxhYmVsLCBzY29wZTogbG9ja1Njb3BlIH0pO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBTZXR1cCBsb2NrIGFjcXVpcmVkLmApO1xuICB9XG5cbiAgYXdhaXQgc3dlZXBMZWZ0b3ZlcnMoeyBsYWJlbCwgcGhhc2U6ICdzZXR1cCcsIHRyYW5zcG9ydE9wdGlvbnMgfSk7XG5cbiAgbGV0IHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnQgfCB1bmRlZmluZWQ7XG4gIGxldCB0ZW1wVmF1bHQ6IFRlbXBWYXVsdCB8IHVuZGVmaW5lZDtcblxuICB0cnkge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBDcmVhdGluZyB0cmFuc3BvcnQuLi5gKTtcbiAgICB0cmFuc3BvcnQgPSBhd2FpdCBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyh0cmFuc3BvcnRPcHRpb25zKTtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gVHJhbnNwb3J0IGNyZWF0ZWQ6ICR7dHJhbnNwb3J0LmNvbnN0cnVjdG9yLm5hbWV9YCk7XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUHJvamVjdCByb290OiAke3Byb2plY3RSb290fWApO1xuICAgIGNvbnN0IHNob3VsZEluc3RhbGxQbHVnaW4gPSBwYXJhbXM/Lmluc3RhbGxQbHVnaW4gIT09IGZhbHNlO1xuXG4gICAgdGVtcFZhdWx0ID0gbmV3IFRlbXBWYXVsdCgpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBDcmVhdGVkIHRlbXAgdmF1bHQ6ICR7dGVtcFZhdWx0LnBhdGh9YCk7XG5cbiAgICBsZXQgcGx1Z2luSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIGlmIChzaG91bGRJbnN0YWxsUGx1Z2luKSB7XG4gICAgICBwbHVnaW5JZCA9IGF3YWl0IGNvcHlQbHVnaW5JbnRvVmF1bHQoeyBsYWJlbCwgcHJvamVjdFJvb3QsIHRlbXBWYXVsdCwgdHJhbnNwb3J0IH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gU2tpcHBpbmcgcGx1Z2luIGluc3RhbGwgKGluc3RhbGxQbHVnaW46IGZhbHNlKSBcdTIwMTQgcmVnaXN0ZXJpbmcgYW4gZW1wdHkgdmF1bHQuYCk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcz8ucG9wdWxhdGUpIHtcbiAgICAgIGNvbnN0IGVudHJ5Q291bnQgPSBPYmplY3Qua2V5cyhwYXJhbXMucG9wdWxhdGUpLmxlbmd0aDtcbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBQb3B1bGF0aW5nIHZhdWx0IHdpdGggJHtTdHJpbmcoZW50cnlDb3VudCl9IGVudHJpZXMgYmVmb3JlIG9wZW4uLi5gKTtcbiAgICAgIHRlbXBWYXVsdC5wb3B1bGF0ZShwYXJhbXMucG9wdWxhdGUpO1xuICAgIH1cblxuICAgIGF3YWl0IGVuc3VyZUFsd2F5c1VwZGF0ZUxpbmtzKHRlbXBWYXVsdCwgbGFiZWwpO1xuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFN5bmNpbmcgdmF1bHQgdG8gZGV2aWNlLi4uYCk7XG4gICAgYXdhaXQgdGVtcFZhdWx0LnN5bmNUb0RldmljZSh0cmFuc3BvcnQpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBSZWdpc3RlcmluZyB2YXVsdC4uLmApO1xuICAgIGF3YWl0IHRlbXBWYXVsdC5yZWdpc3Rlcih0cmFuc3BvcnQpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBWYXVsdCByZWdpc3RlcmVkLmApO1xuXG4gICAgaWYgKHBsdWdpbklkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGF3YWl0IGVuYWJsZVBsdWdpbkluVmF1bHQoeyBsYWJlbCwgcGx1Z2luSWQsIHRlbXBWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRPcHRpb25zIH0pO1xuICAgIH1cblxuICAgIGF3YWl0IGVuYWJsZUV4dHJhQ29tbXVuaXR5UGx1Z2lucyh7XG4gICAgICBsYWJlbCxcbiAgICAgIHBsdWdpbklkczogcGFyYW1zPy5lbmFibGVDb21tdW5pdHlQbHVnaW5zID8/IFtdLFxuICAgICAgdGVtcFZhdWx0LFxuICAgICAgdHJhbnNwb3J0LFxuICAgICAgdHJhbnNwb3J0T3B0aW9uc1xuICAgIH0pO1xuXG4gICAgY29uc3QgYXVnbWVudGVkT3B0aW9ucyA9IGF1Z21lbnRUcmFuc3BvcnRPcHRpb25zKHRyYW5zcG9ydE9wdGlvbnMsIHRyYW5zcG9ydCk7XG4gICAgY29uc3QgcmVzdWx0OiBDb3JlU2V0dXBSZXN1bHQgPSB7IHRlbXBWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRMYWJlbDogbGFiZWwsIHRyYW5zcG9ydE9wdGlvbnM6IGF1Z21lbnRlZE9wdGlvbnMgfTtcbiAgICBhY3RpdmVTZXR1cHMuYWRkKHJlc3VsdCk7XG4gICAgaWYgKGxvY2spIHtcbiAgICAgIHNldHVwTG9ja3Muc2V0KHJlc3VsdCwgbG9jayk7XG4gICAgfVxuICAgIHJlZ2lzdGVyUHJvY2Vzc0NsZWFudXBIYW5kbGVyKCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gU2V0dXAgZmFpbGVkLCBjbGVhbmluZyB1cC4uLmApO1xuICAgIHRyeSB7XG4gICAgICBpZiAodGVtcFZhdWx0ICYmIHRyYW5zcG9ydCkge1xuICAgICAgICBhd2FpdCB0ZW1wVmF1bHQuZGlzcG9zZSh0cmFuc3BvcnQpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGNsZWFudXBFcnJvcjogdW5rbm93bikge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFZhdWx0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhjbGVhbnVwRXJyb3IpfWApO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdHJhbnNwb3J0Py5kaXNwb3NlPy4oKTtcbiAgICB9IGNhdGNoIChjbGVhbnVwRXJyb3I6IHVua25vd24pIHtcbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBUcmFuc3BvcnQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGNsZWFudXBFcnJvcil9YCk7XG4gICAgfVxuXG4gICAgLy8gUmVsZWFzZSB0aGUgbG9jayBzbyBhIHdhaXRpbmcgcnVuIGNhbiBwcm9jZWVkIGV2ZW4gdGhvdWdoIHRoaXMgcnVuIGZhaWxlZC5cbiAgICBsb2NrPy5yZWxlYXNlKCk7XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gTk9URTogSWYgdGhlIHRlc3QgcnVubmVyIHJlcG9ydHMgXCJObyB0ZXN0IGZpbGVzIGZvdW5kXCIsIGlnbm9yZSBpdCBcdTIwMTQgaXQgaXMgYSBzaWRlIGVmZmVjdCBvZiB0aGUgc2V0dXAgZmFpbHVyZSBhYm92ZS5gKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG4vKipcbiAqIEZyYW1ld29yay1hZ25vc3RpYyBnbG9iYWwgdGVhcmRvd24gbG9naWMuXG4gKlxuICogRGlzcG9zZXMgb2YgdGhlIHRlbXBvcmFyeSB2YXVsdCBhbmQgdHJhbnNwb3J0IGNyZWF0ZWQgZHVyaW5nIHNldHVwLlxuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBUaGUgcmVzdWx0IGZyb20ge0BsaW5rIGNvcmVTZXR1cH0uIFdoZW4gYHVuZGVmaW5lZGAsIGRvZXMgbm90aGluZy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvcmVUZWFyZG93bihyZXN1bHQ/OiBDb3JlU2V0dXBSZXN1bHQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKCFyZXN1bHQgfHwgZGlzcG9zZWRSZXN1bHRzLmhhcyhyZXN1bHQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGRpc3Bvc2VkUmVzdWx0cy5hZGQocmVzdWx0KTtcblxuICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIFRlYXJpbmcgZG93bi4uLmApO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgdGVhcmRvd25Bc3luYyhyZXN1bHQpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gQ2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBhY3RpdmVTZXR1cHMuZGVsZXRlKHJlc3VsdCk7XG4gICAgcmVsZWFzZVNldHVwTG9jayhyZXN1bHQpO1xuICB9XG5cbiAgYXdhaXQgc3dlZXBMZWZ0b3ZlcnMoe1xuICAgIGV4Y2x1ZGVkTmFtZXM6IFsuLi5hY3RpdmVTZXR1cHNdLm1hcCgoYWN0aXZlU2V0dXApID0+IGJhc2VuYW1lKGFjdGl2ZVNldHVwLnRlbXBWYXVsdC5wYXRoKSksXG4gICAgbGFiZWw6IHJlc3VsdC50cmFuc3BvcnRMYWJlbCxcbiAgICBwaGFzZTogJ3RlYXJkb3duJyxcbiAgICB0cmFuc3BvcnRPcHRpb25zOiByZXN1bHQudHJhbnNwb3J0T3B0aW9uc1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0cmFuc3BvcnQgb3B0aW9ucyBmb3IgYW4gaW50ZWdyYXRpb24gcnVuLlxuICpcbiAqIERlc2t0b3AgbGF1bmNoZXMgYXJlIG5vcm1hbGx5IHZpc2libGUsIGJ1dCB0ZXN0IHNldHVwIGV4cGxpY2l0bHkga2VlcHMgaXRzXG4gKiBvd25lZCBpbnN0YW5jZSBvZmYtc2NyZWVuIHNvIGl0IGRvZXMgbm90IGludGVycnVwdCB0aGUgZGV2ZWxvcGVyLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uc3VtZXItcHJvdmlkZWQgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcmV0dXJucyBPcHRpb25zIHdpdGggdGhlIGRlc2t0b3AgaW50ZWdyYXRpb24gdmlzaWJpbGl0eSBkZWZhdWx0IGFwcGxpZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlSW50ZWdyYXRpb25UcmFuc3BvcnRPcHRpb25zKG9wdGlvbnM/OiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMpOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMge1xuICBpZiAob3B0aW9ucz8udHlwZSA9PT0gJ29ic2lkaWFuLWFuZHJvaWQtYXBwaXVtJykge1xuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGlzT2JzaWRpYW5BcHBWaXNpYmxlOiBvcHRpb25zPy5pc09ic2lkaWFuQXBwVmlzaWJsZSA/PyBmYWxzZSxcbiAgICB0eXBlOiAnb2JzaWRpYW4tY2RwJ1xuICB9O1xufVxuXG4vKipcbiAqIEF1Z21lbnRzIHRyYW5zcG9ydCBvcHRpb25zIHdpdGggcmV1c2UgaW5mbyBzbyB0ZXN0IHdvcmtlcnMgY2FuIHJlYXR0YWNoIHRvIHRoZVxuICogaW5zdGFuY2UgdGhlIGdsb2JhbCBzZXR1cCBhbHJlYWR5IGxhdW5jaGVkIGluc3RlYWQgb2YgY3JlYXRpbmcgdGhlaXIgb3duOlxuICpcbiAqIC0gKipBcHBpdW0qKiBcdTIwMTQgaW5qZWN0cyB0aGUgZXN0YWJsaXNoZWQgYHNlc3Npb25JZGAvYGRldmljZUlkYC5cbiAqIC0gKipPd25lZCBkZXNrdG9wIENEUCoqIFx1MjAxNCBpbmplY3RzIHRoZSBvd25lZCBpbnN0YW5jZSdzIGBob3N0YC9gcG9ydGAgKGNob3NlblxuICogICBhdCBsYXVuY2gpIHBsdXMgdGhlIGludGVybmFsIGBpc0hhcm5lc3NPd25lZEluc3RhbmNlYCBmbGFnLCBzbyBlYWNoIHdvcmtlclxuICogICAqKmF0dGFjaGVzKiogdG8gdGhhdCBpbnN0YW5jZSBvdmVyIENEUCByYXRoZXIgdGhhbiBsYXVuY2hpbmcgKGFuZCBuZXZlclxuICogICByZWdpc3RlcmluZykgaXRzIG93biBcdTIwMTQgdGhlIGJ1ZyB0aGF0IG90aGVyd2lzZSBsZWF2ZXMgYSB3b3JrZXIncyB0cmFuc3BvcnRcbiAqICAgd2l0aCBubyBDRFAgZW5kcG9pbnQuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgb3JpZ2luYWwgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcGFyYW0gdHJhbnNwb3J0IC0gVGhlIHRyYW5zcG9ydCBpbnN0YW5jZSBjcmVhdGVkIGR1cmluZyBzZXR1cC5cbiAqIEByZXR1cm5zIFRoZSBhdWdtZW50ZWQgb3B0aW9ucywgb3IgdGhlIG9yaWdpbmFsIG9wdGlvbnMgaWYgbm90IGFwcGxpY2FibGUuXG4gKi9cbmZ1bmN0aW9uIGF1Z21lbnRUcmFuc3BvcnRPcHRpb25zKFxuICBvcHRpb25zOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQsXG4gIHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnRcbik6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIGlmIChvcHRpb25zPy50eXBlID09PSAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nICYmIHRyYW5zcG9ydCBpbnN0YW5jZW9mIEFwcGl1bVRyYW5zcG9ydCkge1xuICAgIGNvbnN0IHNlc3Npb25JbmZvID0gdHJhbnNwb3J0LmdldFNlc3Npb25JbmZvKCk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtvcHRpb25zLnR5cGV9XSBTZXNzaW9uIHJldXNlIGluZm86IHNlc3Npb25JZD0ke3Nlc3Npb25JbmZvLnNlc3Npb25JZH0sIGRldmljZUlkPSR7c2Vzc2lvbkluZm8uZGV2aWNlSWR9YCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBkZXZpY2VJZDogc2Vzc2lvbkluZm8uZGV2aWNlSWQsXG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JbmZvLnNlc3Npb25JZFxuICAgIH07XG4gIH1cblxuICBpZiAoKG9wdGlvbnMgPT09IHVuZGVmaW5lZCB8fCBvcHRpb25zLnR5cGUgPT09ICdvYnNpZGlhbi1jZHAnKSAmJiB0cmFuc3BvcnQgaW5zdGFuY2VvZiBEZXNrdG9wQ2RwVHJhbnNwb3J0KSB7XG4gICAgY29uc3QgZW5kcG9pbnQgPSB0cmFuc3BvcnQuZ2V0T3duZWRJbnN0YW5jZUVuZHBvaW50KCk7XG4gICAgaWYgKGVuZHBvaW50KSB7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke0RFRkFVTFRfVFJBTlNQT1JUX1RZUEV9XSBPd25lZCBpbnN0YW5jZSByZXVzZSBpbmZvOiBob3N0PSR7ZW5kcG9pbnQuaG9zdH0sIHBvcnQ9JHtTdHJpbmcoZW5kcG9pbnQucG9ydCl9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICBob3N0OiBlbmRwb2ludC5ob3N0LFxuICAgICAgICBpc0hhcm5lc3NPd25lZEluc3RhbmNlOiB0cnVlLFxuICAgICAgICBwb3J0OiBlbmRwb2ludC5wb3J0LFxuICAgICAgICB0eXBlOiAnb2JzaWRpYW4tY2RwJ1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuLyoqXG4gKiBDb3BpZXMgdGhlIGJ1aWx0IHBsdWdpbiBpbnRvIHRoZSB0ZW1wIHZhdWx0IGFuZCBtYXJrcyBpdCBhcyBhIGNvbW11bml0eSBwbHVnaW4uXG4gKlxuICogUmVhZHMgYG1hbmlmZXN0Lmpzb25gIGZyb20gdGhlIG5ld2VyIG9mIGBkaXN0L2RldmAvYGRpc3QvYnVpbGRgLCByZWplY3RzIGFcbiAqIGRlc2t0b3Atb25seSBwbHVnaW4gb24gYSBtb2JpbGUgdHJhbnNwb3J0LCBjb3BpZXMgdGhlIGJ1aWxkIGludG9cbiAqIGAub2JzaWRpYW4vcGx1Z2lucy88aWQ+YCwgYW5kIHdyaXRlcyBgLm9ic2lkaWFuL2NvbW11bml0eS1wbHVnaW5zLmpzb25gLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgY29weSBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgVGhlIHBsdWdpbiBpZCByZWFkIGZyb20gdGhlIG1hbmlmZXN0LlxuICovXG5hc3luYyBmdW5jdGlvbiBjb3B5UGx1Z2luSW50b1ZhdWx0KHBhcmFtczogQ29weVBsdWdpbkludG9WYXVsdFBhcmFtcyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHsgbGFiZWwsIHByb2plY3RSb290LCB0ZW1wVmF1bHQsIHRyYW5zcG9ydCB9ID0gcGFyYW1zO1xuICBjb25zdCBkaXN0UGF0aCA9IGF3YWl0IHJlc29sdmVEaXN0UGF0aChwcm9qZWN0Um9vdCk7XG4gIGNvbnN0IG1hbmlmZXN0SnNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUoam9pbihkaXN0UGF0aCwgJ21hbmlmZXN0Lmpzb24nKSwgJ3V0Zi04JykpIGFzIFBsdWdpbk1hbmlmZXN0O1xuICBjb25zdCBwbHVnaW5JZCA9IG1hbmlmZXN0SnNvbi5pZDtcblxuICBpZiAodHJhbnNwb3J0LmlzTW9iaWxlICYmIG1hbmlmZXN0SnNvbi5pc0Rlc2t0b3BPbmx5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFBsdWdpbiBcIiR7cGx1Z2luSWR9XCIgaGFzIGlzRGVza3RvcE9ubHk6IHRydWUgaW4gbWFuaWZlc3QuanNvbi4gTW9iaWxlIGludGVncmF0aW9uIHRlc3RzIGNhbm5vdCBydW4gZm9yIGRlc2t0b3Atb25seSBwbHVnaW5zLmBcbiAgICApO1xuICB9XG5cbiAgY29uc3QgbWFpbkpzID0gam9pbihkaXN0UGF0aCwgTUFJTl9KUyk7XG4gIGNvbnN0IGJ1aWxkU3RhdCA9IGF3YWl0IHN0YXQobWFpbkpzKTtcbiAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFVzaW5nICR7ZGlzdFBhdGh9ICgke2J1aWxkU3RhdC5tdGltZS50b0lTT1N0cmluZygpfSkuIElmIG91dGRhdGVkLCByZWJ1aWxkLmApO1xuXG4gIGNvbnN0IHBsdWdpbkRpciA9IGpvaW4odGVtcFZhdWx0LnBhdGgsIE9CU0lESUFOX0NPTkZJR19ESVIsIFBMVUdJTlNfRElSLCBwbHVnaW5JZCk7XG4gIGF3YWl0IG1rZGlyKHBsdWdpbkRpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGF3YWl0IGNwKGRpc3RQYXRoLCBwbHVnaW5EaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICBhd2FpdCB3cml0ZUZpbGUoam9pbih0ZW1wVmF1bHQucGF0aCwgT0JTSURJQU5fQ09ORklHX0RJUiwgQ09NTVVOSVRZX1BMVUdJTlNfSlNPTiksIEpTT04uc3RyaW5naWZ5KFtwbHVnaW5JZF0pKTtcblxuICByZXR1cm4gcGx1Z2luSWQ7XG59XG5cbi8qKlxuICogRW5hYmxlcyBleHRyYSBjb21tdW5pdHkgcGx1Z2lucyAoYmV5b25kIHRoZSBwbHVnaW4tdW5kZXItdGVzdCkgaW4gdGhlIHJlZ2lzdGVyZWQgdmF1bHQsIGVhY2ggdGhyb3VnaCB0aGVcbiAqIHNhbWUge0BsaW5rIGVuYWJsZVBsdWdpbkluVmF1bHR9IHBhdGguIEVhY2ggcGx1Z2luJ3MgYnVpbHQgZmlsZXMgbXVzdCBhbHJlYWR5IGJlIHByZXNlbnQgaW4gdGhlIHZhdWx0IChzZWVkXG4gKiB0aGVtIHZpYSB7QGxpbmsgQ29yZVNldHVwUGFyYW1zLnBvcHVsYXRlfSkuIEEgbm8tb3Agd2hlbiB0aGUgbGlzdCBpcyBlbXB0eS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGVuYWJsZSBwYXJhbWV0ZXJzLlxuICovXG5hc3luYyBmdW5jdGlvbiBlbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnMocGFyYW1zOiBFbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcGx1Z2luSWRzLCB0ZW1wVmF1bHQsIHRyYW5zcG9ydCwgdHJhbnNwb3J0T3B0aW9ucyB9ID0gcGFyYW1zO1xuICBmb3IgKGNvbnN0IHBsdWdpbklkIG9mIHBsdWdpbklkcykge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBFbmFibGluZyBleHRyYSBjb21tdW5pdHkgcGx1Z2luIFwiJHtwbHVnaW5JZH1cIi4uLmApO1xuICAgIGF3YWl0IGVuYWJsZVBsdWdpbkluVmF1bHQoeyBsYWJlbCwgcGx1Z2luSWQsIHRlbXBWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRPcHRpb25zIH0pO1xuICB9XG59XG5cbi8qKlxuICogRW5hYmxlcyB0aGUgcGx1Z2luIGluIHRoZSByZWdpc3RlcmVkIHZhdWx0IGFuZCB2ZXJpZmllcyBpdCBsb2FkZWQuXG4gKlxuICogT2JzaWRpYW4ncyBgZW5hYmxlUGx1Z2luKClgIHdyYXBzIGBsb2FkUGx1Z2luKClgIGluIGEgdHJ5LWNhdGNoIHRoYXQgc3dhbGxvd3NcbiAqIGVycm9ycyBhbmQgcmV0dXJucyBmYWxzZSwgc28ge0BsaW5rIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmV9IG1vbmtleS1wYXRjaGVzXG4gKiBgbG9hZFBsdWdpbigpYCB0byBjYXB0dXJlIHRoZSBlcnJvciBiZWZvcmUgaXQncyBzd2FsbG93ZWQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBlbmFibGUgcGFyYW1ldGVycy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZW5hYmxlUGx1Z2luSW5WYXVsdChwYXJhbXM6IEVuYWJsZVBsdWdpbkluVmF1bHRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcGx1Z2luSWQsIHRlbXBWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRPcHRpb25zIH0gPSBwYXJhbXM7XG4gIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBFbmFibGluZyBwbHVnaW4gXCIke3BsdWdpbklkfVwiLi4uYCk7XG5cbiAgLypcbiAgICogT3BlbiBhIG5hdGl2ZSBjb25zb2xlLWNhcHR1cmUgd2luZG93IChMYXllciAyLCBBbmRyb2lkIG9ubHkpIGFyb3VuZCB0aGVcbiAgICogZW5hYmxlIHNvIHRoYXQgaWYgT2JzaWRpYW4gc3dhbGxvd3MgdGhlIGxvYWQgZXJyb3IgYmVmb3JlIHRoZSBtb25rZXktcGF0Y2hcbiAgICogYW5kIHRoZSByZW5kZXJlciBjb25zb2xlIChMYXllciAxKSBjYW1lIHVwIGVtcHR5LCB3ZSBjYW4gc3RpbGwgcmVjb3ZlciB0aGVcbiAgICogcmVhbCBjYXVzZSBmcm9tIGBhZGIgbG9nY2F0YC4gTm8tb3AgKHVuZGVmaW5lZCkgb24gdHJhbnNwb3J0cyB0aGF0IGRvbid0XG4gICAqIGltcGxlbWVudCBpdCAoZS5nLiBkZXNrdG9wKS5cbiAgICovXG4gIGNvbnN0IGNhcHR1cmVIYW5kbGUgPSBhd2FpdCB0cmFuc3BvcnQuYmVnaW5Db25zb2xlQ2FwdHVyZT8uKCk7XG5cbiAgLypcbiAgICogT24gYSBmcmVzaGx5IGNvbGQtYm9vdGVkIGVtdWxhdG9yIHRoZSBwbHVnaW4gc3Vic3lzdGVtIGNhbiBzdGlsbCBiZSBzZXR0bGluZ1xuICAgKiB3aGVuIHdlIGVuYWJsZSB0aGUgcGx1Z2luLCBzbyBhIHNpbmdsZS1zaG90IGVuYWJsZSByYWNlcyB0aGUgbG9hZCBhbmQgbG9zZXNcbiAgICogKHRoZSBwbHVnaW4gbGFuZHMgaW4gdGhlIGVuYWJsZWQgc2V0IGJ1dCBuZXZlciBsb2FkcykuIFJldHJ5IHRoZSBlbmFibGUgK1xuICAgKiBsb2FkLXZlcmlmaWNhdGlvbiBhIGZldyB0aW1lcyB3aXRoIGV4cG9uZW50aWFsIGJhY2tvZmYsIHdoaWNoIHJlY292ZXJzIHRoZVxuICAgKiB0cmFuc2llbnQgcmFjZS4gQSBjYXB0dXJlZCBsb2FkIGVycm9yIChgcmVhbEVycm9yYCkgaXMgYSBkZXRlcm1pbmlzdGljIGJ1ZyBcdTIwMTRcbiAgICogcmV0cnlpbmcgY2Fubm90IGZpeCBpdCwgc28gd2UgZmFpbCBmYXN0LiBOb24tQW5kcm9pZCB0cmFuc3BvcnRzIHJlc29sdmUgdG9cbiAgICogdGhlIHNhbWUgZGVmYXVsdHMgYnV0IG5ldmVyIGVudGVyIHRoZSByZXRyeSBwYXRoOiB0aGVpciBsb2FkIGVpdGhlciBzdWNjZWVkc1xuICAgKiBvbiB0aGUgZmlyc3QgYXR0ZW1wdCBvciB0aHJvd3MgYSBjYXB0dXJlZCBlcnJvci5cbiAgICovXG4gIGNvbnN0IG1heEF0dGVtcHRzID0gMSArIHJlc29sdmVQbHVnaW5FbmFibGVSZXRyeUNvdW50KHRyYW5zcG9ydE9wdGlvbnMpO1xuICBjb25zdCBiYXNlRGVsYXlJbk1pbGxpc2Vjb25kcyA9IHJlc29sdmVQbHVnaW5FbmFibGVSZXRyeURlbGF5SW5NaWxsaXNlY29uZHModHJhbnNwb3J0T3B0aW9ucyk7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gbWF4QXR0ZW1wdHM7IGF0dGVtcHQrKykge1xuICAgIGxldCByZXN1bHQ6IEVuYWJsZVBsdWdpblJlc3VsdDtcbiAgICB0cnkge1xuICAgICAgcmVzdWx0ID0gYXdhaXQgZXZhbEluT2JzaWRpYW4oe1xuICAgICAgICBhcmdzOiB7IHBsdWdpbklkIH0sXG4gICAgICAgIGZuOiBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlLFxuICAgICAgICBzaG91bGRTa2lwUHJlZmxpZ2h0Q2hlY2tzOiB0cnVlLFxuICAgICAgICB0cmFuc3BvcnQsXG4gICAgICAgIHZhdWx0UGF0aDogdGVtcFZhdWx0LnBhdGhcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvKlxuICAgICAgICogVGhlIGV2YWwgaXRzZWxmIHRocmV3IChlLmcuIHRoZSBXZWJWaWV3IGNvbnRleHQgd2FzIGxvc3QgbWlkLWV4ZWN1dGlvbiBvblxuICAgICAgICogYSBjaHVybmluZyBndWVzdCkgXHUyMDE0IGEgdHJhbnNwb3J0LWxldmVsIHRyYW5zaWVudC4gUmV0cnkgaWYgYXR0ZW1wdHMgcmVtYWluLlxuICAgICAgICovXG4gICAgICBpZiAoYXR0ZW1wdCA8IG1heEF0dGVtcHRzKSB7XG4gICAgICAgIGNvbnN0IGRlbGF5SW5NaWxsaXNlY29uZHMgPSBjb21wdXRlQmFja29mZkRlbGF5SW5NaWxsaXNlY29uZHMoYmFzZURlbGF5SW5NaWxsaXNlY29uZHMsIGF0dGVtcHQgLSAxKTtcbiAgICAgICAgbG9nKFxuICAgICAgICAgIGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEVuYWJsZSBhdHRlbXB0ICR7U3RyaW5nKGF0dGVtcHQpfS8ke1N0cmluZyhtYXhBdHRlbXB0cyl9IHRocmV3IGBcbiAgICAgICAgICAgICsgYCgke2Vycm9yVG9TdHJpbmcoZXJyb3IpfSk7IHJldHJ5aW5nIGluICR7U3RyaW5nKGRlbGF5SW5NaWxsaXNlY29uZHMpfW1zLi4uYFxuICAgICAgICApO1xuICAgICAgICBhd2FpdCBzbGVlcChkZWxheUluTWlsbGlzZWNvbmRzKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIGBlcnJvck1lc3NhZ2VgIGlzIHRoZSByZWFsIHRocm93IHNlZW4gYnkgdGhlIG1vbmtleS1wYXRjaDtcbiAgICAgKiBgcmVuZGVyZXJDb25zb2xlRXJyb3JzYCAoTGF5ZXIgMSkgaXMgdGhlIHJlYWwgY2F1c2UgY29uc29sZS1sb2dnZWQgaW4gdGhlIHJlbmRlcmVyLlxuICAgICAqL1xuICAgIGNvbnN0IHJlYWxFcnJvciA9IHJlc3VsdC5lcnJvck1lc3NhZ2UgPz8gcmVzdWx0LnJlbmRlcmVyQ29uc29sZUVycm9ycztcblxuICAgIGlmIChyZXN1bHQuaXNMb2FkZWQgJiYgIXJlYWxFcnJvcikge1xuICAgICAgY29uc3QgYXR0ZW1wdFN1ZmZpeCA9IGF0dGVtcHQgPiAxID8gYCAoYXR0ZW1wdCAke1N0cmluZyhhdHRlbXB0KX0vJHtTdHJpbmcobWF4QXR0ZW1wdHMpfSlgIDogJyc7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBlbmFibGVkIHN1Y2Nlc3NmdWxseSR7YXR0ZW1wdFN1ZmZpeH0uYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQSBjYXB0dXJlZCBsb2FkIGVycm9yIGlzIGRldGVybWluaXN0aWMgXHUyMDE0IGZhaWwgZmFzdCByYXRoZXIgdGhhbiByZXRyeS5cbiAgICBpZiAoIXNob3VsZFJldHJ5UGx1Z2luRW5hYmxlKHJlc3VsdCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBmYWlsZWQgdG8gbG9hZDogJHtyZWFsRXJyb3IgPz8gZ2V0R2VuZXJpY1BsdWdpbkxvYWRGYWlsdXJlTWVzc2FnZShwbHVnaW5JZCl9YCk7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNpZW50IGNvbGQtYm9vdCByYWNlIChlbmFibGVkIGJ1dCBub3QgbG9hZGVkLCBubyBjYXVzZSBjYXB0dXJlZCk6IHJldHJ5LlxuICAgIGlmIChhdHRlbXB0IDwgbWF4QXR0ZW1wdHMpIHtcbiAgICAgIGNvbnN0IGRlbGF5SW5NaWxsaXNlY29uZHMgPSBjb21wdXRlQmFja29mZkRlbGF5SW5NaWxsaXNlY29uZHMoYmFzZURlbGF5SW5NaWxsaXNlY29uZHMsIGF0dGVtcHQgLSAxKTtcbiAgICAgIGxvZyhcbiAgICAgICAgYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBlbmFibGVkIGJ1dCBub3QgbG9hZGVkIGBcbiAgICAgICAgICArIGAoYXR0ZW1wdCAke1N0cmluZyhhdHRlbXB0KX0vJHtTdHJpbmcobWF4QXR0ZW1wdHMpfSk7IHJldHJ5aW5nIGluICR7U3RyaW5nKGRlbGF5SW5NaWxsaXNlY29uZHMpfW1zLi4uYFxuICAgICAgKTtcbiAgICAgIGF3YWl0IHNsZWVwKGRlbGF5SW5NaWxsaXNlY29uZHMpO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICAqIEV4aGF1c3RlZCBldmVyeSBhdHRlbXB0IG9uIHRoZSB0cmFuc2llbnQgc2lnbmF0dXJlOiBjb21wb3NlIHRoZSBtb3N0XG4gICAqIHNwZWNpZmljIGRldGFpbCBhdmFpbGFibGUgKGBhZGIgbG9nY2F0YCB0YWlsIG9uIEFuZHJvaWQsIGVsc2UgdGhlIGdlbmVyaWNcbiAgICogbWVzc2FnZSkgXHUyMDE0IHVuY2hhbmdlZCBmcm9tIHRoZSBwcmUtcmV0cnkgc2luZ2xlLXNob3QgZmFpbHVyZS5cbiAgICovXG4gIGNvbnN0IGxvZ2NhdFRhaWwgPSBhd2FpdCB0cmFuc3BvcnQucmVhZENvbnNvbGVDYXB0dXJlU2luY2U/LihjYXB0dXJlSGFuZGxlKTtcbiAgY29uc3QgZGV0YWlsID0gbG9nY2F0VGFpbCA/PyBnZXRHZW5lcmljUGx1Z2luTG9hZEZhaWx1cmVNZXNzYWdlKHBsdWdpbklkKTtcbiAgdGhyb3cgbmV3IEVycm9yKGBQbHVnaW4gXCIke3BsdWdpbklkfVwiIGZhaWxlZCB0byBsb2FkOiAke2RldGFpbH1gKTtcbn1cblxuLyoqXG4gKiBFbmFibGVzIGBhbHdheXNVcGRhdGVMaW5rc2AgaW4gdGhlIG93bmVkIHZhdWx0J3MgYC5vYnNpZGlhbi9hcHAuanNvbmAuXG4gKlxuICogV2l0aG91dCBpdCwgYW55IHJlbmFtZSBvciBtb3ZlIHRoYXQgYWZmZWN0cyBsaW5rcyBtYWtlcyBPYnNpZGlhbidzXG4gKiBgRmlsZU1hbmFnZXIudXBkYXRlQWxsTGlua3NgIHBvcCBhbiBpbnRlcmFjdGl2ZSBcIlVwZGF0ZSBsaW5rcz9cIiBjb25maXJtYXRpb24gbW9kYWxcbiAqIChpdCBvbmx5IHNraXBzIHRoZSBtb2RhbCB3aGVuIGBhbHdheXNVcGRhdGVMaW5rc2AgaXMgb24pLiBIZWFkbGVzcyB0aGVyZSBpcyBubyB1c2VyXG4gKiB0byBhbnN3ZXIgaXQsIHNvIHRoZSBQcm9taXNlIG5ldmVyIHJlc29sdmVzIFx1MjAxNCB0aGUgcmVuYW1lJ3MgaW50ZXJuYWxcbiAqIGBGaWxlTWFuYWdlci51cGRhdGVRdWV1ZWAgdGFzayBoYW5ncyBmb3JldmVyLCBhbmQgYmVjYXVzZSB0aGF0IHF1ZXVlIGlzIGEgc2luZ2xldG9uXG4gKiBldmVyeSBzdWJzZXF1ZW50IGByZW5hbWVGaWxlYCBpbiB0aGUgc2hhcmVkIGluc3RhbmNlIGhhbmdzIHRvbyAodGhlIGxvbmctb2JzZXJ2ZWRcbiAqIFwicmVuYW1lIHdhbGxcIikuIEVuYWJsaW5nIHRoZSBzZXR0aW5nIG1ha2VzIHJlbmFtZXMgdXBkYXRlIGxpbmtzIG5vbi1pbnRlcmFjdGl2ZWx5LFxuICogc28gcmVuYW1lLWRyaXZlbiBpbnRlZ3JhdGlvbiB0ZXN0cyBydW4gaW4gaGVhZGxlc3MgbW9kZS5cbiAqXG4gKiBNZXJnZXMgaW50byBhbnkgZXhpc3RpbmcgYGFwcC5qc29uYCAoZS5nLiBvbmUgY2FycmllZCBpbiB2aWEgYHBvcHVsYXRlYCkgc28gb3RoZXJcbiAqIGNvbmZpZyBrZXlzIGFyZSBwcmVzZXJ2ZWQsIGFuZCBydW5zIGJlZm9yZSBgc3luY1RvRGV2aWNlYCBzbyB0aGUgdmFsdWUgcmVhY2hlc1xuICogbW9iaWxlIGRldmljZXMgdG9vLlxuICpcbiAqIEBwYXJhbSB0ZW1wVmF1bHQgLSBUaGUgb3duZWQgdGVtcCB2YXVsdCB0byBjb25maWd1cmUuXG4gKiBAcGFyYW0gbGFiZWwgLSBUaGUgdHJhbnNwb3J0IGxhYmVsLCBmb3IgbG9nZ2luZy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZW5zdXJlQWx3YXlzVXBkYXRlTGlua3ModGVtcFZhdWx0OiBUZW1wVmF1bHQsIGxhYmVsOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgY29uZmlnRGlyID0gam9pbih0ZW1wVmF1bHQucGF0aCwgT0JTSURJQU5fQ09ORklHX0RJUik7XG4gIGNvbnN0IGFwcEpzb25QYXRoID0gam9pbihjb25maWdEaXIsIEFQUF9KU09OKTtcbiAgbGV0IGFwcENvbmZpZzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgdHJ5IHtcbiAgICBhcHBDb25maWcgPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRGaWxlKGFwcEpzb25QYXRoLCAndXRmLTgnKSkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIH0gY2F0Y2gge1xuICAgIC8vIE5vIGV4aXN0aW5nIGFwcC5qc29uIChvciB1bnJlYWRhYmxlKSBcdTIwMTQgc3RhcnQgZnJvbSBhbiBlbXB0eSBjb25maWcuXG4gIH1cbiAgYXBwQ29uZmlnWydhbHdheXNVcGRhdGVMaW5rcyddID0gdHJ1ZTtcbiAgYXdhaXQgbWtkaXIoY29uZmlnRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgYXdhaXQgd3JpdGVGaWxlKGFwcEpzb25QYXRoLCBKU09OLnN0cmluZ2lmeShhcHBDb25maWcsIG51bGwsIEFQUF9KU09OX0lOREVOVCkpO1xuICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gRW5hYmxlZCBhbHdheXNVcGRhdGVMaW5rcyBpbiAke0FQUF9KU09OfSAoaGVhZGxlc3MgcmVuYW1lIHN1cHBvcnQpLmApO1xufVxuXG4vKipcbiAqIEZpbmRzIHRoZSBwcm9qZWN0IHJvb3QgYnkgd2Fsa2luZyB1cCBmcm9tIGBwcm9jZXNzLmN3ZCgpYCBsb29raW5nIGZvciBgcGFja2FnZS5qc29uYC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgcHJvamVjdCByb290LlxuICovXG5mdW5jdGlvbiBmaW5kUHJvamVjdFJvb3QoKTogc3RyaW5nIHtcbiAgbGV0IGRpciA9IHByb2Nlc3MuY3dkKCk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb24gLS0gTG9vcCB0ZXJtaW5hdGVzIGF0IGZpbGVzeXN0ZW0gcm9vdC5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoZXhpc3RzU3luYyhqb2luKGRpciwgJ3BhY2thZ2UuanNvbicpKSkge1xuICAgICAgcmV0dXJuIGRpcjtcbiAgICB9XG4gICAgY29uc3QgcGFyZW50ID0gam9pbihkaXIsICcuLicpO1xuICAgIGlmIChwYXJlbnQgPT09IGRpcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZmluZCBwcm9qZWN0IHJvb3QgKG5vIHBhY2thZ2UuanNvbiBmb3VuZCkuJyk7XG4gICAgfVxuICAgIGRpciA9IHBhcmVudDtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBjcm9zcy1wcm9jZXNzIGxvY2sgc2NvcGUgZm9yIGEgdHJhbnNwb3J0LCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vXG4gKiBsb2NrIGlzIG5lZWRlZC5cbiAqXG4gKiBEZXNrdG9wIHJ1bnMgdXNlIGhhcm5lc3Mtb3duZWQsIGlzb2xhdGVkIGluc3RhbmNlcyAodGhlaXIgb3duIHVzZXItZGF0YSBkaXJcbiAqIGFuZCBDRFAgcG9ydCksIHNvIHRoZXkgbm8gbG9uZ2VyIGNvbnRlbmQgYW5kIG5lZWQgbm8gbG9jay4gT25seSB0aGUgQW5kcm9pZFxuICogdHJhbnNwb3J0LCB3aGljaCBzaGFyZXMgdGhlIHNpbmdsZSBlbXVsYXRvciBhbmQgQXBwaXVtIHNlcnZlciwgbXVzdCBzZXJpYWxpemUuXG4gKlxuICogQHBhcmFtIHRyYW5zcG9ydE9wdGlvbnMgLSBUaGUgcmVzb2x2ZWQgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcmV0dXJucyBUaGUgbG9jayBzY29wZSBzdHJpbmcsIG9yIGB1bmRlZmluZWRgIGlmIG5vIGxvY2sgaXMgbmVlZGVkLlxuICovXG5mdW5jdGlvbiBnZXRMb2NrU2NvcGUodHJhbnNwb3J0T3B0aW9uczogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHRyYW5zcG9ydE9wdGlvbnM/LnR5cGUgPT09ICdvYnNpZGlhbi1hbmRyb2lkLWFwcGl1bScgPyBBTkRST0lEX0xPQ0tfU0NPUEUgOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIGNsZWFudXAgaGFuZGxlcnMgZm9yIG9ycGhhbmVkIHNldHVwcyB0aGF0IHdlcmUgbmV2ZXIgZXhwbGljaXRseVxuICogdG9ybiBkb3duLlxuICpcbiAqIFR3byBoYW5kbGVycyBjb3ZlciBkaWZmZXJlbnQgZXhpdCBzY2VuYXJpb3M6XG4gKlxuICogLSBgYmVmb3JlRXhpdGAgXHUyMDE0IGZpcmVzIHdoZW4gdGhlIGV2ZW50IGxvb3AgZHJhaW5zIG5hdHVyYWxseS4gQWxsb3dzIGZ1bGxcbiAqICAgYXN5bmMgdGVhcmRvd24gKHVucmVnaXN0ZXIgdmF1bHRzLCBkaXNwb3NlIHRyYW5zcG9ydHMpLiBEb2VzIE5PVCBmaXJlXG4gKiAgIHdoZW4gYHByb2Nlc3MuZXhpdCgpYCBpcyBjYWxsZWQgZGlyZWN0bHkuXG4gKlxuICogLSBgdW5oYW5kbGVkUmVqZWN0aW9uYCBcdTIwMTQgY2F0Y2hlcyBhc3luYyBlcnJvcnMgdGhhdCBieXBhc3MgYGNvcmVTZXR1cGAnc1xuICogICBjYXRjaCBibG9jay4gUGVyZm9ybXMgZnVsbCBhc3luYyB0ZWFyZG93biB3aGlsZSB3ZSBzdGlsbCBjYW4uXG4gKlxuICogLSBgZXhpdGAgXHUyMDE0IGZpcmVzIG9uIGV2ZXJ5IGV4aXQsIGluY2x1ZGluZyBgcHJvY2Vzcy5leGl0KClgLiBPbmx5IHN5bmNocm9ub3VzXG4gKiAgIHdvcmsgaXMgcG9zc2libGUsIHNvIHRoaXMgaGFuZGxlciBkb2VzIGJlc3QtZWZmb3J0IGNsZWFudXA6IGtpbGxzIGNoaWxkXG4gKiAgIHByb2Nlc3NlcyB2aWEgYGRpc3Bvc2VTeW5jKClgIGFuZCByZW1vdmVzIHRlbXAgdmF1bHQgZGlyZWN0b3JpZXMgd2l0aFxuICogICBgcm1TeW5jYC4gVW5yZWdpc3RlcmluZyB2YXVsdHMgKHdoaWNoIHJlcXVpcmVzIElQQyB3aXRoIE9ic2lkaWFuKSBpc1xuICogICBza2lwcGVkIFx1MjAxNCBhIHN0YWxlIHZhdWx0IGVudHJ5IGlzIGFuIGFjY2VwdGFibGUgdHJhZGUtb2ZmIHZzLiBsZWFrZWRcbiAqICAgcHJvY2Vzc2VzIGFuZCB0ZW1wIGRpcmVjdG9yaWVzLlxuICovXG5mdW5jdGlvbiByZWdpc3RlclByb2Nlc3NDbGVhbnVwSGFuZGxlcigpOiB2b2lkIHtcbiAgaWYgKGlzQ2xlYW51cEhhbmRsZXJSZWdpc3RlcmVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlzQ2xlYW51cEhhbmRsZXJSZWdpc3RlcmVkID0gdHJ1ZTtcblxuICBwcm9jZXNzLm9uKCdiZWZvcmVFeGl0JywgKCkgPT4ge1xuICAgIGlmIChhY3RpdmVTZXR1cHMuc2l6ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duXSBQcm9jZXNzIGV4aXRpbmcgd2l0aCAke1N0cmluZyhhY3RpdmVTZXR1cHMuc2l6ZSl9IHNldHVwKHMpIG5vdCB0b3JuIGRvd24uIENsZWFuaW5nIHVwLi4uYCk7XG5cbiAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiBbLi4uYWN0aXZlU2V0dXBzXSkge1xuICAgICAgY29yZVRlYXJkb3duKHJlc3VsdCkuY2F0Y2goKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gUHJvY2VzcyBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICBwcm9jZXNzLm9uKCd1bmhhbmRsZWRSZWplY3Rpb24nLCAoKSA9PiB7XG4gICAgaWYgKGFjdGl2ZVNldHVwcy5zaXplID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd25dIFVuaGFuZGxlZCByZWplY3Rpb24gZGV0ZWN0ZWQuIFRlYXJpbmcgZG93biAke1N0cmluZyhhY3RpdmVTZXR1cHMuc2l6ZSl9IGFjdGl2ZSBzZXR1cChzKS4uLmApO1xuICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIFsuLi5hY3RpdmVTZXR1cHNdKSB7XG4gICAgICBjb3JlVGVhcmRvd24ocmVzdWx0KS5jYXRjaCgoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBSZWplY3Rpb24gY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJvY2Vzcy5vbignZXhpdCcsICgpID0+IHtcbiAgICBpZiAoYWN0aXZlU2V0dXBzLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bl0gU3luYyBjbGVhbnVwOiAke1N0cmluZyhhY3RpdmVTZXR1cHMuc2l6ZSl9IG9ycGhhbmVkIHNldHVwKHMpLmApO1xuICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIFsuLi5hY3RpdmVTZXR1cHNdKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXN1bHQudHJhbnNwb3J0LmRpc3Bvc2VTeW5jPy4oKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gU3luYyB0cmFuc3BvcnQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIHJtU3luYyhyZXN1bHQudGVtcFZhdWx0LnBhdGgsIHsgZm9yY2U6IHRydWUsIHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gU3luYyB2YXVsdCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICAgcmVsZWFzZVNldHVwTG9jayhyZXN1bHQpO1xuICAgIH1cbiAgICBhY3RpdmVTZXR1cHMuY2xlYXIoKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmVsZWFzZXMgYW5kIGZvcmdldHMgdGhlIHNldHVwIGxvY2sgYXNzb2NpYXRlZCB3aXRoIGEgcmVzdWx0LCBpZiBhbnkuXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIFRoZSBzZXR1cCByZXN1bHQgd2hvc2UgbG9jayBzaG91bGQgYmUgcmVsZWFzZWQuXG4gKi9cbmZ1bmN0aW9uIHJlbGVhc2VTZXR1cExvY2socmVzdWx0OiBDb3JlU2V0dXBSZXN1bHQpOiB2b2lkIHtcbiAgY29uc3QgbG9jayA9IHNldHVwTG9ja3MuZ2V0KHJlc3VsdCk7XG4gIGlmIChsb2NrKSB7XG4gICAgbG9jay5yZWxlYXNlKCk7XG4gICAgc2V0dXBMb2Nrcy5kZWxldGUocmVzdWx0KTtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBkaXN0IHBhdGggdG8gdXNlIGZvciBpbnRlZ3JhdGlvbiB0ZXN0cy5cbiAqXG4gKiBQaWNrcyB3aGljaGV2ZXIgb2YgYGRpc3QvZGV2YCBhbmQgYGRpc3QvYnVpbGRgIGhhcyBhIG5ld2VyIGBtYWluLmpzYC5cbiAqIElmIG9ubHkgb25lIGV4aXN0cywgdGhhdCBvbmUgaXMgdXNlZC4gVGhyb3dzIGlmIG5laXRoZXIgZXhpc3RzLlxuICpcbiAqIEBwYXJhbSBwcm9qZWN0Um9vdCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBwcm9qZWN0IHJvb3QuXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgY2hvc2VuIGRpc3QgZm9sZGVyLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlRGlzdFBhdGgocHJvamVjdFJvb3Q6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGRldlBhdGggPSBqb2luKHByb2plY3RSb290LCBESVNUX0RFVik7XG4gIGNvbnN0IGJ1aWxkUGF0aCA9IGpvaW4ocHJvamVjdFJvb3QsIERJU1RfQlVJTEQpO1xuICBjb25zdCBkZXZNYWluSnMgPSBqb2luKGRldlBhdGgsIE1BSU5fSlMpO1xuICBjb25zdCBidWlsZE1haW5KcyA9IGpvaW4oYnVpbGRQYXRoLCBNQUlOX0pTKTtcbiAgY29uc3QgZGV2U3RhdCA9IGV4aXN0c1N5bmMoZGV2TWFpbkpzKSA/IGF3YWl0IHN0YXQoZGV2TWFpbkpzKSA6IG51bGw7XG4gIGNvbnN0IGJ1aWxkU3RhdCA9IGV4aXN0c1N5bmMoYnVpbGRNYWluSnMpID8gYXdhaXQgc3RhdChidWlsZE1haW5KcykgOiBudWxsO1xuXG4gIGlmIChkZXZTdGF0ICYmIGJ1aWxkU3RhdCkge1xuICAgIHJldHVybiBkZXZTdGF0Lm10aW1lID4gYnVpbGRTdGF0Lm10aW1lID8gZGV2UGF0aCA6IGJ1aWxkUGF0aDtcbiAgfVxuXG4gIGlmIChkZXZTdGF0KSB7XG4gICAgcmV0dXJuIGRldlBhdGg7XG4gIH1cblxuICBpZiAoYnVpbGRTdGF0KSB7XG4gICAgcmV0dXJuIGJ1aWxkUGF0aDtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignTm8gYnVpbGQgZm91bmQuIFJ1biBgbnBtIHJ1biBidWlsZGAgb3IgYG5wbSBydW4gZGV2YCBmaXJzdC4nKTtcbn1cblxuLyoqXG4gKiBSZW1vdmVzIHRoZSBob3N0LXNpZGUgdGVtcCBkaXJlY3RvcmllcyBlYXJsaWVyIHJ1bnMgbGVha2VkLlxuICpcbiAqIFJ1bnMgYXQgYm90aCBlbmRzIG9mIGEgcnVuOiBhdCBzZXR1cCBpdCBoYXBwZW5zICoqYmVmb3JlKiogdGhlIHRyYW5zcG9ydCBpc1xuICogY3JlYXRlZCwgc28gaXQgZG9lcyBub3QgZGVwZW5kIG9uIGEgaGVhbHRoeSBPYnNpZGlhbi9XZWJWaWV3IFx1MjAxNCB3aGljaCBpc1xuICogZXhhY3RseSB3aGF0IGEgZmFpbGVkIHJ1biBubyBsb25nZXIgaGFzLCBhbmQgd2h5IGEgZmFpbGVkIHJ1biBjYW5ub3QgY2xlYW4gdXBcbiAqIGFmdGVyIGl0c2VsZi4gQWdlLWdhdGVkIChzZWUgYGxlZnRvdmVyTWF4QWdlSW5NaWxsaXNlY29uZHNgKSBiZWNhdXNlIGRlc2t0b3BcbiAqIHJ1bnMgYXJlIG5vdCBzZXJpYWxpemVkIGFuZCBldmVyeSBwcm9qZWN0IG9uIHRoZSBtYWNoaW5lIHNoYXJlcyBvbmUgdGVtcFxuICogZGlyZWN0b3J5LiBCZXN0LWVmZm9ydDogYSBzd2VlcCBuZXZlciBmYWlscyB0aGUgcnVuIGl0IGlzIGNsZWFuaW5nIHVwIGZvci5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHN3ZWVwIHBhcmFtZXRlcnMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN3ZWVwTGVmdG92ZXJzKHBhcmFtczogU3dlZXBMZWZ0b3ZlcnNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcGhhc2UsIHRyYW5zcG9ydE9wdGlvbnMgfSA9IHBhcmFtcztcbiAgaWYgKCFyZXNvbHZlU2hvdWxkU3dlZXBMZWZ0b3ZlcnModHJhbnNwb3J0T3B0aW9ucykpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN3ZWVwSG9zdExlZnRvdmVycyh7XG4gICAgICBleGNsdWRlZE5hbWVzOiBwYXJhbXMuZXhjbHVkZWROYW1lcyxcbiAgICAgIG1heEFnZUluTWlsbGlzZWNvbmRzOiByZXNvbHZlTGVmdG92ZXJNYXhBZ2VJbk1pbGxpc2Vjb25kcyh0cmFuc3BvcnRPcHRpb25zKVxuICAgIH0pO1xuICAgIGlmIChyZXN1bHQucmVtb3ZlZENvdW50ID4gMCB8fCByZXN1bHQuZmFpbGVkQ291bnQgPiAwKSB7XG4gICAgICBsb2coXG4gICAgICAgIGBbaW50ZWdyYXRpb24tJHtwaGFzZX06JHtsYWJlbH1dIFN3ZXB0ICR7U3RyaW5nKHJlc3VsdC5yZW1vdmVkQ291bnQpfSBsZWZ0b3ZlciB0ZW1wIGRpcmVjdG9yKGllcykgYFxuICAgICAgICAgICsgYGZyb20gZWFybGllciBydW5zICgke1N0cmluZyhyZXN1bHQuZmFpbGVkQ291bnQpfSBzdGlsbCBpbiB1c2UpLmBcbiAgICAgICk7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLSR7cGhhc2V9OiR7bGFiZWx9XSBMZWZ0b3ZlciBzd2VlcCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfVxufVxuXG4vKipcbiAqIFBlcmZvcm1zIHRoZSBhc3luYyB0ZWFyZG93biB3b3JrICh2YXVsdCBkaXNwb3NhbCArIHRyYW5zcG9ydCBkaXNwb3NhbCkuXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIFRoZSBzZXR1cCByZXN1bHQgdG8gdGVhciBkb3duLlxuICovXG5hc3luYyBmdW5jdGlvbiB0ZWFyZG93bkFzeW5jKHJlc3VsdDogQ29yZVNldHVwUmVzdWx0KTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgcmVzdWx0LnRlbXBWYXVsdC5kaXNwb3NlKHJlc3VsdC50cmFuc3BvcnQpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gVmF1bHQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgYXdhaXQgcmVzdWx0LnRyYW5zcG9ydC5kaXNwb3NlPy4oKTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIFRyYW5zcG9ydCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFZQSxxQkFHTztBQUNQLHNCQU1PO0FBQ1AsdUJBR087QUFDUCwwQkFBcUM7QUFDckMsSUFBQUEsbUJBQW9DO0FBUXBDLDJCQUdPO0FBQ1AsNkJBQThCO0FBQzlCLDhCQUErQjtBQUMvQiw4QkFJTztBQUNQLGlCQUFvQjtBQUNwQixpQ0FLTztBQUNQLHdCQUFpQztBQUNqQyx3QkFBMEI7QUFDMUIsOEJBQWdDO0FB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