dsh-client-auto-continue 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js ADDED
@@ -0,0 +1,1197 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "dsh-client-auto-continue",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ "use strict";
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
12
+ var __export = (target, all) => {
13
+ for (var name in all)
14
+ __defProp(target, name, { get: all[name], enumerable: true });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
+
26
+ // src/client/index.ts
27
+ var index_exports = {};
28
+ __export(index_exports, {
29
+ apply: () => apply,
30
+ inject: () => inject
31
+ });
32
+ module.exports = __toCommonJS(index_exports);
33
+
34
+ // src/client/engine.ts
35
+ var DEFAULT_CONFIG = {
36
+ continueText: "继续",
37
+ graceMs: 3e3,
38
+ cooldownMs: 2e4,
39
+ maxConsecutive: 3,
40
+ scanOnBoot: true,
41
+ scanLimit: 8,
42
+ freshMs: 15 * 60 * 1e3,
43
+ reconnectScanDelayMs: 5e3,
44
+ reconnectBackoffMs: 3e3,
45
+ verbose: true
46
+ };
47
+ function numberOr(value, fallback) {
48
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
49
+ }
50
+ function booleanOr(value, fallback) {
51
+ return typeof value === "boolean" ? value : fallback;
52
+ }
53
+ function resolveConfig(section) {
54
+ const value = section ?? {};
55
+ const text = typeof value.continueText === "string" && value.continueText.trim() !== "" ? value.continueText : DEFAULT_CONFIG.continueText;
56
+ return {
57
+ continueText: text,
58
+ graceMs: numberOr(value.graceMs, DEFAULT_CONFIG.graceMs),
59
+ cooldownMs: numberOr(value.cooldownMs, DEFAULT_CONFIG.cooldownMs),
60
+ maxConsecutive: Math.max(1, numberOr(value.maxConsecutive, DEFAULT_CONFIG.maxConsecutive)),
61
+ scanOnBoot: booleanOr(value.scanOnBoot, DEFAULT_CONFIG.scanOnBoot),
62
+ scanLimit: Math.max(1, numberOr(value.scanLimit, DEFAULT_CONFIG.scanLimit)),
63
+ freshMs: numberOr(value.freshMs, DEFAULT_CONFIG.freshMs),
64
+ reconnectScanDelayMs: numberOr(value.reconnectScanDelayMs, DEFAULT_CONFIG.reconnectScanDelayMs),
65
+ reconnectBackoffMs: numberOr(value.reconnectBackoffMs, DEFAULT_CONFIG.reconnectBackoffMs),
66
+ verbose: booleanOr(value.verbose, DEFAULT_CONFIG.verbose)
67
+ };
68
+ }
69
+ function isNonHumanReason(kind) {
70
+ return kind === "error" || kind === "interrupted" || kind === "max-tokens";
71
+ }
72
+ function sleep(ms) {
73
+ return new Promise((resolve) => setTimeout(resolve, ms));
74
+ }
75
+ function clientTimeZone() {
76
+ try {
77
+ return Intl.DateTimeFormat().resolvedOptions().timeZone || void 0;
78
+ } catch {
79
+ return void 0;
80
+ }
81
+ }
82
+ var lockPrefix = "dsh-auto-continue:";
83
+ var lockKey = (sessionId) => `${lockPrefix}lock:${sessionId}`;
84
+ var stampKey = (sessionId) => `${lockPrefix}last:${sessionId}`;
85
+ function claimSend(sessionId) {
86
+ try {
87
+ const token = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
88
+ localStorage.setItem(lockKey(sessionId), token);
89
+ return localStorage.getItem(lockKey(sessionId)) === token;
90
+ } catch {
91
+ return true;
92
+ }
93
+ }
94
+ function releaseSend(sessionId) {
95
+ try {
96
+ localStorage.removeItem(lockKey(sessionId));
97
+ } catch {
98
+ }
99
+ }
100
+ function readLastSend(sessionId) {
101
+ try {
102
+ return Number(localStorage.getItem(stampKey(sessionId)) ?? 0) || 0;
103
+ } catch {
104
+ return 0;
105
+ }
106
+ }
107
+ function writeLastSend(sessionId, at) {
108
+ try {
109
+ localStorage.setItem(stampKey(sessionId), String(at));
110
+ } catch {
111
+ }
112
+ }
113
+ var freshState = () => ({
114
+ consecutive: 0,
115
+ lastAutoAt: 0,
116
+ lastAttemptAt: 0,
117
+ lastSentText: "",
118
+ pendingTimer: void 0,
119
+ running: void 0,
120
+ queued: 0,
121
+ subagent: false
122
+ });
123
+ function isOurEcho(state, event) {
124
+ if (event.type !== "user/message") return false;
125
+ const message = event.data;
126
+ if (message.source.kind !== "user") return false;
127
+ if (state.lastSentText === "") return false;
128
+ if (Date.now() - state.lastAutoAt > 3e4) return false;
129
+ const text = message.content.filter((part) => part.type === "text").map((part) => part.text).join("");
130
+ return text === state.lastSentText;
131
+ }
132
+ async function pumpStream(open, onFrame, onReconnect, getBackoff, log, signal) {
133
+ let backoff = getBackoff();
134
+ while (!signal.aborted) {
135
+ let connected = false;
136
+ try {
137
+ for await (const envelope of open(signal)) {
138
+ connected = true;
139
+ onFrame(envelope.payload);
140
+ }
141
+ if (signal.aborted) return;
142
+ } catch (error) {
143
+ if (signal.aborted) return;
144
+ log(`stream error: ${error instanceof Error ? error.message : String(error)}`);
145
+ }
146
+ if (!connected) {
147
+ await sleep(backoff);
148
+ backoff = Math.min(backoff * 2, 15e3);
149
+ continue;
150
+ }
151
+ backoff = getBackoff();
152
+ onReconnect();
153
+ await sleep(backoff);
154
+ }
155
+ }
156
+ var AutoContinueRunner = class {
157
+ /**
158
+ * @param api - shared wire client (ctx.connection.api).
159
+ * @param getConfig - read the current resolved configuration (settings scope).
160
+ */
161
+ constructor(api, getConfig) {
162
+ this.api = api;
163
+ this.getConfig = getConfig;
164
+ this.states = /* @__PURE__ */ new Map();
165
+ this.muxAbort = new AbortController();
166
+ this.hostAbort = new AbortController();
167
+ this.disposed = false;
168
+ this.reconnectScans = 0;
169
+ const config = this.getConfig();
170
+ void this.runMux();
171
+ void this.runHost();
172
+ if (config.scanOnBoot) {
173
+ void this.bootScanLoop();
174
+ }
175
+ this.log(
176
+ `已启动(文本="${config.continueText}", 宽限 ${config.graceMs}ms, 冷却 ${config.cooldownMs}ms, 最多连续 ${config.maxConsecutive} 次)`
177
+ );
178
+ }
179
+ log(message) {
180
+ if (this.getConfig().verbose) console.info(`[auto-continue] ${message}`);
181
+ }
182
+ dispose() {
183
+ this.disposed = true;
184
+ this.muxAbort.abort();
185
+ this.hostAbort.abort();
186
+ for (const state of this.states.values()) {
187
+ if (state.pendingTimer !== void 0) clearTimeout(state.pendingTimer);
188
+ }
189
+ this.states.clear();
190
+ }
191
+ state(sessionId) {
192
+ let state = this.states.get(sessionId);
193
+ if (state === void 0) {
194
+ state = freshState();
195
+ this.states.set(sessionId, state);
196
+ }
197
+ return state;
198
+ }
199
+ runMux() {
200
+ return pumpStream(
201
+ (signal) => this.api.events.mux({}, signal),
202
+ (payload) => this.onMuxFrame(payload),
203
+ () => this.scheduleReconnectScan(),
204
+ () => this.getConfig().reconnectBackoffMs,
205
+ (m) => this.log(m),
206
+ this.muxAbort.signal
207
+ );
208
+ }
209
+ runHost() {
210
+ return pumpStream(
211
+ (signal) => this.api.events.host({}, signal),
212
+ (payload) => this.onHostFrame(payload),
213
+ () => this.scheduleReconnectScan(),
214
+ () => this.getConfig().reconnectBackoffMs,
215
+ (m) => this.log(m),
216
+ this.hostAbort.signal
217
+ );
218
+ }
219
+ // ---------- mux 帧 ----------
220
+ onMuxFrame(frame) {
221
+ switch (frame.type) {
222
+ case "session/event":
223
+ this.onSessionEvent(frame.sessionId, frame.event);
224
+ break;
225
+ case "session/queue":
226
+ this.state(frame.sessionId).queued = frame.items.length;
227
+ if (frame.items.length > 0) this.cancelPending(frame.sessionId, "出现排队消息");
228
+ break;
229
+ case "stream/error":
230
+ this.log(`mux stream/error: ${frame.error.code} ${frame.error.message}`);
231
+ break;
232
+ default:
233
+ break;
234
+ }
235
+ }
236
+ onSessionEvent(sessionId, event) {
237
+ const state = this.state(sessionId);
238
+ switch (event.type) {
239
+ case "turn/start":
240
+ state.running = true;
241
+ this.cancelPending(sessionId, "宿主自行开启新回合");
242
+ break;
243
+ case "turn/end": {
244
+ state.running = false;
245
+ this.cancelPending(sessionId, "收到新的 turn/end");
246
+ const reason = event.data.reason;
247
+ if (reason.kind === "completed") {
248
+ state.consecutive = 0;
249
+ } else if (reason.kind === "aborted") {
250
+ state.consecutive = 0;
251
+ } else if (reason.kind === "blocked") {
252
+ } else if (isNonHumanReason(reason.kind)) {
253
+ this.schedule(sessionId, `turn/end:${reason.kind}`);
254
+ }
255
+ break;
256
+ }
257
+ case "user/message":
258
+ if (isOurEcho(state, event)) break;
259
+ if (event.data.source.kind === "user") {
260
+ state.consecutive = 0;
261
+ this.cancelPending(sessionId, "用户手动发送消息");
262
+ }
263
+ break;
264
+ default:
265
+ break;
266
+ }
267
+ }
268
+ // ---------- host 帧 ----------
269
+ onHostFrame(frame) {
270
+ switch (frame.type) {
271
+ case "host/session-status":
272
+ this.state(frame.sessionId).running = frame.running;
273
+ if (frame.running) this.cancelPending(frame.sessionId, "宿主报告会话开始运行");
274
+ break;
275
+ case "host/session-added":
276
+ this.state(frame.sessionId).subagent = frame.parentSessionId !== void 0;
277
+ break;
278
+ case "host/agent-error":
279
+ if (this.state(frame.sessionId).subagent) break;
280
+ this.log(`host/agent-error(${frame.sessionId}): ${frame.message}`);
281
+ this.schedule(frame.sessionId, "host/agent-error");
282
+ break;
283
+ case "host/session-removed":
284
+ this.cancelPending(frame.sessionId, "会话已移除");
285
+ this.states.delete(frame.sessionId);
286
+ break;
287
+ default:
288
+ break;
289
+ }
290
+ }
291
+ // ---------- 调度 ----------
292
+ schedule(sessionId, reason) {
293
+ const state = this.state(sessionId);
294
+ const config = this.getConfig();
295
+ if (state.subagent) return;
296
+ if (state.pendingTimer !== void 0) return;
297
+ if (Date.now() - state.lastAttemptAt < config.cooldownMs) return;
298
+ if (state.consecutive >= config.maxConsecutive) {
299
+ this.log(
300
+ `跳过 ${sessionId}(${reason}): 已连续自动继续 ${state.consecutive} 次, 等待用户介入或成功回合`
301
+ );
302
+ return;
303
+ }
304
+ if (state.queued > 0) return;
305
+ const timer = setTimeout(() => {
306
+ if (state.pendingTimer !== timer) return;
307
+ state.pendingTimer = void 0;
308
+ void this.fire(sessionId, reason);
309
+ }, config.graceMs);
310
+ state.pendingTimer = timer;
311
+ this.log(
312
+ `检测到非人为中断 ${sessionId}(${reason}), ${config.graceMs}ms 后自动发送「${config.continueText}」`
313
+ );
314
+ }
315
+ cancelPending(sessionId, why) {
316
+ const state = this.state(sessionId);
317
+ if (state.pendingTimer === void 0) return;
318
+ clearTimeout(state.pendingTimer);
319
+ state.pendingTimer = void 0;
320
+ this.log(`取消 ${sessionId} 的自动继续(${why})`);
321
+ }
322
+ async fire(sessionId, reason) {
323
+ if (this.disposed) return;
324
+ const state = this.state(sessionId);
325
+ const config = this.getConfig();
326
+ if (state.running === void 0) {
327
+ const running = await this.runningViaList(sessionId);
328
+ if (running === void 0 || running) {
329
+ this.log(`跳过 ${sessionId}: 无法确认空闲(${running === void 0 ? "未知" : "运行中"})`);
330
+ return;
331
+ }
332
+ } else if (state.running) {
333
+ this.log(`跳过 ${sessionId}: 会话仍在运行`);
334
+ return;
335
+ }
336
+ if (state.queued > 0) {
337
+ this.log(`跳过 ${sessionId}: 已有排队消息`);
338
+ return;
339
+ }
340
+ if (Date.now() - readLastSend(sessionId) < config.cooldownMs) {
341
+ this.log(`跳过 ${sessionId}: 其他标签页刚发送过`);
342
+ return;
343
+ }
344
+ if (!claimSend(sessionId)) {
345
+ this.log(`跳过 ${sessionId}: 其他标签页正在发送`);
346
+ return;
347
+ }
348
+ const text = config.continueText;
349
+ const zone = clientTimeZone();
350
+ state.lastAttemptAt = Date.now();
351
+ try {
352
+ const response = await this.api.sessions.prompt({
353
+ sessionId,
354
+ mode: "queue",
355
+ content: [{ type: "text", text }],
356
+ ...zone === void 0 ? {} : { clientTimeZone: zone }
357
+ });
358
+ if (response.result.ok) {
359
+ const now = Date.now();
360
+ state.consecutive += 1;
361
+ state.lastAutoAt = now;
362
+ state.lastSentText = text;
363
+ writeLastSend(sessionId, now);
364
+ this.log(`已自动发送「${text}」到 ${sessionId}(${reason}), 第 ${state.consecutive} 次连续`);
365
+ } else {
366
+ this.log(
367
+ `发送失败 ${sessionId}: ${response.result.error.code} ${response.result.error.message}`
368
+ );
369
+ }
370
+ } catch (error) {
371
+ this.log(`发送异常 ${sessionId}: ${error instanceof Error ? error.message : String(error)}`);
372
+ } finally {
373
+ releaseSend(sessionId);
374
+ }
375
+ }
376
+ async runningViaList(sessionId) {
377
+ try {
378
+ const response = await this.api.sessions.list({});
379
+ if (!response.result.ok) return void 0;
380
+ const item = response.result.value.items.find(
381
+ (summary) => summary.sessionId === sessionId
382
+ );
383
+ return item === void 0 ? void 0 : item.running;
384
+ } catch {
385
+ return void 0;
386
+ }
387
+ }
388
+ // ---------- 启动/重连扫描 ----------
389
+ scheduleReconnectScan() {
390
+ this.reconnectScans += 1;
391
+ const scan = this.reconnectScans;
392
+ setTimeout(() => {
393
+ if (scan !== this.reconnectScans || this.disposed) return;
394
+ void this.scanLoop(6, this.getConfig().reconnectScanDelayMs);
395
+ }, this.getConfig().reconnectScanDelayMs);
396
+ }
397
+ async bootScanLoop() {
398
+ await this.scanLoop(Infinity, 3e3);
399
+ }
400
+ /** 反复尝试扫描, 直到成功(宿主就绪)或达到次数上限。 */
401
+ async scanLoop(attempts, delayMs) {
402
+ for (let attempt = 0; attempt < attempts && !this.disposed; attempt += 1) {
403
+ try {
404
+ if (await this.scanInterrupted()) return;
405
+ } catch (error) {
406
+ if (this.disposed) return;
407
+ if (attempt % 10 === 0) {
408
+ this.log(
409
+ `扫描失败(${attempt + 1}/${attempts === Infinity ? "∞" : attempts}): ${error instanceof Error ? error.message : String(error)}`
410
+ );
411
+ }
412
+ }
413
+ if (attempt + 1 < attempts) await sleep(delayMs);
414
+ }
415
+ }
416
+ /**
417
+ * 扫描最近中断过的会话: 最后回合以非人为原因结束, 且其后没有新回合或用户消息。
418
+ * @returns 是否成功完成一次扫描(宿主就绪)。
419
+ */
420
+ async scanInterrupted() {
421
+ const config = this.getConfig();
422
+ const response = await this.api.sessions.list({});
423
+ if (!response.result.ok) return false;
424
+ const items = response.result.value.items;
425
+ const candidates = items.filter((summary) => !summary.running && summary.parentSessionId === void 0).slice(0, config.scanLimit);
426
+ const now = Date.now();
427
+ for (const summary of candidates) {
428
+ if (this.disposed) return true;
429
+ const state = this.state(summary.sessionId);
430
+ if (state.pendingTimer !== void 0) continue;
431
+ if (state.consecutive >= config.maxConsecutive) continue;
432
+ if (now - state.lastAttemptAt < config.cooldownMs) continue;
433
+ let events;
434
+ try {
435
+ const page = await this.api.sessions.history({
436
+ sessionId: summary.sessionId,
437
+ maxMessages: 30
438
+ });
439
+ if (!page.result.ok) continue;
440
+ events = page.result.value.events;
441
+ } catch {
442
+ continue;
443
+ }
444
+ let lastEnd;
445
+ for (let i = events.length - 1; i >= 0; i -= 1) {
446
+ const event = events[i]?.event;
447
+ if (event !== void 0 && event.type === "turn/end") {
448
+ lastEnd = event;
449
+ break;
450
+ }
451
+ }
452
+ if (lastEnd === void 0) continue;
453
+ const reason = lastEnd.data.reason;
454
+ if (!isNonHumanReason(reason.kind)) continue;
455
+ if (lastEnd.time < now - config.freshMs) continue;
456
+ let superseded = false;
457
+ for (const entry of events) {
458
+ const event = entry.event;
459
+ if (event.seq <= lastEnd.seq) continue;
460
+ if (event.type === "turn/start") superseded = true;
461
+ if (event.type === "user/message" && event.data.source.kind === "user") superseded = true;
462
+ if (superseded) break;
463
+ }
464
+ if (superseded) continue;
465
+ this.log(`扫描发现中断 ${summary.sessionId}(turn/end:${reason.kind}), 安排自动继续`);
466
+ this.schedule(summary.sessionId, `scan:turn/end:${reason.kind}`);
467
+ }
468
+ return true;
469
+ }
470
+ };
471
+
472
+ // src/client/locales.ts
473
+ var zh = {
474
+ "card.title": "自动继续",
475
+ "card.description": "请求因网络等原因(非人为)中断后, 自动发送「继续」续跑。",
476
+ "field.continueText": "继续文本",
477
+ "field.continueTextHint": "中断后自动发送的消息内容。",
478
+ "field.graceMs": "宽限期 (ms)",
479
+ "field.graceMsHint": "检测到中断后等待的时长; 期间宿主自行恢复则取消。",
480
+ "field.cooldownMs": "冷却时间 (ms)",
481
+ "field.cooldownMsHint": "同一会话两次自动「继续」的最小间隔, 失败尝试也计入。",
482
+ "field.maxConsecutive": "最大连续次数",
483
+ "field.maxConsecutiveHint": "同一会话连续自动「继续」的上限; 超过后停止, 直到用户手动介入或出现成功回合。",
484
+ "field.scanOnBoot": "启动/重连扫描",
485
+ "field.scanOnBootHint": "页面启动或重连时扫描最近中断的会话并自动续跑(如浏览器关闭期间宿主崩溃)。",
486
+ "field.scanLimit": "扫描会话数",
487
+ "field.scanLimitHint": "最多检查多少个最近更新的会话(不含运行中与子代理会话)。",
488
+ "field.freshMs": "扫描时间窗 (ms)",
489
+ "field.freshMsHint": "扫描只处理该时间窗内的中断。",
490
+ "field.reconnectScanDelayMs": "重连扫描延迟 (ms)",
491
+ "field.reconnectScanDelayMsHint": "重连后等待宿主完成恢复再扫描。",
492
+ "field.reconnectBackoffMs": "重连退避 (ms)",
493
+ "field.reconnectBackoffMsHint": "事件流断开后的重连间隔。",
494
+ "field.verbose": "详细日志",
495
+ "field.verboseHint": "在浏览器控制台输出 [auto-continue] 日志。",
496
+ "chrome.collapse": "收起设置",
497
+ "chrome.expand": "展开设置",
498
+ "chrome.unsaved": "未保存",
499
+ "chrome.readOnly": "当前部署的设置只读。",
500
+ "chrome.saveFailed": "部署未接受这些值, 已保留供你修改。",
501
+ "chrome.discard": "放弃",
502
+ "chrome.saving": "保存中…",
503
+ "chrome.save": "保存",
504
+ "chrome.overridden": "已覆盖",
505
+ "chrome.reset": "恢复默认",
506
+ "chrome.invalidNumber": "请输入数字, 留空则使用默认值。",
507
+ "chrome.inherit": "继承",
508
+ "chrome.on": "开",
509
+ "chrome.off": "关"
510
+ };
511
+ var en = {
512
+ "card.title": "Auto continue",
513
+ "card.description": "When a request is interrupted by a non-human cause, automatically send 「继续」 to resume.",
514
+ "field.continueText": "Continue text",
515
+ "field.continueTextHint": "Message automatically sent after an interruption.",
516
+ "field.graceMs": "Grace period (ms)",
517
+ "field.graceMsHint": "Wait after an interruption; cancelled if the host recovers on its own.",
518
+ "field.cooldownMs": "Cooldown (ms)",
519
+ "field.cooldownMsHint": "Minimum interval between auto-continues per session; failed attempts count too.",
520
+ "field.maxConsecutive": "Max consecutive",
521
+ "field.maxConsecutiveHint": "Max consecutive auto-continues per session; stops until a user intervenes or a turn completes.",
522
+ "field.scanOnBoot": "Scan on load / reconnect",
523
+ "field.scanOnBootHint": "Scan recently interrupted sessions on page load or reconnect (e.g. the host crashed while the browser was closed).",
524
+ "field.scanLimit": "Scan limit",
525
+ "field.scanLimitHint": "How many most-recently-updated sessions to check (running / subagent sessions excluded).",
526
+ "field.freshMs": "Scan window (ms)",
527
+ "field.freshMsHint": "Only interruptions inside this window are considered.",
528
+ "field.reconnectScanDelayMs": "Reconnect scan delay (ms)",
529
+ "field.reconnectScanDelayMsHint": "Wait for the host to finish recovering before scanning after a reconnect.",
530
+ "field.reconnectBackoffMs": "Reconnect backoff (ms)",
531
+ "field.reconnectBackoffMsHint": "Interval between event-stream reconnect attempts.",
532
+ "field.verbose": "Verbose logs",
533
+ "field.verboseHint": "Log [auto-continue] lines to the browser console.",
534
+ "chrome.collapse": "Hide settings",
535
+ "chrome.expand": "Show settings",
536
+ "chrome.unsaved": "Unsaved",
537
+ "chrome.readOnly": "This deployment stores settings read-only.",
538
+ "chrome.saveFailed": "The deployment did not accept these values; they were left for you to correct.",
539
+ "chrome.discard": "Discard",
540
+ "chrome.saving": "Saving…",
541
+ "chrome.save": "Save",
542
+ "chrome.overridden": "Overridden",
543
+ "chrome.reset": "Reset to default",
544
+ "chrome.invalidNumber": "Enter a number, or leave blank to use the default.",
545
+ "chrome.inherit": "Inherit",
546
+ "chrome.on": "On",
547
+ "chrome.off": "Off"
548
+ };
549
+
550
+ // src/client/settings-card.tsx
551
+ var import_react = require("react");
552
+ var import_client = require("@deepseek-ai/dsh-client-runtime/client");
553
+
554
+ // src/client/settings-form.ts
555
+ function numberField(field, min = 0) {
556
+ return {
557
+ field,
558
+ format: (value) => typeof value === "number" ? String(value) : "",
559
+ parse: (text) => {
560
+ const trimmed = text.trim();
561
+ if (trimmed === "") return { kind: "clear" };
562
+ const parsed = Number(trimmed);
563
+ if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed < min) return void 0;
564
+ return { kind: "set", value: parsed };
565
+ }
566
+ };
567
+ }
568
+ function textField(field) {
569
+ return {
570
+ field,
571
+ format: (value) => typeof value === "string" ? value : "",
572
+ parse: (text) => {
573
+ const trimmed = text.trim();
574
+ return trimmed === "" ? { kind: "clear" } : { kind: "set", value: trimmed };
575
+ }
576
+ };
577
+ }
578
+ function booleanField(field) {
579
+ return {
580
+ field,
581
+ format: (value) => typeof value === "boolean" ? String(value) : "",
582
+ parse: (text) => {
583
+ const trimmed = text.trim();
584
+ if (trimmed === "") return { kind: "clear" };
585
+ if (trimmed === "true") return { kind: "set", value: true };
586
+ if (trimmed === "false") return { kind: "set", value: false };
587
+ return void 0;
588
+ }
589
+ };
590
+ }
591
+ var CardForm = class {
592
+ /**
593
+ * @param scope - the bound settings scope for this card's namespace.
594
+ * @param specs - the section fields this card edits.
595
+ */
596
+ constructor(scope, specs) {
597
+ this.scope = scope;
598
+ this.staged = /* @__PURE__ */ new Map();
599
+ this.listeners = /* @__PURE__ */ new Set();
600
+ this.saving = false;
601
+ this.failed = false;
602
+ this.specs = new Map(specs.map((spec) => [spec.field, spec]));
603
+ this.scope.subscribe(() => this.publish());
604
+ }
605
+ /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */
606
+ bind(project, createStore) {
607
+ const store = createStore(project());
608
+ this.listeners.add(() => store.set(project()));
609
+ return store;
610
+ }
611
+ /** Read the card-level state: what the Host serves, and what a save would do. */
612
+ shell() {
613
+ const snapshot = this.scope.getSnapshot();
614
+ return {
615
+ available: snapshot.status === "ready",
616
+ writable: snapshot.writable,
617
+ dirty: this.plan().length > 0,
618
+ invalid: this.plan().some((item) => item.run === void 0),
619
+ saving: this.saving,
620
+ failed: this.failed
621
+ };
622
+ }
623
+ /** Read one field's state from the effective section and its staged draft. */
624
+ field(field) {
625
+ const spec = this.specOf(field);
626
+ const staged = this.staged.get(field);
627
+ if (staged === void 0) {
628
+ return {
629
+ text: spec.format(this.sectionValue(field)),
630
+ overridden: this.stored(field),
631
+ invalid: false
632
+ };
633
+ }
634
+ const write = staged.clear ? { kind: "clear" } : spec.parse(staged.text);
635
+ return {
636
+ text: staged.text,
637
+ overridden: write?.kind === "set",
638
+ invalid: write === void 0
639
+ };
640
+ }
641
+ /** The actions the card's slot registration injects. */
642
+ actions() {
643
+ return {
644
+ edit: (field, text) => this.stage(field, { text, clear: false }),
645
+ resetField: (field) => {
646
+ this.stage(field, { text: this.specOf(field).format(this.baseValue(field)), clear: true });
647
+ },
648
+ save: () => void this.save(),
649
+ discard: () => {
650
+ if (this.staged.size === 0 && !this.failed) return;
651
+ this.staged.clear();
652
+ this.failed = false;
653
+ this.publish();
654
+ }
655
+ };
656
+ }
657
+ /**
658
+ * Write every staged edit, then re-seed from what the Host accepted.
659
+ * @returns settlement after every write and the read-back.
660
+ */
661
+ async save() {
662
+ const plan = this.plan();
663
+ const writes = plan.flatMap((item) => item.run === void 0 ? [] : [item.run]);
664
+ if (plan.length === 0 || this.saving || writes.length !== plan.length) return;
665
+ const fields = new Set(plan.map((item) => item.field));
666
+ this.saving = true;
667
+ this.failed = false;
668
+ this.publish();
669
+ let landed = true;
670
+ for (const write of writes) {
671
+ landed = await write() && landed;
672
+ }
673
+ if (landed) {
674
+ for (const field of fields) this.staged.delete(field);
675
+ }
676
+ this.saving = false;
677
+ this.failed = !landed;
678
+ this.publish();
679
+ }
680
+ /**
681
+ * Every staged edit a save would write. An entry whose draft is not a value
682
+ * its field accepts carries no write: the form is still dirty, and the save
683
+ * refuses rather than dropping the edit. A staged edit that matches the
684
+ * effective section is not a write at all.
685
+ */
686
+ plan() {
687
+ const plan = [];
688
+ for (const [field, staged] of this.staged) {
689
+ const spec = this.specOf(field);
690
+ if (staged.clear) {
691
+ if (this.stored(field)) plan.push({ field, run: () => this.clear(field) });
692
+ continue;
693
+ }
694
+ if (staged.text === spec.format(this.sectionValue(field))) continue;
695
+ const write = spec.parse(staged.text);
696
+ if (write === void 0) plan.push({ field, run: void 0 });
697
+ else if (write.kind === "clear") plan.push({ field, run: () => this.clear(field) });
698
+ else plan.push({ field, run: () => this.store(field, write.value) });
699
+ }
700
+ return plan;
701
+ }
702
+ async clear(field) {
703
+ await this.scope.unset(field);
704
+ return !this.stored(field);
705
+ }
706
+ async store(field, value) {
707
+ await this.scope.set(field, value);
708
+ return this.userLayer()?.[field] === value;
709
+ }
710
+ stage(field, edit) {
711
+ this.staged.set(field, edit);
712
+ this.failed = false;
713
+ this.publish();
714
+ }
715
+ specOf(field) {
716
+ const spec = this.specs.get(field);
717
+ if (spec === void 0) throw new Error(`settings card has no field ${field}`);
718
+ return spec;
719
+ }
720
+ sectionValue(field) {
721
+ return this.scope.getSnapshot().value?.[field];
722
+ }
723
+ baseValue(field) {
724
+ return this.scope.getSnapshot().base?.[field];
725
+ }
726
+ userLayer() {
727
+ return this.scope.getSnapshot().user;
728
+ }
729
+ stored(field) {
730
+ const user = this.userLayer();
731
+ return user !== void 0 && Object.prototype.hasOwnProperty.call(user, field);
732
+ }
733
+ publish() {
734
+ for (const listener of this.listeners) listener();
735
+ }
736
+ };
737
+
738
+ // src/client/styles.ts
739
+ var css = `
740
+ .dshAcCard {
741
+ border: 1px solid var(--dsw-alias-border-l2);
742
+ background: var(--dsw-alias-bg-layer-3);
743
+ border-radius: 12px;
744
+ list-style: none;
745
+ transition: border-color .16s, background .16s;
746
+ }
747
+ .dshAcCard:hover { border-color: var(--dsw-alias-label-dimmed); }
748
+ .dshAcCardOpen {
749
+ background: var(--dsw-alias-bg-layer-2);
750
+ border-color: var(--dsw-alias-label-dimmed);
751
+ }
752
+ .dshAcHeader {
753
+ appearance: none;
754
+ width: 100%;
755
+ font: inherit;
756
+ color: inherit;
757
+ text-align: left;
758
+ cursor: pointer;
759
+ background: none;
760
+ border: 0;
761
+ border-radius: 12px;
762
+ align-items: center;
763
+ gap: 12px;
764
+ padding: 14px 16px;
765
+ display: flex;
766
+ }
767
+ .dshAcHeader:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: -2px; }
768
+ .dshAcHeadText { flex-direction: column; flex: 1; gap: 4px; min-width: 0; display: flex; }
769
+ .dshAcName { color: var(--dsw-alias-label-primary); font-size: 15px; font-weight: 600; line-height: 1.4; }
770
+ .dshAcDescription { color: var(--dsw-alias-label-tertiary); font-size: 13px; line-height: 1.5; }
771
+ .dshAcChevron { color: var(--dsw-alias-label-tertiary); flex: none; transition: transform .16s; }
772
+ .dshAcChevronOpen { transform: rotate(180deg); }
773
+ .dshAcBody { border-top: 1px solid var(--dsw-alias-border-l2); margin: 0 16px; padding-bottom: 8px; }
774
+ .dshAcReadOnly { color: var(--dsw-alias-label-tertiary); margin: 12px 0 0; font-size: 12px; line-height: 1.5; }
775
+ .dshAcPending {
776
+ white-space: nowrap;
777
+ background: var(--dsw-alias-bg-module-platform);
778
+ color: var(--dsw-alias-label-secondary);
779
+ border-radius: 999px;
780
+ flex: none;
781
+ padding: 1px 8px;
782
+ font-size: 11px;
783
+ font-weight: 500;
784
+ line-height: 17px;
785
+ }
786
+ .dshAcFooter {
787
+ border-top: 1px solid var(--dsw-alias-border-l2);
788
+ justify-content: flex-end;
789
+ align-items: center;
790
+ gap: 8px;
791
+ padding: 12px 0 4px;
792
+ display: flex;
793
+ }
794
+ .dshAcFailed { min-width: 0; color: var(--dsw-alias-label-error); flex: 1; margin: 0; font-size: 12px; line-height: 1.5; }
795
+ .dshAcDiscard, .dshAcSave {
796
+ appearance: none;
797
+ font: inherit;
798
+ cursor: pointer;
799
+ border: 1px solid transparent;
800
+ border-radius: 8px;
801
+ padding: 5px 14px;
802
+ font-size: 13px;
803
+ line-height: 1.5;
804
+ }
805
+ .dshAcDiscard { border-color: var(--dsw-alias-border-l2); color: var(--dsw-alias-label-secondary); background: none; }
806
+ .dshAcDiscard:hover:not(:disabled) { color: var(--dsw-alias-label-primary); border-color: var(--dsw-alias-label-dimmed); }
807
+ .dshAcSave { background: var(--dsw-alias-label-primary); color: var(--dsw-alias-bg-layer-3); }
808
+ .dshAcDiscard:disabled, .dshAcSave:disabled { opacity: .4; cursor: default; }
809
+ .dshAcDiscard:focus-visible, .dshAcSave:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: 1px; }
810
+ .dshAcField { flex-direction: column; gap: 6px; padding: 12px 0; display: flex; }
811
+ .dshAcField + .dshAcField { border-top: 1px solid var(--dsw-alias-border-l2); }
812
+ .dshAcHead { align-items: center; gap: 8px; display: flex; }
813
+ .dshAcLabel { min-width: 0; color: var(--dsw-alias-label-primary); flex: 1; font-size: 13px; font-weight: 500; line-height: 1.5; }
814
+ .dshAcBadges { align-items: center; gap: 8px; display: inline-flex; }
815
+ .dshAcBadge {
816
+ white-space: nowrap;
817
+ background: var(--dsw-alias-bg-module-platform);
818
+ color: var(--dsw-alias-label-secondary);
819
+ border-radius: 999px;
820
+ padding: 1px 8px;
821
+ font-size: 11px;
822
+ font-weight: 500;
823
+ line-height: 17px;
824
+ }
825
+ .dshAcReset {
826
+ font: inherit;
827
+ color: var(--dsw-alias-label-secondary);
828
+ cursor: pointer;
829
+ background: none;
830
+ border: none;
831
+ padding: 0;
832
+ font-size: 12px;
833
+ line-height: 1.5;
834
+ }
835
+ .dshAcReset:hover:not(:disabled) { color: var(--dsw-alias-label-primary); }
836
+ .dshAcReset:disabled { cursor: default; }
837
+ .dshAcInput {
838
+ border: 1px solid var(--dsw-alias-border-l2);
839
+ background: var(--dsw-alias-bg-layer-3);
840
+ height: 34px;
841
+ font: inherit;
842
+ color: var(--dsw-alias-label-primary);
843
+ border-radius: 8px;
844
+ padding: 0 12px;
845
+ font-size: 13px;
846
+ line-height: 1.5;
847
+ }
848
+ .dshAcInput:focus-visible { border-color: var(--dsw-alias-brand-primary); outline: none; }
849
+ .dshAcInput:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }
850
+ .dshAcInputInvalid { border-color: var(--dsw-alias-label-error); }
851
+ .dshAcSelect {
852
+ border: 1px solid var(--dsw-alias-border-l2);
853
+ background: var(--dsw-alias-bg-layer-3);
854
+ height: 34px;
855
+ font: inherit;
856
+ color: var(--dsw-alias-label-primary);
857
+ border-radius: 8px;
858
+ padding: 0 8px;
859
+ font-size: 13px;
860
+ line-height: 1.5;
861
+ }
862
+ .dshAcSelect:focus-visible { border-color: var(--dsw-alias-brand-primary); outline: none; }
863
+ .dshAcSelect:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }
864
+ .dshAcInvalid { color: var(--dsw-alias-label-error); margin: 0; font-size: 12px; line-height: 1.5; }
865
+ .dshAcHint { color: var(--dsw-alias-label-tertiary); margin: 0; font-size: 12px; line-height: 1.5; }
866
+ `;
867
+ function injectStyles() {
868
+ if (typeof document === "undefined") return;
869
+ if (document.querySelector('style[data-plugin-css="auto-continue/card"]') !== null) return;
870
+ const tag = document.createElement("style");
871
+ tag.dataset.plugin = "dsh-client-auto-continue";
872
+ tag.dataset.pluginCss = "auto-continue/card";
873
+ tag.textContent = css;
874
+ document.head.appendChild(tag);
875
+ }
876
+
877
+ // src/client/settings-card.tsx
878
+ var import_jsx_runtime = require("react/jsx-runtime");
879
+ injectStyles();
880
+ var AutoContinueSettingsCardController = class {
881
+ /**
882
+ * @param scope - the bound settings scope for the `auto-continue` namespace.
883
+ */
884
+ constructor(scope) {
885
+ this.form = new CardForm(scope, [
886
+ textField("continueText"),
887
+ numberField("graceMs", 0),
888
+ numberField("cooldownMs", 0),
889
+ numberField("maxConsecutive", 1),
890
+ booleanField("scanOnBoot"),
891
+ numberField("scanLimit", 1),
892
+ numberField("freshMs", 0),
893
+ numberField("reconnectScanDelayMs", 0),
894
+ numberField("reconnectBackoffMs", 0),
895
+ booleanField("verbose")
896
+ ]);
897
+ this.store = this.form.bind(() => this.projection(), import_client.createSnapshotStore);
898
+ }
899
+ projection() {
900
+ return {
901
+ ...this.form.shell(),
902
+ continueText: this.form.field("continueText"),
903
+ graceMs: this.form.field("graceMs"),
904
+ cooldownMs: this.form.field("cooldownMs"),
905
+ maxConsecutive: this.form.field("maxConsecutive"),
906
+ scanOnBoot: this.form.field("scanOnBoot"),
907
+ scanLimit: this.form.field("scanLimit"),
908
+ freshMs: this.form.field("freshMs"),
909
+ reconnectScanDelayMs: this.form.field("reconnectScanDelayMs"),
910
+ reconnectBackoffMs: this.form.field("reconnectBackoffMs"),
911
+ verbose: this.form.field("verbose")
912
+ };
913
+ }
914
+ /**
915
+ * Build the face the card's slot registration injects.
916
+ * @returns the card's snapshot and its form actions.
917
+ */
918
+ inject() {
919
+ return { hooks: { autoContinueSettingsCard: this.store }, ...this.form.actions() };
920
+ }
921
+ };
922
+ function SettingsCard(props) {
923
+ const [open, setOpen] = (0, import_react.useState)(false);
924
+ const { state } = props;
925
+ if (!state.available) return null;
926
+ const title = props.t(props.titleKey);
927
+ const blocked = !state.dirty || state.invalid || state.saving;
928
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: open ? "dshAcCard dshAcCardOpen" : "dshAcCard", children: [
929
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
930
+ "button",
931
+ {
932
+ type: "button",
933
+ className: "dshAcHeader",
934
+ "aria-expanded": open,
935
+ "aria-label": `${props.t(open ? "chrome.collapse" : "chrome.expand")}: ${title}`,
936
+ title: props.t(props.descriptionKey),
937
+ onClick: () => setOpen(!open),
938
+ children: [
939
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dshAcHeadText", children: [
940
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dshAcName", children: title }),
941
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dshAcDescription", children: props.t(props.descriptionKey) })
942
+ ] }),
943
+ state.dirty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dshAcPending", title: props.t("chrome.unsaved"), children: props.t("chrome.unsaved") }) : null,
944
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: open ? "dshAcChevron dshAcChevronOpen" : "dshAcChevron", children: "▾" })
945
+ ]
946
+ }
947
+ ),
948
+ open ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dshAcBody", children: [
949
+ !state.writable ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dshAcReadOnly", role: "status", children: props.t("chrome.readOnly") }) : null,
950
+ props.children,
951
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dshAcFooter", children: [
952
+ state.failed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dshAcFailed", role: "status", children: props.t("chrome.saveFailed") }) : null,
953
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
954
+ "button",
955
+ {
956
+ type: "button",
957
+ className: "dshAcDiscard",
958
+ disabled: !state.dirty || state.saving,
959
+ onClick: props.onDiscard,
960
+ children: props.t("chrome.discard")
961
+ }
962
+ ),
963
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "dshAcSave", disabled: blocked, onClick: props.onSave, children: props.t(!state.saving ? "chrome.save" : "chrome.saving") })
964
+ ] })
965
+ ] }) : null
966
+ ] });
967
+ }
968
+ function ValueField(props) {
969
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dshAcField", children: [
970
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dshAcHead", children: [
971
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "dshAcLabel", htmlFor: props.id, children: props.label }),
972
+ props.overridden ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dshAcBadges", children: [
973
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dshAcBadge", children: props.t("chrome.overridden") }),
974
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "dshAcReset", disabled: props.disabled, onClick: props.onReset, children: props.t("chrome.reset") })
975
+ ] }) : null
976
+ ] }),
977
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
978
+ "input",
979
+ {
980
+ id: props.id,
981
+ className: props.invalid ? "dshAcInput dshAcInputInvalid" : "dshAcInput",
982
+ type: "text",
983
+ inputMode: props.numeric === true ? "numeric" : void 0,
984
+ "aria-invalid": props.invalid || void 0,
985
+ value: props.text,
986
+ placeholder: props.placeholder ?? "",
987
+ disabled: props.disabled,
988
+ onChange: (event) => props.onEdit(event.target.value)
989
+ }
990
+ ),
991
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: props.invalid ? "dshAcInvalid" : "dshAcHint", children: props.invalid ? props.t("chrome.invalidNumber") : props.hint })
992
+ ] });
993
+ }
994
+ function BooleanField(props) {
995
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dshAcField", children: [
996
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dshAcHead", children: [
997
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "dshAcLabel", htmlFor: props.id, children: props.label }),
998
+ props.overridden ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dshAcBadges", children: [
999
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dshAcBadge", children: props.t("chrome.overridden") }),
1000
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "dshAcReset", disabled: props.disabled, onClick: props.onReset, children: props.t("chrome.reset") })
1001
+ ] }) : null
1002
+ ] }),
1003
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1004
+ "select",
1005
+ {
1006
+ id: props.id,
1007
+ className: "dshAcSelect",
1008
+ value: props.text,
1009
+ disabled: props.disabled,
1010
+ onChange: (event) => props.onEdit(event.target.value),
1011
+ children: [
1012
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: props.t("chrome.inherit") }),
1013
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "true", children: props.t("chrome.on") }),
1014
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "false", children: props.t("chrome.off") })
1015
+ ]
1016
+ }
1017
+ ),
1018
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dshAcHint", children: props.hint })
1019
+ ] });
1020
+ }
1021
+ function AutoContinueSettingsCard(props) {
1022
+ const { t } = props;
1023
+ const state = props.useAutoContinueSettingsCard((snapshot) => snapshot);
1024
+ const disabled = !state.writable;
1025
+ const shared = { t, disabled };
1026
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1027
+ SettingsCard,
1028
+ {
1029
+ t,
1030
+ titleKey: "card.title",
1031
+ descriptionKey: "card.description",
1032
+ state,
1033
+ onSave: props.save,
1034
+ onDiscard: props.discard,
1035
+ children: [
1036
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1037
+ ValueField,
1038
+ {
1039
+ id: "auto-continue-continue-text",
1040
+ label: t("field.continueText"),
1041
+ hint: t("field.continueTextHint"),
1042
+ ...shared,
1043
+ ...state.continueText,
1044
+ onEdit: (text) => props.edit("continueText", text),
1045
+ onReset: () => props.resetField("continueText")
1046
+ }
1047
+ ),
1048
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1049
+ ValueField,
1050
+ {
1051
+ id: "auto-continue-grace-ms",
1052
+ label: t("field.graceMs"),
1053
+ hint: t("field.graceMsHint"),
1054
+ numeric: true,
1055
+ ...shared,
1056
+ ...state.graceMs,
1057
+ onEdit: (text) => props.edit("graceMs", text),
1058
+ onReset: () => props.resetField("graceMs")
1059
+ }
1060
+ ),
1061
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1062
+ ValueField,
1063
+ {
1064
+ id: "auto-continue-cooldown-ms",
1065
+ label: t("field.cooldownMs"),
1066
+ hint: t("field.cooldownMsHint"),
1067
+ numeric: true,
1068
+ ...shared,
1069
+ ...state.cooldownMs,
1070
+ onEdit: (text) => props.edit("cooldownMs", text),
1071
+ onReset: () => props.resetField("cooldownMs")
1072
+ }
1073
+ ),
1074
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1075
+ ValueField,
1076
+ {
1077
+ id: "auto-continue-max-consecutive",
1078
+ label: t("field.maxConsecutive"),
1079
+ hint: t("field.maxConsecutiveHint"),
1080
+ numeric: true,
1081
+ ...shared,
1082
+ ...state.maxConsecutive,
1083
+ onEdit: (text) => props.edit("maxConsecutive", text),
1084
+ onReset: () => props.resetField("maxConsecutive")
1085
+ }
1086
+ ),
1087
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1088
+ BooleanField,
1089
+ {
1090
+ id: "auto-continue-scan-on-boot",
1091
+ label: t("field.scanOnBoot"),
1092
+ hint: t("field.scanOnBootHint"),
1093
+ ...shared,
1094
+ ...state.scanOnBoot,
1095
+ onEdit: (text) => props.edit("scanOnBoot", text),
1096
+ onReset: () => props.resetField("scanOnBoot")
1097
+ }
1098
+ ),
1099
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1100
+ ValueField,
1101
+ {
1102
+ id: "auto-continue-scan-limit",
1103
+ label: t("field.scanLimit"),
1104
+ hint: t("field.scanLimitHint"),
1105
+ numeric: true,
1106
+ ...shared,
1107
+ ...state.scanLimit,
1108
+ onEdit: (text) => props.edit("scanLimit", text),
1109
+ onReset: () => props.resetField("scanLimit")
1110
+ }
1111
+ ),
1112
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1113
+ ValueField,
1114
+ {
1115
+ id: "auto-continue-fresh-ms",
1116
+ label: t("field.freshMs"),
1117
+ hint: t("field.freshMsHint"),
1118
+ numeric: true,
1119
+ ...shared,
1120
+ ...state.freshMs,
1121
+ onEdit: (text) => props.edit("freshMs", text),
1122
+ onReset: () => props.resetField("freshMs")
1123
+ }
1124
+ ),
1125
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1126
+ ValueField,
1127
+ {
1128
+ id: "auto-continue-reconnect-scan-delay",
1129
+ label: t("field.reconnectScanDelayMs"),
1130
+ hint: t("field.reconnectScanDelayMsHint"),
1131
+ numeric: true,
1132
+ ...shared,
1133
+ ...state.reconnectScanDelayMs,
1134
+ onEdit: (text) => props.edit("reconnectScanDelayMs", text),
1135
+ onReset: () => props.resetField("reconnectScanDelayMs")
1136
+ }
1137
+ ),
1138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1139
+ ValueField,
1140
+ {
1141
+ id: "auto-continue-reconnect-backoff",
1142
+ label: t("field.reconnectBackoffMs"),
1143
+ hint: t("field.reconnectBackoffMsHint"),
1144
+ numeric: true,
1145
+ ...shared,
1146
+ ...state.reconnectBackoffMs,
1147
+ onEdit: (text) => props.edit("reconnectBackoffMs", text),
1148
+ onReset: () => props.resetField("reconnectBackoffMs")
1149
+ }
1150
+ ),
1151
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1152
+ BooleanField,
1153
+ {
1154
+ id: "auto-continue-verbose",
1155
+ label: t("field.verbose"),
1156
+ hint: t("field.verboseHint"),
1157
+ ...shared,
1158
+ ...state.verbose,
1159
+ onEdit: (text) => props.edit("verbose", text),
1160
+ onReset: () => props.resetField("verbose")
1161
+ }
1162
+ )
1163
+ ]
1164
+ }
1165
+ );
1166
+ }
1167
+
1168
+ // src/client/index.ts
1169
+ var NS = "auto-continue";
1170
+ var SETTINGS_NS = "auto-continue";
1171
+ var inject = ["slots", "locale", "connection", "settingsScope"];
1172
+ var current = null;
1173
+ function apply(ctx) {
1174
+ ctx.effect(() => ctx.locale.register(NS, { zh, en }), "auto-continue: dictionaries");
1175
+ const scope = ctx.settingsScope.bind({ namespace: SETTINGS_NS });
1176
+ current?.dispose();
1177
+ current = new AutoContinueRunner(ctx.connection.api, () => resolveConfig(scope.getSnapshot().value));
1178
+ const controller = new AutoContinueSettingsCardController(scope);
1179
+ ctx.slots.inject(
1180
+ "settings.plugin.item",
1181
+ () => ctx.slots.register(
1182
+ {
1183
+ name: "settings.plugin.item",
1184
+ id: "auto-continue",
1185
+ order: 90,
1186
+ locale: NS,
1187
+ inject: () => controller.inject()
1188
+ },
1189
+ AutoContinueSettingsCard
1190
+ )
1191
+ );
1192
+ }
1193
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL2NsaWVudC9pbmRleC50cyIsICJzcmMvY2xpZW50L2VuZ2luZS50cyIsICJzcmMvY2xpZW50L2xvY2FsZXMudHMiLCAic3JjL2NsaWVudC9zZXR0aW5ncy1jYXJkLnRzeCIsICJzcmMvY2xpZW50L3NldHRpbmdzLWZvcm0udHMiLCAic3JjL2NsaWVudC9zdHlsZXMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQXV0by1jb250aW51ZSBwbHVnaW4sIGJyb3dzZXIgaGFsZi5cbiAqXG4gKiAtIFJ1bnMgdGhlIGF1dG8tY29udGludWUgZW5naW5lIG92ZXIgdGhlIGxpdmUgbXV4ICsgaG9zdCBldmVudCBzdHJlYW1zLlxuICogLSBSZWdpc3RlcnMgdGhlIGBhdXRvLWNvbnRpbnVlYCBzZXR0aW5ncyBjYXJkIGludG8gdGhlIHBsdWdpbi1jb25maWd1cmF0aW9uXG4gKiAgIHNlY3Rpb24gKGBzZXR0aW5ncy5wbHVnaW4uaXRlbWApLCBlZGl0aW5nIHRoZSBzYW1lIG5hbWVzcGFjZSB0aGUgZW5naW5lXG4gKiAgIHJlYWRzIOKAlCBldmVyeSBiZWhhdmlvciBrbm9iIGlzIGNvbmZpZ3VyYWJsZSBmcm9tIHRoZSBHVUkuXG4gKi9cbmltcG9ydCB0eXBlIHsgQ2xpZW50Q29udGV4dCB9IGZyb20gJ0BkZWVwc2Vlay1haS9kc2gtY2xpZW50LXJ1bnRpbWUvY2xpZW50JztcbmltcG9ydCB0eXBlIHsgQ29ubmVjdGlvbkhhbmRsZSB9IGZyb20gJ0BkZWVwc2Vlay1haS9kc2gtY2xpZW50LWNvbm5lY3Rpb24vY2xpZW50Jztcbi8vIFR5cGUtb25seTogcHVsbHMgdGhlIGxvY2FsZSBwbHVnaW4ncyBDb250ZXh0IG1lcmdlIChjdHgubG9jYWxlKS5cbmltcG9ydCB0eXBlIHt9IGZyb20gJ0BkZWVwc2Vlay1haS9kc2gtY2xpZW50LWxvY2FsZS9jbGllbnQnO1xuLy8gVHlwZS1vbmx5OiBwdWxscyB0aGUgc2V0dGluZ3Mtc3VyZmFjZSBTbG90TWFwIG1lcmdlIGFuZCBjdHguc2V0dGluZ3NTY29wZS5cbmltcG9ydCB0eXBlIHt9IGZyb20gJ0BkZWVwc2Vlay1haS9kc2gtY2xpZW50LXVpLXNldHRpbmdzL2NsaWVudCc7XG4vLyBUeXBlLW9ubHk6IHB1bGxzIHRoZSBgc2V0dGluZ3MucGx1Z2luLml0ZW1gIFNsb3RNYXAgbWVyZ2UuXG5pbXBvcnQgdHlwZSB7fSBmcm9tICdAZGVlcHNlZWstYWkvZHNoLWNsaWVudC11aS1zZXR0aW5ncy1wbHVnaW5zL2NsaWVudCc7XG5pbXBvcnQgeyBBdXRvQ29udGludWVSdW5uZXIsIHJlc29sdmVDb25maWcsIHR5cGUgQXV0b0NvbnRpbnVlU2V0dGluZ3MgfSBmcm9tICcuL2VuZ2luZS50cyc7XG5pbXBvcnQgeyBlbiwgemgsIHR5cGUgU2V0dGluZ3NDYXJkS2V5IH0gZnJvbSAnLi9sb2NhbGVzLnRzJztcbmltcG9ydCB7XG4gIEF1dG9Db250aW51ZVNldHRpbmdzQ2FyZCxcbiAgQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkQ29udHJvbGxlcixcbn0gZnJvbSAnLi9zZXR0aW5ncy1jYXJkLnRzeCc7XG5cbi8qKiDlrqLmiLfnq6/moLnkuIrkuIvmlofnmoQgY29ubmVjdGlvbiDmnI3liqEo55SxIGRzaC1jbGllbnQtY29ubmVjdGlvbiDmjILovb0p44CCICovXG5kZWNsYXJlIG1vZHVsZSAnQGRlZXBzZWVrLWFpL2NvcmRpcycge1xuICBpbnRlcmZhY2UgQ29udGV4dCB7XG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbkhhbmRsZTtcbiAgfVxufVxuXG4vKiogRGljdGlvbmFyeSBuYW1lc3BhY2Ugb3duZWQgYnkgdGhpcyBwbHVnaW4uICovXG5jb25zdCBOUyA9ICdhdXRvLWNvbnRpbnVlJztcblxuLyoqIFNldHRpbmdzIG5hbWVzcGFjZSB0aGUgZW5naW5lIHJlYWRzIGFuZCB0aGUgc2V0dGluZ3MgY2FyZCBlZGl0cy4gKi9cbmNvbnN0IFNFVFRJTkdTX05TID0gJ2F1dG8tY29udGludWUnO1xuXG5kZWNsYXJlIG1vZHVsZSAnQGRlZXBzZWVrLWFpL2RzaC1jbGllbnQtdWktc2xvdHMnIHtcbiAgaW50ZXJmYWNlIExvY2FsZU5hbWVzcGFjZU1hcCB7XG4gICAgLyoqIGF1dG8tY29udGludWUgc2V0dGluZ3MtY2FyZCBjb3B5LiAqL1xuICAgICdhdXRvLWNvbnRpbnVlJzogU2V0dGluZ3NDYXJkS2V5O1xuICB9XG59XG5cbi8qKiBTZXJ2aWNlcyByZXF1aXJlZCBieSB0aGlzIHBsdWdpbi4gKi9cbmV4cG9ydCBjb25zdCBpbmplY3QgPSBbJ3Nsb3RzJywgJ2xvY2FsZScsICdjb25uZWN0aW9uJywgJ3NldHRpbmdzU2NvcGUnXTtcblxuLyoqIOW9k+WJjSBydW5uZXIoSE1SIOmHjei9veaXtuWFiOmUgOavgeaXp+eahOWGjeW7uuaWsOeahCnjgIIgKi9cbmxldCBjdXJyZW50OiBBdXRvQ29udGludWVSdW5uZXIgfCBudWxsID0gbnVsbDtcblxuLyoqXG4gKiBQbHVnaW4gYm9keTogbW91bnQgdGhlIGVuZ2luZSBhbmQgdGhlIHNldHRpbmdzIGNhcmQuXG4gKiBAcGFyYW0gY3R4IC0gY2xpZW50IHJvb3QgY29udGV4dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5KGN0eDogQ2xpZW50Q29udGV4dCk6IHZvaWQge1xuICBjdHguZWZmZWN0KCgpID0+IGN0eC5sb2NhbGUucmVnaXN0ZXIoTlMsIHsgemgsIGVuIH0pLCAnYXV0by1jb250aW51ZTogZGljdGlvbmFyaWVzJyk7XG5cbiAgLy8gRW5naW5lOiByZWFkcyB0aGUgc2V0dGluZ3Mgc2NvcGUgbGl2ZSwgc28gR1VJIGNoYW5nZXMgYXBwbHkgaW1tZWRpYXRlbHkuXG4gIGNvbnN0IHNjb3BlID0gY3R4LnNldHRpbmdzU2NvcGUuYmluZDxBdXRvQ29udGludWVTZXR0aW5ncz4oeyBuYW1lc3BhY2U6IFNFVFRJTkdTX05TIH0pO1xuICBjdXJyZW50Py5kaXNwb3NlKCk7XG4gIGN1cnJlbnQgPSBuZXcgQXV0b0NvbnRpbnVlUnVubmVyKGN0eC5jb25uZWN0aW9uLmFwaSwgKCkgPT4gcmVzb2x2ZUNvbmZpZyhzY29wZS5nZXRTbmFwc2hvdCgpLnZhbHVlKSk7XG5cbiAgLy8gUGx1Z2luIGNvbmZpZ3VyYXRpb24gY2FyZDogb25lIHN0YWdlZCBmb3JtIG92ZXIgdGhlIGBhdXRvLWNvbnRpbnVlYFxuICAvLyBzZXR0aW5ncyBuYW1lc3BhY2UsIGNvbnRyaWJ1dGVkIHRvIHRoZSBwbHVnaW4tY29uZmlndXJhdGlvbiBzZWN0aW9uLlxuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEF1dG9Db250aW51ZVNldHRpbmdzQ2FyZENvbnRyb2xsZXIoc2NvcGUpO1xuICBjdHguc2xvdHMuaW5qZWN0KCdzZXR0aW5ncy5wbHVnaW4uaXRlbScsICgpID0+XG4gICAgY3R4LnNsb3RzLnJlZ2lzdGVyKFxuICAgICAge1xuICAgICAgICBuYW1lOiAnc2V0dGluZ3MucGx1Z2luLml0ZW0nLFxuICAgICAgICBpZDogJ2F1dG8tY29udGludWUnLFxuICAgICAgICBvcmRlcjogOTAsXG4gICAgICAgIGxvY2FsZTogTlMsXG4gICAgICAgIGluamVjdDogKCkgPT4gY29udHJvbGxlci5pbmplY3QoKSxcbiAgICAgIH0sXG4gICAgICBBdXRvQ29udGludWVTZXR0aW5nc0NhcmQsXG4gICAgKSxcbiAgKTtcbn1cbiIsICIvKipcbiAqIEF1dG8tY29udGludWUgZW5naW5lIOKAlCBicm93c2VyIGhhbGYgY29yZS5cbiAqXG4gKiBXYXRjaGVzIHRoZSB0d28gbGl2ZSBldmVudCBzdHJlYW1zIG9mIHRoZSBkc2ggd2ViIEdVSSAobXV4ICsgaG9zdCk6XG4gKiAgIC0gdHVybnMgZW5kZWQgZm9yIGEgbm9uLWh1bWFuIHJlYXNvbiAoYHR1cm4vZW5kYCByZWFzb24g4oiIIGVycm9yIC8gaW50ZXJydXB0ZWQgLyBtYXgtdG9rZW5zKVxuICogICAtIGhvc3QtcmVwb3J0ZWQgYWdlbnQgZmFpbHVyZXMgd2l0aCBubyB0dXJuIHBvc2l0aW9uIChgaG9zdC9hZ2VudC1lcnJvcmApXG4gKiBBZnRlciBhIGdyYWNlIHBlcmlvZCBpdCBzZW5kcyBhIHF1ZXVlZCBwcm9tcHQgKGRlZmF1bHQg44CM57un57ut44CNKSB0byB0aGF0XG4gKiBzZXNzaW9uIOKAlCBleGFjdGx5IGVxdWl2YWxlbnQgdG8gdGhlIHVzZXIgdHlwaW5nIGl0IG1hbnVhbGx5LlxuICpcbiAqIEFsbCBiZWhhdmlvciBpcyBkcml2ZW4gYnkgdGhlIGBhdXRvLWNvbnRpbnVlYCBzZXR0aW5ncyBuYW1lc3BhY2UgKHNlZSB0aGVcbiAqIHBsdWdpbidzIHNldHRpbmdzIGNhcmQpOyBldmVyeSBrbm9iIGJlbG93IGlzIHVzZXItY29uZmlndXJhYmxlIHRoZXJlLlxuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgSG9zdEZyYW1lLFxuICBJQXBpQ2xpZW50LFxuICBNdXhGcmFtZSxcbiAgU2Vzc2lvbklkLFxuICBTZXNzaW9uU3VtbWFyeSxcbn0gZnJvbSAnQGRlZXBzZWVrLWFpL2RzaC1jbGllbnQtY29ubmVjdGlvbi9jbGllbnQnO1xuaW1wb3J0IHR5cGUgeyBTZXNzaW9uRXZlbnQgfSBmcm9tICdAZGVlcHNlZWstYWkvZHNoLXNlc3Npb24vdHlwZXMnO1xuXG4vKiogVGhlIGBhdXRvLWNvbnRpbnVlYCBzZXR0aW5ncyBzZWN0aW9uIChhbGwgZmllbGRzIG9wdGlvbmFsIG9uIHRoZSB3aXJlOyB0aGUgaG9zdCBzY2hlbWEgY2FycmllcyBkZWZhdWx0cykuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dG9Db250aW51ZVNldHRpbmdzIHtcbiAgLyoqIFRleHQgYXV0b21hdGljYWxseSBzZW50IGFmdGVyIGFuIGludGVycnVwdGlvbi4gKi9cbiAgY29udGludWVUZXh0Pzogc3RyaW5nO1xuICAvKiogR3JhY2UgcGVyaW9kIGFmdGVyIGFuIGludGVycnVwdGlvbiBiZWZvcmUgYXV0by1zZW5kaW5nIChtcykuICovXG4gIGdyYWNlTXM/OiBudW1iZXI7XG4gIC8qKiBNaW5pbXVtIGludGVydmFsIGJldHdlZW4gdHdvIGF1dG8tY29udGludWVzIHBlciBzZXNzaW9uIChtcykuICovXG4gIGNvb2xkb3duTXM/OiBudW1iZXI7XG4gIC8qKiBNYXggY29uc2VjdXRpdmUgYXV0by1jb250aW51ZXMgcGVyIHNlc3Npb24gYmVmb3JlIHN0b3BwaW5nLiAqL1xuICBtYXhDb25zZWN1dGl2ZT86IG51bWJlcjtcbiAgLyoqIFNjYW4gcmVjZW50bHkgaW50ZXJydXB0ZWQgc2Vzc2lvbnMgb24gcGFnZSBsb2FkIC8gcmVjb25uZWN0LiAqL1xuICBzY2FuT25Cb290PzogYm9vbGVhbjtcbiAgLyoqIE1heCBzZXNzaW9ucyB0aGUgc2NhbiBjaGVja3MgKG1vc3QgcmVjZW50bHkgdXBkYXRlZCkuICovXG4gIHNjYW5MaW1pdD86IG51bWJlcjtcbiAgLyoqIFNjYW4gb25seSBjb25zaWRlcnMgaW50ZXJydXB0aW9ucyBpbnNpZGUgdGhpcyB3aW5kb3cgKG1zKS4gKi9cbiAgZnJlc2hNcz86IG51bWJlcjtcbiAgLyoqIERlbGF5IGJlZm9yZSBzY2FubmluZyBhZnRlciBhIHJlY29ubmVjdCAobXMpLiAqL1xuICByZWNvbm5lY3RTY2FuRGVsYXlNcz86IG51bWJlcjtcbiAgLyoqIFNTRSByZWNvbm5lY3QgYmFja29mZiAobXMpLiAqL1xuICByZWNvbm5lY3RCYWNrb2ZmTXM/OiBudW1iZXI7XG4gIC8qKiBMb2cgYFthdXRvLWNvbnRpbnVlXWAgbGluZXMgdG8gdGhlIGJyb3dzZXIgY29uc29sZS4gKi9cbiAgdmVyYm9zZT86IGJvb2xlYW47XG59XG5cbi8qKiBGdWxseSByZXNvbHZlZCBjb25maWd1cmF0aW9uIChidWlsdC1pbiBkZWZhdWx0cyArIHVzZXIgb3ZlcnJpZGVzKS4gKi9cbmV4cG9ydCB0eXBlIEF1dG9Db250aW51ZUNvbmZpZyA9IFJlcXVpcmVkPEF1dG9Db250aW51ZVNldHRpbmdzPjtcblxuLyoqIEJ1aWx0LWluIGRlZmF1bHRzIOKAlCBtdXN0IG1hdGNoIHRoZSBob3N0IHNjaGVtYSBkZWZhdWx0cyBpbiBzcmMvaW5kZXgudHMuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9DT05GSUc6IEF1dG9Db250aW51ZUNvbmZpZyA9IHtcbiAgY29udGludWVUZXh0OiAn57un57utJyxcbiAgZ3JhY2VNczogMzAwMCxcbiAgY29vbGRvd25NczogMjAwMDAsXG4gIG1heENvbnNlY3V0aXZlOiAzLFxuICBzY2FuT25Cb290OiB0cnVlLFxuICBzY2FuTGltaXQ6IDgsXG4gIGZyZXNoTXM6IDE1ICogNjAgKiAxMDAwLFxuICByZWNvbm5lY3RTY2FuRGVsYXlNczogNTAwMCxcbiAgcmVjb25uZWN0QmFja29mZk1zOiAzMDAwLFxuICB2ZXJib3NlOiB0cnVlLFxufTtcblxuZnVuY3Rpb24gbnVtYmVyT3IodmFsdWU6IHVua25vd24sIGZhbGxiYWNrOiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpICYmIHZhbHVlID49IDAgPyB2YWx1ZSA6IGZhbGxiYWNrO1xufVxuXG5mdW5jdGlvbiBib29sZWFuT3IodmFsdWU6IHVua25vd24sIGZhbGxiYWNrOiBib29sZWFuKTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJyA/IHZhbHVlIDogZmFsbGJhY2s7XG59XG5cbi8qKiBSZXNvbHZlIGEgKHBvc3NpYmx5IHBhcnRpYWwgLyBub3QteWV0LWxvYWRlZCkgc2V0dGluZ3Mgc2VjdGlvbiB0byBhIGZ1bGwgY29uZmlnLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVDb25maWcoc2VjdGlvbjogQXV0b0NvbnRpbnVlU2V0dGluZ3MgfCB1bmRlZmluZWQpOiBBdXRvQ29udGludWVDb25maWcge1xuICBjb25zdCB2YWx1ZSA9IHNlY3Rpb24gPz8ge307XG4gIGNvbnN0IHRleHQgPVxuICAgIHR5cGVvZiB2YWx1ZS5jb250aW51ZVRleHQgPT09ICdzdHJpbmcnICYmIHZhbHVlLmNvbnRpbnVlVGV4dC50cmltKCkgIT09ICcnXG4gICAgICA/IHZhbHVlLmNvbnRpbnVlVGV4dFxuICAgICAgOiBERUZBVUxUX0NPTkZJRy5jb250aW51ZVRleHQ7XG4gIHJldHVybiB7XG4gICAgY29udGludWVUZXh0OiB0ZXh0LFxuICAgIGdyYWNlTXM6IG51bWJlck9yKHZhbHVlLmdyYWNlTXMsIERFRkFVTFRfQ09ORklHLmdyYWNlTXMpLFxuICAgIGNvb2xkb3duTXM6IG51bWJlck9yKHZhbHVlLmNvb2xkb3duTXMsIERFRkFVTFRfQ09ORklHLmNvb2xkb3duTXMpLFxuICAgIG1heENvbnNlY3V0aXZlOiBNYXRoLm1heCgxLCBudW1iZXJPcih2YWx1ZS5tYXhDb25zZWN1dGl2ZSwgREVGQVVMVF9DT05GSUcubWF4Q29uc2VjdXRpdmUpKSxcbiAgICBzY2FuT25Cb290OiBib29sZWFuT3IodmFsdWUuc2Nhbk9uQm9vdCwgREVGQVVMVF9DT05GSUcuc2Nhbk9uQm9vdCksXG4gICAgc2NhbkxpbWl0OiBNYXRoLm1heCgxLCBudW1iZXJPcih2YWx1ZS5zY2FuTGltaXQsIERFRkFVTFRfQ09ORklHLnNjYW5MaW1pdCkpLFxuICAgIGZyZXNoTXM6IG51bWJlck9yKHZhbHVlLmZyZXNoTXMsIERFRkFVTFRfQ09ORklHLmZyZXNoTXMpLFxuICAgIHJlY29ubmVjdFNjYW5EZWxheU1zOiBudW1iZXJPcih2YWx1ZS5yZWNvbm5lY3RTY2FuRGVsYXlNcywgREVGQVVMVF9DT05GSUcucmVjb25uZWN0U2NhbkRlbGF5TXMpLFxuICAgIHJlY29ubmVjdEJhY2tvZmZNczogbnVtYmVyT3IodmFsdWUucmVjb25uZWN0QmFja29mZk1zLCBERUZBVUxUX0NPTkZJRy5yZWNvbm5lY3RCYWNrb2ZmTXMpLFxuICAgIHZlcmJvc2U6IGJvb2xlYW5Pcih2YWx1ZS52ZXJib3NlLCBERUZBVUxUX0NPTkZJRy52ZXJib3NlKSxcbiAgfTtcbn1cblxuLyoqIOinhuS4uuOAjOmdnuS6uuS4uuS4reaWreOAjeeahOWbnuWQiOe7k+adn+WOn+WboOOAgmFib3J0ZWQo55So5oi35YGc5q2iKeS4jiBibG9ja2VkKOetlueVpeaLkue7nSnkuI3lnKjlhbbkuK3jgIIgKi9cbnR5cGUgTm9uSHVtYW5SZWFzb24gPSAnZXJyb3InIHwgJ2ludGVycnVwdGVkJyB8ICdtYXgtdG9rZW5zJztcblxuZnVuY3Rpb24gaXNOb25IdW1hblJlYXNvbihraW5kOiBzdHJpbmcpOiBraW5kIGlzIE5vbkh1bWFuUmVhc29uIHtcbiAgcmV0dXJuIGtpbmQgPT09ICdlcnJvcicgfHwga2luZCA9PT0gJ2ludGVycnVwdGVkJyB8fCBraW5kID09PSAnbWF4LXRva2Vucyc7XG59XG5cbmZ1bmN0aW9uIHNsZWVwKG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG59XG5cbi8qKiDmtY/op4jlmajlvZPliY0gSUFOQSDml7bljLo7IOS4jeWPr+eUqOaXtuecgeeVpSjlrr/kuLvlhYHorrjnnIHnlaUp44CCICovXG5mdW5jdGlvbiBjbGllbnRUaW1lWm9uZSgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICB0cnkge1xuICAgIHJldHVybiBJbnRsLkRhdGVUaW1lRm9ybWF0KCkucmVzb2x2ZWRPcHRpb25zKCkudGltZVpvbmUgfHwgdW5kZWZpbmVkO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKiDot6jmoIfnrb7pobXkupLmlqXkuI7lhrfljbTorrDlvZUo5LuF5rWP6KeI5Zmo5pys5ZywLCDkuI3okL3nm5jliLDlrr/kuLsp44CCICovXG5jb25zdCBsb2NrUHJlZml4ID0gJ2RzaC1hdXRvLWNvbnRpbnVlOic7XG5jb25zdCBsb2NrS2V5ID0gKHNlc3Npb25JZDogU2Vzc2lvbklkKSA9PiBgJHtsb2NrUHJlZml4fWxvY2s6JHtzZXNzaW9uSWR9YDtcbmNvbnN0IHN0YW1wS2V5ID0gKHNlc3Npb25JZDogU2Vzc2lvbklkKSA9PiBgJHtsb2NrUHJlZml4fWxhc3Q6JHtzZXNzaW9uSWR9YDtcblxuLyoqIOWwneivleeLrOWNoOacrOasoeWPkemAgTog5Lik5Liq5qCH562+6aG15ZCM5pe26Kem5Y+R5pe25Y+q5pyJ5LiA5Liq5oiQ5Yqf44CCICovXG5mdW5jdGlvbiBjbGFpbVNlbmQoc2Vzc2lvbklkOiBTZXNzaW9uSWQpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICBjb25zdCB0b2tlbiA9IGAke0RhdGUubm93KCl9LSR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMil9YDtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShsb2NrS2V5KHNlc3Npb25JZCksIHRva2VuKTtcbiAgICByZXR1cm4gbG9jYWxTdG9yYWdlLmdldEl0ZW0obG9ja0tleShzZXNzaW9uSWQpKSA9PT0gdG9rZW47XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB0cnVlOyAvLyDlrZjlgqjkuI3lj6/nlKgo6ZqQ56eB5qih5byP562JKeaXtuaUvuihjFxuICB9XG59XG5cbmZ1bmN0aW9uIHJlbGVhc2VTZW5kKHNlc3Npb25JZDogU2Vzc2lvbklkKTogdm9pZCB7XG4gIHRyeSB7XG4gICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0obG9ja0tleShzZXNzaW9uSWQpKTtcbiAgfSBjYXRjaCB7XG4gICAgLyogaWdub3JlICovXG4gIH1cbn1cblxuLyoqIOivuy/lhpnjgIzkuIrmrKHoh6rliqjlj5HpgIHjgI3ml7bpl7TmiLMo6Leo5qCH562+6aG15Ya35Y20KeOAgiAqL1xuZnVuY3Rpb24gcmVhZExhc3RTZW5kKHNlc3Npb25JZDogU2Vzc2lvbklkKTogbnVtYmVyIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gTnVtYmVyKGxvY2FsU3RvcmFnZS5nZXRJdGVtKHN0YW1wS2V5KHNlc3Npb25JZCkpID8/IDApIHx8IDA7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiAwO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdyaXRlTGFzdFNlbmQoc2Vzc2lvbklkOiBTZXNzaW9uSWQsIGF0OiBudW1iZXIpOiB2b2lkIHtcbiAgdHJ5IHtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShzdGFtcEtleShzZXNzaW9uSWQpLCBTdHJpbmcoYXQpKTtcbiAgfSBjYXRjaCB7XG4gICAgLyogaWdub3JlICovXG4gIH1cbn1cblxuLyoqIOavj+S8muivnei/kOihjOaXtueKtuaAgeOAgiAqL1xuaW50ZXJmYWNlIFNlc3Npb25TdGF0ZSB7XG4gIC8qKiDov57nu63oh6rliqjjgIznu6fnu63jgI3mrKHmlbA7IOaIkOWKn+WbnuWQiOaIlueUqOaIt+aJi+WKqOS7i+WFpeWQjuW9kumbtuOAgiAqL1xuICBjb25zZWN1dGl2ZTogbnVtYmVyO1xuICAvKiog5LiK5qyh6Ieq5Yqo44CM57un57ut44CN5pe26Ze05oiz44CCICovXG4gIGxhc3RBdXRvQXQ6IG51bWJlcjtcbiAgLyoqIOS4iuasoeiHquWKqOOAjOe7p+e7reOAjeWwneivlSjmiJDlip/miJblpLHotKUp5pe26Ze05oizOyDpmLLmraLlpLHotKXlnLrmma/kuIvnmoTlv6vpgJ/ph43or5Xlvqrnjq/jgIIgKi9cbiAgbGFzdEF0dGVtcHRBdDogbnVtYmVyO1xuICAvKiog5oiR5Lus5LiK5qyh6Ieq5Yqo5Y+R6YCB55qE5paH5pysKOeUqOS6juivhuWIq+iHquW3seeahOWbnuaYvinjgIIgKi9cbiAgbGFzdFNlbnRUZXh0OiBzdHJpbmc7XG4gIC8qKiDlrr3pmZDmnJ/lrprml7blmago6L+b6KGM5Lit55qE5b6F5Y+R6YCBKeOAgiAqL1xuICBwZW5kaW5nVGltZXI6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgLyoqIOWuv+S4u+adg+WogSBydW5uaW5nIOS9jSjmnaXoh6ogaG9zdC9zZXNzaW9uLXN0YXR1cyDkuI7lm57lkIjkuovku7Yp44CCICovXG4gIHJ1bm5pbmc6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gIC8qKiDlvZPliY3mjpLpmJ/mtojmga/mlbAo5p2l6IeqIHNlc3Npb24vcXVldWUg5binKeOAgiAqL1xuICBxdWV1ZWQ6IG51bWJlcjtcbiAgLyoqIOWtkOS7o+eQhuS8muivnShob3N0L3Nlc3Npb24tYWRkZWQg5bimIHBhcmVudFNlc3Npb25JZCnjgIIgKi9cbiAgc3ViYWdlbnQ6IGJvb2xlYW47XG59XG5cbmNvbnN0IGZyZXNoU3RhdGUgPSAoKTogU2Vzc2lvblN0YXRlID0+ICh7XG4gIGNvbnNlY3V0aXZlOiAwLFxuICBsYXN0QXV0b0F0OiAwLFxuICBsYXN0QXR0ZW1wdEF0OiAwLFxuICBsYXN0U2VudFRleHQ6ICcnLFxuICBwZW5kaW5nVGltZXI6IHVuZGVmaW5lZCxcbiAgcnVubmluZzogdW5kZWZpbmVkLFxuICBxdWV1ZWQ6IDAsXG4gIHN1YmFnZW50OiBmYWxzZSxcbn0pO1xuXG4vKiog5Yik5a6a5LiA5p2hIHVzZXIvbWVzc2FnZSDmmK/lkKbmmK/miJHku6zoh6rlt7Hoh6rliqjlj5HpgIHnmoTlm57mmL7jgIIgKi9cbmZ1bmN0aW9uIGlzT3VyRWNobyhzdGF0ZTogU2Vzc2lvblN0YXRlLCBldmVudDogU2Vzc2lvbkV2ZW50KTogYm9vbGVhbiB7XG4gIGlmIChldmVudC50eXBlICE9PSAndXNlci9tZXNzYWdlJykgcmV0dXJuIGZhbHNlO1xuICBjb25zdCBtZXNzYWdlID0gZXZlbnQuZGF0YTtcbiAgaWYgKG1lc3NhZ2Uuc291cmNlLmtpbmQgIT09ICd1c2VyJykgcmV0dXJuIGZhbHNlO1xuICBpZiAoc3RhdGUubGFzdFNlbnRUZXh0ID09PSAnJykgcmV0dXJuIGZhbHNlO1xuICBpZiAoRGF0ZS5ub3coKSAtIHN0YXRlLmxhc3RBdXRvQXQgPiAzMDAwMCkgcmV0dXJuIGZhbHNlO1xuICBjb25zdCB0ZXh0ID0gbWVzc2FnZS5jb250ZW50XG4gICAgLmZpbHRlcigocGFydCk6IHBhcnQgaXMgeyB0eXBlOiAndGV4dCc7IHRleHQ6IHN0cmluZyB9ID0+IHBhcnQudHlwZSA9PT0gJ3RleHQnKVxuICAgIC5tYXAoKHBhcnQpID0+IHBhcnQudGV4dClcbiAgICAuam9pbignJyk7XG4gIHJldHVybiB0ZXh0ID09PSBzdGF0ZS5sYXN0U2VudFRleHQ7XG59XG5cbi8qKiBTU0Ug5bin5aSW5aOzOiBgeyBycGNJZCwgcGF5bG9hZCB9YOOAgiAqL1xudHlwZSBGcmFtZUVudmVsb3BlPFQ+ID0geyBwYXlsb2FkOiBUIH07XG5cbi8qKlxuICog5LqL5Lu25rWB5rO1OiDluKbmjIfmlbDpgIDpgb/nmoQgU1NFIOmHjei/nuW+queOr+OAglxuICogLSDku47mnKrmlLbliLDku7vkvZXluKco5a6/5Li75pyq5bCx57uqKTog6YCA6YG/6YeN6K+VLCDkuI3op6blj5Hmiavmj49cbiAqIC0g5pu+6L+e5LiK5ZCO5pat5byAOiDph43ov54sIOW5tumAmui/hyBvblJlY29ubmVjdCDpgJrnn6XlpJblsYIo5a6/5Li75Y+v6IO95bSp5rqD6YeN5ZCv6L+HKVxuICovXG5hc3luYyBmdW5jdGlvbiBwdW1wU3RyZWFtPFQ+KFxuICBvcGVuOiAoc2lnbmFsOiBBYm9ydFNpZ25hbCkgPT4gQXN5bmNJdGVyYWJsZTxGcmFtZUVudmVsb3BlPFQ+PixcbiAgb25GcmFtZTogKHBheWxvYWQ6IFQpID0+IHZvaWQsXG4gIG9uUmVjb25uZWN0OiAoKSA9PiB2b2lkLFxuICBnZXRCYWNrb2ZmOiAoKSA9PiBudW1iZXIsXG4gIGxvZzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZCxcbiAgc2lnbmFsOiBBYm9ydFNpZ25hbCxcbik6IFByb21pc2U8dm9pZD4ge1xuICBsZXQgYmFja29mZiA9IGdldEJhY2tvZmYoKTtcbiAgd2hpbGUgKCFzaWduYWwuYWJvcnRlZCkge1xuICAgIGxldCBjb25uZWN0ZWQgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgZm9yIGF3YWl0IChjb25zdCBlbnZlbG9wZSBvZiBvcGVuKHNpZ25hbCkpIHtcbiAgICAgICAgY29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgb25GcmFtZShlbnZlbG9wZS5wYXlsb2FkKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHJldHVybjtcbiAgICAgIGxvZyhgc3RyZWFtIGVycm9yOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gKTtcbiAgICB9XG4gICAgaWYgKCFjb25uZWN0ZWQpIHtcbiAgICAgIC8vIOS7juacqui/nuS4iijlrr/kuLvmnKrlsLHnu6opOiDmjIfmlbDpgIDpgb/ph43or5VcbiAgICAgIGF3YWl0IHNsZWVwKGJhY2tvZmYpO1xuICAgICAgYmFja29mZiA9IE1hdGgubWluKGJhY2tvZmYgKiAyLCAxNTAwMCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgLy8g5pu+6L+e5LiK5ZCO5pat5byAIOKGkiDph43ov57lubbop6blj5HlpJblsYLmiavmj49cbiAgICBiYWNrb2ZmID0gZ2V0QmFja29mZigpO1xuICAgIG9uUmVjb25uZWN0KCk7XG4gICAgYXdhaXQgc2xlZXAoYmFja29mZik7XG4gIH1cbn1cblxuLyoqIOaPkuS7tuS4u+S9kzog5LiA5p2hIG11eCDmtYEgKyDkuIDmnaEgaG9zdCDmtYEgKyDlkK/liqgv6YeN6L+e5omr5o+P44CCICovXG5leHBvcnQgY2xhc3MgQXV0b0NvbnRpbnVlUnVubmVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBzdGF0ZXMgPSBuZXcgTWFwPFNlc3Npb25JZCwgU2Vzc2lvblN0YXRlPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IG11eEFib3J0ID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGhvc3RBYm9ydCA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgcHJpdmF0ZSBkaXNwb3NlZCA9IGZhbHNlO1xuICBwcml2YXRlIHJlY29ubmVjdFNjYW5zID0gMDtcblxuICAvKipcbiAgICogQHBhcmFtIGFwaSAtIHNoYXJlZCB3aXJlIGNsaWVudCAoY3R4LmNvbm5lY3Rpb24uYXBpKS5cbiAgICogQHBhcmFtIGdldENvbmZpZyAtIHJlYWQgdGhlIGN1cnJlbnQgcmVzb2x2ZWQgY29uZmlndXJhdGlvbiAoc2V0dGluZ3Mgc2NvcGUpLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBhcGk6IElBcGlDbGllbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBnZXRDb25maWc6ICgpID0+IEF1dG9Db250aW51ZUNvbmZpZyxcbiAgKSB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5nZXRDb25maWcoKTtcbiAgICB2b2lkIHRoaXMucnVuTXV4KCk7XG4gICAgdm9pZCB0aGlzLnJ1bkhvc3QoKTtcbiAgICBpZiAoY29uZmlnLnNjYW5PbkJvb3QpIHtcbiAgICAgIC8vIOWQr+WKqOaXtui/nuaOpeWPr+iDveWwmuacquW7uueriywg5b6q546v6YeN6K+V55u05Yiw5oiQ5Yqf44CCXG4gICAgICB2b2lkIHRoaXMuYm9vdFNjYW5Mb29wKCk7XG4gICAgfVxuICAgIHRoaXMubG9nKFxuICAgICAgYOW3suWQr+WKqCjmlofmnKw9XCIke2NvbmZpZy5jb250aW51ZVRleHR9XCIsIOWuvemZkCAke2NvbmZpZy5ncmFjZU1zfW1zLCBgICtcbiAgICAgICAgYOWGt+WNtCAke2NvbmZpZy5jb29sZG93bk1zfW1zLCDmnIDlpJrov57nu60gJHtjb25maWcubWF4Q29uc2VjdXRpdmV9IOasoSlgLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGxvZyhtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5nZXRDb25maWcoKS52ZXJib3NlKSBjb25zb2xlLmluZm8oYFthdXRvLWNvbnRpbnVlXSAke21lc3NhZ2V9YCk7XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuZGlzcG9zZWQgPSB0cnVlO1xuICAgIHRoaXMubXV4QWJvcnQuYWJvcnQoKTtcbiAgICB0aGlzLmhvc3RBYm9ydC5hYm9ydCgpO1xuICAgIGZvciAoY29uc3Qgc3RhdGUgb2YgdGhpcy5zdGF0ZXMudmFsdWVzKCkpIHtcbiAgICAgIGlmIChzdGF0ZS5wZW5kaW5nVGltZXIgIT09IHVuZGVmaW5lZCkgY2xlYXJUaW1lb3V0KHN0YXRlLnBlbmRpbmdUaW1lcik7XG4gICAgfVxuICAgIHRoaXMuc3RhdGVzLmNsZWFyKCk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRlKHNlc3Npb25JZDogU2Vzc2lvbklkKTogU2Vzc2lvblN0YXRlIHtcbiAgICBsZXQgc3RhdGUgPSB0aGlzLnN0YXRlcy5nZXQoc2Vzc2lvbklkKTtcbiAgICBpZiAoc3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgc3RhdGUgPSBmcmVzaFN0YXRlKCk7XG4gICAgICB0aGlzLnN0YXRlcy5zZXQoc2Vzc2lvbklkLCBzdGF0ZSk7XG4gICAgfVxuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIHByaXZhdGUgcnVuTXV4KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBwdW1wU3RyZWFtPE11eEZyYW1lPihcbiAgICAgIChzaWduYWwpID0+IHRoaXMuYXBpLmV2ZW50cy5tdXgoe30sIHNpZ25hbCksXG4gICAgICAocGF5bG9hZCkgPT4gdGhpcy5vbk11eEZyYW1lKHBheWxvYWQpLFxuICAgICAgKCkgPT4gdGhpcy5zY2hlZHVsZVJlY29ubmVjdFNjYW4oKSxcbiAgICAgICgpID0+IHRoaXMuZ2V0Q29uZmlnKCkucmVjb25uZWN0QmFja29mZk1zLFxuICAgICAgKG0pID0+IHRoaXMubG9nKG0pLFxuICAgICAgdGhpcy5tdXhBYm9ydC5zaWduYWwsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgcnVuSG9zdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gcHVtcFN0cmVhbTxIb3N0RnJhbWU+KFxuICAgICAgKHNpZ25hbCkgPT4gdGhpcy5hcGkuZXZlbnRzLmhvc3Qoe30sIHNpZ25hbCksXG4gICAgICAocGF5bG9hZCkgPT4gdGhpcy5vbkhvc3RGcmFtZShwYXlsb2FkKSxcbiAgICAgICgpID0+IHRoaXMuc2NoZWR1bGVSZWNvbm5lY3RTY2FuKCksXG4gICAgICAoKSA9PiB0aGlzLmdldENvbmZpZygpLnJlY29ubmVjdEJhY2tvZmZNcyxcbiAgICAgIChtKSA9PiB0aGlzLmxvZyhtKSxcbiAgICAgIHRoaXMuaG9zdEFib3J0LnNpZ25hbCxcbiAgICApO1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLSBtdXgg5binIC0tLS0tLS0tLS1cblxuICBwcml2YXRlIG9uTXV4RnJhbWUoZnJhbWU6IE11eEZyYW1lKTogdm9pZCB7XG4gICAgc3dpdGNoIChmcmFtZS50eXBlKSB7XG4gICAgICBjYXNlICdzZXNzaW9uL2V2ZW50JzpcbiAgICAgICAgdGhpcy5vblNlc3Npb25FdmVudChmcmFtZS5zZXNzaW9uSWQsIGZyYW1lLmV2ZW50KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdzZXNzaW9uL3F1ZXVlJzpcbiAgICAgICAgdGhpcy5zdGF0ZShmcmFtZS5zZXNzaW9uSWQpLnF1ZXVlZCA9IGZyYW1lLml0ZW1zLmxlbmd0aDtcbiAgICAgICAgaWYgKGZyYW1lLml0ZW1zLmxlbmd0aCA+IDApIHRoaXMuY2FuY2VsUGVuZGluZyhmcmFtZS5zZXNzaW9uSWQsICflh7rnjrDmjpLpmJ/mtojmga8nKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdzdHJlYW0vZXJyb3InOlxuICAgICAgICB0aGlzLmxvZyhgbXV4IHN0cmVhbS9lcnJvcjogJHtmcmFtZS5lcnJvci5jb2RlfSAke2ZyYW1lLmVycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7IC8vIHNlc3Npb24vc3Vic2NyaWJlZOOAgWFwcHJvdmFsLyrjgIFxdWVzdGlvbi8q44CBc2Vzc2lvbi9qb2Jz44CBc2Vzc2lvbi9wcm9qZWN0aW9uIOS4juacrOaPkuS7tuaXoOWFs1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25TZXNzaW9uRXZlbnQoc2Vzc2lvbklkOiBTZXNzaW9uSWQsIGV2ZW50OiBTZXNzaW9uRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuc3RhdGUoc2Vzc2lvbklkKTtcbiAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgIGNhc2UgJ3R1cm4vc3RhcnQnOlxuICAgICAgICBzdGF0ZS5ydW5uaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jYW5jZWxQZW5kaW5nKHNlc3Npb25JZCwgJ+Wuv+S4u+iHquihjOW8gOWQr+aWsOWbnuWQiCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3R1cm4vZW5kJzoge1xuICAgICAgICBzdGF0ZS5ydW5uaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2FuY2VsUGVuZGluZyhzZXNzaW9uSWQsICfmlLbliLDmlrDnmoQgdHVybi9lbmQnKTtcbiAgICAgICAgY29uc3QgcmVhc29uID0gZXZlbnQuZGF0YS5yZWFzb247XG4gICAgICAgIGlmIChyZWFzb24ua2luZCA9PT0gJ2NvbXBsZXRlZCcpIHtcbiAgICAgICAgICAvLyDmiJDlip/lm57lkIg6IOaBouWkjeWBpeW6t+eKtuaAgVxuICAgICAgICAgIHN0YXRlLmNvbnNlY3V0aXZlID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChyZWFzb24ua2luZCA9PT0gJ2Fib3J0ZWQnKSB7XG4gICAgICAgICAgLy8g55So5oi35Li75Yqo5YGc5q2iOiDkuI3oh6rliqjnu6fnu60sIOinhuS4uueUqOaIt+S7i+WFpVxuICAgICAgICAgIHN0YXRlLmNvbnNlY3V0aXZlID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChyZWFzb24ua2luZCA9PT0gJ2Jsb2NrZWQnKSB7XG4gICAgICAgICAgLy8g562W55Wl5ouS57udOiDkuI3oh6rliqjnu6fnu61cbiAgICAgICAgfSBlbHNlIGlmIChpc05vbkh1bWFuUmVhc29uKHJlYXNvbi5raW5kKSkge1xuICAgICAgICAgIHRoaXMuc2NoZWR1bGUoc2Vzc2lvbklkLCBgdHVybi9lbmQ6JHtyZWFzb24ua2luZH1gKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3VzZXIvbWVzc2FnZSc6XG4gICAgICAgIGlmIChpc091ckVjaG8oc3RhdGUsIGV2ZW50KSkgYnJlYWs7IC8vIOaIkeS7rOiHquW3seeahOWbnuaYvlxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5zb3VyY2Uua2luZCA9PT0gJ3VzZXInKSB7XG4gICAgICAgICAgLy8g55So5oi35omL5Yqo5LuL5YWlXG4gICAgICAgICAgc3RhdGUuY29uc2VjdXRpdmUgPSAwO1xuICAgICAgICAgIHRoaXMuY2FuY2VsUGVuZGluZyhzZXNzaW9uSWQsICfnlKjmiLfmiYvliqjlj5HpgIHmtojmga8nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0gaG9zdCDluKcgLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgb25Ib3N0RnJhbWUoZnJhbWU6IEhvc3RGcmFtZSk6IHZvaWQge1xuICAgIHN3aXRjaCAoZnJhbWUudHlwZSkge1xuICAgICAgY2FzZSAnaG9zdC9zZXNzaW9uLXN0YXR1cyc6XG4gICAgICAgIHRoaXMuc3RhdGUoZnJhbWUuc2Vzc2lvbklkKS5ydW5uaW5nID0gZnJhbWUucnVubmluZztcbiAgICAgICAgaWYgKGZyYW1lLnJ1bm5pbmcpIHRoaXMuY2FuY2VsUGVuZGluZyhmcmFtZS5zZXNzaW9uSWQsICflrr/kuLvmiqXlkYrkvJror53lvIDlp4vov5DooYwnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdob3N0L3Nlc3Npb24tYWRkZWQnOlxuICAgICAgICB0aGlzLnN0YXRlKGZyYW1lLnNlc3Npb25JZCkuc3ViYWdlbnQgPSBmcmFtZS5wYXJlbnRTZXNzaW9uSWQgIT09IHVuZGVmaW5lZDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdob3N0L2FnZW50LWVycm9yJzpcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUoZnJhbWUuc2Vzc2lvbklkKS5zdWJhZ2VudCkgYnJlYWs7XG4gICAgICAgIHRoaXMubG9nKGBob3N0L2FnZW50LWVycm9yKCR7ZnJhbWUuc2Vzc2lvbklkfSk6ICR7ZnJhbWUubWVzc2FnZX1gKTtcbiAgICAgICAgdGhpcy5zY2hlZHVsZShmcmFtZS5zZXNzaW9uSWQsICdob3N0L2FnZW50LWVycm9yJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaG9zdC9zZXNzaW9uLXJlbW92ZWQnOlxuICAgICAgICB0aGlzLmNhbmNlbFBlbmRpbmcoZnJhbWUuc2Vzc2lvbklkLCAn5Lya6K+d5bey56e76ZmkJyk7XG4gICAgICAgIHRoaXMuc3RhdGVzLmRlbGV0ZShmcmFtZS5zZXNzaW9uSWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0g6LCD5bqmIC0tLS0tLS0tLS1cblxuICBwcml2YXRlIHNjaGVkdWxlKHNlc3Npb25JZDogU2Vzc2lvbklkLCByZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5zdGF0ZShzZXNzaW9uSWQpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKHN0YXRlLnN1YmFnZW50KSByZXR1cm47IC8vIOWtkOS7o+eQhuS8muivneeUseeItuS7o+eQhuWkhOeQhiwg5LiN5oqi6LeRXG4gICAgaWYgKHN0YXRlLnBlbmRpbmdUaW1lciAhPT0gdW5kZWZpbmVkKSByZXR1cm47IC8vIOW3suacieW+heWPkemAgVxuICAgIGlmIChEYXRlLm5vdygpIC0gc3RhdGUubGFzdEF0dGVtcHRBdCA8IGNvbmZpZy5jb29sZG93bk1zKSByZXR1cm47IC8vIOWGt+WNtOacnyjlkKvlpLHotKXlsJ3or5UpXG4gICAgaWYgKHN0YXRlLmNvbnNlY3V0aXZlID49IGNvbmZpZy5tYXhDb25zZWN1dGl2ZSkge1xuICAgICAgdGhpcy5sb2coXG4gICAgICAgIGDot7Pov4cgJHtzZXNzaW9uSWR9KCR7cmVhc29ufSk6IOW3sui/nue7reiHquWKqOe7p+e7rSAke3N0YXRlLmNvbnNlY3V0aXZlfSDmrKEsIOetieW+heeUqOaIt+S7i+WFpeaIluaIkOWKn+WbnuWQiGAsXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc3RhdGUucXVldWVkID4gMCkgcmV0dXJuOyAvLyDlt7LmnInmjpLpmJ/mtojmga8sIOWuv+S4u+S8muiHquihjOWUpOmGklxuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAoc3RhdGUucGVuZGluZ1RpbWVyICE9PSB0aW1lcikgcmV0dXJuO1xuICAgICAgc3RhdGUucGVuZGluZ1RpbWVyID0gdW5kZWZpbmVkO1xuICAgICAgdm9pZCB0aGlzLmZpcmUoc2Vzc2lvbklkLCByZWFzb24pO1xuICAgIH0sIGNvbmZpZy5ncmFjZU1zKTtcbiAgICBzdGF0ZS5wZW5kaW5nVGltZXIgPSB0aW1lcjtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGDmo4DmtYvliLDpnZ7kurrkuLrkuK3mlq0gJHtzZXNzaW9uSWR9KCR7cmVhc29ufSksICR7Y29uZmlnLmdyYWNlTXN9bXMg5ZCO6Ieq5Yqo5Y+R6YCB44CMJHtjb25maWcuY29udGludWVUZXh0feOAjWAsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgY2FuY2VsUGVuZGluZyhzZXNzaW9uSWQ6IFNlc3Npb25JZCwgd2h5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuc3RhdGUoc2Vzc2lvbklkKTtcbiAgICBpZiAoc3RhdGUucGVuZGluZ1RpbWVyID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICBjbGVhclRpbWVvdXQoc3RhdGUucGVuZGluZ1RpbWVyKTtcbiAgICBzdGF0ZS5wZW5kaW5nVGltZXIgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5sb2coYOWPlua2iCAke3Nlc3Npb25JZH0g55qE6Ieq5Yqo57un57utKCR7d2h5fSlgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmlyZShzZXNzaW9uSWQ6IFNlc3Npb25JZCwgcmVhc29uOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5kaXNwb3NlZCkgcmV0dXJuO1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5zdGF0ZShzZXNzaW9uSWQpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgLy8g5p2D5aiBIHJ1bm5pbmcg5qOA5p+lOiDkvJjlhYjnlKggaG9zdCDluKcsIOacquefpeaXtuWbnumAgOWIsCBzZXNzaW9uLmxpc3RcbiAgICBpZiAoc3RhdGUucnVubmluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBydW5uaW5nID0gYXdhaXQgdGhpcy5ydW5uaW5nVmlhTGlzdChzZXNzaW9uSWQpO1xuICAgICAgaWYgKHJ1bm5pbmcgPT09IHVuZGVmaW5lZCB8fCBydW5uaW5nKSB7XG4gICAgICAgIHRoaXMubG9nKGDot7Pov4cgJHtzZXNzaW9uSWR9OiDml6Dms5Xnoa7orqTnqbrpl7IoJHtydW5uaW5nID09PSB1bmRlZmluZWQgPyAn5pyq55+lJyA6ICfov5DooYzkuK0nfSlgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc3RhdGUucnVubmluZykge1xuICAgICAgdGhpcy5sb2coYOi3s+i/hyAke3Nlc3Npb25JZH06IOS8muivneS7jeWcqOi/kOihjGApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc3RhdGUucXVldWVkID4gMCkge1xuICAgICAgdGhpcy5sb2coYOi3s+i/hyAke3Nlc3Npb25JZH06IOW3suacieaOkumYn+a2iOaBr2ApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyDot6jmoIfnrb7pobXlhrfljbRcbiAgICBpZiAoRGF0ZS5ub3coKSAtIHJlYWRMYXN0U2VuZChzZXNzaW9uSWQpIDwgY29uZmlnLmNvb2xkb3duTXMpIHtcbiAgICAgIHRoaXMubG9nKGDot7Pov4cgJHtzZXNzaW9uSWR9OiDlhbbku5bmoIfnrb7pobXliJrlj5HpgIHov4dgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFjbGFpbVNlbmQoc2Vzc2lvbklkKSkge1xuICAgICAgdGhpcy5sb2coYOi3s+i/hyAke3Nlc3Npb25JZH06IOWFtuS7luagh+etvumhteato+WcqOWPkemAgWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0ZXh0ID0gY29uZmlnLmNvbnRpbnVlVGV4dDtcbiAgICBjb25zdCB6b25lID0gY2xpZW50VGltZVpvbmUoKTtcbiAgICBzdGF0ZS5sYXN0QXR0ZW1wdEF0ID0gRGF0ZS5ub3coKTsgLy8g5YWI6K6w6LSmOiDml6DorrrmiJDotKUsIOacrOasoeWwneivlemDvei/m+WFpeWGt+WNtFxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuYXBpLnNlc3Npb25zLnByb21wdCh7XG4gICAgICAgIHNlc3Npb25JZCxcbiAgICAgICAgbW9kZTogJ3F1ZXVlJyxcbiAgICAgICAgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0IH1dLFxuICAgICAgICAuLi4oem9uZSA9PT0gdW5kZWZpbmVkID8ge30gOiB7IGNsaWVudFRpbWVab25lOiB6b25lIH0pLFxuICAgICAgfSk7XG4gICAgICBpZiAocmVzcG9uc2UucmVzdWx0Lm9rKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIHN0YXRlLmNvbnNlY3V0aXZlICs9IDE7XG4gICAgICAgIHN0YXRlLmxhc3RBdXRvQXQgPSBub3c7XG4gICAgICAgIHN0YXRlLmxhc3RTZW50VGV4dCA9IHRleHQ7XG4gICAgICAgIHdyaXRlTGFzdFNlbmQoc2Vzc2lvbklkLCBub3cpO1xuICAgICAgICB0aGlzLmxvZyhg5bey6Ieq5Yqo5Y+R6YCB44CMJHt0ZXh0feOAjeWIsCAke3Nlc3Npb25JZH0oJHtyZWFzb259KSwg56ysICR7c3RhdGUuY29uc2VjdXRpdmV9IOasoei/nue7rWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2coXG4gICAgICAgICAgYOWPkemAgeWksei0pSAke3Nlc3Npb25JZH06ICR7cmVzcG9uc2UucmVzdWx0LmVycm9yLmNvZGV9ICR7cmVzcG9uc2UucmVzdWx0LmVycm9yLm1lc3NhZ2V9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5sb2coYOWPkemAgeW8guW4uCAke3Nlc3Npb25JZH06ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICByZWxlYXNlU2VuZChzZXNzaW9uSWQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcnVubmluZ1ZpYUxpc3Qoc2Vzc2lvbklkOiBTZXNzaW9uSWQpOiBQcm9taXNlPGJvb2xlYW4gfCB1bmRlZmluZWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmFwaS5zZXNzaW9ucy5saXN0KHt9KTtcbiAgICAgIGlmICghcmVzcG9uc2UucmVzdWx0Lm9rKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgaXRlbSA9IHJlc3BvbnNlLnJlc3VsdC52YWx1ZS5pdGVtcy5maW5kKFxuICAgICAgICAoc3VtbWFyeTogU2Vzc2lvblN1bW1hcnkpID0+IHN1bW1hcnkuc2Vzc2lvbklkID09PSBzZXNzaW9uSWQsXG4gICAgICApO1xuICAgICAgcmV0dXJuIGl0ZW0gPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGl0ZW0ucnVubmluZztcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0tLS0tLSDlkK/liqgv6YeN6L+e5omr5o+PIC0tLS0tLS0tLS1cblxuICBwcml2YXRlIHNjaGVkdWxlUmVjb25uZWN0U2NhbigpOiB2b2lkIHtcbiAgICB0aGlzLnJlY29ubmVjdFNjYW5zICs9IDE7XG4gICAgY29uc3Qgc2NhbiA9IHRoaXMucmVjb25uZWN0U2NhbnM7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAoc2NhbiAhPT0gdGhpcy5yZWNvbm5lY3RTY2FucyB8fCB0aGlzLmRpc3Bvc2VkKSByZXR1cm47XG4gICAgICB2b2lkIHRoaXMuc2Nhbkxvb3AoNiwgdGhpcy5nZXRDb25maWcoKS5yZWNvbm5lY3RTY2FuRGVsYXlNcyk7XG4gICAgfSwgdGhpcy5nZXRDb25maWcoKS5yZWNvbm5lY3RTY2FuRGVsYXlNcyk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJvb3RTY2FuTG9vcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnNjYW5Mb29wKEluZmluaXR5LCAzMDAwKTtcbiAgfVxuXG4gIC8qKiDlj43lpI3lsJ3or5Xmiavmj48sIOebtOWIsOaIkOWKnyjlrr/kuLvlsLHnu6op5oiW6L6+5Yiw5qyh5pWw5LiK6ZmQ44CCICovXG4gIHByaXZhdGUgYXN5bmMgc2Nhbkxvb3AoYXR0ZW1wdHM6IG51bWJlciwgZGVsYXlNczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPCBhdHRlbXB0cyAmJiAhdGhpcy5kaXNwb3NlZDsgYXR0ZW1wdCArPSAxKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoYXdhaXQgdGhpcy5zY2FuSW50ZXJydXB0ZWQoKSkgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKHRoaXMuZGlzcG9zZWQpIHJldHVybjtcbiAgICAgICAgLy8g5a6/5Li75pyq5bCx57uq5pe25q+PIDNzIOmHjeivlTsg5Y+q6IqC5rWB6K6w5b2V5pel5b+XLCDpgb/lhY3liLflsY/jgIJcbiAgICAgICAgaWYgKGF0dGVtcHQgJSAxMCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMubG9nKFxuICAgICAgICAgICAgYOaJq+aPj+Wksei0pSgke2F0dGVtcHQgKyAxfS8ke2F0dGVtcHRzID09PSBJbmZpbml0eSA/ICfiiJ4nIDogYXR0ZW1wdHN9KTogJHtcbiAgICAgICAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgICAgICAgICB9YCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoYXR0ZW1wdCArIDEgPCBhdHRlbXB0cykgYXdhaXQgc2xlZXAoZGVsYXlNcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOaJq+aPj+acgOi/keS4reaWrei/h+eahOS8muivnTog5pyA5ZCO5Zue5ZCI5Lul6Z2e5Lq65Li65Y6f5Zug57uT5p2fLCDkuJTlhbblkI7msqHmnInmlrDlm57lkIjmiJbnlKjmiLfmtojmga/jgIJcbiAgICogQHJldHVybnMg5piv5ZCm5oiQ5Yqf5a6M5oiQ5LiA5qyh5omr5o+PKOWuv+S4u+Wwsee7qinjgIJcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2NhbkludGVycnVwdGVkKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmFwaS5zZXNzaW9ucy5saXN0KHt9KTtcbiAgICBpZiAoIXJlc3BvbnNlLnJlc3VsdC5vaykgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGl0ZW1zID0gcmVzcG9uc2UucmVzdWx0LnZhbHVlLml0ZW1zO1xuICAgIGNvbnN0IGNhbmRpZGF0ZXMgPSBpdGVtc1xuICAgICAgLmZpbHRlcigoc3VtbWFyeSkgPT4gIXN1bW1hcnkucnVubmluZyAmJiBzdW1tYXJ5LnBhcmVudFNlc3Npb25JZCA9PT0gdW5kZWZpbmVkKVxuICAgICAgLnNsaWNlKDAsIGNvbmZpZy5zY2FuTGltaXQpO1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgZm9yIChjb25zdCBzdW1tYXJ5IG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgIGlmICh0aGlzLmRpc3Bvc2VkKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5zdGF0ZShzdW1tYXJ5LnNlc3Npb25JZCk7XG4gICAgICBpZiAoc3RhdGUucGVuZGluZ1RpbWVyICE9PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgaWYgKHN0YXRlLmNvbnNlY3V0aXZlID49IGNvbmZpZy5tYXhDb25zZWN1dGl2ZSkgY29udGludWU7XG4gICAgICBpZiAobm93IC0gc3RhdGUubGFzdEF0dGVtcHRBdCA8IGNvbmZpZy5jb29sZG93bk1zKSBjb250aW51ZTtcbiAgICAgIGxldCBldmVudHM7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5hcGkuc2Vzc2lvbnMuaGlzdG9yeSh7XG4gICAgICAgICAgc2Vzc2lvbklkOiBzdW1tYXJ5LnNlc3Npb25JZCxcbiAgICAgICAgICBtYXhNZXNzYWdlczogMzAsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXBhZ2UucmVzdWx0Lm9rKSBjb250aW51ZTtcbiAgICAgICAgZXZlbnRzID0gcGFnZS5yZXN1bHQudmFsdWUuZXZlbnRzO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIGNvbnRpbnVlOyAvLyDkvJror53lj6/og73liJrooqvnp7vpmaRcbiAgICAgIH1cbiAgICAgIC8vIOS7juWwvumDqOaJvuacgOWQjuS4gOS4qiB0dXJuL2VuZCjlnKjliIbmlK/lhoXlrozmiJDmlLbnqoQpXG4gICAgICBsZXQgbGFzdEVuZDogU2Vzc2lvbkV2ZW50PCd0dXJuL2VuZCc+IHwgdW5kZWZpbmVkO1xuICAgICAgZm9yIChsZXQgaSA9IGV2ZW50cy5sZW5ndGggLSAxOyBpID49IDA7IGkgLT0gMSkge1xuICAgICAgICBjb25zdCBldmVudCA9IGV2ZW50c1tpXT8uZXZlbnQ7XG4gICAgICAgIGlmIChldmVudCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LnR5cGUgPT09ICd0dXJuL2VuZCcpIHtcbiAgICAgICAgICBsYXN0RW5kID0gZXZlbnQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChsYXN0RW5kID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgcmVhc29uID0gbGFzdEVuZC5kYXRhLnJlYXNvbjtcbiAgICAgIGlmICghaXNOb25IdW1hblJlYXNvbihyZWFzb24ua2luZCkpIGNvbnRpbnVlO1xuICAgICAgaWYgKGxhc3RFbmQudGltZSA8IG5vdyAtIGNvbmZpZy5mcmVzaE1zKSBjb250aW51ZTsgLy8g5aSq5LmF6L+cLCDkuI3nv7vml6fotKZcbiAgICAgIC8vIOivpSB0dXJuL2VuZCDkuYvlkI7kuI3og73mnInmlrDlm57lkIjmiJbnlKjmiLfmtojmga8o6K+05piO5bey6KKr5aSE55CGKVxuICAgICAgbGV0IHN1cGVyc2VkZWQgPSBmYWxzZTtcbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZXZlbnRzKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gZW50cnkuZXZlbnQ7XG4gICAgICAgIGlmIChldmVudC5zZXEgPD0gbGFzdEVuZC5zZXEpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ3R1cm4vc3RhcnQnKSBzdXBlcnNlZGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICd1c2VyL21lc3NhZ2UnICYmIGV2ZW50LmRhdGEuc291cmNlLmtpbmQgPT09ICd1c2VyJykgc3VwZXJzZWRlZCA9IHRydWU7XG4gICAgICAgIGlmIChzdXBlcnNlZGVkKSBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChzdXBlcnNlZGVkKSBjb250aW51ZTtcbiAgICAgIHRoaXMubG9nKGDmiavmj4/lj5HnjrDkuK3mlq0gJHtzdW1tYXJ5LnNlc3Npb25JZH0odHVybi9lbmQ6JHtyZWFzb24ua2luZH0pLCDlronmjpLoh6rliqjnu6fnu61gKTtcbiAgICAgIHRoaXMuc2NoZWR1bGUoc3VtbWFyeS5zZXNzaW9uSWQsIGBzY2FuOnR1cm4vZW5kOiR7cmVhc29uLmtpbmR9YCk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG59XG4iLCAiLyoqXG4gKiBgYXV0by1jb250aW51ZWAgbmFtZXNwYWNlIGRpY3Rpb25hcmllczogY29weSBmb3IgdGhlIHBsdWdpbiBzZXR0aW5ncyBjYXJkXG4gKiByZWdpc3RlcmVkIGludG8gdGhlIGBzZXR0aW5ncy5wbHVnaW4uaXRlbWAgc2VhdCBvZiB0aGUgcGx1Z2luLWNvbmZpZ3VyYXRpb25cbiAqIHNlY3Rpb24uIEluY2x1ZGVzIHRoZSBjYXJkLWNocm9tZSBrZXlzIHRoZSBjYXJkIGNvbXBvbmVudCByZWFkcy5cbiAqL1xuXG4vKiog566A5L2T5Lit5paH6K+N5YW4KOmUrumbhueahOS6i+Wunuadpea6kCnjgIIgKi9cbmV4cG9ydCBjb25zdCB6aCA9IHtcbiAgJ2NhcmQudGl0bGUnOiAn6Ieq5Yqo57un57utJyxcbiAgJ2NhcmQuZGVzY3JpcHRpb24nOiAn6K+35rGC5Zug572R57uc562J5Y6f5ZugKOmdnuS6uuS4uinkuK3mlq3lkI4sIOiHquWKqOWPkemAgeOAjOe7p+e7reOAjee7rei3keOAgicsXG4gICdmaWVsZC5jb250aW51ZVRleHQnOiAn57un57ut5paH5pysJyxcbiAgJ2ZpZWxkLmNvbnRpbnVlVGV4dEhpbnQnOiAn5Lit5pat5ZCO6Ieq5Yqo5Y+R6YCB55qE5raI5oGv5YaF5a6544CCJyxcbiAgJ2ZpZWxkLmdyYWNlTXMnOiAn5a696ZmQ5pyfIChtcyknLFxuICAnZmllbGQuZ3JhY2VNc0hpbnQnOiAn5qOA5rWL5Yiw5Lit5pat5ZCO562J5b6F55qE5pe26ZW/OyDmnJ/pl7Tlrr/kuLvoh6rooYzmgaLlpI3liJnlj5bmtojjgIInLFxuICAnZmllbGQuY29vbGRvd25Ncyc6ICflhrfljbTml7bpl7QgKG1zKScsXG4gICdmaWVsZC5jb29sZG93bk1zSGludCc6ICflkIzkuIDkvJror53kuKTmrKHoh6rliqjjgIznu6fnu63jgI3nmoTmnIDlsI/pl7TpmpQsIOWksei0peWwneivleS5n+iuoeWFpeOAgicsXG4gICdmaWVsZC5tYXhDb25zZWN1dGl2ZSc6ICfmnIDlpKfov57nu63mrKHmlbAnLFxuICAnZmllbGQubWF4Q29uc2VjdXRpdmVIaW50JzogJ+WQjOS4gOS8muivnei/nue7reiHquWKqOOAjOe7p+e7reOAjeeahOS4iumZkDsg6LaF6L+H5ZCO5YGc5q2iLCDnm7TliLDnlKjmiLfmiYvliqjku4vlhaXmiJblh7rnjrDmiJDlip/lm57lkIjjgIInLFxuICAnZmllbGQuc2Nhbk9uQm9vdCc6ICflkK/liqgv6YeN6L+e5omr5o+PJyxcbiAgJ2ZpZWxkLnNjYW5PbkJvb3RIaW50JzogJ+mhtemdouWQr+WKqOaIlumHjei/nuaXtuaJq+aPj+acgOi/keS4reaWreeahOS8muivneW5tuiHquWKqOe7rei3kSjlpoLmtY/op4jlmajlhbPpl63mnJ/pl7Tlrr/kuLvltKnmuoMp44CCJyxcbiAgJ2ZpZWxkLnNjYW5MaW1pdCc6ICfmiavmj4/kvJror53mlbAnLFxuICAnZmllbGQuc2NhbkxpbWl0SGludCc6ICfmnIDlpJrmo4Dmn6XlpJrlsJHkuKrmnIDov5Hmm7TmlrDnmoTkvJror50o5LiN5ZCr6L+Q6KGM5Lit5LiO5a2Q5Luj55CG5Lya6K+dKeOAgicsXG4gICdmaWVsZC5mcmVzaE1zJzogJ+aJq+aPj+aXtumXtOeqlyAobXMpJyxcbiAgJ2ZpZWxkLmZyZXNoTXNIaW50JzogJ+aJq+aPj+WPquWkhOeQhuivpeaXtumXtOeql+WGheeahOS4reaWreOAgicsXG4gICdmaWVsZC5yZWNvbm5lY3RTY2FuRGVsYXlNcyc6ICfph43ov57miavmj4/lu7bov58gKG1zKScsXG4gICdmaWVsZC5yZWNvbm5lY3RTY2FuRGVsYXlNc0hpbnQnOiAn6YeN6L+e5ZCO562J5b6F5a6/5Li75a6M5oiQ5oGi5aSN5YaN5omr5o+P44CCJyxcbiAgJ2ZpZWxkLnJlY29ubmVjdEJhY2tvZmZNcyc6ICfph43ov57pgIDpgb8gKG1zKScsXG4gICdmaWVsZC5yZWNvbm5lY3RCYWNrb2ZmTXNIaW50JzogJ+S6i+S7tua1geaWreW8gOWQjueahOmHjei/numXtOmalOOAgicsXG4gICdmaWVsZC52ZXJib3NlJzogJ+ivpue7huaXpeW/lycsXG4gICdmaWVsZC52ZXJib3NlSGludCc6ICflnKjmtY/op4jlmajmjqfliLblj7DovpPlh7ogW2F1dG8tY29udGludWVdIOaXpeW/l+OAgicsXG4gICdjaHJvbWUuY29sbGFwc2UnOiAn5pS26LW36K6+572uJyxcbiAgJ2Nocm9tZS5leHBhbmQnOiAn5bGV5byA6K6+572uJyxcbiAgJ2Nocm9tZS51bnNhdmVkJzogJ+acquS/neWtmCcsXG4gICdjaHJvbWUucmVhZE9ubHknOiAn5b2T5YmN6YOo572y55qE6K6+572u5Y+q6K+744CCJyxcbiAgJ2Nocm9tZS5zYXZlRmFpbGVkJzogJ+mDqOe9suacquaOpeWPl+i/meS6m+WAvCwg5bey5L+d55WZ5L6b5L2g5L+u5pS544CCJyxcbiAgJ2Nocm9tZS5kaXNjYXJkJzogJ+aUvuW8gycsXG4gICdjaHJvbWUuc2F2aW5nJzogJ+S/neWtmOS4reKApicsXG4gICdjaHJvbWUuc2F2ZSc6ICfkv53lrZgnLFxuICAnY2hyb21lLm92ZXJyaWRkZW4nOiAn5bey6KaG55uWJyxcbiAgJ2Nocm9tZS5yZXNldCc6ICfmgaLlpI3pu5jorqQnLFxuICAnY2hyb21lLmludmFsaWROdW1iZXInOiAn6K+36L6T5YWl5pWw5a2XLCDnlZnnqbrliJnkvb/nlKjpu5jorqTlgLzjgIInLFxuICAnY2hyb21lLmluaGVyaXQnOiAn57un5om/JyxcbiAgJ2Nocm9tZS5vbic6ICflvIAnLFxuICAnY2hyb21lLm9mZic6ICflhbMnLFxufSBzYXRpc2ZpZXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuLyoqIOacrOaPkuS7tueahOmUruiBlOWQiOOAgiAqL1xuZXhwb3J0IHR5cGUgU2V0dGluZ3NDYXJkS2V5ID0ga2V5b2YgdHlwZW9mIHpoO1xuXG4vKiogRW5nbGlzaCBkaWN0aW9uYXJ5LCBjaGVja2VkIGNvbXBsZXRlIGFnYWluc3QgdGhlIHpoIGtleSBzZXQuICovXG5leHBvcnQgY29uc3QgZW46IFJlY29yZDxTZXR0aW5nc0NhcmRLZXksIHN0cmluZz4gPSB7XG4gICdjYXJkLnRpdGxlJzogJ0F1dG8gY29udGludWUnLFxuICAnY2FyZC5kZXNjcmlwdGlvbic6ICdXaGVuIGEgcmVxdWVzdCBpcyBpbnRlcnJ1cHRlZCBieSBhIG5vbi1odW1hbiBjYXVzZSwgYXV0b21hdGljYWxseSBzZW5kIOOAjOe7p+e7reOAjSB0byByZXN1bWUuJyxcbiAgJ2ZpZWxkLmNvbnRpbnVlVGV4dCc6ICdDb250aW51ZSB0ZXh0JyxcbiAgJ2ZpZWxkLmNvbnRpbnVlVGV4dEhpbnQnOiAnTWVzc2FnZSBhdXRvbWF0aWNhbGx5IHNlbnQgYWZ0ZXIgYW4gaW50ZXJydXB0aW9uLicsXG4gICdmaWVsZC5ncmFjZU1zJzogJ0dyYWNlIHBlcmlvZCAobXMpJyxcbiAgJ2ZpZWxkLmdyYWNlTXNIaW50JzogJ1dhaXQgYWZ0ZXIgYW4gaW50ZXJydXB0aW9uOyBjYW5jZWxsZWQgaWYgdGhlIGhvc3QgcmVjb3ZlcnMgb24gaXRzIG93bi4nLFxuICAnZmllbGQuY29vbGRvd25Ncyc6ICdDb29sZG93biAobXMpJyxcbiAgJ2ZpZWxkLmNvb2xkb3duTXNIaW50JzogJ01pbmltdW0gaW50ZXJ2YWwgYmV0d2VlbiBhdXRvLWNvbnRpbnVlcyBwZXIgc2Vzc2lvbjsgZmFpbGVkIGF0dGVtcHRzIGNvdW50IHRvby4nLFxuICAnZmllbGQubWF4Q29uc2VjdXRpdmUnOiAnTWF4IGNvbnNlY3V0aXZlJyxcbiAgJ2ZpZWxkLm1heENvbnNlY3V0aXZlSGludCc6ICdNYXggY29uc2VjdXRpdmUgYXV0by1jb250aW51ZXMgcGVyIHNlc3Npb247IHN0b3BzIHVudGlsIGEgdXNlciBpbnRlcnZlbmVzIG9yIGEgdHVybiBjb21wbGV0ZXMuJyxcbiAgJ2ZpZWxkLnNjYW5PbkJvb3QnOiAnU2NhbiBvbiBsb2FkIC8gcmVjb25uZWN0JyxcbiAgJ2ZpZWxkLnNjYW5PbkJvb3RIaW50JzogJ1NjYW4gcmVjZW50bHkgaW50ZXJydXB0ZWQgc2Vzc2lvbnMgb24gcGFnZSBsb2FkIG9yIHJlY29ubmVjdCAoZS5nLiB0aGUgaG9zdCBjcmFzaGVkIHdoaWxlIHRoZSBicm93c2VyIHdhcyBjbG9zZWQpLicsXG4gICdmaWVsZC5zY2FuTGltaXQnOiAnU2NhbiBsaW1pdCcsXG4gICdmaWVsZC5zY2FuTGltaXRIaW50JzogJ0hvdyBtYW55IG1vc3QtcmVjZW50bHktdXBkYXRlZCBzZXNzaW9ucyB0byBjaGVjayAocnVubmluZyAvIHN1YmFnZW50IHNlc3Npb25zIGV4Y2x1ZGVkKS4nLFxuICAnZmllbGQuZnJlc2hNcyc6ICdTY2FuIHdpbmRvdyAobXMpJyxcbiAgJ2ZpZWxkLmZyZXNoTXNIaW50JzogJ09ubHkgaW50ZXJydXB0aW9ucyBpbnNpZGUgdGhpcyB3aW5kb3cgYXJlIGNvbnNpZGVyZWQuJyxcbiAgJ2ZpZWxkLnJlY29ubmVjdFNjYW5EZWxheU1zJzogJ1JlY29ubmVjdCBzY2FuIGRlbGF5IChtcyknLFxuICAnZmllbGQucmVjb25uZWN0U2NhbkRlbGF5TXNIaW50JzogJ1dhaXQgZm9yIHRoZSBob3N0IHRvIGZpbmlzaCByZWNvdmVyaW5nIGJlZm9yZSBzY2FubmluZyBhZnRlciBhIHJlY29ubmVjdC4nLFxuICAnZmllbGQucmVjb25uZWN0QmFja29mZk1zJzogJ1JlY29ubmVjdCBiYWNrb2ZmIChtcyknLFxuICAnZmllbGQucmVjb25uZWN0QmFja29mZk1zSGludCc6ICdJbnRlcnZhbCBiZXR3ZWVuIGV2ZW50LXN0cmVhbSByZWNvbm5lY3QgYXR0ZW1wdHMuJyxcbiAgJ2ZpZWxkLnZlcmJvc2UnOiAnVmVyYm9zZSBsb2dzJyxcbiAgJ2ZpZWxkLnZlcmJvc2VIaW50JzogJ0xvZyBbYXV0by1jb250aW51ZV0gbGluZXMgdG8gdGhlIGJyb3dzZXIgY29uc29sZS4nLFxuICAnY2hyb21lLmNvbGxhcHNlJzogJ0hpZGUgc2V0dGluZ3MnLFxuICAnY2hyb21lLmV4cGFuZCc6ICdTaG93IHNldHRpbmdzJyxcbiAgJ2Nocm9tZS51bnNhdmVkJzogJ1Vuc2F2ZWQnLFxuICAnY2hyb21lLnJlYWRPbmx5JzogJ1RoaXMgZGVwbG95bWVudCBzdG9yZXMgc2V0dGluZ3MgcmVhZC1vbmx5LicsXG4gICdjaHJvbWUuc2F2ZUZhaWxlZCc6ICdUaGUgZGVwbG95bWVudCBkaWQgbm90IGFjY2VwdCB0aGVzZSB2YWx1ZXM7IHRoZXkgd2VyZSBsZWZ0IGZvciB5b3UgdG8gY29ycmVjdC4nLFxuICAnY2hyb21lLmRpc2NhcmQnOiAnRGlzY2FyZCcsXG4gICdjaHJvbWUuc2F2aW5nJzogJ1NhdmluZ+KApicsXG4gICdjaHJvbWUuc2F2ZSc6ICdTYXZlJyxcbiAgJ2Nocm9tZS5vdmVycmlkZGVuJzogJ092ZXJyaWRkZW4nLFxuICAnY2hyb21lLnJlc2V0JzogJ1Jlc2V0IHRvIGRlZmF1bHQnLFxuICAnY2hyb21lLmludmFsaWROdW1iZXInOiAnRW50ZXIgYSBudW1iZXIsIG9yIGxlYXZlIGJsYW5rIHRvIHVzZSB0aGUgZGVmYXVsdC4nLFxuICAnY2hyb21lLmluaGVyaXQnOiAnSW5oZXJpdCcsXG4gICdjaHJvbWUub24nOiAnT24nLFxuICAnY2hyb21lLm9mZic6ICdPZmYnLFxufTtcbiIsICIvKipcbiAqIFRoZSBhdXRvLWNvbnRpbnVlIHNldHRpbmdzIGNhcmQ6IGVkaXRzIHRoZSBgYXV0by1jb250aW51ZWAgbmFtZXNwYWNlIGZpZWxkc1xuICogZnJvbSB0aGUgcGx1Z2luLWNvbmZpZ3VyYXRpb24gc2VjdGlvbiAodGhlIGBzZXR0aW5ncy5wbHVnaW4uaXRlbWAgc2VhdCkuXG4gKlxuICogU2VsZi1jb250YWluZWQgY2FyZCBjaHJvbWUgKGRpc2Nsb3N1cmUgaGVhZGVyLCBzdGFnZWQgZmllbGRzLCBzYXZlL2Rpc2NhcmRcbiAqIGZvb3RlcikgZm9sbG93aW5nIHRoZSBwbHVnaW4tY2FyZCBzdG9yZSBwYXR0ZXJuIG9mIHRoZSBEU0ggcGx1Z2luXG4gKiBjb25maWd1cmF0aW9uIHNlY3Rpb247IHN0eWxlcyBsaXZlIGluIGBzdHlsZXMudHNgIGFuZCB1c2UgdGhlIERTSCBkZXNpZ25cbiAqIHRva2VucyBzbyB0aGUgY2FyZCBmb2xsb3dzIHRoZSBhY3RpdmUgdGhlbWUuXG4gKi9cbmltcG9ydCB7IHVzZVN0YXRlLCB0eXBlIFJlYWN0Tm9kZSB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IGNyZWF0ZVNuYXBzaG90U3RvcmUsIHR5cGUgU2V0dGluZ3NTY29wZSwgdHlwZSBTbmFwc2hvdFN0b3JlIH0gZnJvbSAnQGRlZXBzZWVrLWFpL2RzaC1jbGllbnQtcnVudGltZS9jbGllbnQnO1xuaW1wb3J0IHR5cGUgeyBJbmplY3RGYWNlLCBQcm9wc0xvY2FsZSwgUHJvcHNSdW50aW1lIH0gZnJvbSAnQGRlZXBzZWVrLWFpL2RzaC1jbGllbnQtdWktc2xvdHMnO1xuaW1wb3J0IHR5cGUgeyBBdXRvQ29udGludWVTZXR0aW5ncyB9IGZyb20gJy4vZW5naW5lLnRzJztcbmltcG9ydCB0eXBlIHsgU2V0dGluZ3NDYXJkS2V5IH0gZnJvbSAnLi9sb2NhbGVzLnRzJztcbmltcG9ydCB7XG4gIGJvb2xlYW5GaWVsZCxcbiAgQ2FyZEZvcm0sXG4gIG51bWJlckZpZWxkLFxuICB0ZXh0RmllbGQsXG4gIHR5cGUgQ2FyZEFjdGlvbnMsXG4gIHR5cGUgQ2FyZEZpZWxkU3RhdGUsXG4gIHR5cGUgQ2FyZFNoZWxsLFxufSBmcm9tICcuL3NldHRpbmdzLWZvcm0udHMnO1xuaW1wb3J0IHsgaW5qZWN0U3R5bGVzIH0gZnJvbSAnLi9zdHlsZXMudHMnO1xuXG4vLyBTdHlsZXMgbXVzdCBsYW5kIGR1cmluZyBmYWN0b3J5IG1hdGVyaWFsaXphdGlvbiBzbyB0aGUgbW9kdWxlIHN5c3RlbSdzXG4vLyBzdHlsZSBib29ra2VlcGluZyAoSE1SKSBvd25zIHRoZW0uXG5pbmplY3RTdHlsZXMoKTtcblxuLyoqIFdoYXQgdGhlIGF1dG8tY29udGludWUgY2FyZCByZW5kZXJzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBBdXRvQ29udGludWVTZXR0aW5nc0NhcmRTdGF0ZSBleHRlbmRzIENhcmRTaGVsbCB7XG4gIGNvbnRpbnVlVGV4dDogQ2FyZEZpZWxkU3RhdGU7XG4gIGdyYWNlTXM6IENhcmRGaWVsZFN0YXRlO1xuICBjb29sZG93bk1zOiBDYXJkRmllbGRTdGF0ZTtcbiAgbWF4Q29uc2VjdXRpdmU6IENhcmRGaWVsZFN0YXRlO1xuICBzY2FuT25Cb290OiBDYXJkRmllbGRTdGF0ZTtcbiAgc2NhbkxpbWl0OiBDYXJkRmllbGRTdGF0ZTtcbiAgZnJlc2hNczogQ2FyZEZpZWxkU3RhdGU7XG4gIHJlY29ubmVjdFNjYW5EZWxheU1zOiBDYXJkRmllbGRTdGF0ZTtcbiAgcmVjb25uZWN0QmFja29mZk1zOiBDYXJkRmllbGRTdGF0ZTtcbiAgdmVyYm9zZTogQ2FyZEZpZWxkU3RhdGU7XG59XG5cbi8qKiBUaGUgcmVnaXN0cmF0aW9uLXNpZGUgZmFjZSB0aGUgY2FyZCdzIHNsb3QgZW50cnkgaW5qZWN0cy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkRmFjZSBleHRlbmRzIENhcmRBY3Rpb25zIHtcbiAgaG9va3M6IHtcbiAgICAvKiogQ2FyZCBzbmFwc2hvdCBib3VuZCBieSB0aGUgcmVuZGVyZXIgYXMgdXNlQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkLiAqL1xuICAgIGF1dG9Db250aW51ZVNldHRpbmdzQ2FyZDogU25hcHNob3RTdG9yZTxBdXRvQ29udGludWVTZXR0aW5nc0NhcmRTdGF0ZT47XG4gIH07XG59XG5cbi8qKiBCcmlkZ2VzIHRoZSBgYXV0by1jb250aW51ZWAgc2NvcGUgb250byB0aGUgY2FyZCdzIHN0YWdlZCBmb3JtLiAqL1xuZXhwb3J0IGNsYXNzIEF1dG9Db250aW51ZVNldHRpbmdzQ2FyZENvbnRyb2xsZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGZvcm06IENhcmRGb3JtPEF1dG9Db250aW51ZVNldHRpbmdzPjtcbiAgcHJpdmF0ZSByZWFkb25seSBzdG9yZTogU25hcHNob3RTdG9yZTxBdXRvQ29udGludWVTZXR0aW5nc0NhcmRTdGF0ZT47XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBzY29wZSAtIHRoZSBib3VuZCBzZXR0aW5ncyBzY29wZSBmb3IgdGhlIGBhdXRvLWNvbnRpbnVlYCBuYW1lc3BhY2UuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogU2V0dGluZ3NTY29wZTxBdXRvQ29udGludWVTZXR0aW5ncz4pIHtcbiAgICB0aGlzLmZvcm0gPSBuZXcgQ2FyZEZvcm0oc2NvcGUsIFtcbiAgICAgIHRleHRGaWVsZCgnY29udGludWVUZXh0JyksXG4gICAgICBudW1iZXJGaWVsZCgnZ3JhY2VNcycsIDApLFxuICAgICAgbnVtYmVyRmllbGQoJ2Nvb2xkb3duTXMnLCAwKSxcbiAgICAgIG51bWJlckZpZWxkKCdtYXhDb25zZWN1dGl2ZScsIDEpLFxuICAgICAgYm9vbGVhbkZpZWxkKCdzY2FuT25Cb290JyksXG4gICAgICBudW1iZXJGaWVsZCgnc2NhbkxpbWl0JywgMSksXG4gICAgICBudW1iZXJGaWVsZCgnZnJlc2hNcycsIDApLFxuICAgICAgbnVtYmVyRmllbGQoJ3JlY29ubmVjdFNjYW5EZWxheU1zJywgMCksXG4gICAgICBudW1iZXJGaWVsZCgncmVjb25uZWN0QmFja29mZk1zJywgMCksXG4gICAgICBib29sZWFuRmllbGQoJ3ZlcmJvc2UnKSxcbiAgICBdKTtcbiAgICB0aGlzLnN0b3JlID0gdGhpcy5mb3JtLmJpbmQoKCkgPT4gdGhpcy5wcm9qZWN0aW9uKCksIGNyZWF0ZVNuYXBzaG90U3RvcmUpO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9qZWN0aW9uKCk6IEF1dG9Db250aW51ZVNldHRpbmdzQ2FyZFN0YXRlIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5mb3JtLnNoZWxsKCksXG4gICAgICBjb250aW51ZVRleHQ6IHRoaXMuZm9ybS5maWVsZCgnY29udGludWVUZXh0JyksXG4gICAgICBncmFjZU1zOiB0aGlzLmZvcm0uZmllbGQoJ2dyYWNlTXMnKSxcbiAgICAgIGNvb2xkb3duTXM6IHRoaXMuZm9ybS5maWVsZCgnY29vbGRvd25NcycpLFxuICAgICAgbWF4Q29uc2VjdXRpdmU6IHRoaXMuZm9ybS5maWVsZCgnbWF4Q29uc2VjdXRpdmUnKSxcbiAgICAgIHNjYW5PbkJvb3Q6IHRoaXMuZm9ybS5maWVsZCgnc2Nhbk9uQm9vdCcpLFxuICAgICAgc2NhbkxpbWl0OiB0aGlzLmZvcm0uZmllbGQoJ3NjYW5MaW1pdCcpLFxuICAgICAgZnJlc2hNczogdGhpcy5mb3JtLmZpZWxkKCdmcmVzaE1zJyksXG4gICAgICByZWNvbm5lY3RTY2FuRGVsYXlNczogdGhpcy5mb3JtLmZpZWxkKCdyZWNvbm5lY3RTY2FuRGVsYXlNcycpLFxuICAgICAgcmVjb25uZWN0QmFja29mZk1zOiB0aGlzLmZvcm0uZmllbGQoJ3JlY29ubmVjdEJhY2tvZmZNcycpLFxuICAgICAgdmVyYm9zZTogdGhpcy5mb3JtLmZpZWxkKCd2ZXJib3NlJyksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgZmFjZSB0aGUgY2FyZCdzIHNsb3QgcmVnaXN0cmF0aW9uIGluamVjdHMuXG4gICAqIEByZXR1cm5zIHRoZSBjYXJkJ3Mgc25hcHNob3QgYW5kIGl0cyBmb3JtIGFjdGlvbnMuXG4gICAqL1xuICBpbmplY3QoKTogQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkRmFjZSB7XG4gICAgcmV0dXJuIHsgaG9va3M6IHsgYXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkOiB0aGlzLnN0b3JlIH0sIC4uLnRoaXMuZm9ybS5hY3Rpb25zKCkgfTtcbiAgfVxufVxuXG4vKiogUHJvcHMgdGhlIHJlbmRlcmVyIGJpbmRzIGZvciB0aGUgYXV0by1jb250aW51ZSBjYXJkLiAqL1xuZXhwb3J0IHR5cGUgQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkUHJvcHMgPVxuICBQcm9wc1J1bnRpbWU8J3NldHRpbmdzLnBsdWdpbi5pdGVtJz4gJiBQcm9wc0xvY2FsZTwnYXV0by1jb250aW51ZSc+ICYgSW5qZWN0RmFjZTxBdXRvQ29udGludWVTZXR0aW5nc0NhcmRGYWNlPjtcblxuLyoqIENhcmQgY2hyb21lOiBhIGRpc2Nsb3N1cmUgaGVhZGVyIG5hbWluZyB0aGUgcGx1Z2luIGFuZCB3aGF0IGl0cyBzZXR0aW5ncyBnb3Zlcm4sIHRoZSBjb250cm9scywgYW5kIHRoZSBzYXZlIHRoYXQgd3JpdGVzIHRoZW0uICovXG5mdW5jdGlvbiBTZXR0aW5nc0NhcmQocHJvcHM6IHtcbiAgdDogKGtleTogU2V0dGluZ3NDYXJkS2V5KSA9PiBzdHJpbmc7XG4gIHRpdGxlS2V5OiBTZXR0aW5nc0NhcmRLZXk7XG4gIGRlc2NyaXB0aW9uS2V5OiBTZXR0aW5nc0NhcmRLZXk7XG4gIHN0YXRlOiBDYXJkU2hlbGw7XG4gIG9uU2F2ZTogKCkgPT4gdm9pZDtcbiAgb25EaXNjYXJkOiAoKSA9PiB2b2lkO1xuICBjaGlsZHJlbjogUmVhY3ROb2RlO1xufSkge1xuICBjb25zdCBbb3Blbiwgc2V0T3Blbl0gPSB1c2VTdGF0ZShmYWxzZSk7XG4gIGNvbnN0IHsgc3RhdGUgfSA9IHByb3BzO1xuICBpZiAoIXN0YXRlLmF2YWlsYWJsZSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHRpdGxlID0gcHJvcHMudChwcm9wcy50aXRsZUtleSk7XG4gIGNvbnN0IGJsb2NrZWQgPSAhc3RhdGUuZGlydHkgfHwgc3RhdGUuaW52YWxpZCB8fCBzdGF0ZS5zYXZpbmc7XG4gIHJldHVybiAoXG4gICAgPGxpIGNsYXNzTmFtZT17b3BlbiA/ICdkc2hBY0NhcmQgZHNoQWNDYXJkT3BlbicgOiAnZHNoQWNDYXJkJ30+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzc05hbWU9XCJkc2hBY0hlYWRlclwiXG4gICAgICAgIGFyaWEtZXhwYW5kZWQ9e29wZW59XG4gICAgICAgIGFyaWEtbGFiZWw9e2Ake3Byb3BzLnQob3BlbiA/ICdjaHJvbWUuY29sbGFwc2UnIDogJ2Nocm9tZS5leHBhbmQnKX06ICR7dGl0bGV9YH1cbiAgICAgICAgdGl0bGU9e3Byb3BzLnQocHJvcHMuZGVzY3JpcHRpb25LZXkpfVxuICAgICAgICBvbkNsaWNrPXsoKSA9PiBzZXRPcGVuKCFvcGVuKX1cbiAgICAgID5cbiAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwiZHNoQWNIZWFkVGV4dFwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImRzaEFjTmFtZVwiPnt0aXRsZX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwiZHNoQWNEZXNjcmlwdGlvblwiPntwcm9wcy50KHByb3BzLmRlc2NyaXB0aW9uS2V5KX08L3NwYW4+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAge3N0YXRlLmRpcnR5ID8gKFxuICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImRzaEFjUGVuZGluZ1wiIHRpdGxlPXtwcm9wcy50KCdjaHJvbWUudW5zYXZlZCcpfT5cbiAgICAgICAgICAgIHtwcm9wcy50KCdjaHJvbWUudW5zYXZlZCcpfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgKSA6IG51bGx9XG4gICAgICAgIDxzcGFuIGNsYXNzTmFtZT17b3BlbiA/ICdkc2hBY0NoZXZyb24gZHNoQWNDaGV2cm9uT3BlbicgOiAnZHNoQWNDaGV2cm9uJ30+4pa+PC9zcGFuPlxuICAgICAgPC9idXR0b24+XG4gICAgICB7b3BlbiA/IChcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJkc2hBY0JvZHlcIj5cbiAgICAgICAgICB7IXN0YXRlLndyaXRhYmxlID8gKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPVwiZHNoQWNSZWFkT25seVwiIHJvbGU9XCJzdGF0dXNcIj57cHJvcHMudCgnY2hyb21lLnJlYWRPbmx5Jyl9PC9wPlxuICAgICAgICAgICkgOiBudWxsfVxuICAgICAgICAgIHtwcm9wcy5jaGlsZHJlbn1cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImRzaEFjRm9vdGVyXCI+XG4gICAgICAgICAgICB7c3RhdGUuZmFpbGVkID8gKFxuICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9XCJkc2hBY0ZhaWxlZFwiIHJvbGU9XCJzdGF0dXNcIj57cHJvcHMudCgnY2hyb21lLnNhdmVGYWlsZWQnKX08L3A+XG4gICAgICAgICAgICApIDogbnVsbH1cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzTmFtZT1cImRzaEFjRGlzY2FyZFwiXG4gICAgICAgICAgICAgIGRpc2FibGVkPXshc3RhdGUuZGlydHkgfHwgc3RhdGUuc2F2aW5nfVxuICAgICAgICAgICAgICBvbkNsaWNrPXtwcm9wcy5vbkRpc2NhcmR9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHtwcm9wcy50KCdjaHJvbWUuZGlzY2FyZCcpfVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzc05hbWU9XCJkc2hBY1NhdmVcIiBkaXNhYmxlZD17YmxvY2tlZH0gb25DbGljaz17cHJvcHMub25TYXZlfT5cbiAgICAgICAgICAgICAge3Byb3BzLnQoIXN0YXRlLnNhdmluZyA/ICdjaHJvbWUuc2F2ZScgOiAnY2hyb21lLnNhdmluZycpfVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKSA6IG51bGx9XG4gICAgPC9saT5cbiAgKTtcbn1cblxuLyoqIFByb3BzIGV2ZXJ5IGZpZWxkIGNvbnRyb2wgbmVlZHMgcmVnYXJkbGVzcyBvZiBpdHMgdmFsdWUgdHlwZS4gKi9cbmludGVyZmFjZSBGaWVsZFByb3BzIHtcbiAgaWQ6IHN0cmluZztcbiAgbGFiZWw6IHN0cmluZztcbiAgaGludDogc3RyaW5nO1xuICB0ZXh0OiBzdHJpbmc7XG4gIG92ZXJyaWRkZW46IGJvb2xlYW47XG4gIGludmFsaWQ6IGJvb2xlYW47XG4gIGRpc2FibGVkOiBib29sZWFuO1xuICB0OiAoa2V5OiBTZXR0aW5nc0NhcmRLZXkpID0+IHN0cmluZztcbiAgb25FZGl0OiAodGV4dDogc3RyaW5nKSA9PiB2b2lkO1xuICBvblJlc2V0OiAoKSA9PiB2b2lkO1xufVxuXG4vKiogQSBzdGFnZWQgdmFsdWUgZmllbGQ7IGBudW1lcmljYCBvbmx5IGhpbnRzIHRoZSBrZXlwYWQsIHdoaWNoIGRyYWZ0cyBhIGZpZWxkIGFjY2VwdHMgaXMgZGVjaWRlZCBieSBpdHMgc3BlYy4gKi9cbmZ1bmN0aW9uIFZhbHVlRmllbGQocHJvcHM6IEZpZWxkUHJvcHMgJiB7IG51bWVyaWM/OiBib29sZWFuOyBwbGFjZWhvbGRlcj86IHN0cmluZyB9KSB7XG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9XCJkc2hBY0ZpZWxkXCI+XG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImRzaEFjSGVhZFwiPlxuICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPVwiZHNoQWNMYWJlbFwiIGh0bWxGb3I9e3Byb3BzLmlkfT57cHJvcHMubGFiZWx9PC9sYWJlbD5cbiAgICAgICAge3Byb3BzLm92ZXJyaWRkZW4gPyAoXG4gICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwiZHNoQWNCYWRnZXNcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImRzaEFjQmFkZ2VcIj57cHJvcHMudCgnY2hyb21lLm92ZXJyaWRkZW4nKX08L3NwYW4+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzc05hbWU9XCJkc2hBY1Jlc2V0XCIgZGlzYWJsZWQ9e3Byb3BzLmRpc2FibGVkfSBvbkNsaWNrPXtwcm9wcy5vblJlc2V0fT5cbiAgICAgICAgICAgICAge3Byb3BzLnQoJ2Nocm9tZS5yZXNldCcpfVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICApIDogbnVsbH1cbiAgICAgIDwvZGl2PlxuICAgICAgPGlucHV0XG4gICAgICAgIGlkPXtwcm9wcy5pZH1cbiAgICAgICAgY2xhc3NOYW1lPXtwcm9wcy5pbnZhbGlkID8gJ2RzaEFjSW5wdXQgZHNoQWNJbnB1dEludmFsaWQnIDogJ2RzaEFjSW5wdXQnfVxuICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgIGlucHV0TW9kZT17cHJvcHMubnVtZXJpYyA9PT0gdHJ1ZSA/ICdudW1lcmljJyA6IHVuZGVmaW5lZH1cbiAgICAgICAgYXJpYS1pbnZhbGlkPXtwcm9wcy5pbnZhbGlkIHx8IHVuZGVmaW5lZH1cbiAgICAgICAgdmFsdWU9e3Byb3BzLnRleHR9XG4gICAgICAgIHBsYWNlaG9sZGVyPXtwcm9wcy5wbGFjZWhvbGRlciA/PyAnJ31cbiAgICAgICAgZGlzYWJsZWQ9e3Byb3BzLmRpc2FibGVkfVxuICAgICAgICBvbkNoYW5nZT17KGV2ZW50KSA9PiBwcm9wcy5vbkVkaXQoZXZlbnQudGFyZ2V0LnZhbHVlKX1cbiAgICAgIC8+XG4gICAgICA8cCBjbGFzc05hbWU9e3Byb3BzLmludmFsaWQgPyAnZHNoQWNJbnZhbGlkJyA6ICdkc2hBY0hpbnQnfT5cbiAgICAgICAge3Byb3BzLmludmFsaWQgPyBwcm9wcy50KCdjaHJvbWUuaW52YWxpZE51bWJlcicpIDogcHJvcHMuaGludH1cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cbiAgKTtcbn1cblxuLyoqIEEgc3RhZ2VkIGJvb2xlYW4gZmllbGQ6IGluaGVyaXQgLyBvbiAvIG9mZi4gKi9cbmZ1bmN0aW9uIEJvb2xlYW5GaWVsZChwcm9wczogRmllbGRQcm9wcykge1xuICByZXR1cm4gKFxuICAgIDxkaXYgY2xhc3NOYW1lPVwiZHNoQWNGaWVsZFwiPlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJkc2hBY0hlYWRcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzTmFtZT1cImRzaEFjTGFiZWxcIiBodG1sRm9yPXtwcm9wcy5pZH0+e3Byb3BzLmxhYmVsfTwvbGFiZWw+XG4gICAgICAgIHtwcm9wcy5vdmVycmlkZGVuID8gKFxuICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImRzaEFjQmFkZ2VzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJkc2hBY0JhZGdlXCI+e3Byb3BzLnQoJ2Nocm9tZS5vdmVycmlkZGVuJyl9PC9zcGFuPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3NOYW1lPVwiZHNoQWNSZXNldFwiIGRpc2FibGVkPXtwcm9wcy5kaXNhYmxlZH0gb25DbGljaz17cHJvcHMub25SZXNldH0+XG4gICAgICAgICAgICAgIHtwcm9wcy50KCdjaHJvbWUucmVzZXQnKX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgKSA6IG51bGx9XG4gICAgICA8L2Rpdj5cbiAgICAgIDxzZWxlY3RcbiAgICAgICAgaWQ9e3Byb3BzLmlkfVxuICAgICAgICBjbGFzc05hbWU9XCJkc2hBY1NlbGVjdFwiXG4gICAgICAgIHZhbHVlPXtwcm9wcy50ZXh0fVxuICAgICAgICBkaXNhYmxlZD17cHJvcHMuZGlzYWJsZWR9XG4gICAgICAgIG9uQ2hhbmdlPXsoZXZlbnQpID0+IHByb3BzLm9uRWRpdChldmVudC50YXJnZXQudmFsdWUpfVxuICAgICAgPlxuICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+e3Byb3BzLnQoJ2Nocm9tZS5pbmhlcml0Jyl9PC9vcHRpb24+XG4gICAgICAgIDxvcHRpb24gdmFsdWU9XCJ0cnVlXCI+e3Byb3BzLnQoJ2Nocm9tZS5vbicpfTwvb3B0aW9uPlxuICAgICAgICA8b3B0aW9uIHZhbHVlPVwiZmFsc2VcIj57cHJvcHMudCgnY2hyb21lLm9mZicpfTwvb3B0aW9uPlxuICAgICAgPC9zZWxlY3Q+XG4gICAgICA8cCBjbGFzc05hbWU9XCJkc2hBY0hpbnRcIj57cHJvcHMuaGludH08L3A+XG4gICAgPC9kaXY+XG4gICk7XG59XG5cbi8qKlxuICogUmVuZGVyIHRoZSBhdXRvLWNvbnRpbnVlIGNhcmQuXG4gKiBAcGFyYW0gcHJvcHMgLSBsb2NhbGUgY29weSwgdGhlIGNhcmQgc25hcHNob3QsIGFuZCBpdHMgZm9ybSBhY3Rpb25zLlxuICogQHJldHVybnMgdGhlIGNhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBBdXRvQ29udGludWVTZXR0aW5nc0NhcmQocHJvcHM6IEF1dG9Db250aW51ZVNldHRpbmdzQ2FyZFByb3BzKSB7XG4gIGNvbnN0IHsgdCB9ID0gcHJvcHM7XG4gIGNvbnN0IHN0YXRlID0gcHJvcHMudXNlQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkKChzbmFwc2hvdCkgPT4gc25hcHNob3QpO1xuICBjb25zdCBkaXNhYmxlZCA9ICFzdGF0ZS53cml0YWJsZTtcbiAgY29uc3Qgc2hhcmVkID0geyB0LCBkaXNhYmxlZCB9O1xuICByZXR1cm4gKFxuICAgIDxTZXR0aW5nc0NhcmRcbiAgICAgIHQ9e3R9XG4gICAgICB0aXRsZUtleT1cImNhcmQudGl0bGVcIlxuICAgICAgZGVzY3JpcHRpb25LZXk9XCJjYXJkLmRlc2NyaXB0aW9uXCJcbiAgICAgIHN0YXRlPXtzdGF0ZX1cbiAgICAgIG9uU2F2ZT17cHJvcHMuc2F2ZX1cbiAgICAgIG9uRGlzY2FyZD17cHJvcHMuZGlzY2FyZH1cbiAgICA+XG4gICAgICA8VmFsdWVGaWVsZFxuICAgICAgICBpZD1cImF1dG8tY29udGludWUtY29udGludWUtdGV4dFwiXG4gICAgICAgIGxhYmVsPXt0KCdmaWVsZC5jb250aW51ZVRleHQnKX1cbiAgICAgICAgaGludD17dCgnZmllbGQuY29udGludWVUZXh0SGludCcpfVxuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUuY29udGludWVUZXh0fVxuICAgICAgICBvbkVkaXQ9eyh0ZXh0KSA9PiBwcm9wcy5lZGl0KCdjb250aW51ZVRleHQnLCB0ZXh0KX1cbiAgICAgICAgb25SZXNldD17KCkgPT4gcHJvcHMucmVzZXRGaWVsZCgnY29udGludWVUZXh0Jyl9XG4gICAgICAvPlxuICAgICAgPFZhbHVlRmllbGRcbiAgICAgICAgaWQ9XCJhdXRvLWNvbnRpbnVlLWdyYWNlLW1zXCJcbiAgICAgICAgbGFiZWw9e3QoJ2ZpZWxkLmdyYWNlTXMnKX1cbiAgICAgICAgaGludD17dCgnZmllbGQuZ3JhY2VNc0hpbnQnKX1cbiAgICAgICAgbnVtZXJpY1xuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUuZ3JhY2VNc31cbiAgICAgICAgb25FZGl0PXsodGV4dCkgPT4gcHJvcHMuZWRpdCgnZ3JhY2VNcycsIHRleHQpfVxuICAgICAgICBvblJlc2V0PXsoKSA9PiBwcm9wcy5yZXNldEZpZWxkKCdncmFjZU1zJyl9XG4gICAgICAvPlxuICAgICAgPFZhbHVlRmllbGRcbiAgICAgICAgaWQ9XCJhdXRvLWNvbnRpbnVlLWNvb2xkb3duLW1zXCJcbiAgICAgICAgbGFiZWw9e3QoJ2ZpZWxkLmNvb2xkb3duTXMnKX1cbiAgICAgICAgaGludD17dCgnZmllbGQuY29vbGRvd25Nc0hpbnQnKX1cbiAgICAgICAgbnVtZXJpY1xuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUuY29vbGRvd25Nc31cbiAgICAgICAgb25FZGl0PXsodGV4dCkgPT4gcHJvcHMuZWRpdCgnY29vbGRvd25NcycsIHRleHQpfVxuICAgICAgICBvblJlc2V0PXsoKSA9PiBwcm9wcy5yZXNldEZpZWxkKCdjb29sZG93bk1zJyl9XG4gICAgICAvPlxuICAgICAgPFZhbHVlRmllbGRcbiAgICAgICAgaWQ9XCJhdXRvLWNvbnRpbnVlLW1heC1jb25zZWN1dGl2ZVwiXG4gICAgICAgIGxhYmVsPXt0KCdmaWVsZC5tYXhDb25zZWN1dGl2ZScpfVxuICAgICAgICBoaW50PXt0KCdmaWVsZC5tYXhDb25zZWN1dGl2ZUhpbnQnKX1cbiAgICAgICAgbnVtZXJpY1xuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUubWF4Q29uc2VjdXRpdmV9XG4gICAgICAgIG9uRWRpdD17KHRleHQpID0+IHByb3BzLmVkaXQoJ21heENvbnNlY3V0aXZlJywgdGV4dCl9XG4gICAgICAgIG9uUmVzZXQ9eygpID0+IHByb3BzLnJlc2V0RmllbGQoJ21heENvbnNlY3V0aXZlJyl9XG4gICAgICAvPlxuICAgICAgPEJvb2xlYW5GaWVsZFxuICAgICAgICBpZD1cImF1dG8tY29udGludWUtc2Nhbi1vbi1ib290XCJcbiAgICAgICAgbGFiZWw9e3QoJ2ZpZWxkLnNjYW5PbkJvb3QnKX1cbiAgICAgICAgaGludD17dCgnZmllbGQuc2Nhbk9uQm9vdEhpbnQnKX1cbiAgICAgICAgey4uLnNoYXJlZH1cbiAgICAgICAgey4uLnN0YXRlLnNjYW5PbkJvb3R9XG4gICAgICAgIG9uRWRpdD17KHRleHQpID0+IHByb3BzLmVkaXQoJ3NjYW5PbkJvb3QnLCB0ZXh0KX1cbiAgICAgICAgb25SZXNldD17KCkgPT4gcHJvcHMucmVzZXRGaWVsZCgnc2Nhbk9uQm9vdCcpfVxuICAgICAgLz5cbiAgICAgIDxWYWx1ZUZpZWxkXG4gICAgICAgIGlkPVwiYXV0by1jb250aW51ZS1zY2FuLWxpbWl0XCJcbiAgICAgICAgbGFiZWw9e3QoJ2ZpZWxkLnNjYW5MaW1pdCcpfVxuICAgICAgICBoaW50PXt0KCdmaWVsZC5zY2FuTGltaXRIaW50Jyl9XG4gICAgICAgIG51bWVyaWNcbiAgICAgICAgey4uLnNoYXJlZH1cbiAgICAgICAgey4uLnN0YXRlLnNjYW5MaW1pdH1cbiAgICAgICAgb25FZGl0PXsodGV4dCkgPT4gcHJvcHMuZWRpdCgnc2NhbkxpbWl0JywgdGV4dCl9XG4gICAgICAgIG9uUmVzZXQ9eygpID0+IHByb3BzLnJlc2V0RmllbGQoJ3NjYW5MaW1pdCcpfVxuICAgICAgLz5cbiAgICAgIDxWYWx1ZUZpZWxkXG4gICAgICAgIGlkPVwiYXV0by1jb250aW51ZS1mcmVzaC1tc1wiXG4gICAgICAgIGxhYmVsPXt0KCdmaWVsZC5mcmVzaE1zJyl9XG4gICAgICAgIGhpbnQ9e3QoJ2ZpZWxkLmZyZXNoTXNIaW50Jyl9XG4gICAgICAgIG51bWVyaWNcbiAgICAgICAgey4uLnNoYXJlZH1cbiAgICAgICAgey4uLnN0YXRlLmZyZXNoTXN9XG4gICAgICAgIG9uRWRpdD17KHRleHQpID0+IHByb3BzLmVkaXQoJ2ZyZXNoTXMnLCB0ZXh0KX1cbiAgICAgICAgb25SZXNldD17KCkgPT4gcHJvcHMucmVzZXRGaWVsZCgnZnJlc2hNcycpfVxuICAgICAgLz5cbiAgICAgIDxWYWx1ZUZpZWxkXG4gICAgICAgIGlkPVwiYXV0by1jb250aW51ZS1yZWNvbm5lY3Qtc2Nhbi1kZWxheVwiXG4gICAgICAgIGxhYmVsPXt0KCdmaWVsZC5yZWNvbm5lY3RTY2FuRGVsYXlNcycpfVxuICAgICAgICBoaW50PXt0KCdmaWVsZC5yZWNvbm5lY3RTY2FuRGVsYXlNc0hpbnQnKX1cbiAgICAgICAgbnVtZXJpY1xuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUucmVjb25uZWN0U2NhbkRlbGF5TXN9XG4gICAgICAgIG9uRWRpdD17KHRleHQpID0+IHByb3BzLmVkaXQoJ3JlY29ubmVjdFNjYW5EZWxheU1zJywgdGV4dCl9XG4gICAgICAgIG9uUmVzZXQ9eygpID0+IHByb3BzLnJlc2V0RmllbGQoJ3JlY29ubmVjdFNjYW5EZWxheU1zJyl9XG4gICAgICAvPlxuICAgICAgPFZhbHVlRmllbGRcbiAgICAgICAgaWQ9XCJhdXRvLWNvbnRpbnVlLXJlY29ubmVjdC1iYWNrb2ZmXCJcbiAgICAgICAgbGFiZWw9e3QoJ2ZpZWxkLnJlY29ubmVjdEJhY2tvZmZNcycpfVxuICAgICAgICBoaW50PXt0KCdmaWVsZC5yZWNvbm5lY3RCYWNrb2ZmTXNIaW50Jyl9XG4gICAgICAgIG51bWVyaWNcbiAgICAgICAgey4uLnNoYXJlZH1cbiAgICAgICAgey4uLnN0YXRlLnJlY29ubmVjdEJhY2tvZmZNc31cbiAgICAgICAgb25FZGl0PXsodGV4dCkgPT4gcHJvcHMuZWRpdCgncmVjb25uZWN0QmFja29mZk1zJywgdGV4dCl9XG4gICAgICAgIG9uUmVzZXQ9eygpID0+IHByb3BzLnJlc2V0RmllbGQoJ3JlY29ubmVjdEJhY2tvZmZNcycpfVxuICAgICAgLz5cbiAgICAgIDxCb29sZWFuRmllbGRcbiAgICAgICAgaWQ9XCJhdXRvLWNvbnRpbnVlLXZlcmJvc2VcIlxuICAgICAgICBsYWJlbD17dCgnZmllbGQudmVyYm9zZScpfVxuICAgICAgICBoaW50PXt0KCdmaWVsZC52ZXJib3NlSGludCcpfVxuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUudmVyYm9zZX1cbiAgICAgICAgb25FZGl0PXsodGV4dCkgPT4gcHJvcHMuZWRpdCgndmVyYm9zZScsIHRleHQpfVxuICAgICAgICBvblJlc2V0PXsoKSA9PiBwcm9wcy5yZXNldEZpZWxkKCd2ZXJib3NlJyl9XG4gICAgICAvPlxuICAgIDwvU2V0dGluZ3NDYXJkPlxuICApO1xufVxuIiwgIi8qKlxuICogU3RhZ2VkIGZvcm0gbW9kZWwgYmVoaW5kIHRoZSBwbHVnaW4gc2V0dGluZ3MgY2FyZCDigJQgYSBzZWxmLWNvbnRhaW5lZFxuICogaW1wbGVtZW50YXRpb24gb2YgdGhlIHBsdWdpbi1jYXJkIHN0b3JlIHBhdHRlcm4gdXNlZCBieSB0aGUgRFNIIHBsdWdpblxuICogY29uZmlndXJhdGlvbiBzZWN0aW9uLlxuICpcbiAqIEEgY2FyZCBzdGFnZXMgd2hhdCB0aGUgdXNlciB0eXBlcyBhbmQgd3JpdGVzIGl0IG9ubHkgd2hlbiB0aGV5IHNhdmUuIEVhY2hcbiAqIHNldHRpbmdzIHdyaXRlIGlzIGEgZHVyYWJsZSwgcmV2aXNpb24tZmVuY2VkIGRvY3VtZW50IG11dGF0aW9uLCBzbyBzdGFnaW5nXG4gKiBrZWVwcyB3aGF0IGlzIG9uIHNjcmVlbiBleGFjdGx5IHdoYXQgYSBzYXZlIHdvdWxkIHN0b3JlLiBBIGZpZWxkIHNob3dzIGl0c1xuICogZWZmZWN0aXZlIHZhbHVlIOKAlCB0aGUgdXNlciBsYXllciBvdmVyIHRoZSBjb21wb3NpdGlvbiBsYXllciBvdmVyIHRoZSBzY2hlbWFcbiAqIGRlZmF1bHQg4oCUIGFuZCB3aGV0aGVyIHRoZSB1c2VyIGxheWVyIGNhcnJpZXMgaXQgKHByZXNlbmNlLCBub3QgdmFsdWVcbiAqIGVxdWFsaXR5LCBtYXJrcyBhbiBvdmVycmlkZSkuXG4gKi9cbmltcG9ydCB0eXBlIHsgU2V0dGluZ3NTY29wZSwgU25hcHNob3RTdG9yZSB9IGZyb20gJ0BkZWVwc2Vlay1haS9kc2gtY2xpZW50LXJ1bnRpbWUvY2xpZW50JztcblxuLyoqIFRoZSB3cml0ZSBvbmUgZmllbGQncyBzdGFnZWQgdGV4dCBwZXJmb3JtcyB3aGVuIHRoZSBjYXJkIGlzIHNhdmVkLiAqL1xuZXhwb3J0IHR5cGUgRmllbGRXcml0ZSA9IHsga2luZDogJ3NldCc7IHZhbHVlOiB1bmtub3duIH0gfCB7IGtpbmQ6ICdjbGVhcicgfTtcblxuLyoqIEhvdyBvbmUgZmllbGQgY29udmVydHMgYmV0d2VlbiBpdHMgc3RvcmVkIHZhbHVlIGFuZCBpdHMgZHJhZnQgdGV4dC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FyZEZpZWxkU3BlYyB7XG4gIC8qKiBGaWVsZCBuYW1lIGluc2lkZSB0aGUgbmFtZXNwYWNlIHNlY3Rpb24uICovXG4gIGZpZWxkOiBzdHJpbmc7XG4gIC8qKiBSZW5kZXIgYSBzdG9yZWQgdmFsdWUgYXMgZHJhZnQgdGV4dDsgdGhlIGVtcHR5IHN0cmluZyB3aGVuIHRoZSBzZWN0aW9uIGNhcnJpZXMgbm9uZS4gKi9cbiAgZm9ybWF0OiAodmFsdWU6IHVua25vd24pID0+IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSB3cml0ZSB0aGlzIGRyYWZ0IHRleHQgc3RhZ2VzLCBvciB1bmRlZmluZWQgd2hlbiB0aGUgdGV4dCBpcyBub3QgYVxuICAgKiB2YWx1ZSB0aGlzIGZpZWxkIGFjY2VwdHMg4oCUIHdoaWNoIGJsb2NrcyB0aGUgc2F2ZSByYXRoZXIgdGhhbiBkaXNjYXJkaW5nIGl0LlxuICAgKi9cbiAgcGFyc2U6ICh0ZXh0OiBzdHJpbmcpID0+IEZpZWxkV3JpdGUgfCB1bmRlZmluZWQ7XG59XG5cbi8qKiBPbmUgZmllbGQgYXMgdGhlIGNhcmQncyBjb250cm9sIHJlbmRlcnMgaXQuICovXG5leHBvcnQgaW50ZXJmYWNlIENhcmRGaWVsZFN0YXRlIHtcbiAgLyoqIERyYWZ0IHRleHQgdGhlIGNvbnRyb2wgcmVuZGVycy4gKi9cbiAgdGV4dDogc3RyaW5nO1xuICAvKiogV2hldGhlciBzYXZpbmcgd291bGQgbGVhdmUgYSB1c2VyLWxheWVyIGVudHJ5IGZvciB0aGlzIGZpZWxkLiAqL1xuICBvdmVycmlkZGVuOiBib29sZWFuO1xuICAvKiogV2hldGhlciB0aGUgZHJhZnQgaXMgbm90IGEgdmFsdWUgdGhpcyBmaWVsZCBhY2NlcHRzLCB3aGljaCBibG9ja3Mgc2F2aW5nLiAqL1xuICBpbnZhbGlkOiBib29sZWFuO1xufVxuXG4vKiogRm9ybSBzdGF0ZSBldmVyeSBwbHVnaW4gY2FyZCBzaGFyZXMuICovXG5leHBvcnQgaW50ZXJmYWNlIENhcmRTaGVsbCB7XG4gIC8qKiBGYWxzZSB3aGlsZSB0aGUgbmFtZXNwYWNlIGlzIG5vdCBzZXJ2ZWQgdG8gdGhpcyBjbGllbnQ7IHRoZSBjYXJkIHJlbmRlcnMgbm90aGluZy4gKi9cbiAgYXZhaWxhYmxlOiBib29sZWFuO1xuICAvKiogV2hldGhlciB0aGUgSG9zdCBkb2N1bWVudCBhY2NlcHRzIHdyaXRlcy4gKi9cbiAgd3JpdGFibGU6IGJvb2xlYW47XG4gIC8qKiBXaGV0aGVyIHRoZSBmb3JtIGhvbGRzIGVkaXRzIHRoYXQgYSBzYXZlIHdvdWxkIHdyaXRlLiAqL1xuICBkaXJ0eTogYm9vbGVhbjtcbiAgLyoqIFdoZXRoZXIgYW55IHN0YWdlZCBkcmFmdCBpcyBpbnZhbGlkLCB3aGljaCBibG9ja3MgdGhlIHNhdmUuICovXG4gIGludmFsaWQ6IGJvb2xlYW47XG4gIC8qKiBXaGV0aGVyIGEgc2F2ZSBpcyBjcm9zc2luZyB0aGUgd2lyZS4gKi9cbiAgc2F2aW5nOiBib29sZWFuO1xuICAvKiogV2hldGhlciB0aGUgbGFzdCBzYXZlIGRpZCBub3QgbGFuZCBhcyBzdGFnZWQ7IGNsZWFyZWQgYnkgdGhlIG5leHQgZWRpdCBvciBzYXZlLiAqL1xuICBmYWlsZWQ6IGJvb2xlYW47XG59XG5cbi8qKiBUaGUgd3JpdGUgYWN0aW9ucyB0aGUgY2FyZCdzIHNsb3QgZW50cnkgaW5qZWN0cy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FyZEFjdGlvbnMge1xuICAvKiogU3RhZ2UgZHJhZnQgdGV4dCBmb3Igb25lIGZpZWxkLiAqL1xuICBlZGl0OiAoZmllbGQ6IHN0cmluZywgdGV4dDogc3RyaW5nKSA9PiB2b2lkO1xuICAvKiogU3RhZ2UgYSBjbGVhciwgc28gc2F2aW5nIGxldHMgdGhlIGZpZWxkIHJlLWluaGVyaXQgdGhlIGNvbXBvc2l0aW9uIGxheWVyLiAqL1xuICByZXNldEZpZWxkOiAoZmllbGQ6IHN0cmluZykgPT4gdm9pZDtcbiAgLyoqIFdyaXRlIGV2ZXJ5IHN0YWdlZCBlZGl0LCB0aGVuIHJlLXNlZWQgZnJvbSB3aGF0IHRoZSBIb3N0IGFjY2VwdGVkLiAqL1xuICBzYXZlOiAoKSA9PiB2b2lkO1xuICAvKiogRHJvcCBldmVyeSBzdGFnZWQgZWRpdC4gKi9cbiAgZGlzY2FyZDogKCkgPT4gdm9pZDtcbn1cblxuLyoqIEEgd2hvbGUtbnVtYmVyIGZpZWxkLiBBbiBlbXB0eSBkcmFmdCBjbGVhcnMgdGhlIGZpZWxkOyBhIG5vbi1udW1iZXIgb3Igb3V0LW9mLXJhbmdlIGRyYWZ0IGJsb2NrcyB0aGUgc2F2ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBudW1iZXJGaWVsZChmaWVsZDogc3RyaW5nLCBtaW4gPSAwKTogQ2FyZEZpZWxkU3BlYyB7XG4gIHJldHVybiB7XG4gICAgZmllbGQsXG4gICAgZm9ybWF0OiAodmFsdWUpID0+ICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInID8gU3RyaW5nKHZhbHVlKSA6ICcnKSxcbiAgICBwYXJzZTogKHRleHQpID0+IHtcbiAgICAgIGNvbnN0IHRyaW1tZWQgPSB0ZXh0LnRyaW0oKTtcbiAgICAgIGlmICh0cmltbWVkID09PSAnJykgcmV0dXJuIHsga2luZDogJ2NsZWFyJyB9O1xuICAgICAgY29uc3QgcGFyc2VkID0gTnVtYmVyKHRyaW1tZWQpO1xuICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUocGFyc2VkKSB8fCAhTnVtYmVyLmlzSW50ZWdlcihwYXJzZWQpIHx8IHBhcnNlZCA8IG1pbikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiB7IGtpbmQ6ICdzZXQnLCB2YWx1ZTogcGFyc2VkIH07XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqIEEgZnJlZS10ZXh0IGZpZWxkLiBBbiBlbXB0eSBkcmFmdCBjbGVhcnMgdGhlIGZpZWxkLCBzbyBlbXB0eWluZyB0aGUgY29udHJvbCBhbmQgc2F2aW5nIGlzIHRoZSBzYW1lIGdlc3R1cmUgYXMgcmVzZXR0aW5nIGl0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRleHRGaWVsZChmaWVsZDogc3RyaW5nKTogQ2FyZEZpZWxkU3BlYyB7XG4gIHJldHVybiB7XG4gICAgZmllbGQsXG4gICAgZm9ybWF0OiAodmFsdWUpID0+ICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUgOiAnJyksXG4gICAgcGFyc2U6ICh0ZXh0KSA9PiB7XG4gICAgICBjb25zdCB0cmltbWVkID0gdGV4dC50cmltKCk7XG4gICAgICByZXR1cm4gdHJpbW1lZCA9PT0gJycgPyB7IGtpbmQ6ICdjbGVhcicgfSA6IHsga2luZDogJ3NldCcsIHZhbHVlOiB0cmltbWVkIH07XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqIEEgYm9vbGVhbiBmaWVsZCwgZWRpdGVkIHRocm91Z2ggdHJ1ZS9mYWxzZSBkcmFmdCB0ZXh0OyBhbiBlbXB0eSBkcmFmdCBpbmhlcml0cy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBib29sZWFuRmllbGQoZmllbGQ6IHN0cmluZyk6IENhcmRGaWVsZFNwZWMge1xuICByZXR1cm4ge1xuICAgIGZpZWxkLFxuICAgIGZvcm1hdDogKHZhbHVlKSA9PiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicgPyBTdHJpbmcodmFsdWUpIDogJycpLFxuICAgIHBhcnNlOiAodGV4dCkgPT4ge1xuICAgICAgY29uc3QgdHJpbW1lZCA9IHRleHQudHJpbSgpO1xuICAgICAgaWYgKHRyaW1tZWQgPT09ICcnKSByZXR1cm4geyBraW5kOiAnY2xlYXInIH07XG4gICAgICBpZiAodHJpbW1lZCA9PT0gJ3RydWUnKSByZXR1cm4geyBraW5kOiAnc2V0JywgdmFsdWU6IHRydWUgfTtcbiAgICAgIGlmICh0cmltbWVkID09PSAnZmFsc2UnKSByZXR1cm4geyBraW5kOiAnc2V0JywgdmFsdWU6IGZhbHNlIH07XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKiBPbmUgZmllbGQncyBzdGFnZWQgZWRpdC4gKi9cbmludGVyZmFjZSBTdGFnZWRFZGl0IHtcbiAgLyoqIERyYWZ0IHRleHQgdGhlIGNvbnRyb2wgcmVuZGVycy4gKi9cbiAgdGV4dDogc3RyaW5nO1xuICAvKiogVHJ1ZSB3aGVuIHRoaXMgZWRpdCBjbGVhcnMgdGhlIGZpZWxkIHdoYXRldmVyIHRleHQgaXQgc2hvd3MuICovXG4gIGNsZWFyOiBib29sZWFuO1xufVxuXG4vKipcbiAqIFN0YWdlcyBvbmUgY2FyZCdzIGVkaXRzIG92ZXIgb25lIHNldHRpbmdzIG5hbWVzcGFjZSBhbmQgd3JpdGVzIHRoZW0gb24gc2F2ZS5cbiAqXG4gKiBUaGUgSG9zdCBpcyB0aGUgb25seSBhdXRob3JpdHkgb24gd2hldGhlciBhIHZhbHVlIHdhcyBhY2NlcHRlZCwgc28gdGhlXG4gKiBvdXRjb21lIGlzIHJlYWQgYmFjayBmcm9tIHRoZSBzZWN0aW9uIHJhdGhlciB0aGFuIHByZWRpY3RlZCBoZXJlLiBBIHNhdmVcbiAqIHRoYXQgZGlkIG5vdCBsYW5kIGtlZXBzIGl0cyBkcmFmdHMsIHNvIHRoZSB1c2VyIGNhbiBjb3JyZWN0IHRoZW0gaW5zdGVhZCBvZlxuICogcmV0eXBpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBDYXJkRm9ybTxUPiB7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3BlY3M6IE1hcDxzdHJpbmcsIENhcmRGaWVsZFNwZWM+O1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YWdlZCA9IG5ldyBNYXA8c3RyaW5nLCBTdGFnZWRFZGl0PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGxpc3RlbmVycyA9IG5ldyBTZXQ8KCkgPT4gdm9pZD4oKTtcbiAgcHJpdmF0ZSBzYXZpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBmYWlsZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogQHBhcmFtIHNjb3BlIC0gdGhlIGJvdW5kIHNldHRpbmdzIHNjb3BlIGZvciB0aGlzIGNhcmQncyBuYW1lc3BhY2UuXG4gICAqIEBwYXJhbSBzcGVjcyAtIHRoZSBzZWN0aW9uIGZpZWxkcyB0aGlzIGNhcmQgZWRpdHMuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNjb3BlOiBTZXR0aW5nc1Njb3BlPFQ+LFxuICAgIHNwZWNzOiBDYXJkRmllbGRTcGVjW10sXG4gICkge1xuICAgIHRoaXMuc3BlY3MgPSBuZXcgTWFwKHNwZWNzLm1hcCgoc3BlYykgPT4gW3NwZWMuZmllbGQsIHNwZWNdKSk7XG4gICAgdGhpcy5zY29wZS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5wdWJsaXNoKCkpO1xuICB9XG5cbiAgLyoqIFB1Ymxpc2ggYSBwcm9qZWN0aW9uIG9mIHRoaXMgZm9ybSwgcmVidWlsdCB3aGVuZXZlciB0aGUgc2NvcGUgb3IgYSBkcmFmdCBjaGFuZ2VzLiAqL1xuICBiaW5kPFM+KHByb2plY3Q6ICgpID0+IFMsIGNyZWF0ZVN0b3JlOiAoaW5pdDogUykgPT4gU25hcHNob3RTdG9yZTxTPik6IFNuYXBzaG90U3RvcmU8Uz4ge1xuICAgIGNvbnN0IHN0b3JlID0gY3JlYXRlU3RvcmUocHJvamVjdCgpKTtcbiAgICB0aGlzLmxpc3RlbmVycy5hZGQoKCkgPT4gc3RvcmUuc2V0KHByb2plY3QoKSkpO1xuICAgIHJldHVybiBzdG9yZTtcbiAgfVxuXG4gIC8qKiBSZWFkIHRoZSBjYXJkLWxldmVsIHN0YXRlOiB3aGF0IHRoZSBIb3N0IHNlcnZlcywgYW5kIHdoYXQgYSBzYXZlIHdvdWxkIGRvLiAqL1xuICBzaGVsbCgpOiBDYXJkU2hlbGwge1xuICAgIGNvbnN0IHNuYXBzaG90ID0gdGhpcy5zY29wZS5nZXRTbmFwc2hvdCgpO1xuICAgIHJldHVybiB7XG4gICAgICBhdmFpbGFibGU6IHNuYXBzaG90LnN0YXR1cyA9PT0gJ3JlYWR5JyxcbiAgICAgIHdyaXRhYmxlOiBzbmFwc2hvdC53cml0YWJsZSxcbiAgICAgIGRpcnR5OiB0aGlzLnBsYW4oKS5sZW5ndGggPiAwLFxuICAgICAgaW52YWxpZDogdGhpcy5wbGFuKCkuc29tZSgoaXRlbSkgPT4gaXRlbS5ydW4gPT09IHVuZGVmaW5lZCksXG4gICAgICBzYXZpbmc6IHRoaXMuc2F2aW5nLFxuICAgICAgZmFpbGVkOiB0aGlzLmZhaWxlZCxcbiAgICB9O1xuICB9XG5cbiAgLyoqIFJlYWQgb25lIGZpZWxkJ3Mgc3RhdGUgZnJvbSB0aGUgZWZmZWN0aXZlIHNlY3Rpb24gYW5kIGl0cyBzdGFnZWQgZHJhZnQuICovXG4gIGZpZWxkKGZpZWxkOiBzdHJpbmcpOiBDYXJkRmllbGRTdGF0ZSB7XG4gICAgY29uc3Qgc3BlYyA9IHRoaXMuc3BlY09mKGZpZWxkKTtcbiAgICBjb25zdCBzdGFnZWQgPSB0aGlzLnN0YWdlZC5nZXQoZmllbGQpO1xuICAgIGlmIChzdGFnZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGV4dDogc3BlYy5mb3JtYXQodGhpcy5zZWN0aW9uVmFsdWUoZmllbGQpKSxcbiAgICAgICAgb3ZlcnJpZGRlbjogdGhpcy5zdG9yZWQoZmllbGQpLFxuICAgICAgICBpbnZhbGlkOiBmYWxzZSxcbiAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IHdyaXRlID0gc3RhZ2VkLmNsZWFyID8geyBraW5kOiAnY2xlYXInIGFzIGNvbnN0IH0gOiBzcGVjLnBhcnNlKHN0YWdlZC50ZXh0KTtcbiAgICByZXR1cm4ge1xuICAgICAgdGV4dDogc3RhZ2VkLnRleHQsXG4gICAgICBvdmVycmlkZGVuOiB3cml0ZT8ua2luZCA9PT0gJ3NldCcsXG4gICAgICBpbnZhbGlkOiB3cml0ZSA9PT0gdW5kZWZpbmVkLFxuICAgIH07XG4gIH1cblxuICAvKiogVGhlIGFjdGlvbnMgdGhlIGNhcmQncyBzbG90IHJlZ2lzdHJhdGlvbiBpbmplY3RzLiAqL1xuICBhY3Rpb25zKCk6IENhcmRBY3Rpb25zIHtcbiAgICByZXR1cm4ge1xuICAgICAgZWRpdDogKGZpZWxkLCB0ZXh0KSA9PiB0aGlzLnN0YWdlKGZpZWxkLCB7IHRleHQsIGNsZWFyOiBmYWxzZSB9KSxcbiAgICAgIHJlc2V0RmllbGQ6IChmaWVsZCkgPT4ge1xuICAgICAgICB0aGlzLnN0YWdlKGZpZWxkLCB7IHRleHQ6IHRoaXMuc3BlY09mKGZpZWxkKS5mb3JtYXQodGhpcy5iYXNlVmFsdWUoZmllbGQpKSwgY2xlYXI6IHRydWUgfSk7XG4gICAgICB9LFxuICAgICAgc2F2ZTogKCkgPT4gdm9pZCB0aGlzLnNhdmUoKSxcbiAgICAgIGRpc2NhcmQ6ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuc3RhZ2VkLnNpemUgPT09IDAgJiYgIXRoaXMuZmFpbGVkKSByZXR1cm47XG4gICAgICAgIHRoaXMuc3RhZ2VkLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuZmFpbGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHVibGlzaCgpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFdyaXRlIGV2ZXJ5IHN0YWdlZCBlZGl0LCB0aGVuIHJlLXNlZWQgZnJvbSB3aGF0IHRoZSBIb3N0IGFjY2VwdGVkLlxuICAgKiBAcmV0dXJucyBzZXR0bGVtZW50IGFmdGVyIGV2ZXJ5IHdyaXRlIGFuZCB0aGUgcmVhZC1iYWNrLlxuICAgKi9cbiAgYXN5bmMgc2F2ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBwbGFuID0gdGhpcy5wbGFuKCk7XG4gICAgY29uc3Qgd3JpdGVzID0gcGxhbi5mbGF0TWFwKChpdGVtKSA9PiAoaXRlbS5ydW4gPT09IHVuZGVmaW5lZCA/IFtdIDogW2l0ZW0ucnVuXSkpO1xuICAgIGlmIChwbGFuLmxlbmd0aCA9PT0gMCB8fCB0aGlzLnNhdmluZyB8fCB3cml0ZXMubGVuZ3RoICE9PSBwbGFuLmxlbmd0aCkgcmV0dXJuO1xuICAgIC8vIFNuYXBzaG90IHRoZSBmaWVsZHMgdGhpcyBzYXZlIHdyaXRlcywgc28gZWRpdHMgc3RhZ2VkIHdoaWxlIGl0IGlzIGluXG4gICAgLy8gZmxpZ2h0IHN1cnZpdmU6IG9ubHkgdGhlIHN0YWdlZCBrZXlzIHRoaXMgc2F2ZSBhY3R1YWxseSB3cm90ZSBhcmUgY2xlYXJlZC5cbiAgICBjb25zdCBmaWVsZHMgPSBuZXcgU2V0KHBsYW4ubWFwKChpdGVtKSA9PiBpdGVtLmZpZWxkKSk7XG4gICAgdGhpcy5zYXZpbmcgPSB0cnVlO1xuICAgIHRoaXMuZmFpbGVkID0gZmFsc2U7XG4gICAgdGhpcy5wdWJsaXNoKCk7XG4gICAgbGV0IGxhbmRlZCA9IHRydWU7XG4gICAgZm9yIChjb25zdCB3cml0ZSBvZiB3cml0ZXMpIHtcbiAgICAgIGxhbmRlZCA9IChhd2FpdCB3cml0ZSgpKSAmJiBsYW5kZWQ7XG4gICAgfVxuICAgIGlmIChsYW5kZWQpIHtcbiAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgZmllbGRzKSB0aGlzLnN0YWdlZC5kZWxldGUoZmllbGQpO1xuICAgIH1cbiAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgIHRoaXMuZmFpbGVkID0gIWxhbmRlZDtcbiAgICB0aGlzLnB1Ymxpc2goKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFdmVyeSBzdGFnZWQgZWRpdCBhIHNhdmUgd291bGQgd3JpdGUuIEFuIGVudHJ5IHdob3NlIGRyYWZ0IGlzIG5vdCBhIHZhbHVlXG4gICAqIGl0cyBmaWVsZCBhY2NlcHRzIGNhcnJpZXMgbm8gd3JpdGU6IHRoZSBmb3JtIGlzIHN0aWxsIGRpcnR5LCBhbmQgdGhlIHNhdmVcbiAgICogcmVmdXNlcyByYXRoZXIgdGhhbiBkcm9wcGluZyB0aGUgZWRpdC4gQSBzdGFnZWQgZWRpdCB0aGF0IG1hdGNoZXMgdGhlXG4gICAqIGVmZmVjdGl2ZSBzZWN0aW9uIGlzIG5vdCBhIHdyaXRlIGF0IGFsbC5cbiAgICovXG4gIHByaXZhdGUgcGxhbigpOiB7IGZpZWxkOiBzdHJpbmc7IHJ1bjogKCgpID0+IFByb21pc2U8Ym9vbGVhbj4pIHwgdW5kZWZpbmVkIH1bXSB7XG4gICAgY29uc3QgcGxhbjogeyBmaWVsZDogc3RyaW5nOyBydW46ICgoKSA9PiBQcm9taXNlPGJvb2xlYW4+KSB8IHVuZGVmaW5lZCB9W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IFtmaWVsZCwgc3RhZ2VkXSBvZiB0aGlzLnN0YWdlZCkge1xuICAgICAgY29uc3Qgc3BlYyA9IHRoaXMuc3BlY09mKGZpZWxkKTtcbiAgICAgIGlmIChzdGFnZWQuY2xlYXIpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RvcmVkKGZpZWxkKSkgcGxhbi5wdXNoKHsgZmllbGQsIHJ1bjogKCkgPT4gdGhpcy5jbGVhcihmaWVsZCkgfSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHN0YWdlZC50ZXh0ID09PSBzcGVjLmZvcm1hdCh0aGlzLnNlY3Rpb25WYWx1ZShmaWVsZCkpKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IHdyaXRlID0gc3BlYy5wYXJzZShzdGFnZWQudGV4dCk7XG4gICAgICBpZiAod3JpdGUgPT09IHVuZGVmaW5lZCkgcGxhbi5wdXNoKHsgZmllbGQsIHJ1bjogdW5kZWZpbmVkIH0pO1xuICAgICAgZWxzZSBpZiAod3JpdGUua2luZCA9PT0gJ2NsZWFyJykgcGxhbi5wdXNoKHsgZmllbGQsIHJ1bjogKCkgPT4gdGhpcy5jbGVhcihmaWVsZCkgfSk7XG4gICAgICBlbHNlIHBsYW4ucHVzaCh7IGZpZWxkLCBydW46ICgpID0+IHRoaXMuc3RvcmUoZmllbGQsIHdyaXRlLnZhbHVlKSB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYW47XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNsZWFyKGZpZWxkOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBhd2FpdCB0aGlzLnNjb3BlLnVuc2V0KGZpZWxkKTtcbiAgICByZXR1cm4gIXRoaXMuc3RvcmVkKGZpZWxkKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc3RvcmUoZmllbGQ6IHN0cmluZywgdmFsdWU6IHVua25vd24pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBhd2FpdCB0aGlzLnNjb3BlLnNldChmaWVsZCwgdmFsdWUpO1xuICAgIHJldHVybiB0aGlzLnVzZXJMYXllcigpPy5bZmllbGRdID09PSB2YWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhZ2UoZmllbGQ6IHN0cmluZywgZWRpdDogU3RhZ2VkRWRpdCk6IHZvaWQge1xuICAgIHRoaXMuc3RhZ2VkLnNldChmaWVsZCwgZWRpdCk7XG4gICAgdGhpcy5mYWlsZWQgPSBmYWxzZTtcbiAgICB0aGlzLnB1Ymxpc2goKTtcbiAgfVxuXG4gIHByaXZhdGUgc3BlY09mKGZpZWxkOiBzdHJpbmcpOiBDYXJkRmllbGRTcGVjIHtcbiAgICBjb25zdCBzcGVjID0gdGhpcy5zcGVjcy5nZXQoZmllbGQpO1xuICAgIGlmIChzcGVjID09PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcihgc2V0dGluZ3MgY2FyZCBoYXMgbm8gZmllbGQgJHtmaWVsZH1gKTtcbiAgICByZXR1cm4gc3BlYztcbiAgfVxuXG4gIHByaXZhdGUgc2VjdGlvblZhbHVlKGZpZWxkOiBzdHJpbmcpOiB1bmtub3duIHtcbiAgICByZXR1cm4gKHRoaXMuc2NvcGUuZ2V0U25hcHNob3QoKS52YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZCk/LltmaWVsZF07XG4gIH1cblxuICBwcml2YXRlIGJhc2VWYWx1ZShmaWVsZDogc3RyaW5nKTogdW5rbm93biB7XG4gICAgcmV0dXJuICh0aGlzLnNjb3BlLmdldFNuYXBzaG90KCkuYmFzZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZCk/LltmaWVsZF07XG4gIH1cblxuICBwcml2YXRlIHVzZXJMYXllcigpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuc2NvcGUuZ2V0U25hcHNob3QoKS51c2VyIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9yZWQoZmllbGQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHVzZXIgPSB0aGlzLnVzZXJMYXllcigpO1xuICAgIHJldHVybiB1c2VyICE9PSB1bmRlZmluZWQgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHVzZXIsIGZpZWxkKTtcbiAgfVxuXG4gIHByaXZhdGUgcHVibGlzaCgpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRoaXMubGlzdGVuZXJzKSBsaXN0ZW5lcigpO1xuICB9XG59XG4iLCAiLyoqXG4gKiBTdHlsZXMgZm9yIHRoZSBhdXRvLWNvbnRpbnVlIHNldHRpbmdzIGNhcmQsIGluamVjdGVkIGF0IGZhY3RvcnlcbiAqIG1hdGVyaWFsaXphdGlvbiBzbyB0aGUgY2xpZW50IG1vZHVsZSBzeXN0ZW0ncyBzdHlsZSBib29ra2VlcGluZyAoSE1SKSBvd25zXG4gKiB0aGVtLiBVc2VzIHRoZSBEU0ggZGVzaWduIHRva2VucyAoYC0tZHN3LWFsaWFzLSpgKSBzbyB0aGUgY2FyZCBmb2xsb3dzIHRoZVxuICogYWN0aXZlIHRoZW1lLlxuICovXG5cbmNvbnN0IGNzcyA9IGBcbi5kc2hBY0NhcmQge1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTMpO1xuICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICBsaXN0LXN0eWxlOiBub25lO1xuICB0cmFuc2l0aW9uOiBib3JkZXItY29sb3IgLjE2cywgYmFja2dyb3VuZCAuMTZzO1xufVxuLmRzaEFjQ2FyZDpob3ZlciB7IGJvcmRlci1jb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLWRpbW1lZCk7IH1cbi5kc2hBY0NhcmRPcGVuIHtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTIpO1xuICBib3JkZXItY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1kaW1tZWQpO1xufVxuLmRzaEFjSGVhZGVyIHtcbiAgYXBwZWFyYW5jZTogbm9uZTtcbiAgd2lkdGg6IDEwMCU7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGNvbG9yOiBpbmhlcml0O1xuICB0ZXh0LWFsaWduOiBsZWZ0O1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGJhY2tncm91bmQ6IG5vbmU7XG4gIGJvcmRlcjogMDtcbiAgYm9yZGVyLXJhZGl1czogMTJweDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiAxMnB4O1xuICBwYWRkaW5nOiAxNHB4IDE2cHg7XG4gIGRpc3BsYXk6IGZsZXg7XG59XG4uZHNoQWNIZWFkZXI6Zm9jdXMtdmlzaWJsZSB7IG91dGxpbmU6IDJweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7IG91dGxpbmUtb2Zmc2V0OiAtMnB4OyB9XG4uZHNoQWNIZWFkVGV4dCB7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGZsZXg6IDE7IGdhcDogNHB4OyBtaW4td2lkdGg6IDA7IGRpc3BsYXk6IGZsZXg7IH1cbi5kc2hBY05hbWUgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpOyBmb250LXNpemU6IDE1cHg7IGZvbnQtd2VpZ2h0OiA2MDA7IGxpbmUtaGVpZ2h0OiAxLjQ7IH1cbi5kc2hBY0Rlc2NyaXB0aW9uIHsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7IGZvbnQtc2l6ZTogMTNweDsgbGluZS1oZWlnaHQ6IDEuNTsgfVxuLmRzaEFjQ2hldnJvbiB7IGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpOyBmbGV4OiBub25lOyB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gLjE2czsgfVxuLmRzaEFjQ2hldnJvbk9wZW4geyB0cmFuc2Zvcm06IHJvdGF0ZSgxODBkZWcpOyB9XG4uZHNoQWNCb2R5IHsgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpOyBtYXJnaW46IDAgMTZweDsgcGFkZGluZy1ib3R0b206IDhweDsgfVxuLmRzaEFjUmVhZE9ubHkgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTsgbWFyZ2luOiAxMnB4IDAgMDsgZm9udC1zaXplOiAxMnB4OyBsaW5lLWhlaWdodDogMS41OyB9XG4uZHNoQWNQZW5kaW5nIHtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLW1vZHVsZS1wbGF0Zm9ybSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbiAgYm9yZGVyLXJhZGl1czogOTk5cHg7XG4gIGZsZXg6IG5vbmU7XG4gIHBhZGRpbmc6IDFweCA4cHg7XG4gIGZvbnQtc2l6ZTogMTFweDtcbiAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgbGluZS1oZWlnaHQ6IDE3cHg7XG59XG4uZHNoQWNGb290ZXIge1xuICBib3JkZXItdG9wOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG4gIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogOHB4O1xuICBwYWRkaW5nOiAxMnB4IDAgNHB4O1xuICBkaXNwbGF5OiBmbGV4O1xufVxuLmRzaEFjRmFpbGVkIHsgbWluLXdpZHRoOiAwOyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLWVycm9yKTsgZmxleDogMTsgbWFyZ2luOiAwOyBmb250LXNpemU6IDEycHg7IGxpbmUtaGVpZ2h0OiAxLjU7IH1cbi5kc2hBY0Rpc2NhcmQsIC5kc2hBY1NhdmUge1xuICBhcHBlYXJhbmNlOiBub25lO1xuICBmb250OiBpbmhlcml0O1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIHBhZGRpbmc6IDVweCAxNHB4O1xuICBmb250LXNpemU6IDEzcHg7XG4gIGxpbmUtaGVpZ2h0OiAxLjU7XG59XG4uZHNoQWNEaXNjYXJkIHsgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpOyBiYWNrZ3JvdW5kOiBub25lOyB9XG4uZHNoQWNEaXNjYXJkOmhvdmVyOm5vdCg6ZGlzYWJsZWQpIHsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTsgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtZGltbWVkKTsgfVxuLmRzaEFjU2F2ZSB7IGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0zKTsgfVxuLmRzaEFjRGlzY2FyZDpkaXNhYmxlZCwgLmRzaEFjU2F2ZTpkaXNhYmxlZCB7IG9wYWNpdHk6IC40OyBjdXJzb3I6IGRlZmF1bHQ7IH1cbi5kc2hBY0Rpc2NhcmQ6Zm9jdXMtdmlzaWJsZSwgLmRzaEFjU2F2ZTpmb2N1cy12aXNpYmxlIHsgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTsgb3V0bGluZS1vZmZzZXQ6IDFweDsgfVxuLmRzaEFjRmllbGQgeyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDZweDsgcGFkZGluZzogMTJweCAwOyBkaXNwbGF5OiBmbGV4OyB9XG4uZHNoQWNGaWVsZCArIC5kc2hBY0ZpZWxkIHsgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpOyB9XG4uZHNoQWNIZWFkIHsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7IGRpc3BsYXk6IGZsZXg7IH1cbi5kc2hBY0xhYmVsIHsgbWluLXdpZHRoOiAwOyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpOyBmbGV4OiAxOyBmb250LXNpemU6IDEzcHg7IGZvbnQtd2VpZ2h0OiA1MDA7IGxpbmUtaGVpZ2h0OiAxLjU7IH1cbi5kc2hBY0JhZGdlcyB7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyBkaXNwbGF5OiBpbmxpbmUtZmxleDsgfVxuLmRzaEFjQmFkZ2Uge1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctbW9kdWxlLXBsYXRmb3JtKTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBib3JkZXItcmFkaXVzOiA5OTlweDtcbiAgcGFkZGluZzogMXB4IDhweDtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBmb250LXdlaWdodDogNTAwO1xuICBsaW5lLWhlaWdodDogMTdweDtcbn1cbi5kc2hBY1Jlc2V0IHtcbiAgZm9udDogaW5oZXJpdDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGJhY2tncm91bmQ6IG5vbmU7XG4gIGJvcmRlcjogbm9uZTtcbiAgcGFkZGluZzogMDtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBsaW5lLWhlaWdodDogMS41O1xufVxuLmRzaEFjUmVzZXQ6aG92ZXI6bm90KDpkaXNhYmxlZCkgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpOyB9XG4uZHNoQWNSZXNldDpkaXNhYmxlZCB7IGN1cnNvcjogZGVmYXVsdDsgfVxuLmRzaEFjSW5wdXQge1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTMpO1xuICBoZWlnaHQ6IDM0cHg7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgcGFkZGluZzogMCAxMnB4O1xuICBmb250LXNpemU6IDEzcHg7XG4gIGxpbmUtaGVpZ2h0OiAxLjU7XG59XG4uZHNoQWNJbnB1dDpmb2N1cy12aXNpYmxlIHsgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7IG91dGxpbmU6IG5vbmU7IH1cbi5kc2hBY0lucHV0OmRpc2FibGVkIHsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7IGN1cnNvcjogZGVmYXVsdDsgfVxuLmRzaEFjSW5wdXRJbnZhbGlkIHsgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtZXJyb3IpOyB9XG4uZHNoQWNTZWxlY3Qge1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTMpO1xuICBoZWlnaHQ6IDM0cHg7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgcGFkZGluZzogMCA4cHg7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgbGluZS1oZWlnaHQ6IDEuNTtcbn1cbi5kc2hBY1NlbGVjdDpmb2N1cy12aXNpYmxlIHsgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7IG91dGxpbmU6IG5vbmU7IH1cbi5kc2hBY1NlbGVjdDpkaXNhYmxlZCB7IGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpOyBjdXJzb3I6IGRlZmF1bHQ7IH1cbi5kc2hBY0ludmFsaWQgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLWVycm9yKTsgbWFyZ2luOiAwOyBmb250LXNpemU6IDEycHg7IGxpbmUtaGVpZ2h0OiAxLjU7IH1cbi5kc2hBY0hpbnQgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTsgbWFyZ2luOiAwOyBmb250LXNpemU6IDEycHg7IGxpbmUtaGVpZ2h0OiAxLjU7IH1cbmA7XG5cbi8qKiBJbmplY3QgdGhlIHN0eWxlc2hlZXQgb25jZTsgYSBuby1vcCBvdXRzaWRlIGEgYnJvd3NlciBlbnZpcm9ubWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RTdHlsZXMoKTogdm9pZCB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSByZXR1cm47XG4gIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdzdHlsZVtkYXRhLXBsdWdpbi1jc3M9XCJhdXRvLWNvbnRpbnVlL2NhcmRcIl0nKSAhPT0gbnVsbCkgcmV0dXJuO1xuICBjb25zdCB0YWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuICB0YWcuZGF0YXNldC5wbHVnaW4gPSAnZHNoLWNsaWVudC1hdXRvLWNvbnRpbnVlJztcbiAgdGFnLmRhdGFzZXQucGx1Z2luQ3NzID0gJ2F1dG8tY29udGludWUvY2FyZCc7XG4gIHRhZy50ZXh0Q29udGVudCA9IGNzcztcbiAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZCh0YWcpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7OztBQ2tETyxJQUFNLGlCQUFxQztBQUFBLEVBQ2hELGNBQWM7QUFBQSxFQUNkLFNBQVM7QUFBQSxFQUNULFlBQVk7QUFBQSxF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
1194
+
1195
+ return module.exports;
1196
+ }
1197
+ });