obsidian-dev-utils 97.0.0 → 98.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +1 -1
  3. package/dist/integration-test-plugin/main.js +624 -483
  4. package/dist/lib/cjs/__merged.cjs +14 -9
  5. package/dist/lib/cjs/__merged.d.cts +2 -1
  6. package/dist/lib/cjs/generated-during-build.cjs +1 -1
  7. package/dist/lib/cjs/obsidian/components/rename-delete-handler-component.cjs +38 -38
  8. package/dist/lib/cjs/obsidian/demo-vault-naming.cjs +167 -0
  9. package/dist/lib/cjs/obsidian/demo-vault-naming.d.cts +54 -0
  10. package/dist/lib/cjs/obsidian/desktop-demo-vault-opener.cjs +11 -5
  11. package/dist/lib/cjs/obsidian/desktop-demo-vault-opener.d.cts +10 -8
  12. package/dist/lib/cjs/obsidian/desktop-trusted-input.cjs +9 -9
  13. package/dist/lib/cjs/obsidian/desktop-trusted-input.d.cts +23 -4
  14. package/dist/lib/cjs/obsidian/index.cjs +10 -1
  15. package/dist/lib/cjs/obsidian/index.d.cts +3 -0
  16. package/dist/lib/cjs/obsidian/mobile-trusted-input.cjs +195 -0
  17. package/dist/lib/cjs/obsidian/mobile-trusted-input.d.cts +93 -0
  18. package/dist/lib/cjs/obsidian/plugin/obsidian-plugin-repo-paths.cjs +2 -1
  19. package/dist/lib/cjs/obsidian/plugin/obsidian-plugin-repo-paths.d.cts +4 -0
  20. package/dist/lib/cjs/obsidian/resource-lock.cjs +122 -122
  21. package/dist/lib/cjs/obsidian/trusted-input.cjs +206 -0
  22. package/dist/lib/cjs/obsidian/trusted-input.d.cts +126 -0
  23. package/dist/lib/cjs/script-utils/build.cjs +30 -6
  24. package/dist/lib/cjs/script-utils/build.d.cts +5 -0
  25. package/dist/lib/cjs/script-utils/demo-vault.cjs +26 -6
  26. package/dist/lib/cjs/script-utils/demo-vault.d.cts +12 -8
  27. package/dist/lib/cjs/script-utils/exec.cjs +1 -1
  28. package/dist/lib/cjs/script-utils/formatters/dprint.cjs +3 -2
  29. package/dist/lib/cjs/script-utils/index.cjs +4 -1
  30. package/dist/lib/cjs/script-utils/index.d.cts +1 -0
  31. package/dist/lib/cjs/script-utils/linters/cspell.cjs +3 -3
  32. package/dist/lib/cjs/script-utils/linters/eslint-config.cjs +39 -1
  33. package/dist/lib/cjs/script-utils/linters/eslint-rules/index.cjs +16 -1
  34. package/dist/lib/cjs/script-utils/linters/eslint-rules/index.d.cts +5 -0
  35. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-description.cjs +254 -0
  36. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-description.d.cts +54 -0
  37. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-helpers.cjs +217 -0
  38. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-helpers.d.cts +141 -0
  39. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-id.cjs +214 -0
  40. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-id.d.cts +32 -0
  41. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-name.cjs +215 -0
  42. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-name.d.cts +30 -0
  43. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-schema.cjs +318 -0
  44. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-schema.d.cts +45 -0
  45. package/dist/lib/cjs/script-utils/linters/eslint-rules/obsidian-dev-utils-plugin.cjs +9 -1
  46. package/dist/lib/cjs/script-utils/linters/eslint.cjs +3 -2
  47. package/dist/lib/cjs/script-utils/linters/markdownlint.cjs +4 -4
  48. package/dist/lib/cjs/script-utils/npm-run.cjs +4 -3
  49. package/dist/lib/cjs/script-utils/obsidian-dev-utils-repo-paths.cjs +10 -1
  50. package/dist/lib/cjs/script-utils/obsidian-dev-utils-repo-paths.d.cts +37 -1
  51. package/dist/lib/cjs/script-utils/package-manager.cjs +287 -0
  52. package/dist/lib/cjs/script-utils/package-manager.d.cts +77 -0
  53. package/dist/lib/cjs/script-utils/version.cjs +21 -9
  54. package/dist/lib/esm/__merged.d.mts +2 -1
  55. package/dist/lib/esm/__merged.mjs +16 -10
  56. package/dist/lib/esm/generated-during-build.mjs +1 -1
  57. package/dist/lib/esm/obsidian/components/rename-delete-handler-component.mjs +38 -38
  58. package/dist/lib/esm/obsidian/demo-vault-naming.d.mts +54 -0
  59. package/dist/lib/esm/obsidian/demo-vault-naming.mjs +61 -0
  60. package/dist/lib/esm/obsidian/desktop-demo-vault-opener.d.mts +10 -8
  61. package/dist/lib/esm/obsidian/desktop-demo-vault-opener.mjs +14 -5
  62. package/dist/lib/esm/obsidian/desktop-trusted-input.d.mts +23 -4
  63. package/dist/lib/esm/obsidian/desktop-trusted-input.mjs +9 -9
  64. package/dist/lib/esm/obsidian/index.d.mts +3 -0
  65. package/dist/lib/esm/obsidian/index.mjs +7 -1
  66. package/dist/lib/esm/obsidian/mobile-trusted-input.d.mts +93 -0
  67. package/dist/lib/esm/obsidian/mobile-trusted-input.mjs +84 -0
  68. package/dist/lib/esm/obsidian/plugin/obsidian-plugin-repo-paths.d.mts +4 -0
  69. package/dist/lib/esm/obsidian/plugin/obsidian-plugin-repo-paths.mjs +2 -1
  70. package/dist/lib/esm/obsidian/resource-lock.mjs +122 -122
  71. package/dist/lib/esm/obsidian/trusted-input.d.mts +126 -0
  72. package/dist/lib/esm/obsidian/trusted-input.mjs +85 -0
  73. package/dist/lib/esm/script-utils/build.d.mts +5 -0
  74. package/dist/lib/esm/script-utils/build.mjs +30 -6
  75. package/dist/lib/esm/script-utils/demo-vault.d.mts +12 -8
  76. package/dist/lib/esm/script-utils/demo-vault.mjs +29 -6
  77. package/dist/lib/esm/script-utils/exec.mjs +1 -1
  78. package/dist/lib/esm/script-utils/formatters/dprint.mjs +3 -2
  79. package/dist/lib/esm/script-utils/index.d.mts +1 -0
  80. package/dist/lib/esm/script-utils/index.mjs +3 -1
  81. package/dist/lib/esm/script-utils/linters/cspell.mjs +3 -3
  82. package/dist/lib/esm/script-utils/linters/eslint-config.mjs +39 -1
  83. package/dist/lib/esm/script-utils/linters/eslint-rules/index.d.mts +5 -0
  84. package/dist/lib/esm/script-utils/linters/eslint-rules/index.mjs +11 -1
  85. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-description.d.mts +54 -0
  86. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-description.mjs +148 -0
  87. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-helpers.d.mts +141 -0
  88. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-helpers.mjs +92 -0
  89. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-id.d.mts +32 -0
  90. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-id.mjs +111 -0
  91. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-name.d.mts +30 -0
  92. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-name.mjs +112 -0
  93. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-schema.d.mts +45 -0
  94. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-schema.mjs +217 -0
  95. package/dist/lib/esm/script-utils/linters/eslint-rules/obsidian-dev-utils-plugin.mjs +9 -1
  96. package/dist/lib/esm/script-utils/linters/eslint.mjs +3 -2
  97. package/dist/lib/esm/script-utils/linters/markdownlint.mjs +4 -4
  98. package/dist/lib/esm/script-utils/npm-run.mjs +4 -3
  99. package/dist/lib/esm/script-utils/obsidian-dev-utils-repo-paths.d.mts +37 -1
  100. package/dist/lib/esm/script-utils/obsidian-dev-utils-repo-paths.mjs +10 -1
  101. package/dist/lib/esm/script-utils/package-manager.d.mts +77 -0
  102. package/dist/lib/esm/script-utils/package-manager.mjs +173 -0
  103. package/dist/lib/esm/script-utils/version.mjs +21 -9
  104. package/obsidian/demo-vault-naming/package.json +6 -0
  105. package/obsidian/mobile-trusted-input/package.json +6 -0
  106. package/obsidian/trusted-input/package.json +6 -0
  107. package/package.json +19 -17
  108. package/script-utils/linters/eslint-rules/manifest-description/package.json +6 -0
  109. package/script-utils/linters/eslint-rules/manifest-helpers/package.json +6 -0
  110. package/script-utils/linters/eslint-rules/manifest-id/package.json +6 -0
  111. package/script-utils/linters/eslint-rules/manifest-name/package.json +6 -0
  112. package/script-utils/linters/eslint-rules/manifest-schema/package.json +6 -0
  113. package/script-utils/package-manager/package.json +6 -0
@@ -0,0 +1,126 @@
1
+ /// <reference path="../library.d.mts" />
2
+ /**
3
+ * @file
4
+ *
5
+ * Trusted input helpers that work on **either platform** — the documented entry point for keystrokes,
6
+ * pointer moves and clicks that Obsidian actually believes.
7
+ *
8
+ * Untrusted input (`element.dispatchEvent(new MouseEvent('click'))`) is silently ignored by CodeMirror,
9
+ * by the CSS `:hover` engine and by every `e.isTrusted` guard in Obsidian, so a test driving it exercises
10
+ * nothing while still passing. A trusted event has to come from outside the renderer, and how it gets
11
+ * there is platform-specific: Electron's `webContents.sendInputEvent` on desktop, a CDP injection
12
+ * round-tripped through the harness's host channel on mobile.
13
+ *
14
+ * This module **internalizes that split** (see the project `AGENTS.md` **L6**): it stays
15
+ * cross-platform-loadable — no platform-only module is on its import graph — and each helper defers to a
16
+ * `Platform`-gated call-time dynamic `import()` of the arm that fits. So a consumer writes
17
+ * `await clickElement({ element })` once and never a platform check.
18
+ *
19
+ * The arms remain importable directly, for a caller making a deliberate platform commitment:
20
+ * {@link ./desktop-trusted-input.ts | desktop-trusted-input} and
21
+ * {@link ./mobile-trusted-input.ts | mobile-trusted-input}. Prefer this facade otherwise.
22
+ *
23
+ * **Every helper must be awaited.** The desktop arm has nothing to wait for, but the mobile arm's
24
+ * injection is a round-trip to the host, so a missing `await` lets the assertion run before the input has
25
+ * landed. The signature is the same on both platforms precisely so that a suite growing a mobile lane
26
+ * does not have to be rewritten.
27
+ *
28
+ * **Not every helper survives the port.** `moveMouse`, `hoverElement` and `unhoverElement` **throw** on
29
+ * mobile: a touch screen has no persistent pointer and `:hover` has no touch equivalent. They throw
30
+ * rather than no-op, because a silent no-op is exactly the false confidence trusted input exists to end.
31
+ * Gate those on `Platform.isDesktopApp`, or drive the element with {@link clickElement} instead.
32
+ */
33
+ import type { ClickElementParams, ClickMouseParams, HoverElementParams, MoveMouseParams, PressKeyParams, TypeIntoEditorParams, UnhoverElementParams } from './desktop-trusted-input.mjs';
34
+ export type { ClickElementParams, ClickMouseParams, HoverElementParams, MouseButton, MoveMouseParams, PressKeyParams, TypeIntoEditorParams, UnhoverElementParams } from './desktop-trusted-input.mjs';
35
+ /**
36
+ * Clicks the center of an element using **trusted** input — Electron's `sendInputEvent` on desktop, a CDP
37
+ * touch tap in the WebView on mobile.
38
+ *
39
+ * The element-relative counterpart of {@link clickMouse}, mirroring the {@link moveMouse} /
40
+ * {@link hoverElement} split. Use {@link clickMouse} directly when the point to click is **not** the
41
+ * element's center — the markdown editor's margin, for instance, lies inside `cm.scrollDOM` but outside
42
+ * `.cm-sizer`, so no element's center lands on it.
43
+ *
44
+ * @param params - The element to click, the button to press and any modifiers to hold.
45
+ * @returns A {@link Promise} that resolves once the click has been injected.
46
+ */
47
+ export declare function clickElement(params: ClickElementParams): Promise<void>;
48
+ /**
49
+ * Clicks at the given viewport coordinates using **trusted** input, so the renderer synthesizes a real
50
+ * `click` (or `contextmenu`, for the right button) with `isTrusted === true`.
51
+ *
52
+ * The low-level primitive: one click at one point, with no waiting for any effect — callers poll their own
53
+ * readiness signal. Prefer {@link clickElement} for element-relative clicks.
54
+ *
55
+ * A real context menu actually opens, so a suite driving a right click must close it (or remove the
56
+ * leftover `.menu` element) before the next test.
57
+ *
58
+ * **On mobile the button model does not survive the port**: touch has no buttons, so `'left'` (the
59
+ * default) is a **tap**, `'right'` is the **long-press** that opens Obsidian Mobile's context menu, and
60
+ * `'middle'` throws.
61
+ *
62
+ * @param params - The viewport coordinates to click at, the button to press and any modifiers to hold.
63
+ * @returns A {@link Promise} that resolves once the click has been injected.
64
+ */
65
+ export declare function clickMouse(params: ClickMouseParams): Promise<void>;
66
+ /**
67
+ * Moves the pointer to the center of an element using **trusted** pointer input, then polls until the
68
+ * element actually matches `:hover`.
69
+ *
70
+ * **Desktop only** — it throws on mobile, where `:hover` has no touch equivalent.
71
+ *
72
+ * @param params - The element to hover.
73
+ * @returns A {@link Promise} that resolves once the element matches `:hover`.
74
+ */
75
+ export declare function hoverElement(params: HoverElementParams): Promise<void>;
76
+ /**
77
+ * Moves the pointer to the given viewport coordinates using a **trusted** pointer move, so `:hover` rules
78
+ * genuinely apply.
79
+ *
80
+ * The low-level primitive: a single move that does **not** wait for any state to settle. Prefer
81
+ * {@link hoverElement} / {@link unhoverElement} for element-relative moves.
82
+ *
83
+ * **Desktop only** — it throws on mobile, which has no persistent pointer to move.
84
+ *
85
+ * @param params - The viewport coordinates to move to.
86
+ * @returns A {@link Promise} that resolves once the move has been injected.
87
+ */
88
+ export declare function moveMouse(params: MoveMouseParams): Promise<void>;
89
+ /**
90
+ * Presses a single key (optionally with modifiers) using **trusted** keyboard input, firing the full real
91
+ * key pipeline — `keydown` → `keypress` → `beforeinput` → `input` → `keyup`.
92
+ *
93
+ * It is delivered to the window's DOM-focused element, so the caller focuses the target first and then
94
+ * awaits the expected effect; the press itself polls for nothing. On mobile the accepted keys are the
95
+ * named ones (`'Enter'`, `'Escape'`, `'Tab'`, `'Backspace'`, `'Delete'`, the arrows) plus single printable
96
+ * characters — anything else throws rather than pressing nothing.
97
+ *
98
+ * @param params - The key to press and any modifiers to hold.
99
+ * @returns A {@link Promise} that resolves once the key press has been injected.
100
+ */
101
+ export declare function pressKey(params: PressKeyParams): Promise<void>;
102
+ /**
103
+ * Types text into a CodeMirror editor using **trusted** keyboard input.
104
+ *
105
+ * Focuses the editor (caret to the end) and presses every code point of the text — the same trusted
106
+ * sequence a real user produces — so the text reaches the document **only if the editor genuinely holds
107
+ * focus**. Then it polls until the document reflects the input, or a bounded timeout elapses (the expected
108
+ * outcome when the editor is read-only or focus was stolen).
109
+ *
110
+ * @param params - The editor to type into and the text to type.
111
+ * @returns A {@link Promise} that resolves once the keystrokes have settled.
112
+ */
113
+ export declare function typeIntoEditor(params: TypeIntoEditorParams): Promise<void>;
114
+ /**
115
+ * Moves the pointer to a point just outside an element's bounding box using a **trusted** pointer move,
116
+ * then polls until the element no longer matches `:hover`.
117
+ *
118
+ * The inverse of {@link hoverElement}. When an element spans the full viewport (no point outside its box
119
+ * is reachable), use {@link moveMouse} directly to move the pointer to a known empty coordinate instead.
120
+ *
121
+ * **Desktop only** — it throws on mobile, for the same reason {@link hoverElement} does.
122
+ *
123
+ * @param params - The element to move the pointer away from.
124
+ * @returns A {@link Promise} that resolves once the element no longer matches `:hover`.
125
+ */
126
+ export declare function unhoverElement(params: UnhoverElementParams): Promise<void>;
@@ -0,0 +1,85 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+
6
+ (function () {
7
+ function ensureBrowserProcess() {
8
+ const browserProcess = {
9
+ browser: true,
10
+ cwd() {
11
+ return '/';
12
+ },
13
+ env: {},
14
+ platform: 'android'
15
+ };
16
+
17
+ // eslint-disable-next-line obsidianmd/no-global-this, unicorn/no-unnecessary-global-this -- Must stay `globalThis`-qualified: in the emitted banner a bare `process` is a free identifier, so reading it where the host has none throws a ReferenceError instead of yielding `undefined`. That is the very case this function exists to handle.
18
+ const existingProcess = globalThis.process;
19
+
20
+ if (!existingProcess) {
21
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
22
+ globalThis.process = browserProcess;
23
+ return;
24
+ }
25
+
26
+ if (existingProcess.versions?.node) {
27
+ return;
28
+ }
29
+
30
+ const existingProcessRecord = existingProcess;
31
+
32
+ for (const [key, value] of Object.entries(browserProcess)) {
33
+ existingProcessRecord[key] ??= value;
34
+ }
35
+
36
+ existingProcessRecord['browser'] = true;
37
+ }
38
+
39
+ (function initEsm() {
40
+ ensureBrowserProcess();
41
+ })();
42
+ })();
43
+
44
+ import { Platform } from "obsidian";
45
+ async function clickElement(params) {
46
+ const arm = await loadArm();
47
+ await arm.clickElement(params);
48
+ }
49
+ async function clickMouse(params) {
50
+ const arm = await loadArm();
51
+ await arm.clickMouse(params);
52
+ }
53
+ async function hoverElement(params) {
54
+ const arm = await loadArm();
55
+ await arm.hoverElement(params);
56
+ }
57
+ async function moveMouse(params) {
58
+ const arm = await loadArm();
59
+ await arm.moveMouse(params);
60
+ }
61
+ async function pressKey(params) {
62
+ const arm = await loadArm();
63
+ await arm.pressKey(params);
64
+ }
65
+ async function typeIntoEditor(params) {
66
+ const arm = await loadArm();
67
+ await arm.typeIntoEditor(params);
68
+ }
69
+ async function unhoverElement(params) {
70
+ const arm = await loadArm();
71
+ await arm.unhoverElement(params);
72
+ }
73
+ async function loadArm() {
74
+ return Platform.isDesktopApp ? await import("./desktop-trusted-input.mjs") : await import("./mobile-trusted-input.mjs");
75
+ }
76
+ export {
77
+ clickElement,
78
+ clickMouse,
79
+ hoverElement,
80
+ moveMouse,
81
+ pressKey,
82
+ typeIntoEditor,
83
+ unhoverElement
84
+ };
85
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL3RydXN0ZWQtaW5wdXQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBUcnVzdGVkIGlucHV0IGhlbHBlcnMgdGhhdCB3b3JrIG9uICoqZWl0aGVyIHBsYXRmb3JtKiogXHUyMDE0IHRoZSBkb2N1bWVudGVkIGVudHJ5IHBvaW50IGZvciBrZXlzdHJva2VzLFxuICogcG9pbnRlciBtb3ZlcyBhbmQgY2xpY2tzIHRoYXQgT2JzaWRpYW4gYWN0dWFsbHkgYmVsaWV2ZXMuXG4gKlxuICogVW50cnVzdGVkIGlucHV0IChgZWxlbWVudC5kaXNwYXRjaEV2ZW50KG5ldyBNb3VzZUV2ZW50KCdjbGljaycpKWApIGlzIHNpbGVudGx5IGlnbm9yZWQgYnkgQ29kZU1pcnJvcixcbiAqIGJ5IHRoZSBDU1MgYDpob3ZlcmAgZW5naW5lIGFuZCBieSBldmVyeSBgZS5pc1RydXN0ZWRgIGd1YXJkIGluIE9ic2lkaWFuLCBzbyBhIHRlc3QgZHJpdmluZyBpdCBleGVyY2lzZXNcbiAqIG5vdGhpbmcgd2hpbGUgc3RpbGwgcGFzc2luZy4gQSB0cnVzdGVkIGV2ZW50IGhhcyB0byBjb21lIGZyb20gb3V0c2lkZSB0aGUgcmVuZGVyZXIsIGFuZCBob3cgaXQgZ2V0c1xuICogdGhlcmUgaXMgcGxhdGZvcm0tc3BlY2lmaWM6IEVsZWN0cm9uJ3MgYHdlYkNvbnRlbnRzLnNlbmRJbnB1dEV2ZW50YCBvbiBkZXNrdG9wLCBhIENEUCBpbmplY3Rpb25cbiAqIHJvdW5kLXRyaXBwZWQgdGhyb3VnaCB0aGUgaGFybmVzcydzIGhvc3QgY2hhbm5lbCBvbiBtb2JpbGUuXG4gKlxuICogVGhpcyBtb2R1bGUgKippbnRlcm5hbGl6ZXMgdGhhdCBzcGxpdCoqIChzZWUgdGhlIHByb2plY3QgYEFHRU5UUy5tZGAgKipMNioqKTogaXQgc3RheXNcbiAqIGNyb3NzLXBsYXRmb3JtLWxvYWRhYmxlIFx1MjAxNCBubyBwbGF0Zm9ybS1vbmx5IG1vZHVsZSBpcyBvbiBpdHMgaW1wb3J0IGdyYXBoIFx1MjAxNCBhbmQgZWFjaCBoZWxwZXIgZGVmZXJzIHRvIGFcbiAqIGBQbGF0Zm9ybWAtZ2F0ZWQgY2FsbC10aW1lIGR5bmFtaWMgYGltcG9ydCgpYCBvZiB0aGUgYXJtIHRoYXQgZml0cy4gU28gYSBjb25zdW1lciB3cml0ZXNcbiAqIGBhd2FpdCBjbGlja0VsZW1lbnQoeyBlbGVtZW50IH0pYCBvbmNlIGFuZCBuZXZlciBhIHBsYXRmb3JtIGNoZWNrLlxuICpcbiAqIFRoZSBhcm1zIHJlbWFpbiBpbXBvcnRhYmxlIGRpcmVjdGx5LCBmb3IgYSBjYWxsZXIgbWFraW5nIGEgZGVsaWJlcmF0ZSBwbGF0Zm9ybSBjb21taXRtZW50OlxuICoge0BsaW5rIC4vZGVza3RvcC10cnVzdGVkLWlucHV0LnRzIHwgZGVza3RvcC10cnVzdGVkLWlucHV0fSBhbmRcbiAqIHtAbGluayAuL21vYmlsZS10cnVzdGVkLWlucHV0LnRzIHwgbW9iaWxlLXRydXN0ZWQtaW5wdXR9LiBQcmVmZXIgdGhpcyBmYWNhZGUgb3RoZXJ3aXNlLlxuICpcbiAqICoqRXZlcnkgaGVscGVyIG11c3QgYmUgYXdhaXRlZC4qKiBUaGUgZGVza3RvcCBhcm0gaGFzIG5vdGhpbmcgdG8gd2FpdCBmb3IsIGJ1dCB0aGUgbW9iaWxlIGFybSdzXG4gKiBpbmplY3Rpb24gaXMgYSByb3VuZC10cmlwIHRvIHRoZSBob3N0LCBzbyBhIG1pc3NpbmcgYGF3YWl0YCBsZXRzIHRoZSBhc3NlcnRpb24gcnVuIGJlZm9yZSB0aGUgaW5wdXQgaGFzXG4gKiBsYW5kZWQuIFRoZSBzaWduYXR1cmUgaXMgdGhlIHNhbWUgb24gYm90aCBwbGF0Zm9ybXMgcHJlY2lzZWx5IHNvIHRoYXQgYSBzdWl0ZSBncm93aW5nIGEgbW9iaWxlIGxhbmVcbiAqIGRvZXMgbm90IGhhdmUgdG8gYmUgcmV3cml0dGVuLlxuICpcbiAqICoqTm90IGV2ZXJ5IGhlbHBlciBzdXJ2aXZlcyB0aGUgcG9ydC4qKiBgbW92ZU1vdXNlYCwgYGhvdmVyRWxlbWVudGAgYW5kIGB1bmhvdmVyRWxlbWVudGAgKip0aHJvdyoqIG9uXG4gKiBtb2JpbGU6IGEgdG91Y2ggc2NyZWVuIGhhcyBubyBwZXJzaXN0ZW50IHBvaW50ZXIgYW5kIGA6aG92ZXJgIGhhcyBubyB0b3VjaCBlcXVpdmFsZW50LiBUaGV5IHRocm93XG4gKiByYXRoZXIgdGhhbiBuby1vcCwgYmVjYXVzZSBhIHNpbGVudCBuby1vcCBpcyBleGFjdGx5IHRoZSBmYWxzZSBjb25maWRlbmNlIHRydXN0ZWQgaW5wdXQgZXhpc3RzIHRvIGVuZC5cbiAqIEdhdGUgdGhvc2Ugb24gYFBsYXRmb3JtLmlzRGVza3RvcEFwcGAsIG9yIGRyaXZlIHRoZSBlbGVtZW50IHdpdGgge0BsaW5rIGNsaWNrRWxlbWVudH0gaW5zdGVhZC5cbiAqL1xuXG5pbXBvcnQgeyBQbGF0Zm9ybSB9IGZyb20gJ29ic2lkaWFuJztcblxuaW1wb3J0IHR5cGUge1xuICBDbGlja0VsZW1lbnRQYXJhbXMsXG4gIENsaWNrTW91c2VQYXJhbXMsXG4gIEhvdmVyRWxlbWVudFBhcmFtcyxcbiAgTW92ZU1vdXNlUGFyYW1zLFxuICBQcmVzc0tleVBhcmFtcyxcbiAgVHlwZUludG9FZGl0b3JQYXJhbXMsXG4gIFVuaG92ZXJFbGVtZW50UGFyYW1zXG59IGZyb20gJy4vZGVza3RvcC10cnVzdGVkLWlucHV0LnRzJztcblxuZXhwb3J0IHR5cGUge1xuICBDbGlja0VsZW1lbnRQYXJhbXMsXG4gIENsaWNrTW91c2VQYXJhbXMsXG4gIEhvdmVyRWxlbWVudFBhcmFtcyxcbiAgTW91c2VCdXR0b24sXG4gIE1vdmVNb3VzZVBhcmFtcyxcbiAgUHJlc3NLZXlQYXJhbXMsXG4gIFR5cGVJbnRvRWRpdG9yUGFyYW1zLFxuICBVbmhvdmVyRWxlbWVudFBhcmFtc1xufSBmcm9tICcuL2Rlc2t0b3AtdHJ1c3RlZC1pbnB1dC50cyc7XG5cbi8vIFRoZSBzZXZlbiBoZWxwZXJzIGJvdGggYXJtcyBleHBvcnQsIHdpdGggaWRlbnRpY2FsIHNpZ25hdHVyZXMuIFR5cGVkIG9mZiB0aGUgbW9iaWxlIGFybSBiZWNhdXNlIGl0XG4vLyBFeHBvcnRzIG5vdGhpbmcgZWxzZTsgdGhlIGRlc2t0b3AgYXJtIGFkZGl0aW9uYWxseSBleHBvcnRzIHRoZSBwYXJhbWV0ZXIgY29udHJhY3RzIGJvdGggc2hhcmUuXG50eXBlIFRydXN0ZWRJbnB1dEFybSA9IHR5cGVvZiBpbXBvcnQoJy4vbW9iaWxlLXRydXN0ZWQtaW5wdXQudHMnKTtcblxuLyoqXG4gKiBDbGlja3MgdGhlIGNlbnRlciBvZiBhbiBlbGVtZW50IHVzaW5nICoqdHJ1c3RlZCoqIGlucHV0IFx1MjAxNCBFbGVjdHJvbidzIGBzZW5kSW5wdXRFdmVudGAgb24gZGVza3RvcCwgYSBDRFBcbiAqIHRvdWNoIHRhcCBpbiB0aGUgV2ViVmlldyBvbiBtb2JpbGUuXG4gKlxuICogVGhlIGVsZW1lbnQtcmVsYXRpdmUgY291bnRlcnBhcnQgb2Yge0BsaW5rIGNsaWNrTW91c2V9LCBtaXJyb3JpbmcgdGhlIHtAbGluayBtb3ZlTW91c2V9IC9cbiAqIHtAbGluayBob3ZlckVsZW1lbnR9IHNwbGl0LiBVc2Uge0BsaW5rIGNsaWNrTW91c2V9IGRpcmVjdGx5IHdoZW4gdGhlIHBvaW50IHRvIGNsaWNrIGlzICoqbm90KiogdGhlXG4gKiBlbGVtZW50J3MgY2VudGVyIFx1MjAxNCB0aGUgbWFya2Rvd24gZWRpdG9yJ3MgbWFyZ2luLCBmb3IgaW5zdGFuY2UsIGxpZXMgaW5zaWRlIGBjbS5zY3JvbGxET01gIGJ1dCBvdXRzaWRlXG4gKiBgLmNtLXNpemVyYCwgc28gbm8gZWxlbWVudCdzIGNlbnRlciBsYW5kcyBvbiBpdC5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGVsZW1lbnQgdG8gY2xpY2ssIHRoZSBidXR0b24gdG8gcHJlc3MgYW5kIGFueSBtb2RpZmllcnMgdG8gaG9sZC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgY2xpY2sgaGFzIGJlZW4gaW5qZWN0ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGlja0VsZW1lbnQocGFyYW1zOiBDbGlja0VsZW1lbnRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgYXJtID0gYXdhaXQgbG9hZEFybSgpO1xuICBhd2FpdCBhcm0uY2xpY2tFbGVtZW50KHBhcmFtcyk7XG59XG5cbi8qKlxuICogQ2xpY2tzIGF0IHRoZSBnaXZlbiB2aWV3cG9ydCBjb29yZGluYXRlcyB1c2luZyAqKnRydXN0ZWQqKiBpbnB1dCwgc28gdGhlIHJlbmRlcmVyIHN5bnRoZXNpemVzIGEgcmVhbFxuICogYGNsaWNrYCAob3IgYGNvbnRleHRtZW51YCwgZm9yIHRoZSByaWdodCBidXR0b24pIHdpdGggYGlzVHJ1c3RlZCA9PT0gdHJ1ZWAuXG4gKlxuICogVGhlIGxvdy1sZXZlbCBwcmltaXRpdmU6IG9uZSBjbGljayBhdCBvbmUgcG9pbnQsIHdpdGggbm8gd2FpdGluZyBmb3IgYW55IGVmZmVjdCBcdTIwMTQgY2FsbGVycyBwb2xsIHRoZWlyIG93blxuICogcmVhZGluZXNzIHNpZ25hbC4gUHJlZmVyIHtAbGluayBjbGlja0VsZW1lbnR9IGZvciBlbGVtZW50LXJlbGF0aXZlIGNsaWNrcy5cbiAqXG4gKiBBIHJlYWwgY29udGV4dCBtZW51IGFjdHVhbGx5IG9wZW5zLCBzbyBhIHN1aXRlIGRyaXZpbmcgYSByaWdodCBjbGljayBtdXN0IGNsb3NlIGl0IChvciByZW1vdmUgdGhlXG4gKiBsZWZ0b3ZlciBgLm1lbnVgIGVsZW1lbnQpIGJlZm9yZSB0aGUgbmV4dCB0ZXN0LlxuICpcbiAqICoqT24gbW9iaWxlIHRoZSBidXR0b24gbW9kZWwgZG9lcyBub3Qgc3Vydml2ZSB0aGUgcG9ydCoqOiB0b3VjaCBoYXMgbm8gYnV0dG9ucywgc28gYCdsZWZ0J2AgKHRoZVxuICogZGVmYXVsdCkgaXMgYSAqKnRhcCoqLCBgJ3JpZ2h0J2AgaXMgdGhlICoqbG9uZy1wcmVzcyoqIHRoYXQgb3BlbnMgT2JzaWRpYW4gTW9iaWxlJ3MgY29udGV4dCBtZW51LCBhbmRcbiAqIGAnbWlkZGxlJ2AgdGhyb3dzLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgdmlld3BvcnQgY29vcmRpbmF0ZXMgdG8gY2xpY2sgYXQsIHRoZSBidXR0b24gdG8gcHJlc3MgYW5kIGFueSBtb2RpZmllcnMgdG8gaG9sZC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgY2xpY2sgaGFzIGJlZW4gaW5qZWN0ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGlja01vdXNlKHBhcmFtczogQ2xpY2tNb3VzZVBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBhcm0gPSBhd2FpdCBsb2FkQXJtKCk7XG4gIGF3YWl0IGFybS5jbGlja01vdXNlKHBhcmFtcyk7XG59XG5cbi8qKlxuICogTW92ZXMgdGhlIHBvaW50ZXIgdG8gdGhlIGNlbnRlciBvZiBhbiBlbGVtZW50IHVzaW5nICoqdHJ1c3RlZCoqIHBvaW50ZXIgaW5wdXQsIHRoZW4gcG9sbHMgdW50aWwgdGhlXG4gKiBlbGVtZW50IGFjdHVhbGx5IG1hdGNoZXMgYDpob3ZlcmAuXG4gKlxuICogKipEZXNrdG9wIG9ubHkqKiBcdTIwMTQgaXQgdGhyb3dzIG9uIG1vYmlsZSwgd2hlcmUgYDpob3ZlcmAgaGFzIG5vIHRvdWNoIGVxdWl2YWxlbnQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBlbGVtZW50IHRvIGhvdmVyLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBlbGVtZW50IG1hdGNoZXMgYDpob3ZlcmAuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBob3ZlckVsZW1lbnQocGFyYW1zOiBIb3ZlckVsZW1lbnRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgYXJtID0gYXdhaXQgbG9hZEFybSgpO1xuICBhd2FpdCBhcm0uaG92ZXJFbGVtZW50KHBhcmFtcyk7XG59XG5cbi8qKlxuICogTW92ZXMgdGhlIHBvaW50ZXIgdG8gdGhlIGdpdmVuIHZpZXdwb3J0IGNvb3JkaW5hdGVzIHVzaW5nIGEgKip0cnVzdGVkKiogcG9pbnRlciBtb3ZlLCBzbyBgOmhvdmVyYCBydWxlc1xuICogZ2VudWluZWx5IGFwcGx5LlxuICpcbiAqIFRoZSBsb3ctbGV2ZWwgcHJpbWl0aXZlOiBhIHNpbmdsZSBtb3ZlIHRoYXQgZG9lcyAqKm5vdCoqIHdhaXQgZm9yIGFueSBzdGF0ZSB0byBzZXR0bGUuIFByZWZlclxuICoge0BsaW5rIGhvdmVyRWxlbWVudH0gLyB7QGxpbmsgdW5ob3ZlckVsZW1lbnR9IGZvciBlbGVtZW50LXJlbGF0aXZlIG1vdmVzLlxuICpcbiAqICoqRGVza3RvcCBvbmx5KiogXHUyMDE0IGl0IHRocm93cyBvbiBtb2JpbGUsIHdoaWNoIGhhcyBubyBwZXJzaXN0ZW50IHBvaW50ZXIgdG8gbW92ZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHZpZXdwb3J0IGNvb3JkaW5hdGVzIHRvIG1vdmUgdG8uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIG1vdmUgaGFzIGJlZW4gaW5qZWN0ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtb3ZlTW91c2UocGFyYW1zOiBNb3ZlTW91c2VQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgYXJtID0gYXdhaXQgbG9hZEFybSgpO1xuICBhd2FpdCBhcm0ubW92ZU1vdXNlKHBhcmFtcyk7XG59XG5cbi8qKlxuICogUHJlc3NlcyBhIHNpbmdsZSBrZXkgKG9wdGlvbmFsbHkgd2l0aCBtb2RpZmllcnMpIHVzaW5nICoqdHJ1c3RlZCoqIGtleWJvYXJkIGlucHV0LCBmaXJpbmcgdGhlIGZ1bGwgcmVhbFxuICoga2V5IHBpcGVsaW5lIFx1MjAxNCBga2V5ZG93bmAgXHUyMTkyIGBrZXlwcmVzc2AgXHUyMTkyIGBiZWZvcmVpbnB1dGAgXHUyMTkyIGBpbnB1dGAgXHUyMTkyIGBrZXl1cGAuXG4gKlxuICogSXQgaXMgZGVsaXZlcmVkIHRvIHRoZSB3aW5kb3cncyBET00tZm9jdXNlZCBlbGVtZW50LCBzbyB0aGUgY2FsbGVyIGZvY3VzZXMgdGhlIHRhcmdldCBmaXJzdCBhbmQgdGhlblxuICogYXdhaXRzIHRoZSBleHBlY3RlZCBlZmZlY3Q7IHRoZSBwcmVzcyBpdHNlbGYgcG9sbHMgZm9yIG5vdGhpbmcuIE9uIG1vYmlsZSB0aGUgYWNjZXB0ZWQga2V5cyBhcmUgdGhlXG4gKiBuYW1lZCBvbmVzIChgJ0VudGVyJ2AsIGAnRXNjYXBlJ2AsIGAnVGFiJ2AsIGAnQmFja3NwYWNlJ2AsIGAnRGVsZXRlJ2AsIHRoZSBhcnJvd3MpIHBsdXMgc2luZ2xlIHByaW50YWJsZVxuICogY2hhcmFjdGVycyBcdTIwMTQgYW55dGhpbmcgZWxzZSB0aHJvd3MgcmF0aGVyIHRoYW4gcHJlc3Npbmcgbm90aGluZy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGtleSB0byBwcmVzcyBhbmQgYW55IG1vZGlmaWVycyB0byBob2xkLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBrZXkgcHJlc3MgaGFzIGJlZW4gaW5qZWN0ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcmVzc0tleShwYXJhbXM6IFByZXNzS2V5UGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGFybSA9IGF3YWl0IGxvYWRBcm0oKTtcbiAgYXdhaXQgYXJtLnByZXNzS2V5KHBhcmFtcyk7XG59XG5cbi8qKlxuICogVHlwZXMgdGV4dCBpbnRvIGEgQ29kZU1pcnJvciBlZGl0b3IgdXNpbmcgKip0cnVzdGVkKioga2V5Ym9hcmQgaW5wdXQuXG4gKlxuICogRm9jdXNlcyB0aGUgZWRpdG9yIChjYXJldCB0byB0aGUgZW5kKSBhbmQgcHJlc3NlcyBldmVyeSBjb2RlIHBvaW50IG9mIHRoZSB0ZXh0IFx1MjAxNCB0aGUgc2FtZSB0cnVzdGVkXG4gKiBzZXF1ZW5jZSBhIHJlYWwgdXNlciBwcm9kdWNlcyBcdTIwMTQgc28gdGhlIHRleHQgcmVhY2hlcyB0aGUgZG9jdW1lbnQgKipvbmx5IGlmIHRoZSBlZGl0b3IgZ2VudWluZWx5IGhvbGRzXG4gKiBmb2N1cyoqLiBUaGVuIGl0IHBvbGxzIHVudGlsIHRoZSBkb2N1bWVudCByZWZsZWN0cyB0aGUgaW5wdXQsIG9yIGEgYm91bmRlZCB0aW1lb3V0IGVsYXBzZXMgKHRoZSBleHBlY3RlZFxuICogb3V0Y29tZSB3aGVuIHRoZSBlZGl0b3IgaXMgcmVhZC1vbmx5IG9yIGZvY3VzIHdhcyBzdG9sZW4pLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZWRpdG9yIHRvIHR5cGUgaW50byBhbmQgdGhlIHRleHQgdG8gdHlwZS5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUga2V5c3Ryb2tlcyBoYXZlIHNldHRsZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0eXBlSW50b0VkaXRvcihwYXJhbXM6IFR5cGVJbnRvRWRpdG9yUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGFybSA9IGF3YWl0IGxvYWRBcm0oKTtcbiAgYXdhaXQgYXJtLnR5cGVJbnRvRWRpdG9yKHBhcmFtcyk7XG59XG5cbi8qKlxuICogTW92ZXMgdGhlIHBvaW50ZXIgdG8gYSBwb2ludCBqdXN0IG91dHNpZGUgYW4gZWxlbWVudCdzIGJvdW5kaW5nIGJveCB1c2luZyBhICoqdHJ1c3RlZCoqIHBvaW50ZXIgbW92ZSxcbiAqIHRoZW4gcG9sbHMgdW50aWwgdGhlIGVsZW1lbnQgbm8gbG9uZ2VyIG1hdGNoZXMgYDpob3ZlcmAuXG4gKlxuICogVGhlIGludmVyc2Ugb2Yge0BsaW5rIGhvdmVyRWxlbWVudH0uIFdoZW4gYW4gZWxlbWVudCBzcGFucyB0aGUgZnVsbCB2aWV3cG9ydCAobm8gcG9pbnQgb3V0c2lkZSBpdHMgYm94XG4gKiBpcyByZWFjaGFibGUpLCB1c2Uge0BsaW5rIG1vdmVNb3VzZX0gZGlyZWN0bHkgdG8gbW92ZSB0aGUgcG9pbnRlciB0byBhIGtub3duIGVtcHR5IGNvb3JkaW5hdGUgaW5zdGVhZC5cbiAqXG4gKiAqKkRlc2t0b3Agb25seSoqIFx1MjAxNCBpdCB0aHJvd3Mgb24gbW9iaWxlLCBmb3IgdGhlIHNhbWUgcmVhc29uIHtAbGluayBob3ZlckVsZW1lbnR9IGRvZXMuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBlbGVtZW50IHRvIG1vdmUgdGhlIHBvaW50ZXIgYXdheSBmcm9tLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBlbGVtZW50IG5vIGxvbmdlciBtYXRjaGVzIGA6aG92ZXJgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdW5ob3ZlckVsZW1lbnQocGFyYW1zOiBVbmhvdmVyRWxlbWVudFBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBhcm0gPSBhd2FpdCBsb2FkQXJtKCk7XG4gIGF3YWl0IGFybS51bmhvdmVyRWxlbWVudChwYXJhbXMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBsb2FkQXJtKCk6IFByb21pc2U8VHJ1c3RlZElucHV0QXJtPiB7XG4gIC8vIENvbmRpdGlvbmFsIGltcG9ydCBvZiB0aGUgcGxhdGZvcm0tb25seSBhcm0sIGF0IGNhbGwgdGltZTogbmVpdGhlciBhcm0gaXMgb24gdGhlIG90aGVyIHBsYXRmb3JtJ3NcbiAgLy8gTG9hZCBwYXRoLCBhbmQgdGhlIHNwZWNpZmllcnMgc3RheSBsaXRlcmFsIHNvIGVzYnVpbGQgYnVuZGxlcyBib3RoLlxuICByZXR1cm4gUGxhdGZvcm0uaXNEZXNrdG9wQXBwID8gYXdhaXQgaW1wb3J0KCcuL2Rlc2t0b3AtdHJ1c3RlZC1pbnB1dC50cycpIDogYXdhaXQgaW1wb3J0KCcuL21vYmlsZS10cnVzdGVkLWlucHV0LnRzJyk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0NBLFNBQVMsZ0JBQWdCO0FBdUN6QixlQUFzQixhQUFhLFFBQTJDO0FBQzVFLFFBQU0sTUFBTSxNQUFNLFFBQVE7QUFDMUIsUUFBTSxJQUFJLGFBQWEsTUFBTTtBQUMvQjtBQW1CQSxlQUFzQixXQUFXLFFBQXlDO0FBQ3hFLFFBQU0sTUFBTSxNQUFNLFFBQVE7QUFDMUIsUUFBTSxJQUFJLFdBQVcsTUFBTTtBQUM3QjtBQVdBLGVBQXNCLGFBQWEsUUFBMkM7QUFDNUUsUUFBTSxNQUFNLE1BQU0sUUFBUTtBQUMxQixRQUFNLElBQUksYUFBYSxNQUFNO0FBQy9CO0FBY0EsZUFBc0IsVUFBVSxRQUF3QztBQUN0RSxRQUFNLE1BQU0sTUFBTSxRQUFRO0FBQzFCLFFBQU0sSUFBSSxVQUFVLE1BQU07QUFDNUI7QUFjQSxlQUFzQixTQUFTLFFBQXVDO0FBQ3BFLFFBQU0sTUFBTSxNQUFNLFFBQVE7QUFDMUIsUUFBTSxJQUFJLFNBQVMsTUFBTTtBQUMzQjtBQWFBLGVBQXNCLGVBQWUsUUFBNkM7QUFDaEYsUUFBTSxNQUFNLE1BQU0sUUFBUTtBQUMxQixRQUFNLElBQUksZUFBZSxNQUFNO0FBQ2pDO0FBY0EsZUFBc0IsZUFBZSxRQUE2QztBQUNoRixRQUFNLE1BQU0sTUFBTSxRQUFRO0FBQzFCLFFBQU0sSUFBSSxlQUFlLE1BQU07QUFDakM7QUFFQSxlQUFlLFVBQW9DO0FBR2pELFNBQU8sU0FBUyxlQUFlLE1BQU0sT0FBTyw0QkFBNEIsSUFBSSxNQUFNLE9BQU8sMkJBQTJCO0FBQ3RIOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -23,7 +23,12 @@ export declare function buildCompile(): Promise<void>;
23
23
  /**
24
24
  * Compiles the Svelte code.
25
25
  *
26
+ * The project's Svelte files are found by globbing the Svelte extensions directly. Globbing the tsconfig
27
+ * `include` patterns and filtering that list would never match: `include` lists TypeScript globs
28
+ * (`./src/**\/*.ts`, …), so no `.svelte` path can ever appear in it and the check would always be skipped.
29
+ *
26
30
  * @returns A {@link Promise} that resolves when the code compiles successfully.
31
+ * @throws If the project has Svelte files but does not declare `svelte-check`.
27
32
  */
28
33
  export declare function buildCompileSvelte(): Promise<void>;
29
34
  /**
@@ -61,7 +61,9 @@ import {
61
61
  npmRunOptional,
62
62
  NpmRunOptionalResult
63
63
  } from "./npm-run.mjs";
64
+ import { readPackageJson } from "./npm.mjs";
64
65
  import { ObsidianDevUtilsRepoPaths } from "./obsidian-dev-utils-repo-paths.mjs";
66
+ import { resolveToolCommand } from "./package-manager.mjs";
65
67
  import {
66
68
  execFromRoot,
67
69
  getRootFolder,
@@ -81,16 +83,25 @@ async function buildCompile() {
81
83
  async function buildCompileSvelte() {
82
84
  const tsConfigPath = resolvePathFromRootSafe({ path: ObsidianDevUtilsRepoPaths.TsConfigJson });
83
85
  const tsConfig = await readJson(tsConfigPath);
84
- const allFiles = await toArray(glob(tsConfig.include ?? [], { exclude: tsConfig.exclude ?? [] }));
85
- const svelteFiles = allFiles.filter((file) => file.endsWith(".svelte") || file.endsWith(".svelte.js") || file.endsWith(".svelte.ts"));
86
- if (svelteFiles.length === 0) {
86
+ const svelteFiles = await toArray(glob(SVELTE_FILE_PATTERNS, {
87
+ cwd: resolvePathFromRootSafe({ path: ObsidianDevUtilsRepoPaths.CurrentFolder }),
88
+ exclude: [...SVELTE_FILE_EXCLUDE_PATTERNS, ...tsConfig.exclude ?? []]
89
+ }));
90
+ const [firstSvelteFile] = svelteFiles;
91
+ if (firstSvelteFile === void 0) {
87
92
  getLibDebugger("build:buildCompileSvelte")("No Svelte files found in the project, skipping Svelte compilation");
88
93
  return;
89
94
  }
90
- await execFromRoot(["npx", "svelte-check", "--tsconfig", ObsidianDevUtilsRepoPaths.TsConfigJson]);
95
+ const packageJson = await readPackageJson();
96
+ if (!checkSvelteCheckDeclared(packageJson)) {
97
+ throw new Error(
98
+ `Found Svelte file(s) in the project (e.g. ${firstSvelteFile}), but \`${SVELTE_CHECK_PACKAGE_NAME}\` is not declared in package.json. Add \`${SVELTE_CHECK_PACKAGE_NAME}\` as a devDependency to type-check the Svelte code.`
99
+ );
100
+ }
101
+ await execFromRoot([...resolveToolCommand({ tool: SVELTE_CHECK_PACKAGE_NAME }), "--tsconfig", ObsidianDevUtilsRepoPaths.TsConfigJson]);
91
102
  }
92
103
  async function buildCompileTypeScript() {
93
- await execFromRoot(["npx", "tsc", "--build", "--force"]);
104
+ await execFromRoot([...resolveToolCommand({ tool: "tsc" }), "--build", "--force"]);
94
105
  if (!areProjectTypesValid()) {
95
106
  throw new Error("TypeScript declaration validation failed.");
96
107
  }
@@ -110,6 +121,16 @@ async function buildTemplates() {
110
121
  }
111
122
  const TEMPLATE_FILE_SUFFIX = ".template";
112
123
  const NODE_MODULES_SEGMENT = "/node_modules/";
124
+ const SVELTE_CHECK_PACKAGE_NAME = "svelte-check";
125
+ const SVELTE_FILE_PATTERNS = [
126
+ `${ObsidianDevUtilsRepoPaths.AnyPath}/*.svelte`,
127
+ `${ObsidianDevUtilsRepoPaths.AnyPath}/*.svelte.js`,
128
+ `${ObsidianDevUtilsRepoPaths.AnyPath}/*.svelte.ts`
129
+ ];
130
+ const SVELTE_FILE_EXCLUDE_PATTERNS = [
131
+ `${ObsidianDevUtilsRepoPaths.AnyPath}/${ObsidianDevUtilsRepoPaths.NodeModules}/${ObsidianDevUtilsRepoPaths.AnyPath}`,
132
+ `${ObsidianDevUtilsRepoPaths.AnyPath}/${ObsidianDevUtilsRepoPaths.Dist}/${ObsidianDevUtilsRepoPaths.AnyPath}`
133
+ ];
113
134
  function areProjectTypesValid() {
114
135
  const root = getRootFolder();
115
136
  if (!root) {
@@ -123,6 +144,9 @@ function areProjectTypesValid() {
123
144
  shouldKeepFile: (fileName) => shouldKeepProjectFile({ fileName, rootCanonical })
124
145
  });
125
146
  }
147
+ function checkSvelteCheckDeclared(packageJson) {
148
+ return [packageJson.dependencies, packageJson.devDependencies, packageJson.peerDependencies].some((dependencies) => dependencies?.[SVELTE_CHECK_PACKAGE_NAME] !== void 0);
149
+ }
126
150
  function shouldKeepProjectFile(params) {
127
151
  const { fileName, rootCanonical } = params;
128
152
  return fileName.startsWith(`${rootCanonical}/`) && !fileName.includes(NODE_MODULES_SEGMENT);
@@ -134,4 +158,4 @@ export {
134
158
  buildCompileTypeScript,
135
159
  buildTemplates
136
160
  };
137
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3NjcmlwdC11dGlscy9idWlsZC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRoaXMgbW9kdWxlIHByb3ZpZGVzIHV0aWxpdHkgZnVuY3Rpb25zIHRvIGhhbmRsZSB0aGUgYnVpbGQgcHJvY2VzcyBmb3Igc3RhdGljIGFzc2V0cyBhbmQgY2xlYW5pbmdcbiAqIHRoZSBidWlsZCBvdXRwdXQgZm9sZGVyLiBJdCBpbmNsdWRlcyBmdW5jdGlvbnMgdG8gY29weSBzdGF0aWMgZmlsZXMgdG8gdGhlIGRpc3RyaWJ1dGlvbiBmb2xkZXJcbiAqIGFuZCB0byByZW1vdmUgdGhlIGV4aXN0aW5nIGJ1aWxkIG91dHB1dC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFRzQ29uZmlnSnNvbiB9IGZyb20gJ3R5cGUtZmVzdCc7XG5cbmltcG9ydCB7XG4gIGNwLFxuICBnbG9iLFxuICBybVxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcblxuaW1wb3J0IHsgdG9BcnJheSB9IGZyb20gJy4uL2FzeW5jLnRzJztcbmltcG9ydCB7IGdldExpYkRlYnVnZ2VyIH0gZnJvbSAnLi4vZGVidWcudHMnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJy4uL3BhdGgudHMnO1xuaW1wb3J0IHsgdHJpbVN0YXJ0IH0gZnJvbSAnLi4vc3RyaW5nLnRzJztcbmltcG9ydCB7XG4gIGNoZWNrUHJvamVjdFR5cGVzLFxuICBwYXJzZVRzQ29uZmlnLFxuICB0b0Nhbm9uaWNhbFxufSBmcm9tICcuL2NoZWNrLXByb2plY3QtdHlwZXMudHMnO1xuaW1wb3J0IHsgcmVhZGRpclBvc2l4IH0gZnJvbSAnLi9mcy50cyc7XG5pbXBvcnQgeyByZWFkSnNvbiB9IGZyb20gJy4vanNvbi50cyc7XG5pbXBvcnQge1xuICBucG1SdW5PcHRpb25hbCxcbiAgTnBtUnVuT3B0aW9uYWxSZXN1bHRcbn0gZnJvbSAnLi9ucG0tcnVuLnRzJztcbmltcG9ydCB7IE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMgfSBmcm9tICcuL29ic2lkaWFuLWRldi11dGlscy1yZXBvLXBhdGhzLnRzJztcbmltcG9ydCB7XG4gIGV4ZWNGcm9tUm9vdCxcbiAgZ2V0Um9vdEZvbGRlcixcbiAgcmVzb2x2ZVBhdGhGcm9tUm9vdFNhZmVcbn0gZnJvbSAnLi9yb290LnRzJztcblxuLyoqXG4gKiBSZW1vdmVzIHRoZSBkaXN0cmlidXRpb24gZm9sZGVyIGFuZCBpdHMgY29udGVudHMuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBkZWxldGVzIHRoZSBlbnRpcmUgZGlzdHJpYnV0aW9uIGZvbGRlciB0byBlbnN1cmUgYSBjbGVhbiBidWlsZCBlbnZpcm9ubWVudC5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGZvbGRlciBoYXMgYmVlbiByZW1vdmVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVpbGRDbGVhbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgcm0oT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5EaXN0LCB7IGZvcmNlOiB0cnVlLCByZWN1cnNpdmU6IHRydWUgfSk7XG59XG5cbi8qKlxuICogQ29tcGlsZXMgdGhlIGNvZGUuXG4gKlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBjb2RlIGNvbXBpbGVzIHN1Y2Nlc3NmdWxseS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJ1aWxkQ29tcGlsZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKGF3YWl0IG5wbVJ1bk9wdGlvbmFsKCdidWlsZDpjb21waWxlOnN2ZWx0ZScpID09PSBOcG1SdW5PcHRpb25hbFJlc3VsdC5Ta2lwcGVkKSB7XG4gICAgYXdhaXQgYnVpbGRDb21waWxlU3ZlbHRlKCk7XG4gIH1cbiAgaWYgKGF3YWl0IG5wbVJ1bk9wdGlvbmFsKCdidWlsZDpjb21waWxlOnR5cGVzY3JpcHQnKSA9PT0gTnBtUnVuT3B0aW9uYWxSZXN1bHQuU2tpcHBlZCkge1xuICAgIGF3YWl0IGJ1aWxkQ29tcGlsZVR5cGVTY3JpcHQoKTtcbiAgfVxufVxuXG4vKipcbiAqIENvbXBpbGVzIHRoZSBTdmVsdGUgY29kZS5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGNvZGUgY29tcGlsZXMgc3VjY2Vzc2Z1bGx5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVpbGRDb21waWxlU3ZlbHRlKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB0c0NvbmZpZ1BhdGggPSByZXNvbHZlUGF0aEZyb21Sb290U2FmZSh7IHBhdGg6IE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuVHNDb25maWdKc29uIH0pO1xuICBjb25zdCB0c0NvbmZpZyA9IGF3YWl0IHJlYWRKc29uPFRzQ29uZmlnSnNvbj4odHNDb25maWdQYXRoKTtcbiAgY29uc3QgYWxsRmlsZXMgPSBhd2FpdCB0b0FycmF5KGdsb2IodHNDb25maWcuaW5jbHVkZSA/PyBbXSwgeyBleGNsdWRlOiB0c0NvbmZpZy5leGNsdWRlID8/IFtdIH0pKTtcbiAgY29uc3Qgc3ZlbHRlRmlsZXMgPSBhbGxGaWxlcy5maWx0ZXIoKGZpbGUpID0+IGZpbGUuZW5kc1dpdGgoJy5zdmVsdGUnKSB8fCBmaWxlLmVuZHNXaXRoKCcuc3ZlbHRlLmpzJykgfHwgZmlsZS5lbmRzV2l0aCgnLnN2ZWx0ZS50cycpKTtcblxuICBpZiAoc3ZlbHRlRmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgZ2V0TGliRGVidWdnZXIoJ2J1aWxkOmJ1aWxkQ29tcGlsZVN2ZWx0ZScpKCdObyBTdmVsdGUgZmlsZXMgZm91bmQgaW4gdGhlIHByb2plY3QsIHNraXBwaW5nIFN2ZWx0ZSBjb21waWxhdGlvbicpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGF3YWl0IGV4ZWNGcm9tUm9vdChbJ25weCcsICdzdmVsdGUtY2hlY2snLCAnLS10c2NvbmZpZycsIE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuVHNDb25maWdKc29uXSk7XG59XG5cbi8qKlxuICogQ29tcGlsZXMgdGhlIFR5cGVTY3JpcHQgY29kZS5cbiAqXG4gKiBUaGUgZ2VuZXJhbCBgdHNjYCBwYXNzIHJ1bnMgd2l0aCBgc2tpcExpYkNoZWNrOiB0cnVlYCAoY29uZmlndXJlZCBpbiBgdHNjb25maWcuanNvbmApIHNvIGl0IGRvZXNcbiAqIG5vdCBmYWlsIG9uIGJyb2tlbiB1cHN0cmVhbSBgLmQudHNgIGZpbGVzIHdlIGRvIG5vdCBjb250cm9sLiBBZnRlcndhcmRzLCB7QGxpbmsgYXJlUHJvamVjdFR5cGVzVmFsaWR9XG4gKiByZS1ydW5zIHRoZSB0eXBlLWNoZWNrIGluLW1lbW9yeSB3aXRoIGBza2lwTGliQ2hlY2s6IGZhbHNlYCwgcmVwb3J0aW5nIG9ubHkgZGlhZ25vc3RpY3MgZnJvbSB0aGVcbiAqIGZpbGVzIHdlIG93biwgc28gdGhlIGRlY2xhcmF0aW9ucyB3ZSBhdXRob3IgYXJlIHN0aWxsIGZ1bGx5IHZhbGlkYXRlZC5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGNvZGUgY29tcGlsZXMgc3VjY2Vzc2Z1bGx5LlxuICogQHRocm93cyBJZiB0aGUgcHJvamVjdCdzIG93biBkZWNsYXJhdGlvbnMgZmFpbCB2YWxpZGF0aW9uLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVpbGRDb21waWxlVHlwZVNjcmlwdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgZXhlY0Zyb21Sb290KFsnbnB4JywgJ3RzYycsICctLWJ1aWxkJywgJy0tZm9yY2UnXSk7XG5cbiAgaWYgKCFhcmVQcm9qZWN0VHlwZXNWYWxpZCgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUeXBlU2NyaXB0IGRlY2xhcmF0aW9uIHZhbGlkYXRpb24gZmFpbGVkLicpO1xuICB9XG59XG5cbi8qKlxuICogQ29waWVzIGFsbCB0ZW1wbGF0ZSBmaWxlcyBmcm9tIHRoZSB0ZW1wbGF0ZXMgZm9sZGVyIHRvIHRoZSBgdGVtcGxhdGVzYCBmb2xkZXIgd2l0aGluIHRoZVxuICogZGlzdHJpYnV0aW9uIGZvbGRlci5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHJlY3Vyc2l2ZWx5IHJlYWRzIHRoZSBjb250ZW50cyBvZiB0aGUgdGVtcGxhdGVzIGZvbGRlciBhbmQgY29waWVzIGVhY2ggZmlsZSB0byB0aGVcbiAqIGNvcnJlc3BvbmRpbmcgcGF0aCB1bmRlciB7QGxpbmsgT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5EaXN0VGVtcGxhdGVzfSwgc28gY29uc3VtZXJzIGNhbiBjb3B5IHRoZVxuICogdGVtcGxhdGVzIGZyb20gYG5vZGVfbW9kdWxlcy9vYnNpZGlhbi1kZXYtdXRpbHMvZGlzdC90ZW1wbGF0ZXNgLiBBIHRyYWlsaW5nIGAudGVtcGxhdGVgIG9uIGEgc291cmNlXG4gKiBmaWxlIG5hbWUgaXMgc3RyaXBwZWQgaW4gdGhlIGRlc3RpbmF0aW9uIChlLmcuIGBlc2xpbnQuY29uZmlnLm10cy50ZW1wbGF0ZWAgaXMgY29waWVkIGFzXG4gKiBgZXNsaW50LmNvbmZpZy5tdHNgKSwgc28gYW4gYWN0aXZlIGNvbmZpZyB0ZW1wbGF0ZSBjYW4gbGl2ZSBpbiB0aGUgcmVwbyB1bmRlciBhIG5hbWUgdGhhdCB0aGVcbiAqIGNvcnJlc3BvbmRpbmcgdG9vbCBkb2VzIG5vdCBhdXRvLWRpc2NvdmVyLlxuICpcbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgZmlsZXMgaGF2ZSBiZWVuIGNvcGllZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJ1aWxkVGVtcGxhdGVzKCk6IFByb21pc2U8dm9pZD4ge1xuICBmb3IgKGNvbnN0IGRpcmVudCBvZiBhd2FpdCByZWFkZGlyUG9zaXgoT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5UZW1wbGF0ZXMsIHsgcmVjdXJzaXZlOiB0cnVlLCB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pKSB7XG4gICAgaWYgKCFkaXJlbnQuaXNGaWxlKCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHBhdGggPSB0cmltU3RhcnQoe1xuICAgICAgJHN0cmluZzogam9pbihkaXJlbnQucGFyZW50UGF0aCwgZGlyZW50Lm5hbWUpLFxuICAgICAgcHJlZml4OiBgJHtPYnNpZGlhbkRldlV0aWxzUmVwb1BhdGhzLlRlbXBsYXRlc30vYFxuICAgIH0pO1xuICAgIGNvbnN0IGRlc3RpbmF0aW9uUGF0aCA9IHBhdGguZW5kc1dpdGgoVEVNUExBVEVfRklMRV9TVUZGSVgpID8gcGF0aC5zbGljZSgwLCAtVEVNUExBVEVfRklMRV9TVUZGSVgubGVuZ3RoKSA6IHBhdGg7XG4gICAgYXdhaXQgY3Aoam9pbihPYnNpZGlhbkRldlV0aWxzUmVwb1BhdGhzLlRlbXBsYXRlcywgcGF0aCksIGpvaW4oT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5EaXN0VGVtcGxhdGVzLCBkZXN0aW5hdGlvblBhdGgpKTtcbiAgfVxufVxuXG5jb25zdCBURU1QTEFURV9GSUxFX1NVRkZJWCA9ICcudGVtcGxhdGUnO1xuXG5jb25zdCBOT0RFX01PRFVMRVNfU0VHTUVOVCA9ICcvbm9kZV9tb2R1bGVzLyc7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHNob3VsZEtlZXBQcm9qZWN0RmlsZX0uXG4gKi9cbmludGVyZmFjZSBTaG91bGRLZWVwUHJvamVjdEZpbGVQYXJhbXMge1xuICAvKipcbiAgICogQWJzb2x1dGUgcGF0aCBvZiB0aGUgZmlsZSB1bmRlciBjb25zaWRlcmF0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgZmlsZU5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogQWJzb2x1dGUgKGNhbm9uaWNhbCkgcGF0aCBvZiB0aGUgcHJvamVjdCByb290LlxuICAgKi9cbiAgcmVhZG9ubHkgcm9vdENhbm9uaWNhbDogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlLXJ1bnMgdGhlIHByb2plY3QgdHlwZS1jaGVjayBpbi1tZW1vcnkgd2l0aCBgc2tpcExpYkNoZWNrOiBmYWxzZWAsIHJlcG9ydGluZyBvbmx5IGRpYWdub3N0aWNzXG4gKiB3aG9zZSBzb3VyY2UgZmlsZSBiZWxvbmdzIHRvIHRoZSBwcm9qZWN0ICh1bmRlciB0aGUgcm9vdCBmb2xkZXIsIG91dHNpZGUgYG5vZGVfbW9kdWxlc2ApLlxuICpcbiAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIHRoZSBwcm9qZWN0J3Mgb3duIGZpbGVzIGhhdmUgbm8gdHlwZSBlcnJvcnMsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICogQHRocm93cyBJZiB0aGUgcm9vdCBmb2xkZXIgY2Fubm90IGJlIGZvdW5kLlxuICovXG5mdW5jdGlvbiBhcmVQcm9qZWN0VHlwZXNWYWxpZCgpOiBib29sZWFuIHtcbiAgY29uc3Qgcm9vdCA9IGdldFJvb3RGb2xkZXIoKTtcblxuICBpZiAoIXJvb3QpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIHJvb3QgZm9sZGVyJyk7XG4gIH1cblxuICBjb25zdCByb290Q2Fub25pY2FsID0gdG9DYW5vbmljYWwocm9vdCk7XG4gIGNvbnN0IHsgZmlsZU5hbWVzLCBvcHRpb25zIH0gPSBwYXJzZVRzQ29uZmlnKGpvaW4ocm9vdCwgT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5Uc0NvbmZpZ0pzb24pKTtcblxuICByZXR1cm4gY2hlY2tQcm9qZWN0VHlwZXMoe1xuICAgIG9wdGlvbnMsXG4gICAgcm9vdE5hbWVzOiBmaWxlTmFtZXMsXG4gICAgc2hvdWxkS2VlcEZpbGU6IChmaWxlTmFtZSkgPT4gc2hvdWxkS2VlcFByb2plY3RGaWxlKHsgZmlsZU5hbWUsIHJvb3RDYW5vbmljYWwgfSlcbiAgfSk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgZmlsZSBiZWxvbmdzIHRvIHRoZSBwcm9qZWN0ICh1bmRlciB0aGUgcm9vdCBmb2xkZXIsIG91dHNpZGUgYG5vZGVfbW9kdWxlc2ApLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhlIGNoZWNrLlxuICogQHJldHVybnMgYHRydWVgIHdoZW4gdGhlIGZpbGUgYmVsb25ncyB0byB0aGUgcHJvamVjdC5cbiAqL1xuZnVuY3Rpb24gc2hvdWxkS2VlcFByb2plY3RGaWxlKHBhcmFtczogU2hvdWxkS2VlcFByb2plY3RGaWxlUGFyYW1zKTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgZmlsZU5hbWUsIHJvb3RDYW5vbmljYWwgfSA9IHBhcmFtcztcbiAgcmV0dXJuIGZpbGVOYW1lLnN0YXJ0c1dpdGgoYCR7cm9vdENhbm9uaWNhbH0vYCkgJiYgIWZpbGVOYW1lLmluY2x1ZGVzKE5PREVfTU9EVUxFU19TRUdNRU5UKTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFVQTtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFFUCxTQUFTLGVBQWU7QUFDeEIsU0FBUyxzQkFBc0I7QUFDL0IsU0FBUyxZQUFZO0FBQ3JCLFNBQVMsaUJBQWlCO0FBQzFCO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsb0JBQW9CO0FBQzdCLFNBQVMsZ0JBQWdCO0FBQ3pCO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsU0FBUyxpQ0FBaUM7QUFDMUM7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBU1AsZUFBc0IsYUFBNEI7QUFDaEQsUUFBTSxHQUFHLDBCQUEwQixNQUFNLEVBQUUsT0FBTyxNQUFNLFdBQVcsS0FBSyxDQUFDO0FBQzNFO0FBT0EsZUFBc0IsZUFBOEI7QUFDbEQsTUFBSSxNQUFNLGVBQWUsc0JBQXNCLE1BQU0scUJBQXFCLFNBQVM7QUFDakYsVUFBTSxtQkFBbUI7QUFBQSxFQUMzQjtBQUNBLE1BQUksTUFBTSxlQUFlLDBCQUEwQixNQUFNLHFCQUFxQixTQUFTO0FBQ3JGLFVBQU0sdUJBQXVCO0FBQUEsRUFDL0I7QUFDRjtBQU9BLGVBQXNCLHFCQUFvQztBQUN4RCxRQUFNLGVBQWUsd0JBQXdCLEVBQUUsTUFBTSwwQkFBMEIsYUFBYSxDQUFDO0FBQzdGLFFBQU0sV0FBVyxNQUFNLFNBQXVCLFlBQVk7QUFDMUQsUUFBTSxXQUFXLE1BQU0sUUFBUSxLQUFLLFNBQVMsV0FBVyxDQUFDLEdBQUcsRUFBRSxTQUFTLFNBQVMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2hHLFFBQU0sY0FBYyxTQUFTLE9BQU8sQ0FBQyxTQUFTLEtBQUssU0FBUyxTQUFTLEtBQUssS0FBSyxTQUFTLFlBQVksS0FBSyxLQUFLLFNBQVMsWUFBWSxDQUFDO0FBRXBJLE1BQUksWUFBWSxXQUFXLEdBQUc7QUFDNUIsbUJBQWUsMEJBQTBCLEVBQUUsbUVBQW1FO0FBQzlHO0FBQUEsRUFDRjtBQUVBLFFBQU0sYUFBYSxDQUFDLE9BQU8sZ0JBQWdCLGNBQWMsMEJBQTBCLFlBQVksQ0FBQztBQUNsRztBQWFBLGVBQXNCLHlCQUF3QztBQUM1RCxRQUFNLGFBQWEsQ0FBQyxPQUFPLE9BQU8sV0FBVyxTQUFTLENBQUM7QUFFdkQsTUFBSSxDQUFDLHFCQUFxQixHQUFHO0FBQzNCLFVBQU0sSUFBSSxNQUFNLDJDQUEyQztBQUFBLEVBQzdEO0FBQ0Y7QUFlQSxlQUFzQixpQkFBZ0M7QUFDcEQsYUFBVyxVQUFVLE1BQU0sYUFBYSwwQkFBMEIsV0FBVyxFQUFFLFdBQVcsTUFBTSxlQUFlLEtBQUssQ0FBQyxHQUFHO0FBQ3RILFFBQUksQ0FBQyxPQUFPLE9BQU8sR0FBRztBQUNwQjtBQUFBLElBQ0Y7QUFFQSxVQUFNLE9BQU8sVUFBVTtBQUFBLE1BQ3JCLFNBQVMsS0FBSyxPQUFPLFlBQVksT0FBTyxJQUFJO0FBQUEsTUFDNUMsUUFBUSxHQUFHLDBCQUEwQixTQUFTO0FBQUEsSUFDaEQsQ0FBQztBQUNELFVBQU0sa0JBQWtCLEtBQUssU0FBUyxvQkFBb0IsSUFBSSxLQUFLLE1BQU0sR0FBRyxDQUFDLHFCQUFxQixNQUFNLElBQUk7QUFDNUcsVUFBTSxHQUFHLEtBQUssMEJBQTBCLFdBQVcsSUFBSSxHQUFHLEtBQUssMEJBQTBCLGVBQWUsZUFBZSxDQUFDO0FBQUEsRUFDMUg7QUFDRjtBQUVBLE1BQU0sdUJBQXVCO0FBRTdCLE1BQU0sdUJBQXVCO0FBd0I3QixTQUFTLHVCQUFnQztBQUN2QyxRQUFNLE9BQU8sY0FBYztBQUUzQixNQUFJLENBQUMsTUFBTTtBQUNULFVBQU0sSUFBSSxNQUFNLDRCQUE0QjtBQUFBLEVBQzlDO0FBRUEsUUFBTSxnQkFBZ0IsWUFBWSxJQUFJO0FBQ3RDLFFBQU0sRUFBRSxXQUFXLFFBQVEsSUFBSSxjQUFjLEtBQUssTUFBTSwwQkFBMEIsWUFBWSxDQUFDO0FBRS9GLFNBQU8sa0JBQWtCO0FBQUEsSUFDdkI7QUFBQSxJQUNBLFdBQVc7QUFBQSxJQUNYLGdCQUFnQixDQUFDLGFBQWEsc0JBQXNCLEVBQUUsVUFBVSxjQUFjLENBQUM7QUFBQSxFQUNqRixDQUFDO0FBQ0g7QUFRQSxTQUFTLHNCQUFzQixRQUE4QztBQUMzRSxRQUFNLEVBQUUsVUFBVSxjQUFjLElBQUk7QUFDcEMsU0FBTyxTQUFTLFdBQVcsR0FBRyxhQUFhLEdBQUcsS0FBSyxDQUFDLFNBQVMsU0FBUyxvQkFBb0I7QUFDNUY7IiwKICAibmFtZXMiOiBbXQp9Cg==
161
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3NjcmlwdC11dGlscy9idWlsZC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRoaXMgbW9kdWxlIHByb3ZpZGVzIHV0aWxpdHkgZnVuY3Rpb25zIHRvIGhhbmRsZSB0aGUgYnVpbGQgcHJvY2VzcyBmb3Igc3RhdGljIGFzc2V0cyBhbmQgY2xlYW5pbmdcbiAqIHRoZSBidWlsZCBvdXRwdXQgZm9sZGVyLiBJdCBpbmNsdWRlcyBmdW5jdGlvbnMgdG8gY29weSBzdGF0aWMgZmlsZXMgdG8gdGhlIGRpc3RyaWJ1dGlvbiBmb2xkZXJcbiAqIGFuZCB0byByZW1vdmUgdGhlIGV4aXN0aW5nIGJ1aWxkIG91dHB1dC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7XG4gIFBhY2thZ2VKc29uLFxuICBUc0NvbmZpZ0pzb25cbn0gZnJvbSAndHlwZS1mZXN0JztcblxuaW1wb3J0IHtcbiAgY3AsXG4gIGdsb2IsXG4gIHJtXG59IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuXG5pbXBvcnQgeyB0b0FycmF5IH0gZnJvbSAnLi4vYXN5bmMudHMnO1xuaW1wb3J0IHsgZ2V0TGliRGVidWdnZXIgfSBmcm9tICcuLi9kZWJ1Zy50cyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnLi4vcGF0aC50cyc7XG5pbXBvcnQgeyB0cmltU3RhcnQgfSBmcm9tICcuLi9zdHJpbmcudHMnO1xuaW1wb3J0IHtcbiAgY2hlY2tQcm9qZWN0VHlwZXMsXG4gIHBhcnNlVHNDb25maWcsXG4gIHRvQ2Fub25pY2FsXG59IGZyb20gJy4vY2hlY2stcHJvamVjdC10eXBlcy50cyc7XG5pbXBvcnQgeyByZWFkZGlyUG9zaXggfSBmcm9tICcuL2ZzLnRzJztcbmltcG9ydCB7IHJlYWRKc29uIH0gZnJvbSAnLi9qc29uLnRzJztcbmltcG9ydCB7XG4gIG5wbVJ1bk9wdGlvbmFsLFxuICBOcG1SdW5PcHRpb25hbFJlc3VsdFxufSBmcm9tICcuL25wbS1ydW4udHMnO1xuaW1wb3J0IHsgcmVhZFBhY2thZ2VKc29uIH0gZnJvbSAnLi9ucG0udHMnO1xuaW1wb3J0IHsgT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocyB9IGZyb20gJy4vb2JzaWRpYW4tZGV2LXV0aWxzLXJlcG8tcGF0aHMudHMnO1xuaW1wb3J0IHsgcmVzb2x2ZVRvb2xDb21tYW5kIH0gZnJvbSAnLi9wYWNrYWdlLW1hbmFnZXIudHMnO1xuaW1wb3J0IHtcbiAgZXhlY0Zyb21Sb290LFxuICBnZXRSb290Rm9sZGVyLFxuICByZXNvbHZlUGF0aEZyb21Sb290U2FmZVxufSBmcm9tICcuL3Jvb3QudHMnO1xuXG4vKipcbiAqIFJlbW92ZXMgdGhlIGRpc3RyaWJ1dGlvbiBmb2xkZXIgYW5kIGl0cyBjb250ZW50cy5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGRlbGV0ZXMgdGhlIGVudGlyZSBkaXN0cmlidXRpb24gZm9sZGVyIHRvIGVuc3VyZSBhIGNsZWFuIGJ1aWxkIGVudmlyb25tZW50LlxuICpcbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgZm9sZGVyIGhhcyBiZWVuIHJlbW92ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBidWlsZENsZWFuKCk6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBybShPYnNpZGlhbkRldlV0aWxzUmVwb1BhdGhzLkRpc3QsIHsgZm9yY2U6IHRydWUsIHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbn1cblxuLyoqXG4gKiBDb21waWxlcyB0aGUgY29kZS5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGNvZGUgY29tcGlsZXMgc3VjY2Vzc2Z1bGx5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVpbGRDb21waWxlKCk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoYXdhaXQgbnBtUnVuT3B0aW9uYWwoJ2J1aWxkOmNvbXBpbGU6c3ZlbHRlJykgPT09IE5wbVJ1bk9wdGlvbmFsUmVzdWx0LlNraXBwZWQpIHtcbiAgICBhd2FpdCBidWlsZENvbXBpbGVTdmVsdGUoKTtcbiAgfVxuICBpZiAoYXdhaXQgbnBtUnVuT3B0aW9uYWwoJ2J1aWxkOmNvbXBpbGU6dHlwZXNjcmlwdCcpID09PSBOcG1SdW5PcHRpb25hbFJlc3VsdC5Ta2lwcGVkKSB7XG4gICAgYXdhaXQgYnVpbGRDb21waWxlVHlwZVNjcmlwdCgpO1xuICB9XG59XG5cbi8qKlxuICogQ29tcGlsZXMgdGhlIFN2ZWx0ZSBjb2RlLlxuICpcbiAqIFRoZSBwcm9qZWN0J3MgU3ZlbHRlIGZpbGVzIGFyZSBmb3VuZCBieSBnbG9iYmluZyB0aGUgU3ZlbHRlIGV4dGVuc2lvbnMgZGlyZWN0bHkuIEdsb2JiaW5nIHRoZSB0c2NvbmZpZ1xuICogYGluY2x1ZGVgIHBhdHRlcm5zIGFuZCBmaWx0ZXJpbmcgdGhhdCBsaXN0IHdvdWxkIG5ldmVyIG1hdGNoOiBgaW5jbHVkZWAgbGlzdHMgVHlwZVNjcmlwdCBnbG9ic1xuICogKGAuL3NyYy8qKlxcLyoudHNgLCBcdTIwMjYpLCBzbyBubyBgLnN2ZWx0ZWAgcGF0aCBjYW4gZXZlciBhcHBlYXIgaW4gaXQgYW5kIHRoZSBjaGVjayB3b3VsZCBhbHdheXMgYmUgc2tpcHBlZC5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGNvZGUgY29tcGlsZXMgc3VjY2Vzc2Z1bGx5LlxuICogQHRocm93cyBJZiB0aGUgcHJvamVjdCBoYXMgU3ZlbHRlIGZpbGVzIGJ1dCBkb2VzIG5vdCBkZWNsYXJlIGBzdmVsdGUtY2hlY2tgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVpbGRDb21waWxlU3ZlbHRlKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB0c0NvbmZpZ1BhdGggPSByZXNvbHZlUGF0aEZyb21Sb290U2FmZSh7IHBhdGg6IE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuVHNDb25maWdKc29uIH0pO1xuICBjb25zdCB0c0NvbmZpZyA9IGF3YWl0IHJlYWRKc29uPFRzQ29uZmlnSnNvbj4odHNDb25maWdQYXRoKTtcbiAgY29uc3Qgc3ZlbHRlRmlsZXMgPSBhd2FpdCB0b0FycmF5KGdsb2IoU1ZFTFRFX0ZJTEVfUEFUVEVSTlMsIHtcbiAgICBjd2Q6IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlKHsgcGF0aDogT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5DdXJyZW50Rm9sZGVyIH0pLFxuICAgIGV4Y2x1ZGU6IFsuLi5TVkVMVEVfRklMRV9FWENMVURFX1BBVFRFUk5TLCAuLi50c0NvbmZpZy5leGNsdWRlID8/IFtdXVxuICB9KSk7XG5cbiAgY29uc3QgW2ZpcnN0U3ZlbHRlRmlsZV0gPSBzdmVsdGVGaWxlcztcblxuICBpZiAoZmlyc3RTdmVsdGVGaWxlID09PSB1bmRlZmluZWQpIHtcbiAgICBnZXRMaWJEZWJ1Z2dlcignYnVpbGQ6YnVpbGRDb21waWxlU3ZlbHRlJykoJ05vIFN2ZWx0ZSBmaWxlcyBmb3VuZCBpbiB0aGUgcHJvamVjdCwgc2tpcHBpbmcgU3ZlbHRlIGNvbXBpbGF0aW9uJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgcGFja2FnZUpzb24gPSBhd2FpdCByZWFkUGFja2FnZUpzb24oKTtcblxuICBpZiAoIWNoZWNrU3ZlbHRlQ2hlY2tEZWNsYXJlZChwYWNrYWdlSnNvbikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRm91bmQgU3ZlbHRlIGZpbGUocykgaW4gdGhlIHByb2plY3QgKGUuZy4gJHtmaXJzdFN2ZWx0ZUZpbGV9KSwgYnV0IFxcYCR7U1ZFTFRFX0NIRUNLX1BBQ0tBR0VfTkFNRX1cXGAgaXMgbm90IGRlY2xhcmVkIGluIHBhY2thZ2UuanNvbi5gXG4gICAgICAgICsgYCBBZGQgXFxgJHtTVkVMVEVfQ0hFQ0tfUEFDS0FHRV9OQU1FfVxcYCBhcyBhIGRldkRlcGVuZGVuY3kgdG8gdHlwZS1jaGVjayB0aGUgU3ZlbHRlIGNvZGUuYFxuICAgICk7XG4gIH1cblxuICBhd2FpdCBleGVjRnJvbVJvb3QoWy4uLnJlc29sdmVUb29sQ29tbWFuZCh7IHRvb2w6IFNWRUxURV9DSEVDS19QQUNLQUdFX05BTUUgfSksICctLXRzY29uZmlnJywgT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5Uc0NvbmZpZ0pzb25dKTtcbn1cblxuLyoqXG4gKiBDb21waWxlcyB0aGUgVHlwZVNjcmlwdCBjb2RlLlxuICpcbiAqIFRoZSBnZW5lcmFsIGB0c2NgIHBhc3MgcnVucyB3aXRoIGBza2lwTGliQ2hlY2s6IHRydWVgIChjb25maWd1cmVkIGluIGB0c2NvbmZpZy5qc29uYCkgc28gaXQgZG9lc1xuICogbm90IGZhaWwgb24gYnJva2VuIHVwc3RyZWFtIGAuZC50c2AgZmlsZXMgd2UgZG8gbm90IGNvbnRyb2wuIEFmdGVyd2FyZHMsIHtAbGluayBhcmVQcm9qZWN0VHlwZXNWYWxpZH1cbiAqIHJlLXJ1bnMgdGhlIHR5cGUtY2hlY2sgaW4tbWVtb3J5IHdpdGggYHNraXBMaWJDaGVjazogZmFsc2VgLCByZXBvcnRpbmcgb25seSBkaWFnbm9zdGljcyBmcm9tIHRoZVxuICogZmlsZXMgd2Ugb3duLCBzbyB0aGUgZGVjbGFyYXRpb25zIHdlIGF1dGhvciBhcmUgc3RpbGwgZnVsbHkgdmFsaWRhdGVkLlxuICpcbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29kZSBjb21waWxlcyBzdWNjZXNzZnVsbHkuXG4gKiBAdGhyb3dzIElmIHRoZSBwcm9qZWN0J3Mgb3duIGRlY2xhcmF0aW9ucyBmYWlsIHZhbGlkYXRpb24uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBidWlsZENvbXBpbGVUeXBlU2NyaXB0KCk6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBleGVjRnJvbVJvb3QoWy4uLnJlc29sdmVUb29sQ29tbWFuZCh7IHRvb2w6ICd0c2MnIH0pLCAnLS1idWlsZCcsICctLWZvcmNlJ10pO1xuXG4gIGlmICghYXJlUHJvamVjdFR5cGVzVmFsaWQoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVHlwZVNjcmlwdCBkZWNsYXJhdGlvbiB2YWxpZGF0aW9uIGZhaWxlZC4nKTtcbiAgfVxufVxuXG4vKipcbiAqIENvcGllcyBhbGwgdGVtcGxhdGUgZmlsZXMgZnJvbSB0aGUgdGVtcGxhdGVzIGZvbGRlciB0byB0aGUgYHRlbXBsYXRlc2AgZm9sZGVyIHdpdGhpbiB0aGVcbiAqIGRpc3RyaWJ1dGlvbiBmb2xkZXIuXG4gKlxuICogVGhpcyBmdW5jdGlvbiByZWN1cnNpdmVseSByZWFkcyB0aGUgY29udGVudHMgb2YgdGhlIHRlbXBsYXRlcyBmb2xkZXIgYW5kIGNvcGllcyBlYWNoIGZpbGUgdG8gdGhlXG4gKiBjb3JyZXNwb25kaW5nIHBhdGggdW5kZXIge0BsaW5rIE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuRGlzdFRlbXBsYXRlc30sIHNvIGNvbnN1bWVycyBjYW4gY29weSB0aGVcbiAqIHRlbXBsYXRlcyBmcm9tIGBub2RlX21vZHVsZXMvb2JzaWRpYW4tZGV2LXV0aWxzL2Rpc3QvdGVtcGxhdGVzYC4gQSB0cmFpbGluZyBgLnRlbXBsYXRlYCBvbiBhIHNvdXJjZVxuICogZmlsZSBuYW1lIGlzIHN0cmlwcGVkIGluIHRoZSBkZXN0aW5hdGlvbiAoZS5nLiBgZXNsaW50LmNvbmZpZy5tdHMudGVtcGxhdGVgIGlzIGNvcGllZCBhc1xuICogYGVzbGludC5jb25maWcubXRzYCksIHNvIGFuIGFjdGl2ZSBjb25maWcgdGVtcGxhdGUgY2FuIGxpdmUgaW4gdGhlIHJlcG8gdW5kZXIgYSBuYW1lIHRoYXQgdGhlXG4gKiBjb3JyZXNwb25kaW5nIHRvb2wgZG9lcyBub3QgYXV0by1kaXNjb3Zlci5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdoZW4gYWxsIGZpbGVzIGhhdmUgYmVlbiBjb3BpZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBidWlsZFRlbXBsYXRlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgZm9yIChjb25zdCBkaXJlbnQgb2YgYXdhaXQgcmVhZGRpclBvc2l4KE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuVGVtcGxhdGVzLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KSkge1xuICAgIGlmICghZGlyZW50LmlzRmlsZSgpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBwYXRoID0gdHJpbVN0YXJ0KHtcbiAgICAgICRzdHJpbmc6IGpvaW4oZGlyZW50LnBhcmVudFBhdGgsIGRpcmVudC5uYW1lKSxcbiAgICAgIHByZWZpeDogYCR7T2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5UZW1wbGF0ZXN9L2BcbiAgICB9KTtcbiAgICBjb25zdCBkZXN0aW5hdGlvblBhdGggPSBwYXRoLmVuZHNXaXRoKFRFTVBMQVRFX0ZJTEVfU1VGRklYKSA/IHBhdGguc2xpY2UoMCwgLVRFTVBMQVRFX0ZJTEVfU1VGRklYLmxlbmd0aCkgOiBwYXRoO1xuICAgIGF3YWl0IGNwKGpvaW4oT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5UZW1wbGF0ZXMsIHBhdGgpLCBqb2luKE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuRGlzdFRlbXBsYXRlcywgZGVzdGluYXRpb25QYXRoKSk7XG4gIH1cbn1cblxuY29uc3QgVEVNUExBVEVfRklMRV9TVUZGSVggPSAnLnRlbXBsYXRlJztcblxuY29uc3QgTk9ERV9NT0RVTEVTX1NFR01FTlQgPSAnL25vZGVfbW9kdWxlcy8nO1xuXG5jb25zdCBTVkVMVEVfQ0hFQ0tfUEFDS0FHRV9OQU1FID0gJ3N2ZWx0ZS1jaGVjayc7XG5cbmNvbnN0IFNWRUxURV9GSUxFX1BBVFRFUk5TID0gW1xuICBgJHtPYnNpZGlhbkRldlV0aWxzUmVwb1BhdGhzLkFueVBhdGh9Lyouc3ZlbHRlYCxcbiAgYCR7T2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5BbnlQYXRofS8qLnN2ZWx0ZS5qc2AsXG4gIGAke09ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuQW55UGF0aH0vKi5zdmVsdGUudHNgXG5dO1xuXG4vKipcbiAqIGBub2RlX21vZHVsZXNgIG11c3QgYmUgbGlzdGVkIGV4cGxpY2l0bHk6IGEgdHNjb25maWcgdGhhdCBzZXRzIGBleGNsdWRlYCBhdCBhbGwgKipyZXBsYWNlcyoqIFR5cGVTY3JpcHQnc1xuICogZGVmYXVsdCBgbm9kZV9tb2R1bGVzYCBleGNsdXNpb24sIHNvIGl0IGNhbm5vdCBiZSByZWxpZWQgb24gdG8ga2VlcCBkZXBlbmRlbmNpZXMgb3V0IG9mIHRoZSBnbG9iLlxuICovXG5jb25zdCBTVkVMVEVfRklMRV9FWENMVURFX1BBVFRFUk5TID0gW1xuICBgJHtPYnNpZGlhbkRldlV0aWxzUmVwb1BhdGhzLkFueVBhdGh9LyR7T2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5Ob2RlTW9kdWxlc30vJHtPYnNpZGlhbkRldlV0aWxzUmVwb1BhdGhzLkFueVBhdGh9YCxcbiAgYCR7T2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5BbnlQYXRofS8ke09ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuRGlzdH0vJHtPYnNpZGlhbkRldlV0aWxzUmVwb1BhdGhzLkFueVBhdGh9YFxuXTtcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgc2hvdWxkS2VlcFByb2plY3RGaWxlfS5cbiAqL1xuaW50ZXJmYWNlIFNob3VsZEtlZXBQcm9qZWN0RmlsZVBhcmFtcyB7XG4gIC8qKlxuICAgKiBBYnNvbHV0ZSBwYXRoIG9mIHRoZSBmaWxlIHVuZGVyIGNvbnNpZGVyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBmaWxlTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBYnNvbHV0ZSAoY2Fub25pY2FsKSBwYXRoIG9mIHRoZSBwcm9qZWN0IHJvb3QuXG4gICAqL1xuICByZWFkb25seSByb290Q2Fub25pY2FsOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmUtcnVucyB0aGUgcHJvamVjdCB0eXBlLWNoZWNrIGluLW1lbW9yeSB3aXRoIGBza2lwTGliQ2hlY2s6IGZhbHNlYCwgcmVwb3J0aW5nIG9ubHkgZGlhZ25vc3RpY3NcbiAqIHdob3NlIHNvdXJjZSBmaWxlIGJlbG9uZ3MgdG8gdGhlIHByb2plY3QgKHVuZGVyIHRoZSByb290IGZvbGRlciwgb3V0c2lkZSBgbm9kZV9tb2R1bGVzYCkuXG4gKlxuICogQHJldHVybnMgYHRydWVgIHdoZW4gdGhlIHByb2plY3QncyBvd24gZmlsZXMgaGF2ZSBubyB0eXBlIGVycm9ycywgYGZhbHNlYCBvdGhlcndpc2UuXG4gKiBAdGhyb3dzIElmIHRoZSByb290IGZvbGRlciBjYW5ub3QgYmUgZm91bmQuXG4gKi9cbmZ1bmN0aW9uIGFyZVByb2plY3RUeXBlc1ZhbGlkKCk6IGJvb2xlYW4ge1xuICBjb25zdCByb290ID0gZ2V0Um9vdEZvbGRlcigpO1xuXG4gIGlmICghcm9vdCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGZpbmQgcm9vdCBmb2xkZXInKTtcbiAgfVxuXG4gIGNvbnN0IHJvb3RDYW5vbmljYWwgPSB0b0Nhbm9uaWNhbChyb290KTtcbiAgY29uc3QgeyBmaWxlTmFtZXMsIG9wdGlvbnMgfSA9IHBhcnNlVHNDb25maWcoam9pbihyb290LCBPYnNpZGlhbkRldlV0aWxzUmVwb1BhdGhzLlRzQ29uZmlnSnNvbikpO1xuXG4gIHJldHVybiBjaGVja1Byb2plY3RUeXBlcyh7XG4gICAgb3B0aW9ucyxcbiAgICByb290TmFtZXM6IGZpbGVOYW1lcyxcbiAgICBzaG91bGRLZWVwRmlsZTogKGZpbGVOYW1lKSA9PiBzaG91bGRLZWVwUHJvamVjdEZpbGUoeyBmaWxlTmFtZSwgcm9vdENhbm9uaWNhbCB9KVxuICB9KTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHByb2plY3QgZGVjbGFyZXMgYHN2ZWx0ZS1jaGVja2AuXG4gKlxuICogVGhlIGRlY2xhcmF0aW9uIGlzIHJlYWQgZnJvbSBgcGFja2FnZS5qc29uYCByYXRoZXIgdGhhbiBwcm9iZWQgaW4gYG5vZGVfbW9kdWxlcy8uYmluYCwgYmVjYXVzZVxuICoge0BsaW5rIHJlc29sdmVUb29sQ29tbWFuZH0gZGVsaWJlcmF0ZWx5IGZhbGxzIGJhY2sgdG8gdGhlIHBhY2thZ2UgbWFuYWdlcidzIGV4ZWMgZm9ybSBmb3IgdG9vbHMgdGhhdCBoYXZlXG4gKiBubyBiaW4gc2hpbSBcdTIwMTQgdGhlIG9ubHkgd2F5IGEgbG9jYWxseSBpbnN0YWxsZWQgdG9vbCByZXNvbHZlcyB1bmRlciB5YXJuIFBuUC4gVHJlYXRpbmcgYSBtaXNzaW5nIHNoaW0gYXMgYVxuICogbWlzc2luZyB0b29sIHdvdWxkIHRoZXJlZm9yZSBicmVhayBQblAgcHJvamVjdHMuXG4gKlxuICogQHBhcmFtIHBhY2thZ2VKc29uIC0gVGhlIHByb2plY3QncyBwYXJzZWQgYHBhY2thZ2UuanNvbmAuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiBgc3ZlbHRlLWNoZWNrYCBpcyBkZWNsYXJlZCBhcyBhIHJlZ3VsYXIsIGRldiwgb3IgcGVlciBkZXBlbmRlbmN5LlxuICovXG5mdW5jdGlvbiBjaGVja1N2ZWx0ZUNoZWNrRGVjbGFyZWQocGFja2FnZUpzb246IFBhY2thZ2VKc29uKTogYm9vbGVhbiB7XG4gIHJldHVybiBbcGFja2FnZUpzb24uZGVwZW5kZW5jaWVzLCBwYWNrYWdlSnNvbi5kZXZEZXBlbmRlbmNpZXMsIHBhY2thZ2VKc29uLnBlZXJEZXBlbmRlbmNpZXNdXG4gICAgLnNvbWUoKGRlcGVuZGVuY2llcykgPT4gZGVwZW5kZW5jaWVzPy5bU1ZFTFRFX0NIRUNLX1BBQ0tBR0VfTkFNRV0gIT09IHVuZGVmaW5lZCk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgZmlsZSBiZWxvbmdzIHRvIHRoZSBwcm9qZWN0ICh1bmRlciB0aGUgcm9vdCBmb2xkZXIsIG91dHNpZGUgYG5vZGVfbW9kdWxlc2ApLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhlIGNoZWNrLlxuICogQHJldHVybnMgYHRydWVgIHdoZW4gdGhlIGZpbGUgYmVsb25ncyB0byB0aGUgcHJvamVjdC5cbiAqL1xuZnVuY3Rpb24gc2hvdWxkS2VlcFByb2plY3RGaWxlKHBhcmFtczogU2hvdWxkS2VlcFByb2plY3RGaWxlUGFyYW1zKTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgZmlsZU5hbWUsIHJvb3RDYW5vbmljYWwgfSA9IHBhcmFtcztcbiAgcmV0dXJuIGZpbGVOYW1lLnN0YXJ0c1dpdGgoYCR7cm9vdENhbm9uaWNhbH0vYCkgJiYgIWZpbGVOYW1lLmluY2x1ZGVzKE5PREVfTU9EVUxFU19TRUdNRU5UKTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFhQTtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFFUCxTQUFTLGVBQWU7QUFDeEIsU0FBUyxzQkFBc0I7QUFDL0IsU0FBUyxZQUFZO0FBQ3JCLFNBQVMsaUJBQWlCO0FBQzFCO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsb0JBQW9CO0FBQzdCLFNBQVMsZ0JBQWdCO0FBQ3pCO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsU0FBUyx1QkFBdUI7QUFDaEMsU0FBUyxpQ0FBaUM7QUFDMUMsU0FBUywwQkFBMEI7QUFDbkM7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBU1AsZUFBc0IsYUFBNEI7QUFDaEQsUUFBTSxHQUFHLDBCQUEwQixNQUFNLEVBQUUsT0FBTyxNQUFNLFdBQVcsS0FBSyxDQUFDO0FBQzNFO0FBT0EsZUFBc0IsZUFBOEI7QUFDbEQsTUFBSSxNQUFNLGVBQWUsc0JBQXNCLE1BQU0scUJBQXFCLFNBQVM7QUFDakYsVUFBTSxtQkFBbUI7QUFBQSxFQUMzQjtBQUNBLE1BQUksTUFBTSxlQUFlLDBCQUEwQixNQUFN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
@@ -6,22 +6,26 @@
6
6
  *
7
7
  * A plugin can ship a curated demo vault at `demo-vault/` in its repo root. At release time this
8
8
  * module installs the freshly built plugin into that vault's `.obsidian/plugins/<id>/` folder and
9
- * zips the whole vault into `dist/build/<plugin-id>-demo-vault-<version>.zip`, so the existing
10
- * GitHub-release step (which uploads every file in `dist/build/`) attaches it automatically. The
11
- * archive name carries the plugin id (so several plugins' demo vaults never collide) and the version
12
- * (so each release ships its own distinctly named artifact).
9
+ * zips the whole vault into `dist/build/<plugin-id>-demo-vault.zip`, so the existing GitHub-release
10
+ * step (which uploads every file in `dist/build/`) attaches it automatically.
11
+ *
12
+ * The version is deliberately absent from that name and lives INSIDE the archive instead — see
13
+ * `obsidian/demo-vault-naming.ts` for why — in the two places a person actually meets it: the vault
14
+ * sits under a single `<plugin-id>-demo-vault-<version>/` folder, so unzipping several releases by hand
15
+ * into one folder neither collides nor produces anonymous directories, and the vault's `README.md`
16
+ * heading gains the version it demonstrates.
13
17
  *
14
18
  * The archived copy also carries the `.obsidian/app.json` settings this package owns (see
15
- * `demo-vault-app-json.ts`). They are written into the ZIP ENTRY and never into the repo folder: the
16
- * committed `app.json` is a tracked file, and `updateVersion` archives after it has already pushed, so
17
- * an in-place write would leave an uncommitted change behind a published release.
19
+ * `demo-vault-app-json.ts`). Those settings and the README heading are written into the ZIP ENTRY and
20
+ * never into the repo folder: both files are tracked, and `updateVersion` archives after it has already
21
+ * pushed, so an in-place write would leave an uncommitted change behind a published release.
18
22
  */
19
23
  /**
20
24
  * Archives the plugin's demo vault (`demo-vault/` in the repo root) as a release artifact.
21
25
  *
22
26
  * Installs the freshly built plugin from `dist/build/` into the vault's
23
27
  * `.obsidian/plugins/<id>/` folder, then zips the whole vault to
24
- * `dist/build/<plugin-id>-demo-vault-<version>.zip`.
28
+ * `dist/build/<plugin-id>-demo-vault.zip`, under a single `<plugin-id>-demo-vault-<version>/` folder.
25
29
  *
26
30
  * @returns A {@link Promise} that resolves to the absolute path of the created zip archive, or
27
31
  * `null` if the repo has no `demo-vault/` folder.
@@ -49,6 +49,10 @@ import {
49
49
  readFile,
50
50
  writeFile
51
51
  } from "node:fs/promises";
52
+ import {
53
+ getDemoVaultArchiveFileName,
54
+ getDemoVaultFolderName
55
+ } from "../obsidian/demo-vault-naming.mjs";
52
56
  import { ObsidianPluginRepoPaths } from "../obsidian/plugin/obsidian-plugin-repo-paths.mjs";
53
57
  import {
54
58
  getFolderName,
@@ -67,6 +71,8 @@ import {
67
71
  const DEMO_VAULT_HELPER_PLUGIN_ID = "demo-vault-helper";
68
72
  const DATA_JSON_FILE_NAME = "data.json";
69
73
  const DATA_JSON_INDENT = 2;
74
+ const README_FILE_NAME = "README.md";
75
+ const OPENING_HEADING_REG_EXP = /^# .*/;
70
76
  async function archivePluginDemoVault() {
71
77
  const demoVaultPath = resolvePathFromRootSafe({ path: ObsidianPluginRepoPaths.DemoVault });
72
78
  if (!existsSync(demoVaultPath)) {
@@ -87,16 +93,21 @@ async function archivePluginDemoVault() {
87
93
  await cp(distBuildPath, pluginFolder, { recursive: true });
88
94
  await injectDemoVaultHelper(manifest.id);
89
95
  const zipPath = resolvePathFromRootSafe({
90
- path: join(ObsidianPluginRepoPaths.DistBuild, `${manifest.id}-demo-vault-${manifest.version}.zip`)
96
+ path: join(ObsidianPluginRepoPaths.DistBuild, getDemoVaultArchiveFileName(manifest.id))
97
+ });
98
+ const rootFolderName = getDemoVaultFolderName({
99
+ pluginId: manifest.id,
100
+ version: manifest.version
91
101
  });
92
102
  const zip = new AdmZip();
93
- zip.addLocalFolder(demoVaultPath);
94
- injectAppJson(zip, await readCommittedAppJson());
103
+ zip.addLocalFolder(demoVaultPath, rootFolderName);
104
+ injectAppJson(zip, await readCommittedAppJson(), rootFolderName);
105
+ injectReadmeVersion(zip, rootFolderName, manifest.version);
95
106
  await zip.writeZipPromise(zipPath);
96
107
  return zipPath;
97
108
  }
98
- function injectAppJson(zip, appJson) {
99
- const entryName = join(ObsidianPluginRepoPaths.DotObsidian, ObsidianPluginRepoPaths.AppJson);
109
+ function injectAppJson(zip, appJson, rootFolderName) {
110
+ const entryName = join(rootFolderName, ObsidianPluginRepoPaths.DotObsidian, ObsidianPluginRepoPaths.AppJson);
100
111
  const content = Buffer.from(buildArchivedDemoVaultAppJsonContent({ appJson }), "utf-8");
101
112
  const entry = zip.getEntry(entryName);
102
113
  if (entry) {
@@ -125,6 +136,18 @@ async function injectDemoVaultHelper(demoedPluginId) {
125
136
  await writeFile(join(helperFolder, DATA_JSON_FILE_NAME), `${JSON.stringify(settings, null, DATA_JSON_INDENT)}
126
137
  `, "utf-8");
127
138
  }
139
+ function injectReadmeVersion(zip, rootFolderName, version) {
140
+ const entry = zip.getEntry(join(rootFolderName, README_FILE_NAME));
141
+ if (!entry) {
142
+ return;
143
+ }
144
+ const content = entry.getData().toString("utf-8");
145
+ const versionedContent = content.replace(OPENING_HEADING_REG_EXP, (heading) => `${heading} v${version}`);
146
+ if (versionedContent === content) {
147
+ return;
148
+ }
149
+ zip.updateFile(entry, Buffer.from(versionedContent, "utf-8"));
150
+ }
128
151
  async function readCommittedAppJson() {
129
152
  const appJsonPath = resolvePathFromRootSafe({
130
153
  path: join(ObsidianPluginRepoPaths.DemoVault, ObsidianPluginRepoPaths.DotObsidian, ObsidianPluginRepoPaths.AppJson)
@@ -142,4 +165,4 @@ async function readCommittedAppJson() {
142
165
  export {
143
166
  archivePluginDemoVault
144
167
  };
145
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3NjcmlwdC11dGlscy9kZW1vLXZhdWx0LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQXJjaGl2ZXMgYSBwbHVnaW4ncyBkZW1vIHZhdWx0IGFzIGEgcmVsZWFzZSBhcnRpZmFjdC5cbiAqXG4gKiBBIHBsdWdpbiBjYW4gc2hpcCBhIGN1cmF0ZWQgZGVtbyB2YXVsdCBhdCBgZGVtby12YXVsdC9gIGluIGl0cyByZXBvIHJvb3QuIEF0IHJlbGVhc2UgdGltZSB0aGlzXG4gKiBtb2R1bGUgaW5zdGFsbHMgdGhlIGZyZXNobHkgYnVpbHQgcGx1Z2luIGludG8gdGhhdCB2YXVsdCdzIGAub2JzaWRpYW4vcGx1Z2lucy88aWQ+L2AgZm9sZGVyIGFuZFxuICogemlwcyB0aGUgd2hvbGUgdmF1bHQgaW50byBgZGlzdC9idWlsZC88cGx1Z2luLWlkPi1kZW1vLXZhdWx0LTx2ZXJzaW9uPi56aXBgLCBzbyB0aGUgZXhpc3RpbmdcbiAqIEdpdEh1Yi1yZWxlYXNlIHN0ZXAgKHdoaWNoIHVwbG9hZHMgZXZlcnkgZmlsZSBpbiBgZGlzdC9idWlsZC9gKSBhdHRhY2hlcyBpdCBhdXRvbWF0aWNhbGx5LiBUaGVcbiAqIGFyY2hpdmUgbmFtZSBjYXJyaWVzIHRoZSBwbHVnaW4gaWQgKHNvIHNldmVyYWwgcGx1Z2lucycgZGVtbyB2YXVsdHMgbmV2ZXIgY29sbGlkZSkgYW5kIHRoZSB2ZXJzaW9uXG4gKiAoc28gZWFjaCByZWxlYXNlIHNoaXBzIGl0cyBvd24gZGlzdGluY3RseSBuYW1lZCBhcnRpZmFjdCkuXG4gKlxuICogVGhlIGFyY2hpdmVkIGNvcHkgYWxzbyBjYXJyaWVzIHRoZSBgLm9ic2lkaWFuL2FwcC5qc29uYCBzZXR0aW5ncyB0aGlzIHBhY2thZ2Ugb3ducyAoc2VlXG4gKiBgZGVtby12YXVsdC1hcHAtanNvbi50c2ApLiBUaGV5IGFyZSB3cml0dGVuIGludG8gdGhlIFpJUCBFTlRSWSBhbmQgbmV2ZXIgaW50byB0aGUgcmVwbyBmb2xkZXI6IHRoZVxuICogY29tbWl0dGVkIGBhcHAuanNvbmAgaXMgYSB0cmFja2VkIGZpbGUsIGFuZCBgdXBkYXRlVmVyc2lvbmAgYXJjaGl2ZXMgYWZ0ZXIgaXQgaGFzIGFscmVhZHkgcHVzaGVkLCBzb1xuICogYW4gaW4tcGxhY2Ugd3JpdGUgd291bGQgbGVhdmUgYW4gdW5jb21taXR0ZWQgY2hhbmdlIGJlaGluZCBhIHB1Ymxpc2hlZCByZWxlYXNlLlxuICovXG5cbmltcG9ydCBBZG1aaXAgZnJvbSAnYWRtLXppcCc7XG5pbXBvcnQgeyBleGlzdHNTeW5jIH0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBjcCxcbiAgbWtkaXIsXG4gIHJlYWRGaWxlLFxuICB3cml0ZUZpbGVcbn0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5cbmltcG9ydCB0eXBlIHsgRGVtb1ZhdWx0SGVscGVyU2V0dGluZ3MgfSBmcm9tICcuLi9vYnNpZGlhbi9kZW1vLXZhdWx0LWhlbHBlci1zZXR0aW5ncy50cyc7XG5pbXBvcnQgdHlwZSB7IERlbW9WYXVsdEFwcEpzb24gfSBmcm9tICcuL2RlbW8tdmF1bHQtYXBwLWpzb24udHMnO1xuXG5pbXBvcnQgeyBPYnNpZGlhblBsdWdpblJlcG9QYXRocyB9IGZyb20gJy4uL29ic2lkaWFuL3BsdWdpbi9vYnNpZGlhbi1wbHVnaW4tcmVwby1wYXRocy50cyc7XG5pbXBvcnQge1xuICBnZXRGb2xkZXJOYW1lLFxuICBqb2luXG59IGZyb20gJy4uL3BhdGgudHMnO1xuaW1wb3J0IHtcbiAgYnVpbGRBcmNoaXZlZERlbW9WYXVsdEFwcEpzb25Db250ZW50LFxuICBmaW5kT3duZWREZW1vVmF1bHRBcHBKc29uU2V0dGluZ3MsXG4gIHBhcnNlRGVtb1ZhdWx0QXBwSnNvblxufSBmcm9tICcuL2RlbW8tdmF1bHQtYXBwLWpzb24udHMnO1xuaW1wb3J0IHsgT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocyB9IGZyb20gJy4vb2JzaWRpYW4tZGV2LXV0aWxzLXJlcG8tcGF0aHMudHMnO1xuaW1wb3J0IHtcbiAgZ2V0Um9vdEZvbGRlcixcbiAgcmVzb2x2ZVBhdGhGcm9tUm9vdFNhZmVcbn0gZnJvbSAnLi9yb290LnRzJztcblxuY29uc3QgREVNT19WQVVMVF9IRUxQRVJfUExVR0lOX0lEID0gJ2RlbW8tdmF1bHQtaGVscGVyJztcbmNvbnN0IERBVEFfSlNPTl9GSUxFX05BTUUgPSAnZGF0YS5qc29uJztcbmNvbnN0IERBVEFfSlNPTl9JTkRFTlQgPSAyO1xuXG4vKipcbiAqIFRoZSBtaW5pbWFsIHNoYXBlIG9mIGEgcGx1Z2luIGBtYW5pZmVzdC5qc29uYCByZWFkIGJ5IHtAbGluayBhcmNoaXZlUGx1Z2luRGVtb1ZhdWx0fS5cbiAqL1xuaW50ZXJmYWNlIFBsdWdpbk1hbmlmZXN0IHtcbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4gaWQsIHVzZWQgYXMgdGhlIGZvbGRlciBuYW1lIHVuZGVyIGBkZW1vLXZhdWx0Ly5vYnNpZGlhbi9wbHVnaW5zL2AuXG4gICAqL1xuICByZWFkb25seSBpZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcGx1Z2luIHZlcnNpb24sIGVtYmVkZGVkIGluIHRoZSBhcmNoaXZlIGZpbGUgbmFtZS5cbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb246IHN0cmluZztcbn1cblxuLyoqXG4gKiBBcmNoaXZlcyB0aGUgcGx1Z2luJ3MgZGVtbyB2YXVsdCAoYGRlbW8tdmF1bHQvYCBpbiB0aGUgcmVwbyByb290KSBhcyBhIHJlbGVhc2UgYXJ0aWZhY3QuXG4gKlxuICogSW5zdGFsbHMgdGhlIGZyZXNobHkgYnVpbHQgcGx1Z2luIGZyb20gYGRpc3QvYnVpbGQvYCBpbnRvIHRoZSB2YXVsdCdzXG4gKiBgLm9ic2lkaWFuL3BsdWdpbnMvPGlkPi9gIGZvbGRlciwgdGhlbiB6aXBzIHRoZSB3aG9sZSB2YXVsdCB0b1xuICogYGRpc3QvYnVpbGQvPHBsdWdpbi1pZD4tZGVtby12YXVsdC08dmVyc2lvbj4uemlwYC5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHRvIHRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBjcmVhdGVkIHppcCBhcmNoaXZlLCBvclxuICogYG51bGxgIGlmIHRoZSByZXBvIGhhcyBubyBgZGVtby12YXVsdC9gIGZvbGRlci5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFyY2hpdmVQbHVnaW5EZW1vVmF1bHQoKTogUHJvbWlzZTxudWxsIHwgc3RyaW5nPiB7XG4gIGNvbnN0IGRlbW9WYXVsdFBhdGggPSByZXNvbHZlUGF0aEZyb21Sb290U2FmZSh7IHBhdGg6IE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzLkRlbW9WYXVsdCB9KTtcbiAgaWYgKCFleGlzdHNTeW5jKGRlbW9WYXVsdFBhdGgpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBtYW5pZmVzdFBhdGggPSByZXNvbHZlUGF0aEZyb21Sb290U2FmZSh7IHBhdGg6IE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzLk1hbmlmZXN0SnNvbiB9KTtcbiAgY29uc3QgbWFuaWZlc3QgPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRGaWxlKG1hbmlmZXN0UGF0aCwgJ3V0Zi04JykpIGFzIFBsdWdpbk1hbmlmZXN0O1xuXG4gIGNvbnN0IHBsdWdpbkZvbGRlciA9IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlKHtcbiAgICBwYXRoOiBqb2luKFxuICAgICAgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuRGVtb1ZhdWx0LFxuICAgICAgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuRG90T2JzaWRpYW4sXG4gICAgICBPYnNpZGlhblBsdWdpblJlcG9QYXRocy5QbHVnaW5zLFxuICAgICAgbWFuaWZlc3QuaWRcbiAgICApXG4gIH0pO1xuICBhd2FpdCBta2RpcihwbHVnaW5Gb2xkZXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuXG4gIGNvbnN0IGRpc3RCdWlsZFBhdGggPSByZXNvbHZlUGF0aEZyb21Sb290U2FmZSh7IHBhdGg6IE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzLkRpc3RCdWlsZCB9KTtcbiAgYXdhaXQgY3AoZGlzdEJ1aWxkUGF0aCwgcGx1Z2luRm9sZGVyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICBhd2FpdCBpbmplY3REZW1vVmF1bHRIZWxwZXIobWFuaWZlc3QuaWQpO1xuXG4gIC8vIEFyY2hpdmUgbmFtZSBpcyBoYW5kLXN5bmNlZCB3aXRoIHRoZSBydW50aW1lIGBvcGVuRGVtb1ZhdWx0YCBvcGVuZXIsIHdoaWNoIGRvd25sb2FkcyB0aGlzIGV4YWN0IGFzc2V0IG5hbWUuXG4gIGNvbnN0IHppcFBhdGggPSByZXNvbHZlUGF0aEZyb21Sb290U2FmZSh7XG4gICAgcGF0aDogam9pbihPYnNpZGlhblBsdWdpblJlcG9QYXRocy5EaXN0QnVpbGQsIGAke21hbmlmZXN0LmlkfS1kZW1vLXZhdWx0LSR7bWFuaWZlc3QudmVyc2lvbn0uemlwYClcbiAgfSk7XG4gIGNvbnN0IHppcCA9IG5ldyBBZG1aaXAoKTtcbiAgemlwLmFkZExvY2FsRm9sZGVyKGRlbW9WYXVsdFBhdGgpO1xuICBpbmplY3RBcHBKc29uKHppcCwgYXdhaXQgcmVhZENvbW1pdHRlZEFwcEpzb24oKSk7XG4gIGF3YWl0IHppcC53cml0ZVppcFByb21pc2UoemlwUGF0aCk7XG4gIHJldHVybiB6aXBQYXRoO1xufVxuXG4vLyBTdG9yZXMgdGhlIGFyY2hpdmVkIHZhdWx0J3MgYC5vYnNpZGlhbi9hcHAuanNvbmAgXHUyMDE0IHRoZSBjb21taXR0ZWQgc2V0dGluZ3Mgd2l0aCB0aGUgb3duZWQgb25lcyBtZXJnZWRcbi8vIE92ZXIgdGhlbS4gVGhlIGVudHJ5IGlzIHJlcGxhY2VkIHJhdGhlciB0aGFuIHRoZSBmaWxlLCBzbyB0aGUgcmVwbyBmb2xkZXIgaXMgbGVmdCBleGFjdGx5IGFzIGl0IHdhcy5cbmZ1bmN0aW9uIGluamVjdEFwcEpzb24oemlwOiBBZG1aaXAsIGFwcEpzb246IERlbW9WYXVsdEFwcEpzb24pOiB2b2lkIHtcbiAgY29uc3QgZW50cnlOYW1lID0gam9pbihPYnNpZGlhblBsdWdpblJlcG9QYXRocy5Eb3RPYnNpZGlhbiwgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuQXBwSnNvbik7XG4gIGNvbnN0IGNvbnRlbnQgPSBCdWZmZXIuZnJvbShidWlsZEFyY2hpdmVkRGVtb1ZhdWx0QXBwSnNvbkNvbnRlbnQoeyBhcHBKc29uIH0pLCAndXRmLTgnKTtcbiAgY29uc3QgZW50cnkgPSB6aXAuZ2V0RW50cnkoZW50cnlOYW1lKTtcbiAgaWYgKGVudHJ5KSB7XG4gICAgemlwLnVwZGF0ZUZpbGUoZW50cnksIGNvbnRlbnQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEEgdmF1bHQgd2l0aCBub3RoaW5nIGVsc2UgdG8gY29uZmlndXJlIGNvbW1pdHMgbm8gYGFwcC5qc29uYCBhdCBhbGwsIHdoaWNoIGlzIHRoZSBleHBlY3RlZCBzdGF0ZS5cbiAgemlwLmFkZEZpbGUoZW50cnlOYW1lLCBjb250ZW50KTtcbn1cblxuLy8gSW5qZWN0cyB0aGUgYnVpbHQsIGBvYnNpZGlhbi1kZXYtdXRpbHNgLW93bmVkIGBkZW1vLXZhdWx0LWhlbHBlcmAgYm9vdHN0cmFwIHBsdWdpbiAoc2hpcHBlZCBpbiB0aGlzIHBhY2thZ2UpIGludG8gdGhlIGRlbW8gdmF1bHQsIHNvIG5vIHBlci12YXVsdCBjb3B5IGlzIGNvbW1pdHRlZCBhbmQgYW4gYG9ic2lkaWFuLWRldi11dGlsc2AgYnVtcCBwcm9wYWdhdGVzIGZpeGVzLlxuLy9cbi8vIEFsb25nc2lkZSB0aGUgYmluYXJpZXMgaXQgd3JpdGVzIHRoZSBoZWxwZXIncyBvd24gYGRhdGEuanNvbmAgbmFtaW5nIHRoZSBkZW1vbnN0cmF0ZWQgcGx1Z2luLiBUaGF0IGlzXG4vLyBUaGUgb25lIG1vbWVudCB0aGUgaWQgaXMga25vd24gZm9yIGNlcnRhaW4gXHUyMDE0IGl0IGNvbWVzIGZyb20gdGhlIHBsdWdpbidzIG93biBtYW5pZmVzdCBcdTIwMTQgd2hlcmVhcyB0aGVcbi8vIE9wZW5lZCB2YXVsdCBvbmx5IG9mZmVycyBwbHVnaW4gZm9sZGVycyB0byBjb3VudCwgd2hpY2ggdGhlIGJvb3RzdHJhcCBpdHNlbGYgYWRkcyB0byAoc2VlXG4vLyBgRGVtb1ZhdWx0SGVscGVyU2V0dGluZ3NgKS5cbmFzeW5jIGZ1bmN0aW9uIGluamVjdERlbW9WYXVsdEhlbHBlcihkZW1vZWRQbHVnaW5JZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHBhY2thZ2VGb2xkZXIgPSBnZXRSb290Rm9sZGVyKGdldEZvbGRlck5hbWUoaW1wb3J0Lm1ldGEudXJsKSk7XG4gIGlmICghcGFja2FnZUZvbGRlcikge1xuICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IHJlc29sdmUgdGhlIG9ic2lkaWFuLWRldi11dGlscyBwYWNrYWdlIGZvbGRlciB0byBpbmplY3QgdGhlIGRlbW8tdmF1bHQtaGVscGVyIHBsdWdpbi4nKTtcbiAgfVxuXG4gIGNvbnN0IGhlbHBlclNvdXJjZVBhdGggPSBqb2luKHBhY2thZ2VGb2xkZXIsIE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuRGlzdERlbW9WYXVsdEhlbHBlcik7XG4gIGNvbnN0IGhlbHBlckZvbGRlciA9IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlKHtcbiAgICBwYXRoOiBqb2luKFxuICAgICAgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuRGVtb1ZhdWx0LFxuICAgICAgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuRG90T2JzaWRpYW4sXG4gICAgICBPYnNpZGlhblBsdWdpblJlcG9QYXRocy5QbHVnaW5zLFxuICAgICAgREVNT19WQVVMVF9IRUxQRVJfUExVR0lOX0lEXG4gICAgKVxuICB9KTtcbiAgYXdhaXQgbWtkaXIoaGVscGVyRm9sZGVyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgYXdhaXQgY3AoaGVscGVyU291cmNlUGF0aCwgaGVscGVyRm9sZGVyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICBjb25zdCBzZXR0aW5nczogRGVtb1ZhdWx0SGVscGVyU2V0dGluZ3MgPSB7IGRlbW9lZFBsdWdpbklkIH07XG4gIGF3YWl0IHdyaXRlRmlsZShqb2luKGhlbHBlckZvbGRlciwgREFUQV9KU09OX0ZJTEVfTkFNRSksIGAke0pTT04uc3RyaW5naWZ5KHNldHRpbmdzLCBudWxsLCBEQVRBX0pTT05fSU5ERU5UKX1cXG5gLCAndXRmLTgnKTtcbn1cblxuLy8gUmVhZHMgdGhlIGRlbW8gdmF1bHQncyBjb21taXR0ZWQgYC5vYnNpZGlhbi9hcHAuanNvbmAsIHJlZnVzaW5nIHRoZSBzZXR0aW5ncyB0aGlzIHBhY2thZ2Ugb3ducy5cbi8vXG4vLyBUaG9zZSBzZXR0aW5ncyBhcmUgaW5qZWN0ZWQgaW50byB0aGUgYXJjaGl2ZSwgc28gYSBjb21taXR0ZWQgb25lIGlzIGEgc2Vjb25kIHNvdXJjZSBvZiB0cnV0aCB0aGF0XG4vLyBOb3RoaW5nIGtlZXBzIGluIHN0ZXAuIFRoZSBkZW1vLXZhdWx0IGNvdmVyYWdlIHN1aXRlIGFscmVhZHkgZmFpbHMgb24gaXQsIHdoaWNoIG1lYW5zIHJlYWNoaW5nIGhlcmVcbi8vIE1lYW5zIHRoYXQgZ2F0ZSB3YXMgc2tpcHBlZCBcdTIwMTQgc28gdGhpcyByZWZ1c2VzIHJhdGhlciB0aGFuIG92ZXJ3cml0aW5nIGEgdmFsdWUgc29tZWJvZHkgY2hvc2Ugb24gcHVycG9zZS5cbmFzeW5jIGZ1bmN0aW9uIHJlYWRDb21taXR0ZWRBcHBKc29uKCk6IFByb21pc2U8RGVtb1ZhdWx0QXBwSnNvbj4ge1xuICBjb25zdCBhcHBKc29uUGF0aCA9IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlKHtcbiAgICBwYXRoOiBqb2luKE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzLkRlbW9WYXVsdCwgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuRG90T2JzaWRpYW4sIE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzLkFwcEpzb24pXG4gIH0pO1xuICBjb25zdCBjb250ZW50ID0gZXhpc3RzU3luYyhhcHBKc29uUGF0aCkgPyBhd2FpdCByZWFkRmlsZShhcHBKc29uUGF0aCwgJ3V0Zi04JykgOiBudWxsO1xuICBjb25zdCBhcHBKc29uID0gcGFyc2VEZW1vVmF1bHRBcHBKc29uKHsgY29udGVudCwgcGF0aDogYXBwSnNvblBhdGggfSk7XG5cbiAgY29uc3Qgb3duZWRTZXR0aW5ncyA9IGZpbmRPd25lZERlbW9WYXVsdEFwcEpzb25TZXR0aW5ncyh7IGFwcEpzb24gfSk7XG4gIGlmIChvd25lZFNldHRpbmdzLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgJHthcHBKc29uUGF0aH0gc2V0cyAke293bmVkU2V0dGluZ3Muam9pbignLCAnKX0sIHdoaWNoIG9ic2lkaWFuLWRldi11dGlscyBvd25zIGFuZCB3cml0ZXMgaW50byB0aGUgYXJjaGl2ZWQgZGVtbyB2YXVsdC4gU2V0dGluZ3MgaXQgb3ducyBtdXN0IG5vdCBiZSBjb21taXR0ZWQuYFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gYXBwSnNvbjtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFrQkEsT0FBTyxZQUFZO0FBQ25CLFNBQVMsa0JBQWtCO0FBQzNCO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFLUCxTQUFTLCtCQUErQjtBQUN4QztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsaUNBQWlDO0FBQzFDO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBRVAsTUFBTSw4QkFBOEI7QUFDcEMsTUFBTSxzQkFBc0I7QUFDNUIsTUFBTSxtQkFBbUI7QUEyQnpCLGVBQXNCLHlCQUFpRDtBQUNyRSxRQUFNLGdCQUFnQix3QkFBd0IsRUFBRSxNQUFNLHdCQUF3QixVQUFVLENBQUM7QUFDekYsTUFBSSxDQUFDLFdBQVcs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
168
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3NjcmlwdC11dGlscy9kZW1vLXZhdWx0LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQXJjaGl2ZXMgYSBwbHVnaW4ncyBkZW1vIHZhdWx0IGFzIGEgcmVsZWFzZSBhcnRpZmFjdC5cbiAqXG4gKiBBIHBsdWdpbiBjYW4gc2hpcCBhIGN1cmF0ZWQgZGVtbyB2YXVsdCBhdCBgZGVtby12YXVsdC9gIGluIGl0cyByZXBvIHJvb3QuIEF0IHJlbGVhc2UgdGltZSB0aGlzXG4gKiBtb2R1bGUgaW5zdGFsbHMgdGhlIGZyZXNobHkgYnVpbHQgcGx1Z2luIGludG8gdGhhdCB2YXVsdCdzIGAub2JzaWRpYW4vcGx1Z2lucy88aWQ+L2AgZm9sZGVyIGFuZFxuICogemlwcyB0aGUgd2hvbGUgdmF1bHQgaW50byBgZGlzdC9idWlsZC88cGx1Z2luLWlkPi1kZW1vLXZhdWx0LnppcGAsIHNvIHRoZSBleGlzdGluZyBHaXRIdWItcmVsZWFzZVxuICogc3RlcCAod2hpY2ggdXBsb2FkcyBldmVyeSBmaWxlIGluIGBkaXN0L2J1aWxkL2ApIGF0dGFjaGVzIGl0IGF1dG9tYXRpY2FsbHkuXG4gKlxuICogVGhlIHZlcnNpb24gaXMgZGVsaWJlcmF0ZWx5IGFic2VudCBmcm9tIHRoYXQgbmFtZSBhbmQgbGl2ZXMgSU5TSURFIHRoZSBhcmNoaXZlIGluc3RlYWQgXHUyMDE0IHNlZVxuICogYG9ic2lkaWFuL2RlbW8tdmF1bHQtbmFtaW5nLnRzYCBmb3Igd2h5IFx1MjAxNCBpbiB0aGUgdHdvIHBsYWNlcyBhIHBlcnNvbiBhY3R1YWxseSBtZWV0cyBpdDogdGhlIHZhdWx0XG4gKiBzaXRzIHVuZGVyIGEgc2luZ2xlIGA8cGx1Z2luLWlkPi1kZW1vLXZhdWx0LTx2ZXJzaW9uPi9gIGZvbGRlciwgc28gdW56aXBwaW5nIHNldmVyYWwgcmVsZWFzZXMgYnkgaGFuZFxuICogaW50byBvbmUgZm9sZGVyIG5laXRoZXIgY29sbGlkZXMgbm9yIHByb2R1Y2VzIGFub255bW91cyBkaXJlY3RvcmllcywgYW5kIHRoZSB2YXVsdCdzIGBSRUFETUUubWRgXG4gKiBoZWFkaW5nIGdhaW5zIHRoZSB2ZXJzaW9uIGl0IGRlbW9uc3RyYXRlcy5cbiAqXG4gKiBUaGUgYXJjaGl2ZWQgY29weSBhbHNvIGNhcnJpZXMgdGhlIGAub2JzaWRpYW4vYXBwLmpzb25gIHNldHRpbmdzIHRoaXMgcGFja2FnZSBvd25zIChzZWVcbiAqIGBkZW1vLXZhdWx0LWFwcC1qc29uLnRzYCkuIFRob3NlIHNldHRpbmdzIGFuZCB0aGUgUkVBRE1FIGhlYWRpbmcgYXJlIHdyaXR0ZW4gaW50byB0aGUgWklQIEVOVFJZIGFuZFxuICogbmV2ZXIgaW50byB0aGUgcmVwbyBmb2xkZXI6IGJvdGggZmlsZXMgYXJlIHRyYWNrZWQsIGFuZCBgdXBkYXRlVmVyc2lvbmAgYXJjaGl2ZXMgYWZ0ZXIgaXQgaGFzIGFscmVhZHlcbiAqIHB1c2hlZCwgc28gYW4gaW4tcGxhY2Ugd3JpdGUgd291bGQgbGVhdmUgYW4gdW5jb21taXR0ZWQgY2hhbmdlIGJlaGluZCBhIHB1Ymxpc2hlZCByZWxlYXNlLlxuICovXG5cbmltcG9ydCBBZG1aaXAgZnJvbSAnYWRtLXppcCc7XG5pbXBvcnQgeyBleGlzdHNTeW5jIH0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBjcCxcbiAgbWtkaXIsXG4gIHJlYWRGaWxlLFxuICB3cml0ZUZpbGVcbn0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5cbmltcG9ydCB0eXBlIHsgRGVtb1ZhdWx0SGVscGVyU2V0dGluZ3MgfSBmcm9tICcuLi9vYnNpZGlhbi9kZW1vLXZhdWx0LWhlbHBlci1zZXR0aW5ncy50cyc7XG5pbXBvcnQgdHlwZSB7IERlbW9WYXVsdEFwcEpzb24gfSBmcm9tICcuL2RlbW8tdmF1bHQtYXBwLWpzb24udHMnO1xuXG5pbXBvcnQge1xuICBnZXREZW1vVmF1bHRBcmNoaXZlRmlsZU5hbWUsXG4gIGdldERlbW9WYXVsdEZvbGRlck5hbWVcbn0gZnJvbSAnLi4vb2JzaWRpYW4vZGVtby12YXVsdC1uYW1pbmcudHMnO1xuaW1wb3J0IHsgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMgfSBmcm9tICcuLi9vYnNpZGlhbi9wbHVnaW4vb2JzaWRpYW4tcGx1Z2luLXJlcG8tcGF0aHMudHMnO1xuaW1wb3J0IHtcbiAgZ2V0Rm9sZGVyTmFtZSxcbiAgam9pblxufSBmcm9tICcuLi9wYXRoLnRzJztcbmltcG9ydCB7XG4gIGJ1aWxkQXJjaGl2ZWREZW1vVmF1bHRBcHBKc29uQ29udGVudCxcbiAgZmluZE93bmVkRGVtb1ZhdWx0QXBwSnNvblNldHRpbmdzLFxuICBwYXJzZURlbW9WYXVsdEFwcEpzb25cbn0gZnJvbSAnLi9kZW1vLXZhdWx0LWFwcC1qc29uLnRzJztcbmltcG9ydCB7IE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMgfSBmcm9tICcuL29ic2lkaWFuLWRldi11dGlscy1yZXBvLXBhdGhzLnRzJztcbmltcG9ydCB7XG4gIGdldFJvb3RGb2xkZXIsXG4gIHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlXG59IGZyb20gJy4vcm9vdC50cyc7XG5cbmNvbnN0IERFTU9fVkFVTFRfSEVMUEVSX1BMVUdJTl9JRCA9ICdkZW1vLXZhdWx0LWhlbHBlcic7XG5jb25zdCBEQVRBX0pTT05fRklMRV9OQU1FID0gJ2RhdGEuanNvbic7XG5jb25zdCBEQVRBX0pTT05fSU5ERU5UID0gMjtcbmNvbnN0IFJFQURNRV9GSUxFX05BTUUgPSAnUkVBRE1FLm1kJztcblxuLy8gVGhlIFJFQURNRSdzIG9wZW5pbmcgYCMgSDFgLCBhbmQgb25seSB0aGF0IG9uZTogd2l0aG91dCB0aGUgYG1gIGZsYWcgdGhlIG1hdGNoIGlzIGFuY2hvcmVkIHRvIHRoZSBzdGFydFxuLy8gT2YgdGhlIGZpbGUsIGFuZCBgLmAgc3RvcHMgYXQgdGhlIG5ld2xpbmUgdGhhdCBlbmRzIHRoZSBsaW5lLlxuY29uc3QgT1BFTklOR19IRUFESU5HX1JFR19FWFAgPSAvXiMgLiovO1xuXG4vKipcbiAqIFRoZSBtaW5pbWFsIHNoYXBlIG9mIGEgcGx1Z2luIGBtYW5pZmVzdC5qc29uYCByZWFkIGJ5IHtAbGluayBhcmNoaXZlUGx1Z2luRGVtb1ZhdWx0fS5cbiAqL1xuaW50ZXJmYWNlIFBsdWdpbk1hbmlmZXN0IHtcbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4gaWQsIHVzZWQgYXMgdGhlIGZvbGRlciBuYW1lIHVuZGVyIGBkZW1vLXZhdWx0Ly5vYnNpZGlhbi9wbHVnaW5zL2AuXG4gICAqL1xuICByZWFkb25seSBpZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcGx1Z2luIHZlcnNpb24sIGVtYmVkZGVkIGluIHRoZSBhcmNoaXZlJ3MgdG9wLWxldmVsIGZvbGRlciBuYW1lIGFuZCBpdHMgUkVBRE1FIGhlYWRpbmcuXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQXJjaGl2ZXMgdGhlIHBsdWdpbidzIGRlbW8gdmF1bHQgKGBkZW1vLXZhdWx0L2AgaW4gdGhlIHJlcG8gcm9vdCkgYXMgYSByZWxlYXNlIGFydGlmYWN0LlxuICpcbiAqIEluc3RhbGxzIHRoZSBmcmVzaGx5IGJ1aWx0IHBsdWdpbiBmcm9tIGBkaXN0L2J1aWxkL2AgaW50byB0aGUgdmF1bHQnc1xuICogYC5vYnNpZGlhbi9wbHVnaW5zLzxpZD4vYCBmb2xkZXIsIHRoZW4gemlwcyB0aGUgd2hvbGUgdmF1bHQgdG9cbiAqIGBkaXN0L2J1aWxkLzxwbHVnaW4taWQ+LWRlbW8tdmF1bHQuemlwYCwgdW5kZXIgYSBzaW5nbGUgYDxwbHVnaW4taWQ+LWRlbW8tdmF1bHQtPHZlcnNpb24+L2AgZm9sZGVyLlxuICpcbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGFic29sdXRlIHBhdGggb2YgdGhlIGNyZWF0ZWQgemlwIGFyY2hpdmUsIG9yXG4gKiBgbnVsbGAgaWYgdGhlIHJlcG8gaGFzIG5vIGBkZW1vLXZhdWx0L2AgZm9sZGVyLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXJjaGl2ZVBsdWdpbkRlbW9WYXVsdCgpOiBQcm9taXNlPG51bGwgfCBzdHJpbmc+IHtcbiAgY29uc3QgZGVtb1ZhdWx0UGF0aCA9IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlKHsgcGF0aDogT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuRGVtb1ZhdWx0IH0pO1xuICBpZiAoIWV4aXN0c1N5bmMoZGVtb1ZhdWx0UGF0aCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IG1hbmlmZXN0UGF0aCA9IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlKHsgcGF0aDogT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuTWFuaWZlc3RKc29uIH0pO1xuICBjb25zdCBtYW5pZmVzdCA9IEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUobWFuaWZlc3RQYXRoLCAndXRmLTgnKSkgYXMgUGx1Z2luTWFuaWZlc3Q7XG5cbiAgY29uc3QgcGx1Z2luRm9sZGVyID0gcmVzb2x2ZVBhdGhGcm9tUm9vdFNhZmUoe1xuICAgIHBhdGg6IGpvaW4oXG4gICAgICBPYnNpZGlhblBsdWdpblJlcG9QYXRocy5EZW1vVmF1bHQsXG4gICAgICBPYnNpZGlhblBsdWdpblJlcG9QYXRocy5Eb3RPYnNpZGlhbixcbiAgICAgIE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzLlBsdWdpbnMsXG4gICAgICBtYW5pZmVzdC5pZFxuICAgIClcbiAgfSk7XG4gIGF3YWl0IG1rZGlyKHBsdWdpbkZvbGRlciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgY29uc3QgZGlzdEJ1aWxkUGF0aCA9IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlKHsgcGF0aDogT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuRGlzdEJ1aWxkIH0pO1xuICBhd2FpdCBjcChkaXN0QnVpbGRQYXRoLCBwbHVnaW5Gb2xkZXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuXG4gIGF3YWl0IGluamVjdERlbW9WYXVsdEhlbHBlcihtYW5pZmVzdC5pZCk7XG5cbiAgY29uc3QgemlwUGF0aCA9IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlKHtcbiAgICBwYXRoOiBqb2luKE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzLkRpc3RCdWlsZCwgZ2V0RGVtb1ZhdWx0QXJjaGl2ZUZpbGVOYW1lKG1hbmlmZXN0LmlkKSlcbiAgfSk7XG4gIGNvbnN0IHJvb3RGb2xkZXJOYW1lID0gZ2V0RGVtb1ZhdWx0Rm9sZGVyTmFtZSh7XG4gICAgcGx1Z2luSWQ6IG1hbmlmZXN0LmlkLFxuICAgIHZlcnNpb246IG1hbmlmZXN0LnZlcnNpb25cbiAgfSk7XG4gIGNvbnN0IHppcCA9IG5ldyBBZG1aaXAoKTtcbiAgemlwLmFkZExvY2FsRm9sZGVyKGRlbW9WYXVsdFBhdGgsIHJvb3RGb2xkZXJOYW1lKTtcbiAgaW5qZWN0QXBwSnNvbih6aXAsIGF3YWl0IHJlYWRDb21taXR0ZWRBcHBKc29uKCksIHJvb3RGb2xkZXJOYW1lKTtcbiAgaW5qZWN0UmVhZG1lVmVyc2lvbih6aXAsIHJvb3RGb2xkZXJOYW1lLCBtYW5pZmVzdC52ZXJzaW9uKTtcbiAgYXdhaXQgemlwLndyaXRlWmlwUHJvbWlzZSh6aXBQYXRoKTtcbiAgcmV0dXJuIHppcFBhdGg7XG59XG5cbi8vIFN0b3JlcyB0aGUgYXJjaGl2ZWQgdmF1bHQncyBgLm9ic2lkaWFuL2FwcC5qc29uYCBcdTIwMTQgdGhlIGNvbW1pdHRlZCBzZXR0aW5ncyB3aXRoIHRoZSBvd25lZCBvbmVzIG1lcmdlZFxuLy8gT3ZlciB0aGVtLiBUaGUgZW50cnkgaXMgcmVwbGFjZWQgcmF0aGVyIHRoYW4gdGhlIGZpbGUsIHNvIHRoZSByZXBvIGZvbGRlciBpcyBsZWZ0IGV4YWN0bHkgYXMgaXQgd2FzLlxuZnVuY3Rpb24gaW5qZWN0QXBwSnNvbih6aXA6IEFkbVppcCwgYXBwSnNvbjogRGVtb1ZhdWx0QXBwSnNvbiwgcm9vdEZvbGRlck5hbWU6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCBlbnRyeU5hbWUgPSBqb2luKHJvb3RGb2xkZXJOYW1lLCBPYnNpZGlhblBsdWdpblJlcG9QYXRocy5Eb3RPYnNpZGlhbiwgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuQXBwSnNvbik7XG4gIGNvbnN0IGNvbnRlbnQgPSBCdWZmZXIuZnJvbShidWlsZEFyY2hpdmVkRGVtb1ZhdWx0QXBwSnNvbkNvbnRlbnQoeyBhcHBKc29uIH0pLCAndXRmLTgnKTtcbiAgY29uc3QgZW50cnkgPSB6aXAuZ2V0RW50cnkoZW50cnlOYW1lKTtcbiAgaWYgKGVudHJ5KSB7XG4gICAgemlwLnVwZGF0ZUZpbGUoZW50cnksIGNvbnRlbnQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEEgdmF1bHQgd2l0aCBub3RoaW5nIGVsc2UgdG8gY29uZmlndXJlIGNvbW1pdHMgbm8gYGFwcC5qc29uYCBhdCBhbGwsIHdoaWNoIGlzIHRoZSBleHBlY3RlZCBzdGF0ZS5cbiAgemlwLmFkZEZpbGUoZW50cnlOYW1lLCBjb250ZW50KTtcbn1cblxuLy8gSW5qZWN0cyB0aGUgYnVpbHQsIGBvYnNpZGlhbi1kZXYtdXRpbHNgLW93bmVkIGBkZW1vLXZhdWx0LWhlbHBlcmAgYm9vdHN0cmFwIHBsdWdpbiAoc2hpcHBlZCBpbiB0aGlzIHBhY2thZ2UpIGludG8gdGhlIGRlbW8gdmF1bHQsIHNvIG5vIHBlci12YXVsdCBjb3B5IGlzIGNvbW1pdHRlZCBhbmQgYW4gYG9ic2lkaWFuLWRldi11dGlsc2AgYnVtcCBwcm9wYWdhdGVzIGZpeGVzLlxuLy9cbi8vIEFsb25nc2lkZSB0aGUgYmluYXJpZXMgaXQgd3JpdGVzIHRoZSBoZWxwZXIncyBvd24gYGRhdGEuanNvbmAgbmFtaW5nIHRoZSBkZW1vbnN0cmF0ZWQgcGx1Z2luLiBUaGF0IGlzXG4vLyBUaGUgb25lIG1vbWVudCB0aGUgaWQgaXMga25vd24gZm9yIGNlcnRhaW4gXHUyMDE0IGl0IGNvbWVzIGZyb20gdGhlIHBsdWdpbidzIG93biBtYW5pZmVzdCBcdTIwMTQgd2hlcmVhcyB0aGVcbi8vIE9wZW5lZCB2YXVsdCBvbmx5IG9mZmVycyBwbHVnaW4gZm9sZGVycyB0byBjb3VudCwgd2hpY2ggdGhlIGJvb3RzdHJhcCBpdHNlbGYgYWRkcyB0byAoc2VlXG4vLyBgRGVtb1ZhdWx0SGVscGVyU2V0dGluZ3NgKS5cbmFzeW5jIGZ1bmN0aW9uIGluamVjdERlbW9WYXVsdEhlbHBlcihkZW1vZWRQbHVnaW5JZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHBhY2thZ2VGb2xkZXIgPSBnZXRSb290Rm9sZGVyKGdldEZvbGRlck5hbWUoaW1wb3J0Lm1ldGEudXJsKSk7XG4gIGlmICghcGFja2FnZUZvbGRlcikge1xuICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IHJlc29sdmUgdGhlIG9ic2lkaWFuLWRldi11dGlscyBwYWNrYWdlIGZvbGRlciB0byBpbmplY3QgdGhlIGRlbW8tdmF1bHQtaGVscGVyIHBsdWdpbi4nKTtcbiAgfVxuXG4gIGNvbnN0IGhlbHBlclNvdXJjZVBhdGggPSBqb2luKHBhY2thZ2VGb2xkZXIsIE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuRGlzdERlbW9WYXVsdEhlbHBlcik7XG4gIGNvbnN0IGhlbHBlckZvbGRlciA9IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlKHtcbiAgICBwYXRoOiBqb2luKFxuICAgICAgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuRGVtb1ZhdWx0LFxuICAgICAgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuRG90T2JzaWRpYW4sXG4gICAgICBPYnNpZGlhblBsdWdpblJlcG9QYXRocy5QbHVnaW5zLFxuICAgICAgREVNT19WQVVMVF9IRUxQRVJfUExVR0lOX0lEXG4gICAgKVxuICB9KTtcbiAgYXdhaXQgbWtkaXIoaGVscGVyRm9sZGVyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgYXdhaXQgY3AoaGVscGVyU291cmNlUGF0aCwgaGVscGVyRm9sZGVyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICBjb25zdCBzZXR0aW5nczogRGVtb1ZhdWx0SGVscGVyU2V0dGluZ3MgPSB7IGRlbW9lZFBsdWdpbklkIH07XG4gIGF3YWl0IHdyaXRlRmlsZShqb2luKGhlbHBlckZvbGRlciwgREFUQV9KU09OX0ZJTEVfTkFNRSksIGAke0pTT04uc3RyaW5naWZ5KHNldHRpbmdzLCBudWxsLCBEQVRBX0pTT05fSU5ERU5UKX1cXG5gLCAndXRmLTgnKTtcbn1cblxuLy8gTmFtZXMgdGhlIHZlcnNpb24gb24gdGhlIGFyY2hpdmVkIGBSRUFETUUubWRgJ3MgaGVhZGluZywgc28gdGhlIHZhdWx0IHNheXMgd2hpY2ggcmVsZWFzZSBpdCBkZW1vbnN0cmF0ZXNcbi8vIEhvd2V2ZXIgZmFyIGl0IHRyYXZlbHMgZnJvbSB0aGUgcmVsZWFzZSBwYWdlIGl0IHdhcyBkb3dubG9hZGVkIGZyb20uXG4vL1xuLy8gRW50cnktb25seSwgZm9yIHRoZSBzYW1lIHJlYXNvbiBgaW5qZWN0QXBwSnNvbmAgaXM6IHRoZSBjb21taXR0ZWQgUkVBRE1FIGlzIGEgdHJhY2tlZCwgaGFuZC1hdXRob3JlZFxuLy8gRmlsZSBhbmQgYHVwZGF0ZVZlcnNpb25gIGFyY2hpdmVzIGFmdGVyIGl0IGhhcyBhbHJlYWR5IHB1c2hlZC5cbi8vXG4vLyBBIHZhdWx0IHRoYXQgc2hpcHMgbm8gUkVBRE1FLCBvciBvbmUgb3BlbmluZyBvbiBzb21ldGhpbmcgb3RoZXIgdGhhbiBhbiBgIyBIMWAsIGlzIGxlZnQgYWxvbmUgcmF0aGVyXG4vLyBUaGFuIGNvcnJlY3RlZC4gVGhlIGRlbW8tdmF1bHQgY292ZXJhZ2Ugc3VpdGUgZXhlbXB0cyBgUkVBRE1FLm1kYCBmcm9tIGl0cyBIMSBjaGVjaywgc28gbmVpdGhlciBzaGFwZVxuLy8gSXMgYSBkZWZlY3QgXHUyMDE0IGFuZCBhIHJlbGVhc2UgaXMgdGhlIHdyb25nIG1vbWVudCB0byBzdGFydCBmYWlsaW5nIG9uIG9uZS5cbmZ1bmN0aW9uIGluamVjdFJlYWRtZVZlcnNpb24oemlwOiBBZG1aaXAsIHJvb3RGb2xkZXJOYW1lOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCBlbnRyeSA9IHppcC5nZXRFbnRyeShqb2luKHJvb3RGb2xkZXJOYW1lLCBSRUFETUVfRklMRV9OQU1FKSk7XG4gIGlmICghZW50cnkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBjb250ZW50ID0gZW50cnkuZ2V0RGF0YSgpLnRvU3RyaW5nKCd1dGYtOCcpO1xuICBjb25zdCB2ZXJzaW9uZWRDb250ZW50ID0gY29udGVudC5yZXBsYWNlKE9QRU5JTkdfSEVBRElOR19SRUdfRVhQLCAoaGVhZGluZykgPT4gYCR7aGVhZGluZ30gdiR7dmVyc2lvbn1gKTtcbiAgaWYgKHZlcnNpb25lZENvbnRlbnQgPT09IGNvbnRlbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB6aXAudXBkYXRlRmlsZShlbnRyeSwgQnVmZmVyLmZyb20odmVyc2lvbmVkQ29udGVudCwgJ3V0Zi04JykpO1xufVxuXG4vLyBSZWFkcyB0aGUgZGVtbyB2YXVsdCdzIGNvbW1pdHRlZCBgLm9ic2lkaWFuL2FwcC5qc29uYCwgcmVmdXNpbmcgdGhlIHNldHRpbmdzIHRoaXMgcGFja2FnZSBvd25zLlxuLy9cbi8vIFRob3NlIHNldHRpbmdzIGFyZSBpbmplY3RlZCBpbnRvIHRoZSBhcmNoaXZlLCBzbyBhIGNvbW1pdHRlZCBvbmUgaXMgYSBzZWNvbmQgc291cmNlIG9mIHRydXRoIHRoYXRcbi8vIE5vdGhpbmcga2VlcHMgaW4gc3RlcC4gVGhlIGRlbW8tdmF1bHQgY292ZXJhZ2Ugc3VpdGUgYWxyZWFkeSBmYWlscyBvbiBpdCwgd2hpY2ggbWVhbnMgcmVhY2hpbmcgaGVyZVxuLy8gTWVhbnMgdGhhdCBnYXRlIHdhcyBza2lwcGVkIFx1MjAxNCBzbyB0aGlzIHJlZnVzZXMgcmF0aGVyIHRoYW4gb3ZlcndyaXRpbmcgYSB2YWx1ZSBzb21lYm9keSBjaG9zZSBvbiBwdXJwb3NlLlxuYXN5bmMgZnVuY3Rpb24gcmVhZENvbW1pdHRlZEFwcEpzb24oKTogUHJvbWlzZTxEZW1vVmF1bHRBcHBKc29uPiB7XG4gIGNvbnN0IGFwcEpzb25QYXRoID0gcmVzb2x2ZVBhdGhGcm9tUm9vdFNhZmUoe1xuICAgIHBhdGg6IGpvaW4oT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuRGVtb1ZhdWx0LCBPYnNpZGlhblBsdWdpblJlcG9QYXRocy5Eb3RPYnNpZGlhbiwgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuQXBwSnNvbilcbiAgfSk7XG4gIGNvbnN0IGNvbnRlbnQgPSBleGlzdHNTeW5jKGFwcEpzb25QYXRoKSA/IGF3YWl0IHJlYWRGaWxlKGFwcEpzb25QYXRoLCAndXRmLTgnKSA6IG51bGw7XG4gIGNvbnN0IGFwcEpzb24gPSBwYXJzZURlbW9WYXVsdEFwcEpzb24oeyBjb250ZW50LCBwYXRoOiBhcHBKc29uUGF0aCB9KTtcblxuICBjb25zdCBvd25lZFNldHRpbmdzID0gZmluZE93bmVkRGVtb1ZhdWx0QXBwSnNvblNldHRpbmdzKHsgYXBwSnNvbiB9KTtcbiAgaWYgKG93bmVkU2V0dGluZ3MubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGAke2FwcEpzb25QYXRofSBzZXRzICR7b3duZWRTZXR0aW5ncy5qb2luKCcsICcpfSwgd2hpY2ggb2JzaWRpYW4tZGV2LXV0aWxzIG93bnMgYW5kIHdyaXRlcyBpbnRvIHRoZSBhcmNoaXZlZCBkZW1vIHZhdWx0LiBTZXR0aW5ncyBpdCBvd25zIG11c3Qgbm90IGJlIGNvbW1pdHRlZC5gXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBhcHBKc29uO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXNCQSxPQUFPLFlBQVk7QUFDbkIsU0FBUyxrQkFBa0I7QUFDM0I7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUtQO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsU0FBUywrQkFBK0I7QUFDeEM7QUFBQSxFQUNF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