mulmoclaude 0.6.2 → 0.6.4

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 (182) hide show
  1. package/README.md +26 -0
  2. package/bin/mulmoclaude.js +11 -1
  3. package/client/assets/JsonEditor-D6WBWLoa.js +10 -0
  4. package/client/assets/JsonEditor-Di5xGeZY.css +1 -0
  5. package/client/assets/_plugin-vue_export-helper-BOai-rQB.js +1 -0
  6. package/client/assets/chunk-D8eiyYIV-LcKZGJv5.js +1 -0
  7. package/client/assets/{html2canvas-CDGcmOD3-Bkf2uOth.js → html2canvas-CDGcmOD3-XVrO-eyz.js} +1 -1
  8. package/client/assets/index-CyBr8Mkr.css +2 -0
  9. package/client/assets/index-zZIqEbNX.js +5106 -0
  10. package/client/assets/{index.es-DqtpmBm8-D9mAh_KQ.js → index.es-DqtpmBm8-DHT6q10o.js} +1 -1
  11. package/client/assets/material-symbols-outlined-DtIK7AQn.woff2 +0 -0
  12. package/client/assets/runtime-protocol-vue-D6kcV0wa.js +1 -0
  13. package/client/assets/{runtime-vue-BVUzgYGA.js → runtime-vue-fFYhnNg3.js} +1 -1
  14. package/client/assets/{vue-C8UuIO9J.js → vue-D4w8THF_.js} +1 -1
  15. package/client/assets/vue-i18n-CQbxVmNs.js +3 -0
  16. package/client/assets/vue.runtime.esm-bundler-BTyIdNAI.js +4 -0
  17. package/client/index.html +10 -10
  18. package/package.json +9 -8
  19. package/server/agent/backend/claude-code.ts +34 -0
  20. package/server/agent/backend/fake-echo.ts +370 -0
  21. package/server/agent/backend/index.ts +16 -1
  22. package/server/agent/config.ts +74 -24
  23. package/server/agent/index.ts +104 -80
  24. package/server/agent/mcpFailureMonitor.ts +167 -0
  25. package/server/agent/mcpPreflight.ts +185 -0
  26. package/server/agent/prompt.ts +50 -359
  27. package/server/agent/stdioHttpShim.ts +171 -0
  28. package/server/agent/stream.ts +12 -1
  29. package/server/api/routes/encore.ts +55 -0
  30. package/server/api/routes/files.ts +22 -0
  31. package/server/api/routes/mulmo-script.ts +19 -1
  32. package/server/api/routes/schedulerHandlers.ts +52 -4
  33. package/server/api/routes/sessions.ts +15 -0
  34. package/server/api/routes/skills.ts +263 -0
  35. package/server/build/dispatcher.mjs +299 -0
  36. package/server/encore/INVARIANTS.md +272 -0
  37. package/server/encore/boot.ts +39 -0
  38. package/server/encore/closure.ts +36 -0
  39. package/server/encore/cycle.ts +276 -0
  40. package/server/encore/dispatch.ts +103 -0
  41. package/server/encore/handlers/amend.ts +99 -0
  42. package/server/encore/handlers/appendNote.ts +74 -0
  43. package/server/encore/handlers/defineEncore.ts +42 -0
  44. package/server/encore/handlers/listTickets.ts +107 -0
  45. package/server/encore/handlers/markStepDone.ts +41 -0
  46. package/server/encore/handlers/markTargetSkipped.ts +33 -0
  47. package/server/encore/handlers/query.ts +138 -0
  48. package/server/encore/handlers/recordValues.ts +44 -0
  49. package/server/encore/handlers/resolveNotification.ts +121 -0
  50. package/server/encore/handlers/setup.ts +81 -0
  51. package/server/encore/handlers/shared.ts +137 -0
  52. package/server/encore/handlers/snooze.ts +87 -0
  53. package/server/encore/handlers/startObligationChat.ts +64 -0
  54. package/server/encore/handlers/startSetupChat.ts +50 -0
  55. package/server/encore/lock.ts +61 -0
  56. package/server/encore/notifier.ts +123 -0
  57. package/server/encore/obligation.ts +25 -0
  58. package/server/encore/paths.ts +78 -0
  59. package/server/encore/reconcile.ts +661 -0
  60. package/server/encore/tick.ts +191 -0
  61. package/server/encore/yaml-fm.ts +63 -0
  62. package/server/events/notifications.ts +19 -91
  63. package/server/index.ts +94 -9
  64. package/server/notifier/engine.ts +102 -1
  65. package/server/notifier/macosReminderAdapter.ts +30 -0
  66. package/server/notifier/runtime-api.ts +41 -1
  67. package/server/notifier/types.ts +15 -2
  68. package/server/plugins/runtime.ts +11 -2
  69. package/server/prompts/index.ts +39 -0
  70. package/server/prompts/system/journal-pointer.md +12 -0
  71. package/server/prompts/system/memory-management-atomic.md +33 -0
  72. package/server/prompts/system/memory-management-topic.md +60 -0
  73. package/server/prompts/system/news-concierge.md +24 -0
  74. package/server/prompts/system/sandbox-tools.md +10 -0
  75. package/server/prompts/system/sources-context.md +16 -0
  76. package/server/prompts/system/system.md +91 -0
  77. package/server/system/announceOptionalDeps.ts +57 -0
  78. package/server/system/appVersion.ts +34 -0
  79. package/server/system/config.ts +17 -1
  80. package/server/system/docker.ts +14 -6
  81. package/server/system/env.ts +18 -5
  82. package/server/system/optionalDeps.ts +129 -0
  83. package/server/utils/cli-flags.d.mts +14 -0
  84. package/server/utils/cli-flags.mjs +53 -0
  85. package/server/utils/files/encore-io.ts +111 -0
  86. package/server/utils/time.ts +6 -0
  87. package/server/workspace/helps/business.md +2 -2
  88. package/server/workspace/helps/encore-dsl.md +482 -0
  89. package/server/workspace/helps/index.md +15 -13
  90. package/server/workspace/helps/mulmoscript.md +3 -3
  91. package/server/workspace/helps/sandbox.md +2 -2
  92. package/server/workspace/hooks/dispatcher.ts +7 -5
  93. package/server/workspace/hooks/provision.ts +6 -3
  94. package/server/workspace/paths.ts +13 -4
  95. package/server/workspace/skills/catalog.ts +355 -0
  96. package/server/workspace/skills/external/catalog.ts +283 -0
  97. package/server/workspace/skills/external/clone.ts +129 -0
  98. package/server/workspace/skills/external/id.ts +194 -0
  99. package/server/workspace/skills/external/install.ts +417 -0
  100. package/server/workspace/skills/external/presets.ts +50 -0
  101. package/server/workspace/skills-preset.ts +29 -17
  102. package/server/workspace/workspace.ts +10 -5
  103. package/src/App.vue +37 -8
  104. package/src/components/FileContentRenderer.vue +102 -9
  105. package/src/components/JsonEditor.vue +160 -0
  106. package/src/components/NotificationBell.vue +35 -3
  107. package/src/components/PluginLauncher.vue +20 -41
  108. package/src/components/RightSidebar.vue +19 -0
  109. package/src/components/SettingsMcpTab.vue +58 -11
  110. package/src/components/SettingsModal.vue +22 -1
  111. package/src/components/StackView.vue +10 -1
  112. package/src/components/TodoExplorer.vue +16 -0
  113. package/src/components/todo/TodoKanbanView.vue +34 -6
  114. package/src/composables/useNotifications.ts +21 -1
  115. package/src/config/apiRoutes.ts +0 -6
  116. package/src/config/mcpCatalog.ts +12 -7
  117. package/src/config/mcpTypes.ts +5 -0
  118. package/src/config/roles.ts +52 -15
  119. package/src/config/systemFileDescriptors.ts +12 -0
  120. package/src/lang/de.ts +108 -12
  121. package/src/lang/en.ts +105 -11
  122. package/src/lang/es.ts +106 -11
  123. package/src/lang/fr.ts +106 -11
  124. package/src/lang/ja.ts +104 -11
  125. package/src/lang/ko.ts +105 -11
  126. package/src/lang/pt-BR.ts +106 -11
  127. package/src/lang/zh.ts +103 -11
  128. package/src/main.ts +1 -0
  129. package/src/plugins/_generated/metas.ts +4 -0
  130. package/src/plugins/_generated/registrations.ts +2 -0
  131. package/src/plugins/_generated/server-bindings.ts +5 -0
  132. package/src/plugins/encore/EncoreDashboard.vue +504 -0
  133. package/src/plugins/encore/EncoreRedirect.vue +116 -0
  134. package/src/plugins/encore/View.vue +36 -0
  135. package/src/plugins/encore/defineEncoreDefinition.ts +74 -0
  136. package/src/plugins/encore/defineEncoreMeta.ts +13 -0
  137. package/src/plugins/encore/index.ts +93 -0
  138. package/src/plugins/encore/manageEncoreDefinition.ts +100 -0
  139. package/src/plugins/encore/manageEncoreMeta.ts +36 -0
  140. package/src/plugins/manageSkills/View.vue +832 -30
  141. package/src/plugins/manageSkills/categories.ts +125 -0
  142. package/src/plugins/manageSkills/meta.ts +30 -0
  143. package/src/plugins/markdown/definition.ts +3 -3
  144. package/src/plugins/meta-types.ts +5 -0
  145. package/src/plugins/presentMulmoScript/Preview.vue +3 -3
  146. package/src/plugins/presentMulmoScript/View.vue +157 -33
  147. package/src/plugins/presentMulmoScript/meta.ts +4 -0
  148. package/src/plugins/scheduler/View.vue +45 -9
  149. package/src/plugins/scheduler/calendarDefinition.ts +6 -2
  150. package/src/plugins/scheduler/multiDayHelpers.ts +95 -0
  151. package/src/plugins/skill/View.vue +1 -5
  152. package/src/plugins/spreadsheet/View.vue +3 -3
  153. package/src/plugins/spreadsheet/definition.ts +1 -1
  154. package/src/plugins/textResponse/Preview.vue +14 -1
  155. package/src/plugins/textResponse/View.vue +39 -24
  156. package/src/plugins/wiki/components/WikiPageBody.vue +4 -0
  157. package/src/router/index.ts +11 -0
  158. package/src/router/pageRoutes.ts +1 -0
  159. package/src/types/encore-dsl/at-expression.ts +120 -0
  160. package/src/types/encore-dsl/at-resolver.ts +32 -0
  161. package/src/types/encore-dsl/cadence.ts +289 -0
  162. package/src/types/encore-dsl/schema.ts +288 -0
  163. package/src/types/notification.ts +2 -1
  164. package/src/types/session.ts +6 -0
  165. package/src/types/sse.ts +5 -0
  166. package/src/types/toolCallHistory.ts +7 -0
  167. package/src/utils/agent/eventDispatch.ts +26 -5
  168. package/src/utils/agent/mcpHint.ts +50 -0
  169. package/src/utils/image/htmlSrcAttrs.ts +117 -13
  170. package/src/utils/session/sessionEntries.ts +8 -32
  171. package/client/assets/PluginScopedRoot-YjvQq0Nn.js +0 -3
  172. package/client/assets/chunk-CernVdwh.js +0 -1
  173. package/client/assets/chunk-D8eiyYIV-CAXpUwLd.js +0 -1
  174. package/client/assets/index-BwrlMMHr.js +0 -5005
  175. package/client/assets/index-CvvNuegU.css +0 -2
  176. package/client/assets/material-symbols-outlined-BOZVWuR3.woff2 +0 -0
  177. package/client/assets/runtime-protocol-vue-C1To4M3t.js +0 -1
  178. package/client/assets/vue.runtime.esm-bundler-DQ8Kjjui.js +0 -4
  179. package/server/api/routes/notifications.ts +0 -195
  180. package/server/notifier/legacy-adapters.ts +0 -76
  181. package/server/workspace/hooks/dispatcher.mjs +0 -300
  182. package/src/composables/useSelectedResult.ts +0 -49
@@ -1,300 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // server/workspace/hooks/shared/sidecar.ts
4
- import { readFileSync } from "node:fs";
5
- import path2 from "node:path";
6
-
7
- // server/utils/time.ts
8
- var ONE_SECOND_MS = 1e3;
9
- var ONE_MINUTE_MS = 6e4;
10
- var SUBPROCESS_PROBE_TIMEOUT_MS = 5 * ONE_SECOND_MS;
11
- var STARTUP_FAILURE_FORCE_EXIT_MS = 5 * ONE_SECOND_MS;
12
- var CLI_SUBPROCESS_TIMEOUT_MS = 5 * ONE_MINUTE_MS;
13
-
14
- // server/workspace/hooks/shared/workspace.ts
15
- import { homedir } from "node:os";
16
- import path from "node:path";
17
- function workspaceRoot() {
18
- return process.env.CLAUDE_PROJECT_DIR ?? path.join(homedir(), "mulmoclaude");
19
- }
20
-
21
- // server/workspace/hooks/shared/sidecar.ts
22
- var TOKEN_FILE = ".session-token";
23
- var PORT_FILE = ".server-port";
24
- function serverHost() {
25
- return process.env.MULMOCLAUDE_HOST ?? "127.0.0.1";
26
- }
27
- function readSidecar(rel) {
28
- try {
29
- return readFileSync(path2.join(workspaceRoot(), rel), "utf-8").trim();
30
- } catch {
31
- return "";
32
- }
33
- }
34
- function readToken() {
35
- return readSidecar(TOKEN_FILE);
36
- }
37
- function readPort() {
38
- const raw = readSidecar(PORT_FILE);
39
- if (!raw) return null;
40
- const port = Number.parseInt(raw, 10);
41
- return Number.isInteger(port) && port > 0 && port < 65536 ? port : null;
42
- }
43
- function buildAuthPost(pathname, body) {
44
- const token = readToken();
45
- const port = readPort();
46
- if (!token || port === null) return null;
47
- const headers = {
48
- Authorization: `Bearer ${token}`
49
- };
50
- const init = { method: "POST", headers };
51
- if (body !== void 0) {
52
- headers["Content-Type"] = "application/json";
53
- init.body = JSON.stringify(body);
54
- }
55
- return {
56
- url: `http://${serverHost()}:${port}${pathname}`,
57
- init
58
- };
59
- }
60
- var DEFAULT_TIMEOUT_MS = 2 * ONE_SECOND_MS;
61
- async function safePost(req, timeoutMs = DEFAULT_TIMEOUT_MS) {
62
- if (!req) return;
63
- const controller = new AbortController();
64
- const timer = setTimeout(() => controller.abort(), timeoutMs);
65
- try {
66
- await fetch(req.url, { ...req.init, signal: controller.signal });
67
- } catch {
68
- } finally {
69
- clearTimeout(timer);
70
- }
71
- }
72
- var LOG_TIMEOUT_MS = ONE_SECOND_MS;
73
- async function serverLog(namespace, message, options = {}) {
74
- const body = {
75
- namespace,
76
- message,
77
- level: options.level ?? "info",
78
- ...options.data ? { data: options.data } : {}
79
- };
80
- const req = buildAuthPost("/api/hooks/log", body);
81
- await safePost(req, LOG_TIMEOUT_MS);
82
- }
83
-
84
- // server/workspace/hooks/shared/stdin.ts
85
- async function readHookPayload() {
86
- const chunks = [];
87
- for await (const chunk of process.stdin) {
88
- chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
89
- }
90
- const raw = Buffer.concat(chunks).toString("utf-8");
91
- if (!raw.trim()) return null;
92
- try {
93
- return JSON.parse(raw);
94
- } catch {
95
- return null;
96
- }
97
- }
98
- function extractFilePath(payload) {
99
- const fromInput = payload.tool_input?.file_path;
100
- if (typeof fromInput === "string") return fromInput;
101
- const fromResponse = payload.tool_response?.filePath;
102
- if (typeof fromResponse === "string") return fromResponse;
103
- return "";
104
- }
105
- function extractCommand(payload) {
106
- const command = payload.tool_input?.command;
107
- return typeof command === "string" ? command : "";
108
- }
109
- function extractToolName(payload) {
110
- return typeof payload.tool_name === "string" ? payload.tool_name : "";
111
- }
112
- function extractSessionId(payload) {
113
- const sessionId = payload.session_id;
114
- return typeof sessionId === "string" && sessionId.length > 0 ? sessionId : void 0;
115
- }
116
-
117
- // server/workspace/hooks/handlers/configRefresh.ts
118
- var PATTERNS = [/[\\/]\.claude[\\/]skills[\\/][^\\/]+[\\/]SKILL\.md$/, /[\\/]config[\\/]scheduler[\\/]tasks\.json$/];
119
- async function handleConfigRefresh(payload) {
120
- const tool = extractToolName(payload);
121
- if (tool !== "Write" && tool !== "Edit") return;
122
- const filePath = extractFilePath(payload);
123
- if (!filePath) return;
124
- if (!PATTERNS.some((pattern) => pattern.test(filePath))) return;
125
- const req = buildAuthPost("/api/config/refresh");
126
- await safePost(req);
127
- }
128
-
129
- // server/workspace/hooks/handlers/skillBridge.ts
130
- import { mkdirSync, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync } from "node:fs";
131
- import path3 from "node:path";
132
-
133
- // server/utils/errors.ts
134
- function errorMessage(err, fallback) {
135
- if (err instanceof Error) return err.message;
136
- if (err !== null && typeof err === "object") {
137
- const obj = err;
138
- if (typeof obj.details === "string" && obj.details) return obj.details;
139
- if (typeof obj.message === "string" && obj.message) return obj.message;
140
- }
141
- if (fallback !== void 0) return fallback;
142
- return String(err);
143
- }
144
-
145
- // server/workspace/hooks/handlers/skillBridge.ts
146
- var DATA_SKILLS_DIR = path3.join("data", "skills");
147
- var CLAUDE_SKILLS_DIR = path3.join(".claude", "skills");
148
- var SKILL_FILENAME = "SKILL.md";
149
- var SLUG_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
150
- var RM_RE = /^\s*rm\s+((?:-[a-zA-Z]+\s+)+)['"]?data\/skills\/([a-z0-9-]+)\/?['"]?\s*$/;
151
- var RECURSIVE_FLAG_RE = /[rR]/;
152
- function dataSkillDir(slug) {
153
- return path3.join(workspaceRoot(), DATA_SKILLS_DIR, slug);
154
- }
155
- function dataSkillFilePath(slug) {
156
- return path3.join(dataSkillDir(slug), SKILL_FILENAME);
157
- }
158
- function claudeSkillDir(slug) {
159
- return path3.join(workspaceRoot(), CLAUDE_SKILLS_DIR, slug);
160
- }
161
- function claudeSkillFilePath(slug) {
162
- return path3.join(claudeSkillDir(slug), SKILL_FILENAME);
163
- }
164
- function slugFromDataPath(filePath) {
165
- const root = workspaceRoot();
166
- const staging = path3.join(root, DATA_SKILLS_DIR);
167
- const rel = path3.relative(staging, filePath);
168
- if (!rel || rel.startsWith("..")) return null;
169
- const segments = rel.split(path3.sep);
170
- if (segments.length !== 2) return null;
171
- const [slug, basename] = segments;
172
- if (basename !== SKILL_FILENAME) return null;
173
- return SLUG_RE.test(slug) ? slug : null;
174
- }
175
- function slugFromRmCommand(command) {
176
- const match = RM_RE.exec(command);
177
- if (!match) return null;
178
- const [, flags, slug] = match;
179
- if (!RECURSIVE_FLAG_RE.test(flags)) return null;
180
- return SLUG_RE.test(slug) ? slug : null;
181
- }
182
- function mirrorWrite(slug) {
183
- const content = readFileSync2(dataSkillFilePath(slug), "utf-8");
184
- const destDir = claudeSkillDir(slug);
185
- mkdirSync(destDir, { recursive: true });
186
- const dest = claudeSkillFilePath(slug);
187
- const tmp = path3.join(destDir, `.SKILL.md.${process.pid}.tmp`);
188
- writeFileSync(tmp, content, "utf-8");
189
- renameSync(tmp, dest);
190
- }
191
- function mirrorDelete(slug) {
192
- rmSync(claudeSkillDir(slug), { recursive: true, force: true });
193
- }
194
- async function refreshConfig() {
195
- await safePost(buildAuthPost("/api/config/refresh"));
196
- }
197
- async function handleWriteOrEdit(payload) {
198
- const filePath = extractFilePath(payload);
199
- if (!filePath) return;
200
- const slug = slugFromDataPath(filePath);
201
- if (slug === null) return;
202
- try {
203
- mirrorWrite(slug);
204
- await refreshConfig();
205
- await serverLog("skill-bridge", `mirrored ${dataSkillFilePath(slug)} \u2192 ${claudeSkillFilePath(slug)}`, { data: { slug, op: "write" } });
206
- } catch (err) {
207
- await serverLog("skill-bridge", `mirror write failed for slug=${slug}`, {
208
- level: "error",
209
- data: { slug, error: errorMessage(err) }
210
- });
211
- }
212
- }
213
- async function handleBash(payload) {
214
- const command = extractCommand(payload);
215
- if (!command) return;
216
- const slug = slugFromRmCommand(command);
217
- if (slug === null) return;
218
- try {
219
- mirrorDelete(slug);
220
- await refreshConfig();
221
- await serverLog("skill-bridge", `removed ${claudeSkillDir(slug)}`, { data: { slug, op: "delete" } });
222
- } catch (err) {
223
- await serverLog("skill-bridge", `mirror delete failed for slug=${slug}`, {
224
- level: "error",
225
- data: { slug, error: errorMessage(err) }
226
- });
227
- }
228
- }
229
- async function handleSkillBridge(payload) {
230
- const tool = extractToolName(payload);
231
- if (tool === "Write" || tool === "Edit") {
232
- await handleWriteOrEdit(payload);
233
- return;
234
- }
235
- if (tool === "Bash") {
236
- await handleBash(payload);
237
- }
238
- }
239
-
240
- // server/workspace/hooks/handlers/wikiSnapshot.ts
241
- import path5 from "node:path";
242
-
243
- // src/lib/wiki-page/paths.ts
244
- import path4 from "node:path";
245
-
246
- // src/lib/wiki-page/slug.ts
247
- function isSafeSlug(slug) {
248
- if (slug.length === 0) return false;
249
- if (slug === "." || slug === "..") return false;
250
- if (slug.includes("/") || slug.includes("\\")) return false;
251
- if (slug.includes("\0")) return false;
252
- return true;
253
- }
254
-
255
- // src/lib/wiki-page/paths.ts
256
- function wikiSlugFromAbsPath(absPath, pagesDir) {
257
- const rel = path4.relative(pagesDir, absPath);
258
- if (rel.length === 0) return null;
259
- if (path4.isAbsolute(rel)) return null;
260
- if (rel.includes(path4.sep)) return null;
261
- if (!rel.endsWith(".md")) return null;
262
- const slug = rel.slice(0, -".md".length);
263
- if (!isSafeSlug(slug)) return null;
264
- return slug;
265
- }
266
-
267
- // server/workspace/hooks/handlers/wikiSnapshot.ts
268
- var WIKI_PAGES_REL = path5.join("data", "wiki", "pages");
269
- async function handleWikiSnapshot(payload) {
270
- const tool = extractToolName(payload);
271
- if (tool !== "Write" && tool !== "Edit") return;
272
- const filePath = extractFilePath(payload);
273
- if (!filePath) return;
274
- const wikiPagesDir = path5.join(workspaceRoot(), WIKI_PAGES_REL);
275
- const slug = wikiSlugFromAbsPath(filePath, wikiPagesDir);
276
- if (slug === null) return;
277
- const envChatSessionId = process.env.MULMOCLAUDE_CHAT_SESSION_ID;
278
- const payloadSessionId = extractSessionId(payload);
279
- const sessionId = envChatSessionId && envChatSessionId.length > 0 ? envChatSessionId : payloadSessionId;
280
- const body = sessionId === void 0 ? { slug } : { slug, sessionId };
281
- const req = buildAuthPost("/api/wiki/internal/snapshot", body);
282
- await safePost(req);
283
- }
284
-
285
- // server/workspace/hooks/dispatcher.ts
286
- var HANDLERS = [handleWikiSnapshot, handleConfigRefresh, handleSkillBridge];
287
- async function runHandler(handler, payload) {
288
- try {
289
- await handler(payload);
290
- } catch {
291
- }
292
- }
293
- async function main() {
294
- const payload = await readHookPayload();
295
- if (!payload) return;
296
- await Promise.all(HANDLERS.map((handler) => runHandler(handler, payload)));
297
- }
298
- main().catch(() => {
299
- });
300
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic2hhcmVkL3NpZGVjYXIudHMiLCAiLi4vLi4vdXRpbHMvdGltZS50cyIsICJzaGFyZWQvd29ya3NwYWNlLnRzIiwgInNoYXJlZC9zdGRpbi50cyIsICJoYW5kbGVycy9jb25maWdSZWZyZXNoLnRzIiwgImhhbmRsZXJzL3NraWxsQnJpZGdlLnRzIiwgIi4uLy4uL3V0aWxzL2Vycm9ycy50cyIsICJoYW5kbGVycy93aWtpU25hcHNob3QudHMiLCAiLi4vLi4vLi4vc3JjL2xpYi93aWtpLXBhZ2UvcGF0aHMudHMiLCAiLi4vLi4vLi4vc3JjL2xpYi93aWtpLXBhZ2Uvc2x1Zy50cyIsICJkaXNwYXRjaGVyLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvLyBSZWFkIHRoZSBiZWFyZXIgdG9rZW4gYW5kIHNlcnZlciBwb3J0IGZyb20gc2lkZWNhciBmaWxlcyB0aGVcbi8vIHBhcmVudCBzZXJ2ZXIgd3JpdGVzIG9uIGVhY2ggc3RhcnR1cC4gSG9va3MgUE9TVCBiYWNrIHRvIHRoZVxuLy8gcGFyZW50IHNlcnZlciB1c2luZyB0aGVzZSBcdTIwMTQgdGhleSBuZWVkIHRvIHJ1biB3aXRob3V0IGFueVxuLy8gcnVudGltZSBjb25maWcgYmFrZWQgaW4uXG4vL1xuLy8gU3RyaWN0IGludGVnZXIgcGFyc2luZyBvbiB0aGUgcG9ydDogYSBjcmFmdGVkIGZpbGUgdmFsdWUgbGlrZVxuLy8gYDgwQGF0dGFja2VyLmV4YW1wbGVgIHdvdWxkIG90aGVyd2lzZSBjaGFuZ2UgdGhlIHJlcXVlc3Rcbi8vIGF1dGhvcml0eSBhbmQgZXhmaWx0cmF0ZSB0aGUgYmVhcmVyIHRva2VuIG9mZi1ob3N0LiBTYW1lXG4vLyBoYXJkZW5pbmcgYXBwbGllZCBhcyB0aGUgQ29kZXggcmV2aWV3IG9uIFBSICMxMjg0LlxuXG5pbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgT05FX1NFQ09ORF9NUyB9IGZyb20gXCIuLi8uLi8uLi91dGlscy90aW1lLmpzXCI7XG5pbXBvcnQgeyB3b3Jrc3BhY2VSb290IH0gZnJvbSBcIi4vd29ya3NwYWNlLmpzXCI7XG5cbmNvbnN0IFRPS0VOX0ZJTEUgPSBcIi5zZXNzaW9uLXRva2VuXCI7XG5jb25zdCBQT1JUX0ZJTEUgPSBcIi5zZXJ2ZXItcG9ydFwiO1xuXG4vLyBJbiBEb2NrZXIgbW9kZSB0aGUgcGFyZW50IHNlcnZlciBsaXZlcyBvbiB0aGUgaG9zdCdzIDEyNy4wLjAuMVxuLy8gd2hpY2ggdGhlIGNvbnRhaW5lciBjYW4ndCByZWFjaCB2aWEgcGxhaW4gbG9vcGJhY2suIFRoZSBEb2NrZXJcbi8vIHNwYXduIHBsdW1iaW5nIHNldHMgTVVMTU9DTEFVREVfSE9TVD1ob3N0LmRvY2tlci5pbnRlcm5hbCBzb1xuLy8gZmV0Y2goKSByZXNvbHZlcyB0byB0aGUgaG9zdCBzZXJ2ZXIuIE91dHNpZGUgRG9ja2VyIChvciB3aGVuIHRoZVxuLy8gdmFyIGlzIHVuc2V0KSB3ZSBmYWxsIGJhY2sgdG8gdGhlIGxvb3BiYWNrIGFkZHJlc3MuXG5leHBvcnQgZnVuY3Rpb24gc2VydmVySG9zdCgpOiBzdHJpbmcge1xuICByZXR1cm4gcHJvY2Vzcy5lbnYuTVVMTU9DTEFVREVfSE9TVCA/PyBcIjEyNy4wLjAuMVwiO1xufVxuXG5mdW5jdGlvbiByZWFkU2lkZWNhcihyZWw6IHN0cmluZyk6IHN0cmluZyB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHJlYWRGaWxlU3luYyhwYXRoLmpvaW4od29ya3NwYWNlUm9vdCgpLCByZWwpLCBcInV0Zi04XCIpLnRyaW0oKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlYWRUb2tlbigpOiBzdHJpbmcge1xuICByZXR1cm4gcmVhZFNpZGVjYXIoVE9LRU5fRklMRSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWFkUG9ydCgpOiBudW1iZXIgfCBudWxsIHtcbiAgY29uc3QgcmF3ID0gcmVhZFNpZGVjYXIoUE9SVF9GSUxFKTtcbiAgaWYgKCFyYXcpIHJldHVybiBudWxsO1xuICBjb25zdCBwb3J0ID0gTnVtYmVyLnBhcnNlSW50KHJhdywgMTApO1xuICByZXR1cm4gTnVtYmVyLmlzSW50ZWdlcihwb3J0KSAmJiBwb3J0ID4gMCAmJiBwb3J0IDwgNjU1MzYgPyBwb3J0IDogbnVsbDtcbn1cblxuLy8gQnVpbGQgYW4gYXV0aGVudGljYXRlZCBQT1NUIHJlcXVlc3QgYWdhaW5zdCB0aGUgcGFyZW50IHNlcnZlci5cbi8vIFJldHVybnMgbnVsbCB3aGVuIHRva2VuIC8gcG9ydCBhcmUgbWlzc2luZyAoc2VydmVyIGlzbid0IHVwIHlldCk7XG4vLyBjYWxsZXIgdHJlYXRzIG51bGwgYXMgYSBzaWxlbnQgbm8tb3Agc28gYSBvbmUtb2ZmIGhvb2sgbWlzc1xuLy8gZHVyaW5nIHN0YXJ0dXAgZG9lc24ndCBzdXJmYWNlIGFzIGEgdG9vbCBlcnJvci5cbi8vIGBQYXJhbWV0ZXJzPHR5cGVvZiBmZXRjaD5bMV1gIGRlcml2ZXMgdGhlIHJlcXVlc3QtaW5pdCBzaGFwZVxuLy8gZnJvbSB0aGUgZ2xvYmFsIGBmZXRjaGAgdHlwZSByYXRoZXIgdGhhbiBuYW1pbmcgYFJlcXVlc3RJbml0YFxuLy8gZGlyZWN0bHkgXHUyMDE0IGtlZXBzIHRoZSBmaWxlIGxpbnQtY2xlYW4gdW5kZXIgb3VyIHNoYXJlZCBuby11bmRlZlxuLy8gY29uZmlnIHdpdGhvdXQgbmVlZGluZyBhIGN1c3RvbSBET00tdHlwZXMgdHNjb25maWcgZm9yIHRoZSBob29rXG4vLyBidW5kbGUuXG50eXBlIEZldGNoSW5pdCA9IFBhcmFtZXRlcnM8dHlwZW9mIGZldGNoPlsxXTtcblxuZXhwb3J0IGludGVyZmFjZSBQb3N0UmVxdWVzdCB7XG4gIHVybDogc3RyaW5nO1xuICBpbml0OiBGZXRjaEluaXQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEF1dGhQb3N0KHBhdGhuYW1lOiBzdHJpbmcsIGJvZHk/OiB1bmtub3duKTogUG9zdFJlcXVlc3QgfCBudWxsIHtcbiAgY29uc3QgdG9rZW4gPSByZWFkVG9rZW4oKTtcbiAgY29uc3QgcG9ydCA9IHJlYWRQb3J0KCk7XG4gIGlmICghdG9rZW4gfHwgcG9ydCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke3Rva2VufWAsXG4gIH07XG4gIGNvbnN0IGluaXQ6IEZldGNoSW5pdCA9IHsgbWV0aG9kOiBcIlBPU1RcIiwgaGVhZGVycyB9O1xuICBpZiAoYm9keSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaGVhZGVyc1tcIkNvbnRlbnQtVHlwZVwiXSA9IFwiYXBwbGljYXRpb24vanNvblwiO1xuICAgIGluaXQuYm9keSA9IEpTT04uc3RyaW5naWZ5KGJvZHkpO1xuICB9XG4gIHJldHVybiB7XG4gICAgdXJsOiBgaHR0cDovLyR7c2VydmVySG9zdCgpfToke3BvcnR9JHtwYXRobmFtZX1gLFxuICAgIGluaXQsXG4gIH07XG59XG5cbi8vIDIgcyBkZWZhdWx0IHRpbWVvdXQuIFBvc3RUb29sVXNlIGhvb2tzIGJsb2NrIENsYXVkZSBDTEkncyB0b29sXG4vLyB0dXJuIHVudGlsIHRoZSBzY3JpcHQgZXhpdHMsIHNvIGEgc2xvdyAvIGh1bmcgcGFyZW50IHNlcnZlclxuLy8gKHJlZnJlc2ggZGVhZGxvY2ssIEdDIHBhdXNlLCB1bnJlbGF0ZWQgbG9uZy1ydW5uaW5nIHJvdXRlKSB3b3VsZFxuLy8gbGVhdmUgdGhlIHVzZXIncyBXcml0ZS9FZGl0IGFwcGVhcmluZyBmcm96ZW4uIFRoZSByZWZyZXNoLXN0eWxlXG4vLyBQT1NUcyBhcmUgZmlyZS1hbmQtZm9yZ2V0IGFueXdheTsgaWYgdGhlIHNlcnZlciBjYW4ndCByZXNwb25kXG4vLyBpbnNpZGUgdGhhdCB3aW5kb3csIHRoZSBmaWxlIGlzIGFscmVhZHkgb24gZGlzayBhbmQgdGhlIG5leHRcbi8vIHJlc3RhcnQgcGlja3MgaXQgdXAuXG5jb25zdCBERUZBVUxUX1RJTUVPVVRfTVMgPSAyICogT05FX1NFQ09ORF9NUztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNhZmVQb3N0KHJlcTogUG9zdFJlcXVlc3QgfCBudWxsLCB0aW1lb3V0TXMgPSBERUZBVUxUX1RJTUVPVVRfTVMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKCFyZXEpIHJldHVybjtcbiAgY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IGNvbnRyb2xsZXIuYWJvcnQoKSwgdGltZW91dE1zKTtcbiAgdHJ5IHtcbiAgICBhd2FpdCBmZXRjaChyZXEudXJsLCB7IC4uLnJlcS5pbml0LCBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsIH0pO1xuICB9IGNhdGNoIHtcbiAgICAvLyBTZXJ2ZXIgbWlnaHQgYmUgcmVzdGFydGluZyAvIHVucmVhY2hhYmxlIC8gdGltZWQgb3V0IFx1MjAxNCBzaWxlbnRcbiAgICAvLyBmYWlsIGlzIGZpbmU7IHRoZSBmaWxlIGlzIG9uIGRpc2sgYW5kIHRoZSBuZXh0IG1hbnVhbCByZXN0YXJ0XG4gICAgLy8gcGlja3MgaXQgdXAuXG4gIH0gZmluYWxseSB7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgfVxufVxuXG4vLyBGb3J3YXJkIGEgc3RydWN0dXJlZCBsb2cgbGluZSBpbnRvIHRoZSBzZXJ2ZXIncyBsb2dnZXIgdmlhXG4vLyBgUE9TVCAvYXBpL2hvb2tzL2xvZ2AuIEhhbmRsZXJzIGNhbGwgdGhpcyBhZnRlciBlYWNoIG1lYW5pbmdmdWxcbi8vIHNpZGUtZWZmZWN0IChtaXJyb3IgY29weSwgZGVsZXRlLCBldGMuKSBzbyB0aGUgdXNlciBjYW4gdmVyaWZ5XG4vLyBmcm9tIHNlcnZlciBsb2dzIHRoYXQgdGhlIGhvb2sgZmlyZWQgYW5kIHdoYXQgaXQgZGlkLiBUaGUgZW5kcG9pbnRcbi8vIGF1dGhlbnRpY2F0ZXMgdmlhIGJlYXJlciB0b2tlbiAoc2FtZSBhcyBldmVyeSBvdGhlciBpbnRlcm5hbCBob29rXG4vLyBQT1NUKTsgYSBtaXNzaW5nIHRva2VuIC8gcG9ydCBpcyB0aGUgc2lsZW50IG5vLW9wIHNhZmVQb3N0XG4vLyBhbHJlYWR5IGhhbmRsZXMuIDEgcyB0aW1lb3V0IFx1MjAxNCBsb2dnaW5nIHNob3VsZG4ndCBzdGFsbCB0aGUgdXNlcidzXG4vLyB0b29sIHR1cm4gZXZlbiBpZiB0aGUgc2VydmVyIGlzIGJyaWVmbHkgc2xvdy5cbmNvbnN0IExPR19USU1FT1VUX01TID0gT05FX1NFQ09ORF9NUztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNlcnZlckxvZyhuYW1lc3BhY2U6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nLCBvcHRpb25zOiB7IGxldmVsPzogXCJpbmZvXCIgfCBcIndhcm5cIiB8IFwiZXJyb3JcIjsgZGF0YT86IG9iamVjdCB9ID0ge30pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgYm9keSA9IHtcbiAgICBuYW1lc3BhY2UsXG4gICAgbWVzc2FnZSxcbiAgICBsZXZlbDogb3B0aW9ucy5sZXZlbCA/PyBcImluZm9cIixcbiAgICAuLi4ob3B0aW9ucy5kYXRhID8geyBkYXRhOiBvcHRpb25zLmRhdGEgfSA6IHt9KSxcbiAgfTtcbiAgY29uc3QgcmVxID0gYnVpbGRBdXRoUG9zdChcIi9hcGkvaG9va3MvbG9nXCIsIGJvZHkpO1xuICBhd2FpdCBzYWZlUG9zdChyZXEsIExPR19USU1FT1VUX01TKTtcbn1cbiIsICIvLyBDb21tb24gdGltZSBjb25zdGFudHMgaW4gbWlsbGlzZWNvbmRzLiBBdm9pZHMgbWFnaWMgbnVtYmVycyBsaWtlXG4vLyAzXzYwMF8wMDAgc2NhdHRlcmVkIGFjcm9zcyB0aGUgY29kZWJhc2UuXG4vL1xuLy8gQWxsIHNlcnZlci1zaWRlIGNvZGUgc2hvdWxkIGltcG9ydCBmcm9tIGhlcmUgaW5zdGVhZCBvZiB1c2luZyByYXdcbi8vIG51bWVyaWMgbGl0ZXJhbHMuIFdoZW4gYSBzcGVjaWZpYyBkdXJhdGlvbiBpcyBuZWVkZWQgKGUuZy4gYVxuLy8gNS1zZWNvbmQgdGltZW91dCksIGV4cHJlc3MgaXQgYXMgYDUgKiBPTkVfU0VDT05EX01TYC5cblxuZXhwb3J0IGNvbnN0IE9ORV9TRUNPTkRfTVMgPSAxXzAwMDtcbmV4cG9ydCBjb25zdCBPTkVfTUlOVVRFX01TID0gNjBfMDAwO1xuZXhwb3J0IGNvbnN0IE9ORV9IT1VSX01TID0gM182MDBfMDAwO1xuZXhwb3J0IGNvbnN0IE9ORV9EQVlfTVMgPSA4Nl80MDBfMDAwO1xuXG4vKiogTWFwIHRpbWUtdW5pdCBzdWZmaXhlcyAocy9tL2gpIHRvIG1pbGxpc2Vjb25kcy4gKi9cbmV4cG9ydCBjb25zdCBUSU1FX1VOSVRfTVM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7XG4gIHM6IE9ORV9TRUNPTkRfTVMsXG4gIG06IE9ORV9NSU5VVEVfTVMsXG4gIGg6IE9ORV9IT1VSX01TLFxufTtcblxuLy8gXHUyNTAwXHUyNTAwIENvbW1vbiB0aW1lb3V0IHByZXNldHMgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG4vLyBOYW1lZCB0aW1lb3V0cyBmb3IgcmVjdXJyaW5nIHBhdHRlcm5zLiBQcmVmZXIgdGhlc2Ugb3ZlciBpbmxpbmVcbi8vIGA1ICogT05FX1NFQ09ORF9NU2Agd2hlbiB0aGUgc2FtZSB2YWx1ZSBpcyB1c2VkIGluIDMrIHBsYWNlcy5cblxuLyoqIFF1aWNrIHN1YnByb2Nlc3MgcHJvYmUgKGRvY2tlciBwcywgbGlicmVvZmZpY2UgLS12ZXJzaW9uLCBldGMuKSAqL1xuZXhwb3J0IGNvbnN0IFNVQlBST0NFU1NfUFJPQkVfVElNRU9VVF9NUyA9IDUgKiBPTkVfU0VDT05EX01TO1xuXG4vKiogRGVib3VuY2Ugd2luZG93IGZvciBkZXYtcGx1Z2luIGBkaXN0L2Agd2F0Y2hlciAoIzExNTkgUFIzKS4gVml0ZVxuICogIHdyaXRlcyA0LTUgZmlsZXMgd2l0aGluIH4xMDBtcyBvbiBhIHNpbmdsZSByZWJ1aWxkOyAzMDBtcyBjb2xsYXBzZXNcbiAqICB0aGUgYnVyc3QgaW50byBvbmUgcHVibGlzaC4gKi9cbmV4cG9ydCBjb25zdCBERVZfUExVR0lOX1dBVENIX0RFQk9VTkNFX01TID0gMzAwO1xuXG4vKiogSGFyZCBjYXAgb24gaG93IGxvbmcgdGhlIHN0YXJ0dXAtZmFpbHVyZSBwYXRoIHdhaXRzIGZvclxuICogIGBodHRwU2VydmVyLmNsb3NlKClgIHRvIGRyYWluIGluLWZsaWdodCBjb25uZWN0aW9ucyBiZWZvcmVcbiAqICBmb3JjaW5nIGBwcm9jZXNzLmV4aXQoMSlgLiBTU0Ugc3RyZWFtcyArIFdlYlNvY2tldCB1cGdyYWRlcyBob2xkXG4gKiAgY29ubmVjdGlvbnMgb3BlbiBpbmRlZmluaXRlbHksIHNvIHRoZSBncmFjZWZ1bCBjbG9zZSBhbG9uZSBpc24ndFxuICogIGEgZmFpbC1mYXN0IGd1YXJhbnRlZS4gKi9cbmV4cG9ydCBjb25zdCBTVEFSVFVQX0ZBSUxVUkVfRk9SQ0VfRVhJVF9NUyA9IDUgKiBPTkVfU0VDT05EX01TO1xuXG4vKiogSGVhdnkgc3VicHJvY2VzcyB3b3JrIChsaWJyZW9mZmljZSBjb252ZXJzaW9uLCBldGMuKSAqL1xuZXhwb3J0IGNvbnN0IFNVQlBST0NFU1NfV09SS19USU1FT1VUX01TID0gT05FX01JTlVURV9NUztcblxuLyoqIENMSSBzdWJwcm9jZXNzIHRpbWVvdXQgKGNsYXVkZSAtcCBmb3Igc3VtbWFyaXphdGlvbiwgZXRjLikgKi9cbmV4cG9ydCBjb25zdCBDTElfU1VCUFJPQ0VTU19USU1FT1VUX01TID0gNSAqIE9ORV9NSU5VVEVfTVM7XG5cbi8qKiBNYXhpbXVtIG9uZS1zaG90IG5vdGlmaWNhdGlvbiBkZWxheSAqL1xuZXhwb3J0IGNvbnN0IE1BWF9OT1RJRklDQVRJT05fREVMQVlfU0VDID0gM182MDA7IC8vIDEgaG91ciBpbiBzZWNvbmRzXG4iLCAiLy8gV29ya3NwYWNlIHJvb3QgcmVzb2x1dGlvbiBmb3IgaG9vayBzY3JpcHRzLlxuLy9cbi8vIGBDTEFVREVfUFJPSkVDVF9ESVJgIGlzIHNldCBieSBDbGF1ZGUgQ0xJIHRvIHRoZSB3b3Jrc3BhY2Ugcm9vdFxuLy8gdGhlIGhvb2sgZmlyZWQgYWdhaW5zdCBcdTIwMTQgdGhpcyBpcyB0aGUgdmFsdWUgd2UgdHJ1c3QgYXQgcnVudGltZS5cbi8vIEZhbGxpbmcgYmFjayB0byBgfi9tdWxtb2NsYXVkZWAga2VlcHMgdGhlIHNjcmlwdCByb2J1c3Qgd2hlbiBydW5cbi8vIG91dHNpZGUgQ0xJIGNvbnRleHQgKHRlc3QgaGFybmVzcywgbWFudWFsIHJlcHJvZHVjdGlvbikuXG5cbmltcG9ydCB7IGhvbWVkaXIgfSBmcm9tIFwibm9kZTpvc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuXG5leHBvcnQgZnVuY3Rpb24gd29ya3NwYWNlUm9vdCgpOiBzdHJpbmcge1xuICByZXR1cm4gcHJvY2Vzcy5lbnYuQ0xBVURFX1BST0pFQ1RfRElSID8/IHBhdGguam9pbihob21lZGlyKCksIFwibXVsbW9jbGF1ZGVcIik7XG59XG4iLCAiLy8gUmVhZCB0aGUgSlNPTiBQb3N0VG9vbFVzZSBwYXlsb2FkIENsYXVkZSBDTEkgc3RyZWFtcyBvbiBzdGRpbi5cbi8vIFJldHVybnMgdGhlIHBhcnNlZCBwYXlsb2FkIG9yIG51bGwgd2hlbiB0aGUgaW5wdXQgaXMgZW1wdHkgL1xuLy8gbWFsZm9ybWVkIFx1MjAxNCB0aGUgZGlzcGF0Y2hlciB0cmVhdHMgbnVsbCBhcyBhIGZhc3Qgbm8tb3Agc28gYSBob29rXG4vLyBmaXJlZCB3aXRoIG5vIGJvZHkgbmV2ZXIgY3Jhc2hlcyB0aGUgdXNlcidzIHRvb2wgdHVybi5cblxuZXhwb3J0IGludGVyZmFjZSBIb29rUGF5bG9hZCB7XG4gIHRvb2xfbmFtZT86IHVua25vd247XG4gIHRvb2xfaW5wdXQ/OiB7XG4gICAgZmlsZV9wYXRoPzogdW5rbm93bjtcbiAgICBjb21tYW5kPzogdW5rbm93bjtcbiAgICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xuICB9O1xuICB0b29sX3Jlc3BvbnNlPzoge1xuICAgIGZpbGVQYXRoPzogdW5rbm93bjtcbiAgICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xuICB9O1xuICBzZXNzaW9uX2lkPzogdW5rbm93bjtcbiAgW2tleTogc3RyaW5nXTogdW5rbm93bjtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRIb29rUGF5bG9hZCgpOiBQcm9taXNlPEhvb2tQYXlsb2FkIHwgbnVsbD4ge1xuICBjb25zdCBjaHVua3M6IEJ1ZmZlcltdID0gW107XG4gIGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgcHJvY2Vzcy5zdGRpbikge1xuICAgIGNodW5rcy5wdXNoKHR5cGVvZiBjaHVuayA9PT0gXCJzdHJpbmdcIiA/IEJ1ZmZlci5mcm9tKGNodW5rKSA6IGNodW5rKTtcbiAgfVxuICBjb25zdCByYXcgPSBCdWZmZXIuY29uY2F0KGNodW5rcykudG9TdHJpbmcoXCJ1dGYtOFwiKTtcbiAgaWYgKCFyYXcudHJpbSgpKSByZXR1cm4gbnVsbDtcbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShyYXcpIGFzIEhvb2tQYXlsb2FkO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vLyBEaWZmZXJlbnQgdG9vbHMgc3VyZmFjZSB0aGUgcGF0aCB1bmRlciBkaWZmZXJlbnQga2V5cyAoV3JpdGUvRWRpdFxuLy8gdXNlIHRvb2xfaW5wdXQuZmlsZV9wYXRoOyB0aGUgcmVzcG9uc2Ugc2hhcGUgdXNlcyBmaWxlUGF0aCkuIFRoZVxuLy8gaGVscGVyIGNoZWNrcyBib3RoIGRlZmVuc2l2ZWx5IHNvIGhhbmRsZXJzIGRvbid0IG5lZWQgdG8uXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEZpbGVQYXRoKHBheWxvYWQ6IEhvb2tQYXlsb2FkKTogc3RyaW5nIHtcbiAgY29uc3QgZnJvbUlucHV0ID0gcGF5bG9hZC50b29sX2lucHV0Py5maWxlX3BhdGg7XG4gIGlmICh0eXBlb2YgZnJvbUlucHV0ID09PSBcInN0cmluZ1wiKSByZXR1cm4gZnJvbUlucHV0O1xuICBjb25zdCBmcm9tUmVzcG9uc2UgPSBwYXlsb2FkLnRvb2xfcmVzcG9uc2U/LmZpbGVQYXRoO1xuICBpZiAodHlwZW9mIGZyb21SZXNwb25zZSA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIGZyb21SZXNwb25zZTtcbiAgcmV0dXJuIFwiXCI7XG59XG5cbi8vIEJhc2ggdG9vbCBjYWxscyBwdXQgdGhlIHNoZWxsIGNvbW1hbmQgc3RyaW5nIGluIHRvb2xfaW5wdXQuY29tbWFuZC5cbi8vIEVtcHR5IHN0cmluZyB3aGVuIHRoZSBwYXlsb2FkIGlzIGEgbm9uLUJhc2ggdG9vbCBvciBtYWxmb3JtZWQuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdENvbW1hbmQocGF5bG9hZDogSG9va1BheWxvYWQpOiBzdHJpbmcge1xuICBjb25zdCBjb21tYW5kID0gcGF5bG9hZC50b29sX2lucHV0Py5jb21tYW5kO1xuICByZXR1cm4gdHlwZW9mIGNvbW1hbmQgPT09IFwic3RyaW5nXCIgPyBjb21tYW5kIDogXCJcIjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3RUb29sTmFtZShwYXlsb2FkOiBIb29rUGF5bG9hZCk6IHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgcGF5bG9hZC50b29sX25hbWUgPT09IFwic3RyaW5nXCIgPyBwYXlsb2FkLnRvb2xfbmFtZSA6IFwiXCI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0U2Vzc2lvbklkKHBheWxvYWQ6IEhvb2tQYXlsb2FkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc2Vzc2lvbklkID0gcGF5bG9hZC5zZXNzaW9uX2lkO1xuICByZXR1cm4gdHlwZW9mIHNlc3Npb25JZCA9PT0gXCJzdHJpbmdcIiAmJiBzZXNzaW9uSWQubGVuZ3RoID4gMCA/IHNlc3Npb25JZCA6IHVuZGVmaW5lZDtcbn1cbiIsICIvLyBDb25maWctcmVmcmVzaCBoYW5kbGVyIFx1MjAxNCBmaXJlcyBhZnRlciBXcml0ZS9FZGl0IG9uIGZpbGVzIHRoYXRcbi8vIGRyaXZlIHdvcmtzcGFjZSBzdGF0ZSB0aGUgcGFyZW50IHNlcnZlciBob3QtcmVsb2Fkczpcbi8vXG4vLyAgIDx3cz4vLmNsYXVkZS9za2lsbHMvPHNsdWc+L1NLSUxMLm1kICAgKG1hbnVhbCBlZGl0cyB0byBjYW5vbmljYWwgc2tpbGxzKVxuLy8gICA8d3M+L2NvbmZpZy9zY2hlZHVsZXIvdGFza3MuanNvbiAgICAgICh1c2VyLXRhc2sgc2NoZWR1bGVyIGNvbmZpZylcbi8vXG4vLyBQT1NUcyAvYXBpL2NvbmZpZy9yZWZyZXNoIHNvIHRoZSBjaGFuZ2UgYWN0aXZhdGVzIHdpdGhvdXQgYSBzZXJ2ZXJcbi8vIHJlc3RhcnQuIE1pZ3JhdGVkIGZyb20gYHNlcnZlci93b3Jrc3BhY2UvY29uZmlnLXJlZnJlc2gvaG9vay5tanNgLlxuLy9cbi8vIE5PVEUgb24gc3RhZ2luZyBza2lsbHMgKGBkYXRhL3NraWxscy88c2x1Zz4vU0tJTEwubWRgKTpcbi8vIFRoZSBzdGFnaW5nIHBhdGggaXMgSU5URU5USU9OQUxMWSBleGNsdWRlZCBmcm9tIFBBVFRFUk5TIGhlcmUuXG4vLyBSZWZyZXNoaW5nIG9uIHRoZSBzdGFnaW5nIHdyaXRlIHdvdWxkIHJhY2Ugd2l0aCBgc2tpbGxCcmlkZ2VgJ3Ncbi8vIG1pcnJvciBjb3B5IFx1MjAxNCBgL2FwaS9jb25maWcvcmVmcmVzaGAgY291bGQgbGFuZCBiZWZvcmUgdGhlIGNhbm9uaWNhbFxuLy8gZmlsZSBpcyB3cml0dGVuLCBsZWF2aW5nIGEgZnJlc2ggc2tpbGwgdW5yZWdpc3RlcmVkIHVudGlsIHRoZSBuZXh0XG4vLyByZXN0YXJ0LiBgc2tpbGxCcmlkZ2VgIG93bnMgaXRzIG93biByZWZyZXNoIHRyaWdnZXIgYW5kIGZpcmVzIGl0XG4vLyBBRlRFUiB0aGUgbWlycm9yIHN1Y2NlZWRzLCBzbyB0aGUgb3JkZXJpbmcgaXMgZGV0ZXJtaW5pc3RpYy5cblxuaW1wb3J0IHsgYnVpbGRBdXRoUG9zdCwgc2FmZVBvc3QgfSBmcm9tIFwiLi4vc2hhcmVkL3NpZGVjYXIuanNcIjtcbmltcG9ydCB0eXBlIHsgSG9va1BheWxvYWQgfSBmcm9tIFwiLi4vc2hhcmVkL3N0ZGluLmpzXCI7XG5pbXBvcnQgeyBleHRyYWN0RmlsZVBhdGgsIGV4dHJhY3RUb29sTmFtZSB9IGZyb20gXCIuLi9zaGFyZWQvc3RkaW4uanNcIjtcblxuLy8gRWFjaCBwYXR0ZXJuIGlzIG1hdGNoZWQgYWdhaW5zdCB0aGUgYWJzb2x1dGUgcGF0aCB0aGUgQ0xJXG4vLyBkZWxpdmVyZWQuIFdpbmRvd3MgcGF0aCBzZXBhcmF0b3JzIGFyZSB0b2xlcmF0ZWQgZm9yIGNyb3NzLVxuLy8gcGxhdGZvcm0gcm9idXN0bmVzcyBldmVuIHRob3VnaCB0aGUgaG9zdCBpcyBjdXJyZW50bHkgZGFyd2luIC9cbi8vIGxpbnV4IG9ubHkuXG5jb25zdCBQQVRURVJOUyA9IFsvW1xcXFwvXVxcLmNsYXVkZVtcXFxcL11za2lsbHNbXFxcXC9dW15cXFxcL10rW1xcXFwvXVNLSUxMXFwubWQkLywgL1tcXFxcL11jb25maWdbXFxcXC9dc2NoZWR1bGVyW1xcXFwvXXRhc2tzXFwuanNvbiQvXTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZUNvbmZpZ1JlZnJlc2gocGF5bG9hZDogSG9va1BheWxvYWQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgdG9vbCA9IGV4dHJhY3RUb29sTmFtZShwYXlsb2FkKTtcbiAgaWYgKHRvb2wgIT09IFwiV3JpdGVcIiAmJiB0b29sICE9PSBcIkVkaXRcIikgcmV0dXJuO1xuXG4gIGNvbnN0IGZpbGVQYXRoID0gZXh0cmFjdEZpbGVQYXRoKHBheWxvYWQpO1xuICBpZiAoIWZpbGVQYXRoKSByZXR1cm47XG4gIGlmICghUEFUVEVSTlMuc29tZSgocGF0dGVybikgPT4gcGF0dGVybi50ZXN0KGZpbGVQYXRoKSkpIHJldHVybjtcblxuICBjb25zdCByZXEgPSBidWlsZEF1dGhQb3N0KFwiL2FwaS9jb25maWcvcmVmcmVzaFwiKTtcbiAgYXdhaXQgc2FmZVBvc3QocmVxKTtcbn1cbiIsICIvLyBTa2lsbC1icmlkZ2UgaGFuZGxlciBcdTIwMTQgYWdlbnQgd3JpdGVzIHNraWxsIGRyYWZ0cyB0b1xuLy8gYGRhdGEvc2tpbGxzLzxzbHVnPi9TS0lMTC5tZGAgKGEgcGxhaW4gZGF0YSBkaXIsIG5vIHBlcm1pc3Npb25cbi8vIHNwZWNpYWwgY2FzZSkgYW5kIHRoaXMgaG9vayBtaXJyb3JzIHRoZW0gaW50b1xuLy8gYC5jbGF1ZGUvc2tpbGxzLzxzbHVnPi9TS0lMTC5tZGAgc28gQ2xhdWRlIENMSSdzIHNraWxsIGRpc2NvdmVyeVxuLy8gcGlja3MgdGhlbSB1cC5cbi8vXG4vLyBXaHkgYSBicmlkZ2U6IENsYXVkZSBDb2RlJ3MgcGVybWlzc2lvbiBzeXN0ZW0gZ2l2ZXMgYC5jbGF1ZGUvYFxuLy8gc3RyaWN0ZXIgc2NydXRpbnkgdGhhbiBvcmRpbmFyeSBjd2Qgc3ViZGlycyAodGhlIGRpciBob2xkcyB0aGVcbi8vIGFnZW50J3Mgb3duIHNraWxscyAvIGhvb2tzIC8gc2V0dGluZ3MsIHNvIHdyaXRlcyB0aGVyZSBhcmUgYVxuLy8gc2VsZi1tb2RpZmljYXRpb24gcmlzaykuIEV2ZW4gd2l0aCBleHBsaWNpdCBgV3JpdGUoLmNsYXVkZS8qKilgXG4vLyBhbGxvdyBydWxlcyBpbiB3b3Jrc3BhY2Ugc2V0dGluZ3MuanNvbiwgd3JpdGVzIHByb21wdCBcdTIwMTQgYW5kIHRoZVxuLy8gaG9zdCBHVUkgaGFzIG5vIHN1cmZhY2UgdG8gYW5zd2VyIHRoZSBwcm9tcHQuIFJvdXRpbmcgd3JpdGVzXG4vLyB0aHJvdWdoIGBkYXRhL3NraWxscy9gIGF2b2lkcyB0aGUgZ2F0ZTsgdGhpcyBob29rIChhIHJlZ3VsYXJcbi8vIHN1YnByb2Nlc3MsIE5PVCBhIENsYXVkZSB0b29sIGNhbGwpIGRvZXMgdGhlIG1pcnJvciBjb3B5IGFuZCBpc1xuLy8gbm90IHN1YmplY3QgdG8gdGhlIGdhdGUuXG4vL1xuLy8gV2h5IG1pcnJvciBhcyBgPHNsdWc+L1NLSUxMLm1kYCAobm90IGZsYXQgYDxzbHVnPi5tZGApOiBDbGF1ZGVcbi8vIENMSSdzIGNhbm9uaWNhbCBza2lsbCBsYXlvdXQgSVMgdGhlIG5lc3RlZCBmb3JtLCBhbmQgdGhlIGFnZW50XG4vLyBuYXR1cmFsbHkgd3JpdGVzIHRoYXQgc2hhcGUuIEEgZmxhdCBzdGFnaW5nIHBhdGggZm9yY2VkIHRoZSBhZ2VudFxuLy8gdG8gcmVhc29uIGFnYWluc3QgaXRzIG93biB0cmFpbmluZywgbWlzc2VkIHRoZSByZWdleCwgYW5kIHRoZVxuLy8gbWlycm9yIHNpbGVudGx5IG5ldmVyIGZpcmVkLiBNaXJyb3JpbmcgMToxIGtlZXBzIHRoZSBwYXRoIG1hdGhcbi8vIHRyaXZpYWwgZm9yIGJvdGggc2lkZXMuXG4vL1xuLy8gTWlycm9yIG9wZXJhdGlvbnM6XG4vL1xuLy8gICBXcml0ZS9FZGl0IGRhdGEvc2tpbGxzLzxzbHVnPi9TS0lMTC5tZFxuLy8gICAgIFx1MjE5MiBjb3B5IGNvbnRlbnQgdG8gLmNsYXVkZS9za2lsbHMvPHNsdWc+L1NLSUxMLm1kXG4vLyAgICAgICAoY3JlYXRlcyB0aGUgcGFyZW50IGRpciBvbiBmaXJzdCBpbnN0YWxsKVxuLy9cbi8vICAgQmFzaCBcInJtIC1yZiBkYXRhL3NraWxscy88c2x1Zz4vXCIgb3IgXCJybSAtcmYgZGF0YS9za2lsbHMvPHNsdWc+XCJcbi8vICAgICBcdTIxOTIgcm0gLXJmIC5jbGF1ZGUvc2tpbGxzLzxzbHVnPi9cbi8vICAgICAgIChyZWdleC1tYXRjaGVkIHNvIHRoZSBhZ2VudCdzIGludGVudCBpcyB1bmFtYmlndW91cztcbi8vICAgICAgICBhIGJ1bGsgYHJtIC1yZiBkYXRhL3NraWxscy9gIG9yIHdpbGRjYXJkcyBhcmUgaW50ZW50aW9uYWxseVxuLy8gICAgICAgIE5PVCBtaXJyb3JlZCB0byBhdm9pZCBtYXNzIGRlbGV0aW9uIHN1cnByaXNlcylcblxuaW1wb3J0IHsgbWtkaXJTeW5jLCByZWFkRmlsZVN5bmMsIHJlbmFtZVN5bmMsIHJtU3luYywgd3JpdGVGaWxlU3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBidWlsZEF1dGhQb3N0LCBzYWZlUG9zdCwgc2VydmVyTG9nIH0gZnJvbSBcIi4uL3NoYXJlZC9zaWRlY2FyLmpzXCI7XG5pbXBvcnQgdHlwZSB7IEhvb2tQYXlsb2FkIH0gZnJvbSBcIi4uL3NoYXJlZC9zdGRpbi5qc1wiO1xuaW1wb3J0IHsgZXh0cmFjdENvbW1hbmQsIGV4dHJhY3RGaWxlUGF0aCwgZXh0cmFjdFRvb2xOYW1lIH0gZnJvbSBcIi4uL3NoYXJlZC9zdGRpbi5qc1wiO1xuaW1wb3J0IHsgd29ya3NwYWNlUm9vdCB9IGZyb20gXCIuLi9zaGFyZWQvd29ya3NwYWNlLmpzXCI7XG5pbXBvcnQgeyBlcnJvck1lc3NhZ2UgfSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvZXJyb3JzLmpzXCI7XG5cbmNvbnN0IERBVEFfU0tJTExTX0RJUiA9IHBhdGguam9pbihcImRhdGFcIiwgXCJza2lsbHNcIik7XG5jb25zdCBDTEFVREVfU0tJTExTX0RJUiA9IHBhdGguam9pbihcIi5jbGF1ZGVcIiwgXCJza2lsbHNcIik7XG5jb25zdCBTS0lMTF9GSUxFTkFNRSA9IFwiU0tJTEwubWRcIjtcblxuLy8gU2x1Z3MgZm9sbG93IENsYXVkZSBDb2RlJ3Mgc2tpbGwtbmFtZSBjb252ZW50aW9uOiBsb3dlcmNhc2UgQVNDSUlcbi8vIGxldHRlcnMgLyBkaWdpdHMgd2l0aCBzaW5nbGUtaHlwaGVuIHNlcGFyYXRvcnMuIE1hdGNoaW5nIGlzXG4vLyBzdHJpY3Qgc28gYSB0eXBvIG9yIHBhdGggdHJhdmVyc2FsIGF0dGVtcHQgKGAuLi9mb29gKSBuZXZlclxuLy8gcmVhY2hlcyB0aGUgZGVzdGluYXRpb24gcGF0aCBtYXRoLlxuLy9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzZWN1cml0eS9kZXRlY3QtdW5zYWZlLXJlZ2V4IC0tIGlucHV0IGlzIGFsd2F5cyBhIGJhc2VuYW1lIHNsaWNlIFx1MjI2NCA2NCBjaGFycywgc28gdGhlIHRoZW9yZXRpY2FsIHdvcnN0LWNhc2UgYmFja3RyYWNraW5nIGlzIGJvdW5kZWQ7IHRoaXMgaXMgdGhlIGNhbm9uaWNhbCBrZWJhYi1jYXNlIHBhdHRlcm4gdXNlZCBhY3Jvc3MgdGhlIHNraWxsIHRvb2xjaGFpbi5cbmNvbnN0IFNMVUdfUkUgPSAvXlthLXowLTldKygtW2EtejAtOV0rKSokLztcblxuLy8gYHJtIC1yZiBkYXRhL3NraWxscy88c2x1Zz5gIHJlZ2V4LiBDYXB0dXJlcyB0aGUgZmxhZyBydW4gYXNcbi8vIGBtYXRjaFsxXWAgc28gdGhlIGNhbGxlciBjYW4gcG9zdC12YWxpZGF0ZSB0aGF0IHRoZSB1c2VyIHBhc3NlZFxuLy8gYSByZWN1cnNpdmUgZmxhZyAoYC1yYCwgYC1SYCwgYC1yZmAsIGAtZnJgLCBcdTIwMjYpLiBUb2xlcmF0ZXMgb3B0aW9uYWxcbi8vIHRyYWlsaW5nIHNsYXNoIGFuZCBvcHRpb25hbCBxdW90aW5nIGFyb3VuZCB0aGUgcGF0aC4gQSBsaXRlcmFsXG4vLyBgcm0gLXJmIGRhdGEvc2tpbGxzYCAodGhlIHBhcmVudCBkaXIgaXRzZWxmKSBvciBwYXRocyB3aXRoXG4vLyB3aWxkY2FyZHMgLyBzaGVsbCBleHBhbnNpb24gYXJlIGludGVudGlvbmFsbHkgTk9UIG1hdGNoZWQuXG4vL1xuLy8gUmVjdXJzaXZlLWZsYWcgZW5mb3JjZW1lbnQgKENvZGV4IHJldmlldyBvbiB0aGlzIFBSKTogcGxhaW4gYHJtYFxuLy8gb3IgYHJtIC1mYCBjYW5ub3QgcmVtb3ZlIGEgZGlyZWN0b3J5LCBzbyB0aGUgc3RhZ2luZyBkZWxldGUgZmFpbHNcbi8vIHNpbGVudGx5IHdoaWxlIHRoZSBjYW5vbmljYWwgZGVsZXRlIHN0aWxsIHJ1bnMgXHUyMDE0IGRlc3luY2luZyB0aGVcbi8vIHR3byB0cmVlcy4gUmVxdWlyaW5nIGF0IGxlYXN0IG9uZSBgcmAgLyBgUmAgaW4gdGhlIGZsYWdzIHJlamVjdHNcbi8vIHRob3NlIGZvcm1zIG91dHJpZ2h0LlxuLy9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzZWN1cml0eS9kZXRlY3QtdW5zYWZlLXJlZ2V4IC0tIHRoZSBgKC1bYS16MC05XSspKmAgc2x1ZyBjbGF1c2UgaXMgYm91bmRlZCBieSB0aGUgcGF0aCB0YWlsIGFuZCB0aGUgaW5wdXQgaXMgYSBzaW5nbGUtbGluZSBCYXNoIGNvbW1hbmQgQ2xhdWRlIENMSSBjYXB0dXJlZDsgbm8gcGF0aG9sb2dpY2FsIGJhY2t0cmFja2luZyBzdXJmYWNlLlxuY29uc3QgUk1fUkUgPSAvXlxccypybVxccysoKD86LVthLXpBLVpdK1xccyspKylbJ1wiXT9kYXRhXFwvc2tpbGxzXFwvKFthLXowLTktXSspXFwvP1snXCJdP1xccyokLztcbmNvbnN0IFJFQ1VSU0lWRV9GTEFHX1JFID0gL1tyUl0vO1xuXG4vLyBQdXJlIGhlbHBlcnMgZXhwb3J0ZWQgZm9yIHVuaXQgdGVzdGluZy4gU291cmNlIHBhdGhzIHN0YXkgcmVsYXRpdmVcbi8vIHRvIHRoZSB3b3Jrc3BhY2Ugcm9vdCByZXNvbHZlZCBhdCBjYWxsIHRpbWUgc28gdGhlIGhhbmRsZXIgaXNcbi8vIHNhZmUgdG8gcnVuIGZyb20gYW55IGN3ZC5cblxuZXhwb3J0IGZ1bmN0aW9uIGRhdGFTa2lsbERpcihzbHVnOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcGF0aC5qb2luKHdvcmtzcGFjZVJvb3QoKSwgREFUQV9TS0lMTFNfRElSLCBzbHVnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRhdGFTa2lsbEZpbGVQYXRoKHNsdWc6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBwYXRoLmpvaW4oZGF0YVNraWxsRGlyKHNsdWcpLCBTS0lMTF9GSUxFTkFNRSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbGF1ZGVTa2lsbERpcihzbHVnOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcGF0aC5qb2luKHdvcmtzcGFjZVJvb3QoKSwgQ0xBVURFX1NLSUxMU19ESVIsIHNsdWcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2xhdWRlU2tpbGxGaWxlUGF0aChzbHVnOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcGF0aC5qb2luKGNsYXVkZVNraWxsRGlyKHNsdWcpLCBTS0lMTF9GSUxFTkFNRSk7XG59XG5cbi8vIEV4dHJhY3QgdGhlIHNsdWcgZnJvbSBhIFdyaXRlL0VkaXQgb24gYVxuLy8gYGRhdGEvc2tpbGxzLzxzbHVnPi9TS0lMTC5tZGAgcGF0aC4gUmV0dXJucyBudWxsIHdoZW46XG4vLyAgIC0gdGhlIHBhdGggZG9lc24ndCBzaXQgZGlyZWN0bHkgdW5kZXIgZGF0YS9za2lsbHMvPHNsdWc+L1xuLy8gICAtIHRoZSBmaWxlbmFtZSBpc24ndCBTS0lMTC5tZFxuLy8gICAtIHRoZSBzbHVnIGlzbid0IGEgdmFsaWQga2ViYWItY2FzZSBpZGVudGlmaWVyXG4vL1xuLy8gU2libGluZyBmaWxlcyBpbiB0aGUgc2FtZSBkaXIgKGUuZy4gZGF0YS9za2lsbHMvPHNsdWc+L1JFQURNRS5tZFxuLy8gb3IgZGF0YS9za2lsbHMvPHNsdWc+L2Fzc2V0cy9mb28ucG5nKSBhcmUgaW50ZW50aW9uYWxseSBOT1Rcbi8vIGJyaWRnZWQgXHUyMDE0IG9ubHkgdGhlIGNhbm9uaWNhbCBTS0lMTC5tZCBjcm9zc2VzIG92ZXIuIFNraWxsIGF1dGhvcnNcbi8vIGNhbiBrZWVwIGV4dHJhIG1hdGVyaWFsIHN0YWdpbmctc2lkZSB1bnRpbCB0aGV5IGRlY2lkZSB3aGF0XG4vLyBiZWxvbmdzIGluIHRoZSBidW5kbGUuXG5leHBvcnQgZnVuY3Rpb24gc2x1Z0Zyb21EYXRhUGF0aChmaWxlUGF0aDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IHJvb3QgPSB3b3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IHN0YWdpbmcgPSBwYXRoLmpvaW4ocm9vdCwgREFUQV9TS0lMTFNfRElSKTtcbiAgY29uc3QgcmVsID0gcGF0aC5yZWxhdGl2ZShzdGFnaW5nLCBmaWxlUGF0aCk7XG4gIGlmICghcmVsIHx8IHJlbC5zdGFydHNXaXRoKFwiLi5cIikpIHJldHVybiBudWxsO1xuICAvLyBFeHBlY3QgZXhhY3RseSBgPHNsdWc+L1NLSUxMLm1kYCBcdTIwMTQgdHdvIHNlZ21lbnRzIGRlZXAuXG4gIGNvbnN0IHNlZ21lbnRzID0gcmVsLnNwbGl0KHBhdGguc2VwKTtcbiAgaWYgKHNlZ21lbnRzLmxlbmd0aCAhPT0gMikgcmV0dXJuIG51bGw7XG4gIGNvbnN0IFtzbHVnLCBiYXNlbmFtZV0gPSBzZWdtZW50cztcbiAgaWYgKGJhc2VuYW1lICE9PSBTS0lMTF9GSUxFTkFNRSkgcmV0dXJuIG51bGw7XG4gIHJldHVybiBTTFVHX1JFLnRlc3Qoc2x1ZykgPyBzbHVnIDogbnVsbDtcbn1cblxuLy8gRXh0cmFjdCB0aGUgc2x1ZyBmcm9tIGEgQmFzaCBgcm0gLXJmIGRhdGEvc2tpbGxzLzxzbHVnPi9gIGNvbW1hbmQuXG4vLyBSZXR1cm5zIG51bGwgb24gYW55IG1pc21hdGNoIFx1MjAxNCB3aWxkY2FyZHMsIHBhdGhzIG91dHNpZGUgdGhlXG4vLyBzdGFnaW5nIGRpciwgb3Igbm9uLXJlY3Vyc2l2ZSBgcm1gIC8gYHJtIC1mYCAod2hpY2ggY2FuJ3QgZGVsZXRlXG4vLyB0aGUgc3RhZ2luZyBkaXIgYW55d2F5LCBzbyBtaXJyb3Jpbmcgd291bGQgZGVzeW5jKSBhcmUgYWxsXG4vLyBpbnRlbnRpb25hbGx5IHJlamVjdGVkLlxuZXhwb3J0IGZ1bmN0aW9uIHNsdWdGcm9tUm1Db21tYW5kKGNvbW1hbmQ6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBtYXRjaCA9IFJNX1JFLmV4ZWMoY29tbWFuZCk7XG4gIGlmICghbWF0Y2gpIHJldHVybiBudWxsO1xuICBjb25zdCBbLCBmbGFncywgc2x1Z10gPSBtYXRjaDtcbiAgaWYgKCFSRUNVUlNJVkVfRkxBR19SRS50ZXN0KGZsYWdzKSkgcmV0dXJuIG51bGw7XG4gIHJldHVybiBTTFVHX1JFLnRlc3Qoc2x1ZykgPyBzbHVnIDogbnVsbDtcbn1cblxuLy8gQXRvbWljIG1pcnJvcjogd3JpdGUgdG8gYSB0bXAgZmlsZSBpbiB0aGUgZGVzdGluYXRpb24gZGlyLCB0aGVuXG4vLyByZW5hbWUgb250byB0aGUgY2Fub25pY2FsIHBhdGguIGBmcy5yZW5hbWVTeW5jYCBpcyBhdG9taWMgb24gUE9TSVhcbi8vIHdoZW4gc291cmNlICsgZGVzdGluYXRpb24gc2hhcmUgYSBmaWxlc3lzdGVtIChhbHdheXMgdHJ1ZSBoZXJlIFx1MjAxNFxuLy8gYm90aCBhcmUgaW5zaWRlIGAuY2xhdWRlL3NraWxscy88c2x1Zz4vYCkuIElmIHRoZSBob29rIGlzIGtpbGxlZFxuLy8gbWlkLXdyaXRlLCB0aGUgaGFsZi13cml0dGVuIHRtcCBmaWxlIGlzIGxlZnQgYmVoaW5kIChoYXJtbGVzcyxcbi8vIG5ldmVyIHJlYWQpIGFuZCBTS0lMTC5tZCBzdGlsbCBoYXMgaXRzIHByZXZpb3VzIGNvbnRlbnRzIFx1MjAxNCBDbGF1ZGVcbi8vIENMSSdzIHNraWxsIGRpc2NvdmVyeSBuZXZlciBzZWVzIGEgdG9ybiBmaWxlLiBDb2RlUmFiYml0IHJldmlld1xuLy8gb24gUFIgIzEyOTguXG5mdW5jdGlvbiBtaXJyb3JXcml0ZShzbHVnOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhkYXRhU2tpbGxGaWxlUGF0aChzbHVnKSwgXCJ1dGYtOFwiKTtcbiAgY29uc3QgZGVzdERpciA9IGNsYXVkZVNraWxsRGlyKHNsdWcpO1xuICBta2RpclN5bmMoZGVzdERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGNvbnN0IGRlc3QgPSBjbGF1ZGVTa2lsbEZpbGVQYXRoKHNsdWcpO1xuICBjb25zdCB0bXAgPSBwYXRoLmpvaW4oZGVzdERpciwgYC5TS0lMTC5tZC4ke3Byb2Nlc3MucGlkfS50bXBgKTtcbiAgd3JpdGVGaWxlU3luYyh0bXAsIGNvbnRlbnQsIFwidXRmLThcIik7XG4gIHJlbmFtZVN5bmModG1wLCBkZXN0KTtcbn1cblxuZnVuY3Rpb24gbWlycm9yRGVsZXRlKHNsdWc6IHN0cmluZyk6IHZvaWQge1xuICBybVN5bmMoY2xhdWRlU2tpbGxEaXIoc2x1ZyksIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbn1cblxuLy8gYGNvbmZpZ1JlZnJlc2hgIHVzZWQgdG8gZmFuIHRoaXMgb3V0IGZvciB1cyBhcyBhIHNpYmxpbmcgaGFuZGxlcixcbi8vIGJ1dCBydW5uaW5nIGl0IGluIHBhcmFsbGVsIHdpdGggdGhlIG1pcnJvciByYWNlJ2Q6IHRoZVxuLy8gYC9hcGkvY29uZmlnL3JlZnJlc2hgIFBPU1QgY291bGQgbGFuZCBiZWZvcmUgdGhlIGNhbm9uaWNhbFxuLy8gYC5jbGF1ZGUvc2tpbGxzLzxzbHVnPi9TS0lMTC5tZGAgZXhpc3RlZCBvbiBkaXNrLCBsZWF2aW5nIGEgZnJlc2hcbi8vIHNraWxsIHVucmVnaXN0ZXJlZCB1bnRpbCB0aGUgbmV4dCByZXN0YXJ0LiBgc2tpbGxCcmlkZ2VgIG5vd1xuLy8gZmlyZXMgdGhlIHJlZnJlc2ggaXRzZWxmLCBBTFdBWVMgYWZ0ZXIgYSBzdWNjZXNzZnVsIG1pcnJvciAob3Jcbi8vIGRlbGV0ZSksIHNvIG9yZGVyaW5nIGlzIGRldGVybWluaXN0aWMgKENvZGV4IHJldmlldyBvbiB0aGlzIFBSKS5cbmFzeW5jIGZ1bmN0aW9uIHJlZnJlc2hDb25maWcoKTogUHJvbWlzZTx2b2lkPiB7XG4gIGF3YWl0IHNhZmVQb3N0KGJ1aWxkQXV0aFBvc3QoXCIvYXBpL2NvbmZpZy9yZWZyZXNoXCIpKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gaGFuZGxlV3JpdGVPckVkaXQocGF5bG9hZDogSG9va1BheWxvYWQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgZmlsZVBhdGggPSBleHRyYWN0RmlsZVBhdGgocGF5bG9hZCk7XG4gIGlmICghZmlsZVBhdGgpIHJldHVybjtcbiAgY29uc3Qgc2x1ZyA9IHNsdWdGcm9tRGF0YVBhdGgoZmlsZVBhdGgpO1xuICBpZiAoc2x1ZyA9PT0gbnVsbCkgcmV0dXJuO1xuICB0cnkge1xuICAgIG1pcnJvcldyaXRlKHNsdWcpO1xuICAgIC8vIE9yZGVyIG1hdHRlcnM6IG1pcnJvciBtdXN0IGNvbXBsZXRlIGJlZm9yZSByZWZyZXNoIHNvIHRoZVxuICAgIC8vIHNlcnZlcidzIHNraWxsIHNjYW4gc2VlcyB0aGUgbmV3IFNLSUxMLm1kLiBTZWUgcmVmcmVzaENvbmZpZ1xuICAgIC8vIGNvbW1lbnQgZm9yIHRoZSByYWNlIGhpc3RvcnkuXG4gICAgYXdhaXQgcmVmcmVzaENvbmZpZygpO1xuICAgIC8vIFNlcnZlci1zaWRlIGxvZyBsaW5lIHNvIHRoZSB1c2VyIGNhbiBzZWUgZnJvbVxuICAgIC8vIGBzZXJ2ZXItPGRhdGU+LmxvZ2AgdGhhdCB0aGUgaG9vayBmaXJlZCBhbmQgd2hhdCBpdCBkaWQuXG4gICAgLy8gV2l0aG91dCB0aGlzIHRoZSBtaXJyb3IgaXMgaW52aXNpYmxlIFx1MjAxNCBhIHN1Y2Nlc3NmdWwgY29weVxuICAgIC8vIGFuZCBcInRoZSBob29rIG5ldmVyIHJhblwiIGxvb2sgaWRlbnRpY2FsIGZyb20gdGhlIGNoYXQgVUkuXG4gICAgYXdhaXQgc2VydmVyTG9nKFwic2tpbGwtYnJpZGdlXCIsIGBtaXJyb3JlZCAke2RhdGFTa2lsbEZpbGVQYXRoKHNsdWcpfSBcdTIxOTIgJHtjbGF1ZGVTa2lsbEZpbGVQYXRoKHNsdWcpfWAsIHsgZGF0YTogeyBzbHVnLCBvcDogXCJ3cml0ZVwiIH0gfSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIC8vIFRoZSBXcml0ZSBpdHNlbGYgc3VjY2VlZGVkOyBhIGZhaWxlZCBtaXJyb3Igd291bGQgbGVhdmUgdGhlXG4gICAgLy8gc3RhZ2luZyBjb3B5IGluIHBsYWNlLiBTdXJmYWNlIHRoZSBmYWlsdXJlIHRvIHNlcnZlciBsb2dzXG4gICAgLy8gKHNvIHRoZSB1c2VyIGhhcyBhIGNoYW5jZSB0byByZWFjdCkgYnV0IG5ldmVyIHRocm93IFx1MjAxNCB0aGVcbiAgICAvLyB1c2VyJ3MgdG9vbCB0dXJuIG11c3Qgc3RheSBjbGVhbi5cbiAgICBhd2FpdCBzZXJ2ZXJMb2coXCJza2lsbC1icmlkZ2VcIiwgYG1pcnJvciB3cml0ZSBmYWlsZWQgZm9yIHNsdWc9JHtzbHVnfWAsIHtcbiAgICAgIGxldmVsOiBcImVycm9yXCIsXG4gICAgICBkYXRhOiB7IHNsdWcsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9LFxuICAgIH0pO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGhhbmRsZUJhc2gocGF5bG9hZDogSG9va1BheWxvYWQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgY29tbWFuZCA9IGV4dHJhY3RDb21tYW5kKHBheWxvYWQpO1xuICBpZiAoIWNvbW1hbmQpIHJldHVybjtcbiAgY29uc3Qgc2x1ZyA9IHNsdWdGcm9tUm1Db21tYW5kKGNvbW1hbmQpO1xuICBpZiAoc2x1ZyA9PT0gbnVsbCkgcmV0dXJuO1xuICB0cnkge1xuICAgIG1pcnJvckRlbGV0ZShzbHVnKTtcbiAgICAvLyBTYW1lIG9yZGVyaW5nIGludmFyaWFudCBhcyBoYW5kbGVXcml0ZU9yRWRpdCBcdTIwMTQgcmVmcmVzaCBtdXN0XG4gICAgLy8gcnVuIGFmdGVyIHRoZSBjYW5vbmljYWwgZGlyIGlzIGdvbmUgc28gdGhlIHNlcnZlcidzIHJlc2NhblxuICAgIC8vIGRlcmVnaXN0ZXJzIHRoZSBkZWxldGVkIHNraWxsLlxuICAgIGF3YWl0IHJlZnJlc2hDb25maWcoKTtcbiAgICBhd2FpdCBzZXJ2ZXJMb2coXCJza2lsbC1icmlkZ2VcIiwgYHJlbW92ZWQgJHtjbGF1ZGVTa2lsbERpcihzbHVnKX1gLCB7IGRhdGE6IHsgc2x1Zywgb3A6IFwiZGVsZXRlXCIgfSB9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgLy8gU2FtZSBzaWxlbnQtZmFpbCBkaXNjaXBsaW5lIFx1MjAxNCBhIG1pc3NlZCBkZWxldGUgbGVhdmVzIGFuXG4gICAgLy8gb3JwaGFuIGluIGAuY2xhdWRlL3NraWxscy9gIHRoYXQgdGhlIHVzZXIgY2FuIGNsZWFuIHVwXG4gICAgLy8gbWFudWFsbHksIHdoaWNoIGlzIGJldHRlciB0aGFuIGFib3J0aW5nIHRoZSB0b29sIHR1cm4uXG4gICAgYXdhaXQgc2VydmVyTG9nKFwic2tpbGwtYnJpZGdlXCIsIGBtaXJyb3IgZGVsZXRlIGZhaWxlZCBmb3Igc2x1Zz0ke3NsdWd9YCwge1xuICAgICAgbGV2ZWw6IFwiZXJyb3JcIixcbiAgICAgIGRhdGE6IHsgc2x1ZywgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0sXG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZVNraWxsQnJpZGdlKHBheWxvYWQ6IEhvb2tQYXlsb2FkKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHRvb2wgPSBleHRyYWN0VG9vbE5hbWUocGF5bG9hZCk7XG4gIGlmICh0b29sID09PSBcIldyaXRlXCIgfHwgdG9vbCA9PT0gXCJFZGl0XCIpIHtcbiAgICBhd2FpdCBoYW5kbGVXcml0ZU9yRWRpdChwYXlsb2FkKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHRvb2wgPT09IFwiQmFzaFwiKSB7XG4gICAgYXdhaXQgaGFuZGxlQmFzaChwYXlsb2FkKTtcbiAgfVxufVxuIiwgIi8vIFNoYXJlZCBlcnJvciBoZWxwZXJzLiBVc2UgYGVycm9yTWVzc2FnZShlcnIpYCBpbnN0ZWFkIG9mIGlubGluaW5nXG4vLyBgZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpYCBcdTIwMTQgc2VhcmNoaW5nIGZvclxuLy8gb25lIGNhbm9uaWNhbCBoZWxwZXIgaXMgZWFzaWVyIHRoYW4gZ3JlcHBpbmcgZm9yIHRoZSBpbmxpbmUgZm9ybS5cbi8vXG4vLyBOb24tRXJyb3Igb2JqZWN0cyB3aXRoIGEgYGRldGFpbHNgIChnUlBDIGNvbnZlbnRpb24pIG9yIGBtZXNzYWdlYFxuLy8gc3RyaW5nIGZpZWxkIGhhdmUgdGhhdCBmaWVsZCBzdXJmYWNlZCBcdTIwMTQgd2l0aG91dCB0aGlzLCBnUlBDIGVycm9yc1xuLy8gbGlrZSBgeyBjb2RlLCBkZXRhaWxzLCBtZXRhZGF0YSB9YCBzaG93IHVwIHRvIHVzZXJzIGFzXG4vLyBgW29iamVjdCBPYmplY3RdYC5cbi8vXG4vLyBUaGUgb3B0aW9uYWwgYGZhbGxiYWNrYCBjb3ZlcnMgdGhlIGNvbW1vbiByb3V0ZS1oYW5kbGVyIGlkaW9tIHdoZXJlXG4vLyBhIHRocm93IG9mIGEgcGxhaW4gbm9uLUVycm9yIHZhbHVlIHNob3VsZCBzdXJmYWNlIGFzIGEgZGVzY3JpcHRpdmVcbi8vIG1lc3NhZ2UgKFwicmVidWlsZCBmYWlsZWRcIikgcmF0aGVyIHRoYW4gYFN0cmluZyhlcnIpYCBub2lzZS4gUHJlZmVyXG4vLyBwYXNzaW5nIGEgZmFsbGJhY2sgYXQgZXJyb3ItcmVzcG9uc2UgYm91bmRhcmllcyBcdTIwMTQgb21pdCBpdCBmb3Jcbi8vIGxvZ2dpbmcgY29udGV4dHMgd2hlcmUgYFN0cmluZyhlcnIpYCBpcyBmaW5lLlxuXG5leHBvcnQgZnVuY3Rpb24gZXJyb3JNZXNzYWdlKGVycjogdW5rbm93biwgZmFsbGJhY2s/OiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHJldHVybiBlcnIubWVzc2FnZTtcbiAgaWYgKGVyciAhPT0gbnVsbCAmJiB0eXBlb2YgZXJyID09PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3Qgb2JqID0gZXJyIGFzIHsgZGV0YWlscz86IHVua25vd247IG1lc3NhZ2U/OiB1bmtub3duIH07XG4gICAgaWYgKHR5cGVvZiBvYmouZGV0YWlscyA9PT0gXCJzdHJpbmdcIiAmJiBvYmouZGV0YWlscykgcmV0dXJuIG9iai5kZXRhaWxzO1xuICAgIGlmICh0eXBlb2Ygb2JqLm1lc3NhZ2UgPT09IFwic3RyaW5nXCIgJiYgb2JqLm1lc3NhZ2UpIHJldHVybiBvYmoubWVzc2FnZTtcbiAgfVxuICBpZiAoZmFsbGJhY2sgIT09IHVuZGVmaW5lZCkgcmV0dXJuIGZhbGxiYWNrO1xuICByZXR1cm4gU3RyaW5nKGVycik7XG59XG4iLCAiLy8gV2lraSBwYWdlIHNuYXBzaG90IGhhbmRsZXIgXHUyMDE0IGZpcmVzIGFmdGVyIFdyaXRlL0VkaXQgb24gYSB3aWtpXG4vLyBwYWdlIHNvIHRoZSBzbmFwc2hvdCBwaXBlbGluZSAoIzc2MyBQUiAyKSByZWNvcmRzIHRoZSBuZXcgc3RhdGUuXG4vL1xuLy8gTWlncmF0ZWQgZnJvbSBgc2VydmVyL3dvcmtzcGFjZS93aWtpLWhpc3RvcnkvaG9vay9zbmFwc2hvdC50c2AuXG4vLyBTYW1lIGJlaGF2aW91ciwgbm93IHBhcnQgb2YgdGhlIHVuaWZpZWQgZGlzcGF0Y2hlciBzbyBzZXR0aW5ncy5qc29uXG4vLyBjYXJyaWVzIGEgc2luZ2xlIFBvc3RUb29sVXNlIGVudHJ5IGluc3RlYWQgb2Ygb25lIHBlciBob29rIHNvdXJjZS5cblxuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgd2lraVNsdWdGcm9tQWJzUGF0aCB9IGZyb20gXCIuLi8uLi8uLi8uLi9zcmMvbGliL3dpa2ktcGFnZS9wYXRocy5qc1wiO1xuaW1wb3J0IHsgYnVpbGRBdXRoUG9zdCwgc2FmZVBvc3QgfSBmcm9tIFwiLi4vc2hhcmVkL3NpZGVjYXIuanNcIjtcbmltcG9ydCB0eXBlIHsgSG9va1BheWxvYWQgfSBmcm9tIFwiLi4vc2hhcmVkL3N0ZGluLmpzXCI7XG5pbXBvcnQgeyBleHRyYWN0RmlsZVBhdGgsIGV4dHJhY3RTZXNzaW9uSWQsIGV4dHJhY3RUb29sTmFtZSB9IGZyb20gXCIuLi9zaGFyZWQvc3RkaW4uanNcIjtcbmltcG9ydCB7IHdvcmtzcGFjZVJvb3QgfSBmcm9tIFwiLi4vc2hhcmVkL3dvcmtzcGFjZS5qc1wiO1xuXG5jb25zdCBXSUtJX1BBR0VTX1JFTCA9IHBhdGguam9pbihcImRhdGFcIiwgXCJ3aWtpXCIsIFwicGFnZXNcIik7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVXaWtpU25hcHNob3QocGF5bG9hZDogSG9va1BheWxvYWQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgdG9vbCA9IGV4dHJhY3RUb29sTmFtZShwYXlsb2FkKTtcbiAgLy8gV2lraSBwYWdlcyBhcmUgd3JpdHRlbiB2aWEgV3JpdGUgb3IgRWRpdCBcdTIwMTQgQmFzaCBybSBvciBzaGVsbFxuICAvLyBtdXRhdGlvbnMgZG9uJ3QgZ28gdGhyb3VnaCB0aGUgc25hcHNob3QgcGlwZWxpbmUgKHRoZSB3aWtpXG4gIC8vIHJvdXRlIGRvZXMgdGhhdCBleHBsaWNpdGx5IHNlcnZlci1zaWRlIHdoZW4gbmVlZGVkKS5cbiAgaWYgKHRvb2wgIT09IFwiV3JpdGVcIiAmJiB0b29sICE9PSBcIkVkaXRcIikgcmV0dXJuO1xuXG4gIGNvbnN0IGZpbGVQYXRoID0gZXh0cmFjdEZpbGVQYXRoKHBheWxvYWQpO1xuICBpZiAoIWZpbGVQYXRoKSByZXR1cm47XG5cbiAgY29uc3Qgd2lraVBhZ2VzRGlyID0gcGF0aC5qb2luKHdvcmtzcGFjZVJvb3QoKSwgV0lLSV9QQUdFU19SRUwpO1xuICBjb25zdCBzbHVnID0gd2lraVNsdWdGcm9tQWJzUGF0aChmaWxlUGF0aCwgd2lraVBhZ2VzRGlyKTtcbiAgaWYgKHNsdWcgPT09IG51bGwpIHJldHVybjtcblxuICAvLyBQcmVmZXIgdGhlIHBhcmVudCBzZXJ2ZXIncyBjaGF0U2Vzc2lvbklkICgjOTYzKSBcdTIwMTQgdGhlIHNlcnZlcidzXG4gIC8vIHNlc3Npb24gc3RvcmUga2V5cyBieSBjaGF0U2Vzc2lvbklkLCBub3QgQ2xhdWRlIENMSSdzIGludGVybmFsXG4gIC8vIHNlc3Npb25faWQsIHNvIHRoZSB0b29sUmVzdWx0IHB1Ymxpc2ggb24gdGhlIHNlcnZlciBzaWRlIG9ubHlcbiAgLy8gbWF0Y2hlcyB3aGVuIHdlIGZvcndhcmQgb3VyIG93biBpZC4gRmFsbCBiYWNrIHRvIENsYXVkZSBDTEknc1xuICAvLyBzZXNzaW9uX2lkIHdoZW4gdGhlIGVudiB2YXIgaXMgYWJzZW50LlxuICBjb25zdCBlbnZDaGF0U2Vzc2lvbklkID0gcHJvY2Vzcy5lbnYuTVVMTU9DTEFVREVfQ0hBVF9TRVNTSU9OX0lEO1xuICBjb25zdCBwYXlsb2FkU2Vzc2lvbklkID0gZXh0cmFjdFNlc3Npb25JZChwYXlsb2FkKTtcbiAgY29uc3Qgc2Vzc2lvbklkID0gZW52Q2hhdFNlc3Npb25JZCAmJiBlbnZDaGF0U2Vzc2lvbklkLmxlbmd0aCA+IDAgPyBlbnZDaGF0U2Vzc2lvbklkIDogcGF5bG9hZFNlc3Npb25JZDtcbiAgY29uc3QgYm9keSA9IHNlc3Npb25JZCA9PT0gdW5kZWZpbmVkID8geyBzbHVnIH0gOiB7IHNsdWcsIHNlc3Npb25JZCB9O1xuXG4gIGNvbnN0IHJlcSA9IGJ1aWxkQXV0aFBvc3QoXCIvYXBpL3dpa2kvaW50ZXJuYWwvc25hcHNob3RcIiwgYm9keSk7XG4gIGF3YWl0IHNhZmVQb3N0KHJlcSk7XG59XG4iLCAiLy8gTm9kZS1vbmx5IHdpa2ktcGFnZSBoZWxwZXJzIFx1MjAxNCBhbnl0aGluZyB0aGF0IG5lZWRzIGBub2RlOnBhdGhgXG4vLyBsaXZlcyBoZXJlIHNvIHRoZSByZXN0IG9mIGBzcmMvbGliL3dpa2ktcGFnZS9gIHN0YXlzIHB1cmVcbi8vIChzdHJpbmctb25seSwgaW1wb3J0YWJsZSBmcm9tIGJvdGggYnJvd3NlciBhbmQgTm9kZSBidW5kbGVzKS5cbi8vIEZyb250ZW5kIGNvZGUgTVVTVCBOT1QgaW1wb3J0IHRoaXMgZmlsZSBkaXJlY3RseTsgdXNlIHRoZSBwdXJlXG4vLyBtb2R1bGVzIGluc3RlYWQuXG5cbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IGlzU2FmZVNsdWcgfSBmcm9tIFwiLi9zbHVnLmpzXCI7XG5cbi8qKiBHaXZlbiBhbiBhYnNvbHV0ZSBwYXRoIGFuZCB0aGUgYWJzb2x1dGUgYHBhZ2VzRGlyYCwgcmV0dXJuIHRoZVxuICogIHNsdWcgaWYgYGFic1BhdGhgIGlzIGEgZGlyZWN0IGAubWRgIGNoaWxkIG9mIGBwYWdlc0RpcmAsIGVsc2VcbiAqICBudWxsLiBQdXJlIHBhdGgtc3RyaW5nIG1hdGggXHUyMDE0IG5vIGZzIElPLCBubyBzeW1saW5rIHJlc29sdXRpb24uXG4gKlxuICogIENhbGxlciByZXNwb25zaWJpbGl0eTogcGFzcyBhbHJlYWR5LXJlYWxwYXRoJ2QgdmFsdWVzIGZvciBib3RoXG4gKiAgYXJndW1lbnRzLiBNaXhpbmcgYSByZWFscGF0aCdkIGBhYnNQYXRoYCB3aXRoIGEgc3ltbGlua2VkXG4gKiAgYHBhZ2VzRGlyYCAob3IgdmljZSB2ZXJzYSkgc2lsZW50bHkgbWlzbWF0Y2hlcyBiZWNhdXNlXG4gKiAgYHBhdGgucmVsYXRpdmVgIGlzIHBsYWluIHN0cmluZyBhcml0aG1ldGljLiBUaGUgdHJhcCBjYXVzZWRcbiAqICAjODgzIHJldmlldy1pdGVyLTEgXHUyMDE0IGEgc3ltbGlua2VkIHdvcmtzcGFjZSBzaWxlbnRseSByb3V0ZWRcbiAqICB3aWtpIHdyaXRlcyB0aHJvdWdoIHRoZSBnZW5lcmljIHdyaXRlci4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aWtpU2x1Z0Zyb21BYnNQYXRoKGFic1BhdGg6IHN0cmluZywgcGFnZXNEaXI6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCByZWwgPSBwYXRoLnJlbGF0aXZlKHBhZ2VzRGlyLCBhYnNQYXRoKTtcbiAgaWYgKHJlbC5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuICBpZiAocGF0aC5pc0Fic29sdXRlKHJlbCkpIHJldHVybiBudWxsO1xuICAvLyBEaXJlY3QgY2hpbGQgb25seSBcdTIwMTQgbm8gbmVzdGVkIGxheW91dCB0b2RheS4gQW55IHNlcGFyYXRvclxuICAvLyBtZWFucyB0aGUgcGF0aCBlaXRoZXIgZXNjYXBlcyAoYC4uL3NlY3JldC5tZGApIG9yIGRlc2NlbmRzXG4gIC8vIChgc3ViZGlyL2Zvby5tZGApLiBBIGxpdGVyYWwgcGFnZSBuYW1lIGxpa2UgYC4uZm9vLm1kYCBpcyBhXG4gIC8vIHNpbmdsZSBzZWdtZW50IHdpdGhvdXQgYSBzZXBhcmF0b3IgYW5kIGlzIGFsbG93ZWQgKGNvZGV4XG4gIC8vIGl0ZXItMyAjODgzIFx1MjAxNCB0aGUgcHJpb3IgYHN0YXJ0c1dpdGgoXCIuLlwiKWAgcnVsZSB3cm9uZ2x5XG4gIC8vIHJlamVjdGVkIGl0KS5cbiAgaWYgKHJlbC5pbmNsdWRlcyhwYXRoLnNlcCkpIHJldHVybiBudWxsO1xuICBpZiAoIXJlbC5lbmRzV2l0aChcIi5tZFwiKSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHNsdWcgPSByZWwuc2xpY2UoMCwgLVwiLm1kXCIubGVuZ3RoKTtcbiAgaWYgKCFpc1NhZmVTbHVnKHNsdWcpKSByZXR1cm4gbnVsbDtcbiAgcmV0dXJuIHNsdWc7XG59XG4iLCAiLy8gUHVyZSB3aWtpLXBhZ2Ugc2x1ZyBoZWxwZXJzIFx1MjAxNCBzdHJpbmctb25seSwgbm8gTm9kZSAvIGJyb3dzZXJcbi8vIGRlcGVuZGVuY2llcywgaW1wb3J0YWJsZSBmcm9tIGFueSBidW5kbGUuXG4vL1xuLy8gVXNlZCBieTpcbi8vICAgLSBzZXJ2ZXIvd29ya3NwYWNlL3dpa2ktcGFnZXMvaW8udHMgKHRoZSB3cml0ZSBjaG9rZXBvaW50KVxuLy8gICAtIHNlcnZlci93b3Jrc3BhY2UvaG9va3MvaGFuZGxlcnMvd2lraVNuYXBzaG90LnRzICh0aGVcbi8vICAgICBQb3N0VG9vbFVzZSBoYW5kbGVyIHRoYXQgZmlyZXMgb24gV3JpdGUvRWRpdCBvZiBhIHdpa2kgcGFnZSlcbi8vICAgLSBzZXJ2ZXIvYXBpL3JvdXRlcy93aWtpLnRzIChwYWdlIHJlc29sdmVyICsgbGludClcbi8vICAgLSBzZXJ2ZXIvYXBpL3JvdXRlcy93aWtpL2hpc3RvcnkudHMgKGhpc3Rvcnkgc2x1ZyBndWFyZClcbi8vICAgLSBzcmMvcGx1Z2lucy93aWtpL3JvdXRlLnRzIChyb3V0ZXIgc2x1ZyBndWFyZCBcdTIwMTQgcmVwbGFjZXMgdGhlXG4vLyAgICAgbG9jYWwgYGlzU2FmZVdpa2lTbHVnYCBkdXBsaWNhdGUgdGhhdCBleGlzdGVkIGJlZm9yZSB0aGVcbi8vICAgICBwdXJlLWxpYiByZWZhY3Rvcilcbi8vICAgLSBzcmMvcGx1Z2lucy93aWtpL2hlbHBlcnMudHMgKHJlbmRlcmVyIHNsdWdpZnkgZm9yIFtbXHUyMDI2XV0gbGlua3MpXG4vL1xuLy8gQW55IGhlbHBlciB0aGF0IG5lZWRzIGBub2RlOnBhdGhgIGxpdmVzIGluIGAuL3BhdGhzLnRzYCBzbyB0aGF0XG4vLyBpbXBvcnRpbmcgdGhpcyBmaWxlIGZyb20gZnJvbnRlbmQgY29kZSBuZXZlciBwdWxscyBpbiBOb2RlXG4vLyBidWlsdGlucy5cblxuLyoqIFJlamVjdCBzbHVncyB0aGF0IHdvdWxkIGVzY2FwZSBgZGF0YS93aWtpL3BhZ2VzL2Agb25jZVxuICogIGpvaW5lZCBiYWNrIGludG8gYSBwYXRoLCBvciB0aGF0IGFyZSBvdGhlcndpc2UgaW52YWxpZCBhc1xuICogIHBhZ2UgZmlsZW5hbWVzLiBUaGUgY2hva2Vwb2ludCBtdXN0IGRlZmVuZCBpdHNlbGYgZXZlbiB3aGVuXG4gKiAgY2FsbGVycyBkZXJpdmUgdGhlIHNsdWcgZnJvbSBhIHRydXN0ZWQgc291cmNlIFx1MjAxNCBhIHR5cG8gb3JcbiAqICBmdXR1cmUgY2FsbGVyIG1pc3Rha2Ugc2hvdWxkIGZhaWwgbG91ZCwgbm90IHNpbGVudGx5IHdyaXRlXG4gKiAgb3V0c2lkZSB0aGUgd2lraSB0cmVlLlxuICpcbiAqICBUaGUgcnVsZSBpcyBpbnRlbnRpb25hbGx5IG5hcnJvdyBcdTIwMTQgc2VwYXJhdG9ycyAvIGAuLmAgLyBOVUwgL1xuICogIGVtcHR5IFx1MjAxNCBzbyBpdCBvbmx5IHJlamVjdHMgdW5hbWJpZ3VvdXMgdmlvbGF0aW9ucy4gQWVzdGhldGljXG4gKiAgY29uY2VybnMgKGUuZy4gZG90LXByZWZpeGVkIGZpbGVuYW1lcykgYXJlIG91dCBvZiBzY29wZTogYVxuICogIHByZS1leGlzdGluZyBgZGF0YS93aWtpL3BhZ2VzLy5mb28ubWRgIHNob3VsZCByZW1haW4gd3JpdGFibGVcbiAqICB0aHJvdWdoIHRoZSBjaG9rZXBvaW50IChjb2RleCByZXZpZXcgaXRlci0yICM4ODMpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2FmZVNsdWcoc2x1Zzogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChzbHVnLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoc2x1ZyA9PT0gXCIuXCIgfHwgc2x1ZyA9PT0gXCIuLlwiKSByZXR1cm4gZmFsc2U7XG4gIGlmIChzbHVnLmluY2x1ZGVzKFwiL1wiKSB8fCBzbHVnLmluY2x1ZGVzKFwiXFxcXFwiKSkgcmV0dXJuIGZhbHNlO1xuICBpZiAoc2x1Zy5pbmNsdWRlcyhcIlxcMFwiKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqIFNsdWcgcnVsZXMgZm9yIGBbW3dpa2kgbGlua11dYCB0ZXh0IFx1MjE5MiBzbHVnIGRlcml2YXRpb246XG4gKiAgbG93ZXJjYXNlLCBzcGFjZXMgY29sbGFwc2VkIHRvIGh5cGhlbnMsIGV2ZXJ5IG5vbi1BU0NJSSAvXG4gKiAgbm9uLWFscGhhbnVtZXJpYyAvIG5vbi1oeXBoZW4gY2hhcmFjdGVyIHN0cmlwcGVkLlxuICpcbiAqICBQdXJlOiBubyBub3JtYWxpc2F0aW9uLCBubyB0cmFuc2xpdGVyYXRpb24gXHUyMDE0IHRoaXMgaXMgdGhlXG4gKiAgc2FtZSBzaGFwZSB0aGUgaW5kZXggcGFyc2VyLCBwYWdlIHJlc29sdmVyLCBhbmQgZnJvbnRlbmRcbiAqICByZW5kZXJlciBhbGwgbmVlZCB0byBhZ3JlZSBvbi4gTm9uLUFTQ0lJIHRpdGxlcyAoZS5nLlxuICogIEphcGFuZXNlKSBjb2xsYXBzZSB0byBhbiBlbXB0eSBzdHJpbmcgaGVyZTsgY2FsbGVycyBmYWxsIGJhY2tcbiAqICB0byBvdGhlciBzdHJhdGVnaWVzICh0aXRsZS1tYXRjaCBpbiB0aGUgaW5kZXgsIG9yIHRoZSBhZ2VudFxuICogIHByZS1yZXNvbHZpbmcgdG8gYSBzbHVnLWZvcm0gdGFyZ2V0IHZpYSBgW1tzbHVnfGRpc3BsYXldXWApLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpa2lTbHVnaWZ5KHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB0ZXh0XG4gICAgLnRvTG93ZXJDYXNlKClcbiAgICAucmVwbGFjZSgvXFxzKy9nLCBcIi1cIilcbiAgICAucmVwbGFjZSgvW15hLXowLTktXS9nLCBcIlwiKTtcbn1cbiIsICIvLyBQb3N0VG9vbFVzZSBkaXNwYXRjaGVyIFx1MjAxNCBydW5zIGFmdGVyIGV2ZXJ5IENsYXVkZSBDTEkgV3JpdGUgLyBFZGl0XG4vLyAvIEJhc2ggdG9vbCBjYWxsIGFuZCBmYW5zIG91dCB0byB0aGUgcmVnaXN0ZXJlZCBoYW5kbGVycy4gRWFjaFxuLy8gaGFuZGxlciBkZWNpZGVzIGZvciBpdHNlbGYgd2hldGhlciB0aGUgY2FsbCBpcyByZWxldmFudCAoYnlcbi8vIHRvb2xfbmFtZSArIGZpbGVfcGF0aCAvIGNvbW1hbmQpLCBzbyBhZGRpbmcgYSBuZXcgYmVoYXZpb3VyIG1lYW5zXG4vLyBkcm9wcGluZyBhIG5ldyBmaWxlIHVuZGVyIGBoYW5kbGVycy9gIGFuZCByZWdpc3RlcmluZyBpdCBoZXJlIFx1MjAxNFxuLy8gc2V0dGluZ3MuanNvbiBuZXZlciBjaGFuZ2VzLlxuLy9cbi8vIFRISVMgRklMRSBJUyBUSEUgU09VUkNFIE9GIFRSVVRILiBFZGl0cyBoZXJlLCB0aGVuIHJ1blxuLy8gYHlhcm4gYnVpbGQ6aG9va3NgIChvciBgeWFybiBidWlsZGApIHRvIHJlZ2VuZXJhdGUgYC4vZGlzcGF0Y2hlci5tanNgLlxuLy8gVGhlIGJ1bmRsZWQgYC5tanNgIGlzIGNvbW1pdHRlZCB0byBnaXQgc28gYHByb3Zpc2lvbi50c2AgY2FuIHJlYWRcbi8vIGl0IGF0IHNlcnZlciBzdGFydHVwIHdpdGhvdXQgaW52b2tpbmcgZXNidWlsZCBvbiB0aGUgcnVudGltZSBwYXRoLlxuLy8gQ0kgcnVucyBgeWFybiBidWlsZDpob29rcyAmJiBnaXQgZGlmZiAtLWV4aXQtY29kZWAgdG8gY2F0Y2ggYVxuLy8gc3RhbGUgYnVuZGxlLlxuLy9cbi8vIFRoZSBob29rIGV4ZWN1dGVzIGluc2lkZSBDbGF1ZGUgQ0xJJ3MgcHJvY2VzcyBzcGFjZSBcdTIwMTQgbXVzdCBiZSBhXG4vLyBzZWxmLWNvbnRhaW5lZCBFU00gYnVuZGxlLiBlc2J1aWxkIHJvbGxzIGV2ZXJ5IGltcG9ydCAoaGFuZGxlcnMsXG4vLyBzaGFyZWQsIGFuZCB0aGUgd2lraS1zbHVnIGhlbHBlciBmcm9tIGBzcmMvbGliL2ApIGludG8gb25lIGZpbGUuXG5cbmltcG9ydCB7IGhhbmRsZUNvbmZpZ1JlZnJlc2ggfSBmcm9tIFwiLi9oYW5kbGVycy9jb25maWdSZWZyZXNoLmpzXCI7XG5pbXBvcnQgeyBoYW5kbGVTa2lsbEJyaWRnZSB9IGZyb20gXCIuL2hhbmRsZXJzL3NraWxsQnJpZGdlLmpzXCI7XG5pbXBvcnQgeyBoYW5kbGVXaWtpU25hcHNob3QgfSBmcm9tIFwiLi9oYW5kbGVycy93aWtpU25hcHNob3QuanNcIjtcbmltcG9ydCB7IHJlYWRIb29rUGF5bG9hZCwgdHlwZSBIb29rUGF5bG9hZCB9IGZyb20gXCIuL3NoYXJlZC9zdGRpbi5qc1wiO1xuXG50eXBlIEhhbmRsZXIgPSAocGF5bG9hZDogSG9va1BheWxvYWQpID0+IFByb21pc2U8dm9pZD47XG5cbi8vIE9yZGVyIGlzIGluZm9ybWF0aW9uYWwgb25seSBcdTIwMTQgaGFuZGxlcnMgZG9uJ3QgaW50ZXJhY3QuIEFkZCBuZXdcbi8vIGVudHJpZXMgaGVyZS4gRWFjaCBvbmUgaXMgd3JhcHBlZCBzbyBhbiBpbmRpdmlkdWFsIGZhaWx1cmVcbi8vIGRvZXNuJ3QgYmxvY2sgaXRzIHNpYmxpbmdzICh0aGUgdXNlcidzIHRvb2wgdHVybiB3b3VsZCB2aXNpYmx5XG4vLyBzdGFsbCBvdGhlcndpc2UpLlxuY29uc3QgSEFORExFUlM6IEhhbmRsZXJbXSA9IFtoYW5kbGVXaWtpU25hcHNob3QsIGhhbmRsZUNvbmZpZ1JlZnJlc2gsIGhhbmRsZVNraWxsQnJpZGdlXTtcblxuYXN5bmMgZnVuY3Rpb24gcnVuSGFuZGxlcihoYW5kbGVyOiBIYW5kbGVyLCBwYXlsb2FkOiBIb29rUGF5bG9hZCk6IFByb21pc2U8dm9pZD4ge1xuICB0cnkge1xuICAgIGF3YWl0IGhhbmRsZXIocGF5bG9hZCk7XG4gIH0gY2F0Y2gge1xuICAgIC8vIEhvb2tzIHJ1biBzeW5jaHJvbm91c2x5IHRvIHRoZSBMTE0gdG9vbCBmbG93IFx1MjAxNCBuZXZlciB0aHJvdy5cbiAgICAvLyBBIGJ1c3RlZCBoYW5kbGVyIHdvdWxkIG1ha2UgdGhlIHRvb2wgaXRzZWxmIGxvb2sgbGlrZSBpdFxuICAgIC8vIGZhaWxlZCB0byB0aGUgTExNLCB3aGljaCBpcyBtdWNoIHdvcnNlIHRoYW4gYSBtaXNzZWRcbiAgICAvLyBzaWRlLWVmZmVjdC5cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBtYWluKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwYXlsb2FkID0gYXdhaXQgcmVhZEhvb2tQYXlsb2FkKCk7XG4gIGlmICghcGF5bG9hZCkgcmV0dXJuO1xuICAvLyBSdW4gaGFuZGxlcnMgaW4gcGFyYWxsZWwgXHUyMDE0IHRoZXkgdG91Y2ggZGlzam9pbnQgcmVzb3VyY2VzXG4gIC8vICh3aWtpIHNuYXBzaG90IGVuZHBvaW50IHZzIGNvbmZpZy1yZWZyZXNoIGVuZHBvaW50IHZzIGxvY2FsXG4gIC8vIGZpbGUgY29weSkgYW5kIHNlcmlhbGlzaW5nIHRoZW0gd291bGQgcHVzaCB0aGUgcGVyLXR1cm5cbiAgLy8gbGF0ZW5jeSBwYXN0IHRoZSAyIHMgc2FmZVBvc3QgdGltZW91dCB1bmRlciBiYWQgY29uZGl0aW9ucy5cbiAgYXdhaXQgUHJvbWlzZS5hbGwoSEFORExFUlMubWFwKChoYW5kbGVyKSA9PiBydW5IYW5kbGVyKGhhbmRsZXIsIHBheWxvYWQpKSk7XG59XG5cbm1haW4oKS5jYXRjaCgoKSA9PiB7XG4gIC8vIE91dGVybW9zdCBzYWZldHkgbmV0IFx1MjAxNCBzZWUgcnVuSGFuZGxlciBjb21tZW50LlxufSk7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7QUFVQSxTQUFTLG9CQUFvQjtBQUM3QixPQUFPQSxXQUFVOzs7QUNKVixJQUFNLGdCQUFnQjtBQUN0QixJQUFNLGdCQUFnQjtBQWdCdEIsSUFBTSw4QkFBOEIsSUFBSTtBQVl4QyxJQUFNLGdDQUFnQyxJQUFJO0FBTTFDLElBQU0sNEJBQTRCLElBQUk7OztBQ25DN0MsU0FBUyxlQUFlO0FBQ3hCLE9BQU8sVUFBVTtBQUVWLFNBQVMsZ0JBQXdCO0FBQ3RDLFNBQU8sUUFBUSxJQUFJLHNCQUFzQixLQUFLLEtBQUssUUFBUSxHQUFHLGFBQWE7QUFDN0U7OztBRkdBLElBQU0sYUFBYTtBQUNuQixJQUFNLFlBQVk7QUFPWCxTQUFTLGFBQXFCO0FBQ25DLFNBQU8sUUFBUSxJQUFJLG9CQUFvQjtBQUN6QztBQUVBLFNBQVMsWUFBWSxLQUFxQjtBQUN4QyxNQUFJO0FBQ0YsV0FBTyxhQUFhQyxNQUFLLEtBQUssY0FBYyxHQUFHLEdBQUcsR0FBRyxPQUFPLEVBQUUsS0FBSztBQUFBLEVBQ3JFLFFBQVE7QUFDTixXQUFPO0FBQUEsRUFDVDtBQUNGO0FBRU8sU0FBUyxZQUFvQjtBQUNsQyxTQUFPLFlBQVksVUFBVTtBQUMvQjtBQUVPLFNBQVMsV0FBMEI7QUFDeEMsUUFBTSxNQUFNLFlBQVksU0FBUztBQUNqQyxNQUFJLENBQUMsSUFBSyxRQUFPO0FBQ2pCLFFBQU0sT0FBTyxPQUFPLFNBQVMsS0FBSyxFQUFFO0FBQ3BDLFNBQU8sT0FBTyxVQUFVLElBQUksS0FBSyxPQUFPLEtBQUssT0FBTyxRQUFRLE9BQU87QUFDckU7QUFrQk8sU0FBUyxjQUFjLFVBQWtCLE1BQW9D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QUFTLEtBQU07QUFPbkIsUUFBTSxtQkFBbUIsUUFBUSxJQUFJO0FBQ3JDLFFBQU0sbUJBQW1CLGlCQUFpQixPQUFPO0FBQ2pELFFBQU0sWUFBWSxvQkFBb0IsaUJBQWlCLFNBQVMsSUFBSSxtQkFBbUI7QUFDdkYsUUFBTSxPQUFPLGNBQWMsU0FBWSxFQUFFLEtBQUssSUFBSSxFQUFFLE1BQU0sVUFBVTtBQUVwRSxRQUFNLE1BQU0sY0FBYywrQkFBK0IsSUFBSTtBQUM3RCxRQUFNLFNBQVMsR0FBRztBQUNwQjs7O0FHYkEsSUFBTSxXQUFzQixDQUFDLG9CQUFvQixxQkFBcUIsaUJBQWlCO0FBRXZGLGVBQWUsV0FBVyxTQUFrQixTQUFxQztBQUMvRSxNQUFJO0FBQ0YsVUFBTSxRQUFRLE9BQU87QUFBQSxFQUN2QixRQUFRO0FBQUEsRUFLUjtBQUNGO0FBRUEsZUFBZSxPQUFzQjtBQUNuQyxRQUFNLFVBQVUsTUFBTSxnQkFBZ0I7QUFDdEMsTUFBSSxDQUFDLFFBQVM7QUFLZCxRQUFNLFFBQVEsSUFBSSxTQUFTLElBQUksQ0FBQyxZQUFZLFdBQVcsU0FBUyxPQUFPLENBQUMsQ0FBQztBQUMzRTtBQUVBLEtBQUssRUFBRSxNQUFNLE1BQU07QUFFbkIsQ0FBQzsiLAogICJuYW1lcyI6IFsicGF0aCIsICJwYXRoIiwgInJlYWRGaWxlU3luYyIsICJwYXRoIiwgInBhdGgiLCAicmVhZEZpbGVTeW5jIiwgInBhdGgiLCAicGF0aCIsICJwYXRoIiwgInBhdGgiXQp9Cg==
@@ -1,49 +0,0 @@
1
- // Writable computed that bridges activeSession.selectedResultUuid
2
- // with the URL's ?result= query parameter.
3
-
4
- import { computed, watch, type ComputedRef, type WritableComputedRef } from "vue";
5
- import { useRoute, useRouter, isNavigationFailure } from "vue-router";
6
- import type { ActiveSession } from "../types/session";
7
-
8
- export function useSelectedResult(opts: {
9
- activeSession: ComputedRef<ActiveSession | undefined>;
10
- sessionMap: Map<string, ActiveSession>;
11
- currentSessionId: { readonly value: string };
12
- }): {
13
- selectedResultUuid: WritableComputedRef<string | null>;
14
- } {
15
- const { activeSession } = opts;
16
- const route = useRoute();
17
- const router = useRouter();
18
-
19
- const selectedResultUuid = computed({
20
- get: () => activeSession.value?.selectedResultUuid ?? null,
21
- set: (val: string | null) => {
22
- if (activeSession.value) activeSession.value.selectedResultUuid = val;
23
- const { result: __result, ...restQuery } = route.query;
24
- const nextQuery = val ? { ...restQuery, result: val } : restQuery;
25
- router.replace({ query: nextQuery }).catch((err: unknown) => {
26
- if (!isNavigationFailure(err)) {
27
- console.error("[selectedResultUuid] navigation failed:", err);
28
- }
29
- });
30
- },
31
- });
32
-
33
- // External URL changes for ?result= → sync into the session.
34
- watch(
35
- () => route.query.result,
36
- (newResult) => {
37
- const session = opts.sessionMap.get(opts.currentSessionId.value);
38
- if (!session) return;
39
- // Ignore malformed (array) values rather than clobbering state.
40
- if (Array.isArray(newResult)) return;
41
- const resultId = typeof newResult === "string" ? newResult : null;
42
- if (resultId !== session.selectedResultUuid) {
43
- session.selectedResultUuid = resultId;
44
- }
45
- },
46
- );
47
-
48
- return { selectedResultUuid };
49
- }