import { createHotContext as __vite__createHotContext } from "/@vite/client";import.meta.hot = __vite__createHotContext("/components/ChatPanel.vue");import { defineComponent as _defineComponent } from "/@fs/D:/dndClaw/agent-console/node_modules/.vite/deps/vue.js?v=4266a811"; import { computed, nextTick, onMounted, reactive, ref, watch } from "/@fs/D:/dndClaw/agent-console/node_modules/.vite/deps/vue.js?v=4266a811"; import { marked } from "/@fs/D:/dndClaw/agent-console/node_modules/.vite/deps/marked.js?v=4266a811"; const _sfc_main = /* @__PURE__ */ _defineComponent({ __name: "ChatPanel", props: { conversation: { type: Object, required: true } }, emits: ["openPreview"], setup(__props, { expose: __expose, emit: __emit }) { __expose(); const props = __props; const emit = __emit; const input = ref(""); const listRef = ref(); const streaming = ref(false); const messages = reactive([...props.conversation.messages]); watch( () => props.conversation.id, () => { messages.splice(0, messages.length, ...props.conversation.messages); } ); marked.setOptions({ breaks: true, headerIds: false, mangle: false }); function renderMd(text) { if (!text) return '▍'; return marked.parse(text); } const savedApis = ref([]); const currentApiId = ref(""); const currentModelName = computed(() => { const api = savedApis.value.find((a) => a.id === currentApiId.value); return api ? String(api.model) : "未选择模型"; }); async function loadApis() { try { const list = await window.electronAPI.callAgent("llm:list"); savedApis.value = (list || []).map((r) => ({ id: r.id, name: r.name, provider: r.provider, ...r.config })); if (!currentApiId.value) { const active = await window.electronAPI.callAgent("llm:getActive"); if (active) { currentApiId.value = active.id; } else { currentApiId.value = savedApis.value[0]?.id || ""; } } } catch (e) { console.error("[ChatPanel] 加载 API 列表失败:", e); savedApis.value = []; } } async function onApiChange() { if (currentApiId.value) { try { await window.electronAPI.callAgent("llm:setActive", { id: currentApiId.value }); } catch (e) { console.error("[ChatPanel] 设置激活 API 失败:", e); } } } onMounted(loadApis); function statusText(s) { return { pending: "待执行", running: "执行中", done: "完成", error: "失败" }[s] ?? s; } function canPreview(t) { return /file|read|write/i.test(t.name); } function openPreview(t) { const name = t.params.path || t.params.file || `output_${t.id}.md`; const content = [ `# ${name.split("/").pop()}`, "", `> 由工具 \`${t.name}\` 读取(耗时 ${t.durationMs ?? 0}ms)`, "", "---", t.result ?? "(无返回内容)", "", "## 示例内容", "这是从工具调用结果中提取的文件预览内容,真实项目中可替换为后端返回的完整文本。" ].join("\n"); emit("openPreview", { name, content }); } function scrollToBottom() { nextTick(() => { if (listRef.value) listRef.value.scrollTop = listRef.value.scrollHeight; }); } async function send() { const text = input.value.trim(); if (!text || streaming.value) return; const api = savedApis.value.find((a) => a.id === currentApiId.value); if (!api) { alert("请先在「大模型 API 设置」中保存并测试通过一个 API 配置"); return; } messages.push({ id: `u-${Date.now()}`, role: "user", content: text, time: nowTime(), toolCalls: [] }); input.value = ""; scrollToBottom(); const assistantMsg = reactive({ id: `a-${Date.now()}`, role: "assistant", content: "", time: nowTime(), toolCalls: [], loading: true }); messages.push(assistantMsg); streaming.value = true; try { await streamChat(api, assistantMsg); } catch (e) { assistantMsg.loading = false; assistantMsg.content = `⚠️ 调用失败:${e?.message || String(e)}`; } finally { assistantMsg.loading = false; streaming.value = false; } } function nowTime() { return (/* @__PURE__ */ new Date()).toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }); } async function streamChat(api, assistantMsg) { const isQianfan = api.provider === "qianfan_v2"; let url = String(api.baseUrl); const headers = { "Content-Type": "application/json" }; if (isQianfan) { headers["Authorization"] = String(api.authorization || ""); } else { if (!url.endsWith("/chat/completions")) { url = url.replace(/\/$/, "") + "/chat/completions"; } headers["Authorization"] = "Bearer " + String(api.apiKey || ""); } const history = messages.filter((m) => m.role !== "system").slice(-10).map((m) => ({ role: m.role, content: m.content })); const body = { model: String(api.model), messages: history, temperature: Number(api.temperature ?? 0.7), stream: true }; const res = await fetch(url, { method: "POST", headers, body: JSON.stringify(body) }); if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(`HTTP ${res.status} ${err?.error?.message || res.statusText}`); } const reader = res.body.getReader(); const decoder = new TextDecoder(); let rawBuffer = ""; let typeBuffer = ""; let typeTimer = null; const TYPE_INTERVAL = 12; function startTypewriter() { if (typeTimer) return; typeTimer = window.setInterval(() => { if (typeBuffer.length > 0) { const chunk = typeBuffer.slice(0, 2); typeBuffer = typeBuffer.slice(2); assistantMsg.content += chunk; scrollToBottom(); } else if (!streaming.value) { if (typeTimer) { clearInterval(typeTimer); typeTimer = null; } } }, TYPE_INTERVAL); } while (true) { const { done, value } = await reader.read(); if (done) break; rawBuffer += decoder.decode(value, { stream: true }); const lines = rawBuffer.split("\n"); rawBuffer = lines.pop() || ""; for (const line of lines) { const trimmed = line.trim(); if (!trimmed.startsWith("data:")) continue; const data = trimmed.slice(5).trim(); if (data === "[DONE]") { await waitTypewriterDone(); return; } try { const json = JSON.parse(data); const delta = json.choices?.[0]?.delta?.content; if (delta && delta.trim()) { if (assistantMsg.loading) assistantMsg.loading = false; typeBuffer += delta; startTypewriter(); } } catch { } } } await waitTypewriterDone(); function waitTypewriterDone() { return new Promise((resolve) => { const check = () => { if (typeBuffer.length === 0) { if (typeTimer) { clearInterval(typeTimer); typeTimer = null; } resolve(); } else { setTimeout(check, 30); } }; check(); }); } } function runAgent() { scrollToBottom(); } const __returned__ = { props, emit, input, listRef, streaming, messages, renderMd, savedApis, currentApiId, currentModelName, loadApis, onApiChange, statusText, canPreview, openPreview, scrollToBottom, send, nowTime, streamChat, runAgent }; Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); return __returned__; } }); import { createCommentVNode as _createCommentVNode, toDisplayString as _toDisplayString, createElementVNode as _createElementVNode, createTextVNode as _createTextVNode, renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, normalizeClass as _normalizeClass, vModelText as _vModelText, withModifiers as _withModifiers, withKeys as _withKeys, withDirectives as _withDirectives, vModelSelect as _vModelSelect } from "/@fs/D:/dndClaw/agent-console/node_modules/.vite/deps/vue.js?v=4266a811"; const _hoisted_1 = { class: "chat" }; const _hoisted_2 = { class: "header" }; const _hoisted_3 = { class: "chat-title" }; const _hoisted_4 = { class: "chat-sub" }; const _hoisted_5 = { ref: "listRef", class: "messages" }; const _hoisted_6 = { key: 0, class: "role-tag" }; const _hoisted_7 = { key: 1, class: "loading-dots" }; const _hoisted_8 = ["innerHTML"]; const _hoisted_9 = { key: 3, class: "tools" }; const _hoisted_10 = { class: "tool-head" }; const _hoisted_11 = { class: "tool-name" }; const _hoisted_12 = { class: "tool-params" }; const _hoisted_13 = ["onClick"]; const _hoisted_14 = { class: "input-bar" }; const _hoisted_15 = ["onKeydown"]; const _hoisted_16 = { class: "input-actions" }; const _hoisted_17 = { class: "right-actions" }; const _hoisted_18 = { key: 0, value: "" }; const _hoisted_19 = ["value"]; const _hoisted_20 = ["disabled"]; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { return _openBlock(), _createElementBlock("section", _hoisted_1, [ _createCommentVNode(" 顶部:会话模型信息 "), _createElementVNode("header", _hoisted_2, [ _createElementVNode("div", null, [ _createElementVNode( "div", _hoisted_3, _toDisplayString($props.conversation.title), 1 /* TEXT */ ), _createElementVNode("div", _hoisted_4, [ _cache[2] || (_cache[2] = _createTextVNode( " 模型 ", -1 /* CACHED */ )), _createElementVNode( "b", null, _toDisplayString($setup.currentModelName), 1 /* TEXT */ ), _createTextVNode( " · " + _toDisplayString($setup.messages.length) + " 条消息 ", 1 /* TEXT */ ) ]) ]), _createElementVNode("button", { class: "run-btn", onClick: $setup.runAgent }, "▶ 运行") ]), _createCommentVNode(" 消息列表 "), _createElementVNode( "div", _hoisted_5, [ (_openBlock(true), _createElementBlock( _Fragment, null, _renderList($setup.messages, (msg) => { return _openBlock(), _createElementBlock( "div", { key: msg.id, class: _normalizeClass(["msg", msg.role]) }, [ _createElementVNode( "div", { class: _normalizeClass(["bubble", { user: msg.role === "user" }]) }, [ msg.role !== "user" ? (_openBlock(), _createElementBlock( "div", _hoisted_6, _toDisplayString(msg.role === "assistant" ? "dndClaw" : "系统"), 1 /* TEXT */ )) : _createCommentVNode("v-if", true), msg.loading ? (_openBlock(), _createElementBlock("div", _hoisted_7, [..._cache[3] || (_cache[3] = [ _createElementVNode( "span", null, null, -1 /* CACHED */ ), _createElementVNode( "span", null, null, -1 /* CACHED */ ), _createElementVNode( "span", null, null, -1 /* CACHED */ ) ])])) : (_openBlock(), _createElementBlock("div", { key: 2, class: "content markdown-body", innerHTML: $setup.renderMd(msg.content) }, null, 8, _hoisted_8)), _createCommentVNode(" 工具调用 "), msg.toolCalls?.length ? (_openBlock(), _createElementBlock("div", _hoisted_9, [ (_openBlock(true), _createElementBlock( _Fragment, null, _renderList(msg.toolCalls, (t) => { return _openBlock(), _createElementBlock("div", { key: t.id, class: "tool" }, [ _createElementVNode("div", _hoisted_10, [ _createElementVNode( "span", _hoisted_11, "🔧 " + _toDisplayString(t.name), 1 /* TEXT */ ), _createElementVNode( "span", { class: _normalizeClass(["tool-status", t.status]) }, _toDisplayString($setup.statusText(t.status)), 3 /* TEXT, CLASS */ ) ]), _createElementVNode("div", _hoisted_12, [ (_openBlock(true), _createElementBlock( _Fragment, null, _renderList(t.params, (v, k) => { return _openBlock(), _createElementBlock( "code", { key: k }, _toDisplayString(k) + "=" + _toDisplayString(v), 1 /* TEXT */ ); }), 128 /* KEYED_FRAGMENT */ )) ]), t.status === "done" && $setup.canPreview(t) ? (_openBlock(), _createElementBlock("button", { key: 0, class: "preview-btn", onClick: ($event) => $setup.openPreview(t) }, " 预览文件 ", 8, _hoisted_13)) : _createCommentVNode("v-if", true) ]); }), 128 /* KEYED_FRAGMENT */ )) ])) : _createCommentVNode("v-if", true) ], 2 /* CLASS */ ) ], 2 /* CLASS */ ); }), 128 /* KEYED_FRAGMENT */ )) ], 512 /* NEED_PATCH */ ), _createCommentVNode(" 输入框 "), _createElementVNode("footer", _hoisted_14, [ _withDirectives(_createElementVNode("textarea", { "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.input = $event), rows: "2", placeholder: "输入指令,或要求智能体执行某项任务…", onKeydown: _withKeys(_withModifiers($setup.send, ["exact", "prevent"]), ["enter"]) }, null, 40, _hoisted_15), [ [_vModelText, $setup.input] ]), _createElementVNode("div", _hoisted_16, [ _cache[4] || (_cache[4] = _createElementVNode( "span", { class: "hint" }, "Enter 发送 · Shift+Enter 换行", -1 /* CACHED */ )), _createElementVNode("div", _hoisted_17, [ _withDirectives(_createElementVNode( "select", { "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $setup.currentApiId = $event), class: "api-select", title: "选择 LLM API", onFocus: $setup.loadApis, onChange: $setup.onApiChange }, [ !$setup.savedApis.length ? (_openBlock(), _createElementBlock("option", _hoisted_18, "请先在设置中保存 API")) : _createCommentVNode("v-if", true), (_openBlock(true), _createElementBlock( _Fragment, null, _renderList($setup.savedApis, (a) => { return _openBlock(), _createElementBlock("option", { key: a.id, value: a.id }, _toDisplayString(a.name), 9, _hoisted_19); }), 128 /* KEYED_FRAGMENT */ )) ], 544 /* NEED_HYDRATION, NEED_PATCH */ ), [ [_vModelSelect, $setup.currentApiId] ]), _createElementVNode("button", { class: "send-btn", disabled: $setup.streaming, onClick: $setup.send }, _toDisplayString($setup.streaming ? "生成中…" : "发送"), 9, _hoisted_20) ]) ]) ]) ]); } import "/components/ChatPanel.vue?vue&type=style&index=0&scoped=2c15c3a8&lang.css"; _sfc_main.__hmrId = "2c15c3a8"; typeof __VUE_HMR_RUNTIME__ !== "undefined" && __VUE_HMR_RUNTIME__.createRecord(_sfc_main.__hmrId, _sfc_main); import.meta.hot.on("file-changed", ({ file }) => { __VUE_HMR_RUNTIME__.CHANGED_FILE = file; }); import.meta.hot.accept((mod) => { if (!mod) return; const { default: updated, _rerender_only } = mod; if (_rerender_only) { __VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render); } else { __VUE_HMR_RUNTIME__.reload(updated.__hmrId, updated); } }); import _export_sfc from "/@id/__x00__plugin-vue:export-helper"; export default /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-2c15c3a8"], ["__file", "D:/dndClaw/agent-console/src/renderer/components/ChatPanel.vue"]]); //# sourceMappingURL=data:application/json;base64,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Qk07QUFBQSxrQ0FsQko7QUFBQSxVQUFtRDtBQUFBLFlBQTdDLE9BQU0sT0FBTTtBQUFBLFVBQUM7QUFBQSxVQUF5QjtBQUFBO0FBQUE7QUFBQSxRQUM1QyxvQkFnQk0sT0FoQk4sYUFnQk07QUFBQSwwQkFmSjtBQUFBLFlBV1M7QUFBQTtBQUFBLDJFQVZFLHNCQUFZO0FBQUEsY0FDckIsT0FBTTtBQUFBLGNBQ04sT0FBTTtBQUFBLGNBQ0wsU0FBTztBQUFBLGNBQ1AsVUFBUTtBQUFBOztlQUVNLGlCQUFVLHdCQUF6QixvQkFBK0QsVUFBL0QsYUFBMEMsY0FBWTtpQ0FDdEQ7QUFBQSxnQkFFUztBQUFBO0FBQUEsNEJBRlcsa0JBQVMsQ0FBZCxNQUFDO3VDQUFoQixvQkFFUztBQUFBLG9CQUZ1QixLQUFLLEVBQUU7QUFBQSxvQkFBSyxPQUFPLEVBQUU7QUFBQSxzQ0FDaEQsRUFBRSxJQUFJO0FBQUE7Ozs7Ozs7OzRCQVJGLG1CQUFZO0FBQUE7VUFXdkIsb0JBRVM7QUFBQSxZQUZELE9BQU07QUFBQSxZQUFZLFVBQVU7QUFBQSxZQUFZLFNBQU87QUFBQSw4QkFDbEQsbUJBQVM7QUFBQSIsIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsiQ2hhdFBhbmVsLnZ1ZSJdLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGU+XG4gIDxzZWN0aW9uIGNsYXNzPVwiY2hhdFwiPlxuICAgIDwhLS0g6aG26YOo77ya5Lya6K+d5qih5Z6L5L+h5oGvIC0tPlxuICAgIDxoZWFkZXIgY2xhc3M9XCJoZWFkZXJcIj5cbiAgICAgIDxkaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjaGF0LXRpdGxlXCI+e3sgY29udmVyc2F0aW9uLnRpdGxlIH19PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjaGF0LXN1YlwiPlxuICAgICAgICAgIOaooeWeiyA8Yj57eyBjdXJyZW50TW9kZWxOYW1lIH19PC9iPiDCt1xuICAgICAgICAgIHt7IG1lc3NhZ2VzLmxlbmd0aCB9fSDmnaHmtojmga9cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJydW4tYnRuXCIgQGNsaWNrPVwicnVuQWdlbnRcIj7ilrYg6L+Q6KGMPC9idXR0b24+XG4gICAgPC9oZWFkZXI+XG5cbiAgICA8IS0tIOa2iOaBr+WIl+ihqCAtLT5cbiAgICA8ZGl2IHJlZj1cImxpc3RSZWZcIiBjbGFzcz1cIm1lc3NhZ2VzXCI+XG4gICAgICA8ZGl2XG4gICAgICAgIHYtZm9yPVwibXNnIGluIG1lc3NhZ2VzXCJcbiAgICAgICAgOmtleT1cIm1zZy5pZFwiXG4gICAgICAgIGNsYXNzPVwibXNnXCJcbiAgICAgICAgOmNsYXNzPVwibXNnLnJvbGVcIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYnViYmxlXCIgOmNsYXNzPVwieyB1c2VyOiBtc2cucm9sZSA9PT0gJ3VzZXInIH1cIj5cbiAgICAgICAgICA8ZGl2IHYtaWY9XCJtc2cucm9sZSAhPT0gJ3VzZXInXCIgY2xhc3M9XCJyb2xlLXRhZ1wiPlxuICAgICAgICAgICAge3sgbXNnLnJvbGUgPT09ICdhc3Npc3RhbnQnID8gJ2RuZENsYXcnIDogJ+ezu+e7nycgfX1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IHYtaWY9XCJtc2cubG9hZGluZ1wiIGNsYXNzPVwibG9hZGluZy1kb3RzXCI+XG4gICAgICAgICAgICA8c3Bhbj48L3NwYW4+PHNwYW4+PC9zcGFuPjxzcGFuPjwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IHYtZWxzZSBjbGFzcz1cImNvbnRlbnQgbWFya2Rvd24tYm9keVwiIHYtaHRtbD1cInJlbmRlck1kKG1zZy5jb250ZW50KVwiPjwvZGl2PlxuXG4gICAgICAgICAgPCEtLSDlt6XlhbfosIPnlKggLS0+XG4gICAgICAgICAgPGRpdiB2LWlmPVwibXNnLnRvb2xDYWxscz8ubGVuZ3RoXCIgY2xhc3M9XCJ0b29sc1wiPlxuICAgICAgICAgICAgPGRpdiB2LWZvcj1cInQgaW4gbXNnLnRvb2xDYWxsc1wiIDprZXk9XCJ0LmlkXCIgY2xhc3M9XCJ0b29sXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b29sLWhlYWRcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRvb2wtbmFtZVwiPvCflKcge3sgdC5uYW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidG9vbC1zdGF0dXNcIiA6Y2xhc3M9XCJ0LnN0YXR1c1wiPlxuICAgICAgICAgICAgICAgICAge3sgc3RhdHVzVGV4dCh0LnN0YXR1cykgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9vbC1wYXJhbXNcIj5cbiAgICAgICAgICAgICAgICA8Y29kZSB2LWZvcj1cIih2LCBrKSBpbiB0LnBhcmFtc1wiIDprZXk9XCJrXCI+e3sgayB9fT17eyB2IH19PC9jb2RlPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIHYtaWY9XCJ0LnN0YXR1cyA9PT0gJ2RvbmUnICYmIGNhblByZXZpZXcodClcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwicHJldmlldy1idG5cIlxuICAgICAgICAgICAgICAgIEBjbGljaz1cIm9wZW5QcmV2aWV3KHQpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIOmihOiniOaWh+S7tlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSDovpPlhaXmoYYgLS0+XG4gICAgPGZvb3RlciBjbGFzcz1cImlucHV0LWJhclwiPlxuICAgICAgPHRleHRhcmVhXG4gICAgICAgIHYtbW9kZWw9XCJpbnB1dFwiXG4gICAgICAgIHJvd3M9XCIyXCJcbiAgICAgICAgcGxhY2Vob2xkZXI9XCLovpPlhaXmjIfku6TvvIzmiJbopoHmsYLmmbrog73kvZPmiafooYzmn5Dpobnku7vliqHigKZcIlxuICAgICAgICBAa2V5ZG93bi5lbnRlci5leGFjdC5wcmV2ZW50PVwic2VuZFwiXG4gICAgICA+PC90ZXh0YXJlYT5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1hY3Rpb25zXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaGludFwiPkVudGVyIOWPkemAgSDCtyBTaGlmdCtFbnRlciDmjaLooYw8L3NwYW4+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyaWdodC1hY3Rpb25zXCI+XG4gICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgdi1tb2RlbD1cImN1cnJlbnRBcGlJZFwiXG4gICAgICAgICAgICBjbGFzcz1cImFwaS1zZWxlY3RcIlxuICAgICAgICAgICAgdGl0bGU9XCLpgInmi6kgTExNIEFQSVwiXG4gICAgICAgICAgICBAZm9jdXM9XCJsb2FkQXBpc1wiXG4gICAgICAgICAgICBAY2hhbmdlPVwib25BcGlDaGFuZ2VcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxvcHRpb24gdi1pZj1cIiFzYXZlZEFwaXMubGVuZ3RoXCIgdmFsdWU9XCJcIj7or7flhYjlnKjorr7nva7kuK3kv53lrZggQVBJPC9vcHRpb24+XG4gICAgICAgICAgICA8b3B0aW9uIHYtZm9yPVwiYSBpbiBzYXZlZEFwaXNcIiA6a2V5PVwiYS5pZFwiIDp2YWx1ZT1cImEuaWRcIj5cbiAgICAgICAgICAgICAge3sgYS5uYW1lIH19XG4gICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwic2VuZC1idG5cIiA6ZGlzYWJsZWQ9XCJzdHJlYW1pbmdcIiBAY2xpY2s9XCJzZW5kXCI+XG4gICAgICAgICAgICB7eyBzdHJlYW1pbmcgPyAn55Sf5oiQ5Lit4oCmJyA6ICflj5HpgIEnIH19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9mb290ZXI+XG4gIDwvc2VjdGlvbj5cbjwvdGVtcGxhdGU+XG5cbjxzY3JpcHQgc2V0dXAgbGFuZz1cInRzXCI+XG5pbXBvcnQgeyBjb21wdXRlZCwgbmV4dFRpY2ssIG9uTW91bnRlZCwgcmVhY3RpdmUsIHJlZiwgd2F0Y2ggfSBmcm9tICd2dWUnXG5pbXBvcnQgeyBtYXJrZWQgfSBmcm9tICdtYXJrZWQnXG5pbXBvcnQgdHlwZSB7IENoYXRNZXNzYWdlLCBDb252ZXJzYXRpb24sIFRvb2xDYWxsIH0gZnJvbSAnLi4vdHlwZXMnXG5cbmNvbnN0IHByb3BzID0gZGVmaW5lUHJvcHM8e1xuICBjb252ZXJzYXRpb246IENvbnZlcnNhdGlvblxufT4oKVxuXG5jb25zdCBlbWl0ID0gZGVmaW5lRW1pdHM8e1xuICAoZTogJ29wZW5QcmV2aWV3JywgZjogeyBuYW1lOiBzdHJpbmc7IGNvbnRlbnQ6IHN0cmluZyB9KTogdm9pZFxufT4oKVxuXG5jb25zdCBpbnB1dCA9IHJlZignJylcbmNvbnN0IGxpc3RSZWYgPSByZWY8SFRNTEVsZW1lbnQ+KClcbmNvbnN0IHN0cmVhbWluZyA9IHJlZihmYWxzZSlcblxuLy8g5pys5Zyw5ZON5bqU5byP5raI5oGv5YiX6KGo77yM56Gu5L+d6YCQ5a2X5L+u5pS56IO96Kem5Y+R5pu05pawXG5jb25zdCBtZXNzYWdlcyA9IHJlYWN0aXZlPENoYXRNZXNzYWdlW10+KFsuLi5wcm9wcy5jb252ZXJzYXRpb24ubWVzc2FnZXNdKVxuXG4vLyDliIfmjaLkvJror53ml7blkIzmraXmtojmga9cbndhdGNoKFxuICAoKSA9PiBwcm9wcy5jb252ZXJzYXRpb24uaWQsXG4gICgpID0+IHtcbiAgICBtZXNzYWdlcy5zcGxpY2UoMCwgbWVzc2FnZXMubGVuZ3RoLCAuLi5wcm9wcy5jb252ZXJzYXRpb24ubWVzc2FnZXMpXG4gIH1cbilcblxuLy8gbWFya2VkIOmFjee9ru+8muW8gOWQr+aNouihjO+8jOS4jeS9v+eUqOWktOmDqCBpZFxubWFya2VkLnNldE9wdGlvbnMoeyBicmVha3M6IHRydWUsIGhlYWRlcklkczogZmFsc2UsIG1hbmdsZTogZmFsc2UgfSlcblxuZnVuY3Rpb24gcmVuZGVyTWQodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKCF0ZXh0KSByZXR1cm4gJzxzcGFuIGNsYXNzPVwiY3Vyc29yXCI+4paNPC9zcGFuPidcbiAgcmV0dXJuIG1hcmtlZC5wYXJzZSh0ZXh0KSBhcyBzdHJpbmdcbn1cblxuaW50ZXJmYWNlIFNhdmVkQXBpIHtcbiAgaWQ6IHN0cmluZ1xuICBuYW1lOiBzdHJpbmdcbiAgcHJvdmlkZXI6IHN0cmluZ1xuICBba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXJcbn1cblxuY29uc3Qgc2F2ZWRBcGlzID0gcmVmPFNhdmVkQXBpW10+KFtdKVxuY29uc3QgY3VycmVudEFwaUlkID0gcmVmKCcnKVxuXG4vLyDlvZPliY3pgInkuK0gQVBJIOeahOaooeWei+WQjVxuY29uc3QgY3VycmVudE1vZGVsTmFtZSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgY29uc3QgYXBpID0gc2F2ZWRBcGlzLnZhbHVlLmZpbmQoKGEpID0+IGEuaWQgPT09IGN1cnJlbnRBcGlJZC52YWx1ZSlcbiAgcmV0dXJuIGFwaSA/IFN0cmluZyhhcGkubW9kZWwpIDogJ+acqumAieaLqeaooeWeiydcbn0pXG5cbi8qKlxuICog5LuOIGFnZW50LWNvcmXvvIhTUUxpdGXvvInliqDovb0gQVBJIOWIl+ihqFxuICovXG5hc3luYyBmdW5jdGlvbiBsb2FkQXBpcygpIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBsaXN0ID0gYXdhaXQgd2luZG93LmVsZWN0cm9uQVBJLmNhbGxBZ2VudCgnbGxtOmxpc3QnKVxuICAgIC8vIOi9rOaNouS4uuWJjeerr+agvOW8j++8muaKiiBjb25maWcg5bGV5byA5Yiw6aG25bGCXG4gICAgc2F2ZWRBcGlzLnZhbHVlID0gKGxpc3QgfHwgW10pLm1hcCgocjogYW55KSA9PiAoe1xuICAgICAgaWQ6IHIuaWQsXG4gICAgICBuYW1lOiByLm5hbWUsXG4gICAgICBwcm92aWRlcjogci5wcm92aWRlcixcbiAgICAgIC4uLnIuY29uZmlnXG4gICAgfSkpXG5cbiAgICAvLyDojrflj5blvZPliY3mv4DmtLvnmoTphY3nva5cbiAgICBpZiAoIWN1cnJlbnRBcGlJZC52YWx1ZSkge1xuICAgICAgY29uc3QgYWN0aXZlID0gYXdhaXQgd2luZG93LmVsZWN0cm9uQVBJLmNhbGxBZ2VudCgnbGxtOmdldEFjdGl2ZScpXG4gICAgICBpZiAoYWN0aXZlKSB7XG4gICAgICAgIGN1cnJlbnRBcGlJZC52YWx1ZSA9IGFjdGl2ZS5pZFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3VycmVudEFwaUlkLnZhbHVlID0gc2F2ZWRBcGlzLnZhbHVlWzBdPy5pZCB8fCAnJ1xuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoJ1tDaGF0UGFuZWxdIOWKoOi9vSBBUEkg5YiX6KGo5aSx6LSlOicsIGUpXG4gICAgc2F2ZWRBcGlzLnZhbHVlID0gW11cbiAgfVxufVxuXG4vKipcbiAqIOmAieaLqSBBUEkg5pe277yM5ZCM5q2l5YiwIGFnZW50LWNvcmXvvIjorr7nva7mv4DmtLvnirbmgIHvvIlcbiAqL1xuYXN5bmMgZnVuY3Rpb24gb25BcGlDaGFuZ2UoKSB7XG4gIGlmIChjdXJyZW50QXBpSWQudmFsdWUpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgd2luZG93LmVsZWN0cm9uQVBJLmNhbGxBZ2VudCgnbGxtOnNldEFjdGl2ZScsIHsgaWQ6IGN1cnJlbnRBcGlJZC52YWx1ZSB9KVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tDaGF0UGFuZWxdIOiuvue9rua/gOa0uyBBUEkg5aSx6LSlOicsIGUpXG4gICAgfVxuICB9XG59XG5cbm9uTW91bnRlZChsb2FkQXBpcylcblxuZnVuY3Rpb24gc3RhdHVzVGV4dChzOiBzdHJpbmcpIHtcbiAgcmV0dXJuIChcbiAgICB7XG4gICAgICBwZW5kaW5nOiAn5b6F5omn6KGMJyxcbiAgICAgIHJ1bm5pbmc6ICfmiafooYzkuK0nLFxuICAgICAgZG9uZTogJ+WujOaIkCcsXG4gICAgICBlcnJvcjogJ+Wksei0pSdcbiAgICB9W3NdID8/IHNcbiAgKVxufVxuXG5mdW5jdGlvbiBjYW5QcmV2aWV3KHQ6IFRvb2xDYWxsKSB7XG4gIHJldHVybiAvZmlsZXxyZWFkfHdyaXRlL2kudGVzdCh0Lm5hbWUpXG59XG5cbmZ1bmN0aW9uIG9wZW5QcmV2aWV3KHQ6IFRvb2xDYWxsKSB7XG4gIGNvbnN0IG5hbWUgPSB0LnBhcmFtcy5wYXRoIHx8IHQucGFyYW1zLmZpbGUgfHwgYG91dHB1dF8ke3QuaWR9Lm1kYFxuICBjb25zdCBjb250ZW50ID0gW1xuICAgIGAjICR7bmFtZS5zcGxpdCgnLycpLnBvcCgpfWAsXG4gICAgJycsXG4gICAgYD4g55Sx5bel5YW3IFxcYCR7dC5uYW1lfVxcYCDor7vlj5bvvIjogJfml7YgJHt0LmR1cmF0aW9uTXMgPz8gMH1tc++8iWAsXG4gICAgJycsXG4gICAgJy0tLScsXG4gICAgdC5yZXN1bHQgPz8gJ++8iOaXoOi/lOWbnuWGheWuue+8iScsXG4gICAgJycsXG4gICAgJyMjIOekuuS+i+WGheWuuScsXG4gICAgJ+i/meaYr+S7juW3peWFt+iwg+eUqOe7k+aenOS4reaPkOWPlueahOaWh+S7tumihOiniOWGheWuue+8jOecn+WunumhueebruS4reWPr+abv+aNouS4uuWQjuerr+i/lOWbnueahOWujOaVtOaWh+acrOOAgidcbiAgXS5qb2luKCdcXG4nKVxuICBlbWl0KCdvcGVuUHJldmlldycsIHsgbmFtZSwgY29udGVudCB9KVxufVxuXG5mdW5jdGlvbiBzY3JvbGxUb0JvdHRvbSgpIHtcbiAgbmV4dFRpY2soKCkgPT4ge1xuICAgIGlmIChsaXN0UmVmLnZhbHVlKSBsaXN0UmVmLnZhbHVlLnNjcm9sbFRvcCA9IGxpc3RSZWYudmFsdWUuc2Nyb2xsSGVpZ2h0XG4gIH0pXG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNlbmQoKSB7XG4gIGNvbnN0IHRleHQgPSBpbnB1dC52YWx1ZS50cmltKClcbiAgaWYgKCF0ZXh0IHx8IHN0cmVhbWluZy52YWx1ZSkgcmV0dXJuXG5cbiAgY29uc3QgYXBpID0gc2F2ZWRBcGlzLnZhbHVlLmZpbmQoKGEpID0+IGEuaWQgPT09IGN1cnJlbnRBcGlJZC52YWx1ZSlcbiAgaWYgKCFhcGkpIHtcbiAgICBhbGVydCgn6K+35YWI5Zyo44CM5aSn5qih5Z6LIEFQSSDorr7nva7jgI3kuK3kv53lrZjlubbmtYvor5XpgJrov4fkuIDkuKogQVBJIOmFjee9ricpXG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyDnlKjmiLfmtojmga9cbiAgbWVzc2FnZXMucHVzaCh7XG4gICAgaWQ6IGB1LSR7RGF0ZS5ub3coKX1gLFxuICAgIHJvbGU6ICd1c2VyJyxcbiAgICBjb250ZW50OiB0ZXh0LFxuICAgIHRpbWU6IG5vd1RpbWUoKSxcbiAgICB0b29sQ2FsbHM6IFtdXG4gIH0pXG4gIGlucHV0LnZhbHVlID0gJydcbiAgc2Nyb2xsVG9Cb3R0b20oKVxuXG4gIC8vIOWNoOS9jSBhc3Npc3RhbnQg5raI5oGv77yI5rWB5byP5aGr5YWF77yJXG4gIGNvbnN0IGFzc2lzdGFudE1zZyA9IHJlYWN0aXZlPENoYXRNZXNzYWdlPih7XG4gICAgaWQ6IGBhLSR7RGF0ZS5ub3coKX1gLFxuICAgIHJvbGU6ICdhc3Npc3RhbnQnLFxuICAgIGNvbnRlbnQ6ICcnLFxuICAgIHRpbWU6IG5vd1RpbWUoKSxcbiAgICB0b29sQ2FsbHM6IFtdLFxuICAgIGxvYWRpbmc6IHRydWVcbiAgfSlcbiAgbWVzc2FnZXMucHVzaChhc3Npc3RhbnRNc2cpXG5cbiAgc3RyZWFtaW5nLnZhbHVlID0gdHJ1ZVxuICB0cnkge1xuICAgIGF3YWl0IHN0cmVhbUNoYXQoYXBpLCBhc3Npc3RhbnRNc2cpXG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGFzc2lzdGFudE1zZy5sb2FkaW5nID0gZmFsc2VcbiAgICBhc3Npc3RhbnRNc2cuY29udGVudCA9IGDimqDvuI8g6LCD55So5aSx6LSl77yaJHtlPy5tZXNzYWdlIHx8IFN0cmluZyhlKX1gXG4gIH0gZmluYWxseSB7XG4gICAgYXNzaXN0YW50TXNnLmxvYWRpbmcgPSBmYWxzZVxuICAgIHN0cmVhbWluZy52YWx1ZSA9IGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24gbm93VGltZSgpIHtcbiAgcmV0dXJuIG5ldyBEYXRlKCkudG9Mb2NhbGVUaW1lU3RyaW5nKCd6aC1DTicsIHtcbiAgICBob3VyOiAnMi1kaWdpdCcsXG4gICAgbWludXRlOiAnMi1kaWdpdCdcbiAgfSlcbn1cblxuYXN5bmMgZnVuY3Rpb24gc3RyZWFtQ2hhdChhcGk6IFNhdmVkQXBpLCBhc3Npc3RhbnRNc2c6IENoYXRNZXNzYWdlKSB7XG4gIGNvbnN0IGlzUWlhbmZhbiA9IGFwaS5wcm92aWRlciA9PT0gJ3FpYW5mYW5fdjInXG4gIGxldCB1cmwgPSBTdHJpbmcoYXBpLmJhc2VVcmwpXG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfVxuXG4gIGlmIChpc1FpYW5mYW4pIHtcbiAgICBoZWFkZXJzWydBdXRob3JpemF0aW9uJ10gPSBTdHJpbmcoYXBpLmF1dGhvcml6YXRpb24gfHwgJycpXG4gIH0gZWxzZSB7XG4gICAgaWYgKCF1cmwuZW5kc1dpdGgoJy9jaGF0L2NvbXBsZXRpb25zJykpIHtcbiAgICAgIHVybCA9IHVybC5yZXBsYWNlKC9cXC8kLywgJycpICsgJy9jaGF0L2NvbXBsZXRpb25zJ1xuICAgIH1cbiAgICBoZWFkZXJzWydBdXRob3JpemF0aW9uJ10gPSAnQmVhcmVyICcgKyBTdHJpbmcoYXBpLmFwaUtleSB8fCAnJylcbiAgfVxuXG4gIC8vIOaehOmAoOa2iOaBr+S4iuS4i+aWh++8iOacgOi/kSAxMCDmnaHvvIlcbiAgY29uc3QgaGlzdG9yeSA9IG1lc3NhZ2VzXG4gICAgLmZpbHRlcigobSkgPT4gbS5yb2xlICE9PSAnc3lzdGVtJylcbiAgICAuc2xpY2UoLTEwKVxuICAgIC5tYXAoKG0pID0+ICh7IHJvbGU6IG0ucm9sZSwgY29udGVudDogbS5jb250ZW50IH0pKVxuXG4gIGNvbnN0IGJvZHkgPSB7XG4gICAgbW9kZWw6IFN0cmluZyhhcGkubW9kZWwpLFxuICAgIG1lc3NhZ2VzOiBoaXN0b3J5LFxuICAgIHRlbXBlcmF0dXJlOiBOdW1iZXIoYXBpLnRlbXBlcmF0dXJlID8/IDAuNyksXG4gICAgc3RyZWFtOiB0cnVlXG4gIH1cblxuICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICBoZWFkZXJzLFxuICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJvZHkpXG4gIH0pXG5cbiAgaWYgKCFyZXMub2spIHtcbiAgICBjb25zdCBlcnIgPSBhd2FpdCByZXMuanNvbigpLmNhdGNoKCgpID0+ICh7fSkpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBIVFRQICR7cmVzLnN0YXR1c30gJHtlcnI/LmVycm9yPy5tZXNzYWdlIHx8IHJlcy5zdGF0dXNUZXh0fWApXG4gIH1cblxuICBjb25zdCByZWFkZXIgPSByZXMuYm9keSEuZ2V0UmVhZGVyKClcbiAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpXG4gIGxldCByYXdCdWZmZXIgPSAnJ1xuXG4gIC8vIOaJk+Wtl+acuue8k+WGsu+8muaUtuWIsOeahOWGheWuueWFiOaUvui/memHjO+8jOeUqOWumuaXtuWZqOmAkOWtl+aYvuekulxuICBsZXQgdHlwZUJ1ZmZlciA9ICcnXG4gIGxldCB0eXBlVGltZXI6IG51bWJlciB8IG51bGwgPSBudWxsXG4gIGNvbnN0IFRZUEVfSU5URVJWQUwgPSAxMiAvLyDmr48gMTJtcyDmmL7npLrkuIDkuKrlrZfnrKZcblxuICBmdW5jdGlvbiBzdGFydFR5cGV3cml0ZXIoKSB7XG4gICAgaWYgKHR5cGVUaW1lcikgcmV0dXJuXG4gICAgdHlwZVRpbWVyID0gd2luZG93LnNldEludGVydmFsKCgpID0+IHtcbiAgICAgIGlmICh0eXBlQnVmZmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8g5q+P5qyh5Y+WIDF+MyDkuKrlrZfnrKbvvIzpgJ/luqbmm7Toh6rnhLZcbiAgICAgICAgY29uc3QgY2h1bmsgPSB0eXBlQnVmZmVyLnNsaWNlKDAsIDIpXG4gICAgICAgIHR5cGVCdWZmZXIgPSB0eXBlQnVmZmVyLnNsaWNlKDIpXG4gICAgICAgIGFzc2lzdGFudE1zZy5jb250ZW50ICs9IGNodW5rXG4gICAgICAgIHNjcm9sbFRvQm90dG9tKClcbiAgICAgIH0gZWxzZSBpZiAoIXN0cmVhbWluZy52YWx1ZSkge1xuICAgICAgICAvLyDmtYHlt7Lnu5PmnZ/kuJTnvJPlhrLljLrmuIXnqbrvvIzlgZzmraLlrprml7blmahcbiAgICAgICAgaWYgKHR5cGVUaW1lcikgeyBjbGVhckludGVydmFsKHR5cGVUaW1lcik7IHR5cGVUaW1lciA9IG51bGwgfVxuICAgICAgfVxuICAgIH0sIFRZUEVfSU5URVJWQUwpXG4gIH1cblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKClcbiAgICBpZiAoZG9uZSkgYnJlYWtcbiAgICByYXdCdWZmZXIgKz0gZGVjb2Rlci5kZWNvZGUodmFsdWUsIHsgc3RyZWFtOiB0cnVlIH0pXG5cbiAgICAvLyBTU0Ug5oyJ6KGM6Kej5p6QXG4gICAgY29uc3QgbGluZXMgPSByYXdCdWZmZXIuc3BsaXQoJ1xcbicpXG4gICAgcmF3QnVmZmVyID0gbGluZXMucG9wKCkgfHwgJydcbiAgICBmb3IgKGNvbnN0IGxpbmUgb2YgbGluZXMpIHtcbiAgICAgIGNvbnN0IHRyaW1tZWQgPSBsaW5lLnRyaW0oKVxuICAgICAgaWYgKCF0cmltbWVkLnN0YXJ0c1dpdGgoJ2RhdGE6JykpIGNvbnRpbnVlXG4gICAgICBjb25zdCBkYXRhID0gdHJpbW1lZC5zbGljZSg1KS50cmltKClcbiAgICAgIGlmIChkYXRhID09PSAnW0RPTkVdJykge1xuICAgICAgICAvLyDmtYHnu5PmnZ/vvIznrYnmiZPlrZfmnLrmiornvJPlhrLljLrmuIXnqbpcbiAgICAgICAgYXdhaXQgd2FpdFR5cGV3cml0ZXJEb25lKClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBqc29uID0gSlNPTi5wYXJzZShkYXRhKVxuICAgICAgICBjb25zdCBkZWx0YSA9IGpzb24uY2hvaWNlcz8uWzBdPy5kZWx0YT8uY29udGVudFxuICAgICAgICBpZiAoZGVsdGEgJiYgZGVsdGEudHJpbSgpKSB7XG4gICAgICAgICAgaWYgKGFzc2lzdGFudE1zZy5sb2FkaW5nKSBhc3Npc3RhbnRNc2cubG9hZGluZyA9IGZhbHNlXG4gICAgICAgICAgdHlwZUJ1ZmZlciArPSBkZWx0YVxuICAgICAgICAgIHN0YXJ0VHlwZXdyaXRlcigpXG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyDlv73nlaXpnZ4gSlNPTiDooYxcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgLy8g5rWB5q2j5bi457uT5p2f77yM562J5omT5a2X5py65riF56m657yT5Yay5Yy6XG4gIGF3YWl0IHdhaXRUeXBld3JpdGVyRG9uZSgpXG5cbiAgZnVuY3Rpb24gd2FpdFR5cGV3cml0ZXJEb25lKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgY29uc3QgY2hlY2sgPSAoKSA9PiB7XG4gICAgICAgIGlmICh0eXBlQnVmZmVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGlmICh0eXBlVGltZXIpIHsgY2xlYXJJbnRlcnZhbCh0eXBlVGltZXIpOyB0eXBlVGltZXIgPSBudWxsIH1cbiAgICAgICAgICByZXNvbHZlKClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KGNoZWNrLCAzMClcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2hlY2soKVxuICAgIH0pXG4gIH1cbn1cblxuZnVuY3Rpb24gcnVuQWdlbnQoKSB7XG4gIHNjcm9sbFRvQm90dG9tKClcbn1cbjwvc2NyaXB0PlxuXG48c3R5bGUgc2NvcGVkPlxuLmNoYXQge1xuICBmbGV4OiAxO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1iZy1wYW5lbCk7XG4gIG1pbi13aWR0aDogMDtcbn1cbi5oZWFkZXIge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gIHBhZGRpbmc6IDE0cHggMjBweDtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG59XG4uY2hhdC10aXRsZSB7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG4gIGZvbnQtc2l6ZTogMTVweDtcbn1cbi5jaGF0LXN1YiB7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLXRleHQtbXV0ZWQpO1xuICBtYXJnaW4tdG9wOiAycHg7XG59XG4ucnVuLWJ0biB7XG4gIGJhY2tncm91bmQ6IHZhcigtLXByaW1hcnkpO1xuICBjb2xvcjogI2ZmZjtcbiAgcGFkZGluZzogN3B4IDE2cHg7XG4gIGJvcmRlci1yYWRpdXM6IDdweDtcbiAgZm9udC1zaXplOiAxM3B4O1xuICBmb250LXdlaWdodDogNTAwO1xufVxuLnJ1bi1idG46aG92ZXIge1xuICBvcGFjaXR5OiAwLjk7XG59XG4ubWVzc2FnZXMge1xuICBmbGV4OiAxO1xuICBvdmVyZmxvdy15OiBhdXRvO1xuICBwYWRkaW5nOiAxOHB4IDIwcHg7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogMTZweDtcbn1cbi5tc2cge1xuICBkaXNwbGF5OiBmbGV4O1xufVxuLm1zZy51c2VyIHtcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcbn1cbi5idWJibGUge1xuICBtYXgtd2lkdGg6IDgyJTtcbiAgcGFkZGluZzogMTFweCAxNHB4O1xuICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1iZy1zaWRlYmFyKTtcbiAgbGluZS1oZWlnaHQ6IDEuNjU7XG59XG4uYnViYmxlLnVzZXIge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1wcmltYXJ5KTtcbiAgY29sb3I6ICNmZmY7XG4gIGJvcmRlci1jb2xvcjogdmFyKC0tcHJpbWFyeSk7XG59XG4ucm9sZS10YWcge1xuICBmb250LXNpemU6IDEycHg7XG4gIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbiAgbWFyZ2luLWJvdHRvbTogNHB4O1xufVxuLnRvb2xzIHtcbiAgbWFyZ2luLXRvcDogMTBweDtcbiAgYm9yZGVyLXRvcDogMXB4IGRhc2hlZCB2YXIoLS1ib3JkZXIpO1xuICBwYWRkaW5nLXRvcDogOHB4O1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBnYXA6IDZweDtcbn1cbi50b29sIHtcbiAgcGFkZGluZzogOHB4IDEwcHg7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgYmFja2dyb3VuZDogdmFyKC0tY29kZS1iZyk7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG59XG4udG9vbC1oZWFkIHtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuLnRvb2wtbmFtZSB7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgZm9udC13ZWlnaHQ6IDUwMDtcbn1cbi50b29sLXN0YXR1cyB7XG4gIGZvbnQtc2l6ZTogMTFweDtcbiAgcGFkZGluZzogMnB4IDhweDtcbiAgYm9yZGVyLXJhZGl1czogOTlweDtcbn1cbi50b29sLXN0YXR1cy5kb25lIHtcbiAgYmFja2dyb3VuZDogdmFyKC0tc3VjY2Vzcyk7XG4gIGNvbG9yOiAjZmZmO1xufVxuLnRvb2wtc3RhdHVzLnJ1bm5pbmcge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS13YXJuaW5nKTtcbiAgY29sb3I6ICNmZmY7XG59XG4udG9vbC1zdGF0dXMuZXJyb3Ige1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kYW5nZXIpO1xuICBjb2xvcjogI2ZmZjtcbn1cbi50b29sLXBhcmFtcyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtd3JhcDogd3JhcDtcbiAgZ2FwOiA0cHggMTJweDtcbiAgbWFyZ2luLXRvcDogNnB4O1xuICBmb250LXNpemU6IDExcHg7XG4gIGNvbG9yOiB2YXIoLS10ZXh0LXNlY29uZGFyeSk7XG59XG4ucHJldmlldy1idG4ge1xuICBtYXJnaW4tdG9wOiA4cHg7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLXByaW1hcnkpO1xufVxuLmlucHV0LWJhciB7XG4gIGJvcmRlci10b3A6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICBwYWRkaW5nOiAxMnB4IDE0cHg7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogOHB4O1xufVxuLmlucHV0LWJhciB0ZXh0YXJlYSB7XG4gIHJlc2l6ZTogbm9uZTtcbiAgcGFkZGluZzogMTBweCAxMnB4O1xuICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1iZy1pbnB1dCk7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG4gIGxpbmUtaGVpZ2h0OiAxLjU7XG59XG4uaW5wdXQtYmFyIHRleHRhcmVhOmZvY3VzIHtcbiAgYm9yZGVyLWNvbG9yOiB2YXIoLS1wcmltYXJ5KTtcbn1cbi5pbnB1dC1hY3Rpb25zIHtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuLnJpZ2h0LWFjdGlvbnMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDEwcHg7XG59XG4uYXBpLXNlbGVjdCB7XG4gIHBhZGRpbmc6IDVweCAxMHB4O1xuICBib3JkZXItcmFkaXVzOiA3cHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG4gIGJhY2tncm91bmQ6IHZhcigtLWJnLWlucHV0KTtcbiAgY29sb3I6IHZhcigtLXRleHQtcHJpbWFyeSk7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgbWF4LXdpZHRoOiAyMDBweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xufVxuLmFwaS1zZWxlY3Q6Zm9jdXMge1xuICBib3JkZXItY29sb3I6IHZhcigtLXByaW1hcnkpO1xuICBvdXRsaW5lOiBub25lO1xufVxuLmhpbnQge1xuICBmb250LXNpemU6IDExcHg7XG4gIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbn1cbi5zZW5kLWJ0biB7XG4gIGJhY2tncm91bmQ6IHZhcigtLXByaW1hcnkpO1xuICBjb2xvcjogI2ZmZjtcbiAgcGFkZGluZzogNnB4IDE4cHg7XG4gIGJvcmRlci1yYWRpdXM6IDdweDtcbiAgZm9udC1zaXplOiAxM3B4O1xufVxuLnNlbmQtYnRuOmhvdmVyIHtcbiAgb3BhY2l0eTogMC45O1xufVxuLnNlbmQtYnRuOmRpc2FibGVkIHtcbiAgb3BhY2l0eTogMC42O1xuICBjdXJzb3I6IG5vdC1hbGxvd2VkO1xufVxuXG4vKiDliqDovb3liqjmlYjvvIjkuInngrnot7PliqjvvIkgKi9cbi5sb2FkaW5nLWRvdHMge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgZ2FwOiA0cHg7XG4gIHBhZGRpbmc6IDRweCAwO1xufVxuLmxvYWRpbmctZG90cyBzcGFuIHtcbiAgd2lkdGg6IDdweDtcbiAgaGVpZ2h0OiA3cHg7XG4gIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgYmFja2dyb3VuZDogdmFyKC0tcHJpbWFyeSk7XG4gIG9wYWNpdHk6IDAuNDtcbiAgYW5pbWF0aW9uOiBkb3QtYm91bmNlIDEuMnMgaW5maW5pdGUgZWFzZS1pbi1vdXQ7XG59XG4ubG9hZGluZy1kb3RzIHNwYW46bnRoLWNoaWxkKDIpIHsgYW5pbWF0aW9uLWRlbGF5OiAwLjE1czsgfVxuLmxvYWRpbmctZG90cyBzcGFuOm50aC1jaGlsZCgzKSB7IGFuaW1hdGlvbi1kZWxheTogMC4zczsgfVxuQGtleWZyYW1lcyBkb3QtYm91bmNlIHtcbiAgMCUsIDgwJSwgMTAwJSB7IG9wYWNpdHk6IDAuMzsgdHJhbnNmb3JtOiBzY2FsZSgwLjgpOyB9XG4gIDQwJSB7IG9wYWNpdHk6IDE7IHRyYW5zZm9ybTogc2NhbGUoMS4yKTsgfVxufVxuXG4vKiDmtYHlvI/lhYnmoIcgKi9cbi5jdXJzb3Ige1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIGNvbG9yOiB2YXIoLS1wcmltYXJ5KTtcbiAgYW5pbWF0aW9uOiBibGluayAxcyBzdGVwLWVuZCBpbmZpbml0ZTtcbn1cbkBrZXlmcmFtZXMgYmxpbmsge1xuICA1MCUgeyBvcGFjaXR5OiAwOyB9XG59XG5cbi8qIE1hcmtkb3duIOa4suafk+agt+W8jyAqL1xuLm1hcmtkb3duLWJvZHkge1xuICBmb250LXNpemU6IDE0cHg7XG4gIGxpbmUtaGVpZ2h0OiAxLjc7XG4gIHdvcmQtYnJlYWs6IGJyZWFrLXdvcmQ7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcChwKSB7IG1hcmdpbjogMCAwIDEwcHg7IH1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKHA6bGFzdC1jaGlsZCkgeyBtYXJnaW4tYm90dG9tOiAwOyB9XG4ubWFya2Rvd24tYm9keSA6ZGVlcChoMSksXG4ubWFya2Rvd24tYm9keSA6ZGVlcChoMiksXG4ubWFya2Rvd24tYm9keSA6ZGVlcChoMykge1xuICBtYXJnaW46IDE0cHggMCA4cHg7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcChoMSkgeyBmb250LXNpemU6IDE4cHg7IH1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKGgyKSB7IGZvbnQtc2l6ZTogMTZweDsgfVxuLm1hcmtkb3duLWJvZHkgOmRlZXAoaDMpIHsgZm9udC1zaXplOiAxNXB4OyB9XG4ubWFya2Rvd24tYm9keSA6ZGVlcCh1bCksXG4ubWFya2Rvd24tYm9keSA6ZGVlcChvbCkge1xuICBtYXJnaW46IDhweCAwO1xuICBwYWRkaW5nLWxlZnQ6IDIycHg7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcChsaSkgeyBtYXJnaW46IDNweCAwOyB9XG4ubWFya2Rvd24tYm9keSA6ZGVlcChzdHJvbmcpIHsgZm9udC13ZWlnaHQ6IDYwMDsgfVxuLm1hcmtkb3duLWJvZHkgOmRlZXAoYmxvY2txdW90ZSkge1xuICBtYXJnaW46IDhweCAwO1xuICBwYWRkaW5nOiA2cHggMTJweDtcbiAgYm9yZGVyLWxlZnQ6IDNweCBzb2xpZCB2YXIoLS1wcmltYXJ5KTtcbiAgYmFja2dyb3VuZDogdmFyKC0tYmctaG92ZXIpO1xuICBjb2xvcjogdmFyKC0tdGV4dC1zZWNvbmRhcnkpO1xufVxuLm1hcmtkb3duLWJvZHkgOmRlZXAoY29kZSkge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1jb2RlLWJnKTtcbiAgcGFkZGluZzogMnB4IDZweDtcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xuICBmb250LXNpemU6IDEzcHg7XG4gIGZvbnQtZmFtaWx5OiAnQ29uc29sYXMnLCAnTW9uYWNvJywgbW9ub3NwYWNlO1xufVxuLm1hcmtkb3duLWJvZHkgOmRlZXAocHJlKSB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWNvZGUtYmcpO1xuICBwYWRkaW5nOiAxMnB4O1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIG92ZXJmbG93LXg6IGF1dG87XG4gIG1hcmdpbjogMTBweCAwO1xufVxuLm1hcmtkb3duLWJvZHkgOmRlZXAocHJlIGNvZGUpIHtcbiAgYmFja2dyb3VuZDogbm9uZTtcbiAgcGFkZGluZzogMDtcbiAgZm9udC1zaXplOiAxM3B4O1xufVxuLm1hcmtkb3duLWJvZHkgOmRlZXAoYSkge1xuICBjb2xvcjogdmFyKC0tcHJpbWFyeSk7XG4gIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xufVxuLm1hcmtkb3duLWJvZHkgOmRlZXAodGFibGUpIHtcbiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTtcbiAgbWFyZ2luOiAxMHB4IDA7XG59XG4ubWFya2Rvd24tYm9keSA6ZGVlcCh0aCksXG4ubWFya2Rvd24tYm9keSA6ZGVlcCh0ZCkge1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICBwYWRkaW5nOiA2cHggMTBweDtcbn1cbi5tYXJrZG93bi1ib2R5IDpkZWVwKGhyKSB7XG4gIGJvcmRlcjogbm9uZTtcbiAgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XG4gIG1hcmdpbjogMTJweCAwO1xufVxuXG4vKiDnlKjmiLfmsJTms6HlhoXnmoQgTWFya2Rvd24g6aKc6Imy6KaG55uWICovXG4uYnViYmxlLnVzZXIgLm1hcmtkb3duLWJvZHkgOmRlZXAoY29kZSksXG4uYnViYmxlLnVzZXIgLm1hcmtkb3duLWJvZHkgOmRlZXAocHJlKSB7XG4gIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4yKTtcbiAgY29sb3I6ICNmZmY7XG59XG4uYnViYmxlLnVzZXIgLm1hcmtkb3duLWJvZHkgOmRlZXAoYmxvY2txdW90ZSkge1xuICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMTUpO1xuICBjb2xvcjogI2ZmZjtcbiAgYm9yZGVyLWNvbG9yOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNSk7XG59XG4uYnViYmxlLnVzZXIgLm1hcmtkb3duLWJvZHkgOmRlZXAoYSkgeyBjb2xvcjogI2ZmZjsgfVxuPC9zdHlsZT5cbiJdLCJmaWxlIjoiRDovZG5kQ2xhdy9hZ2VudC1jb25zb2xlL3NyYy9yZW5kZXJlci9jb21wb25lbnRzL0NoYXRQYW5lbC52dWUifQ==