obsidian-dev-utils 97.0.0 → 99.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 (143) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +1 -1
  3. package/dist/integration-test-plugin/main.js +686 -439
  4. package/dist/lib/cjs/__merged.cjs +22 -9
  5. package/dist/lib/cjs/__merged.d.cts +4 -3
  6. package/dist/lib/cjs/generated-during-build.cjs +1 -1
  7. package/dist/lib/cjs/obsidian/components/plugin-settings-component.cjs +36 -1
  8. package/dist/lib/cjs/obsidian/components/plugin-settings-component.d.cts +21 -0
  9. package/dist/lib/cjs/obsidian/components/plugin-suggestion-component.cjs +20 -6
  10. package/dist/lib/cjs/obsidian/components/plugin-suggestion-component.d.cts +26 -4
  11. package/dist/lib/cjs/obsidian/components/rename-delete-handler-component.cjs +38 -38
  12. package/dist/lib/cjs/obsidian/demo-vault-naming.cjs +167 -0
  13. package/dist/lib/cjs/obsidian/demo-vault-naming.d.cts +54 -0
  14. package/dist/lib/cjs/obsidian/desktop-demo-vault-opener.cjs +11 -5
  15. package/dist/lib/cjs/obsidian/desktop-demo-vault-opener.d.cts +10 -8
  16. package/dist/lib/cjs/obsidian/desktop-trusted-input.cjs +9 -9
  17. package/dist/lib/cjs/obsidian/desktop-trusted-input.d.cts +23 -4
  18. package/dist/lib/cjs/obsidian/file-change.cjs +6 -6
  19. package/dist/lib/cjs/obsidian/index.cjs +10 -1
  20. package/dist/lib/cjs/obsidian/index.d.cts +3 -0
  21. package/dist/lib/cjs/obsidian/link.cjs +33 -6
  22. package/dist/lib/cjs/obsidian/link.d.cts +35 -0
  23. package/dist/lib/cjs/obsidian/mobile-trusted-input.cjs +195 -0
  24. package/dist/lib/cjs/obsidian/mobile-trusted-input.d.cts +93 -0
  25. package/dist/lib/cjs/obsidian/plugin/obsidian-plugin-repo-paths.cjs +2 -1
  26. package/dist/lib/cjs/obsidian/plugin/obsidian-plugin-repo-paths.d.cts +4 -0
  27. package/dist/lib/cjs/obsidian/reference.cjs +9 -1
  28. package/dist/lib/cjs/obsidian/reference.d.cts +33 -0
  29. package/dist/lib/cjs/obsidian/resource-lock.cjs +122 -122
  30. package/dist/lib/cjs/obsidian/trusted-input.cjs +206 -0
  31. package/dist/lib/cjs/obsidian/trusted-input.d.cts +126 -0
  32. package/dist/lib/cjs/obsidian/validation.cjs +22 -3
  33. package/dist/lib/cjs/obsidian/validation.d.cts +37 -0
  34. package/dist/lib/cjs/obsidian/vault.cjs +4 -1
  35. package/dist/lib/cjs/obsidian/vault.d.cts +8 -1
  36. package/dist/lib/cjs/script-utils/build.cjs +30 -6
  37. package/dist/lib/cjs/script-utils/build.d.cts +5 -0
  38. package/dist/lib/cjs/script-utils/demo-vault.cjs +26 -6
  39. package/dist/lib/cjs/script-utils/demo-vault.d.cts +12 -8
  40. package/dist/lib/cjs/script-utils/exec.cjs +1 -1
  41. package/dist/lib/cjs/script-utils/formatters/dprint.cjs +3 -2
  42. package/dist/lib/cjs/script-utils/index.cjs +4 -1
  43. package/dist/lib/cjs/script-utils/index.d.cts +1 -0
  44. package/dist/lib/cjs/script-utils/linters/cspell.cjs +3 -3
  45. package/dist/lib/cjs/script-utils/linters/eslint-config.cjs +39 -1
  46. package/dist/lib/cjs/script-utils/linters/eslint-rules/index.cjs +16 -1
  47. package/dist/lib/cjs/script-utils/linters/eslint-rules/index.d.cts +5 -0
  48. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-description.cjs +254 -0
  49. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-description.d.cts +54 -0
  50. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-helpers.cjs +217 -0
  51. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-helpers.d.cts +141 -0
  52. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-id.cjs +214 -0
  53. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-id.d.cts +32 -0
  54. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-name.cjs +215 -0
  55. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-name.d.cts +30 -0
  56. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-schema.cjs +318 -0
  57. package/dist/lib/cjs/script-utils/linters/eslint-rules/manifest-schema.d.cts +45 -0
  58. package/dist/lib/cjs/script-utils/linters/eslint-rules/obsidian-dev-utils-plugin.cjs +9 -1
  59. package/dist/lib/cjs/script-utils/linters/eslint.cjs +3 -2
  60. package/dist/lib/cjs/script-utils/linters/markdownlint.cjs +4 -4
  61. package/dist/lib/cjs/script-utils/nano-staged-config.cjs +7 -5
  62. package/dist/lib/cjs/script-utils/nano-staged-config.d.cts +5 -2
  63. package/dist/lib/cjs/script-utils/npm-run.cjs +4 -3
  64. package/dist/lib/cjs/script-utils/obsidian-dev-utils-repo-paths.cjs +10 -1
  65. package/dist/lib/cjs/script-utils/obsidian-dev-utils-repo-paths.d.cts +37 -1
  66. package/dist/lib/cjs/script-utils/package-manager.cjs +370 -0
  67. package/dist/lib/cjs/script-utils/package-manager.d.cts +93 -0
  68. package/dist/lib/cjs/script-utils/version.cjs +21 -9
  69. package/dist/lib/esm/__merged.d.mts +4 -3
  70. package/dist/lib/esm/__merged.mjs +24 -10
  71. package/dist/lib/esm/generated-during-build.mjs +1 -1
  72. package/dist/lib/esm/obsidian/components/plugin-settings-component.d.mts +21 -0
  73. package/dist/lib/esm/obsidian/components/plugin-settings-component.mjs +36 -1
  74. package/dist/lib/esm/obsidian/components/plugin-suggestion-component.d.mts +26 -4
  75. package/dist/lib/esm/obsidian/components/plugin-suggestion-component.mjs +20 -6
  76. package/dist/lib/esm/obsidian/components/rename-delete-handler-component.mjs +38 -38
  77. package/dist/lib/esm/obsidian/demo-vault-naming.d.mts +54 -0
  78. package/dist/lib/esm/obsidian/demo-vault-naming.mjs +61 -0
  79. package/dist/lib/esm/obsidian/desktop-demo-vault-opener.d.mts +10 -8
  80. package/dist/lib/esm/obsidian/desktop-demo-vault-opener.mjs +14 -5
  81. package/dist/lib/esm/obsidian/desktop-trusted-input.d.mts +23 -4
  82. package/dist/lib/esm/obsidian/desktop-trusted-input.mjs +9 -9
  83. package/dist/lib/esm/obsidian/file-change.mjs +6 -6
  84. package/dist/lib/esm/obsidian/index.d.mts +3 -0
  85. package/dist/lib/esm/obsidian/index.mjs +7 -1
  86. package/dist/lib/esm/obsidian/link.d.mts +35 -0
  87. package/dist/lib/esm/obsidian/link.mjs +38 -7
  88. package/dist/lib/esm/obsidian/mobile-trusted-input.d.mts +93 -0
  89. package/dist/lib/esm/obsidian/mobile-trusted-input.mjs +84 -0
  90. package/dist/lib/esm/obsidian/plugin/obsidian-plugin-repo-paths.d.mts +4 -0
  91. package/dist/lib/esm/obsidian/plugin/obsidian-plugin-repo-paths.mjs +2 -1
  92. package/dist/lib/esm/obsidian/reference.d.mts +33 -0
  93. package/dist/lib/esm/obsidian/reference.mjs +8 -1
  94. package/dist/lib/esm/obsidian/resource-lock.mjs +122 -122
  95. package/dist/lib/esm/obsidian/trusted-input.d.mts +126 -0
  96. package/dist/lib/esm/obsidian/trusted-input.mjs +85 -0
  97. package/dist/lib/esm/obsidian/validation.d.mts +37 -0
  98. package/dist/lib/esm/obsidian/validation.mjs +21 -2
  99. package/dist/lib/esm/obsidian/vault.d.mts +8 -1
  100. package/dist/lib/esm/obsidian/vault.mjs +4 -1
  101. package/dist/lib/esm/script-utils/build.d.mts +5 -0
  102. package/dist/lib/esm/script-utils/build.mjs +30 -6
  103. package/dist/lib/esm/script-utils/demo-vault.d.mts +12 -8
  104. package/dist/lib/esm/script-utils/demo-vault.mjs +29 -6
  105. package/dist/lib/esm/script-utils/exec.mjs +1 -1
  106. package/dist/lib/esm/script-utils/formatters/dprint.mjs +3 -2
  107. package/dist/lib/esm/script-utils/index.d.mts +1 -0
  108. package/dist/lib/esm/script-utils/index.mjs +3 -1
  109. package/dist/lib/esm/script-utils/linters/cspell.mjs +3 -3
  110. package/dist/lib/esm/script-utils/linters/eslint-config.mjs +39 -1
  111. package/dist/lib/esm/script-utils/linters/eslint-rules/index.d.mts +5 -0
  112. package/dist/lib/esm/script-utils/linters/eslint-rules/index.mjs +11 -1
  113. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-description.d.mts +54 -0
  114. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-description.mjs +148 -0
  115. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-helpers.d.mts +141 -0
  116. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-helpers.mjs +92 -0
  117. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-id.d.mts +32 -0
  118. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-id.mjs +111 -0
  119. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-name.d.mts +30 -0
  120. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-name.mjs +112 -0
  121. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-schema.d.mts +45 -0
  122. package/dist/lib/esm/script-utils/linters/eslint-rules/manifest-schema.mjs +217 -0
  123. package/dist/lib/esm/script-utils/linters/eslint-rules/obsidian-dev-utils-plugin.mjs +9 -1
  124. package/dist/lib/esm/script-utils/linters/eslint.mjs +3 -2
  125. package/dist/lib/esm/script-utils/linters/markdownlint.mjs +4 -4
  126. package/dist/lib/esm/script-utils/nano-staged-config.d.mts +5 -2
  127. package/dist/lib/esm/script-utils/nano-staged-config.mjs +7 -5
  128. package/dist/lib/esm/script-utils/npm-run.mjs +4 -3
  129. package/dist/lib/esm/script-utils/obsidian-dev-utils-repo-paths.d.mts +37 -1
  130. package/dist/lib/esm/script-utils/obsidian-dev-utils-repo-paths.mjs +10 -1
  131. package/dist/lib/esm/script-utils/package-manager.d.mts +93 -0
  132. package/dist/lib/esm/script-utils/package-manager.mjs +256 -0
  133. package/dist/lib/esm/script-utils/version.mjs +21 -9
  134. package/obsidian/demo-vault-naming/package.json +6 -0
  135. package/obsidian/mobile-trusted-input/package.json +6 -0
  136. package/obsidian/trusted-input/package.json +6 -0
  137. package/package.json +19 -17
  138. package/script-utils/linters/eslint-rules/manifest-description/package.json +6 -0
  139. package/script-utils/linters/eslint-rules/manifest-helpers/package.json +6 -0
  140. package/script-utils/linters/eslint-rules/manifest-id/package.json +6 -0
  141. package/script-utils/linters/eslint-rules/manifest-name/package.json +6 -0
  142. package/script-utils/linters/eslint-rules/manifest-schema/package.json +6 -0
  143. package/script-utils/package-manager/package.json +6 -0
@@ -0,0 +1,256 @@
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 { existsSync } from "node:fs";
45
+ import process from "node:process";
46
+ import {
47
+ dirname,
48
+ join,
49
+ toPosixPath
50
+ } from "../path.mjs";
51
+ import { getMandatoryNamedGroup } from "../reg-exp.mjs";
52
+ import { assertNever } from "../type-guards.mjs";
53
+ import { readJsonSync } from "./json.mjs";
54
+ import { ObsidianDevUtilsRepoPaths } from "./obsidian-dev-utils-repo-paths.mjs";
55
+ import { getRootFolder } from "./root.mjs";
56
+ var PackageManager = /* @__PURE__ */ ((PackageManager2) => {
57
+ PackageManager2["Bun"] = "bun";
58
+ PackageManager2["Npm"] = "npm";
59
+ PackageManager2["Pnpm"] = "pnpm";
60
+ PackageManager2["Yarn"] = "yarn";
61
+ return PackageManager2;
62
+ })(PackageManager || {});
63
+ function getPackageManager(cwd) {
64
+ const root = getStartFolder(cwd);
65
+ const declaredPackageManager = detectPackageManagerFromPackageJson(root);
66
+ const lockfiles = LOCKFILES.filter((lockfile) => existsSync(join(root, lockfile.fileName)));
67
+ const claimants = new Set(lockfiles.map((lockfile) => lockfile.packageManager));
68
+ if (declaredPackageManager !== null) {
69
+ claimants.add(declaredPackageManager);
70
+ }
71
+ const packageManager = resolvePackageManager({
72
+ claimants,
73
+ declaredPackageManager
74
+ });
75
+ if (claimants.size > 1) {
76
+ warnAboutSeveralClaimants({
77
+ declaredPackageManager,
78
+ lockfiles,
79
+ packageManager,
80
+ root
81
+ });
82
+ }
83
+ return packageManager;
84
+ }
85
+ function getPackageManagerRunCommand(cwd) {
86
+ return [getPackageManager(cwd), "run"];
87
+ }
88
+ function resolveToolCommand(params) {
89
+ const { cwd, tool } = params;
90
+ const shimPath = findBinShim({ cwd, tool });
91
+ if (shimPath !== null) {
92
+ return [shimPath];
93
+ }
94
+ return [...getPackageManagerExecCommand(cwd), tool];
95
+ }
96
+ const DECLARATION_NAME_REG_EXP = /^(?<name>[^@\s]+)@/;
97
+ const LOCKFILES = [
98
+ { fileName: ObsidianDevUtilsRepoPaths.BunLock, packageManager: "bun" /* Bun */ },
99
+ { fileName: ObsidianDevUtilsRepoPaths.BunLockb, packageManager: "bun" /* Bun */ },
100
+ { fileName: ObsidianDevUtilsRepoPaths.PnpmLockYaml, packageManager: "pnpm" /* Pnpm */ },
101
+ { fileName: ObsidianDevUtilsRepoPaths.YarnLock, packageManager: "yarn" /* Yarn */ },
102
+ { fileName: ObsidianDevUtilsRepoPaths.PackageLockJson, packageManager: "npm" /* Npm */ }
103
+ ];
104
+ const USER_AGENT_NAME_REG_EXP = /^(?<name>[^/\s]+)\//;
105
+ const reportedDisagreements = /* @__PURE__ */ new Set();
106
+ function detectPackageManagerFromPackageJson(root) {
107
+ const packageJsonPath = join(root, ObsidianDevUtilsRepoPaths.PackageJson);
108
+ if (!existsSync(packageJsonPath)) {
109
+ return null;
110
+ }
111
+ let packageJson;
112
+ try {
113
+ packageJson = readJsonSync(packageJsonPath);
114
+ } catch {
115
+ return null;
116
+ }
117
+ const declaration = packageJson.packageManager;
118
+ if (!declaration) {
119
+ return null;
120
+ }
121
+ const match = DECLARATION_NAME_REG_EXP.exec(declaration);
122
+ if (!match) {
123
+ return null;
124
+ }
125
+ return parsePackageManagerName(getMandatoryNamedGroup(match, "name"));
126
+ }
127
+ function detectPackageManagerFromUserAgent() {
128
+ const userAgent = process.env["npm_config_user_agent"];
129
+ if (!userAgent) {
130
+ return null;
131
+ }
132
+ const match = USER_AGENT_NAME_REG_EXP.exec(userAgent);
133
+ if (!match) {
134
+ return null;
135
+ }
136
+ return parsePackageManagerName(getMandatoryNamedGroup(match, "name"));
137
+ }
138
+ function findBinShim(params) {
139
+ const { cwd, tool } = params;
140
+ const candidates = getShimCandidates(tool);
141
+ let currentFolder = getStartFolder(cwd);
142
+ while (currentFolder !== ObsidianDevUtilsRepoPaths.CurrentFolder && currentFolder !== ObsidianDevUtilsRepoPaths.RootFolder) {
143
+ for (const candidate of candidates) {
144
+ const shimPath = join(currentFolder, ObsidianDevUtilsRepoPaths.NodeModules, ObsidianDevUtilsRepoPaths.Bin, candidate);
145
+ if (existsSync(shimPath)) {
146
+ return shimPath;
147
+ }
148
+ }
149
+ currentFolder = dirname(currentFolder);
150
+ }
151
+ return null;
152
+ }
153
+ function getPackageManagerExecCommand(cwd) {
154
+ const packageManager = getPackageManager(cwd);
155
+ switch (packageManager) {
156
+ case "bun" /* Bun */: {
157
+ return ["bun", "x"];
158
+ }
159
+ case "npm" /* Npm */: {
160
+ return ["npx"];
161
+ }
162
+ case "pnpm" /* Pnpm */: {
163
+ return ["pnpm", "exec"];
164
+ }
165
+ case "yarn" /* Yarn */: {
166
+ return ["yarn", "exec"];
167
+ }
168
+ /* v8 ignore start -- Exhaustive switch guard; default branch is unreachable. */
169
+ default: {
170
+ return assertNever(packageManager);
171
+ }
172
+ }
173
+ }
174
+ function getShimCandidates(tool) {
175
+ if (process.platform !== "win32") {
176
+ return [tool];
177
+ }
178
+ return [
179
+ `${tool}${ObsidianDevUtilsRepoPaths.CommandExtension}`,
180
+ `${tool}${ObsidianDevUtilsRepoPaths.ExeExtension}`,
181
+ `${tool}${ObsidianDevUtilsRepoPaths.BatExtension}`
182
+ ];
183
+ }
184
+ function getStartFolder(cwd) {
185
+ return getRootFolder(cwd) ?? toPosixPath(cwd ?? process.cwd());
186
+ }
187
+ function parsePackageManagerName(name) {
188
+ switch (name) {
189
+ case "bun" /* Bun */: {
190
+ return "bun" /* Bun */;
191
+ }
192
+ case "npm" /* Npm */: {
193
+ return "npm" /* Npm */;
194
+ }
195
+ case "pnpm" /* Pnpm */: {
196
+ return "pnpm" /* Pnpm */;
197
+ }
198
+ case "yarn" /* Yarn */: {
199
+ return "yarn" /* Yarn */;
200
+ }
201
+ default: {
202
+ return null;
203
+ }
204
+ }
205
+ }
206
+ function resolvePackageManager(params) {
207
+ const {
208
+ claimants,
209
+ declaredPackageManager
210
+ } = params;
211
+ if (declaredPackageManager !== null) {
212
+ return declaredPackageManager;
213
+ }
214
+ const lockfileOwners = [...claimants];
215
+ const [firstLockfileOwner] = lockfileOwners;
216
+ if (firstLockfileOwner === void 0) {
217
+ return detectPackageManagerFromUserAgent() ?? "npm" /* Npm */;
218
+ }
219
+ if (lockfileOwners.length === 1) {
220
+ return firstLockfileOwner;
221
+ }
222
+ const launchedBy = detectPackageManagerFromUserAgent();
223
+ if (launchedBy !== null && claimants.has(launchedBy)) {
224
+ return launchedBy;
225
+ }
226
+ return firstLockfileOwner;
227
+ }
228
+ function warnAboutSeveralClaimants(params) {
229
+ const {
230
+ declaredPackageManager,
231
+ lockfiles,
232
+ packageManager,
233
+ root
234
+ } = params;
235
+ const lockfileNames = lockfiles.map((lockfile) => lockfile.fileName).join(", ");
236
+ const advice = declaredPackageManager === null ? 'Delete the stale lockfile, or declare "packageManager" in package.json, to settle it.' : "Delete the stale lockfile to settle it.";
237
+ const message = [
238
+ `obsidian-dev-utils: more than one package manager claims ${root}.`,
239
+ `Lockfiles: ${lockfileNames}.`,
240
+ `package.json "packageManager": ${declaredPackageManager ?? "not set"}.`,
241
+ `Using ${packageManager}.`,
242
+ advice
243
+ ].join(" ");
244
+ if (reportedDisagreements.has(message)) {
245
+ return;
246
+ }
247
+ reportedDisagreements.add(message);
248
+ console.warn(message);
249
+ }
250
+ export {
251
+ PackageManager,
252
+ getPackageManager,
253
+ getPackageManagerRunCommand,
254
+ resolveToolCommand
255
+ };
256
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3NjcmlwdC11dGlscy9wYWNrYWdlLW1hbmFnZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBSZXNvbHZlcyBsb2NhbGx5LWluc3RhbGxlZCB0b29sIGJpbmFyaWVzIGFuZCBwYWNrYWdlLXNjcmlwdCBydW5uZXJzIHdpdGhvdXQgYXNzdW1pbmcgYG5wbWAuXG4gKlxuICogRGVsZWdhdGluZyB0byBgbnB4YCBzaWxlbnRseSBhc3N1bWVzIGFuIG5wbS1pbnN0YWxsZWQgdHJlZS4gT24gV2luZG93cyB0aGF0IGFzc3VtcHRpb24gaXMgZmF0YWwgdW5kZXJcbiAqIGBidW5gOiBgYnVuIGluc3RhbGxgIHdyaXRlcyBgbm9kZV9tb2R1bGVzLy5iaW4vPHRvb2w+LmV4ZWAsIG5vdCB0aGUgYDx0b29sPi5jbWRgIHRoYXQgbnBtJ3MgYG5weGAgbG9va3NcbiAqIGZvciwgc28gYG5weGAgbWlzc2VzIHRoZSBsb2NhbCBpbnN0YWxsIGVudGlyZWx5IGFuZCBkb3dubG9hZHMgdGhlIHRvb2wgZnJvbSB0aGUgcmVnaXN0cnkgaW5zdGVhZCBcdTIwMTQgd2hpY2hcbiAqIGZvciBgdHNjYCBpcyB0aGUgd2VsbC1rbm93biBkZWNveSBwYWNrYWdlLCBub3QgVHlwZVNjcmlwdC4gUmVzb2x2aW5nIHRoZSBzaGltIGZyb20gYG5vZGVfbW9kdWxlcy8uYmluYFxuICogb3Vyc2VsdmVzIHNpZGVzdGVwcyB0aGUgd2hvbGUgc2hpbS1mb3JtYXQgcXVlc3Rpb24sIGJlY2F1c2UgZXZlcnkgcGFja2FnZSBtYW5hZ2VyIHdyaXRlcyBvbmUgdGhlcmUuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBQYWNrYWdlSnNvbiB9IGZyb20gJ3R5cGUtZmVzdCc7XG5cbmltcG9ydCB7IGV4aXN0c1N5bmMgfSBmcm9tICdub2RlOmZzJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbmltcG9ydCB7XG4gIGRpcm5hbWUsXG4gIGpvaW4sXG4gIHRvUG9zaXhQYXRoXG59IGZyb20gJy4uL3BhdGgudHMnO1xuaW1wb3J0IHsgZ2V0TWFuZGF0b3J5TmFtZWRHcm91cCB9IGZyb20gJy4uL3JlZy1leHAudHMnO1xuaW1wb3J0IHsgYXNzZXJ0TmV2ZXIgfSBmcm9tICcuLi90eXBlLWd1YXJkcy50cyc7XG5pbXBvcnQgeyByZWFkSnNvblN5bmMgfSBmcm9tICcuL2pzb24udHMnO1xuaW1wb3J0IHsgT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocyB9IGZyb20gJy4vb2JzaWRpYW4tZGV2LXV0aWxzLXJlcG8tcGF0aHMudHMnO1xuaW1wb3J0IHsgZ2V0Um9vdEZvbGRlciB9IGZyb20gJy4vcm9vdC50cyc7XG5cbi8qKlxuICogQSBwYWNrYWdlIG1hbmFnZXIgdGhhdCBjYW4gb3duIGEgcHJvamVjdCdzIGRlcGVuZGVuY3kgdHJlZS5cbiAqL1xuZXhwb3J0IGVudW0gUGFja2FnZU1hbmFnZXIge1xuICAvKipcbiAgICogVGhlIGBidW5gIHBhY2thZ2UgbWFuYWdlci5cbiAgICovXG4gIEJ1biA9ICdidW4nLFxuXG4gIC8qKlxuICAgKiBUaGUgYG5wbWAgcGFja2FnZSBtYW5hZ2VyLlxuICAgKi9cbiAgTnBtID0gJ25wbScsXG5cbiAgLyoqXG4gICAqIFRoZSBgcG5wbWAgcGFja2FnZSBtYW5hZ2VyLlxuICAgKi9cbiAgUG5wbSA9ICdwbnBtJyxcblxuICAvKipcbiAgICogVGhlIGB5YXJuYCBwYWNrYWdlIG1hbmFnZXIuXG4gICAqL1xuICBZYXJuID0gJ3lhcm4nXG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHJlc29sdmVUb29sQ29tbWFuZH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZVRvb2xDb21tYW5kUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50IHdvcmtpbmcgZm9sZGVyIHRvIHJlc29sdmUgZnJvbS5cbiAgICovXG4gIHJlYWRvbmx5IGN3ZD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGxvY2FsbHktaW5zdGFsbGVkIHRvb2wsIGFzIGl0IGFwcGVhcnMgaW4gYG5vZGVfbW9kdWxlcy8uYmluYC5cbiAgICovXG4gIHJlYWRvbmx5IHRvb2w6IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoaWNoIHBhY2thZ2UgbWFuYWdlciBvd25zIHRoZSBwcm9qZWN0J3MgZGVwZW5kZW5jeSB0cmVlLlxuICpcbiAqIEV2ZXJ5IHNpZ25hbCBpcyBjb2xsZWN0ZWQgYmVmb3JlIGFueSBvZiB0aGVtIGlzIGJlbGlldmVkLCBiZWNhdXNlIGEgcmVwbyBjYXJyeWluZyB0d28gbG9ja2ZpbGVzIHVzZWQgdG9cbiAqIHJlc29sdmUgdG8gd2hpY2hldmVyIHNhdCBlYXJsaWVyIGluIGEgZml4ZWQgbGlzdCBcdTIwMTQgc2lsZW50bHkgcmVhc3NpZ25pbmcgZXZlcnkgcGFja2FnZSBzY3JpcHQgYW5kIGV2ZXJ5XG4gKiB0b29sIGludm9jYXRpb24gdG8gYSBtYW5hZ2VyIHRoYXQgbmV2ZXIgaW5zdGFsbGVkIHRoZSB0cmVlLlxuICpcbiAqIFRoZSBvcmRlciBpczpcbiAqXG4gKiAxLiBUaGUgYHBhY2thZ2VNYW5hZ2VyYCBmaWVsZCBvZiBgcGFja2FnZS5qc29uYC4gSXQgaXMgYSBkZWxpYmVyYXRlIGRlY2xhcmF0aW9uIGJ5IHRoZSByZXBvJ3MgYXV0aG9yXG4gKiAgICByYXRoZXIgdGhhbiBhbiBhcnRpZmFjdCBsZWZ0IGJlaGluZCBieSB3aGF0ZXZlciByYW4gbGFzdCwgc28gaXQgb3V0cmFua3MgZXZlcnkgbG9ja2ZpbGUgXHUyMDE0IGFuZCBpdCBpc1xuICogICAgdGhlIG9ubHkgc2lnbmFsIHRoYXQgaGVscHMgYXQgYWxsIGJlZm9yZSB0aGUgZmlyc3QgaW5zdGFsbCwgd2hlbiBubyBsb2NrZmlsZSBleGlzdHMgeWV0LlxuICogMi4gVGhlIHNvbGUgbG9ja2ZpbGUsIHdoZW4gZXhhY3RseSBvbmUgbWFuYWdlciBjbGFpbXMgdGhlIHRyZWUuXG4gKiAzLiBBbW9uZyBzZXZlcmFsIGxvY2tmaWxlcywgdGhlIG1hbmFnZXIgdGhhdCBsYXVuY2hlZCB1cyAoYG5wbV9jb25maWdfdXNlcl9hZ2VudGApLCB3aGVuIGl0IG93bnMgb25lIG9mXG4gKiAgICB0aGVtIFx1MjAxNCBhIGxpdmUgc2lnbmFsIGJlYXRzIGEgZmlsZSB0aGF0IG1heSBoYXZlIGJlZW4gYWJhbmRvbmVkIG1pZC1taWdyYXRpb24uIE90aGVyd2lzZSB0aGVcbiAqICAgIGRvY3VtZW50ZWQgZmFsbGJhY2sgb3JkZXIgaW4ge0BsaW5rIExPQ0tGSUxFU30gZGVjaWRlcy4gTm90ZSB0aGlzIGlzIGRlbGliZXJhdGVseSBOT1QgXCJ0aGUgbW9zdFxuICogICAgcmVjZW50bHkgbW9kaWZpZWQgbG9ja2ZpbGVcIjogYSBzdHJheSBsb2NrZmlsZSBpcyB0eXBpY2FsbHkgdGhlIG5ld2VzdCBmaWxlLCBzbyBtdGltZSBwaWNrcyBwcmVjaXNlbHlcbiAqICAgIHRoZSB3cm9uZyBvbmUuXG4gKiA0LiBgbnBtX2NvbmZpZ191c2VyX2FnZW50YCBvbiBpdHMgb3duLCB3aGVuIHRoZXJlIGlzIG5vIGxvY2tmaWxlLlxuICogNS4ge0BsaW5rIFBhY2thZ2VNYW5hZ2VyLk5wbX0uXG4gKlxuICogV2hlbmV2ZXIgbW9yZSB0aGFuIG9uZSBtYW5hZ2VyIGNsYWltcyB0aGUgdHJlZSwgdGhlIGRpc2FncmVlbWVudCBpcyByZXBvcnRlZCBvbmNlIHBlciBwcm9qZWN0IHRocm91Z2hcbiAqIHtAbGluayB3YXJuQWJvdXRTZXZlcmFsQ2xhaW1hbnRzfSBcdTIwMTQgdGhlIHJlc29sdXRpb24gc3RheXMgZGV0ZXJtaW5pc3RpYywgYnV0IGl0IHN0b3BzIGJlaW5nIHNpbGVudC5cbiAqXG4gKiBAcGFyYW0gY3dkIC0gVGhlIGN1cnJlbnQgd29ya2luZyBmb2xkZXIgdG8gcmVzb2x2ZSBmcm9tLlxuICogQHJldHVybnMgVGhlIGRldGVjdGVkIHBhY2thZ2UgbWFuYWdlciwgb3Ige0BsaW5rIFBhY2thZ2VNYW5hZ2VyLk5wbX0gd2hlbiBub3RoaW5nIGluZGljYXRlcyBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYWNrYWdlTWFuYWdlcihjd2Q/OiBzdHJpbmcpOiBQYWNrYWdlTWFuYWdlciB7XG4gIGNvbnN0IHJvb3QgPSBnZXRTdGFydEZvbGRlcihjd2QpO1xuICBjb25zdCBkZWNsYXJlZFBhY2thZ2VNYW5hZ2VyID0gZGV0ZWN0UGFja2FnZU1hbmFnZXJGcm9tUGFja2FnZUpzb24ocm9vdCk7XG4gIGNvbnN0IGxvY2tmaWxlcyA9IExPQ0tGSUxFUy5maWx0ZXIoKGxvY2tmaWxlKSA9PiBleGlzdHNTeW5jKGpvaW4ocm9vdCwgbG9ja2ZpbGUuZmlsZU5hbWUpKSk7XG4gIGNvbnN0IGNsYWltYW50cyA9IG5ldyBTZXQobG9ja2ZpbGVzLm1hcCgobG9ja2ZpbGUpID0+IGxvY2tmaWxlLnBhY2thZ2VNYW5hZ2VyKSk7XG5cbiAgaWYgKGRlY2xhcmVkUGFja2FnZU1hbmFnZXIgIT09IG51bGwpIHtcbiAgICBjbGFpbWFudHMuYWRkKGRlY2xhcmVkUGFja2FnZU1hbmFnZXIpO1xuICB9XG5cbiAgY29uc3QgcGFja2FnZU1hbmFnZXIgPSByZXNvbHZlUGFja2FnZU1hbmFnZXIoe1xuICAgIGNsYWltYW50cyxcbiAgICBkZWNsYXJlZFBhY2thZ2VNYW5hZ2VyXG4gIH0pO1xuXG4gIGlmIChjbGFpbWFudHMuc2l6ZSA+IDEpIHtcbiAgICB3YXJuQWJvdXRTZXZlcmFsQ2xhaW1hbnRzKHtcbiAgICAgIGRlY2xhcmVkUGFja2FnZU1hbmFnZXIsXG4gICAgICBsb2NrZmlsZXMsXG4gICAgICBwYWNrYWdlTWFuYWdlcixcbiAgICAgIHJvb3RcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBwYWNrYWdlTWFuYWdlcjtcbn1cblxuLyoqXG4gKiBCdWlsZHMgdGhlIGNvbW1hbmQgcGFydHMgdGhhdCBydW4gYSBwYWNrYWdlIHNjcmlwdCB0aHJvdWdoIHRoZSBtYW5hZ2VyIHRoYXQgb3ducyB0aGUgdHJlZS5cbiAqXG4gKiBAcGFyYW0gY3dkIC0gVGhlIGN1cnJlbnQgd29ya2luZyBmb2xkZXIgdG8gcmVzb2x2ZSBmcm9tLlxuICogQHJldHVybnMgVGhlIGNvbW1hbmQgcGFydHMsIGUuZy4gYFsnYnVuJywgJ3J1biddYC4gVGhlIHNjcmlwdCBuYW1lIGlzIGFwcGVuZGVkIGJ5IHRoZSBjYWxsZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYWNrYWdlTWFuYWdlclJ1bkNvbW1hbmQoY3dkPzogc3RyaW5nKTogc3RyaW5nW10ge1xuICByZXR1cm4gW2dldFBhY2thZ2VNYW5hZ2VyKGN3ZCksICdydW4nXTtcbn1cblxuLyoqXG4gKiBCdWlsZHMgdGhlIGNvbW1hbmQgcGFydHMgdGhhdCBydW4gYSBsb2NhbGx5LWluc3RhbGxlZCB0b29sLCB3aXRoIHRoZSB0b29sIGl0c2VsZiBhbHJlYWR5IGluY2x1ZGVkLlxuICpcbiAqIFByZWZlcnMgdGhlIHNoaW0gaW4gdGhlIG5lYXJlc3QgYG5vZGVfbW9kdWxlcy8uYmluYCwgd2Fsa2luZyB1cCB0aHJvdWdoIGFuY2VzdG9yIGZvbGRlcnMgc28gYSBob2lzdGVkXG4gKiB3b3Jrc3BhY2UgaW5zdGFsbCBpcyBzdGlsbCBmb3VuZC4gRmFsbHMgYmFjayB0byB0aGUgb3duaW5nIG1hbmFnZXIncyBleGVjIGZvcm0gd2hlbiBubyBzaGltIHJlc29sdmVzIFx1MjAxNFxuICogd2hpY2ggaXMgYm90aCB0aGUgcHJldmlvdXMgYmVoYXZpb3IgYW5kIHRoZSBvbmx5IHRoaW5nIHRoYXQgd29ya3MgdW5kZXIgeWFybidzIFBsdWcnbidQbGF5LCB3aGVyZVxuICogYG5vZGVfbW9kdWxlcy8uYmluYCBkb2VzIG5vdCBleGlzdCBhdCBhbGwuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgcmVzb2x1dGlvbi5cbiAqIEByZXR1cm5zIFRoZSBjb21tYW5kIHBhcnRzLCBlLmcuIGBbJy9wcm9qZWN0L25vZGVfbW9kdWxlcy8uYmluL3RzYyddYCBvciBgWydidW4nLCAneCcsICd0c2MnXWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlVG9vbENvbW1hbmQocGFyYW1zOiBSZXNvbHZlVG9vbENvbW1hbmRQYXJhbXMpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHsgY3dkLCB0b29sIH0gPSBwYXJhbXM7XG4gIGNvbnN0IHNoaW1QYXRoID0gZmluZEJpblNoaW0oeyBjd2QsIHRvb2wgfSk7XG5cbiAgaWYgKHNoaW1QYXRoICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIFtzaGltUGF0aF07XG4gIH1cblxuICByZXR1cm4gWy4uLmdldFBhY2thZ2VNYW5hZ2VyRXhlY0NvbW1hbmQoY3dkKSwgdG9vbF07XG59XG5cbi8qKlxuICogTWF0Y2hlcyB0aGUgbGVhZGluZyBgPG5hbWU+QGAgdG9rZW4gb2YgYSBgcGFja2FnZS5qc29uYCBgcGFja2FnZU1hbmFnZXJgIHZhbHVlLlxuICpcbiAqIFRoZSBgQGAgaXMgcmVxdWlyZWQsIGJlY2F1c2UgY29yZXBhY2sncyBmb3JtYXQgaXMgYDxuYW1lPkA8dmVyc2lvbj5gIFx1MjAxNCBhIGJhcmUgbmFtZSBpcyBhIG1hbGZvcm1lZFxuICogZGVjbGFyYXRpb24gcmF0aGVyIHRoYW4gYSBzaG9ydGhhbmQsIGFuZCBpcyBpZ25vcmVkIGluc3RlYWQgb2YgZ3Vlc3NlZCBhdC5cbiAqL1xuY29uc3QgREVDTEFSQVRJT05fTkFNRV9SRUdfRVhQID0gL14oPzxuYW1lPlteQFxcc10rKUAvO1xuXG4vKipcbiAqIFRoZSBsb2NrZmlsZXMgdGhhdCBpZGVudGlmeSBhIHBhY2thZ2UgbWFuYWdlciwgaW4gdGhlIG9yZGVyIHRoZXkgZGVjaWRlIGEgdGllIG5vIG90aGVyIHNpZ25hbCBzZXR0bGVzLlxuICpcbiAqIEJvdGggYnVuIGxvY2tmaWxlIGZvcm1hdHMgbWFwIHRvIHRoZSBzYW1lIG1hbmFnZXIsIHNvIGEgcmVwbyBob2xkaW5nIGJvdGggaXMgb25lIGNsYWltYW50LCBub3QgdHdvLlxuICovXG5jb25zdCBMT0NLRklMRVM6IExvY2tmaWxlQ2xhaW1bXSA9IFtcbiAgeyBmaWxlTmFtZTogT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5CdW5Mb2NrLCBwYWNrYWdlTWFuYWdlcjogUGFja2FnZU1hbmFnZXIuQnVuIH0sXG4gIHsgZmlsZU5hbWU6IE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuQnVuTG9ja2IsIHBhY2thZ2VNYW5hZ2VyOiBQYWNrYWdlTWFuYWdlci5CdW4gfSxcbiAgeyBmaWxlTmFtZTogT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5QbnBtTG9ja1lhbWwsIHBhY2thZ2VNYW5hZ2VyOiBQYWNrYWdlTWFuYWdlci5QbnBtIH0sXG4gIHsgZmlsZU5hbWU6IE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuWWFybkxvY2ssIHBhY2thZ2VNYW5hZ2VyOiBQYWNrYWdlTWFuYWdlci5ZYXJuIH0sXG4gIHsgZmlsZU5hbWU6IE9ic2lkaWFuRGV2VXRpbHNSZXBvUGF0aHMuUGFja2FnZUxvY2tKc29uLCBwYWNrYWdlTWFuYWdlcjogUGFja2FnZU1hbmFnZXIuTnBtIH1cbl07XG5cbi8qKlxuICogTWF0Y2hlcyB0aGUgbGVhZGluZyBgPG5hbWU+L2AgdG9rZW4gb2YgYW4gYG5wbV9jb25maWdfdXNlcl9hZ2VudGAgdmFsdWUuXG4gKi9cbmNvbnN0IFVTRVJfQUdFTlRfTkFNRV9SRUdfRVhQID0gL14oPzxuYW1lPlteL1xcc10rKVxcLy87XG5cbi8qKlxuICogVGhlIGRpc2FncmVlbWVudHMgYWxyZWFkeSByZXBvcnRlZCwgc28gYSBidWlsZCB0aGF0IHJlc29sdmVzIHRoZSBtYW5hZ2VyIG9uY2UgcGVyIHNjcmlwdCBob3AgYW5kIG9uY2VcbiAqIHBlciB0b29sIGludm9jYXRpb24gc3RpbGwgc2F5cyBpdCBvbmx5IG9uY2UuXG4gKi9cbmNvbnN0IHJlcG9ydGVkRGlzYWdyZWVtZW50cyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBmaW5kQmluU2hpbX0uXG4gKi9cbmludGVyZmFjZSBGaW5kQmluU2hpbVBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgY3VycmVudCB3b3JraW5nIGZvbGRlciB0byByZXNvbHZlIGZyb20uXG4gICAqL1xuICByZWFkb25seSBjd2Q/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBsb2NhbGx5LWluc3RhbGxlZCB0b29sLlxuICAgKi9cbiAgcmVhZG9ubHkgdG9vbDogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgbG9ja2ZpbGUgYW5kIHRoZSBwYWNrYWdlIG1hbmFnZXIgd2hvc2UgcHJlc2VuY2UgaXQgcHJvdmVzLlxuICovXG5pbnRlcmZhY2UgTG9ja2ZpbGVDbGFpbSB7XG4gIC8qKlxuICAgKiBUaGUgbG9ja2ZpbGUgbmFtZSwgYXMgaXQgYXBwZWFycyBhdCB0aGUgcHJvamVjdCByb290LlxuICAgKi9cbiAgcmVhZG9ubHkgZmlsZU5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHBhY2thZ2UgbWFuYWdlciB0aGF0IHdyaXRlcyB0aGlzIGxvY2tmaWxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcGFja2FnZU1hbmFnZXI6IFBhY2thZ2VNYW5hZ2VyO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayByZXNvbHZlUGFja2FnZU1hbmFnZXJ9LlxuICovXG5pbnRlcmZhY2UgUmVzb2x2ZVBhY2thZ2VNYW5hZ2VyUGFyYW1zIHtcbiAgLyoqXG4gICAqIEV2ZXJ5IHBhY2thZ2UgbWFuYWdlciBjbGFpbWluZyB0aGUgdHJlZSBcdTIwMTQgdGhlIGxvY2tmaWxlIG93bmVycyBpbiB7QGxpbmsgTE9DS0ZJTEVTfSBvcmRlciwgcGx1cyB0aGVcbiAgICogZGVjbGFyZWQgb25lLiBPbmx5IGNvbnN1bHRlZCB3aGVuIG5vdGhpbmcgaXMgZGVjbGFyZWQsIGluIHdoaWNoIGNhc2UgaXQgaG9sZHMgZXhhY3RseSB0aGUgbG9ja2ZpbGVcbiAgICogb3duZXJzLlxuICAgKi9cbiAgcmVhZG9ubHkgY2xhaW1hbnRzOiBSZWFkb25seVNldDxQYWNrYWdlTWFuYWdlcj47XG5cbiAgLyoqXG4gICAqIFRoZSBwYWNrYWdlIG1hbmFnZXIgZGVjbGFyZWQgaW4gYHBhY2thZ2UuanNvbmAsIG9yIGBudWxsYCB3aGVuIG5vbmUgaXMuXG4gICAqL1xuICByZWFkb25seSBkZWNsYXJlZFBhY2thZ2VNYW5hZ2VyOiBudWxsIHwgUGFja2FnZU1hbmFnZXI7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHdhcm5BYm91dFNldmVyYWxDbGFpbWFudHN9LlxuICovXG5pbnRlcmZhY2UgV2FybkFib3V0U2V2ZXJhbENsYWltYW50c1BhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgcGFja2FnZSBtYW5hZ2VyIGRlY2xhcmVkIGluIGBwYWNrYWdlLmpzb25gLCBvciBgbnVsbGAgd2hlbiBub25lIGlzLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVjbGFyZWRQYWNrYWdlTWFuYWdlcjogbnVsbCB8IFBhY2thZ2VNYW5hZ2VyO1xuXG4gIC8qKlxuICAgKiBUaGUgbG9ja2ZpbGVzIGFjdHVhbGx5IGZvdW5kIGF0IHRoZSBwcm9qZWN0IHJvb3QuXG4gICAqL1xuICByZWFkb25seSBsb2NrZmlsZXM6IHJlYWRvbmx5IExvY2tmaWxlQ2xhaW1bXTtcblxuICAvKipcbiAgICogVGhlIHBhY2thZ2UgbWFuYWdlciB0aGF0IHdvbi5cbiAgICovXG4gIHJlYWRvbmx5IHBhY2thZ2VNYW5hZ2VyOiBQYWNrYWdlTWFuYWdlcjtcblxuICAvKipcbiAgICogVGhlIHByb2plY3Qgcm9vdCB0aGUgbG9ja2ZpbGVzIHdlcmUgZm91bmQgaW4uXG4gICAqL1xuICByZWFkb25seSByb290OiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmVhZHMgdGhlIHBhY2thZ2UgbWFuYWdlciBvdXQgb2YgdGhlIGBwYWNrYWdlTWFuYWdlcmAgZmllbGQgb2YgdGhlIHByb2plY3QncyBgcGFja2FnZS5qc29uYCwgd2hpY2ggaXNcbiAqIGNvcmVwYWNrJ3MgYDxuYW1lPkA8dmVyc2lvbj5gIGRlY2xhcmF0aW9uLlxuICpcbiAqIEBwYXJhbSByb290IC0gVGhlIHByb2plY3Qgcm9vdCB0byByZWFkIGBwYWNrYWdlLmpzb25gIGZyb20uXG4gKiBAcmV0dXJucyBUaGUgZGVjbGFyZWQgcGFja2FnZSBtYW5hZ2VyLCBvciBgbnVsbGAgd2hlbiB0aGVyZSBpcyBubyBgcGFja2FnZS5qc29uYCwgaXQgY2Fubm90IGJlIHBhcnNlZCxcbiAqIHRoZSBmaWVsZCBpcyBhYnNlbnQgb3IgbWFsZm9ybWVkLCBvciBpdCBuYW1lcyBhIG1hbmFnZXIgd2UgZG8gbm90IGhhbmRsZS5cbiAqL1xuZnVuY3Rpb24gZGV0ZWN0UGFja2FnZU1hbmFnZXJGcm9tUGFja2FnZUpzb24ocm9vdDogc3RyaW5nKTogbnVsbCB8IFBhY2thZ2VNYW5hZ2VyIHtcbiAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gam9pbihyb290LCBPYnNpZGlhbkRldlV0aWxzUmVwb1BhdGhzLlBhY2thZ2VKc29uKTtcblxuICBpZiAoIWV4aXN0c1N5bmMocGFja2FnZUpzb25QYXRoKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgbGV0IHBhY2thZ2VKc29uOiBQYWNrYWdlSnNvbjtcblxuICB0cnkge1xuICAgIHBhY2thZ2VKc29uID0gcmVhZEpzb25TeW5jPFBhY2thZ2VKc29uPihwYWNrYWdlSnNvblBhdGgpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGRlY2xhcmF0aW9uID0gcGFja2FnZUpzb24ucGFja2FnZU1hbmFnZXI7XG5cbiAgaWYgKCFkZWNsYXJhdGlvbikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgbWF0Y2ggPSBERUNMQVJBVElPTl9OQU1FX1JFR19FWFAuZXhlYyhkZWNsYXJhdGlvbik7XG5cbiAgaWYgKCFtYXRjaCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHBhcnNlUGFja2FnZU1hbmFnZXJOYW1lKGdldE1hbmRhdG9yeU5hbWVkR3JvdXAobWF0Y2gsICduYW1lJykpO1xufVxuXG4vKipcbiAqIFJlYWRzIHRoZSBwYWNrYWdlIG1hbmFnZXIgb3V0IG9mIGBucG1fY29uZmlnX3VzZXJfYWdlbnRgLCB3aGljaCBldmVyeSBtYW5hZ2VyIHNldHMgZm9yIHRoZSBwcm9jZXNzZXMgaXRcbiAqIGxhdW5jaGVzLlxuICpcbiAqIEByZXR1cm5zIFRoZSBkZXRlY3RlZCBwYWNrYWdlIG1hbmFnZXIsIG9yIGBudWxsYCB3aGVuIHRoZSB2YXJpYWJsZSBpcyBhYnNlbnQsIG1hbGZvcm1lZCwgb3IgbmFtZXMgYVxuICogcnVudGltZSB3ZSBkbyBub3QgaGFuZGxlLlxuICovXG5mdW5jdGlvbiBkZXRlY3RQYWNrYWdlTWFuYWdlckZyb21Vc2VyQWdlbnQoKTogbnVsbCB8IFBhY2thZ2VNYW5hZ2VyIHtcbiAgY29uc3QgdXNlckFnZW50ID0gcHJvY2Vzcy5lbnZbJ25wbV9jb25maWdfdXNlcl9hZ2VudCddO1xuXG4gIGlmICghdXNlckFnZW50KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBtYXRjaCA9IFVTRVJfQUdFTlRfTkFNRV9SRUdfRVhQLmV4ZWModXNlckFnZW50KTtcblxuICBpZiAoIW1hdGNoKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gcGFyc2VQYWNrYWdlTWFuYWdlck5hbWUoZ2V0TWFuZGF0b3J5TmFtZWRHcm91cChtYXRjaCwgJ25hbWUnKSk7XG59XG5cbi8qKlxuICogRmluZHMgdGhlIGBub2RlX21vZHVsZXMvLmJpbmAgc2hpbSBmb3IgYSB0b29sLCB3YWxraW5nIHVwIGZyb20gdGhlIHByb2plY3Qgcm9vdCB0aHJvdWdoIGFuY2VzdG9yIGZvbGRlcnMuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgbG9va3VwLlxuICogQHJldHVybnMgVGhlIGFic29sdXRlIHBhdGggb2YgdGhlIHNoaW0sIG9yIGBudWxsYCB3aGVuIG5vbmUgZXhpc3RzLlxuICovXG5mdW5jdGlvbiBmaW5kQmluU2hpbShwYXJhbXM6IEZpbmRCaW5TaGltUGFyYW1zKTogbnVsbCB8IHN0cmluZyB7XG4gIGNvbnN0IHsgY3dkLCB0b29sIH0gPSBwYXJhbXM7XG4gIGNvbnN0IGNhbmRpZGF0ZXMgPSBnZXRTaGltQ2FuZGlkYXRlcyh0b29sKTtcbiAgbGV0IGN1cnJlbnRGb2xkZXIgPSBnZXRTdGFydEZvbGRlcihjd2QpO1xuXG4gIHdoaWxlIChcbiAgICBjdXJyZW50Rm9sZGVyICE9PSBPYnNpZGlhbkRldlV0aWxzUmVwb1BhdGhzLkN1cnJlbnRGb2xkZXIgYXMgc3RyaW5nXG4gICAgJiYgY3VycmVudEZvbGRlciAhPT0gT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5Sb290Rm9sZGVyIGFzIHN0cmluZ1xuICApIHtcbiAgICBmb3IgKGNvbnN0IGNhbmRpZGF0ZSBvZiBjYW5kaWRhdGVzKSB7XG4gICAgICBjb25zdCBzaGltUGF0aCA9IGpvaW4oY3VycmVudEZvbGRlciwgT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5Ob2RlTW9kdWxlcywgT2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5CaW4sIGNhbmRpZGF0ZSk7XG4gICAgICBpZiAoZXhpc3RzU3luYyhzaGltUGF0aCkpIHtcbiAgICAgICAgcmV0dXJuIHNoaW1QYXRoO1xuICAgICAgfVxuICAgIH1cblxuICAgIGN1cnJlbnRGb2xkZXIgPSBkaXJuYW1lKGN1cnJlbnRGb2xkZXIpO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBjb21tYW5kIHBhcnRzIHRoYXQgcnVuIGEgb25lLW9mZiB0b29sIHRocm91Z2ggdGhlIG1hbmFnZXIgdGhhdCBvd25zIHRoZSB0cmVlLlxuICpcbiAqIEBwYXJhbSBjd2QgLSBUaGUgY3VycmVudCB3b3JraW5nIGZvbGRlciB0byByZXNvbHZlIGZyb20uXG4gKiBAcmV0dXJucyBUaGUgY29tbWFuZCBwYXJ0cywgZS5nLiBgWydidW4nLCAneCddYC4gVGhlIHRvb2wgbmFtZSBpcyBhcHBlbmRlZCBieSB0aGUgY2FsbGVyLlxuICovXG5mdW5jdGlvbiBnZXRQYWNrYWdlTWFuYWdlckV4ZWNDb21tYW5kKGN3ZD86IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgcGFja2FnZU1hbmFnZXIgPSBnZXRQYWNrYWdlTWFuYWdlcihjd2QpO1xuXG4gIHN3aXRjaCAocGFja2FnZU1hbmFnZXIpIHtcbiAgICBjYXNlIFBhY2thZ2VNYW5hZ2VyLkJ1bjoge1xuICAgICAgcmV0dXJuIFsnYnVuJywgJ3gnXTtcbiAgICB9XG4gICAgY2FzZSBQYWNrYWdlTWFuYWdlci5OcG06IHtcbiAgICAgIHJldHVybiBbJ25weCddO1xuICAgIH1cbiAgICBjYXNlIFBhY2thZ2VNYW5hZ2VyLlBucG06IHtcbiAgICAgIHJldHVybiBbJ3BucG0nLCAnZXhlYyddO1xuICAgIH1cbiAgICBjYXNlIFBhY2thZ2VNYW5hZ2VyLllhcm46IHtcbiAgICAgIHJldHVybiBbJ3lhcm4nLCAnZXhlYyddO1xuICAgIH1cbiAgICAvKiB2OCBpZ25vcmUgc3RhcnQgLS0gRXhoYXVzdGl2ZSBzd2l0Y2ggZ3VhcmQ7IGRlZmF1bHQgYnJhbmNoIGlzIHVucmVhY2hhYmxlLiAqL1xuICAgIGRlZmF1bHQ6IHtcbiAgICAgIHJldHVybiBhc3NlcnROZXZlcihwYWNrYWdlTWFuYWdlcik7XG4gICAgfVxuICAgICAgLyogdjggaWdub3JlIHN0b3AgKi9cbiAgfVxufVxuXG4vKipcbiAqIExpc3RzIHRoZSBzaGltIGZpbGUgbmFtZXMgdG8gdHJ5IGZvciBhIHRvb2wsIG1vc3Qgc3BlY2lmaWMgZmlyc3QuXG4gKlxuICogT24gV2luZG93cyBvbmx5IHRoZSBleGVjdXRhYmxlIGZvcm1zIGFyZSB2aWFibGU6IG5wbSBhbmQgcG5wbSBhbHNvIHdyaXRlIGEgc2hpbSB3aXRoIG5vIGV4dGVuc2lvbiwgYnV0XG4gKiB0aGF0IG9uZSBpcyBhIGBzaGAgc2NyaXB0IHRoYXQgYGNtZC5leGVgIGNhbm5vdCBydW4sIHNvIGl0IG11c3QgbmV2ZXIgYmUgY2hvc2VuIHRoZXJlLlxuICpcbiAqIEBwYXJhbSB0b29sIC0gVGhlIG5hbWUgb2YgdGhlIGxvY2FsbHktaW5zdGFsbGVkIHRvb2wuXG4gKiBAcmV0dXJucyBUaGUgY2FuZGlkYXRlIGZpbGUgbmFtZXMsIGluIHRoZSBvcmRlciB0aGV5IHNob3VsZCBiZSB0cmllZC5cbiAqL1xuZnVuY3Rpb24gZ2V0U2hpbUNhbmRpZGF0ZXModG9vbDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSAhPT0gJ3dpbjMyJykge1xuICAgIHJldHVybiBbdG9vbF07XG4gIH1cblxuICByZXR1cm4gW1xuICAgIGAke3Rvb2x9JHtPYnNpZGlhbkRldlV0aWxzUmVwb1BhdGhzLkNvbW1hbmRFeHRlbnNpb259YCxcbiAgICBgJHt0b29sfSR7T2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5FeGVFeHRlbnNpb259YCxcbiAgICBgJHt0b29sfSR7T2JzaWRpYW5EZXZVdGlsc1JlcG9QYXRocy5CYXRFeHRlbnNpb259YFxuICBdO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBmb2xkZXIgdG8gc3RhcnQgYSBsb29rdXAgZnJvbSBcdTIwMTQgdGhlIHByb2plY3Qgcm9vdCB3aGVuIHRoZXJlIGlzIG9uZSwgdGhlIHdvcmtpbmcgZm9sZGVyXG4gKiBvdGhlcndpc2UuXG4gKlxuICogQHBhcmFtIGN3ZCAtIFRoZSBjdXJyZW50IHdvcmtpbmcgZm9sZGVyIHRvIHJlc29sdmUgZnJvbS5cbiAqIEByZXR1cm5zIFRoZSBhYnNvbHV0ZSBmb2xkZXIgdG8gc3RhcnQgZnJvbS5cbiAqL1xuZnVuY3Rpb24gZ2V0U3RhcnRGb2xkZXIoY3dkPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGdldFJvb3RGb2xkZXIoY3dkKSA/PyB0b1Bvc2l4UGF0aChjd2QgPz8gcHJvY2Vzcy5jd2QoKSk7XG59XG5cbi8qKlxuICogTWFwcyB0aGUgYmFyZSBuYW1lIGEgbG9ja2ZpbGUgZGVjbGFyYXRpb24gb3IgYSB1c2VyIGFnZW50IHJlcG9ydHMgb250byB0aGUgcGFja2FnZSBtYW5hZ2VyIGl0IG5hbWVzLlxuICpcbiAqIEBwYXJhbSBuYW1lIC0gVGhlIHJlcG9ydGVkIG5hbWUuXG4gKiBAcmV0dXJucyBUaGUgbWF0Y2hpbmcgcGFja2FnZSBtYW5hZ2VyLCBvciBgbnVsbGAgZm9yIGEgcnVudGltZSB3ZSBkbyBub3QgaGFuZGxlLlxuICovXG5mdW5jdGlvbiBwYXJzZVBhY2thZ2VNYW5hZ2VyTmFtZShuYW1lOiBzdHJpbmcpOiBudWxsIHwgUGFja2FnZU1hbmFnZXIge1xuICBzd2l0Y2ggKG5hbWUpIHtcbiAgICBjYXNlIFBhY2thZ2VNYW5hZ2VyLkJ1biBhcyBzdHJpbmc6IHtcbiAgICAgIHJldHVybiBQYWNrYWdlTWFuYWdlci5CdW47XG4gICAgfVxuICAgIGNhc2UgUGFja2FnZU1hbmFnZXIuTnBtIGFzIHN0cmluZzoge1xuICAgICAgcmV0dXJuIFBhY2thZ2VNYW5hZ2VyLk5wbTtcbiAgICB9XG4gICAgY2FzZSBQYWNrYWdlTWFuYWdlci5QbnBtIGFzIHN0cmluZzoge1xuICAgICAgcmV0dXJuIFBhY2thZ2VNYW5hZ2VyLlBucG07XG4gICAgfVxuICAgIGNhc2UgUGFja2FnZU1hbmFnZXIuWWFybiBhcyBzdHJpbmc6IHtcbiAgICAgIHJldHVybiBQYWNrYWdlTWFuYWdlci5ZYXJuO1xuICAgIH1cbiAgICBkZWZhdWx0OiB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBQaWNrcyB0aGUgd2lubmVyIG91dCBvZiB0aGUgY29sbGVjdGVkIHNpZ25hbHMsIHBlciB0aGUgb3JkZXIgZG9jdW1lbnRlZCBvbiB7QGxpbmsgZ2V0UGFja2FnZU1hbmFnZXJ9LlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhlIHJlc29sdXRpb24uXG4gKiBAcmV0dXJucyBUaGUgcGFja2FnZSBtYW5hZ2VyIHRoYXQgb3ducyB0aGUgdHJlZS5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVBhY2thZ2VNYW5hZ2VyKHBhcmFtczogUmVzb2x2ZVBhY2thZ2VNYW5hZ2VyUGFyYW1zKTogUGFja2FnZU1hbmFnZXIge1xuICBjb25zdCB7XG4gICAgY2xhaW1hbnRzLFxuICAgIGRlY2xhcmVkUGFja2FnZU1hbmFnZXJcbiAgfSA9IHBhcmFtcztcblxuICBpZiAoZGVjbGFyZWRQYWNrYWdlTWFuYWdlciAhPT0gbnVsbCkge1xuICAgIHJldHVybiBkZWNsYXJlZFBhY2thZ2VNYW5hZ2VyO1xuICB9XG5cbiAgY29uc3QgbG9ja2ZpbGVPd25lcnMgPSBbLi4uY2xhaW1hbnRzXTtcbiAgY29uc3QgW2ZpcnN0TG9ja2ZpbGVPd25lcl0gPSBsb2NrZmlsZU93bmVycztcblxuICBpZiAoZmlyc3RMb2NrZmlsZU93bmVyID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZGV0ZWN0UGFja2FnZU1hbmFnZXJGcm9tVXNlckFnZW50KCkgPz8gUGFja2FnZU1hbmFnZXIuTnBtO1xuICB9XG5cbiAgaWYgKGxvY2tmaWxlT3duZXJzLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiBmaXJzdExvY2tmaWxlT3duZXI7XG4gIH1cblxuICBjb25zdCBsYXVuY2hlZEJ5ID0gZGV0ZWN0UGFja2FnZU1hbmFnZXJGcm9tVXNlckFnZW50KCk7XG5cbiAgaWYgKGxhdW5jaGVkQnkgIT09IG51bGwgJiYgY2xhaW1hbnRzLmhhcyhsYXVuY2hlZEJ5KSkge1xuICAgIHJldHVybiBsYXVuY2hlZEJ5O1xuICB9XG5cbiAgcmV0dXJuIGZpcnN0TG9ja2ZpbGVPd25lcjtcbn1cblxuLyoqXG4gKiBSZXBvcnRzIHRoYXQgc2V2ZXJhbCBwYWNrYWdlIG1hbmFnZXJzIGNsYWltIHRoZSBzYW1lIHRyZWUsIG5hbWluZyBlYWNoIGxvY2tmaWxlIGZvdW5kLCB3aGF0XG4gKiBgcGFja2FnZS5qc29uYCBkZWNsYXJlcywgYW5kIHdoaWNoIG1hbmFnZXIgd29uLlxuICpcbiAqIGBjb25zb2xlLndhcm5gIHJhdGhlciB0aGFuIGEgZGVidWcgY2hhbm5lbDogdGhpcyBydW5zIGluIHRoZSBidWlsZCdzIG93biB0ZXJtaW5hbCwgYW5kIGEgbWVzc2FnZSBub2JvZHlcbiAqIHNlZXMgdW5sZXNzIHRoZXkgYWxyZWFkeSBzdXNwZWN0IHRoZSBwcm9ibGVtIGxlYXZlcyB0aGUgZmFpbHVyZSBleGFjdGx5IGFzIHNpbGVudCBhcyBpdCB3YXMuIEVhY2hcbiAqIGRpc3RpbmN0IG1lc3NhZ2UgaXMgcHJpbnRlZCBvbmNlLCBiZWNhdXNlIHRoZSBtYW5hZ2VyIGlzIHJlc29sdmVkIG9uY2UgcGVyIHBhY2thZ2Utc2NyaXB0IGhvcCBhbmQgb25jZVxuICogcGVyIHRvb2wgaW52b2NhdGlvbi5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoZSByZXBvcnQuXG4gKi9cbmZ1bmN0aW9uIHdhcm5BYm91dFNldmVyYWxDbGFpbWFudHMocGFyYW1zOiBXYXJuQWJvdXRTZXZlcmFsQ2xhaW1hbnRzUGFyYW1zKTogdm9pZCB7XG4gIGNvbnN0IHtcbiAgICBkZWNsYXJlZFBhY2thZ2VNYW5hZ2VyLFxuICAgIGxvY2tmaWxlcyxcbiAgICBwYWNrYWdlTWFuYWdlcixcbiAgICByb290XG4gIH0gPSBwYXJhbXM7XG5cbiAgY29uc3QgbG9ja2ZpbGVOYW1lcyA9IGxvY2tmaWxlcy5tYXAoKGxvY2tmaWxlKSA9PiBsb2NrZmlsZS5maWxlTmFtZSkuam9pbignLCAnKTtcbiAgY29uc3QgYWR2aWNlID0gZGVjbGFyZWRQYWNrYWdlTWFuYWdlciA9PT0gbnVsbFxuICAgID8gJ0RlbGV0ZSB0aGUgc3RhbGUgbG9ja2ZpbGUsIG9yIGRlY2xhcmUgXCJwYWNrYWdlTWFuYWdlclwiIGluIHBhY2thZ2UuanNvbiwgdG8gc2V0dGxlIGl0LidcbiAgICA6ICdEZWxldGUgdGhlIHN0YWxlIGxvY2tmaWxlIHRvIHNldHRsZSBpdC4nO1xuICBjb25zdCBtZXNzYWdlID0gW1xuICAgIGBvYnNpZGlhbi1kZXYtdXRpbHM6IG1vcmUgdGhhbiBvbmUgcGFja2FnZSBtYW5hZ2VyIGNsYWltcyAke3Jvb3R9LmAsXG4gICAgYExvY2tmaWxlczogJHtsb2NrZmlsZU5hbWVzfS5gLFxuICAgIGBwYWNrYWdlLmpzb24gXCJwYWNrYWdlTWFuYWdlclwiOiAke2RlY2xhcmVkUGFja2FnZU1hbmFnZXIgPz8gJ25vdCBzZXQnfS5gLFxuICAgIGBVc2luZyAke3BhY2thZ2VNYW5hZ2VyfS5gLFxuICAgIGFkdmljZVxuICBdLmpvaW4oJyAnKTtcblxuICBpZiAocmVwb3J0ZWREaXNhZ3JlZW1lbnRzLmhhcyhtZXNzYWdlKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJlcG9ydGVkRGlzYWdyZWVtZW50cy5hZGQobWVzc2FnZSk7XG4gIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFjQSxTQUFTLGtCQUFrQjtBQUMzQixPQUFPLGFBQWE7QUFFcEI7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsU0FBUyw4QkFBOEI7QUFDdkMsU0FBUyxtQkFBbUI7QUFDNUIsU0FBUyxvQkFBb0I7QUFDN0IsU0FBUyxpQ0FBaUM7QUFDMUMsU0FBUyxxQkFBcUI7QUFLdkIsSUFBSyxpQkFBTCxrQkFBS0Esb0JBQUw7QUFJTCxFQUFBQSxnQkFBQSxTQUFNO0FBS04sRUFBQUEsZ0JBQUEsU0FBTTtBQUtOLEVBQUFBLGdCQUFBLFVBQU87QUFLUCxFQUFBQSxnQkFBQSxVQUFPO0FBbkJHLFNBQUFBO0FBQUEsR0FBQTtBQWdFTCxTQUFTLGtCQUFrQixLQUE4QjtBQUM5RCxRQUFNLE9BQU8sZUFBZSxHQUFHO0FBQy9CLFFBQU0seUJBQXlCLG9DQUFvQyxJQUFJO0FBQ3ZFLFFBQU0sWUFBWSxVQUFVLE9BQU8sQ0FBQyxhQUFhLFdBQVcsS0FBSyxNQUFNLFNB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