@dollhousemcp/mcp-server 2.0.18 → 2.0.20

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 (45) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/generated/version.d.ts +2 -2
  3. package/dist/generated/version.js +3 -3
  4. package/dist/handlers/ElementCRUDHandler.d.ts +30 -0
  5. package/dist/handlers/ElementCRUDHandler.d.ts.map +1 -1
  6. package/dist/handlers/ElementCRUDHandler.js +141 -2
  7. package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts +3 -0
  8. package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts.map +1 -1
  9. package/dist/handlers/mcp-aql/MCPAQLHandler.js +98 -1
  10. package/dist/handlers/mcp-aql/OperationRouter.d.ts.map +1 -1
  11. package/dist/handlers/mcp-aql/OperationRouter.js +6 -1
  12. package/dist/handlers/mcp-aql/OperationSchema.d.ts.map +1 -1
  13. package/dist/handlers/mcp-aql/OperationSchema.js +17 -1
  14. package/dist/handlers/mcp-aql/policies/AgentToolPolicyTranslator.d.ts.map +1 -1
  15. package/dist/handlers/mcp-aql/policies/AgentToolPolicyTranslator.js +2 -1
  16. package/dist/handlers/mcp-aql/policies/ElementPolicies.d.ts.map +1 -1
  17. package/dist/handlers/mcp-aql/policies/ElementPolicies.js +2 -1
  18. package/dist/handlers/mcp-aql/policies/OperationPolicies.d.ts.map +1 -1
  19. package/dist/handlers/mcp-aql/policies/OperationPolicies.js +6 -1
  20. package/dist/handlers/mcp-aql/policies/ToolClassification.d.ts.map +1 -1
  21. package/dist/handlers/mcp-aql/policies/ToolClassification.js +2 -1
  22. package/dist/server/tools/MCPAQLTools.js +2 -1
  23. package/dist/web/console/IngestRoutes.d.ts +6 -0
  24. package/dist/web/console/IngestRoutes.d.ts.map +1 -1
  25. package/dist/web/console/IngestRoutes.js +38 -9
  26. package/dist/web/console/LeaderElection.d.ts +39 -0
  27. package/dist/web/console/LeaderElection.d.ts.map +1 -1
  28. package/dist/web/console/LeaderElection.js +147 -29
  29. package/dist/web/console/LeaderForwardingSink.d.ts.map +1 -1
  30. package/dist/web/console/LeaderForwardingSink.js +5 -1
  31. package/dist/web/console/PromotionManager.d.ts.map +1 -1
  32. package/dist/web/console/PromotionManager.js +3 -11
  33. package/dist/web/console/StaleProcessRecovery.d.ts +11 -0
  34. package/dist/web/console/StaleProcessRecovery.d.ts.map +1 -1
  35. package/dist/web/console/StaleProcessRecovery.js +229 -63
  36. package/dist/web/console/UnifiedConsole.d.ts +22 -1
  37. package/dist/web/console/UnifiedConsole.d.ts.map +1 -1
  38. package/dist/web/console/UnifiedConsole.js +172 -11
  39. package/dist/web/public/app.js +62 -1
  40. package/dist/web/public/index.html +19 -17
  41. package/dist/web/public/sessions.js +111 -0
  42. package/dist/web/server.d.ts.map +1 -1
  43. package/dist/web/server.js +12 -10
  44. package/package.json +1 -1
  45. package/server.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"StaleProcessRecovery.d.ts","sourceRoot":"","sources":["../../../src/web/console/StaleProcessRecovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA6BH;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsBxE;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAwDlF;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA6BrE"}
1
+ {"version":3,"file":"StaleProcessRecovery.d.ts","sourceRoot":"","sources":["../../../src/web/console/StaleProcessRecovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA8DH,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EACF,gBAAgB,GAChB,gBAAgB,GAChB,uBAAuB,GACvB,oBAAoB,GACpB,YAAY,GACZ,cAAc,GACd,aAAa,GACb,eAAe,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGlE;AA8LD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxE;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGlF;AAED,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAyB1G;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoCrE"}
@@ -8,6 +8,7 @@
8
8
  * Extracted to a standalone module so it can be tested without importing
9
9
  * the full Express server and its dependency chain.
10
10
  */
11
+ import { UnicodeValidator } from '../../security/validators/unicodeValidator.js';
11
12
  // Use lazy import for logger to avoid pulling in the full env.ts/config chain
12
13
  // at module load time. This keeps the module independently testable.
13
14
  /** Timeout for lsof/fuser/ps system calls (ms) */
@@ -20,6 +21,12 @@ const KILL_POLL_COUNT = 10;
20
21
  const SIGKILL_WAIT_MS = 500;
21
22
  /** Wait between lock file reads for TOCTOU mitigation (ms) */
22
23
  const LOCK_RECHECK_DELAY_MS = 500;
24
+ /** Number of lock-file checks before deciding the port holder is not a fresh leader. */
25
+ const LOCK_RECHECK_ATTEMPTS = 2;
26
+ /** PID used by the OS init/launchd process; direct children are effectively orphaned. */
27
+ const ROOT_PARENT_PID = 1;
28
+ /** Number of `ps` columns requested by inspectProcess: user, pid, ppid, command. */
29
+ const PROCESS_INSPECTION_FIELD_COUNT = 4;
23
30
  let _logger = null;
24
31
  async function getLogger() {
25
32
  if (!_logger) {
@@ -31,10 +38,190 @@ async function getLogger() {
31
38
  return _logger;
32
39
  }
33
40
  const logger = {
34
- warn: async (...args) => { const l = await getLogger(); l ? l.warn(args[0], args[1]) : console.error('[WARN]', ...args); },
35
- info: async (...args) => { const l = await getLogger(); l ? l.info(args[0], args[1]) : console.error('[INFO]', ...args); },
36
- debug: async (...args) => { const l = await getLogger(); l ? l.debug(args[0], args[1]) : void 0; },
41
+ warn: async (...args) => {
42
+ const l = await getLogger();
43
+ if (l)
44
+ l.warn(args[0], args[1]);
45
+ else
46
+ console.error('[WARN]', ...args);
47
+ },
48
+ info: async (...args) => {
49
+ const l = await getLogger();
50
+ if (l)
51
+ l.info(args[0], args[1]);
52
+ else
53
+ console.error('[INFO]', ...args);
54
+ },
55
+ debug: async (...args) => {
56
+ const l = await getLogger();
57
+ if (l)
58
+ l.debug(args[0], args[1]);
59
+ },
37
60
  };
61
+ const MCP_HOST_PARENT_PATTERNS = [
62
+ /Claude\.app\/Contents\/Helpers\/disclaimer/i,
63
+ /Codex\.app\/Contents\/Resources\/codex app-server/i,
64
+ /Cursor\.app\//i,
65
+ /Windsurf\.app\//i,
66
+ ];
67
+ export function isRecognizedMcpHostParent(command) {
68
+ const normalizedCommand = UnicodeValidator.normalize(command).normalizedContent;
69
+ return MCP_HOST_PARENT_PATTERNS.some((pattern) => pattern.test(normalizedCommand));
70
+ }
71
+ function isDollhouseProcessCommand(cmdLine) {
72
+ const normalizedCommand = UnicodeValidator.normalize(cmdLine).normalizedContent;
73
+ const isDollhouseBin = /(?:^|\/)dollhousemcp(?:\s|$)/.test(normalizedCommand) ||
74
+ normalizedCommand.includes('.bin/dollhousemcp');
75
+ const isMcpServerBin = normalizedCommand.includes('.bin/mcp-server') ||
76
+ /(?:dollhousemcp|mcp-server)[/\\]dist[/\\]index\.js/.test(normalizedCommand);
77
+ return isDollhouseBin || isMcpServerBin;
78
+ }
79
+ function parsePidToken(value) {
80
+ if (!value)
81
+ return null;
82
+ for (let i = 0; i < value.length; i++) {
83
+ const codePoint = value.codePointAt(i);
84
+ if (codePoint === undefined || codePoint < 48 || codePoint > 57) {
85
+ return null;
86
+ }
87
+ }
88
+ const parsed = Number.parseInt(value, 10);
89
+ if (!Number.isSafeInteger(parsed) || parsed < ROOT_PARENT_PID) {
90
+ return null;
91
+ }
92
+ return parsed;
93
+ }
94
+ function isWhitespaceChar(value) {
95
+ return value === ' ' || value === '\t' || value === '\n' || value === '\r' || value === '\f' || value === '\v';
96
+ }
97
+ function buildKillOutcome(killed, reason, processInfo, parentCommand, detail) {
98
+ return {
99
+ killed,
100
+ reason,
101
+ pid: processInfo.pid,
102
+ parentPid: processInfo.parentPid,
103
+ command: processInfo.command,
104
+ parentCommand,
105
+ ...(detail ? { detail } : {}),
106
+ };
107
+ }
108
+ async function getKillGuardFailure(processInfo, port) {
109
+ const currentUser = (await import('node:os')).userInfo().username;
110
+ if (processInfo.user !== currentUser) {
111
+ await logger.warn(`[WebUI] Port ${port} held by different user (pid ${processInfo.pid}) — not killing`);
112
+ return buildKillOutcome(false, 'different_user', processInfo);
113
+ }
114
+ if (!isDollhouseProcessCommand(processInfo.command)) {
115
+ await logger.warn(`[WebUI] Port ${port} held by non-DollhouseMCP process (pid ${processInfo.pid}) — not killing`, {
116
+ cmdLine: processInfo.command,
117
+ });
118
+ return buildKillOutcome(false, 'not_dollhouse_process', processInfo);
119
+ }
120
+ if (processInfo.parentPid <= ROOT_PARENT_PID || !isPidAlive(processInfo.parentPid)) {
121
+ return null;
122
+ }
123
+ const parentCommand = (await getProcessCommand(processInfo.parentPid)) ?? undefined;
124
+ if (parentCommand && isRecognizedMcpHostParent(parentCommand)) {
125
+ await logger.warn(`[WebUI] Port ${port} held by active client-backed DollhouseMCP process (pid ${processInfo.pid}) — not killing`, {
126
+ cmdLine: processInfo.command,
127
+ parentPid: processInfo.parentPid,
128
+ parentCommand,
129
+ });
130
+ return buildKillOutcome(false, 'active_host_parent', processInfo, parentCommand);
131
+ }
132
+ return null;
133
+ }
134
+ async function terminateProcess(processInfo, port, parentCommand) {
135
+ process.kill(processInfo.pid, 'SIGTERM');
136
+ logger.warn(`[WebUI] Sent SIGTERM to stale process ${processInfo.pid} on port ${port}`, {
137
+ cmdLine: processInfo.command,
138
+ parentPid: processInfo.parentPid,
139
+ parentCommand,
140
+ });
141
+ for (let i = 0; i < KILL_POLL_COUNT; i++) {
142
+ await new Promise(r => setTimeout(r, SIGTERM_POLL_MS));
143
+ if (!isPidAlive(processInfo.pid)) {
144
+ return buildKillOutcome(true, 'terminated', processInfo, parentCommand);
145
+ }
146
+ }
147
+ process.kill(processInfo.pid, 'SIGKILL');
148
+ logger.warn(`[WebUI] Sent SIGKILL to stale process ${processInfo.pid} on port ${port}`);
149
+ await new Promise(r => setTimeout(r, SIGKILL_WAIT_MS));
150
+ return isPidAlive(processInfo.pid)
151
+ ? buildKillOutcome(false, 'still_alive', processInfo, parentCommand)
152
+ : buildKillOutcome(true, 'terminated', processInfo, parentCommand);
153
+ }
154
+ function splitProcessInspectionFields(line) {
155
+ const fields = [];
156
+ let index = 0;
157
+ const normalizedLine = UnicodeValidator.normalize(line).normalizedContent.trim();
158
+ while (index < normalizedLine.length && fields.length < PROCESS_INSPECTION_FIELD_COUNT - 1) {
159
+ while (index < normalizedLine.length && isWhitespaceChar(normalizedLine[index])) {
160
+ index++;
161
+ }
162
+ if (index >= normalizedLine.length)
163
+ break;
164
+ const fieldStart = index;
165
+ while (index < normalizedLine.length && !isWhitespaceChar(normalizedLine[index])) {
166
+ index++;
167
+ }
168
+ fields.push(normalizedLine.slice(fieldStart, index));
169
+ }
170
+ while (index < normalizedLine.length && isWhitespaceChar(normalizedLine[index])) {
171
+ index++;
172
+ }
173
+ if (index < normalizedLine.length) {
174
+ fields.push(normalizedLine.slice(index));
175
+ }
176
+ return fields.length === PROCESS_INSPECTION_FIELD_COUNT ? fields : null;
177
+ }
178
+ async function inspectProcess(pid) {
179
+ const { execFile: execFileCb } = await import('node:child_process');
180
+ const { promisify } = await import('node:util');
181
+ const execFileAsync = promisify(execFileCb);
182
+ try {
183
+ const { stdout } = await execFileAsync('ps', ['-p', String(pid), '-o', 'user=,pid=,ppid=,command='], { timeout: COMMAND_TIMEOUT_MS });
184
+ const fields = splitProcessInspectionFields(stdout);
185
+ if (!fields)
186
+ return null;
187
+ const [user, pidToken, parentPidToken, command] = fields;
188
+ const parsedPid = parsePidToken(pidToken);
189
+ const parsedParentPid = parsePidToken(parentPidToken);
190
+ if (parsedPid === null || parsedParentPid === null)
191
+ return null;
192
+ return {
193
+ user: UnicodeValidator.normalize(user).normalizedContent,
194
+ pid: parsedPid,
195
+ parentPid: parsedParentPid,
196
+ command: UnicodeValidator.normalize(command).normalizedContent,
197
+ };
198
+ }
199
+ catch {
200
+ return null;
201
+ }
202
+ }
203
+ async function getProcessCommand(pid) {
204
+ const { execFile: execFileCb } = await import('node:child_process');
205
+ const { promisify } = await import('node:util');
206
+ const execFileAsync = promisify(execFileCb);
207
+ try {
208
+ const { stdout } = await execFileAsync('ps', ['-p', String(pid), '-o', 'command='], { timeout: COMMAND_TIMEOUT_MS });
209
+ const normalized = UnicodeValidator.normalize(stdout).normalizedContent.trim();
210
+ return normalized || null;
211
+ }
212
+ catch {
213
+ return null;
214
+ }
215
+ }
216
+ function isPidAlive(pid) {
217
+ try {
218
+ process.kill(pid, 0);
219
+ return true;
220
+ }
221
+ catch {
222
+ return false;
223
+ }
224
+ }
38
225
  /**
39
226
  * Find the PID of the process listening on a given port.
40
227
  * Uses lsof on macOS/Linux. Returns null if not found or on error.
@@ -56,7 +243,10 @@ export async function findPidOnPort(port) {
56
243
  const { stdout, stderr } = await execFileAsync(cmd.bin, cmd.args, { timeout: COMMAND_TIMEOUT_MS });
57
244
  // fuser outputs to stderr on some systems
58
245
  const output = (stdout || stderr || '').trim();
59
- const pids = output.split(/\s+/).map(Number).filter(n => !Number.isNaN(n) && n > 0);
246
+ const pids = output
247
+ .split(/\s+/)
248
+ .map((token) => parsePidToken(token))
249
+ .filter((pid) => pid !== null);
60
250
  const otherPid = pids.find(p => p !== process.pid);
61
251
  if (otherPid)
62
252
  return otherPid;
@@ -76,63 +266,31 @@ export async function findPidOnPort(port) {
76
266
  * before escalating to SIGKILL. Total worst case: ~4s.
77
267
  */
78
268
  export async function killStaleProcess(pid, port) {
79
- const { execFile: execFileCb } = await import('node:child_process');
80
- const { promisify } = await import('node:util');
81
- const execFileAsync = promisify(execFileCb);
82
- // Security verification flow three checks must pass before we kill:
83
- // 1. Process must be owned by the current OS user (prevents cross-user kills)
84
- // 2. Command line must match a DollhouseMCP binary path (prevents killing other services)
85
- // 3. If both fail or ps can't run, we refuse safe default is to not kill
86
- let cmdLine = '';
87
- try {
88
- const { stdout } = await execFileAsync('ps', ['-p', String(pid), '-o', 'user=,command='], { timeout: COMMAND_TIMEOUT_MS });
89
- // Check 1: User ownership — only kill our own processes
90
- const currentUser = (await import('node:os')).userInfo().username;
91
- if (!stdout.trim().startsWith(currentUser)) {
92
- await logger.warn(`[WebUI] Port ${port} held by different user (pid ${pid}) — not killing`);
93
- return false;
94
- }
95
- // Check 2: Binary identity — must be .bin/mcp-server, .bin/dollhousemcp,
96
- // /bin/dollhousemcp (global install), or dist/index.js (direct node execution).
97
- // NOT just 'mcp-server' anywhere in the path — that would match Jest workers
98
- // running from within the mcp-server project directory.
99
- cmdLine = stdout.trim();
100
- const isDollhouseBin = /(?:^|\/)dollhousemcp(?:\s|$)/.test(cmdLine) ||
101
- cmdLine.includes('.bin/dollhousemcp');
102
- const isMcpServerBin = cmdLine.includes('.bin/mcp-server') ||
103
- /(?:dollhousemcp|mcp-server)[/\\]dist[/\\]index\.js/.test(cmdLine);
104
- if (!isDollhouseBin && !isMcpServerBin) {
105
- await logger.warn(`[WebUI] Port ${port} held by non-DollhouseMCP process (pid ${pid}) — not killing`, { cmdLine });
106
- return false;
107
- }
108
- await logger.debug(`[WebUI] Verified stale process ${pid} is DollhouseMCP`, { cmdLine });
269
+ const outcome = await killStaleProcessDetailed(pid, port);
270
+ return outcome.killed;
271
+ }
272
+ export async function killStaleProcessDetailed(pid, port) {
273
+ const processInfo = await inspectProcess(pid);
274
+ if (!processInfo) {
275
+ await logger.debug(`[WebUI] Cannot verify process ${pid}skipping kill`);
276
+ return { killed: false, reason: 'inspect_failed', pid };
109
277
  }
110
- catch (err) {
111
- // Check 3: If we can't verify, don't kill — safe default
112
- await logger.debug(`[WebUI] Cannot verify process ${pid} — skipping kill`, {
113
- error: err instanceof Error ? err.message : String(err),
114
- });
115
- return false;
278
+ const guardFailure = await getKillGuardFailure(processInfo, port);
279
+ if (guardFailure) {
280
+ return guardFailure;
116
281
  }
282
+ const parentCommand = processInfo.parentPid > ROOT_PARENT_PID
283
+ ? (await getProcessCommand(processInfo.parentPid)) ?? undefined
284
+ : undefined;
285
+ await logger.debug(`[WebUI] Verified stale process ${pid} is DollhouseMCP`, { cmdLine: processInfo.command, parentPid: processInfo.parentPid, parentCommand });
117
286
  try {
118
- process.kill(pid, 'SIGTERM');
119
- logger.warn(`[WebUI] Sent SIGTERM to stale process ${pid} on port ${port}`, { cmdLine });
120
- for (let i = 0; i < KILL_POLL_COUNT; i++) {
121
- await new Promise(r => setTimeout(r, SIGTERM_POLL_MS));
122
- try {
123
- process.kill(pid, 0);
124
- }
125
- catch {
126
- return true;
127
- }
128
- }
129
- process.kill(pid, 'SIGKILL');
130
- logger.warn(`[WebUI] Sent SIGKILL to stale process ${pid} on port ${port}`);
131
- await new Promise(r => setTimeout(r, SIGKILL_WAIT_MS));
132
- return true;
287
+ return await terminateProcess(processInfo, port, parentCommand);
133
288
  }
134
- catch {
135
- return true; // process already dead
289
+ catch (err) {
290
+ if (!isPidAlive(pid)) {
291
+ return buildKillOutcome(true, 'already_dead', processInfo, parentCommand);
292
+ }
293
+ return buildKillOutcome(false, 'signal_failed', processInfo, parentCommand, err instanceof Error ? err.message : String(err));
136
294
  }
137
295
  }
138
296
  /**
@@ -150,7 +308,7 @@ export async function recoverStalePort(port) {
150
308
  // written its lock file. Read the lock, pause, re-read. If the second read
151
309
  // now matches the port holder, it's a fresh leader — don't kill.
152
310
  const { readLeaderLock } = await import('./LeaderElection.js');
153
- for (let check = 0; check < 2; check++) {
311
+ for (let check = 0; check < LOCK_RECHECK_ATTEMPTS; check++) {
154
312
  try {
155
313
  const lock = await readLeaderLock();
156
314
  if (lock?.pid === stalePid && lock?.port === port && lock.pid !== process.pid) {
@@ -161,15 +319,23 @@ export async function recoverStalePort(port) {
161
319
  catch {
162
320
  // Can't read lock file — continue to next check or kill
163
321
  }
164
- if (check === 0) {
322
+ if (check < LOCK_RECHECK_ATTEMPTS - 1) {
165
323
  await new Promise(r => setTimeout(r, LOCK_RECHECK_DELAY_MS));
166
324
  }
167
325
  }
168
- const killed = await killStaleProcess(stalePid, port);
169
- if (killed) {
326
+ const outcome = await killStaleProcessDetailed(stalePid, port);
327
+ if (outcome.killed) {
170
328
  logger.info(`[WebUI] Stale process ${stalePid} removed from port ${port}`);
171
329
  await new Promise(r => setTimeout(r, SIGKILL_WAIT_MS)); // brief pause for port release
172
330
  }
173
- return killed;
331
+ else {
332
+ await logger.debug(`[WebUI] Stale-port recovery skipped for pid ${stalePid}`, {
333
+ reason: outcome.reason,
334
+ parentPid: outcome.parentPid,
335
+ parentCommand: outcome.parentCommand,
336
+ detail: outcome.detail,
337
+ });
338
+ }
339
+ return outcome.killed;
174
340
  }
175
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RhbGVQcm9jZXNzUmVjb3ZlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2ViL2NvbnNvbGUvU3RhbGVQcm9jZXNzUmVjb3ZlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7OztHQVNHO0FBRUgsOEVBQThFO0FBQzlFLHFFQUFxRTtBQUNyRSxrREFBa0Q7QUFDbEQsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUM7QUFDaEMsb0VBQW9FO0FBQ3BFLE1BQU0sZUFBZSxHQUFHLEdBQUcsQ0FBQztBQUM1QixtREFBbUQ7QUFDbkQsTUFBTSxlQUFlLEdBQUcsRUFBRSxDQUFDO0FBQzNCLCtDQUErQztBQUMvQyxNQUFNLGVBQWUsR0FBRyxHQUFHLENBQUM7QUFDNUIsOERBQThEO0FBQzlELE1BQU0scUJBQXFCLEdBQUcsR0FBRyxDQUFDO0FBRWxDLElBQUksT0FBTyxHQUF5RCxJQUFJLENBQUM7QUFDekUsS0FBSyxVQUFVLFNBQVM7SUFDdEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2IsSUFBSSxDQUFDO1lBQUMsT0FBTyxHQUFHLENBQUMsTUFBTSxNQUFNLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUFDLENBQUM7UUFDakUsTUFBTSxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBQ0QsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQUNELE1BQU0sTUFBTSxHQUFHO0lBQ2IsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLElBQWUsRUFBRSxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsTUFBTSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFXLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFL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QU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCx3REFBd0Q7UUFDMUQsQ0FBQztRQUNELElBQUksS0FBSyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLHFCQUFxQixDQUFDLENBQUMsQ0FBQztRQUMvRCxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3RELElBQUksTUFBTSxFQUFFLENBQUM7UUFDWCxNQUFNLENBQUMsSUFBSSxDQUFDLHlCQUF5QixRQUFRLHNCQUFzQixJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzNFLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQywrQkFBK0I7SUFDekYsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFN0YWxlIHByb2Nlc3MgZGV0ZWN0aW9uIGFuZCByZWNvdmVyeSAoIzE4NTApLlxuICpcbiAqIEZpbmRzIGFuZCBraWxscyB6b21iaWUgRG9sbGhvdXNlTUNQIHByb2Nlc3NlcyB0aGF0IHNxdWF0IG9uIHRoZSBjb25zb2xlXG4gKiBwb3J0IGFmdGVyIHRoZWlyIHNlc3Npb24gaGFzIGVuZGVkLiBVc2VkIGJ5IGJpbmRBbmRMaXN0ZW4gaW4gc2VydmVyLnRzXG4gKiB3aGVuIEVBRERSSU5VU0Ugb2NjdXJzLlxuICpcbiAqIEV4dHJhY3RlZCB0byBhIHN0YW5kYWxvbmUgbW9kdWxlIHNvIGl0IGNhbiBiZSB0ZXN0ZWQgd2l0aG91dCBpbXBvcnRpbmdcbiAqIHRoZSBmdWxsIEV4cHJlc3Mgc2VydmVyIGFuZCBpdHMgZGVwZW5kZW5jeSBjaGFpbi5cbiAqL1xuXG4vLyBVc2UgbGF6eSBpbXBvcnQgZm9yIGxvZ2dlciB0byBhdm9pZCBwdWxsaW5nIGluIHRoZSBmdWxsIGVudi50cy9jb25maWcgY2hhaW5cbi8vIGF0IG1vZHVsZSBsb2FkIHRpbWUuIFRoaXMga2VlcHMgdGhlIG1vZHVsZSBpbmRlcGVuZGVudGx5IHRlc3RhYmxlLlxuLyoqIFRpbWVvdXQgZm9yIGxzb2YvZnVzZXIvcHMgc3lzdGVtIGNhbGxzIChtcykgKi9cbmNvbnN0IENPTU1BTkRfVElNRU9VVF9NUyA9IDEwMDA7XG4vKiogUG9sbGluZyBpbnRlcnZhbCB3aGVuIHdhaXRpbmcgZm9yIFNJR1RFUk0gdG8gdGFrZSBlZmZlY3QgKG1zKSAqL1xuY29uc3QgU0lHVEVSTV9QT0xMX01TID0gMzAwO1xuLyoqIE51bWJlciBvZiBwb2xscyBiZWZvcmUgZXNjYWxhdGluZyB0byBTSUdLSUxMICovXG5jb25zdCBLSUxMX1BPTExfQ09VTlQgPSAxMDtcbi8qKiBXYWl0IGFmdGVyIFNJR0tJTEwgYmVmb3JlIHJldHVybmluZyAobXMpICovXG5jb25zdCBTSUdLSUxMX1dBSVRfTVMgPSA1MDA7XG4vKiogV2FpdCBiZXR3ZWVuIGxvY2sgZmlsZSByZWFkcyBmb3IgVE9DVE9VIG1pdGlnYXRpb24gKG1zKSAqL1xuY29uc3QgTE9DS19SRUNIRUNLX0RFTEFZX01TID0gNTAwO1xuXG5sZXQgX2xvZ2dlcjogdHlwZW9mIGltcG9ydCgnLi4vLi4vdXRpbHMvbG9nZ2VyLmpzJykubG9nZ2VyIHwgbnVsbCA9IG51bGw7XG5hc3luYyBmdW5jdGlvbiBnZXRMb2dnZXIoKSB7XG4gIGlmICghX2xvZ2dlcikge1xuICAgIHRyeSB7IF9sb2dnZXIgPSAoYXdhaXQgaW1wb3J0KCcuLi8uLi91dGlscy9sb2dnZXIuanMnKSkubG9nZ2VyOyB9XG4gICAgY2F0Y2ggeyAvKiBmYWxsYmFjayBiZWxvdyAqLyB9XG4gIH1cbiAgcmV0dXJuIF9sb2dnZXI7XG59XG5jb25zdCBsb2dnZXIgPSB7XG4gIHdhcm46IGFzeW5jICguLi5hcmdzOiB1bmtub3duW10pID0+IHsgY29uc3QgbCA9IGF3YWl0IGdldExvZ2dlcigpOyBsID8gbC53YXJuKGFyZ3NbMF0gYXMgc3RyaW5nLCBhcmdzWzFdKSA6IGNvbnNvbGUuZXJyb3IoJ1tXQVJOXScsIC4uLmFyZ3MpOyB9LFxuICBpbmZvOiBhc3luYyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7IGNvbnN0IGwgPSBhd2FpdCBnZXRMb2dnZXIoKTsgbCA/IGwuaW5mbyhhcmdzWzBdIGFzIHN0cmluZywgYXJnc1sxXSkgOiBjb25zb2xlLmVycm9yKCdbSU5GT10nLCAuLi5hcmdzKTsgfSxcbiAgZGVidWc6IGFzeW5jICguLi5hcmdzOiB1bmtub3duW10pID0+IHsgY29uc3QgbCA9IGF3YWl0IGdldExvZ2dlcigpOyBsID8gbC5kZWJ1ZyhhcmdzWzBdIGFzIHN0cmluZywgYXJnc1sxXSkgOiB2b2lkIDA7IH0sXG59O1xuXG4vKipcbiAqIEZpbmQgdGhlIFBJRCBvZiB0aGUgcHJvY2VzcyBsaXN0ZW5pbmcgb24gYSBnaXZlbiBwb3J0LlxuICogVXNlcyBsc29mIG9uIG1hY09TL0xpbnV4LiBSZXR1cm5zIG51bGwgaWYgbm90IGZvdW5kIG9yIG9uIGVycm9yLlxuICpcbiAqIFRpbWVvdXQ6IDFzIOKAlCBsc29mIG9uIGxvY2FsaG9zdCBpcyB0eXBpY2FsbHkgPDEwMG1zLiBUaGUgMXMgY2VpbGluZ1xuICogaGFuZGxlcyBzbG93IE5GUy1tb3VudGVkIC9kZXYvZmQgb3Igb3ZlcmxvYWRlZCBDSSBydW5uZXJzIHdpdGhvdXRcbiAqIGRlbGF5aW5nIHN0YXJ0dXAgbm90aWNlYWJseS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpbmRQaWRPblBvcnQocG9ydDogbnVtYmVyKTogUHJvbWlzZTxudW1iZXIgfCBudWxsPiB7XG4gIGNvbnN0IHsgZXhlY0ZpbGU6IGV4ZWNGaWxlQ2IgfSA9IGF3YWl0IGltcG9ydCgnbm9kZTpjaGlsZF9wcm9jZXNzJyk7XG4gIGNvbnN0IHsgcHJvbWlzaWZ5IH0gPSBhd2FpdCBpbXBvcnQoJ25vZGU6dXRpbCcpO1xuICBjb25zdCBleGVjRmlsZUFzeW5jID0gcHJvbWlzaWZ5KGV4ZWNGaWxlQ2IpO1xuXG4gIC8vIFRyeSBsc29mIGZpcnN0IChtYWNPUyArIG1vc3QgTGludXgpLCBmYWxsIGJhY2sgdG8gZnVzZXIgKG1pbmltYWwgTGludXgvRG9ja2VyKVxuICBmb3IgKGNvbnN0IGNtZCBvZiBbXG4gICAgeyBiaW46ICdsc29mJywgYXJnczogWyctdGknLCBgOiR7cG9ydH1gXSB9LFxuICAgIHsgYmluOiAnZnVzZXInLCBhcmdzOiBbYCR7cG9ydH0vdGNwYF0gfSxcbiAgXSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IHN0ZG91dCwgc3RkZXJyIH0gPSBhd2FpdCBleGVjRmlsZUFzeW5jKGNtZC5iaW4sIGNtZC5hcmdzLCB7IHRpbWVvdXQ6IENPTU1BTkRfVElNRU9VVF9NUyB9KTtcbiAgICAgIC8vIGZ1c2VyIG91dHB1dHMgdG8gc3RkZXJyIG9uIHNvbWUgc3lzdGVtc1xuICAgICAgY29uc3Qgb3V0cHV0ID0gKHN0ZG91dCB8fCBzdGRlcnIgfHwgJycpLnRyaW0oKTtcbiAgICAgIGNvbnN0IHBpZHMgPSBvdXRwdXQuc3BsaXQoL1xccysvKS5tYXAoTnVtYmVyKS5maWx0ZXIobiA9PiAhTnVtYmVyLmlzTmFOKG4pICYmIG4gPiAwKTtcbiAgICAgIGNvbnN0IG90aGVyUGlkID0gcGlkcy5maW5kKHAgPT4gcCAhPT0gcHJvY2Vzcy5waWQpO1xuICAgICAgaWYgKG90aGVyUGlkKSByZXR1cm4gb3RoZXJQaWQ7XG4gICAgfSBjYXRjaCB7XG4gICAgICBjb250aW51ZTsgLy8gY29tbWFuZCBub3QgZm91bmQgb3Igbm8gcmVzdWx0cyDigJQgdHJ5IG5leHRcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogS2lsbCBhIHN0YWxlIHByb2Nlc3MgaG9sZGluZyBhIHBvcnQuIFNlbmRzIFNJR1RFUk0sIHdhaXRzIGJyaWVmbHksXG4gKiB0aGVuIFNJR0tJTEwgaWYgc3RpbGwgYWxpdmUuIE9ubHkga2lsbHMgRG9sbGhvdXNlTUNQIHByb2Nlc3Nlc1xuICogKHZlcmlmaWVkIGJ5IGNoZWNraW5nIHRoZSBjb21tYW5kIGxpbmUgYW5kIHVzZXIgb3duZXJzaGlwKS5cbiAqXG4gKiBUaW1lb3V0OiAxcyBmb3IgcHMgdmVyaWZpY2F0aW9uLiBLaWxsIHdhaXQ6IDMwMG1zIMOXIDEwIHBvbGxzID0gM3NcbiAqIGJlZm9yZSBlc2NhbGF0aW5nIHRvIFNJR0tJTEwuIFRvdGFsIHdvcnN0IGNhc2U6IH40cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGtpbGxTdGFsZVByb2Nlc3MocGlkOiBudW1iZXIsIHBvcnQ6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBjb25zdCB7IGV4ZWNGaWxlOiBleGVjRmlsZUNiIH0gPSBhd2FpdCBpbXBvcnQoJ25vZGU6Y2hpbGRfcHJvY2VzcycpO1xuICBjb25zdCB7IHByb21pc2lmeSB9ID0gYXdhaXQgaW1wb3J0KCdub2RlOnV0aWwnKTtcbiAgY29uc3QgZXhlY0ZpbGVBc3luYyA9IHByb21pc2lmeShleGVjRmlsZUNiKTtcblxuICAvLyBTZWN1cml0eSB2ZXJpZmljYXRpb24gZmxvdyDigJQgdGhyZWUgY2hlY2tzIG11c3QgcGFzcyBiZWZvcmUgd2Uga2lsbDpcbiAgLy8gMS4gUHJvY2VzcyBtdXN0IGJlIG93bmVkIGJ5IHRoZSBjdXJyZW50IE9TIHVzZXIgKHByZXZlbnRzIGNyb3NzLXVzZXIga2lsbHMpXG4gIC8vIDIuIENvbW1hbmQgbGluZSBtdXN0IG1hdGNoIGEgRG9sbGhvdXNlTUNQIGJpbmFyeSBwYXRoIChwcmV2ZW50cyBraWxsaW5nIG90aGVyIHNlcnZpY2VzKVxuICAvLyAzLiBJZiBib3RoIGZhaWwgb3IgcHMgY2FuJ3QgcnVuLCB3ZSByZWZ1c2Ug4oCUIHNhZmUgZGVmYXVsdCBpcyB0byBub3Qga2lsbFxuICBsZXQgY21kTGluZSA9ICcnO1xuICB0cnkge1xuICAgIGNvbnN0IHsgc3Rkb3V0IH0gPSBhd2FpdCBleGVjRmlsZUFzeW5jKCdwcycsIFsnLXAnLCBTdHJpbmcocGlkKSwgJy1vJywgJ3VzZXI9LGNvbW1hbmQ9J10sIHsgdGltZW91dDogQ09NTUFORF9USU1FT1VUX01TIH0pO1xuXG4gICAgLy8gQ2hlY2sgMTogVXNlciBvd25lcnNoaXAg4oCUIG9ubHkga2lsbCBvdXIgb3duIHByb2Nlc3Nlc1xuICAgIGNvbnN0IGN1cnJlbnRVc2VyID0gKGF3YWl0IGltcG9ydCgnbm9kZTpvcycpKS51c2VySW5mbygpLnVzZXJuYW1lO1xuICAgIGlmICghc3Rkb3V0LnRyaW0oKS5zdGFydHNXaXRoKGN1cnJlbnRVc2VyKSkge1xuICAgICAgYXdhaXQgbG9nZ2VyLndhcm4oYFtXZWJVSV0gUG9ydCAke3BvcnR9IGhlbGQgYnkgZGlmZmVyZW50IHVzZXIgKHBpZCAke3BpZH0pIOKAlCBub3Qga2lsbGluZ2ApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIENoZWNrIDI6IEJpbmFyeSBpZGVudGl0eSDigJQgbXVzdCBiZSAuYmluL21jcC1zZXJ2ZXIsIC5iaW4vZG9sbGhvdXNlbWNwLFxuICAgIC8vIC9iaW4vZG9sbGhvdXNlbWNwIChnbG9iYWwgaW5zdGFsbCksIG9yIGRpc3QvaW5kZXguanMgKGRpcmVjdCBub2RlIGV4ZWN1dGlvbikuXG4gICAgLy8gTk9UIGp1c3QgJ21jcC1zZXJ2ZXInIGFueXdoZXJlIGluIHRoZSBwYXRoIOKAlCB0aGF0IHdvdWxkIG1hdGNoIEplc3Qgd29ya2Vyc1xuICAgIC8vIHJ1bm5pbmcgZnJvbSB3aXRoaW4gdGhlIG1jcC1zZXJ2ZXIgcHJvamVjdCBkaXJlY3RvcnkuXG4gICAgY21kTGluZSA9IHN0ZG91dC50cmltKCk7XG4gICAgY29uc3QgaXNEb2xsaG91c2VCaW4gPSAvKD86XnxcXC8pZG9sbGhvdXNlbWNwKD86XFxzfCQpLy50ZXN0KGNtZExpbmUpIHx8XG4gICAgICBjbWRMaW5lLmluY2x1ZGVzKCcuYmluL2RvbGxob3VzZW1jcCcpO1xuICAgIGNvbnN0IGlzTWNwU2VydmVyQmluID0gY21kTGluZS5pbmNsdWRlcygnLmJpbi9tY3Atc2VydmVyJykgfHxcbiAgICAgIC8oPzpkb2xsaG91c2VtY3B8bWNwLXNlcnZlcilbL1xcXFxdZGlzdFsvXFxcXF1pbmRleFxcLmpzLy50ZXN0KGNtZExpbmUpO1xuICAgIGlmICghaXNEb2xsaG91c2VCaW4gJiYgIWlzTWNwU2VydmVyQmluKSB7XG4gICAgICBhd2FpdCBsb2dnZXIud2FybihgW1dlYlVJXSBQb3J0ICR7cG9ydH0gaGVsZCBieSBub24tRG9sbGhvdXNlTUNQIHByb2Nlc3MgKHBpZCAke3BpZH0pIOKAlCBub3Qga2lsbGluZ2AsIHsgY21kTGluZSB9KTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgYXdhaXQgbG9nZ2VyLmRlYnVnKGBbV2ViVUldIFZlcmlmaWVkIHN0YWxlIHByb2Nlc3MgJHtwaWR9IGlzIERvbGxob3VzZU1DUGAsIHsgY21kTGluZSB9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgLy8gQ2hlY2sgMzogSWYgd2UgY2FuJ3QgdmVyaWZ5LCBkb24ndCBraWxsIOKAlCBzYWZlIGRlZmF1bHRcbiAgICBhd2FpdCBsb2dnZXIuZGVidWcoYFtXZWJVSV0gQ2Fubm90IHZlcmlmeSBwcm9jZXNzICR7cGlkfSDigJQgc2tpcHBpbmcga2lsbGAsIHtcbiAgICAgIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgfSk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBwcm9jZXNzLmtpbGwocGlkLCAnU0lHVEVSTScpO1xuICAgIGxvZ2dlci53YXJuKGBbV2ViVUldIFNlbnQgU0lHVEVSTSB0byBzdGFsZSBwcm9jZXNzICR7cGlkfSBvbiBwb3J0ICR7cG9ydH1gLCB7IGNtZExpbmUgfSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBLSUxMX1BPTExfQ09VTlQ7IGkrKykge1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIFNJR1RFUk1fUE9MTF9NUykpO1xuICAgICAgdHJ5IHsgcHJvY2Vzcy5raWxsKHBpZCwgMCk7IH0gY2F0Y2ggeyByZXR1cm4gdHJ1ZTsgfVxuICAgIH1cbiAgICBwcm9jZXNzLmtpbGwocGlkLCAnU0lHS0lMTCcpO1xuICAgIGxvZ2dlci53YXJuKGBbV2ViVUldIFNlbnQgU0lHS0lMTCB0byBzdGFsZSBwcm9jZXNzICR7cGlkfSBvbiBwb3J0ICR7cG9ydH1gKTtcbiAgICBhd2FpdCBuZXcgUHJvbWlzZShyID0+IHNldFRpbWVvdXQociwgU0lHS0lMTF9XQUlUX01TKSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB0cnVlOyAvLyBwcm9jZXNzIGFscmVhZHkgZGVhZFxuICB9XG59XG5cbi8qKlxuICogRGV0ZWN0IGFuZCByZWNvdmVyIGZyb20gYSBzdGFsZSBwcm9jZXNzIHNxdWF0dGluZyBvbiB0aGUgcG9ydC5cbiAqIENvbXBhcmVzIHRoZSBwb3J0IGhvbGRlcidzIFBJRCBhZ2FpbnN0IHRoZSBsZWFkZXIgbG9jayBmaWxlIHRvIGRldGVybWluZVxuICogaWYgaXQncyBhIHNxdWF0dGVyLiBSZXR1cm5zIHRydWUgaWYgdGhlIHNxdWF0dGVyIHdhcyBraWxsZWQuXG4gKlxuICogVGltZW91dHM6IGxzb2YgMXMsIHBzIDFzLCBTSUdURVJNIHdhaXQgM3Mg4oCUIG1heCB+NXMgdG90YWwuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWNvdmVyU3RhbGVQb3J0KHBvcnQ6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBjb25zdCBzdGFsZVBpZCA9IGF3YWl0IGZpbmRQaWRPblBvcnQocG9ydCk7XG4gIGlmICghc3RhbGVQaWQpIHJldHVybiBmYWxzZTtcblxuICAvLyBUT0NUT1UgbWl0aWdhdGlvbjogYSBuZXcgcHJvY2VzcyBtYXkgaGF2ZSBqdXN0IGJvdW5kIHRoZSBwb3J0IGJ1dCBub3QgeWV0XG4gIC8vIHdyaXR0ZW4gaXRzIGxvY2sgZmlsZS4gUmVhZCB0aGUgbG9jaywgcGF1c2UsIHJlLXJlYWQuIElmIHRoZSBzZWNvbmQgcmVhZFxuICAvLyBub3cgbWF0Y2hlcyB0aGUgcG9ydCBob2xkZXIsIGl0J3MgYSBmcmVzaCBsZWFkZXIg4oCUIGRvbid0IGtpbGwuXG4gIGNvbnN0IHsgcmVhZExlYWRlckxvY2sgfSA9IGF3YWl0IGltcG9ydCgnLi9MZWFkZXJFbGVjdGlvbi5qcycpO1xuICBmb3IgKGxldCBjaGVjayA9IDA7IGNoZWNrIDwgMjsgY2hlY2srKykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBsb2NrID0gYXdhaXQgcmVhZExlYWRlckxvY2soKTtcbiAgICAgIGlmIChsb2NrPy5waWQgPT09IHN0YWxlUGlkICYmIGxvY2s/LnBvcnQgPT09IHBvcnQgJiYgbG9jay5waWQgIT09IHByb2Nlc3MucGlkKSB7XG4gICAgICAgIGF3YWl0IGxvZ2dlci53YXJuKGBbV2ViVUldIFBvcnQgJHtwb3J0fSBoZWxkIGJ5IGxlZ2l0aW1hdGUgbGVhZGVyIChwaWQgJHtzdGFsZVBpZH0pIOKAlCBub3Qga2lsbGluZ2ApO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBDYW4ndCByZWFkIGxvY2sgZmlsZSDigJQgY29udGludWUgdG8gbmV4dCBjaGVjayBvciBraWxsXG4gICAgfVxuICAgIGlmIChjaGVjayA9PT0gMCkge1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIExPQ0tfUkVDSEVDS19ERUxBWV9NUykpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGtpbGxlZCA9IGF3YWl0IGtpbGxTdGFsZVByb2Nlc3Moc3RhbGVQaWQsIHBvcnQpO1xuICBpZiAoa2lsbGVkKSB7XG4gICAgbG9nZ2VyLmluZm8oYFtXZWJVSV0gU3RhbGUgcHJvY2VzcyAke3N0YWxlUGlkfSByZW1vdmVkIGZyb20gcG9ydCAke3BvcnR9YCk7XG4gICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIFNJR0tJTExfV0FJVF9NUykpOyAvLyBicmllZiBwYXVzZSBmb3IgcG9ydCByZWxlYXNlXG4gIH1cbiAgcmV0dXJuIGtpbGxlZDtcbn1cbiJdfQ==
341
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RhbGVQcm9jZXNzUmVjb3ZlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2ViL2NvbnNvbGUvU3RhbGVQcm9jZXNzUmVjb3ZlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7OztHQVNHO0FBRUgsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFFakYsOEVBQThFO0FBQzlFLHFFQUFxRTtBQUNyRSxrREFBa0Q7QUFDbEQsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUM7QUFDaEMsb0VBQW9FO0FBQ3BFLE1BQU0sZUFBZSxHQUFHLEdBQUcsQ0FBQztBQUM1QixtREFBbUQ7QUFDbkQsTUFBTSxlQUFlLEdBQUcsRUFBRSxDQUFDO0FBQzNCLCtDQUErQztBQUMvQyxNQUFNLGVBQWUsR0FBRyxHQUFHLENBQUM7QUFDNUIsOERBQThEO0FBQzlELE1BQU0scUJBQXFCLEdBQUcsR0FBRyxDQUFDO0FBQ2xDLHdGQUF3RjtBQUN4RixNQUFNLHFCQUFxQixHQUFHLENBQUMsQ0FBQztBQUNoQyx5RkFBeUY7QUFDekYsTUFBTSxlQUFlLEdBQUcsQ0FBQyxDQUFDO0FBQzFCLG9GQUFvRjtBQUNwRixNQUFNLDhCQUE4QixHQUFHLENBQUMsQ0FBQztBQUV6QyxJQUFJLE9BQU8sR0FBeUQsSUFBSSxDQUFDO0FBQ3pFLEtBQUssVUFBVSxTQUFTO0lBQ3RCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQztZQUFDLE9BQU8sR0FBRyxDQUFDLE1BQU0sTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFBQyxDQUFDO1FBQ2pFLE1BQU0sQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUM7QUFDRCxNQUFNLE1BQU0sR0FBRztJQUNiLElBQUksRUFBRSxLQUFLLEVBQUUsR0FB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QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTdGFsZSBwcm9jZXNzIGRldGVjdGlvbiBhbmQgcmVjb3ZlcnkgKCMxODUwKS5cbiAqXG4gKiBGaW5kcyBhbmQga2lsbHMgem9tYmllIERvbGxob3VzZU1DUCBwcm9jZXNzZXMgdGhhdCBzcXVhdCBvbiB0aGUgY29uc29sZVxuICogcG9ydCBhZnRlciB0aGVpciBzZXNzaW9uIGhhcyBlbmRlZC4gVXNlZCBieSBiaW5kQW5kTGlzdGVuIGluIHNlcnZlci50c1xuICogd2hlbiBFQUREUklOVVNFIG9jY3Vycy5cbiAqXG4gKiBFeHRyYWN0ZWQgdG8gYSBzdGFuZGFsb25lIG1vZHVsZSBzbyBpdCBjYW4gYmUgdGVzdGVkIHdpdGhvdXQgaW1wb3J0aW5nXG4gKiB0aGUgZnVsbCBFeHByZXNzIHNlcnZlciBhbmQgaXRzIGRlcGVuZGVuY3kgY2hhaW4uXG4gKi9cblxuaW1wb3J0IHsgVW5pY29kZVZhbGlkYXRvciB9IGZyb20gJy4uLy4uL3NlY3VyaXR5L3ZhbGlkYXRvcnMvdW5pY29kZVZhbGlkYXRvci5qcyc7XG5cbi8vIFVzZSBsYXp5IGltcG9ydCBmb3IgbG9nZ2VyIHRvIGF2b2lkIHB1bGxpbmcgaW4gdGhlIGZ1bGwgZW52LnRzL2NvbmZpZyBjaGFpblxuLy8gYXQgbW9kdWxlIGxvYWQgdGltZS4gVGhpcyBrZWVwcyB0aGUgbW9kdWxlIGluZGVwZW5kZW50bHkgdGVzdGFibGUuXG4vKiogVGltZW91dCBmb3IgbHNvZi9mdXNlci9wcyBzeXN0ZW0gY2FsbHMgKG1zKSAqL1xuY29uc3QgQ09NTUFORF9USU1FT1VUX01TID0gMTAwMDtcbi8qKiBQb2xsaW5nIGludGVydmFsIHdoZW4gd2FpdGluZyBmb3IgU0lHVEVSTSB0byB0YWtlIGVmZmVjdCAobXMpICovXG5jb25zdCBTSUdURVJNX1BPTExfTVMgPSAzMDA7XG4vKiogTnVtYmVyIG9mIHBvbGxzIGJlZm9yZSBlc2NhbGF0aW5nIHRvIFNJR0tJTEwgKi9cbmNvbnN0IEtJTExfUE9MTF9DT1VOVCA9IDEwO1xuLyoqIFdhaXQgYWZ0ZXIgU0lHS0lMTCBiZWZvcmUgcmV0dXJuaW5nIChtcykgKi9cbmNvbnN0IFNJR0tJTExfV0FJVF9NUyA9IDUwMDtcbi8qKiBXYWl0IGJldHdlZW4gbG9jayBmaWxlIHJlYWRzIGZvciBUT0NUT1UgbWl0aWdhdGlvbiAobXMpICovXG5jb25zdCBMT0NLX1JFQ0hFQ0tfREVMQVlfTVMgPSA1MDA7XG4vKiogTnVtYmVyIG9mIGxvY2stZmlsZSBjaGVja3MgYmVmb3JlIGRlY2lkaW5nIHRoZSBwb3J0IGhvbGRlciBpcyBub3QgYSBmcmVzaCBsZWFkZXIuICovXG5jb25zdCBMT0NLX1JFQ0hFQ0tfQVRURU1QVFMgPSAyO1xuLyoqIFBJRCB1c2VkIGJ5IHRoZSBPUyBpbml0L2xhdW5jaGQgcHJvY2VzczsgZGlyZWN0IGNoaWxkcmVuIGFyZSBlZmZlY3RpdmVseSBvcnBoYW5lZC4gKi9cbmNvbnN0IFJPT1RfUEFSRU5UX1BJRCA9IDE7XG4vKiogTnVtYmVyIG9mIGBwc2AgY29sdW1ucyByZXF1ZXN0ZWQgYnkgaW5zcGVjdFByb2Nlc3M6IHVzZXIsIHBpZCwgcHBpZCwgY29tbWFuZC4gKi9cbmNvbnN0IFBST0NFU1NfSU5TUEVDVElPTl9GSUVMRF9DT1VOVCA9IDQ7XG5cbmxldCBfbG9nZ2VyOiB0eXBlb2YgaW1wb3J0KCcuLi8uLi91dGlscy9sb2dnZXIuanMnKS5sb2dnZXIgfCBudWxsID0gbnVsbDtcbmFzeW5jIGZ1bmN0aW9uIGdldExvZ2dlcigpIHtcbiAgaWYgKCFfbG9nZ2VyKSB7XG4gICAgdHJ5IHsgX2xvZ2dlciA9IChhd2FpdCBpbXBvcnQoJy4uLy4uL3V0aWxzL2xvZ2dlci5qcycpKS5sb2dnZXI7IH1cbiAgICBjYXRjaCB7IC8qIGZhbGxiYWNrIGJlbG93ICovIH1cbiAgfVxuICByZXR1cm4gX2xvZ2dlcjtcbn1cbmNvbnN0IGxvZ2dlciA9IHtcbiAgd2FybjogYXN5bmMgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICAgIGNvbnN0IGwgPSBhd2FpdCBnZXRMb2dnZXIoKTtcbiAgICBpZiAobCkgbC53YXJuKGFyZ3NbMF0gYXMgc3RyaW5nLCBhcmdzWzFdKTtcbiAgICBlbHNlIGNvbnNvbGUuZXJyb3IoJ1tXQVJOXScsIC4uLmFyZ3MpO1xuICB9LFxuICBpbmZvOiBhc3luYyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgY29uc3QgbCA9IGF3YWl0IGdldExvZ2dlcigpO1xuICAgIGlmIChsKSBsLmluZm8oYXJnc1swXSBhcyBzdHJpbmcsIGFyZ3NbMV0pO1xuICAgIGVsc2UgY29uc29sZS5lcnJvcignW0lORk9dJywgLi4uYXJncyk7XG4gIH0sXG4gIGRlYnVnOiBhc3luYyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgY29uc3QgbCA9IGF3YWl0IGdldExvZ2dlcigpO1xuICAgIGlmIChsKSBsLmRlYnVnKGFyZ3NbMF0gYXMgc3RyaW5nLCBhcmdzWzFdKTtcbiAgfSxcbn07XG5cbmNvbnN0IE1DUF9IT1NUX1BBUkVOVF9QQVRURVJOUyA9IFtcbiAgL0NsYXVkZVxcLmFwcFxcL0NvbnRlbnRzXFwvSGVscGVyc1xcL2Rpc2NsYWltZXIvaSxcbiAgL0NvZGV4XFwuYXBwXFwvQ29udGVudHNcXC9SZXNvdXJjZXNcXC9jb2RleCBhcHAtc2VydmVyL2ksXG4gIC9DdXJzb3JcXC5hcHBcXC8vaSxcbiAgL1dpbmRzdXJmXFwuYXBwXFwvL2ksXG5dO1xuXG5pbnRlcmZhY2UgUHJvY2Vzc0luc3BlY3Rpb24ge1xuICB1c2VyOiBzdHJpbmc7XG4gIHBpZDogbnVtYmVyO1xuICBwYXJlbnRQaWQ6IG51bWJlcjtcbiAgY29tbWFuZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEtpbGxTdGFsZVByb2Nlc3NPdXRjb21lIHtcbiAga2lsbGVkOiBib29sZWFuO1xuICByZWFzb246XG4gICAgfCAnaW5zcGVjdF9mYWlsZWQnXG4gICAgfCAnZGlmZmVyZW50X3VzZXInXG4gICAgfCAnbm90X2RvbGxob3VzZV9wcm9jZXNzJ1xuICAgIHwgJ2FjdGl2ZV9ob3N0X3BhcmVudCdcbiAgICB8ICd0ZXJtaW5hdGVkJ1xuICAgIHwgJ2FscmVhZHlfZGVhZCdcbiAgICB8ICdzdGlsbF9hbGl2ZSdcbiAgICB8ICdzaWduYWxfZmFpbGVkJztcbiAgcGlkOiBudW1iZXI7XG4gIHBhcmVudFBpZD86IG51bWJlcjtcbiAgY29tbWFuZD86IHN0cmluZztcbiAgcGFyZW50Q29tbWFuZD86IHN0cmluZztcbiAgZGV0YWlsPzogc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSZWNvZ25pemVkTWNwSG9zdFBhcmVudChjb21tYW5kOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3Qgbm9ybWFsaXplZENvbW1hbmQgPSBVbmljb2RlVmFsaWRhdG9yLm5vcm1hbGl6ZShjb21tYW5kKS5ub3JtYWxpemVkQ29udGVudDtcbiAgcmV0dXJuIE1DUF9IT1NUX1BBUkVOVF9QQVRURVJOUy5zb21lKChwYXR0ZXJuKSA9PiBwYXR0ZXJuLnRlc3Qobm9ybWFsaXplZENvbW1hbmQpKTtcbn1cblxuZnVuY3Rpb24gaXNEb2xsaG91c2VQcm9jZXNzQ29tbWFuZChjbWRMaW5lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3Qgbm9ybWFsaXplZENvbW1hbmQgPSBVbmljb2RlVmFsaWRhdG9yLm5vcm1hbGl6ZShjbWRMaW5lKS5ub3JtYWxpemVkQ29udGVudDtcbiAgY29uc3QgaXNEb2xsaG91c2VCaW4gPSAvKD86XnxcXC8pZG9sbGhvdXNlbWNwKD86XFxzfCQpLy50ZXN0KG5vcm1hbGl6ZWRDb21tYW5kKSB8fFxuICAgIG5vcm1hbGl6ZWRDb21tYW5kLmluY2x1ZGVzKCcuYmluL2RvbGxob3VzZW1jcCcpO1xuICBjb25zdCBpc01jcFNlcnZlckJpbiA9IG5vcm1hbGl6ZWRDb21tYW5kLmluY2x1ZGVzKCcuYmluL21jcC1zZXJ2ZXInKSB8fFxuICAgIC8oPzpkb2xsaG91c2VtY3B8bWNwLXNlcnZlcilbL1xcXFxdZGlzdFsvXFxcXF1pbmRleFxcLmpzLy50ZXN0KG5vcm1hbGl6ZWRDb21tYW5kKTtcbiAgcmV0dXJuIGlzRG9sbGhvdXNlQmluIHx8IGlzTWNwU2VydmVyQmluO1xufVxuXG5mdW5jdGlvbiBwYXJzZVBpZFRva2VuKHZhbHVlOiBzdHJpbmcpOiBudW1iZXIgfCBudWxsIHtcbiAgaWYgKCF2YWx1ZSkgcmV0dXJuIG51bGw7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjb2RlUG9pbnQgPSB2YWx1ZS5jb2RlUG9pbnRBdChpKTtcbiAgICBpZiAoY29kZVBvaW50ID09PSB1bmRlZmluZWQgfHwgY29kZVBvaW50IDwgNDggfHwgY29kZVBvaW50ID4gNTcpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHBhcnNlZCA9IE51bWJlci5wYXJzZUludCh2YWx1ZSwgMTApO1xuICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKHBhcnNlZCkgfHwgcGFyc2VkIDwgUk9PVF9QQVJFTlRfUElEKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuZnVuY3Rpb24gaXNXaGl0ZXNwYWNlQ2hhcih2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiB2YWx1ZSA9PT0gJyAnIHx8IHZhbHVlID09PSAnXFx0JyB8fCB2YWx1ZSA9PT0gJ1xcbicgfHwgdmFsdWUgPT09ICdcXHInIHx8IHZhbHVlID09PSAnXFxmJyB8fCB2YWx1ZSA9PT0gJ1xcdic7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkS2lsbE91dGNvbWUoXG4gIGtpbGxlZDogYm9vbGVhbixcbiAgcmVhc29uOiBLaWxsU3RhbGVQcm9jZXNzT3V0Y29tZVsncmVhc29uJ10sXG4gIHByb2Nlc3NJbmZvOiBQcm9jZXNzSW5zcGVjdGlvbixcbiAgcGFyZW50Q29tbWFuZD86IHN0cmluZyxcbiAgZGV0YWlsPzogc3RyaW5nLFxuKTogS2lsbFN0YWxlUHJvY2Vzc091dGNvbWUge1xuICByZXR1cm4ge1xuICAgIGtpbGxlZCxcbiAgICByZWFzb24sXG4gICAgcGlkOiBwcm9jZXNzSW5mby5waWQsXG4gICAgcGFyZW50UGlkOiBwcm9jZXNzSW5mby5wYXJlbnRQaWQsXG4gICAgY29tbWFuZDogcHJvY2Vzc0luZm8uY29tbWFuZCxcbiAgICBwYXJlbnRDb21tYW5kLFxuICAgIC4uLihkZXRhaWwgPyB7IGRldGFpbCB9IDoge30pLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRLaWxsR3VhcmRGYWlsdXJlKFxuICBwcm9jZXNzSW5mbzogUHJvY2Vzc0luc3BlY3Rpb24sXG4gIHBvcnQ6IG51bWJlcixcbik6IFByb21pc2U8S2lsbFN0YWxlUHJvY2Vzc091dGNvbWUgfCBudWxsPiB7XG4gIGNvbnN0IGN1cnJlbnRVc2VyID0gKGF3YWl0IGltcG9ydCgnbm9kZTpvcycpKS51c2VySW5mbygpLnVzZXJuYW1lO1xuICBpZiAocHJvY2Vzc0luZm8udXNlciAhPT0gY3VycmVudFVzZXIpIHtcbiAgICBhd2FpdCBsb2dnZXIud2FybihgW1dlYlVJXSBQb3J0ICR7cG9ydH0gaGVsZCBieSBkaWZmZXJlbnQgdXNlciAocGlkICR7cHJvY2Vzc0luZm8ucGlkfSkg4oCUIG5vdCBraWxsaW5nYCk7XG4gICAgcmV0dXJuIGJ1aWxkS2lsbE91dGNvbWUoZmFsc2UsICdkaWZmZXJlbnRfdXNlcicsIHByb2Nlc3NJbmZvKTtcbiAgfVxuXG4gIGlmICghaXNEb2xsaG91c2VQcm9jZXNzQ29tbWFuZChwcm9jZXNzSW5mby5jb21tYW5kKSkge1xuICAgIGF3YWl0IGxvZ2dlci53YXJuKGBbV2ViVUldIFBvcnQgJHtwb3J0fSBoZWxkIGJ5IG5vbi1Eb2xsaG91c2VNQ1AgcHJvY2VzcyAocGlkICR7cHJvY2Vzc0luZm8ucGlkfSkg4oCUIG5vdCBraWxsaW5nYCwge1xuICAgICAgY21kTGluZTogcHJvY2Vzc0luZm8uY29tbWFuZCxcbiAgICB9KTtcbiAgICByZXR1cm4gYnVpbGRLaWxsT3V0Y29tZShmYWxzZSwgJ25vdF9kb2xsaG91c2VfcHJvY2VzcycsIHByb2Nlc3NJbmZvKTtcbiAgfVxuXG4gIGlmIChwcm9jZXNzSW5mby5wYXJlbnRQaWQgPD0gUk9PVF9QQVJFTlRfUElEIHx8ICFpc1BpZEFsaXZlKHByb2Nlc3NJbmZvLnBhcmVudFBpZCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHBhcmVudENvbW1hbmQgPSAoYXdhaXQgZ2V0UHJvY2Vzc0NvbW1hbmQocHJvY2Vzc0luZm8ucGFyZW50UGlkKSkgPz8gdW5kZWZpbmVkO1xuICBpZiAocGFyZW50Q29tbWFuZCAmJiBpc1JlY29nbml6ZWRNY3BIb3N0UGFyZW50KHBhcmVudENvbW1hbmQpKSB7XG4gICAgYXdhaXQgbG9nZ2VyLndhcm4oYFtXZWJVSV0gUG9ydCAke3BvcnR9IGhlbGQgYnkgYWN0aXZlIGNsaWVudC1iYWNrZWQgRG9sbGhvdXNlTUNQIHByb2Nlc3MgKHBpZCAke3Byb2Nlc3NJbmZvLnBpZH0pIOKAlCBub3Qga2lsbGluZ2AsIHtcbiAgICAgIGNtZExpbmU6IHByb2Nlc3NJbmZvLmNvbW1hbmQsXG4gICAgICBwYXJlbnRQaWQ6IHByb2Nlc3NJbmZvLnBhcmVudFBpZCxcbiAgICAgIHBhcmVudENvbW1hbmQsXG4gICAgfSk7XG4gICAgcmV0dXJuIGJ1aWxkS2lsbE91dGNvbWUoZmFsc2UsICdhY3RpdmVfaG9zdF9wYXJlbnQnLCBwcm9jZXNzSW5mbywgcGFyZW50Q29tbWFuZCk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdGVybWluYXRlUHJvY2VzcyhcbiAgcHJvY2Vzc0luZm86IFByb2Nlc3NJbnNwZWN0aW9uLFxuICBwb3J0OiBudW1iZXIsXG4gIHBhcmVudENvbW1hbmQ/OiBzdHJpbmcsXG4pOiBQcm9taXNlPEtpbGxTdGFsZVByb2Nlc3NPdXRjb21lPiB7XG4gIHByb2Nlc3Mua2lsbChwcm9jZXNzSW5mby5waWQsICdTSUdURVJNJyk7XG4gIGxvZ2dlci53YXJuKGBbV2ViVUldIFNlbnQgU0lHVEVSTSB0byBzdGFsZSBwcm9jZXNzICR7cHJvY2Vzc0luZm8ucGlkfSBvbiBwb3J0ICR7cG9ydH1gLCB7XG4gICAgY21kTGluZTogcHJvY2Vzc0luZm8uY29tbWFuZCxcbiAgICBwYXJlbnRQaWQ6IHByb2Nlc3NJbmZvLnBhcmVudFBpZCxcbiAgICBwYXJlbnRDb21tYW5kLFxuICB9KTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IEtJTExfUE9MTF9DT1VOVDsgaSsrKSB7XG4gICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIFNJR1RFUk1fUE9MTF9NUykpO1xuICAgIGlmICghaXNQaWRBbGl2ZShwcm9jZXNzSW5mby5waWQpKSB7XG4gICAgICByZXR1cm4gYnVpbGRLaWxsT3V0Y29tZSh0cnVlLCAndGVybWluYXRlZCcsIHByb2Nlc3NJbmZvLCBwYXJlbnRDb21tYW5kKTtcbiAgICB9XG4gIH1cblxuICBwcm9jZXNzLmtpbGwocHJvY2Vzc0luZm8ucGlkLCAnU0lHS0lMTCcpO1xuICBsb2dnZXIud2FybihgW1dlYlVJXSBTZW50IFNJR0tJTEwgdG8gc3RhbGUgcHJvY2VzcyAke3Byb2Nlc3NJbmZvLnBpZH0gb24gcG9ydCAke3BvcnR9YCk7XG4gIGF3YWl0IG5ldyBQcm9taXNlKHIgPT4gc2V0VGltZW91dChyLCBTSUdLSUxMX1dBSVRfTVMpKTtcbiAgcmV0dXJuIGlzUGlkQWxpdmUocHJvY2Vzc0luZm8ucGlkKVxuICAgID8gYnVpbGRLaWxsT3V0Y29tZShmYWxzZSwgJ3N0aWxsX2FsaXZlJywgcHJvY2Vzc0luZm8sIHBhcmVudENvbW1hbmQpXG4gICAgOiBidWlsZEtpbGxPdXRjb21lKHRydWUsICd0ZXJtaW5hdGVkJywgcHJvY2Vzc0luZm8sIHBhcmVudENvbW1hbmQpO1xufVxuXG5mdW5jdGlvbiBzcGxpdFByb2Nlc3NJbnNwZWN0aW9uRmllbGRzKGxpbmU6IHN0cmluZyk6IHN0cmluZ1tdIHwgbnVsbCB7XG4gIGNvbnN0IGZpZWxkczogc3RyaW5nW10gPSBbXTtcbiAgbGV0IGluZGV4ID0gMDtcbiAgY29uc3Qgbm9ybWFsaXplZExpbmUgPSBVbmljb2RlVmFsaWRhdG9yLm5vcm1hbGl6ZShsaW5lKS5ub3JtYWxpemVkQ29udGVudC50cmltKCk7XG5cbiAgd2hpbGUgKGluZGV4IDwgbm9ybWFsaXplZExpbmUubGVuZ3RoICYmIGZpZWxkcy5sZW5ndGggPCBQUk9DRVNTX0lOU1BFQ1RJT05fRklFTERfQ09VTlQgLSAxKSB7XG4gICAgd2hpbGUgKGluZGV4IDwgbm9ybWFsaXplZExpbmUubGVuZ3RoICYmIGlzV2hpdGVzcGFjZUNoYXIobm9ybWFsaXplZExpbmVbaW5kZXhdKSkge1xuICAgICAgaW5kZXgrKztcbiAgICB9XG4gICAgaWYgKGluZGV4ID49IG5vcm1hbGl6ZWRMaW5lLmxlbmd0aCkgYnJlYWs7XG5cbiAgICBjb25zdCBmaWVsZFN0YXJ0ID0gaW5kZXg7XG4gICAgd2hpbGUgKGluZGV4IDwgbm9ybWFsaXplZExpbmUubGVuZ3RoICYmICFpc1doaXRlc3BhY2VDaGFyKG5vcm1hbGl6ZWRMaW5lW2luZGV4XSkpIHtcbiAgICAgIGluZGV4Kys7XG4gICAgfVxuICAgIGZpZWxkcy5wdXNoKG5vcm1hbGl6ZWRMaW5lLnNsaWNlKGZpZWxkU3RhcnQsIGluZGV4KSk7XG4gIH1cblxuICB3aGlsZSAoaW5kZXggPCBub3JtYWxpemVkTGluZS5sZW5ndGggJiYgaXNXaGl0ZXNwYWNlQ2hhcihub3JtYWxpemVkTGluZVtpbmRleF0pKSB7XG4gICAgaW5kZXgrKztcbiAgfVxuICBpZiAoaW5kZXggPCBub3JtYWxpemVkTGluZS5sZW5ndGgpIHtcbiAgICBmaWVsZHMucHVzaChub3JtYWxpemVkTGluZS5zbGljZShpbmRleCkpO1xuICB9XG5cbiAgcmV0dXJuIGZpZWxkcy5sZW5ndGggPT09IFBST0NFU1NfSU5TUEVDVElPTl9GSUVMRF9DT1VOVCA/IGZpZWxkcyA6IG51bGw7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGluc3BlY3RQcm9jZXNzKHBpZDogbnVtYmVyKTogUHJvbWlzZTxQcm9jZXNzSW5zcGVjdGlvbiB8IG51bGw+IHtcbiAgY29uc3QgeyBleGVjRmlsZTogZXhlY0ZpbGVDYiB9ID0gYXdhaXQgaW1wb3J0KCdub2RlOmNoaWxkX3Byb2Nlc3MnKTtcbiAgY29uc3QgeyBwcm9taXNpZnkgfSA9IGF3YWl0IGltcG9ydCgnbm9kZTp1dGlsJyk7XG4gIGNvbnN0IGV4ZWNGaWxlQXN5bmMgPSBwcm9taXNpZnkoZXhlY0ZpbGVDYik7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB7IHN0ZG91dCB9ID0gYXdhaXQgZXhlY0ZpbGVBc3luYyhcbiAgICAgICdwcycsXG4gICAgICBbJy1wJywgU3RyaW5nKHBpZCksICctbycsICd1c2VyPSxwaWQ9LHBwaWQ9LGNvbW1hbmQ9J10sXG4gICAgICB7IHRpbWVvdXQ6IENPTU1BTkRfVElNRU9VVF9NUyB9LFxuICAgICk7XG4gICAgY29uc3QgZmllbGRzID0gc3BsaXRQcm9jZXNzSW5zcGVjdGlvbkZpZWxkcyhzdGRvdXQpO1xuICAgIGlmICghZmllbGRzKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBbdXNlciwgcGlkVG9rZW4sIHBhcmVudFBpZFRva2VuLCBjb21tYW5kXSA9IGZpZWxkcztcbiAgICBjb25zdCBwYXJzZWRQaWQgPSBwYXJzZVBpZFRva2VuKHBpZFRva2VuKTtcbiAgICBjb25zdCBwYXJzZWRQYXJlbnRQaWQgPSBwYXJzZVBpZFRva2VuKHBhcmVudFBpZFRva2VuKTtcbiAgICBpZiAocGFyc2VkUGlkID09PSBudWxsIHx8IHBhcnNlZFBhcmVudFBpZCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdXNlcjogVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUodXNlcikubm9ybWFsaXplZENvbnRlbnQsXG4gICAgICBwaWQ6IHBhcnNlZFBpZCxcbiAgICAgIHBhcmVudFBpZDogcGFyc2VkUGFyZW50UGlkLFxuICAgICAgY29tbWFuZDogVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUoY29tbWFuZCkubm9ybWFsaXplZENvbnRlbnQsXG4gICAgfTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0UHJvY2Vzc0NvbW1hbmQocGlkOiBudW1iZXIpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgY29uc3QgeyBleGVjRmlsZTogZXhlY0ZpbGVDYiB9ID0gYXdhaXQgaW1wb3J0KCdub2RlOmNoaWxkX3Byb2Nlc3MnKTtcbiAgY29uc3QgeyBwcm9taXNpZnkgfSA9IGF3YWl0IGltcG9ydCgnbm9kZTp1dGlsJyk7XG4gIGNvbnN0IGV4ZWNGaWxlQXN5bmMgPSBwcm9taXNpZnkoZXhlY0ZpbGVDYik7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB7IHN0ZG91dCB9ID0gYXdhaXQgZXhlY0ZpbGVBc3luYygncHMnLCBbJy1wJywgU3RyaW5nKHBpZCksICctbycsICdjb21tYW5kPSddLCB7IHRpbWVvdXQ6IENPTU1BTkRfVElNRU9VVF9NUyB9KTtcbiAgICBjb25zdCBub3JtYWxpemVkID0gVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUoc3Rkb3V0KS5ub3JtYWxpemVkQ29udGVudC50cmltKCk7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZWQgfHwgbnVsbDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNQaWRBbGl2ZShwaWQ6IG51bWJlcik6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIHByb2Nlc3Mua2lsbChwaWQsIDApO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBGaW5kIHRoZSBQSUQgb2YgdGhlIHByb2Nlc3MgbGlzdGVuaW5nIG9uIGEgZ2l2ZW4gcG9ydC5cbiAqIFVzZXMgbHNvZiBvbiBtYWNPUy9MaW51eC4gUmV0dXJucyBudWxsIGlmIG5vdCBmb3VuZCBvciBvbiBlcnJvci5cbiAqXG4gKiBUaW1lb3V0OiAxcyDigJQgbHNvZiBvbiBsb2NhbGhvc3QgaXMgdHlwaWNhbGx5IDwxMDBtcy4gVGhlIDFzIGNlaWxpbmdcbiAqIGhhbmRsZXMgc2xvdyBORlMtbW91bnRlZCAvZGV2L2ZkIG9yIG92ZXJsb2FkZWQgQ0kgcnVubmVycyB3aXRob3V0XG4gKiBkZWxheWluZyBzdGFydHVwIG5vdGljZWFibHkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmaW5kUGlkT25Qb3J0KHBvcnQ6IG51bWJlcik6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICBjb25zdCB7IGV4ZWNGaWxlOiBleGVjRmlsZUNiIH0gPSBhd2FpdCBpbXBvcnQoJ25vZGU6Y2hpbGRfcHJvY2VzcycpO1xuICBjb25zdCB7IHByb21pc2lmeSB9ID0gYXdhaXQgaW1wb3J0KCdub2RlOnV0aWwnKTtcbiAgY29uc3QgZXhlY0ZpbGVBc3luYyA9IHByb21pc2lmeShleGVjRmlsZUNiKTtcblxuICAvLyBUcnkgbHNvZiBmaXJzdCAobWFjT1MgKyBtb3N0IExpbnV4KSwgZmFsbCBiYWNrIHRvIGZ1c2VyIChtaW5pbWFsIExpbnV4L0RvY2tlcilcbiAgZm9yIChjb25zdCBjbWQgb2YgW1xuICAgIHsgYmluOiAnbHNvZicsIGFyZ3M6IFsnLXRpJywgYDoke3BvcnR9YF0gfSxcbiAgICB7IGJpbjogJ2Z1c2VyJywgYXJnczogW2Ake3BvcnR9L3RjcGBdIH0sXG4gIF0pIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBzdGRvdXQsIHN0ZGVyciB9ID0gYXdhaXQgZXhlY0ZpbGVBc3luYyhjbWQuYmluLCBjbWQuYXJncywgeyB0aW1lb3V0OiBDT01NQU5EX1RJTUVPVVRfTVMgfSk7XG4gICAgICAvLyBmdXNlciBvdXRwdXRzIHRvIHN0ZGVyciBvbiBzb21lIHN5c3RlbXNcbiAgICAgIGNvbnN0IG91dHB1dCA9IChzdGRvdXQgfHwgc3RkZXJyIHx8ICcnKS50cmltKCk7XG4gICAgICBjb25zdCBwaWRzID0gb3V0cHV0XG4gICAgICAgIC5zcGxpdCgvXFxzKy8pXG4gICAgICAgIC5tYXAoKHRva2VuKSA9PiBwYXJzZVBpZFRva2VuKHRva2VuKSlcbiAgICAgICAgLmZpbHRlcigocGlkKTogcGlkIGlzIG51bWJlciA9PiBwaWQgIT09IG51bGwpO1xuICAgICAgY29uc3Qgb3RoZXJQaWQgPSBwaWRzLmZpbmQocCA9PiBwICE9PSBwcm9jZXNzLnBpZCk7XG4gICAgICBpZiAob3RoZXJQaWQpIHJldHVybiBvdGhlclBpZDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBjb21tYW5kIG5vdCBmb3VuZCBvciBubyByZXN1bHRzIOKAlCB0cnkgbmV4dFxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBLaWxsIGEgc3RhbGUgcHJvY2VzcyBob2xkaW5nIGEgcG9ydC4gU2VuZHMgU0lHVEVSTSwgd2FpdHMgYnJpZWZseSxcbiAqIHRoZW4gU0lHS0lMTCBpZiBzdGlsbCBhbGl2ZS4gT25seSBraWxscyBEb2xsaG91c2VNQ1AgcHJvY2Vzc2VzXG4gKiAodmVyaWZpZWQgYnkgY2hlY2tpbmcgdGhlIGNvbW1hbmQgbGluZSBhbmQgdXNlciBvd25lcnNoaXApLlxuICpcbiAqIFRpbWVvdXQ6IDFzIGZvciBwcyB2ZXJpZmljYXRpb24uIEtpbGwgd2FpdDogMzAwbXMgw5cgMTAgcG9sbHMgPSAzc1xuICogYmVmb3JlIGVzY2FsYXRpbmcgdG8gU0lHS0lMTC4gVG90YWwgd29yc3QgY2FzZTogfjRzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24ga2lsbFN0YWxlUHJvY2VzcyhwaWQ6IG51bWJlciwgcG9ydDogbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IG91dGNvbWUgPSBhd2FpdCBraWxsU3RhbGVQcm9jZXNzRGV0YWlsZWQocGlkLCBwb3J0KTtcbiAgcmV0dXJuIG91dGNvbWUua2lsbGVkO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24ga2lsbFN0YWxlUHJvY2Vzc0RldGFpbGVkKHBpZDogbnVtYmVyLCBwb3J0OiBudW1iZXIpOiBQcm9taXNlPEtpbGxTdGFsZVByb2Nlc3NPdXRjb21lPiB7XG4gIGNvbnN0IHByb2Nlc3NJbmZvID0gYXdhaXQgaW5zcGVjdFByb2Nlc3MocGlkKTtcbiAgaWYgKCFwcm9jZXNzSW5mbykge1xuICAgIGF3YWl0IGxvZ2dlci5kZWJ1ZyhgW1dlYlVJXSBDYW5ub3QgdmVyaWZ5IHByb2Nlc3MgJHtwaWR9IOKAlCBza2lwcGluZyBraWxsYCk7XG4gICAgcmV0dXJuIHsga2lsbGVkOiBmYWxzZSwgcmVhc29uOiAnaW5zcGVjdF9mYWlsZWQnLCBwaWQgfTtcbiAgfVxuXG4gIGNvbnN0IGd1YXJkRmFpbHVyZSA9IGF3YWl0IGdldEtpbGxHdWFyZEZhaWx1cmUocHJvY2Vzc0luZm8sIHBvcnQpO1xuICBpZiAoZ3VhcmRGYWlsdXJlKSB7XG4gICAgcmV0dXJuIGd1YXJkRmFpbHVyZTtcbiAgfVxuICBjb25zdCBwYXJlbnRDb21tYW5kID0gcHJvY2Vzc0luZm8ucGFyZW50UGlkID4gUk9PVF9QQVJFTlRfUElEXG4gICAgPyAoYXdhaXQgZ2V0UHJvY2Vzc0NvbW1hbmQocHJvY2Vzc0luZm8ucGFyZW50UGlkKSkgPz8gdW5kZWZpbmVkXG4gICAgOiB1bmRlZmluZWQ7XG5cbiAgYXdhaXQgbG9nZ2VyLmRlYnVnKGBbV2ViVUldIFZlcmlmaWVkIHN0YWxlIHByb2Nlc3MgJHtwaWR9IGlzIERvbGxob3VzZU1DUGAsIHsgY21kTGluZTogcHJvY2Vzc0luZm8uY29tbWFuZCwgcGFyZW50UGlkOiBwcm9jZXNzSW5mby5wYXJlbnRQaWQsIHBhcmVudENvbW1hbmQgfSk7XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgdGVybWluYXRlUHJvY2Vzcyhwcm9jZXNzSW5mbywgcG9ydCwgcGFyZW50Q29tbWFuZCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGlmICghaXNQaWRBbGl2ZShwaWQpKSB7XG4gICAgICByZXR1cm4gYnVpbGRLaWxsT3V0Y29tZSh0cnVlLCAnYWxyZWFkeV9kZWFkJywgcHJvY2Vzc0luZm8sIHBhcmVudENvbW1hbmQpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRLaWxsT3V0Y29tZShmYWxzZSwgJ3NpZ25hbF9mYWlsZWQnLCBwcm9jZXNzSW5mbywgcGFyZW50Q29tbWFuZCwgZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpKTtcbiAgfVxufVxuXG4vKipcbiAqIERldGVjdCBhbmQgcmVjb3ZlciBmcm9tIGEgc3RhbGUgcHJvY2VzcyBzcXVhdHRpbmcgb24gdGhlIHBvcnQuXG4gKiBDb21wYXJlcyB0aGUgcG9ydCBob2xkZXIncyBQSUQgYWdhaW5zdCB0aGUgbGVhZGVyIGxvY2sgZmlsZSB0byBkZXRlcm1pbmVcbiAqIGlmIGl0J3MgYSBzcXVhdHRlci4gUmV0dXJucyB0cnVlIGlmIHRoZSBzcXVhdHRlciB3YXMga2lsbGVkLlxuICpcbiAqIFRpbWVvdXRzOiBsc29mIDFzLCBwcyAxcywgU0lHVEVSTSB3YWl0IDNzIOKAlCBtYXggfjVzIHRvdGFsLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVjb3ZlclN0YWxlUG9ydChwb3J0OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3Qgc3RhbGVQaWQgPSBhd2FpdCBmaW5kUGlkT25Qb3J0KHBvcnQpO1xuICBpZiAoIXN0YWxlUGlkKSByZXR1cm4gZmFsc2U7XG5cbiAgLy8gVE9DVE9VIG1pdGlnYXRpb246IGEgbmV3IHByb2Nlc3MgbWF5IGhhdmUganVzdCBib3VuZCB0aGUgcG9ydCBidXQgbm90IHlldFxuICAvLyB3cml0dGVuIGl0cyBsb2NrIGZpbGUuIFJlYWQgdGhlIGxvY2ssIHBhdXNlLCByZS1yZWFkLiBJZiB0aGUgc2Vjb25kIHJlYWRcbiAgLy8gbm93IG1hdGNoZXMgdGhlIHBvcnQgaG9sZGVyLCBpdCdzIGEgZnJlc2ggbGVhZGVyIOKAlCBkb24ndCBraWxsLlxuICBjb25zdCB7IHJlYWRMZWFkZXJMb2NrIH0gPSBhd2FpdCBpbXBvcnQoJy4vTGVhZGVyRWxlY3Rpb24uanMnKTtcbiAgZm9yIChsZXQgY2hlY2sgPSAwOyBjaGVjayA8IExPQ0tfUkVDSEVDS19BVFRFTVBUUzsgY2hlY2srKykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBsb2NrID0gYXdhaXQgcmVhZExlYWRlckxvY2soKTtcbiAgICAgIGlmIChsb2NrPy5waWQgPT09IHN0YWxlUGlkICYmIGxvY2s/LnBvcnQgPT09IHBvcnQgJiYgbG9jay5waWQgIT09IHByb2Nlc3MucGlkKSB7XG4gICAgICAgIGF3YWl0IGxvZ2dlci53YXJuKGBbV2ViVUldIFBvcnQgJHtwb3J0fSBoZWxkIGJ5IGxlZ2l0aW1hdGUgbGVhZGVyIChwaWQgJHtzdGFsZVBpZH0pIOKAlCBub3Qga2lsbGluZ2ApO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBDYW4ndCByZWFkIGxvY2sgZmlsZSDigJQgY29udGludWUgdG8gbmV4dCBjaGVjayBvciBraWxsXG4gICAgfVxuICAgIGlmIChjaGVjayA8IExPQ0tfUkVDSEVDS19BVFRFTVBUUyAtIDEpIHtcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHIgPT4gc2V0VGltZW91dChyLCBMT0NLX1JFQ0hFQ0tfREVMQVlfTVMpKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBvdXRjb21lID0gYXdhaXQga2lsbFN0YWxlUHJvY2Vzc0RldGFpbGVkKHN0YWxlUGlkLCBwb3J0KTtcbiAgaWYgKG91dGNvbWUua2lsbGVkKSB7XG4gICAgbG9nZ2VyLmluZm8oYFtXZWJVSV0gU3RhbGUgcHJvY2VzcyAke3N0YWxlUGlkfSByZW1vdmVkIGZyb20gcG9ydCAke3BvcnR9YCk7XG4gICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIFNJR0tJTExfV0FJVF9NUykpOyAvLyBicmllZiBwYXVzZSBmb3IgcG9ydCByZWxlYXNlXG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgbG9nZ2VyLmRlYnVnKGBbV2ViVUldIFN0YWxlLXBvcnQgcmVjb3Zlcnkgc2tpcHBlZCBmb3IgcGlkICR7c3RhbGVQaWR9YCwge1xuICAgICAgcmVhc29uOiBvdXRjb21lLnJlYXNvbixcbiAgICAgIHBhcmVudFBpZDogb3V0Y29tZS5wYXJlbnRQaWQsXG4gICAgICBwYXJlbnRDb21tYW5kOiBvdXRjb21lLnBhcmVudENvbW1hbmQsXG4gICAgICBkZXRhaWw6IG91dGNvbWUuZGV0YWlsLFxuICAgIH0pO1xuICB9XG4gIHJldHVybiBvdXRjb21lLmtpbGxlZDtcbn1cbiJdfQ==
@@ -17,7 +17,8 @@ import type { MetricSnapshot } from '../../metrics/types.js';
17
17
  import type { MemoryLogSink } from '../../logging/sinks/MemoryLogSink.js';
18
18
  import type { MemoryMetricsSink } from '../../metrics/sinks/MemoryMetricsSink.js';
19
19
  import { logger } from '../../utils/logger.js';
20
- import { detectLegacyLeader, type ElectionResult } from './LeaderElection.js';
20
+ import { detectLegacyLeader, readLeaderLock, deleteLeaderLock, type ElectionResult, type ConsoleLeaderInfo } from './LeaderElection.js';
21
+ import { findPidOnPort } from './StaleProcessRecovery.js';
21
22
  /**
22
23
  * Options for starting the unified console.
23
24
  */
@@ -79,6 +80,25 @@ export interface UnifiedConsoleResult {
79
80
  * threw. Exposed so tests can assert the full result shape.
80
81
  */
81
82
  export declare function warnIfLegacyConsolePresent(currentPort: number, detect?: typeof detectLegacyLeader, log?: typeof logger): Promise<Awaited<ReturnType<typeof detectLegacyLeader>> | null>;
83
+ export interface PortLeaderDiscovery {
84
+ leaderInfo: ConsoleLeaderInfo | null;
85
+ ownerPid: number | null;
86
+ source: 'api' | 'lock' | 'synthetic' | 'none';
87
+ }
88
+ export interface BindFailureRecoveryResult extends PortLeaderDiscovery {
89
+ lockCleanupAttempted: boolean;
90
+ lockCleanupPerformed: boolean;
91
+ }
92
+ interface DiscoveryDependencies {
93
+ fetchImpl?: typeof fetch;
94
+ findPidOnPortImpl?: typeof findPidOnPort;
95
+ readLeaderLockImpl?: typeof readLeaderLock;
96
+ }
97
+ export declare function discoverLeaderServingPort(port: number, authToken: string | null, deps?: DiscoveryDependencies): Promise<PortLeaderDiscovery>;
98
+ interface BindFailureRecoveryDependencies extends DiscoveryDependencies {
99
+ deleteLeaderLockImpl?: typeof deleteLeaderLock;
100
+ }
101
+ export declare function recoverLeaderBindFailure(provisionalLeader: ConsoleLeaderInfo, port: number, authToken: string | null, deps?: BindFailureRecoveryDependencies): Promise<BindFailureRecoveryResult>;
82
102
  /**
83
103
  * Start the unified web console.
84
104
  *
@@ -86,4 +106,5 @@ export declare function warnIfLegacyConsolePresent(currentPort: number, detect?:
86
106
  * or sets up event forwarding (follower).
87
107
  */
88
108
  export declare function startUnifiedConsole(options: UnifiedConsoleOptions): Promise<UnifiedConsoleResult>;
109
+ export {};
89
110
  //# sourceMappingURL=UnifiedConsole.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UnifiedConsole.d.ts","sourceRoot":"","sources":["../../../src/web/console/UnifiedConsole.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAML,kBAAkB,EAClB,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAmB7B;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,UAAU,EAAE,aAAa,CAAC;IAC1B,0BAA0B;IAC1B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,qFAAqF;IACrF,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,0DAA0D;IAC1D,eAAe,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;QAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,KAAK,IAAI,CAAC;IACzH,8DAA8D;IAC9D,iBAAiB,EAAE,CAAC,SAAS,EAAE;QAAE,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;QAAC,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAA;KAAE,EAAE,WAAW,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACrL,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,0BAA0B,CAC9C,WAAW,EAAE,MAAM,EACnB,MAAM,GAAE,OAAO,kBAAuC,EACtD,GAAG,GAAE,OAAO,MAAe,GAC1B,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,GAAG,IAAI,CAAC,CAsBhE;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA8BvG"}
1
+ {"version":3,"file":"UnifiedConsole.d.ts","sourceRoot":"","sources":["../../../src/web/console/UnifiedConsole.ts"],"names":[],"mappings":"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"}