You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

517 lines
78 KiB

"use strict";
var __asyncValues = (this && this.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.McpHttpServer = exports.MCP_DEFAULT_PORT = void 0;
const http_1 = __importDefault(require("http"));
const zod_1 = require("zod");
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
/** MCP 服务默认端口(HTTP Streamable)。 */
exports.MCP_DEFAULT_PORT = 33010;
const text = (s, isError = false) => ({
content: [{ type: 'text', text: s }],
isError,
});
const json = (v, isError = false) => ({
content: [{ type: 'text', text: JSON.stringify(v, null, 2) }],
isError,
});
/** 统计节点树总节点数。 */
function countNodes(roots) {
let n = 0;
const walk = (list) => {
for (const r of list) {
n++;
if (Array.isArray(r.children)) {
walk(r.children);
}
}
};
walk(roots !== null && roots !== void 0 ? roots : []);
return n;
}
/** 把节点树裁剪到指定深度(在序列化结果上处理,无需改桥接脚本)。 */
function pruneTree(roots, maxDepth) {
const walk = (list, depth) => {
return (list !== null && list !== void 0 ? list : []).map((r) => {
const out = {
id: r.id,
name: r.name,
active: r.active,
layer: r.layer,
comps: r.comps,
};
if (Array.isArray(r.children) && depth < maxDepth) {
out.children = walk(r.children, depth + 1);
}
else if (Array.isArray(r.children) && r.children.length) {
out.children = `...${r.children.length} 个子节点(超出 max_depth)`;
}
return out;
});
};
return walk(roots !== null && roots !== void 0 ? roots : [], 0);
}
function fmtT(ts) {
const d = new Date(ts);
const p = (n) => String(n).padStart(2, '0');
return `${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
}
/**
* 内嵌在主进程的 MCP 服务(Streamable HTTP)。
* 工具直接代理到游戏侧桥接脚本(query-tree / get-inspector / set-property / capture-frame 等),
* 供 Codex 等 AI Agent 连接并观察、操作正在运行的游戏。
*/
class McpHttpServer {
constructor() {
this.srv = null;
this.port = 0;
this.token = '';
this.deps = null;
/** 每个会话持有独立的 McpServer 实例(SDK 限制一个 Protocol 只能连接一个 Transport)。 */
this.sessions = new Map();
}
get isRunning() {
return !!this.srv;
}
get boundPort() {
return this.port;
}
checkAuth(req) {
if (!this.token) {
return true;
}
return req.headers.authorization === `Bearer ${this.token}`;
}
async readBody(req, maxBytes = 1024 * 1024) {
var _a, e_1, _b, _c;
const chunks = [];
let size = 0;
try {
for (var _d = true, req_1 = __asyncValues(req), req_1_1; req_1_1 = await req_1.next(), _a = req_1_1.done, !_a; _d = true) {
_c = req_1_1.value;
_d = false;
const chunk = _c;
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
size += buf.length;
if (size > maxBytes) {
throw new Error('body too large');
}
chunks.push(buf);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (!_d && !_a && (_b = req_1.return)) await _b.call(req_1);
}
finally { if (e_1) throw e_1.error; }
}
const raw = Buffer.concat(chunks).toString('utf-8');
if (!raw) {
return undefined;
}
try {
return JSON.parse(raw);
}
catch (_e) {
return raw;
}
}
async handle(req, res) {
var _a;
if (!this.checkAuth(req)) {
res.writeHead(401, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'unauthorized' }));
return;
}
const url = (_a = req.url) !== null && _a !== void 0 ? _a : '';
if (!url.startsWith('/mcp')) {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'not found' }));
return;
}
const sessionId = req.headers['mcp-session-id'];
let session = sessionId ? this.sessions.get(sessionId) : undefined;
if (sessionId && !session) {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'invalid session id' }));
return;
}
try {
if (!session) {
// 新会话:为每个会话创建独立的 McpServer 实例,避免 Protocol 重复连接报错
const deps = this.deps;
if (!deps) {
res.writeHead(503, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'server not ready' }));
return;
}
const transport = new streamableHttp_js_1.StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
const sid = transport.sessionId;
const mcp = this.buildServer(deps);
session = { transport, mcp };
this.sessions.set(sid, session);
transport.onclose = () => {
if (this.sessions.get(sid) === session) {
this.sessions.delete(sid);
}
};
await mcp.connect(transport);
}
const parsedBody = req.method === 'POST' ? await this.readBody(req) : undefined;
await session.transport.handleRequest(req, res, parsedBody);
}
catch (err) {
try {
if (!res.headersSent) {
res.writeHead(500, { 'Content-Type': 'application/json' });
}
res.end(JSON.stringify({ error: String(err) }));
}
catch (_b) {
/* ignore */
}
}
}
/** 注册工具集。 */
buildServer(deps) {
const mcp = new mcp_js_1.McpServer({ name: 'yyka-runtime-inspector', version: '1.0.0' });
const noClient = () => {
const st = deps.getServerState();
return !st.running || st.clients === 0;
};
mcp.registerTool('get_runtime_info', {
title: '获取运行时信息',
description: '获取当前连接的游戏实例信息:连接状态、场景名、节点数量、FPS、DrawCall、三角形数、内存占用、物理系统状态、桥接版本。游戏未连接时返回错误。',
inputSchema: zod_1.z.object({}),
}, async () => {
var _a;
if (noClient()) {
return text('游戏未连接:请先启动 WS 服务、运行游戏并确认桥接脚本已连接。', true);
}
try {
const [stats, tree] = await Promise.all([
deps.callGame('get-stats', undefined, 4000),
deps.callGame('query-tree', {}, 4000),
]);
const st = deps.getServerState();
return json({
connected: true,
clients: st.clients,
wsPort: st.port,
scene: (_a = tree === null || tree === void 0 ? void 0 : tree.scene) !== null && _a !== void 0 ? _a : '',
nodeCount: countNodes(tree === null || tree === void 0 ? void 0 : tree.roots),
stats: stats !== null && stats !== void 0 ? stats : {},
});
}
catch (err) {
return text(`获取运行时信息失败: ${String(err)}`, true);
}
});
mcp.registerTool('get_node_tree', {
title: '获取节点树',
description: '获取当前场景的运行时节点树(名称/激活/层级/组件数)。可用 filter 按节点名筛选;max_depth 限制展开深度避免输出过大。',
inputSchema: zod_1.z.object({
filter: zod_1.z.string().optional().describe('按节点名关键字筛选(可选)'),
max_depth: zod_1.z.number().optional().describe('最大展开深度,默认 20(可选)'),
}),
}, async (args) => {
var _a, _b;
if (noClient()) {
return text('游戏未连接。', true);
}
try {
const tree = await deps.callGame('query-tree', { filter: (_a = args === null || args === void 0 ? void 0 : args.filter) !== null && _a !== void 0 ? _a : '' }, 8000);
if (tree && Array.isArray(tree.roots)) {
const depth = typeof (args === null || args === void 0 ? void 0 : args.max_depth) === 'number' ? Math.max(1, Math.min(50, args.max_depth)) : 20;
return json({ scene: (_b = tree.scene) !== null && _b !== void 0 ? _b : '', roots: pruneTree(tree.roots, depth) });
}
return text('获取节点树失败。', true);
}
catch (err) {
return text(`获取节点树失败: ${String(err)}`, true);
}
});
mcp.registerTool('get_node_info', {
title: '获取节点信息',
description: '按节点 id 获取节点详情:位置/旋转/缩放/激活/层级等 Transform 属性,以及所有组件及其可编辑属性(含枚举、数组、向量、颜色、引用等)。',
inputSchema: zod_1.z.object({
id: zod_1.z.string().describe('节点 id(来自 get_node_tree)'),
}),
}, async (args) => {
if (noClient()) {
return text('游戏未连接。', true);
}
if (!(args === null || args === void 0 ? void 0 : args.id)) {
return text('缺少参数 id。', true);
}
try {
const r = await deps.callGame('get-inspector', { id: args.id }, 8000);
if (r && r.error) {
return text(String(r.error), true);
}
return json(r !== null && r !== void 0 ? r : {});
}
catch (err) {
return text(`获取节点信息失败: ${String(err)}`, true);
}
});
mcp.registerTool('set_node_property', {
title: '修改运行时属性',
description: '修改运行中节点的属性。节点级:field 取 position/euler/scale(value 为 {x,y,z})、active(value 为 boolean)、layer(value 为 number)。组件级:传 comp 组件索引(0 起)与 key 属性名,value 为属性值(向量/颜色传对象,枚举传数字)。',
inputSchema: zod_1.z.object({
id: zod_1.z.string().describe('节点 id(来自 get_node_tree)'),
field: zod_1.z.string().optional().describe('节点级字段:position | euler | scale | active | layer'),
value: zod_1.z.any().optional().describe('要写入的值'),
comp: zod_1.z.number().optional().describe('组件索引(0 起,与 get_node_info 的 components 顺序一致)'),
key: zod_1.z.string().optional().describe('组件属性名'),
}),
}, async (args) => {
if (noClient()) {
return text('游戏未连接。', true);
}
if (!(args === null || args === void 0 ? void 0 : args.id)) {
return text('缺少参数 id。', true);
}
try {
const payload = { id: args.id };
if (typeof args.field === 'string') {
payload.field = args.field;
payload.value = args.value;
}
if (typeof args.comp === 'number') {
payload.comp = args.comp;
payload.key = args.key;
payload.value = args.value;
}
const r = await deps.callGame('set-property', payload, 8000);
if (r && r.error) {
return text(String(r.error), true);
}
return json(r !== null && r !== void 0 ? r : { ok: true });
}
catch (err) {
return text(`修改属性失败: ${String(err)}`, true);
}
});
mcp.registerTool('get_screenshot', {
title: '获取游戏截图',
description: '抓取当前游戏画面并返回图片(JPEG),用于视觉验证游戏状态。',
inputSchema: zod_1.z.object({}),
}, async () => {
if (noClient()) {
return text('游戏未连接。', true);
}
try {
const r = await deps.callGame('capture-frame', {}, 6000);
const dataUrl = r && typeof r.data === 'string' ? r.data : '';
const base64 = dataUrl.includes(',') ? dataUrl.split(',')[1] : dataUrl;
if (!base64) {
return text('截图失败:游戏侧未能捕获画面。', true);
}
return {
content: [{ type: 'image', data: base64, mimeType: 'image/jpeg' }],
};
}
catch (err) {
return text(`截图失败: ${String(err)}`, true);
}
});
mcp.registerTool('get_logs', {
title: '获取运行时日志',
description: '获取游戏侧最近的控制台日志(console.log/warn/error)。level 可选 log/warn/error,默认全部。',
inputSchema: zod_1.z.object({
limit: zod_1.z.number().optional().describe('返回条数,默认 50'),
level: zod_1.z.string().optional().describe('过滤级别:all | log | warn | error'),
}),
}, async (args) => {
const limit = typeof (args === null || args === void 0 ? void 0 : args.limit) === 'number' ? Math.max(1, Math.min(200, args.limit)) : 50;
const level = typeof (args === null || args === void 0 ? void 0 : args.level) === 'string' ? args.level : 'all';
const items = deps.getLogs(limit, level);
if (!items.length) {
return text('(暂无日志)');
}
const lines = items.map((it) => {
var _a, _b;
if (it && it.evt === 'console') {
const tag = it.level === 'error' ? 'ERROR' : it.level === 'warn' ? 'WARN ' : 'LOG ';
return `${fmtT(it.t)} [${tag}] ${it.text}`;
}
if (it && it.evt === 'sys') {
return `${fmtT((_a = it.t) !== null && _a !== void 0 ? _a : Date.now())} [SYS] ${(_b = it.msg) !== null && _b !== void 0 ? _b : ''}`;
}
return JSON.stringify(it);
});
return text(lines.join('\n'));
});
mcp.registerTool('wait', {
title: '等待',
description: '等待指定毫秒(1-60000),常用于等待游戏状态变化后再查询。',
inputSchema: zod_1.z.object({
ms: zod_1.z.number().describe('毫秒数,1-60000'),
}),
}, async (args) => {
const ms = Math.max(1, Math.min(60000, Number(args === null || args === void 0 ? void 0 : args.ms) || 0));
await new Promise((r) => setTimeout(r, ms));
return text(`已等待 ${ms}ms`);
});
mcp.registerTool('execute_command', {
title: '执行游戏命令',
description: '向游戏侧桥接脚本发送任意命令。常用:get-stats、get-resource-stats、query-physics、set-preview({enabled,fps})、set-mute({muted})、set-physics-debug({enabled})。',
inputSchema: zod_1.z.object({
cmd: zod_1.z.string().describe('命令名'),
payload: zod_1.z.any().optional().describe('命令参数(可选)'),
}),
}, async (args) => {
if (noClient()) {
return text('游戏未连接。', true);
}
if (!(args === null || args === void 0 ? void 0 : args.cmd)) {
return text('缺少参数 cmd。', true);
}
try {
const r = await deps.callGame(String(args.cmd), args.payload, 8000);
return json(r !== null && r !== void 0 ? r : {});
}
catch (err) {
return text(`命令执行失败: ${String(err)}`, true);
}
});
mcp.registerTool('click', {
title: '模拟点击',
description: '模拟一次触摸点击。传 id 则点击该节点(取其 UI 中心点);传 x/y 则点击屏幕(UI 坐标)上命中的最上层节点。常用于触发按钮、开始游戏等操作。',
inputSchema: zod_1.z.object({
id: zod_1.z.string().optional().describe('节点 id(来自 get_node_tree)'),
x: zod_1.z.number().optional().describe('UI 横坐标(与 id 二选一)'),
y: zod_1.z.number().optional().describe('UI 纵坐标(与 id 二选一)'),
}),
}, async (args) => {
if (noClient()) {
return text('游戏未连接。', true);
}
if (!(args === null || args === void 0 ? void 0 : args.id) && (typeof (args === null || args === void 0 ? void 0 : args.x) !== 'number' || typeof (args === null || args === void 0 ? void 0 : args.y) !== 'number')) {
return text('需要参数 id(节点 id)或 x/y(UI 坐标)。', true);
}
try {
const payload = {};
if (typeof args.id === 'string' && args.id) {
payload.id = args.id;
}
else {
payload.x = args.x;
payload.y = args.y;
}
const r = await deps.callGame('simulate-click', payload, 8000);
if (r && r.error) {
return text(String(r.error), true);
}
return json(r !== null && r !== void 0 ? r : { ok: true });
}
catch (err) {
return text(`模拟点击失败: ${String(err)}`, true);
}
});
mcp.registerTool('list_scenes', {
title: '列出场景',
description: '列出当前运行场景及已加载场景名,用于确认跳转目标。',
inputSchema: zod_1.z.object({}),
}, async () => {
if (noClient()) {
return text('游戏未连接。', true);
}
try {
const r = await deps.callGame('list-scenes', {}, 6000);
return json(r !== null && r !== void 0 ? r : { current: '', scenes: [] });
}
catch (err) {
return text(`列出场景失败: ${String(err)}`, true);
}
});
mcp.registerTool('load_scene', {
title: '跳转场景',
description: '运行时加载指定名称的场景(场景跳转)。场景名可先通过 list_scenes 查看。',
inputSchema: zod_1.z.object({
name: zod_1.z.string().describe('场景名'),
}),
}, async (args) => {
if (noClient()) {
return text('游戏未连接。', true);
}
if (!(args === null || args === void 0 ? void 0 : args.name)) {
return text('缺少参数 name。', true);
}
try {
const r = await deps.callGame('load-scene', { name: String(args.name) }, 6000);
if (r && r.error) {
return text(String(r.error), true);
}
return json(r !== null && r !== void 0 ? r : { ok: true });
}
catch (err) {
return text(`跳转场景失败: ${String(err)}`, true);
}
});
return mcp;
}
/** 启动 HTTP 服务。port 被占用时抛错。 */
async start(port, token, deps) {
if (this.srv) {
return;
}
this.token = token;
this.deps = deps;
const srv = http_1.default.createServer((req, res) => {
this.handle(req, res).catch(() => {
/* handled inside */
});
});
await new Promise((resolve, reject) => {
const onError = (err) => {
srv.removeListener('listening', onListening);
reject(err);
};
const onListening = () => {
srv.removeListener('error', onError);
resolve();
};
srv.once('error', onError);
srv.once('listening', onListening);
srv.listen(port, '127.0.0.1');
});
this.srv = srv;
this.port = port;
}
/** 停止服务并关闭所有会话。 */
async stop() {
const srv = this.srv;
this.srv = null;
this.port = 0;
this.deps = null;
for (const { transport } of this.sessions.values()) {
try {
await transport.close();
}
catch (_a) {
/* ignore */
}
}
this.sessions.clear();
if (srv) {
await new Promise((resolve) => srv.close(() => resolve()));
}
}
}
exports.McpHttpServer = McpHttpServer;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NvdXJjZS9tY3Atc2VydmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFBQSxnREFBd0I7QUFDeEIsNkJBQXdCO0FBQ3hCLG9FQUFvRTtBQUNwRSwwRkFBbUc7QUFFbkcsbUNBQW1DO0FBQ3RCLFFBQUEsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0FBb0J0QyxNQUFNLElBQUksR0FBRyxDQUFDLENBQVMsRUFBRSxPQUFPLEdBQUcsS0FBSyxFQUFjLEVBQUUsQ0FBQyxDQUFDO0lBQ3RELE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDcEMsT0FBTztDQUNWLENBQUMsQ0FBQztBQUVILE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBVSxFQUFFLE9BQU8sR0FBRyxLQUFLLEVBQWMsRUFBRSxDQUFDLENBQUM7SUFDdkQsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUM3RCxPQUFPO0NBQ1YsQ0FBQyxDQUFDO0FBRUgsaUJBQWlCO0FBQ2pCLFNBQVMsVUFBVSxDQUFDLEtBQVk7SUFDNUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFXLEVBQUUsRUFBRTtRQUN6QixLQUFLLE1BQU0sQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ25CLENBQUMsRUFBRSxDQUFDO1lBQ0osSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUM1QixJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3JCLENBQUM7UUFDTCxDQUFDO0lB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SUFBSSxDQUFDO2dCQUNELE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzVCLENBQUM7WUFBQyxXQUFNLENBQUM7Z0JBQ0wsWUFBWTtZQUNoQixDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNOLE1BQU0sSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLENBQUM7SUFDTCxDQUFDO0NBQ0o7QUE5ZEQsc0NBOGRDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcbmltcG9ydCB7IE1jcFNlcnZlciB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc2VydmVyL21jcC5qcyc7XG5pbXBvcnQgeyBTdHJlYW1hYmxlSFRUUFNlcnZlclRyYW5zcG9ydCB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc2VydmVyL3N0cmVhbWFibGVIdHRwLmpzJztcblxuLyoqIE1DUCDmnI3liqHpu5jorqTnq6/lj6PvvIhIVFRQIFN0cmVhbWFibGXvvInjgIIgKi9cbmV4cG9ydCBjb25zdCBNQ1BfREVGQVVMVF9QT1JUID0gMzMwMTA7XG5cbi8qKiDkuLvov5vnqIvlkJEgTUNQIOacjeWKoeaPkOS+m+eahOS+nei1luiDveWKm+OAgiAqL1xuZXhwb3J0IGludGVyZmFjZSBNY3BEZXBzIHtcbiAgICAvKiog5ZCR5ri45oiP5L6n5qGl5o6l6ISa5pys5Y+R5ZG95Luk5bm2562J5b6F5Zue5YyF44CCICovXG4gICAgY2FsbEdhbWU6IChjbWQ6IHN0cmluZywgcGF5bG9hZD86IHVua25vd24sIHRpbWVvdXQ/OiBudW1iZXIpID0+IFByb21pc2U8YW55PjtcbiAgICAvKiog5b2T5YmNIFdTIOacjeWKoeeKtuaAgeOAgiAqL1xuICAgIGdldFNlcnZlclN0YXRlOiAoKSA9PiB7IHJ1bm5pbmc6IGJvb2xlYW47IHBvcnQ6IG51bWJlcjsgY2xpZW50czogbnVtYmVyIH07XG4gICAgLyoqIOW9k+WJjei/nuaOpeS7pOeJjOOAgiAqL1xuICAgIGdldFRva2VuOiAoKSA9PiBzdHJpbmc7XG4gICAgLyoqIOivu+WPluacgOi/keaXpeW/l++8iOS4jea4heepuue8k+WGsu+8ieOAgiAqL1xuICAgIGdldExvZ3M6IChsaW1pdDogbnVtYmVyLCBsZXZlbDogc3RyaW5nKSA9PiB1bmtub3duW107XG59XG5cbmludGVyZmFjZSBUb29sUmVzdWx0IHtcbiAgICBjb250ZW50OiAoeyB0eXBlOiAndGV4dCc7IHRleHQ6IHN0cmluZyB9IHwgeyB0eXBlOiAnaW1hZ2UnOyBkYXRhOiBzdHJpbmc7IG1pbWVUeXBlOiBzdHJpbmcgfSlbXTtcbiAgICBpc0Vycm9yPzogYm9vbGVhbjtcbiAgICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xufVxuXG5jb25zdCB0ZXh0ID0gKHM6IHN0cmluZywgaXNFcnJvciA9IGZhbHNlKTogVG9vbFJlc3VsdCA9PiAoe1xuICAgIGNvbnRlbnQ6IFt7IHR5cGU6ICd0ZXh0JywgdGV4dDogcyB9XSxcbiAgICBpc0Vycm9yLFxufSk7XG5cbmNvbnN0IGpzb24gPSAodjogdW5rbm93biwgaXNFcnJvciA9IGZhbHNlKTogVG9vbFJlc3VsdCA9PiAoe1xuICAgIGNvbnRlbnQ6IFt7IHR5cGU6ICd0ZXh0JywgdGV4dDogSlNPTi5zdHJpbmdpZnkodiwgbnVsbCwgMikgfV0sXG4gICAgaXNFcnJvcixcbn0pO1xuXG4vKiog57uf6K6h6IqC54K55qCR5oC76IqC54K55pWw44CCICovXG5mdW5jdGlvbiBjb3VudE5vZGVzKHJvb3RzOiBhbnlbXSk6IG51bWJlciB7XG4gICAgbGV0IG4gPSAwO1xuICAgIGNvbnN0IHdhbGsgPSAobGlzdDogYW55W10pID0+IHtcbiAgICAgICAgZm9yIChjb25zdCByIG9mIGxpc3QpIHtcbiAgICAgICAgICAgIG4rKztcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHIuY2hpbGRyZW4pKSB7XG4gICAgICAgICAgICAgICAgd2FsayhyLmNoaWxkcmVuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgd2Fsayhyb290cyA/PyBbXSk7XG4gICAgcmV0dXJuIG47XG59XG5cbi8qKiDmioroioLngrnmoJHoo4HliarliLDmjIflrprmt7HluqbvvIjlnKjluo/liJfljJbnu5PmnpzkuIrlpITnkIbvvIzml6DpnIDmlLnmoaXmjqXohJrmnKzvvInjgIIgKi9cbmZ1bmN0aW9uIHBydW5lVHJlZShyb290czogYW55W10sIG1heERlcHRoOiBudW1iZXIpOiBhbnlbXSB7XG4gICAgY29uc3Qgd2FsayA9IChsaXN0OiBhbnlbXSwgZGVwdGg6IG51bWJlcik6IGFueVtdID0+IHtcbiAgICAgICAgcmV0dXJuIChsaXN0ID8/IFtdKS5tYXAoKHIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG91dDogYW55ID0ge1xuICAgICAgICAgICAgICAgIGlkOiByLmlkLFxuICAgICAgICAgICAgICAgIG5hbWU6IHIubmFtZSxcbiAgICAgICAgICAgICAgICBhY3RpdmU6IHIuYWN0aXZlLFxuICAgICAgICAgICAgICAgIGxheWVyOiByLmxheWVyLFxuICAgICAgICAgICAgICAgIGNvbXBzOiByLmNvbXBzLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHIuY2hpbGRyZW4pICYmIGRlcHRoIDwgbWF4RGVwdGgpIHtcbiAgICAgICAgICAgICAgICBvdXQuY2hpbGRyZW4gPSB3YWxrKHIuY2hpbGRyZW4sIGRlcHRoICsgMSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoci5jaGlsZHJlbikgJiYgci5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvdXQuY2hpbGRyZW4gPSBgLi4uJHtyLmNoaWxkcmVuLmxlbmd0aH0g5Liq5a2Q6IqC54K577yI6LaF5Ye6IG1heF9kZXB0aO+8iWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb3V0O1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiB3YWxrKHJvb3RzID8/IFtdLCAwKTtcbn1cblxuZnVuY3Rpb24gZm10VCh0czogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBjb25zdCBkID0gbmV3IERhdGUodHMpO1xuICAgIGNvbnN0IHAgPSAobjogbnVtYmVyKSA9PiBTdHJpbmcobikucGFkU3RhcnQoMiwgJzAnKTtcbiAgICByZXR1cm4gYCR7cChkLmdldEhvdXJzKCkpfToke3AoZC5nZXRNaW51dGVzKCkpfToke3AoZC5nZXRTZWNvbmRzKCkpfWA7XG59XG5cbi8qKlxuICog5YaF5bWM5Zyo5Li76L+b56iL55qEIE1DUCDmnI3liqHvvIhTdHJlYW1hYmxlIEhUVFDvvInjgIJcbiAqIOW3peWFt+ebtOaOpeS7o+eQhuWIsOa4uOaIj+S+p+ahpeaOpeiEmuacrO+8iHF1ZXJ5LXRyZWUgLyBnZXQtaW5zcGVjdG9yIC8gc2V0LXByb3BlcnR5IC8gY2FwdHVyZS1mcmFtZSDnrYnvvInvvIxcbiAqIOS+myBDb2RleCDnrYkgQUkgQWdlbnQg6L+e5o6l5bm26KeC5a+f44CB5pON5L2c5q2j5Zyo6L+Q6KGM55qE5ri45oiP44CCXG4gKi9cbmV4cG9ydCBjbGFzcyBNY3BIdHRwU2VydmVyIHtcbiAgICBwcml2YXRlIHNydjogaHR0cC5TZXJ2ZXIgfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIHBvcnQgPSAwO1xuICAgIHByaXZhdGUgdG9rZW4gPSAnJztcbiAgICBwcml2YXRlIGRlcHM6IE1jcERlcHMgfCBudWxsID0gbnVsbDtcbiAgICAvKiog5q+P5Liq5Lya6K+d5oyB5pyJ54us56uL55qEIE1jcFNlcnZlciDlrp7kvovvvIhTREsg6ZmQ5Yi25LiA5LiqIFByb3RvY29sIOWPquiDvei/nuaOpeS4gOS4qiBUcmFuc3BvcnTvvInjgIIgKi9cbiAgICBwcml2YXRlIHNlc3Npb25zID0gbmV3IE1hcDxzdHJpbmcsIHsgdHJhbnNwb3J0OiBTdHJlYW1hYmxlSFRUUFNlcnZlclRyYW5zcG9ydDsgbWNwOiBNY3BTZXJ2ZXIgfT4oKTtcblxuICAgIGdldCBpc1J1bm5pbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuc3J2O1xuICAgIH1cblxuICAgIGdldCBib3VuZFBvcnQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9ydDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNoZWNrQXV0aChyZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghdGhpcy50b2tlbikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb24gPT09IGBCZWFyZXIgJHt0aGlzLnRva2VufWA7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZWFkQm9keShyZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlLCBtYXhCeXRlcyA9IDEwMjQgKiAxMDI0KTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgICAgIGNvbnN0IGNodW5rczogQnVmZmVyW10gPSBbXTtcbiAgICAgICAgbGV0IHNpemUgPSAwO1xuICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IGNodW5rIG9mIHJlcSkge1xuICAgICAgICAgICAgY29uc3QgYnVmID0gQnVmZmVyLmlzQnVmZmVyKGNodW5rKSA/IGNodW5rIDogQnVmZmVyLmZyb20oU3RyaW5nKGNodW5rKSk7XG4gICAgICAgICAgICBzaXplICs9IGJ1Zi5sZW5ndGg7XG4gICAgICAgICAgICBpZiAoc2l6ZSA+IG1heEJ5dGVzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdib2R5IHRvbyBsYXJnZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2h1bmtzLnB1c2goYnVmKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByYXcgPSBCdWZmZXIuY29uY2F0KGNodW5rcykudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICAgIGlmICghcmF3KSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShyYXcpO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHJldHVybiByYXc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGhhbmRsZShyZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlLCByZXM6IGh0dHAuU2VydmVyUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKCF0aGlzLmNoZWNrQXV0aChyZXEpKSB7XG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDQwMSwgeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pO1xuICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiAndW5hdXRob3JpemVkJyB9KSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJsID0gcmVxLnVybCA/PyAnJztcbiAgICAgICAgaWYgKCF1cmwuc3RhcnRzV2l0aCgnL21jcCcpKSB7XG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDQwNCwgeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pO1xuICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiAnbm90IGZvdW5kJyB9KSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gcmVxLmhlYWRlcnNbJ21jcC1zZXNzaW9uLWlkJ10gYXMgc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgc2Vzc2lvbiA9IHNlc3Npb25JZCA/IHRoaXMuc2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCkgOiB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChzZXNzaW9uSWQgJiYgIXNlc3Npb24pIHtcbiAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoNDA0LCB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgICAgICAgICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KHsgZXJyb3I6ICdpbnZhbGlkIHNlc3Npb24gaWQnIH0pKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgLy8g5paw5Lya6K+d77ya5Li65q+P5Liq5Lya6K+d5Yib5bu654us56uL55qEIE1jcFNlcnZlciDlrp7kvovvvIzpgb/lhY0gUHJvdG9jb2wg6YeN5aSN6L+e5o6l5oql6ZSZXG4gICAgICAgICAgICAgICAgY29uc3QgZGVwcyA9IHRoaXMuZGVwcztcbiAgICAgICAgICAgICAgICBpZiAoIWRlcHMpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzLndyaXRlSGVhZCg1MDMsIHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiAnc2VydmVyIG5vdCByZWFkeScgfSkpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHRyYW5zcG9ydCA9IG5ldyBTdHJlYW1hYmxlSFRUUFNlcnZlclRyYW5zcG9ydCh7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZEdlbmVyYXRvcjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNpZCA9IHRyYW5zcG9ydC5zZXNzaW9uSWQgYXMgc3RyaW5nO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1jcCA9IHRoaXMuYnVpbGRTZXJ2ZXIoZGVwcyk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbiA9IHsgdHJhbnNwb3J0LCBtY3AgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb25zLnNldChzaWQsIHNlc3Npb24pO1xuICAgICAgICAgICAgICAgIHRyYW5zcG9ydC5vbmNsb3NlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9ucy5nZXQoc2lkKSA9PT0gc2Vzc2lvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9ucy5kZWxldGUoc2lkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgYXdhaXQgbWNwLmNvbm5lY3QodHJhbnNwb3J0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZEJvZHkgPSByZXEubWV0aG9kID09PSAnUE9TVCcgPyBhd2FpdCB0aGlzLnJlYWRCb2R5KHJlcSkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBhd2FpdCBzZXNzaW9uLnRyYW5zcG9ydC5oYW5kbGVSZXF1ZXN0KHJlcSwgcmVzLCBwYXJzZWRCb2R5KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoNTAwLCB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogU3RyaW5nKGVycikgfSkpO1xuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgLyogaWdub3JlICovXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiog5rOo5YaM5bel5YW36ZuG44CCICovXG4gICAgcHJpdmF0ZSBidWlsZFNlcnZlcihkZXBzOiBNY3BEZXBzKTogTWNwU2VydmVyIHtcbiAgICAgICAgY29uc3QgbWNwID0gbmV3IE1jcFNlcnZlcih7IG5hbWU6ICd5eWthLXJ1bnRpbWUtaW5zcGVjdG9yJywgdmVyc2lvbjogJzEuMC4wJyB9KTtcbiAgICAgICAgY29uc3Qgbm9DbGllbnQgPSAoKTogYm9vbGVhbiA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdCA9IGRlcHMuZ2V0U2VydmVyU3RhdGUoKTtcbiAgICAgICAgICAgIHJldHVybiAhc3QucnVubmluZyB8fCBzdC5jbGllbnRzID09PSAwO1xuICAgICAgICB9O1xuXG4gICAgICAgIG1jcC5yZWdpc3RlclRvb2woXG4gICAgICAgICAgICAnZ2V0X3J1bnRpbWVfaW5mbycsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICfojrflj5bov5DooYzml7bkv6Hmga8nLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAn6I635Y+W5b2T5YmN6L+e5o6l55qE5ri45oiP5a6e5L6L5L+h5oGv77ya6L+e5o6l54q25oCB44CB5Zy65pmv5ZCN44CB6IqC54K55pWw6YeP44CBRlBT44CBRHJhd0NhbGzjgIHkuInop5LlvaLmlbDjgIHlhoXlrZjljaDnlKjjgIHniannkIbns7vnu5/nirbmgIHjgIHmoaXmjqXniYjmnKzjgILmuLjmiI/mnKrov57mjqXml7bov5Tlm57plJnor6/jgIInLFxuICAgICAgICAgICAgICAgIGlucHV0U2NoZW1hOiB6Lm9iamVjdCh7fSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub0NsaWVudCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfmuLjmiI/mnKrov57mjqXvvJror7flhYjlkK/liqggV1Mg5pyN5Yqh44CB6L+Q6KGM5ri45oiP5bm256Gu6K6k5qGl5o6l6ISa5pys5bey6L+e5o6l44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IFtzdGF0cywgdHJlZV0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXBzLmNhbGxHYW1lKCdnZXQtc3RhdHMnLCB1bmRlZmluZWQsIDQwMDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVwcy5jYWxsR2FtZSgncXVlcnktdHJlZScsIHt9LCA0MDAwKSxcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0ID0gZGVwcy5nZXRTZXJ2ZXJTdGF0ZSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ganNvbih7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0ZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRzOiBzdC5jbGllbnRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgd3NQb3J0OiBzdC5wb3J0LFxuICAgICAgICAgICAgICAgICAgICAgICAgc2NlbmU6IHRyZWU/LnNjZW5lID8/ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUNvdW50OiBjb3VudE5vZGVzKHRyZWU/LnJvb3RzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRzOiBzdGF0cyA/PyB7fSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KGDojrflj5bov5DooYzml7bkv6Hmga/lpLHotKU6ICR7U3RyaW5nKGVycil9YCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBtY3AucmVnaXN0ZXJUb29sKFxuICAgICAgICAgICAgJ2dldF9ub2RlX3RyZWUnLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRpdGxlOiAn6I635Y+W6IqC54K55qCRJyxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICAgICAgICAgJ+iOt+WPluW9k+WJjeWcuuaZr+eahOi/kOihjOaXtuiKgueCueagke+8iOWQjeensC/mv4DmtLsv5bGC57qnL+e7hOS7tuaVsO+8ieOAguWPr+eUqCBmaWx0ZXIg5oyJ6IqC54K55ZCN562b6YCJ77ybbWF4X2RlcHRoIOmZkOWItuWxleW8gOa3seW6pumBv+WFjei+k+WHuui/h+Wkp+OAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ+aMieiKgueCueWQjeWFs+mUruWtl+etm+mAie+8iOWPr+mAie+8iScpLFxuICAgICAgICAgICAgICAgICAgICBtYXhfZGVwdGg6IHoubnVtYmVyKCkub3B0aW9uYWwoKS5kZXNjcmliZSgn5pyA5aSn5bGV5byA5rex5bqm77yM6buY6K6kIDIw77yI5Y+v6YCJ77yJJyksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXN5bmMgKGFyZ3M6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub0NsaWVudCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfmuLjmiI/mnKrov57mjqXjgIInLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJlZSA9IGF3YWl0IGRlcHMuY2FsbEdhbWUoJ3F1ZXJ5LXRyZWUnLCB7IGZpbHRlcjogYXJncz8uZmlsdGVyID8/ICcnIH0sIDgwMDApO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHJlZSAmJiBBcnJheS5pc0FycmF5KHRyZWUucm9vdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZXB0aCA9IHR5cGVvZiBhcmdzPy5tYXhfZGVwdGggPT09ICdudW1iZXInID8gTWF0aC5tYXgoMSwgTWF0aC5taW4oNTAsIGFyZ3MubWF4X2RlcHRoKSkgOiAyMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBqc29uKHsgc2NlbmU6IHRyZWUuc2NlbmUgPz8gJycsIHJvb3RzOiBwcnVuZVRyZWUodHJlZS5yb290cywgZGVwdGgpIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfojrflj5boioLngrnmoJHlpLHotKXjgIInLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoYOiOt+WPluiKgueCueagkeWksei0pTogJHtTdHJpbmcoZXJyKX1gLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIG1jcC5yZWdpc3RlclRvb2woXG4gICAgICAgICAgICAnZ2V0X25vZGVfaW5mbycsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICfojrflj5boioLngrnkv6Hmga8nLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAn5oyJ6IqC54K5IGlkIOiOt+WPluiKgueCueivpuaDhe+8muS9jee9ri/ml4vovawv57yp5pS+L+a/gOa0uy/lsYLnuqfnrYkgVHJhbnNmb3JtIOWxnuaAp++8jOS7peWPiuaJgOaciee7hOS7tuWPiuWFtuWPr+e8lui+keWxnuaAp++8iOWQq+aemuS4vuOAgeaVsOe7hOOAgeWQkemHj+OAgeminOiJsuOAgeW8leeUqOetie+8ieOAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IHouc3RyaW5nKCkuZGVzY3JpYmUoJ+iKgueCuSBpZO+8iOadpeiHqiBnZXRfbm9kZV90cmVl77yJJyksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXN5bmMgKGFyZ3M6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub0NsaWVudCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfmuLjmiI/mnKrov57mjqXjgIInLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFhcmdzPy5pZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dCgn57y65bCR5Y+C5pWwIGlk44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBkZXBzLmNhbGxHYW1lKCdnZXQtaW5zcGVjdG9yJywgeyBpZDogYXJncy5pZCB9LCA4MDAwKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHIgJiYgci5lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoU3RyaW5nKHIuZXJyb3IpLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ganNvbihyID8/IHt9KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoYOiOt+WPluiKgueCueS/oeaBr+Wksei0pTogJHtTdHJpbmcoZXJyKX1gLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIG1jcC5yZWdpc3RlclRvb2woXG4gICAgICAgICAgICAnc2V0X25vZGVfcHJvcGVydHknLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRpdGxlOiAn5L+u5pS56L+Q6KGM5pe25bGe5oCnJyxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICAgICAgICAgJ+S/ruaUuei/kOihjOS4reiKgueCueeahOWxnuaAp+OAguiKgueCuee6p++8mmZpZWxkIOWPliBwb3NpdGlvbi9ldWxlci9zY2FsZe+8iHZhbHVlIOS4uiB7eCx5LHp977yJ44CBYWN0aXZl77yIdmFsdWUg5Li6IGJvb2xlYW7vvInjgIFsYXllcu+8iHZhbHVlIOS4uiBudW1iZXLvvInjgILnu4Tku7bnuqfvvJrkvKAgY29tcCDnu4Tku7bntKLlvJXvvIgwIOi1t++8ieS4jiBrZXkg5bGe5oCn5ZCN77yMdmFsdWUg5Li65bGe5oCn5YC877yI5ZCR6YePL+minOiJsuS8oOWvueixoe+8jOaemuS4vuS8oOaVsOWtl++8ieOAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IHouc3RyaW5nKCkuZGVzY3JpYmUoJ+iKgueCuSBpZO+8iOadpeiHqiBnZXRfbm9kZV90cmVl77yJJyksXG4gICAgICAgICAgICAgICAgICAgIGZpZWxkOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ+iKgueCuee6p+Wtl+aute+8mnBvc2l0aW9uIHwgZXVsZXIgfCBzY2FsZSB8IGFjdGl2ZSB8IGxheWVyJyksXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB6LmFueSgpLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ+imgeWGmeWFpeeahOWAvCcpLFxuICAgICAgICAgICAgICAgICAgICBjb21wOiB6Lm51bWJlcigpLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ+e7hOS7tue0ouW8le+8iDAg6LW377yM5LiOIGdldF9ub2RlX2luZm8g55qEIGNvbXBvbmVudHMg6aG65bqP5LiA6Ie077yJJyksXG4gICAgICAgICAgICAgICAgICAgIGtleTogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKCfnu4Tku7blsZ7mgKflkI0nKSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhc3luYyAoYXJnczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vQ2xpZW50KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoJ+a4uOaIj+acqui/nuaOpeOAgicsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWFyZ3M/LmlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfnvLrlsJHlj4LmlbAgaWTjgIInLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZDogYW55ID0geyBpZDogYXJncy5pZCB9O1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFyZ3MuZmllbGQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXlsb2FkLmZpZWxkID0gYXJncy5maWVsZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBhcmdzLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXJncy5jb21wID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5jb21wID0gYXJncy5jb21wO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5rZXkgPSBhcmdzLmtleTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBhcmdzLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBkZXBzLmNhbGxHYW1lKCdzZXQtcHJvcGVydHknLCBwYXlsb2FkLCA4MDAwKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHIgJiYgci5lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoU3RyaW5nKHIuZXJyb3IpLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ganNvbihyID8/IHsgb2s6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KGDkv67mlLnlsZ7mgKflpLHotKU6ICR7U3RyaW5nKGVycil9YCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBtY3AucmVnaXN0ZXJUb29sKFxuICAgICAgICAgICAgJ2dldF9zY3JlZW5zaG90JyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ+iOt+WPlua4uOaIj+aIquWbvicsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICfmipPlj5blvZPliY3muLjmiI/nlLvpnaLlubbov5Tlm57lm77niYfvvIhKUEVH77yJ77yM55So5LqO6KeG6KeJ6aqM6K+B5ri45oiP54q25oCB44CCJyxcbiAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe30pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobm9DbGllbnQoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dCgn5ri45oiP5pyq6L+e5o6l44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBkZXBzLmNhbGxHYW1lKCdjYXB0dXJlLWZyYW1lJywge30sIDYwMDApO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkYXRhVXJsID0gciAmJiB0eXBlb2Ygci5kYXRhID09PSAnc3RyaW5nJyA/IHIuZGF0YSA6ICcnO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBiYXNlNjQgPSBkYXRhVXJsLmluY2x1ZGVzKCcsJykgPyBkYXRhVXJsLnNwbGl0KCcsJylbMV0gOiBkYXRhVXJsO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWJhc2U2NCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoJ+aIquWbvuWksei0pe+8mua4uOaIj+S+p+acquiDveaNleiOt+eUu+mdouOAgicsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBbeyB0eXBlOiAnaW1hZ2UnLCBkYXRhOiBiYXNlNjQsIG1pbWVUeXBlOiAnaW1hZ2UvanBlZycgfV0sXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KGDmiKrlm77lpLHotKU6ICR7U3RyaW5nKGVycil9YCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBtY3AucmVnaXN0ZXJUb29sKFxuICAgICAgICAgICAgJ2dldF9sb2dzJyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ+iOt+WPlui/kOihjOaXtuaXpeW/lycsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICfojrflj5bmuLjmiI/kvqfmnIDov5HnmoTmjqfliLblj7Dml6Xlv5fvvIhjb25zb2xlLmxvZy93YXJuL2Vycm9y77yJ44CCbGV2ZWwg5Y+v6YCJIGxvZy93YXJuL2Vycm9y77yM6buY6K6k5YWo6YOo44CCJyxcbiAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgICAgICBsaW1pdDogei5udW1iZXIoKS5vcHRpb25hbCgpLmRlc2NyaWJlKCfov5Tlm57mnaHmlbDvvIzpu5jorqQgNTAnKSxcbiAgICAgICAgICAgICAgICAgICAgbGV2ZWw6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZSgn6L+H5ruk57qn5Yir77yaYWxsIHwgbG9nIHwgd2FybiB8IGVycm9yJyksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXN5bmMgKGFyZ3M6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxpbWl0ID0gdHlwZW9mIGFyZ3M/LmxpbWl0ID09PSAnbnVtYmVyJyA/IE1hdGgubWF4KDEsIE1hdGgubWluKDIwMCwgYXJncy5saW1pdCkpIDogNTA7XG4gICAgICAgICAgICAgICAgY29uc3QgbGV2ZWwgPSB0eXBlb2YgYXJncz8ubGV2ZWwgPT09ICdzdHJpbmcnID8gYXJncy5sZXZlbCA6ICdhbGwnO1xuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW1zID0gZGVwcy5nZXRMb2dzKGxpbWl0LCBsZXZlbCk7XG4gICAgICAgICAgICAgICAgaWYgKCFpdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoJ++8iOaaguaXoOaXpeW/l++8iScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBsaW5lcyA9IGl0ZW1zLm1hcCgoaXQ6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXQgJiYgaXQuZXZ0ID09PSAnY29uc29sZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhZyA9IGl0LmxldmVsID09PSAnZXJyb3InID8gJ0VSUk9SJyA6IGl0LmxldmVsID09PSAnd2FybicgPyAnV0FSTiAnIDogJ0xPRyAgJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtmbXRUKGl0LnQpfSBbJHt0YWd9XSAke2l0LnRleHR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoaXQgJiYgaXQuZXZ0ID09PSAnc3lzJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke2ZtdFQoaXQudCA/PyBEYXRlLm5vdygpKX0gW1NZU10gJHtpdC5tc2cgPz8gJyd9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoaXQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KGxpbmVzLmpvaW4oJ1xcbicpKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgbWNwLnJlZ2lzdGVyVG9vbChcbiAgICAgICAgICAgICd3YWl0JyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ+etieW+hScsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICfnrYnlvoXmjIflrprmr6vnp5LvvIgxLTYwMDAw77yJ77yM5bi455So5LqO562J5b6F5ri45oiP54q25oCB5Y+Y5YyW5ZCO5YaN5p+l6K+i44CCJyxcbiAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgICAgICBtczogei5udW1iZXIoKS5kZXNjcmliZSgn5q+r56eS5pWw77yMMS02MDAwMCcpLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFzeW5jIChhcmdzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBtcyA9IE1hdGgubWF4KDEsIE1hdGgubWluKDYwMDAwLCBOdW1iZXIoYXJncz8ubXMpIHx8IDApKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBtcykpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KGDlt7LnrYnlvoUgJHttc31tc2ApO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBtY3AucmVnaXN0ZXJUb29sKFxuICAgICAgICAgICAgJ2V4ZWN1dGVfY29tbWFuZCcsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICfmiafooYzmuLjmiI/lkb3ku6QnLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAn5ZCR5ri45oiP5L6n5qGl5o6l6ISa5pys5Y+R6YCB5Lu75oSP5ZG95Luk44CC5bi455So77yaZ2V0LXN0YXRz44CBZ2V0LXJlc291cmNlLXN0YXRz44CBcXVlcnktcGh5c2ljc+OAgXNldC1wcmV2aWV3KHtlbmFibGVkLGZwc30p44CBc2V0LW11dGUoe211dGVkfSnjgIFzZXQtcGh5c2ljcy1kZWJ1Zyh7ZW5hYmxlZH0p44CCJyxcbiAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgICAgICBjbWQ6IHouc3RyaW5nKCkuZGVzY3JpYmUoJ+WRveS7pOWQjScpLFxuICAgICAgICAgICAgICAgICAgICBwYXlsb2FkOiB6LmFueSgpLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ+WRveS7pOWPguaVsO+8iOWPr+mAie+8iScpLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFzeW5jIChhcmdzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobm9DbGllbnQoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dCgn5ri45oiP5pyq6L+e5o6l44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghYXJncz8uY21kKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfnvLrlsJHlj4LmlbAgY21k44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBkZXBzLmNhbGxHYW1lKFN0cmluZyhhcmdzLmNtZCksIGFyZ3MucGF5bG9hZCwgODAwMCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBqc29uKHIgPz8ge30pO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dChg5ZG95Luk5omn6KGM5aSx6LSlOiAke1N0cmluZyhlcnIpfWAsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgbWNwLnJlZ2lzdGVyVG9vbChcbiAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICfmqKHmi5/ngrnlh7snLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAn5qih5ouf5LiA5qyh6Kem5pG454K55Ye744CC5LygIGlkIOWImeeCueWHu+ivpeiKgueCue+8iOWPluWFtiBVSSDkuK3lv4PngrnvvInvvJvkvKAgeC95IOWImeeCueWHu+Wxj+W5le+8iFVJIOWdkOagh++8ieS4iuWRveS4reeahOacgOS4iuWxguiKgueCueOAguW4uOeUqOS6juinpuWPkeaMiemSruOAgeW8gOWni+a4uOaIj+etieaTjeS9nOOAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZSgn6IqC54K5IGlk77yI5p2l6IeqIGdldF9ub2RlX3RyZWXvvIknKSxcbiAgICAgICAgICAgICAgICAgICAgeDogei5udW1iZXIoKS5vcHRpb25hbCgpLmRlc2NyaWJlKCdVSSDmqKrlnZDmoIfvvIjkuI4gaWQg5LqM6YCJ5LiA77yJJyksXG4gICAgICAgICAgICAgICAgICAgIHk6IHoubnVtYmVyKCkub3B0aW9uYWwoKS5kZXNjcmliZSgnVUkg57q15Z2Q5qCH77yI5LiOIGlkIOS6jOmAieS4gO+8iScpLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFzeW5jIChhcmdzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobm9DbGllbnQoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dCgn5ri45oiP5pyq6L+e5o6l44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghYXJncz8uaWQgJiYgKHR5cGVvZiBhcmdzPy54ICE9PSAnbnVtYmVyJyB8fCB0eXBlb2YgYXJncz8ueSAhPT0gJ251bWJlcicpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfpnIDopoHlj4LmlbAgaWTvvIjoioLngrkgaWTvvInmiJYgeC9577yIVUkg5Z2Q5qCH77yJ44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQ6IGFueSA9IHt9O1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFyZ3MuaWQgPT09ICdzdHJpbmcnICYmIGFyZ3MuaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQuaWQgPSBhcmdzLmlkO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC54ID0gYXJncy54O1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC55ID0gYXJncy55O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBkZXBzLmNhbGxHYW1lKCdzaW11bGF0ZS1jbGljaycsIHBheWxvYWQsIDgwMDApO1xuICAgICAgICAgICAgICAgICAgICBpZiAociAmJiByLmVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dChTdHJpbmcoci5lcnJvciksIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBqc29uKHIgPz8geyBvazogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoYOaooeaLn+eCueWHu+Wksei0pTogJHtTdHJpbmcoZXJyKX1gLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIG1jcC5yZWdpc3RlclRvb2woXG4gICAgICAgICAgICAnbGlzdF9zY2VuZXMnLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRpdGxlOiAn5YiX5Ye65Zy65pmvJyxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ+WIl+WHuuW9k+WJjei/kOihjOWcuuaZr+WPiuW3suWKoOi9veWcuuaZr+WQje+8jOeUqOS6juehruiupOi3s+i9rOebruagh+OAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHt9KSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vQ2xpZW50KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoJ+a4uOaIj+acqui/nuaOpeOAgicsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByID0gYXdhaXQgZGVwcy5jYWxsR2FtZSgnbGlzdC1zY2VuZXMnLCB7fSwgNjAwMCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBqc29uKHIgPz8geyBjdXJyZW50OiAnJywgc2NlbmVzOiBbXSB9KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoYOWIl+WHuuWcuuaZr+Wksei0pTogJHtTdHJpbmcoZXJyKX1gLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIG1jcC5yZWdpc3RlclRvb2woXG4gICAgICAgICAgICAnbG9hZF9zY2VuZScsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICfot7PovazlnLrmma8nLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAn6L+Q6KGM5pe25Yqg6L295oyH5a6a5ZCN56ew55qE5Zy65pmv77yI5Zy65pmv6Lez6L2s77yJ44CC5Zy65pmv5ZCN5Y+v5YWI6YCa6L+HIGxpc3Rfc2NlbmVzIOafpeeci+OAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogei5zdHJpbmcoKS5kZXNjcmliZSgn5Zy65pmv5ZCNJyksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXN5bmMgKGFyZ3M6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub0NsaWVudCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfmuLjmiI/mnKrov57mjqXjgIInLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFhcmdzPy5uYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfnvLrlsJHlj4LmlbAgbmFtZeOAgicsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByID0gYXdhaXQgZGVwcy5jYWxsR2FtZSgnbG9hZC1zY2VuZScsIHsgbmFtZTogU3RyaW5nKGFyZ3MubmFtZSkgfSwgNjAwMCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyICYmIHIuZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KFN0cmluZyhyLmVycm9yKSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGpzb24ociA/PyB7IG9rOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dChg6Lez6L2s5Zy65pmv5aSx6LSlOiAke1N0cmluZyhlcnIpfWAsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIG1jcDtcbiAgICB9XG5cbiAgICAvKiog5ZCv5YqoIEhUVFAg5pyN5Yqh44CCcG9ydCDooqvljaDnlKjml7bmipvplJnjgIIgKi9cbiAgICBhc3luYyBzdGFydChwb3J0OiBudW1iZXIsIHRva2VuOiBzdHJpbmcsIGRlcHM6IE1jcERlcHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMuc3J2KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50b2tlbiA9IHRva2VuO1xuICAgICAgICB0aGlzLmRlcHMgPSBkZXBzO1xuICAgICAgICBjb25zdCBzcnYgPSBodHRwLmNyZWF0ZVNlcnZlcigocmVxLCByZXMpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlKHJlcSwgcmVzKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgLyogaGFuZGxlZCBpbnNpZGUgKi9cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb25FcnJvciA9IChlcnI6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgc3J2LnJlbW92ZUxpc3RlbmVyKCdsaXN0ZW5pbmcnLCBvbkxpc3RlbmluZyk7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3Qgb25MaXN0ZW5pbmcgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgc3J2LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzcnYub25jZSgnZXJyb3InLCBvbkVycm9yKTtcbiAgICAgICAgICAgIHNydi5vbmNlKCdsaXN0ZW5pbmcnLCBvbkxpc3RlbmluZyk7XG4gICAgICAgICAgICBzcnYubGlzdGVuKHBvcnQsICcxMjcuMC4wLjEnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc3J2ID0gc3J2O1xuICAgICAgICB0aGlzLnBvcnQgPSBwb3J0O1xuICAgIH1cblxuICAgIC8qKiDlgZzmraLmnI3liqHlubblhbPpl63miYDmnInkvJror53jgIIgKi9cbiAgICBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBzcnYgPSB0aGlzLnNydjtcbiAgICAgICAgdGhpcy5zcnYgPSBudWxsO1xuICAgICAgICB0aGlzLnBvcnQgPSAwO1xuICAgICAgICB0aGlzLmRlcHMgPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IHsgdHJhbnNwb3J0IH0gb2YgdGhpcy5zZXNzaW9ucy52YWx1ZXMoKSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgIC8qIGlnbm9yZSAqL1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2Vzc2lvbnMuY2xlYXIoKTtcbiAgICAgICAgaWYgKHNydikge1xuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHNydi5jbG9zZSgoKSA9PiByZXNvbHZlKCkpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==