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.
1658 lines
270 KiB
1658 lines
270 KiB
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
// @ts-ignore
|
|
const package_json_1 = __importDefault(require("../../../../package.json"));
|
|
/**
|
|
* 预览:地址读取/刷新/连通性探测 + 无 iframe 的 DOM 渲染 + 左右分隔条拖拽。
|
|
*
|
|
* 面板内直接渲染游戏(不用 iframe)的加载链路:
|
|
* 1. 按序加载引擎脚本(<script> 标签跨域加载 JS 不受 CORS 限制)
|
|
* 2. import-map 内的相对/绝对路径基于「面板 origin」解析会 404,
|
|
* 因此先读取原始 map 内容,把所有路径重写为预览服务绝对 URL 后再注入
|
|
* 3. 最终 System.import(preview-app) 与引擎内部 fetch 资源属于跨域请求,
|
|
* 是否成功取决于预览服务器是否返回 CORS 头(实测验证点)
|
|
*/
|
|
/** socket.io 最小 stub:EventEmitter 语义,满足 preview-app 的 n.on()/t.emit() 调用。
|
|
* 不发起真实 socket.io 连接(面板 origin 与预览服务不一致,连接必然失败且无意义)。 */
|
|
function socketIoStub() {
|
|
const handlers = {};
|
|
return {
|
|
on(evt, fn) {
|
|
(handlers[evt] = handlers[evt] || []).push(fn);
|
|
return this;
|
|
},
|
|
off(evt) {
|
|
delete handlers[evt];
|
|
return this;
|
|
},
|
|
emit(evt, ...args) {
|
|
(handlers[evt] || []).slice().forEach((fn) => fn(...args));
|
|
return this;
|
|
},
|
|
close() {
|
|
for (const k of Object.keys(handlers)) {
|
|
delete handlers[k];
|
|
}
|
|
},
|
|
};
|
|
}
|
|
/** 设备尺寸表(键与真实预览服务渲染的 data-device 完全一致)。
|
|
* 面板内 exactFitScreen=false(SubFrame)模式下引擎画布跟随 #GameDiv 容器尺寸、
|
|
* 忽略 screen.windowSize,因此设备切换要在前端把 #GameDiv 设成目标比例居中显示。
|
|
* 精简集:每档只留一个代表机型,分辨率不重复;键必须能被 preview-app._devices 识别。 */
|
|
const DEVICE_SIZES = {
|
|
'Default': { w: 960, h: 640, label: '设计分辨率' },
|
|
'Apple iPhone 12; 13; 14; 12/13 Pro': { w: 390, h: 844, label: 'iPhone 12/13/14' },
|
|
'Apple iPhone 14 Pro': { w: 393, h: 852, label: 'iPhone 14 Pro' },
|
|
'Apple iPhone 12/13 Pro Max; 14 Plus': { w: 428, h: 926, label: 'iPhone Pro Max/14 Plus' },
|
|
'Apple iPhone XR; 11': { w: 414, h: 896, label: 'iPhone XR/11' },
|
|
'Apple iPhone X; XS; 11 Pro; 12/13 Mini': { w: 375, h: 812, label: 'iPhone X/XS' },
|
|
'Apple iPad 10.2': { w: 1620, h: 2160, label: 'iPad 10.2' },
|
|
'HUAWEI Mate 40 Pro': { w: 448, h: 924, label: 'HUAWEI Mate 40 Pro' },
|
|
'OPPO Reno 2': { w: 360, h: 800, label: 'OPPO Reno 2' },
|
|
'Xiaomi Redmi 8': { w: 360, h: 760, label: 'Xiaomi Redmi 8' },
|
|
'Lenovo Legion 2 Pro': { w: 360, h: 820, label: 'Lenovo Legion 2 Pro' },
|
|
};
|
|
exports.default = {
|
|
async initPreviewInfo() {
|
|
// 设计分辨率默认 960×640,随后用项目真实配置覆盖(Default 等比视口以此为基准)
|
|
this.prefDesignW = 960;
|
|
this.prefDesignH = 640;
|
|
try {
|
|
const [info, proj] = await Promise.all([
|
|
Editor.Message.request(package_json_1.default.name, 'get-preview-info'),
|
|
Editor.Message.request(package_json_1.default.name, 'get-projects-settings'),
|
|
]);
|
|
if (info && info.url) {
|
|
this.previewUrl = info.url;
|
|
}
|
|
const d = proj && proj.designResolution;
|
|
if (d && Number(d.width) > 0 && Number(d.height) > 0) {
|
|
this.prefDesignW = Number(d.width);
|
|
this.prefDesignH = Number(d.height);
|
|
}
|
|
}
|
|
catch (_a) {
|
|
// 保持默认地址/分辨率
|
|
}
|
|
},
|
|
/** 当前项目设计分辨率(读取失败回到 960×640)。 */
|
|
prefDesign() {
|
|
return {
|
|
w: Number(this.prefDesignW) > 0 ? Number(this.prefDesignW) : 960,
|
|
h: Number(this.prefDesignH) > 0 ? Number(this.prefDesignH) : 640,
|
|
};
|
|
},
|
|
/** 地址栏回车 / 点「刷新」/ 遮罩重试:重新渲染游戏画面。 */
|
|
onLoadPreview() {
|
|
this.previewLoaded = false;
|
|
this.previewRenderErr = '';
|
|
this.renderPreview();
|
|
},
|
|
// ===== 预览工具条:新版面工具条通过驱动「隐藏 H5 工具条」与引擎联动 =====
|
|
// 引擎 preview-app 用 document.querySelector('#view-select'/'#btn-rotate'/'#input-set-fps'/
|
|
// '#btn-show-fps'/'#btn-pause'/'#btn-step') 绑定事件,面板内的该工具条被 CSS 隐藏,
|
|
// 只作数据契约。这里用真实 DOM 事件模拟用户操作,与手点效果一致。
|
|
/** 设备/分辨率切换:点选隐藏 #view-select 的对应选项。 */
|
|
onPreviewDevice(device) {
|
|
this.previewDevice = device;
|
|
const el = document.querySelector('#view-select');
|
|
if (!el)
|
|
return;
|
|
el.setAttribute('value', device);
|
|
const name = el.querySelector('#name');
|
|
if (name)
|
|
name.textContent = device;
|
|
el.querySelectorAll('.options li').forEach((li) => {
|
|
if (li.getAttribute('data-device') === device) {
|
|
li.classList.add('selected');
|
|
li.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));
|
|
li.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, cancelable: true }));
|
|
li.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
|
|
}
|
|
else {
|
|
li.classList.remove('selected');
|
|
}
|
|
});
|
|
// 面板内 SubFrame 模式引擎画布跟随 #GameDiv 容器尺寸,设备切换需在此设容器比例,
|
|
// 否则 preview-app 只改 screen.windowSize 不产生视觉变化(真实 H5 才生效)。
|
|
this.applyDeviceViewport(device);
|
|
},
|
|
/** 设备/缩放视口:把 #GameDiv 设成 设备比例 × 缩放因子 的真实尺寸并居中。
|
|
* 引擎 SubFrame 模式按 #GameDiv 实际尺寸重建画布,因此画面比例与输入映射始终一致,
|
|
* 任意缩放比下点击都不会错位。横竖屏方向(previewRotated)交换宽高。
|
|
* 非尺寸映射(FullScreen/Webpage)回到铺满、不应用缩放。 */
|
|
applyDeviceViewport(device, zoom = this.previewZoom) {
|
|
const gd = document.getElementById('GameDiv');
|
|
if (!gd)
|
|
return;
|
|
let d = DEVICE_SIZES[device];
|
|
const host = document.getElementById('yyka-game-host');
|
|
if (!d || !host) {
|
|
gd.style.width = '';
|
|
gd.style.height = '';
|
|
gd.style.margin = '';
|
|
window.dispatchEvent(new Event('resize'));
|
|
return;
|
|
}
|
|
if (device === 'Default') {
|
|
// 设计分辨率取项目真实配置(勿用固定 960×640)
|
|
const pd = this.prefDesign();
|
|
d = { w: pd.w, h: pd.h, label: '设计分辨率' };
|
|
}
|
|
let dw = d.w, dh = d.h;
|
|
if (this.previewRotated) {
|
|
dw = d.h;
|
|
dh = d.w; // 竖屏 ↔ 横屏,交换宽高
|
|
}
|
|
// 预览区(.game-view)基准,等比放入该设备(zoom=1 恰好放入)。
|
|
// 设备模式只留 12px 外边距,外壳尽量大,让游戏窗口撑满壳内部、四角被圆角裁切成全面屏;
|
|
// Default 留 32px。
|
|
const isDev = device !== 'Default' && !!d;
|
|
const pad = isDev ? 12 : 32;
|
|
const aw = Math.max(1, host.clientWidth - pad);
|
|
const ah = Math.max(1, host.clientHeight - pad);
|
|
let w = aw, h = aw * (dh / dw);
|
|
if (h > ah) {
|
|
h = ah;
|
|
w = ah * (dw / dh);
|
|
}
|
|
const z = Math.max(0.2, Math.min(8, zoom));
|
|
const winW = Math.max(10, w * z), winH = Math.max(10, h * z);
|
|
const frame = host.querySelector('.device-frame');
|
|
const isDevice = !!d && device !== 'Default';
|
|
if (frame)
|
|
frame.classList.toggle('device', isDevice);
|
|
if (isDevice && frame) {
|
|
// 真机比例:屏幕(#GameDiv)按设备宽高比尽量放大居中;外壳跟随屏幕,
|
|
// 边框贴着屏幕四周一起缩放(外壳尺寸 = 屏幕 + 细边框)。
|
|
// 旋转(previewRotated)已在 dw/dh 交换过,因此外壳形状会随横竖屏变化。
|
|
const bezX = 42, bezY = 54; // 预留余量:外壳整体在预览区内缩一圈,四周露出背景,避免贴平成"平面"
|
|
const mw = host.clientWidth, mh = host.clientHeight;
|
|
let sw = mw - bezX, sh = sw * (dh / dw);
|
|
if (sh > mh - bezY) {
|
|
sh = mh - bezY;
|
|
sw = sh * (dw / dh);
|
|
}
|
|
let fw = sw * z, fh = sh * z;
|
|
// 缩放上限:放大时整体不超出预览视口,四周留 effPad 余地,等比收缩防溢出
|
|
const effPad = 12;
|
|
const maxW = mw - effPad, maxH = mh - effPad;
|
|
if (fw > maxW || fh > maxH) {
|
|
const r = Math.min(maxW / fw, maxH / fh);
|
|
fw *= r;
|
|
fh *= r;
|
|
}
|
|
frame.style.width = Math.max(20, Math.round(fw)) + 'px';
|
|
frame.style.height = Math.max(20, Math.round(fh)) + 'px';
|
|
frame.style.margin = 'auto';
|
|
gd.style.width = '100%';
|
|
gd.style.height = '100%';
|
|
gd.style.margin = '0';
|
|
// 灵动岛随缩放联动:取机身短边的一定比例作为宽度,
|
|
// 横竖屏(短边不变)尺寸稳定,缩放大小时同步缩放(使用像素避免横屏相对放大)。
|
|
const iso = frame.querySelector('.dynamic-island');
|
|
if (iso) {
|
|
iso.style.width = Math.max(24, Math.round(Math.min(fw, fh) * 0.26)) + 'px';
|
|
}
|
|
}
|
|
else {
|
|
// 普通/Default 视口:按设计分辨率等比居中,同样限幅不超视口并留边距。
|
|
// 尺寸载体用 .device-frame 外壳而非 #GameDiv:面板 CSS 对 #GameDiv 有
|
|
// width/height:100%!important,写在其上的内联像素不生效;若外壳保持
|
|
// max-content,整条链会回落成 canvas 元素固有尺寸(引擎把 canvas.width
|
|
// 设成 screen.windowSize = #GameDiv.clientWidth×dpr,dpr>1 时不断放大),
|
|
// 导致游戏窗口比视口大、被裁剪。给外壳写确定的 fit 像素后 #GameDiv=100%
|
|
// 跟随,尺寸完全确定,不再有 max-content 反馈放大(与设备模式同构)。
|
|
const effPad = 32;
|
|
const maxW = host.clientWidth - effPad, maxH = host.clientHeight - effPad;
|
|
let winW2 = w * z, winH2 = h * z;
|
|
if (winW2 > maxW || winH2 > maxH) {
|
|
const r = Math.min(maxW / winW2, maxH / winH2);
|
|
winW2 *= r;
|
|
winH2 *= r;
|
|
}
|
|
const pxW = Math.max(20, Math.round(winW2)) + 'px';
|
|
const pxH = Math.max(20, Math.round(winH2)) + 'px';
|
|
if (frame) {
|
|
frame.style.width = pxW;
|
|
frame.style.height = pxH;
|
|
frame.style.margin = 'auto';
|
|
gd.style.width = '100%';
|
|
gd.style.height = '100%';
|
|
gd.style.margin = '0';
|
|
}
|
|
else {
|
|
gd.style.width = pxW;
|
|
gd.style.height = pxH;
|
|
gd.style.margin = 'auto';
|
|
}
|
|
}
|
|
// 引擎画面铺满策略:设备模式精确铺满(屏幕顶满边框内缘,无内部黑边),
|
|
// 普通/Default 保持等比适配。screen._exactFitScreen 由 Cocos SubFrame adapter 读取。
|
|
try {
|
|
const ccw = window.cc || window.cclegacy;
|
|
const sc = ccw && (ccw.screen || (ccw.game && ccw.game.screen));
|
|
const targets = sc ? [sc, sc.screenAdapter] : [];
|
|
for (const t of targets) {
|
|
if (t && '_exactFitScreen' in t)
|
|
t._exactFitScreen = !!isDevice;
|
|
}
|
|
}
|
|
catch (_) {
|
|
/* 引擎未就绪时忽略 */
|
|
}
|
|
window.dispatchEvent(new Event('resize'));
|
|
},
|
|
/** 强制走 SubFrame 视口(画布跟随 #GameDiv 尺寸,避免用整窗尺寸生成过大的画布导致
|
|
* 画面比视口大/被裁剪)。批量覆盖所有已知 screenAdapter 来源,并重试等待 System 异步
|
|
* 模块就绪;每成功覆盖一次即重放视口 + 触发 resize 重算。 */
|
|
async forceSubFrameViewport(alive) {
|
|
const apply = (adapter) => {
|
|
if (adapter && '_exactFitScreen' in adapter && adapter._exactFitScreen !== false) {
|
|
adapter._exactFitScreen = false;
|
|
}
|
|
};
|
|
// 1) 同步来源:window.cc.screen 及其 screenAdapter
|
|
const ccw = window.cc || window.cclegacy;
|
|
if (ccw && ccw.screen) {
|
|
apply(ccw.screen);
|
|
apply(ccw.screen.screenAdapter);
|
|
apply(ccw.game && ccw.game.screen);
|
|
apply(ccw.game && ccw.game.screen.screenAdapter);
|
|
}
|
|
// 2) 异步来源:System.import 得到的真实 screenAdapter,重试直至可用或超时(刷新前返回)
|
|
const SysMod = window.System;
|
|
const deadline = Date.now() + 3000;
|
|
while (alive() && Date.now() < deadline) {
|
|
let got = false;
|
|
if (SysMod && typeof SysMod.import === 'function') {
|
|
try {
|
|
const saMod = await SysMod.import('q-bundled:///fs/pal/screen-adapter/web/screen-adapter.js');
|
|
const sa = (saMod && (saMod.screenAdapter || (saMod.default && saMod.default.screenAdapter))) || null;
|
|
if (sa) {
|
|
apply(sa);
|
|
got = true;
|
|
}
|
|
}
|
|
catch (_a) {
|
|
/* 模块未就绪,继续重试 */
|
|
}
|
|
}
|
|
if (got)
|
|
break;
|
|
await new Promise((r) => setTimeout(r, 120));
|
|
}
|
|
if (alive()) {
|
|
this.applyDeviceViewport(this.previewDevice || 'Default');
|
|
window.dispatchEvent(new Event('resize'));
|
|
}
|
|
},
|
|
onPreviewRotate() {
|
|
const btn = document.querySelector('#btn-rotate');
|
|
if (btn)
|
|
btn.click();
|
|
this.previewRotated = !this.previewRotated; // 面板侧视觉指示
|
|
// 设备/默认视口模式下旋转后按新方向重算 #GameDiv 比例
|
|
if (this.previewDevice && DEVICE_SIZES[this.previewDevice]) {
|
|
this.applyDeviceViewport(this.previewDevice);
|
|
}
|
|
this.syncPreviewState();
|
|
},
|
|
/** 帧率上限设置:写隐藏 #input-set-fps 并派发 input/change。 */
|
|
onPreviewFps(val) {
|
|
const n = Math.max(1, Math.min(240, Number(val) || 60));
|
|
this.previewFps = n;
|
|
const inp = document.querySelector('#input-set-fps');
|
|
if (inp) {
|
|
inp.value = String(n);
|
|
inp.dispatchEvent(new Event('input', { bubbles: true }));
|
|
inp.dispatchEvent(new Event('change', { bubbles: true }));
|
|
}
|
|
},
|
|
/** 显示FPS开关:触发隐藏 #btn-show-fps 并回读激活态。 */
|
|
onPreviewShowFps() {
|
|
const btn = document.querySelector('#btn-show-fps');
|
|
if (btn)
|
|
btn.click();
|
|
this.syncPreviewState();
|
|
},
|
|
/** 暂停/继续:触发隐藏 #btn-pause。 */
|
|
onPreviewPause() {
|
|
const btn = document.querySelector('#btn-pause');
|
|
if (btn)
|
|
btn.click();
|
|
this.syncPreviewState();
|
|
},
|
|
/** 步进一帧:仅暂停态可用,触发隐藏 #btn-step。 */
|
|
onPreviewStep() {
|
|
const btn = document.querySelector('#btn-step');
|
|
if (btn)
|
|
btn.click();
|
|
},
|
|
// ─────────── 窗囗级全局静音(default / 预览面板共享)───────────
|
|
onPreviewMute() {
|
|
this.previewMuted = !this.previewMuted;
|
|
this._applyMute();
|
|
},
|
|
/** 确保 context 有 master gain(如无则注入),并返回它。 */
|
|
_ensureMaster(c) {
|
|
if (!c || c.__yykaMaster)
|
|
return c && c.__yykaMaster;
|
|
try {
|
|
const mg = c.createGain();
|
|
c.__yykaMaster = mg;
|
|
const list = this.__muteCtxs();
|
|
if (list.indexOf(c) < 0)
|
|
list.push(c);
|
|
return mg;
|
|
}
|
|
catch (_) {
|
|
return null;
|
|
}
|
|
},
|
|
/** context 采集列表(模块级,换场景/重渲染保持)。 */
|
|
__muteCtxs() {
|
|
const key = '__yykaAudioCtxs';
|
|
const w = window;
|
|
if (!w[key])
|
|
w[key] = [];
|
|
return w[key];
|
|
},
|
|
/** 全局静音标志:进入静音前先把当前实例状态写进全局,供 connect 劫持读取。 */
|
|
__muteGlobal() {
|
|
const key = '__yykaGlobalMute';
|
|
const w = window;
|
|
return { get: () => !!w[key], set: (v) => { w[key] = v; } };
|
|
},
|
|
/** 应用静音到单个 context:master gain 实时开关(g=0 无声 / g=1 有声)。 */
|
|
_applyMuteToCtx(c, muted) {
|
|
try {
|
|
if (!c)
|
|
return;
|
|
if (c.__yykaMaster) {
|
|
c.__yykaMaster.gain.value = muted ? 0 : 1;
|
|
}
|
|
else if (c.createGain) {
|
|
const mg = this._ensureMaster(c);
|
|
if (mg) {
|
|
mg.gain.value = muted ? 0 : 1;
|
|
try {
|
|
mg.connect(c.destination);
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
}
|
|
}
|
|
if (!muted && typeof c.resume === 'function' && c.state === 'suspended') {
|
|
try {
|
|
c.resume();
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
}
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
},
|
|
/** 应用全局静音:写标志 + 引擎音量 + 全部 context master gain + 媒体元素。无轮询。 */
|
|
_applyMute() {
|
|
const muted = !!this.previewMuted;
|
|
this.__muteGlobal().set(muted);
|
|
const lg = window.cc || window.cclegacy;
|
|
const ae = lg && (lg.AudioEngine || (lg.audio && lg.audio.AudioEngine));
|
|
if (ae) {
|
|
try {
|
|
if (typeof ae.setMusicVolume === 'function')
|
|
ae.setMusicVolume(muted ? 0 : 1);
|
|
if (typeof ae.setEffectsVolume === 'function')
|
|
ae.setEffectsVolume(muted ? 0 : 1);
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
}
|
|
const ctxs = this.__muteCtxs();
|
|
for (const c of ctxs)
|
|
this._applyMuteToCtx(c, muted);
|
|
try {
|
|
document.querySelectorAll('audio, video').forEach((el) => {
|
|
try {
|
|
el.muted = muted;
|
|
if (muted)
|
|
el.pause();
|
|
else
|
|
el.play().catch(() => { });
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
});
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
},
|
|
/**
|
|
* 安装窗囗级音频静音 hook(事件驱动,无轮询):
|
|
* 1) 包装 AudioContext 构造器:新建即挂 master 并采集;
|
|
* 2) 劫持 AudioNode.prototype.connect:任何节点连到 context.destination 时接进 master gain。
|
|
* 即使引擎复用模块级缓存的原始 context 单例,connect 时也会动态注入 master,
|
|
* 声音必经 master,g=0 立即无声(攻击音效瞬时哑,无需轮询)。
|
|
*/
|
|
_hookAudioCtx() {
|
|
const w = window;
|
|
const selfRef = this;
|
|
const hijackConnect = (NodeCtor) => {
|
|
if (!NodeCtor || NodeCtor.__yykaConnHook)
|
|
return;
|
|
NodeCtor.__yykaConnHook = true;
|
|
const orig = NodeCtor.prototype.connect;
|
|
NodeCtor.prototype.connect = function (dest, ...rest) {
|
|
try {
|
|
const ctx = this && this.context;
|
|
// master 节点自身连到输出时要放行(直连 destination),否则会把自己
|
|
// 重定向到自身形成自连,音频图被破坏→永久静音(无论开关状态)。
|
|
if (ctx && this === ctx.__yykaMaster) {
|
|
return orig.apply(this, [dest, ...rest]);
|
|
}
|
|
if (ctx && ctx.destination && dest === ctx.destination) {
|
|
let mg = ctx.__yykaMaster;
|
|
if (!mg && ctx.createGain) {
|
|
mg = ctx.createGain();
|
|
ctx.__yykaMaster = mg;
|
|
const list = selfRef.__muteCtxs();
|
|
if (list.indexOf(ctx) < 0)
|
|
list.push(ctx);
|
|
try {
|
|
orig.call(mg, ctx.destination);
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
}
|
|
if (mg) {
|
|
mg.gain.value = selfRef.__muteGlobal().get() ? 0 : 1;
|
|
dest = mg;
|
|
}
|
|
}
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
return orig.apply(this, [dest, ...rest]);
|
|
};
|
|
};
|
|
const AudioNodeCtor = w.AudioNode;
|
|
if (AudioNodeCtor) {
|
|
try {
|
|
hijackConnect(AudioNodeCtor);
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
}
|
|
const wrapCtor = (Ctor, name) => {
|
|
if (!Ctor || Ctor.__patchYyka)
|
|
return;
|
|
const Old = Ctor;
|
|
const Self = function (...a) {
|
|
const c = new Old(...a);
|
|
try {
|
|
const mg = selfRef._ensureMaster(c);
|
|
if (mg) {
|
|
mg.connect(c.destination);
|
|
mg.gain.value = selfRef.__muteGlobal().get() ? 0 : 1;
|
|
}
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
return c;
|
|
};
|
|
Self.prototype = Old.prototype;
|
|
Self.__patchYyka = true;
|
|
w[name] = Self;
|
|
};
|
|
wrapCtor(w.AudioContext, 'AudioContext');
|
|
wrapCtor(w.webkitAudioContext, 'webkitAudioContext');
|
|
try {
|
|
const OE = document.createElement.bind(document);
|
|
document.createElement = function (tag, ...rest) {
|
|
const el = OE(tag, ...rest);
|
|
const t = String(tag).toLowerCase();
|
|
if (t === 'audio' || t === 'video') {
|
|
try {
|
|
if (selfRef.__muteGlobal().get())
|
|
el.muted = true;
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
}
|
|
return el;
|
|
};
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
},
|
|
/** 刷新预览:重置缩放并重新渲染。 */
|
|
doRefreshPreview() {
|
|
this.previewZoom = 1;
|
|
this.previewLoaded = false;
|
|
this.previewRenderErr = '';
|
|
this.renderPreview();
|
|
},
|
|
/** 重渲染前拆解上一次游戏实例:停主循环、清调度器(计时器/update)、停音频、释放资源。
|
|
* 面板内无法像浏览器预览那样整页 reload,cc 全局是单例,旧实例若不清理,
|
|
* 刷新后音乐/计时器/主循环会残留叠加、不关闭面板就无法复原。
|
|
* 每步单独 try/catch 以防某 API 缺失/报错阻断重载流程。 */
|
|
teardownPreview() {
|
|
const lg = window.cc || window.cclegacy;
|
|
if (!lg || !lg.game)
|
|
return; // 首次渲染尚无实例,跳过
|
|
const stop = (fn) => {
|
|
try {
|
|
fn();
|
|
}
|
|
catch (_) {
|
|
/* 忽略单个清理失败 */
|
|
}
|
|
};
|
|
// 停主循环更新(暂停 update/游戏逻辑)
|
|
const g = lg.game;
|
|
stop(() => g.pause && g.pause());
|
|
stop(() => g.pauseByEngine && g.pauseByEngine());
|
|
// 停 director 更新
|
|
const dir = lg.director;
|
|
stop(() => dir.pause && dir.pause());
|
|
// 清调度器:项目用 scheduleOnce/setTimeout 等定时器
|
|
stop(() => {
|
|
const sch = dir && dir.getScheduler && dir.getScheduler();
|
|
sch && sch.unscheduleAll && sch.unscheduleAll();
|
|
});
|
|
// 停止音频(项目音乐/音效,AudioEngine 全局 close 停全部)
|
|
stop(() => {
|
|
const ae = lg.AudioEngine || (lg.audio && lg.audio.AudioEngine);
|
|
ae && ae.close && ae.close();
|
|
});
|
|
// 释放已加载资源,避免新场景复用旧资源句柄造成叠加
|
|
stop(() => lg.assetManager && lg.assetManager.releaseAll && lg.assetManager.releaseAll());
|
|
},
|
|
/** 从隐藏 H5 工具条回读状态,同步面板按钮激活态(loading 完整后调用一次 + 每次操作后)。 */
|
|
syncPreviewState() {
|
|
const showReady = () => {
|
|
const show = document.querySelector('#btn-show-fps');
|
|
const pause = document.querySelector('#btn-pause');
|
|
const step = document.querySelector('#btn-step');
|
|
let paused = false;
|
|
if (pause)
|
|
paused = pause.classList.contains('checked');
|
|
if (!paused && step)
|
|
paused = getComputedStyle(step).display !== 'none';
|
|
this.previewShowFps = !!(show && show.classList.contains('checked'));
|
|
this.previewPaused = paused;
|
|
};
|
|
// 等待 #GameCanvas 就绪后再读;宿主重建瞬间可能取到空 DOM
|
|
const waitFor = () => {
|
|
if (document.querySelector('#btn-pause')) {
|
|
showReady();
|
|
}
|
|
else {
|
|
window.setTimeout(waitFor, 60);
|
|
}
|
|
};
|
|
waitFor();
|
|
},
|
|
/** 预览区滚轮缩放:调整缩放因子并重算 #GameDiv 真实尺寸(等比放大缩小,居中)。
|
|
* 用对称乘法步进(放大 ×1.12 / 缩小 ÷1.12)保证可逆;引擎按容器尺寸重建画布,
|
|
* 因此放大缩小过程输入映射始终正确,不会出现放大了点不到的情况。 */
|
|
onPreviewWheel(e) {
|
|
e.preventDefault();
|
|
// 关键:拦截滚轮传播。否则事件还会继续传到本插件加载的编辑器 preview-app
|
|
// Ui(其滚轮处理器会把设计分辨率重置成默认横屏 960×640,导致竖屏变横屏)。
|
|
// 这里在捕获阶段阻止冒泡到内容层,保证只由我们自己的 applyDeviceViewport 控制缩放。
|
|
e.stopPropagation();
|
|
e.stopImmediatePropagation();
|
|
if (!document.getElementById('GameDiv'))
|
|
return;
|
|
const zoomIn = e.deltaY < 0;
|
|
const step = Math.pow(1.12, zoomIn ? 1 : -1);
|
|
this.previewZoom = Math.min(8, Math.max(0.2, Math.round(this.previewZoom * step * 100) / 100));
|
|
// 仅对尺寸映射的设备/默认视口应用缩放(FullScreen/Webpage 铺满不缩放)
|
|
const dev = this.previewDevice || 'Default';
|
|
if (DEVICE_SIZES[dev]) {
|
|
this.applyDeviceViewport(dev);
|
|
}
|
|
// 兜底:编辑器 preview-app Ui 可能在同一次滚轮/resize 里异步把设计分辨率重置成
|
|
// 默认横屏(960×640)。下一帧再重放一次视口(等比 + _exactFitScreen=false),
|
|
// 把设备/默认设计分辨率强制拉回项目真实竖屏比例。
|
|
cancelAnimationFrame(this._wheelReapply);
|
|
this._wheelReapply = requestAnimationFrame(() => {
|
|
this._wheelReapply = 0;
|
|
const dev0 = this.previewDevice || 'Default';
|
|
if (DEVICE_SIZES[dev0])
|
|
this.applyDeviceViewport(dev0);
|
|
});
|
|
},
|
|
/** 把相对/绝对路径拼到预览服务 origin 上(面板 origin 解析会 404)。 */
|
|
abs(path) {
|
|
const base = (this.previewUrl || '').trim().replace(/\/+$/, '') || 'http://localhost:7456';
|
|
if (/^(https?:)?\/\//i.test(path) || path.startsWith('data:') || path.startsWith('blob:')) {
|
|
return path;
|
|
}
|
|
return base + (path.startsWith('/') ? path : '/' + path);
|
|
},
|
|
/** 游戏宿主容器:创建在顶层 document.body 上。面板内容可能渲染在 shadow DOM 中
|
|
* (Cocos ui-panel 机制),Ui 构造的 document.querySelector 无法穿透 shadow root,
|
|
* 因此游戏 DOM 必须挂在顶层 document 上才能被找到。 */
|
|
ensureGameHost() {
|
|
let host = document.getElementById('yyka-game-host');
|
|
if (!host) {
|
|
host = document.createElement('div');
|
|
host.id = 'yyka-game-host';
|
|
// flex column:toolbar 隐藏后 content(flex:auto) 才能撑满宿主高度
|
|
// z-index 40:盖住面板主体内容(z-index ≤ 10),
|
|
// 但低于 .mcp-mask(50)/.node-picker-mask(9999),避免遮盖面板弹层
|
|
host.style.cssText =
|
|
'position:fixed;z-index:40;overflow:hidden;background:#171717;display:none;' +
|
|
'flex-direction:column;align-items:stretch;';
|
|
document.body.appendChild(host);
|
|
}
|
|
// 滚轮缩放:游戏放大后 #GameDiv 会超出预览区,若把 wheel 绑在宿主上,
|
|
// 当鼠标悬停在溢出的画面区域时事件可能被子元素拦截/丢失,导致放大了缩不回来。
|
|
// 挂在 document(window 捕获)的捕获阶段,保证鼠标落在游戏宿主内任意元素(含溢出部分)
|
|
// 都能触发;且在编辑器 preview-app Ui 的任何滚轮处理器之前先执行(见 onPreviewWheel)。
|
|
// 用 this._docZoomBound 防重复绑定(window 常驻,host 可反复重建)。
|
|
if (!this._docZoomBound) {
|
|
this._docZoomBound = true;
|
|
window.addEventListener('wheel', (e) => {
|
|
const h = document.getElementById('yyka-game-host');
|
|
if (h && (h.contains(e.target) || e.target === h)) {
|
|
this.onPreviewWheel(e);
|
|
}
|
|
}, { capture: true, passive: false });
|
|
}
|
|
return host;
|
|
},
|
|
/** 让游戏宿主跟随面板预览区域(.game-view)的视口位置与尺寸。
|
|
* getBoundingClientRect 对 shadow DOM 内元素同样返回视口坐标,配合 fixed 定位可精确覆盖。
|
|
* 面板被拖动/切走/弹窗遮挡时宿主必须跟随或隐藏,否则会「漂浮」在屏幕上盖住其它窗口。 */
|
|
syncGameHost() {
|
|
const host = document.getElementById('yyka-game-host');
|
|
if (!host)
|
|
return;
|
|
const ref = this.$refs.gameView || document.querySelector('.game-view');
|
|
if (!ref)
|
|
return;
|
|
const r = ref.getBoundingClientRect();
|
|
const vw = window.innerWidth;
|
|
const vh = window.innerHeight;
|
|
// 尺寸为 0(v-show 隐藏)或完全移出视口(面板拖动/独立成窗)时隐藏宿主,避免漂浮遮挡
|
|
const offscreen = r.width <= 1 || r.height <= 1 || r.left >= vw || r.top >= vh || r.left + r.width <= 0 || r.top + r.height <= 0;
|
|
const display = offscreen ? 'none' : 'flex';
|
|
// 仅在状态变化时写样式,避免定期轮询造成无谓重排
|
|
if (this._hostDisplay === display && this._hostLeft === r.left && this._hostTop === r.top &&
|
|
this._hostW === r.width && this._hostH === r.height) {
|
|
return;
|
|
}
|
|
this._hostDisplay = display;
|
|
this._hostLeft = r.left;
|
|
this._hostTop = r.top;
|
|
this._hostW = r.width;
|
|
this._hostH = r.height;
|
|
host.style.display = display; // 与 cssText 的 flex column 布局一致
|
|
if (display === 'none')
|
|
return;
|
|
host.style.left = r.left + 'px';
|
|
host.style.top = r.top + 'px';
|
|
host.style.width = r.width + 'px';
|
|
host.style.height = r.height + 'px';
|
|
},
|
|
/** 停止定期宿主同步(渲染被取代或面板关闭时调用)。 */
|
|
stopHostSync() {
|
|
if (this._hostSyncTimer) {
|
|
window.clearInterval(this._hostSyncTimer);
|
|
this._hostSyncTimer = 0;
|
|
}
|
|
},
|
|
/** 监听预览区域尺寸/显隐变化,自动同步游戏宿主位置(分隔条拖拽、窗口缩放、v-show 切换)。 */
|
|
observeGameHost() {
|
|
if (this._hostObserved)
|
|
return;
|
|
this._hostObserved = true;
|
|
const ref = this.$refs.gameView || document.querySelector('.game-view');
|
|
if (!ref || typeof ResizeObserver === 'undefined')
|
|
return;
|
|
const ro = new ResizeObserver(() => this.syncGameHost());
|
|
ro.observe(ref);
|
|
},
|
|
/** 构建完整游戏 DOM(toolbar 控件条 + content/GameDiv/canvas/splash/bulletin/error),
|
|
* 挂载到顶层 document 的游戏宿主上,并同步定位到面板预览区域。
|
|
* Ui 构造的 document.querySelector('#GameCanvas') 依赖这些元素在顶层 document 可见。 */
|
|
buildGameDom() {
|
|
const host = this.ensureGameHost();
|
|
host.innerHTML = '';
|
|
const el = (tag, cls = '', id = '') => {
|
|
const e = document.createElement(tag);
|
|
if (cls)
|
|
e.className = cls;
|
|
if (id)
|
|
e.id = id;
|
|
return e;
|
|
};
|
|
// 内联样式:等价预览模板 index.css 的关键布局(只作用于 #yyka-game-host 内部)。
|
|
// 缺少这些样式会导致:toolbar 裸奔显示(布局乱)、
|
|
// #GameDiv/#Cocos3dGameContainer/#GameCanvas 塌陷为 0 尺寸(黑屏)。
|
|
const style = el('style');
|
|
style.textContent = `
|
|
#yyka-game-host, #yyka-game-host * { box-sizing: border-box; -webkit-user-select: none; user-select: none; }
|
|
#yyka-game-host .toolbar { display: none !important; } /* 面板内不需要预览器控件条 */
|
|
#yyka-game-host .content {
|
|
flex: auto; min-height: 0;
|
|
display: flex; flex-direction: column;
|
|
align-items: center; justify-content: center; overflow: hidden;
|
|
}
|
|
#yyka-game-host .contentWrap {
|
|
width: 100%; height: 100%; overflow: hidden;
|
|
display: flex; align-items: center; justify-content: center; flex-direction: column;
|
|
}
|
|
#yyka-game-host #GameDiv,
|
|
#yyka-game-host #Cocos3dGameContainer,
|
|
#yyka-game-host #GameCanvas { width: 100%; height: 100%; }
|
|
#yyka-game-host #GameDiv { overflow: hidden; position: relative; }
|
|
#yyka-game-host .wrapper { position: relative; }
|
|
/* 设备外壳容器:默认只作居中包裹;选中设备时加 .device 呈现手机屏幕外观 */
|
|
#yyka-game-host .device-frame {
|
|
display: flex; align-items: center; justify-content: center; width: max-content; height: max-content;
|
|
}
|
|
/* 手机外壳(全面屏):窄边中框 + 圆角裁剪(游戏窗口直角被圆角遮掉,呈全面屏),
|
|
顶部挖孔屏胶囊刘海 + 底部下巴 */
|
|
#yyka-game-host .device-frame.device {
|
|
position: relative;
|
|
border-radius: 18px;
|
|
padding: 0;
|
|
overflow: hidden; /* 让内部游戏窗口直角被圆角裁切 */
|
|
background: linear-gradient(160deg, #3a3f47 0%, #23262b 45%, #141619 100%);
|
|
color: #fff;
|
|
box-shadow:
|
|
inset 0 0 0 1px rgba(255, 255, 255, 0.06),
|
|
0 2px 5px rgba(0, 0, 0, 0.5),
|
|
0 12px 26px rgba(0, 0, 0, 0.45),
|
|
0 26px 52px rgba(0, 0, 0, 0.55);
|
|
}
|
|
/* 边框覆盖层:叠在屏幕之上(不能在 background/box-shadow 画,那些会被子元素屏幕盖住),
|
|
中央透明透出屏幕,四边机身色形成可见的手机边框,圆角跟随外壳 */
|
|
#yyka-game-host .device-frame.device::before {
|
|
content: ""; position: absolute; inset: 0; z-index: 5; pointer-events: none;
|
|
border: 6px solid #26292f;
|
|
border-radius: 16px;
|
|
box-shadow:
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.18),
|
|
inset 0 -1px 0 rgba(0, 0, 0, 0.55),
|
|
inset 0 0 0 1px rgba(255, 255, 255, 0.06);
|
|
}
|
|
/* 底部点亮条(叠在边框下方,像 home 键光条) */
|
|
#yyka-game-host .device-frame.device::after {
|
|
content: ""; position: absolute; bottom: 2px; left: 50%; transform: translateX(-50%);
|
|
width: 46px; height: 2px; border-radius: 2px; background: rgba(255, 255, 255, 0.16);
|
|
z-index: 6;
|
|
}
|
|
/* 灵动岛挖孔镜头:设备模式下覆盖在屏幕顶部中央,圆角胶囊外观。
|
|
尺寸用相对值(宽度取屏幕宽的一定的百分比),随外壳整体缩放同步变化,
|
|
避免缩放时机身放大而灵动岛保持固定像素导致“相对变小/反向”的现象。 */
|
|
#yyka-game-host .device-frame .dynamic-island {
|
|
display: none;
|
|
position: absolute; top: 4%; left: 50%; transform: translateX(-50%);
|
|
width: 26%; aspect-ratio: 4 / 1; border-radius: 999px; background: #000;
|
|
z-index: 6; pointer-events: none;
|
|
box-shadow:
|
|
inset 0 0 0 1px rgba(255, 255, 255, 0.06),
|
|
inset 0 0 6px rgba(255, 255, 255, 0.05),
|
|
0 2px 8px rgba(0, 0, 0, 0.5);
|
|
}
|
|
#yyka-game-host .device-frame.device .dynamic-island { display: block; }
|
|
#yyka-game-host #splash { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; visibility: hidden; }
|
|
#yyka-game-host #bulletin { position: absolute; left: 50%; top: 50%; display: none; }
|
|
#yyka-game-host .error {
|
|
color: #fff; position: absolute; width: 70%; max-width: 960px; top: 5vh; right: 0; left: 0;
|
|
margin: auto; display: none; z-index: 2; background: #171717; padding: 16px;
|
|
border-radius: 4px; word-break: break-all;
|
|
}
|
|
#yyka-game-host canvas { background-color: transparent; outline: none; }
|
|
`;
|
|
host.appendChild(style);
|
|
// 预览器 UI 控件条:Ui 构造函数用 document.querySelector 强依赖这些元素,缺失即抛
|
|
// "UI element xxx doesn't exist"。显示层面由 CSS 隐藏。
|
|
const toolbar = el('div', 'toolbar disabled');
|
|
// 设备列表 data-device 与真实预览服务渲染的完全一致,preview-app 据此键应用分辨率。
|
|
toolbar.innerHTML = `
|
|
<div class="item"><div id="view-select" class="view-select-container" value="Default" tabindex="-1">
|
|
<div class="view-select"><div class="label"><span id="name"></span></div><i class="arrow-triangle"></i></div>
|
|
<div class="options"><ul>
|
|
<li class="selected" data-device="Default">设计分辨率 (960X640)</li>
|
|
<li class="" data-device="FullScreen">全屏</li>
|
|
<li class="" data-device="WebpageFullScreen">网页全屏</li>
|
|
<li class="separator"></li>
|
|
<li class="" data-device="Apple iPhone 12; 13; 14; 12/13 Pro">iPhone 12/13/14 (390X844)</li>
|
|
<li class="" data-device="Apple iPhone 14 Pro">iPhone 14 Pro (393X852)</li>
|
|
<li class="" data-device="Apple iPhone 12/13 Pro Max; 14 Plus">iPhone Pro Max/14 Plus (428X926)</li>
|
|
<li class="" data-device="Apple iPhone XR; 11">iPhone XR/11 (414X896)</li>
|
|
<li class="" data-device="Apple iPhone X; XS; 11 Pro; 12/13 Mini">iPhone X/XS (375X812)</li>
|
|
<li class="" data-device="Apple iPad 10.2">iPad 10.2 (1620X2160)</li>
|
|
<li class="" data-device="HUAWEI Mate 40 Pro">HUAWEI Mate 40 Pro (448X924)</li>
|
|
<li class="" data-device="OPPO Reno 2">OPPO Reno 2 (360X800)</li>
|
|
<li class="" data-device="Xiaomi Redmi 8">Xiaomi Redmi 8 (360X760)</li>
|
|
<li class="" data-device="Lenovo Legion 2 Pro">Lenovo Legion 2 Pro (360X820)</li>
|
|
</ul></div>
|
|
</div></div>
|
|
<div class="item"><button id="btn-rotate" class="checked">Rotate</button></div>
|
|
<span class="item">Debug Mode:</span>
|
|
<div class="item"><select id="opts-debug-mode" value="INFO">
|
|
<option value="NONE">None</option><option value="VERBOSE">Verbose</option>
|
|
<option value="INFO">Info</option><option value="WARN">Warn</option>
|
|
<option value="ERROR">Error</option><option value="INFO_FOR_WEB_PAGE">Info For Web Page</option>
|
|
<option value="WARN_FOR_WEB_PAGE">Warn For Web Page</option>
|
|
<option value="ERROR_FOR_WEB_PAGE">Error For Web Page</option>
|
|
</select></div>
|
|
<div class="item"><button id="btn-show-fps" class="">Show FPS</button></div>
|
|
<div class="item"><span>FPS:</span><input id="input-set-fps" type="number" value="60" /></div>
|
|
<div id="step-length"><span>Step Length: </span><input type="text" value="1"><span>ms</span></div>
|
|
<div class="item"><button id="btn-pause">Pause</button><button id="btn-step" style="display:none;">Step</button></div>`;
|
|
host.appendChild(toolbar);
|
|
const gameDiv = el('div', 'wrapper', 'GameDiv');
|
|
const container = el('div', '', 'Cocos3dGameContainer');
|
|
const canvas = el('canvas', '', 'GameCanvas');
|
|
canvas.tabIndex = -1;
|
|
container.appendChild(canvas);
|
|
gameDiv.appendChild(container);
|
|
const splash = el('div', '', 'splash');
|
|
const bar = el('div', 'progress-bar stripes');
|
|
bar.innerHTML = '<span></span>';
|
|
splash.appendChild(bar);
|
|
gameDiv.appendChild(splash);
|
|
const bulletin = el('div', '', 'bulletin');
|
|
const empty = el('div', 'inner', 'sceneIsEmpty');
|
|
empty.textContent = '预览场景中啥都没有,加点什么,或在编辑器中打开其它场景吧';
|
|
bulletin.appendChild(empty);
|
|
gameDiv.appendChild(bulletin);
|
|
const err = el('div', 'error', 'error');
|
|
err.appendChild(el('div', 'title')).textContent = 'Error (Please open the console to see detailed errors)';
|
|
err.appendChild(el('div', 'error-main'));
|
|
err.appendChild(el('div', 'error-stack'));
|
|
gameDiv.appendChild(err);
|
|
const frame = el('div', 'device-frame'); // 手机外壳容器:选中设备时呈现手机屏幕样式
|
|
frame.appendChild(gameDiv);
|
|
frame.appendChild(el('div', 'dynamic-island')); // 灵动岛挖孔摄像头(覆盖屏幕之上)
|
|
const wrap = el('div', 'contentWrap');
|
|
wrap.appendChild(frame);
|
|
const content = el('div', 'content');
|
|
content.appendChild(wrap);
|
|
host.appendChild(content);
|
|
// 确认 #GameCanvas 已挂载到顶层 document(Ui 构造依赖)
|
|
if (document.querySelector('#GameCanvas')) {
|
|
this.logs.push({ evt: 'sys', msg: '[预览] 游戏 DOM 就绪 (#GameCanvas 已挂载到顶层 document)' });
|
|
}
|
|
else {
|
|
this.logs.push({ evt: 'sys', msg: '[预览] 警告: #GameCanvas 未挂载到顶层 document' });
|
|
}
|
|
this.syncGameHost();
|
|
this.observeGameHost();
|
|
},
|
|
/** 注入补充 import-map:preview-app 内部硬编码 import("/socket.io/socket.io.js"),
|
|
* 该路径基于面板 origin 解析会 404,需映射到预览服务绝对地址。
|
|
* 必须在 system.js 加载前注入,SystemJS 初始化时才会收集。 */
|
|
injectExtraImportMap() {
|
|
const inj = document.createElement('script');
|
|
inj.type = 'systemjs-importmap';
|
|
inj.textContent = JSON.stringify({
|
|
imports: {
|
|
'/socket.io/socket.io.js': this.abs('/socket.io/socket.io.js'),
|
|
},
|
|
});
|
|
document.head.appendChild(inj);
|
|
},
|
|
/** 在 /socket.io/socket.io.js(映射后的绝对地址)注册 SystemJS stub 模块。
|
|
* 必须在 system.js 加载之后、System.import(preview-app) 之前调用。 */
|
|
registerSocketIoStub() {
|
|
const Sys = window.System;
|
|
const socketUrl = this.abs('/socket.io/socket.io.js');
|
|
if (!Sys || typeof Sys.register !== 'function' || Sys.has(socketUrl)) {
|
|
return;
|
|
}
|
|
Sys.register(socketUrl, [], (_export) => ({
|
|
// 注意:execute 不得返回真值(_export 的返回值是导出的值,如 socketIoStub 函数)。
|
|
// SystemJS 的 doExec 对真值直接调 execPromise.then(...),非 Promise 即抛
|
|
// "execPromise.then is not a function";返回 undefined 走同步完成分支。
|
|
execute: () => {
|
|
_export('default', socketIoStub);
|
|
},
|
|
}));
|
|
this.logs.push({ evt: 'sys', msg: `[预览] socket.io stub 已注册 (${socketUrl})` });
|
|
},
|
|
/** 预览环境补齐:面板运行在编辑器 Electron 窗口内,引擎 cc/env 模块用
|
|
* tryDefineGlobal('CC_EDITOR', 探测 electron process) 会把 EDITOR 误判为 true,
|
|
* 从而走进编辑器桥接分支并引用未定义的 EditorExtends 全局导致崩溃
|
|
* (真实浏览器预览无 process,EDITOR=false 故正常)。必须在引擎 bundle 加载前
|
|
* 预置正确的预览标志 + EditorExtends 桩。 */
|
|
patchPreviewEnv() {
|
|
// 预置环境标志:cc/env 的 tryDefineGlobal 优先读 window 上的同名全局
|
|
window.CC_EDITOR = false;
|
|
window.CC_PREVIEW = true;
|
|
window.CC_DEV = true;
|
|
window.CC_JSB = false;
|
|
// EditorExtends 桩:兜住引擎中无 EDITOR 守卫的引用
|
|
// (如 Node._registerIfAttached 的 `if (EditorExtends.Node && ...)`),
|
|
// 各成员为 no-op,避免 ReferenceError/TypeError,也不产生编辑器副作用。
|
|
window.EditorExtends = {
|
|
Node: { add() { }, remove() { }, getNode() { return null; }, emit() { } },
|
|
Component: { add() { }, remove() { }, addMenu() { }, removeMenu() { } },
|
|
PrefabUtils: { addPrefabInstance() { } },
|
|
serialize: { asAsset() { return null; } },
|
|
UuidUtils: { isUuid() { return false; }, decompressUuid() { return null; } },
|
|
};
|
|
this.logs.push({ evt: 'sys', msg: '[预览] 预览环境已补齐 (CC_EDITOR=false, EditorExtends stub)' });
|
|
},
|
|
/** 包装 window.fetch + XMLHttpRequest:记录预览服务(origin 匹配)请求的非 2xx 响应,
|
|
* 面板内看不到网络面板时的调试兜底;编辑器自身请求不受影响。
|
|
* 引擎 AssetManager 部分下载走 XHR,只包装 fetch 会漏掉资源加载失败。
|
|
* 注意:每次渲染都调用本方法重装,但基于 window 上保存的「原始引用」重新包装
|
|
* (__yykaRawIo 只存一次),既保证最新版本逻辑生效,又避免层层嵌套。 */
|
|
hookFetchLogger() {
|
|
const self = this;
|
|
const w = window;
|
|
// 原始 IO 引用只保存一次:旧版本没有此标记时首次取「当前实现」(可能是旧包装),
|
|
// 功能等价;WebContents 重建后 window 全新,这里取到原生实现。
|
|
if (!w.__yykaRawIo) {
|
|
w.__yykaRawIo = {
|
|
fetch: w.fetch.bind(w),
|
|
xhrOpen: XMLHttpRequest.prototype.open,
|
|
xhrSend: XMLHttpRequest.prototype.send,
|
|
};
|
|
}
|
|
const raw = w.__yykaRawIo;
|
|
const base = (this.previewUrl || '').trim().replace(/\/+$/, '');
|
|
const inPreview = (u) => !!base && u.indexOf(base) === 0;
|
|
// 只记录关键请求:非 200(失败/CORS 拦截 status=0)或 URL 含 /scene/(场景加载结果)
|
|
const shouldLog = (u, status) => status !== 200 || /\/scene\//i.test(u);
|
|
// 纯相对路径(无 scheme、不以 / 或 // 开头)在编辑器 document 下会解析到编辑器 origin,
|
|
// 而 preview-app/引擎以相对路径请求场景与资源(scene/xxx.json、assets/general/import/...)。
|
|
// 浏览器预览页面就在预览 origin 下所以正常;面板内必须改写成预览服务绝对地址,
|
|
// 否则场景 JSON 404 → no-scene 黑屏。
|
|
// 特别注意:引擎 wasm 走根相对 /engine_external/?url=external:...(wasm-web.ts),
|
|
// 按面板 origin 解析会失败,且该 fetch 的 catch 是空实现(promise 永不 resolve),
|
|
// 导致 game.init 永久挂起 → no-scene 黑屏且无任何报错。必须一并改写为预览服务 origin。
|
|
const toAbs = (u) => {
|
|
if (/^[a-z][a-z0-9+.-]*:/i.test(u) || u.startsWith('//')) {
|
|
return u;
|
|
}
|
|
if (u.startsWith('/engine_external/')) {
|
|
return self.abs(u);
|
|
}
|
|
return u.startsWith('/') ? u : self.abs(u);
|
|
};
|
|
w.fetch = (input, init) => {
|
|
const raw0 = input;
|
|
const realInput = typeof raw0 === 'string' ? toAbs(raw0) : raw0;
|
|
const realStr = typeof realInput === 'string'
|
|
? realInput
|
|
: realInput instanceof URL
|
|
? realInput.href
|
|
: String((realInput && realInput.url) || '');
|
|
return raw.fetch(realInput, init)
|
|
.then((res) => {
|
|
if (inPreview(realStr) && shouldLog(realStr, res.status)) {
|
|
self.logs.push({ evt: 'sys', msg: `[预览网络] fetch ${res.status} ${realStr}` });
|
|
}
|
|
return res;
|
|
})
|
|
.catch((e) => {
|
|
// 引擎的 wasm fetch 静默吞错,这里补日志定位加载失败的真实 URL
|
|
if (inPreview(realStr) || /\/engine_external\//i.test(realStr)) {
|
|
self.logs.push({ evt: 'sys', msg: `[预览网络] fetch 失败 ${realStr}: ${String((e && e.message) || e)}` });
|
|
}
|
|
throw e;
|
|
});
|
|
};
|
|
// XHR:改写相对路径 + 记录关键请求(场景/纹理/音频等)
|
|
XMLHttpRequest.prototype.open = function (method, url, ...rest) {
|
|
const u = toAbs(String(url));
|
|
this.__yykaUrl = u;
|
|
return raw.xhrOpen.apply(this, [method, u, ...rest]);
|
|
};
|
|
XMLHttpRequest.prototype.send = function (...args) {
|
|
this.addEventListener('load', () => {
|
|
const u = this.__yykaUrl || '';
|
|
if (inPreview(u) && shouldLog(u, this.status)) {
|
|
self.logs.push({ evt: 'sys', msg: `[预览网络] XHR ${this.status} ${u}` });
|
|
}
|
|
});
|
|
this.addEventListener('error', () => {
|
|
const u = this.__yykaUrl || '';
|
|
if (inPreview(u)) {
|
|
self.logs.push({ evt: 'sys', msg: `[预览网络] XHR 失败 ${u}` });
|
|
}
|
|
});
|
|
return raw.xhrSend.apply(this, args);
|
|
};
|
|
// 引擎纹理/图片用 Image 元素加载,相对 src 同样基于 document base 解析,一并改写。
|
|
// 同时强制跨源图片带 crossOrigin='anonymous':引擎的 download-dom-image 只在
|
|
// location.protocol !== 'file:' 时设置,面板/file:// 等跨源场景下漏设会导致
|
|
// WebGL 纹理上传失败(texSubImage2D SecurityError → 粉色贴图)。
|
|
try {
|
|
const srcDesc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, 'src');
|
|
if (srcDesc && srcDesc.set) {
|
|
Object.defineProperty(HTMLImageElement.prototype, 'src', {
|
|
get: function () {
|
|
return srcDesc.get.call(this);
|
|
},
|
|
set: function (v) {
|
|
const nv = typeof v === 'string' ? toAbs(v) : v;
|
|
if (typeof nv === 'string' && /^https?:/i.test(nv)) {
|
|
this.crossOrigin = 'anonymous';
|
|
}
|
|
return srcDesc.set.call(this, nv);
|
|
},
|
|
configurable: true,
|
|
});
|
|
}
|
|
}
|
|
catch (_) {
|
|
/* ignore */
|
|
}
|
|
// 引擎 bundle 脚本(assets/internal/index.js、assets/main/index.js 等)由 downloadScript
|
|
// 直接设 script.src(相对路径),不经过 fetch/XHR,必须同样改写为预览服务绝对地址,
|
|
// 否则按面板 origin 解析 404 → loadBuiltinAssets 失败 → game.init 挂起 → no-scene。
|
|
try {
|
|
const scriptDesc = Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, 'src');
|
|
if (scriptDesc && scriptDesc.set) {
|
|
Object.defineProperty(HTMLScriptElement.prototype, 'src', {
|
|
get: function () {
|
|
return scriptDesc.get.call(this);
|
|
},
|
|
set: function (v) {
|
|
return scriptDesc.set.call(this, typeof v === 'string' ? toAbs(v) : v);
|
|
},
|
|
configurable: true,
|
|
});
|
|
}
|
|
}
|
|
catch (_) {
|
|
/* ignore */
|
|
}
|
|
},
|
|
/** 全量转发 console 输出(log/info/warn/error/debug)到面板日志栏。
|
|
* 必须在加载引擎脚本前安装:preview-app 的 bootstrap 是 fire-and-forget 的
|
|
* async 函数,内部每一步(Ui 构造/System.import("cc")/game.init/game.run/onStart)
|
|
* 抛错都被内层 catch 用 console.error 吞掉,而 onStart 的场景加载又在
|
|
* bootFn 返回后才跑——若转发装得太晚,场景加载失败的真实原因完全不可见。
|
|
* 引擎内部报错同样走 console.error(不触发 window.onerror)。
|
|
* 每次渲染基于 window 保存的「原始方法引用」重新包装,逻辑最新且不层层嵌套;
|
|
* 相同消息 10 秒内合并计数(如 "foo (x3)")防每帧刷屏。 */
|
|
hookConsoleForward() {
|
|
const self = this;
|
|
const w = window;
|
|
if (!w.__yykaRawConsole) {
|
|
const o = {};
|
|
for (const m of ['log', 'info', 'warn', 'error', 'debug']) {
|
|
o[m] = console[m].bind(console);
|
|
}
|
|
w.__yykaRawConsole = o;
|
|
}
|
|
const raw = w.__yykaRawConsole;
|
|
for (const m of ['log', 'info', 'warn', 'error', 'debug']) {
|
|
console[m] = (...args) => {
|
|
const text = args
|
|
.map((a) => {
|
|
if (a instanceof Error) {
|
|
return a.stack || a.message;
|
|
}
|
|
try {
|
|
if (typeof a === 'string') {
|
|
return a;
|
|
}
|
|
const s = JSON.stringify(a);
|
|
return s === undefined ? String(a) : s;
|
|
}
|
|
catch (_) {
|
|
return String(a);
|
|
}
|
|
})
|
|
.join(' ');
|
|
const now = Date.now();
|
|
const key = `${m}|${text}`;
|
|
const last = self._consoleDedup && self._consoleDedup.get(key);
|
|
if (last && now - last.t < 10000) {
|
|
last.n++;
|
|
last.t = now;
|
|
// 已合并的消息只更新计数(数组尾元素),不再新增条目
|
|
const arr = self.logs;
|
|
for (let i = arr.length - 1; i >= 0; i--) {
|
|
const it = arr[i];
|
|
if (it && it.evt === 'console' && it.key === key) {
|
|
it.text = it.base + ` (x${last.n})`;
|
|
it.t = now;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (!self._consoleDedup || self._consoleDedup.size > 3000) {
|
|
// 重渲染/长时间运行后清理去重状态,防止 Map 无限增长
|
|
self._consoleDedup = new Map();
|
|
}
|
|
self._consoleDedup.set(key, { n: 1, t: now });
|
|
self.logs.push({ evt: 'console', level: m, key, base: text, text, t: now });
|
|
}
|
|
// 上限保护:日志栏渲染性能
|
|
while (self.logs.length > 3000) {
|
|
self.logs.shift();
|
|
}
|
|
const orig = raw[m];
|
|
return orig(...args);
|
|
};
|
|
}
|
|
},
|
|
/** 加载单个外部脚本,返回 Promise(onload / onerror / 超时兜底)。 */
|
|
loadScript(src, attrs = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
const s = document.createElement('script');
|
|
s.src = src;
|
|
for (const k in attrs) {
|
|
s.setAttribute(k, attrs[k]);
|
|
}
|
|
const timer = window.setTimeout(() => reject(new Error('脚本加载超时: ' + src)), 20000);
|
|
s.onload = () => {
|
|
window.clearTimeout(timer);
|
|
resolve(s);
|
|
};
|
|
s.onerror = () => {
|
|
window.clearTimeout(timer);
|
|
reject(new Error('脚本加载失败: ' + src));
|
|
};
|
|
document.head.appendChild(s);
|
|
});
|
|
},
|
|
/** 以原生 <script type="systemjs-importmap" src=...> 加载 import-map(与 docs/view.html 一致)。
|
|
* 由 SystemJS 自己 fetch 并按「map 自身 URL」解析相对目标与链式裸说明符,
|
|
* 从而保持引擎 bundle 内 q-bundled:/// 命名模块的相对 import 上下文正确。
|
|
*
|
|
* 早期实现改为「面板 fetch + 重写 + 内联注入 JSON」:手动把 ./、/起始路径绝对化,
|
|
* 破坏了 SystemJS 对 bundle 内物理/网格 loader 相对 import
|
|
* (../../../../virtual/external%253A...wasm.wasm.js) 的解析——被锁成网络
|
|
* /virtual/... (404, Error#3),且 q-bundled:///virtual/... 虚拟模块注册上下文丢失
|
|
* (has→false)。原生 src 加载完全复刻 view.html 的工作链路。
|
|
*/
|
|
async applyImportMap(src) {
|
|
const url = this.abs(src);
|
|
const inj = document.createElement('script');
|
|
inj.type = 'systemjs-importmap';
|
|
inj.src = url;
|
|
document.head.appendChild(inj);
|
|
this.logs.push({ evt: 'sys', msg: `[预览] ${src} import-map 以原生 src 注入 (由 SystemJS 加载)` });
|
|
},
|
|
/** 面板内直接渲染游戏(无 iframe)。每一步结果写入日志栏,便于定位失败环节。 */
|
|
async renderPreview() {
|
|
const seq = (this._renderSeq = (this._renderSeq || 0) + 1); // 新渲染取代旧渲染,旧的立即停止
|
|
this.stopHostSync(); // 清理上一次渲染的定期宿主同步
|
|
// 刷新时先拆解旧游戏实例,避免音乐/计时器/主循环残留叠加
|
|
this.teardownPreview();
|
|
const url = (this.previewUrl || '').trim();
|
|
if (!url) {
|
|
this.previewRenderErr = '未配置预览地址';
|
|
return;
|
|
}
|
|
const log = (msg) => this.logs.push({ evt: 'sys', msg: `[预览] ${msg}` });
|
|
const alive = () => this._renderSeq === seq;
|
|
// 安装窗口级音频静音 hook(事件驱动、幂等),在引擎脚本加载前保证静音覆盖所有播放路径
|
|
try {
|
|
this._hookAudioCtx();
|
|
}
|
|
catch (_) { /* ignore */ }
|
|
// 版本标识:日志开头直接确认面板加载的是哪个版本,避免旧产物误判
|
|
log(`渲染 v${package_json_1.default.version}`);
|
|
// 环境诊断:确认面板 origin(file:/自定义协议决定引擎对 crossOrigin/location 的处理路径)
|
|
log(`环境 href=${window.location.href} base=${document.baseURI} proto=${window.location.protocol} ` +
|
|
`trace=${!!window.__yykaTraceInstalled} rawIo=${!!window.__yykaRawIo}`);
|
|
// 全局错误捕获:拿到完整堆栈,定位引擎初始化失败的真实模块。
|
|
// 标记放 window 上而非实例字段:插件重载/面板复用可能遗留实例 true,
|
|
// 导致新版本代码跳过安装(曾发生:v1.0.156+ 的 /engine_external/、script.src、
|
|
// crossOrigin 钩子从未生效,面板端 wasm 仍静默挂起)。
|
|
if (!window.__yykaErrHooked) {
|
|
window.__yykaErrHooked = true;
|
|
window.addEventListener('error', (ev) => {
|
|
const m = ev.error ? ev.error.stack || ev.error.message || String(ev.error) : ev.message;
|
|
this.logs.push({ evt: 'sys', msg: `[预览错误] ${m}` });
|
|
});
|
|
window.addEventListener('unhandledrejection', (ev) => {
|
|
const r = ev.reason;
|
|
this.logs.push({ evt: 'sys', msg: `[预览错误] unhandledrejection: ${r && r.stack ? r.stack : String(r)}` });
|
|
});
|
|
}
|
|
// 每次渲染强制重装最新版钩子:内部基于全局原始引用重新包装,幂等且不层层嵌套
|
|
this.hookFetchLogger();
|
|
log('网络 hook 已安装 (fetch/XHR/Image/script 路径重写 + 请求结果记录)');
|
|
// console 全量转发同样提前安装:preview-app bootstrap 内部错误走 console.error 被吞,
|
|
// 且场景加载(onStart)在 bootFn 返回后才跑,转发装晚了会漏掉失败的真实原因
|
|
this.hookConsoleForward();
|
|
log('console 转发已安装 (引擎/preview-app 输出全量可见)');
|
|
// 注入 <base href>:SystemJS 的 baseUrl 读取 document.querySelector('base[href]'),
|
|
// external:emscripten/... 虚拟 wasm 模块按 base 解析,面板 base 是 file:// 导致
|
|
// 解析到不存在的本地路径而加载失败(bt.DbvtBroadphase_new is not a function 根因),
|
|
// 改到预览服务 origin 后命中其 virtual handler
|
|
try {
|
|
let baseEl = document.querySelector('base[href]');
|
|
if (!baseEl) {
|
|
baseEl = document.createElement('base');
|
|
document.head.appendChild(baseEl);
|
|
}
|
|
baseEl.href = (this.previewUrl || 'http://localhost:7456/').trim().replace(/\/+$/, '') + '/';
|
|
log(`<base href> 已注入 (${baseEl.href})`);
|
|
}
|
|
catch (_) {
|
|
/* ignore */
|
|
}
|
|
try {
|
|
this.checkPreview(); // 快速探测在线状态(内部节流)
|
|
this.previewRenderErr = '';
|
|
this.previewLoaded = false;
|
|
log('开始加载引擎脚本…');
|
|
await this.loadScript(this.abs('/scripting/polyfills/bundle.js'));
|
|
if (!alive())
|
|
return;
|
|
log('polyfills ✓');
|
|
await this.applyImportMap('/scripting/engine/bin/.cache/dev/preview/import-map.json');
|
|
if (!alive())
|
|
return;
|
|
log('引擎 import-map ✓');
|
|
await this.applyImportMap('/scripting/x/import-map.json');
|
|
if (!alive())
|
|
return;
|
|
log('项目 import-map ✓');
|
|
await this.applyImportMap('/scripting/import-map-global');
|
|
if (!alive())
|
|
return;
|
|
log('cc import-map ✓');
|
|
// 补充映射(socket.io 等 preview-app 硬编码路径),须在 system.js 之前注入
|
|
this.injectExtraImportMap();
|
|
await this.loadScript(this.abs('/scripting/systemjs/system.js'));
|
|
if (!alive())
|
|
return;
|
|
log('systemjs ✓');
|
|
// socket.io stub:preview-app bootstrap 会 import('/socket.io/socket.io.js') 并调用 n.default()。
|
|
// 面板内跨域 + 重复渲染时 SystemJS 的全局探测不可靠(io 全局已存在则探测不到新全局,default 缺失),
|
|
// 直接在该路径注册 stub 模块,保证 n.default() 必定可用且不发起真实 socket.io 连接。
|
|
this.registerSocketIoStub();
|
|
if (!alive())
|
|
return;
|
|
// 注意:不设 System.config({baseURL})、不包装 System.import。
|
|
// 这两样是 view.html 所没有的额外编排,会干扰 engine bundle 内
|
|
// q-bundled:/// 命名模块的相对 import 解析(../../../../virtual/... 被拉起
|
|
// 成网络 /virtual/ 404、has→false)。完全复刻 view.html:只靠 <base href>。
|
|
// 分辨率细节映射(跨域 fetch,失败会反映到启动错误)
|
|
const Sys = window.System;
|
|
if (Sys && typeof Sys.setResolutionDetailMapCallback === 'function') {
|
|
Sys.setResolutionDetailMapCallback(() => {
|
|
const u = this.abs('/scripting/x/resolution-detail-map.json');
|
|
return fetch(u).then((r) => r.json()).then((json) => ({ json, url: u }));
|
|
});
|
|
}
|
|
// 分辨率细节映射已在上方 setResolutionDetailMapCallback 设置。
|
|
// 注意:view.html 不包装 System.import;这里也不做,保持与 view.html 一致的加载链路。
|
|
// 引擎 bundle 加载前置好环境(CC_EDITOR=false + EditorExtends 桩),
|
|
// 否则编辑器 Electron 窗口内 EDITOR 误判为 true 会触发 EditorExtends 崩溃
|
|
this.patchPreviewEnv();
|
|
await this.loadScript(this.abs('/scripting/engine/bin/.cache/dev/preview/bundled/index.js'));
|
|
if (!alive())
|
|
return;
|
|
log('引擎 bundle ✓');
|
|
await this.loadScript(this.abs('/settings.js?scene=current_scene'));
|
|
if (!alive())
|
|
return;
|
|
log('settings ✓');
|
|
const settings = window._CCSettings;
|
|
// 强制 SubFrame 尺寸模式:ScreenAdapter 的 _windowType 在 exactFitScreen=true
|
|
// 时走 BrowserWindow 分支,用 window.innerWidth/Height(编辑器窗口尺寸,非预览区域)
|
|
// 设置 #GameDiv 与画布 buffer,导致布局错位 + 黑屏。
|
|
// exactFitScreen=false → SubFrame → 尺寸按 #GameDiv 实际尺寸(clientWidth/Height)计算。
|
|
// 顶层字段走 _compatibleWithOldParams 转 overrideSettings,screen 字段走 settings.json。
|
|
if (settings && typeof settings === 'object') {
|
|
settings.exactFitScreen = false;
|
|
settings.screen = settings.screen || {};
|
|
settings.screen.exactFitScreen = false;
|
|
log('exactFitScreen=false (SubFrame 尺寸模式)');
|
|
}
|
|
// 引擎脚本全部就绪后,Vue 渲染必然已完成:此刻确保游戏 DOM 就位,
|
|
// 保证 Ui 构造的 document.querySelector('#GameCanvas') 必定命中
|
|
this.buildGameDom();
|
|
if (!alive())
|
|
return;
|
|
// 运行期跟踪:包装 game.run/loadWithJson/runSceneImmediate 并转发 console 错误,
|
|
// 精确定位场景加载卡点(必须在 preview-app 调用之前安装)
|
|
this.installPreviewTrace();
|
|
if (!alive())
|
|
return;
|
|
log('启动预览应用…');
|
|
try {
|
|
const mod = await window.System.import(this.abs('/preview-app/index.js') + '?__t=' + seq);
|
|
// 兼容 { bootstrap } 与 { default: { bootstrap } } 两种导出结构
|
|
const bootFn = (mod && typeof mod.bootstrap === 'function' && mod.bootstrap) ||
|
|
(mod && mod.default && typeof mod.default.bootstrap === 'function' && mod.default.bootstrap);
|
|
if (!bootFn) {
|
|
throw new Error('preview-app 未导出 bootstrap 函数,模块结构: ' + JSON.stringify(Object.keys(mod || {})));
|
|
}
|
|
if (!alive())
|
|
return;
|
|
// 双保险:无论 preview-app 以何种方式传 config 给 game.init,
|
|
// 都确保 ScreenAdapter 走 SubFrame 尺寸模式。
|
|
// querySettings 优先读 settings._override,再读 settings.json;
|
|
// settings.init 只会逐项 set overrideSettings,不会整体覆盖已有键。
|
|
const legacy = window.cc || window.cclegacy;
|
|
if (legacy && legacy.settings) {
|
|
legacy.settings._override = legacy.settings._override || {};
|
|
legacy.settings._override.screen = legacy.settings._override.screen || {};
|
|
legacy.settings._override.screen.exactFitScreen = false;
|
|
}
|
|
// devices 为 Ui 控件条强依赖(设备列表),缺了 Ui 构造会直接崩溃(设备表必须
|
|
// 包含工具栏 li 里出现的全部 data-device;漏设备抛 undefined.name)。
|
|
const _pd = this.prefDesign();
|
|
await bootFn({
|
|
engineBaseUrl: this.abs('/scripting/engine'),
|
|
settings,
|
|
devices: Object.assign({ 'Default': { name: `设计分辨率 (${_pd.w}×${_pd.h})`, width: _pd.w, height: _pd.h }, 'FullScreen': { name: '全屏', width: _pd.w, height: _pd.h }, 'WebpageFullScreen': { name: '网页全屏', width: _pd.w, height: _pd.h } }, Object.entries(DEVICE_SIZES)
|
|
.filter(([k]) => !['Default', 'FullScreen', 'WebpageFullScreen'].includes(k))
|
|
.reduce((acc, [k, v]) => {
|
|
acc[k] = { name: v.label, width: v.w, height: v.h };
|
|
return acc;
|
|
}, {})),
|
|
});
|
|
this.previewLoaded = true;
|
|
this.previewZoom = 1; // 新一次渲染从 100% 缩放开始
|
|
this.syncPreviewState(); // 同步工具条激活态
|
|
log('游戏已启动 ✓');
|
|
// 先定位并显示游戏宿主(display:none → flex),让 #GameDiv 拥有真实尺寸;
|
|
// 必须在 screenAdapter 注入的 resize 之前完成,否则 resize 时容器尺寸为 0,
|
|
// 画布 buffer 会按 0 尺寸计算(表现为 buf 远小于实际区域)。
|
|
this.syncGameHost();
|
|
// 默认按当前设备/设计分辨率等比居中显示(避免画面被拉伸成方形)。
|
|
// 需在宿主已定位、Engine resize 兜底之前应用,#GameDiv 才拿到真实容器尺寸。
|
|
this.applyDeviceViewport(this.previewDevice || 'Default');
|
|
// ===== exactFitScreen 最终兜底:直接改 ScreenAdapter 实例字段 =====
|
|
// 三层 settings 覆盖(_CCSettings / screen 字段 / _override)都依赖 preview-app
|
|
// 如何把 settings 传给 game.init 与 Settings.init 的 override 合并方式,
|
|
// 实测未生效(win 仍是编辑器窗口尺寸/dpr)。直接改实例字段最可靠:
|
|
// _windowType = _exactFitScreen ? BrowserWindow : SubFrame,
|
|
// 改 false 后触发 resize 走 SubFrame 分支按 #GameDiv 实际尺寸重算画布。
|
|
// System.import 是异步的,刷新那一刻可能还没 resolve 就开始渲染 → 画布仍是
|
|
// 浏览器窗口尺寸(比预览视口大)。这里用重试循环等到 adapter 就绪,并在每次
|
|
// 成功后重放视口,确保 SubFrame(跟随 #GameDiv 尺寸)在渲染前必然生效。
|
|
await this.forceSubFrameViewport(alive);
|
|
// 兜底注入可能把 _exactFitScreen 强制成 false(供 Default 铺满),
|
|
// 会覆盖掉上面 applyDeviceViewport 为设备模式设的 true,导致画面不按当前分辨率/缩放显示;
|
|
// 这里在注入之后按当前设备与缩放重放一次,恢复正确视口。
|
|
this.applyDeviceViewport(this.previewDevice || 'Default');
|
|
this.syncGameHost();
|
|
// 场景加载跟踪:若场景加载完成/失败,日志栏可见
|
|
try {
|
|
const legacy2 = window.cc || window.cclegacy;
|
|
const director = legacy2 && legacy2.director;
|
|
if (director && typeof director.on === 'function') {
|
|
const evt = (legacy2.Director && legacy2.Director.EVENT_AFTER_SCENE_LAUNCH) ||
|
|
'director_after_scene_launch';
|
|
director.on(evt, () => {
|
|
if (alive()) {
|
|
const sc = director.getScene && director.getScene();
|
|
log(`场景已加载: ${(sc && sc.name) || '?'}`);
|
|
// 场景激活后才重建最终画布/相机视口;此时重放视口并触发 resize,
|
|
// 让相机按 #GameDiv 最终尺寸计算 viewport(等效于用户滚轮),
|
|
// 修复刷新后相机视角跑偏。
|
|
this.applyDeviceViewport(this.previewDevice || 'Default');
|
|
this.syncGameHost();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
catch (e) {
|
|
log('场景监听注册失败: ' + String((e === null || e === void 0 ? void 0 : e.message) || e));
|
|
}
|
|
// 场景加载看门狗:无场景时周期性输出引擎状态快照,定位主循环/资源管线卡点
|
|
this.startSceneWatchdog();
|
|
// 定期同步:面板拖动/窗口移动/布局变化时 ResizeObserver 可能漏报
|
|
// (只监听尺寸不监听位置),轮询兜底保证宿主不「漂浮」
|
|
this._hostSyncTimer = window.setInterval(() => this.syncGameHost(), 300);
|
|
}
|
|
catch (err) {
|
|
const msg = String((err === null || err === void 0 ? void 0 : err.message) || err);
|
|
this.previewLoaded = false;
|
|
this.previewRenderErr = msg;
|
|
log('启动失败 ✗ ' + msg);
|
|
}
|
|
}
|
|
catch (err) {
|
|
const msg = String((err === null || err === void 0 ? void 0 : err.message) || err);
|
|
this.previewRenderErr = msg;
|
|
log('加载失败 ✗ ' + msg);
|
|
}
|
|
},
|
|
/** 运行期跟踪(必须在 preview-app 调用 game.run 之前安装):
|
|
* 包装 game.run/onStart、pause/resume、loadWithJson、runSceneImmediate,
|
|
* 并把 console.log/info/warn/error/debug 全量转发到面板日志。场景加载黑屏时
|
|
* 可直接从日志栏定位卡点:主循环未启动(onStart 未执行)/ 场景 JSON 请求 /
|
|
* 依赖加载 / 反序列化。
|
|
* 注意:引擎 bundle 是 System.register 模块,<script> 加载只注册不执行,
|
|
* window.cc 要等 System.import(preview-app) 才就绪;因此这里轮询等待安装窗口,
|
|
* 避免漏掉 game.run/loadWithJson 的包装(preview-app 的 game.init 是异步的,
|
|
* 25ms 轮询足够赶在 game.run 之前装上)。 */
|
|
installPreviewTrace() {
|
|
if (this._traceInstalled)
|
|
return;
|
|
const self = this;
|
|
const log = (msg) => self.logs.push({ evt: 'sys', msg: `[预览跟踪] ${msg}` });
|
|
const installNow = () => {
|
|
const legacy = window.cc || window.cclegacy;
|
|
if (!legacy) {
|
|
return false;
|
|
}
|
|
self._traceInstalled = true;
|
|
const g = legacy.game;
|
|
if (g) {
|
|
const origRun = g.run && g.run.bind(g);
|
|
if (origRun) {
|
|
g.run = (onStart) => {
|
|
log('game.run 被调用');
|
|
const wrapped = () => {
|
|
log('onStart 开始(场景加载流程启动)');
|
|
try {
|
|
const r = onStart && onStart();
|
|
if (r && typeof r.then === 'function') {
|
|
r.then(() => log('onStart 完成'), (e) => log('onStart 异常: ' + String((e && (e.message || e)) || e)));
|
|
}
|
|
return r;
|
|
}
|
|
catch (e) {
|
|
log('onStart 同步异常: ' + String((e === null || e === void 0 ? void 0 : e.message) || e));
|
|
throw e;
|
|
}
|
|
};
|
|
return origRun(wrapped);
|
|
};
|
|
}
|
|
for (const m of ['pause', 'resume', 'pauseByEngine', 'resumeByEngine']) {
|
|
const orig = g[m] && g[m].bind(g);
|
|
if (!orig)
|
|
continue;
|
|
g[m] = (...args) => {
|
|
log(`game.${m}()`);
|
|
return orig(...args);
|
|
};
|
|
}
|
|
}
|
|
const am = legacy.assetManager;
|
|
if (am && am.loadWithJson) {
|
|
const orig = am.loadWithJson.bind(am);
|
|
am.loadWithJson = (json, options, onProgress, onComplete) => {
|
|
log(`loadWithJson 开始 id=${options && options.assetId}`);
|
|
const wProgress = (finished, total) => {
|
|
log(`loadWithJson 进度 ${finished}/${total}`);
|
|
if (onProgress)
|
|
onProgress(finished, total);
|
|
};
|
|
const wComplete = (err, data) => {
|
|
log(`loadWithJson 完成 err=${err ? String((err === null || err === void 0 ? void 0 : err.message) || err) : '无'} ` +
|
|
`scene=${data && data.scene ? (data.scene.name || data.scene._name) : '?'}`);
|
|
if (onComplete)
|
|
onComplete(err, data);
|
|
};
|
|
return orig(json, options, wProgress, wComplete);
|
|
};
|
|
}
|
|
const dr = legacy.director;
|
|
if (dr && dr.runSceneImmediate) {
|
|
const orig = dr.runSceneImmediate.bind(dr);
|
|
dr.runSceneImmediate = (scene, onBeforeLoadScene, onLaunched) => {
|
|
log(`runSceneImmediate 调用 scene=${scene && (scene.name || scene._name)}`);
|
|
return orig(scene, onBeforeLoadScene, onLaunched);
|
|
};
|
|
}
|
|
// console 全量转发已由 hookConsoleForward 在渲染早期安装,此处不再重复包装
|
|
log('运行期跟踪已安装 (game.run/loadWithJson/runSceneImmediate)');
|
|
return true;
|
|
};
|
|
if (installNow()) {
|
|
return;
|
|
}
|
|
// System.register 惰性执行:window.cc 尚未就绪,轮询等待(最多约 10s)
|
|
let tries = 0;
|
|
const timer = window.setInterval(() => {
|
|
tries++;
|
|
if (installNow() || tries > 400) {
|
|
window.clearInterval(timer);
|
|
}
|
|
}, 25);
|
|
},
|
|
/** 场景加载看门狗:bootFn 成功后每 2 秒检查一次 director.getScene(),
|
|
* 若长时间无场景则输出引擎状态快照(paused/pacer/assets),区分
|
|
* 「主循环未运行」与「资源管线挂起」两类卡点。重渲染时自动失效。 */
|
|
startSceneWatchdog() {
|
|
const seq = this._renderSeq;
|
|
const log = (msg) => this.logs.push({ evt: 'sys', msg: `[预览跟踪] ${msg}` });
|
|
const legacy = window.cc || window.cclegacy;
|
|
let waited = 0;
|
|
const MAX_TIMEOUT_LOG = 2; // 场景久不出现时最多提示几轮,避免定时器持续刷屏
|
|
let timeoutLogs = 0;
|
|
const timer = window.setInterval(() => {
|
|
var _a, _b, _c, _d;
|
|
if (this._renderSeq !== seq || !this.previewLoaded) {
|
|
window.clearInterval(timer);
|
|
return;
|
|
}
|
|
waited += 2;
|
|
let sc = null;
|
|
try {
|
|
sc = (_b = (_a = legacy === null || legacy === void 0 ? void 0 : legacy.director) === null || _a === void 0 ? void 0 : _a.getScene) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
}
|
|
catch (_) {
|
|
/* ignore */
|
|
}
|
|
if (sc) {
|
|
log(`场景已出现: ${sc.name || sc._name || '?'}`);
|
|
window.clearInterval(timer);
|
|
return;
|
|
}
|
|
if (waited >= 24 && timeoutLogs < MAX_TIMEOUT_LOG) {
|
|
let paused = '?';
|
|
let pacer = '?';
|
|
try {
|
|
const gg = legacy === null || legacy === void 0 ? void 0 : legacy.game;
|
|
paused = String(!!(gg && gg._paused));
|
|
pacer = gg && gg._pacer ? String(!!gg._pacer._isPlaying) : '无pacer';
|
|
}
|
|
catch (_) {
|
|
/* ignore */
|
|
}
|
|
let assets = 0;
|
|
try {
|
|
assets = ((_d = (_c = legacy === null || legacy === void 0 ? void 0 : legacy.assetManager) === null || _c === void 0 ? void 0 : _c.assets) === null || _d === void 0 ? void 0 : _d.count) || 0;
|
|
}
|
|
catch (_) {
|
|
/* ignore */
|
|
}
|
|
timeoutLogs++;
|
|
log(`场景等待超时 ${waited}s: paused=${paused} pacer=${pacer} assets=${assets}`);
|
|
if (timeoutLogs >= MAX_TIMEOUT_LOG) {
|
|
window.clearInterval(timer);
|
|
}
|
|
}
|
|
}, 2000);
|
|
},
|
|
/** 探测预览服务是否在线(no-cors 请求,跨域只判连通性,不读内容)。 */
|
|
async checkPreview() {
|
|
if (this.previewChecking) {
|
|
return;
|
|
}
|
|
// 节流:至少 3 秒探测一次
|
|
if (Date.now() - this.previewCheckAt < 3000) {
|
|
return;
|
|
}
|
|
this.previewChecking = true;
|
|
const url = (this.previewUrl || '').trim();
|
|
try {
|
|
if (!url) {
|
|
this.previewOnline = false;
|
|
return;
|
|
}
|
|
const ctl = new AbortController();
|
|
const timer = window.setTimeout(() => ctl.abort(), 6000);
|
|
await fetch(url, { method: 'GET', mode: 'no-cors', cache: 'no-store', signal: ctl.signal });
|
|
window.clearTimeout(timer);
|
|
this.previewOnline = true;
|
|
}
|
|
catch (_a) {
|
|
this.previewOnline = false;
|
|
}
|
|
finally {
|
|
this.previewCheckAt = Date.now();
|
|
this.previewChecking = false;
|
|
}
|
|
},
|
|
onResize() {
|
|
if (this.showPerf) {
|
|
this.drawPerf();
|
|
}
|
|
},
|
|
startDrag(kind, e) {
|
|
e.preventDefault();
|
|
const el = e.currentTarget;
|
|
if (el && el.setPointerCapture) {
|
|
try {
|
|
el.setPointerCapture(e.pointerId);
|
|
}
|
|
catch (_) {
|
|
/* 捕获失败也不影响 window 级监听 */
|
|
}
|
|
}
|
|
document.body.style.userSelect = 'none';
|
|
document.body.style.cursor = 'col-resize';
|
|
this.drag = {
|
|
kind,
|
|
startX: e.clientX,
|
|
startW: kind === 'left' ? this.treeWidth : this.detailWidth,
|
|
pointerId: e.pointerId,
|
|
el,
|
|
};
|
|
},
|
|
onDragMove(e) {
|
|
if (!this.drag) {
|
|
return;
|
|
}
|
|
const dx = e.clientX - this.drag.startX;
|
|
const w = this.drag.kind === 'left' ? this.drag.startW + dx : this.drag.startW - dx;
|
|
const clamped = Math.max(140, Math.min(480, w));
|
|
if (this.drag.kind === 'left') {
|
|
this.treeWidth = clamped;
|
|
}
|
|
else {
|
|
this.detailWidth = clamped;
|
|
}
|
|
},
|
|
endDrag() {
|
|
if (!this.drag) {
|
|
return;
|
|
}
|
|
if (this.drag.el && this.drag.el.hasPointerCapture && this.drag.el.hasPointerCapture(this.drag.pointerId)) {
|
|
try {
|
|
this.drag.el.releasePointerCapture(this.drag.pointerId);
|
|
}
|
|
catch (_) {
|
|
/* ignore */
|
|
}
|
|
}
|
|
document.body.style.userSelect = '';
|
|
document.body.style.cursor = '';
|
|
this.drag = null;
|
|
},
|
|
};
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldmlldy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NvdXJjZS9wYW5lbHMvZGVmYXVsdC9tZXRob2RzL3ByZXZpZXcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxhQUFhO0FBQ2IsNEVBQW1EO0FBRW5EOzs7Ozs7Ozs7R0FTRztBQUVIO3lEQUN5RDtBQUN6RCxTQUFTLFlBQVk7SUFDakIsTUFBTSxRQUFRLEdBQStCLEVBQUUsQ0FBQztJQUNoRCxPQUFPO1FBQ0gsRUFBRSxDQUFDLEdBQVcsRUFBRSxFQUFZO1lBQ3hCLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDL0MsT0FBTyxJQUFJLENBQUM7UUFDaEIsQ0FBQztRQUNELEdBQUcsQ0FBQyxHQUFXO1lBQ1gsT0FBTyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckIsT0FBTyxJQUFJLENBQUM7UUFDaEIsQ0FBQztRQUNELElBQUksQ0FBQyxHQUFXLEVBQUUsR0FBRyxJQUFXO1lBQzVCLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUMzRCxPQUFPLElBQUksQ0FBQztRQUNoQixDQUFDO1FBQ0QsS0FBSztZQUNELEtBQUssTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUNwQyxPQUFPLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2QixDQUFDO1FBQ0wsQ0FBQztLQUNKLENBQUM7QUFDTixDQUFDO0FBRUQ7OzsyREFHMkQ7QUFDM0QsTUFBTSxZQUFZLEdBQTREO0lB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LENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUM1RCxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDVCxZQUFZO1lBQ2hCLENBQUM7UUFDTCxDQUFDO1FBQ0QsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNwQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ3JCLENBQUM7Q0FDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWlnbm9yZVxuaW1wb3J0IHBhY2thZ2VKU09OIGZyb20gJy4uLy4uLy4uLy4uL3BhY2thZ2UuanNvbic7XG5cbi8qKlxuICog6aKE6KeI77ya5Zyw5Z2A6K+75Y+WL+WIt+aWsC/ov57pgJrmgKfmjqLmtYsgKyDml6AgaWZyYW1lIOeahCBET00g5riy5p+TICsg5bem5Y+z5YiG6ZqU5p2h5ouW5ou944CCXG4gKlxuICog6Z2i5p2/5YaF55u05o6l5riy5p+T5ri45oiP77yI5LiN55SoIGlmcmFtZe+8ieeahOWKoOi9vemTvui3r++8mlxuICogICAxLiDmjInluo/liqDovb3lvJXmk47ohJrmnKzvvIg8c2NyaXB0PiDmoIfnrb7ot6jln5/liqDovb0gSlMg5LiN5Y+XIENPUlMg6ZmQ5Yi277yJXG4gKiAgIDIuIGltcG9ydC1tYXAg5YaF55qE55u45a+5L+e7neWvuei3r+W+hOWfuuS6juOAjOmdouadvyBvcmlnaW7jgI3op6PmnpDkvJogNDA077yMXG4gKiAgICAgIOWboOatpOWFiOivu+WPluWOn+WniyBtYXAg5YaF5a6577yM5oqK5omA5pyJ6Lev5b6E6YeN5YaZ5Li66aKE6KeI5pyN5Yqh57ud5a+5IFVSTCDlkI7lho3ms6jlhaVcbiAqICAgMy4g5pyA57uIIFN5c3RlbS5pbXBvcnQocHJldmlldy1hcHApIOS4juW8leaTjuWGhemDqCBmZXRjaCDotYTmupDlsZ7kuo7ot6jln5/or7fmsYLvvIxcbiAqICAgICAg5piv5ZCm5oiQ5Yqf5Y+W5Yaz5LqO6aKE6KeI5pyN5Yqh5Zmo5piv5ZCm6L+U5ZueIENPUlMg5aS077yI5a6e5rWL6aqM6K+B54K577yJXG4gKi9cblxuLyoqIHNvY2tldC5pbyDmnIDlsI8gc3R1Yu+8mkV2ZW50RW1pdHRlciDor63kuYnvvIzmu6HotrMgcHJldmlldy1hcHAg55qEIG4ub24oKS90LmVtaXQoKSDosIPnlKjjgIJcbiAqICDkuI3lj5HotbfnnJ/lrp4gc29ja2V0LmlvIOi/nuaOpe+8iOmdouadvyBvcmlnaW4g5LiO6aKE6KeI5pyN5Yqh5LiN5LiA6Ie077yM6L+e5o6l5b+F54S25aSx6LSl5LiU5peg5oSP5LmJ77yJ44CCICovXG5mdW5jdGlvbiBzb2NrZXRJb1N0dWIoKTogYW55IHtcbiAgICBjb25zdCBoYW5kbGVyczogUmVjb3JkPHN0cmluZywgRnVuY3Rpb25bXT4gPSB7fTtcbiAgICByZXR1cm4ge1xuICAgICAgICBvbihldnQ6IHN0cmluZywgZm46IEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICAoaGFuZGxlcnNbZXZ0XSA9IGhhbmRsZXJzW2V2dF0gfHwgW10pLnB1c2goZm4pO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG4gICAgICAgIG9mZihldnQ6IHN0cmluZykge1xuICAgICAgICAgICAgZGVsZXRlIGhhbmRsZXJzW2V2dF07XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcbiAgICAgICAgZW1pdChldnQ6IHN0cmluZywgLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgICAgIChoYW5kbGVyc1tldnRdIHx8IFtdKS5zbGljZSgpLmZvckVhY2goKGZuKSA9PiBmbiguLi5hcmdzKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcbiAgICAgICAgY2xvc2UoKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGsgb2YgT2JqZWN0LmtleXMoaGFuZGxlcnMpKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGhhbmRsZXJzW2tdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgIH07XG59XG5cbi8qKiDorr7lpIflsLrlr7jooajvvIjplK7kuI7nnJ/lrp7pooTop4jmnI3liqHmuLLmn5PnmoQgZGF0YS1kZXZpY2Ug5a6M5YWo5LiA6Ie077yJ44CCXG4gKiAg6Z2i5p2/5YaFIGV4YWN0Rml0U2NyZWVuPWZhbHNl77yIU3ViRnJhbWXvvInmqKHlvI/kuIvlvJXmk47nlLvluIPot5/pmo8gI0dhbWVEaXYg5a655Zmo5bC65a+444CBXG4gKiAg5b+955WlIHNjcmVlbi53aW5kb3dTaXpl77yM5Zug5q2k6K6+5aSH5YiH5o2i6KaB5Zyo5YmN56uv5oqKICNHYW1lRGl2IOiuvuaIkOebruagh+avlOS+i+WxheS4reaYvuekuuOAglxuICogIOeyvueugOmbhu+8muavj+aho+WPqueVmeS4gOS4quS7o+ihqOacuuWei++8jOWIhui+qOeOh+S4jemHjeWkje+8m+mUruW/hemhu+iDveiiqyBwcmV2aWV3LWFwcC5fZGV2aWNlcyDor4bliKvjgIIgKi9cbmNvbnN0IERFVklDRV9TSVpFUzogUmVjb3JkPHN0cmluZywgeyB3OiBudW1iZXI7IGg6IG51bWJlcjsgbGFiZWw6IHN0cmluZyB9PiA9IHtcbiAgICAnRGVmYXVsdCc6IHsgdzogOTYwLCBoOiA2NDAsIGxhYmVsOiAn6K6+6K6h5YiG6L6o546HJyB9LFxuICAgICdBcHBsZSBpUGhvbmUgMTI7IDEzOyAxNDsgMTIvMTMgUHJvJzogeyB3OiAzOTAsIGg6IDg0NCwgbGFiZWw6ICdpUGhvbmUgMTIvMTMvMTQnIH0sXG4gICAgJ0FwcGxlIGlQaG9uZSAxNCBQcm8nOiB7IHc6IDM5MywgaDogODUyLCBsYWJlbDogJ2lQaG9uZSAxNCBQcm8nIH0sXG4gICAgJ0FwcGxlIGlQaG9uZSAxMi8xMyBQcm8gTWF4OyAxNCBQbHVzJzogeyB3OiA0MjgsIGg6IDkyNiwgbGFiZWw6ICdpUGhvbmUgUHJvIE1heC8xNCBQbHVzJyB9LFxuICAgICdBcHBsZSBpUGhvbmUgWFI7IDExJzogeyB3OiA0MTQsIGg6IDg5NiwgbGFiZWw6ICdpUGhvbmUgWFIvMTEnIH0sXG4gICAgJ0FwcGxlIGlQaG9uZSBYOyBYUzsgMTEgUHJvOyAxMi8xMyBNaW5pJzogeyB3OiAzNzUsIGg6IDgxMiwgbGFiZWw6ICdpUGhvbmUgWC9YUycgfSxcbiAgICAnQXBwbGUgaVBhZCAxMC4yJzogeyB3OiAxNjIwLCBoOiAyMTYwLCBsYWJlbDogJ2lQYWQgMTAuMicgfSxcbiAgICAnSFVBV0VJIE1hdGUgNDAgUHJvJzogeyB3OiA0NDgsIGg6IDkyNCwgbGFiZWw6ICdIVUFXRUkgTWF0ZSA0MCBQcm8nIH0sXG4gICAgJ09QUE8gUmVubyAyJzogeyB3OiAzNjAsIGg6IDgwMCwgbGFiZWw6ICdPUFBPIFJlbm8gMicgfSxcbiAgICAnWGlhb21pIFJlZG1pIDgnOiB7IHc6IDM2MCwgaDogNzYwLCBsYWJlbDogJ1hpYW9taSBSZWRtaSA4JyB9LFxuICAgICdMZW5vdm8gTGVnaW9uIDIgUHJvJzogeyB3OiAzNjAsIGg6IDgyMCwgbGFiZWw6ICdMZW5vdm8gTGVnaW9uIDIgUHJvJyB9LFxufTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIGFzeW5jIGluaXRQcmV2aWV3SW5mbyh0aGlzOiBhbnkpIHtcbiAgICAgICAgLy8g6K6+6K6h5YiG6L6o546H6buY6K6kIDk2MMOXNjQw77yM6ZqP5ZCO55So6aG555uu55yf5a6e6YWN572u6KaG55uW77yIRGVmYXVsdCDnrYnmr5Top4blj6Pku6XmraTkuLrln7rlh4bvvIlcbiAgICAgICAgdGhpcy5wcmVmRGVzaWduVyA9IDk2MDtcbiAgICAgICAgdGhpcy5wcmVmRGVzaWduSCA9IDY0MDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IFtpbmZvLCBwcm9qXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICBFZGl0b3IuTWVzc2FnZS5yZXF1ZXN0KHBhY2thZ2VKU09OLm5hbWUgYXMgYW55LCAnZ2V0LXByZXZpZXctaW5mbycgYXMgYW55KSxcbiAgICAgICAgICAgICAgICBFZGl0b3IuTWVzc2FnZS5yZXF1ZXN0KHBhY2thZ2VKU09OLm5hbWUgYXMgYW55LCAnZ2V0LXByb2plY3RzLXNldHRpbmdzJyBhcyBhbnkpLFxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICBpZiAoaW5mbyAmJiBpbmZvLnVybCkge1xuICAgICAgICAgICAgICAgIHRoaXMucHJldmlld1VybCA9IGluZm8udXJsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZCA9IHByb2ogJiYgcHJvai5kZXNpZ25SZXNvbHV0aW9uO1xuICAgICAgICAgICAgaWYgKGQgJiYgTnVtYmVyKGQud2lkdGgpID4gMCAmJiBOdW1iZXIoZC5oZWlnaHQpID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMucHJlZkRlc2lnblcgPSBOdW1iZXIoZC53aWR0aCk7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmVmRGVzaWduSCA9IE51bWJlcihkLmhlaWdodCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8g5L+d5oyB6buY6K6k5Zyw5Z2AL+WIhui+qOeOh1xuICAgICAgICB9XG4gICAgfSxcbiAgICAvKiog5b2T5YmN6aG555uu6K6+6K6h5YiG6L6o546H77yI6K+75Y+W5aSx6LSl5Zue5YiwIDk2MMOXNjQw77yJ44CCICovXG4gICAgcHJlZkRlc2lnbih0aGlzOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHc6IE51bWJlcih0aGlzLnByZWZEZXNpZ25XKSA+IDAgPyBOdW1iZXIodGhpcy5wcmVmRGVzaWduVykgOiA5NjAsXG4gICAgICAgICAgICBoOiBOdW1iZXIodGhpcy5wcmVmRGVzaWduSCkgPiAwID8gTnVtYmVyKHRoaXMucHJlZkRlc2lnbkgpIDogNjQwLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgLyoqIOWcsOWdgOagj+Wbnui9piAvIOeCueOAjOWIt+aWsOOAjS8g6YGu572p6YeN6K+V77ya6YeN5paw5riy5p+T5ri45oiP55S76Z2i44CCICovXG4gICAgb25Mb2FkUHJldmlldyh0aGlzOiBhbnkpIHtcbiAgICAgICAgdGhpcy5wcmV2aWV3TG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHJldmlld1JlbmRlckVyciA9ICcnO1xuICAgICAgICB0aGlzLnJlbmRlclByZXZpZXcoKTtcbiAgICB9LFxuICAgIC8vID09PT09IOmihOiniOW3peWFt+adoe+8muaWsOeJiOmdouW3peWFt+adoemAmui/h+mpseWKqOOAjOmakOiXjyBINSDlt6XlhbfmnaHjgI3kuI7lvJXmk47ogZTliqggPT09PT1cbiAgICAvLyDlvJXmk44gcHJldmlldy1hcHAg55SoIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyN2aWV3LXNlbGVjdCcvJyNidG4tcm90YXRlJy8nI2lucHV0LXNldC1mcHMnL1xuICAgIC8vICcjYnRuLXNob3ctZnBzJy8nI2J0bi1wYXVzZScvJyNidG4tc3RlcCcpIOe7keWumuS6i+S7tu+8jOmdouadv+WGheeahOivpeW3peWFt+adoeiiqyBDU1Mg6ZqQ6JeP77yMXG4gICAgLy8g5Y+q5L2c5pWw5o2u5aWR57qm44CC6L+Z6YeM55So55yf5a6eIERPTSDkuovku7bmqKHmi5/nlKjmiLfmk43kvZzvvIzkuI7miYvngrnmlYjmnpzkuIDoh7TjgIJcbiAgICAvKiog6K6+5aSHL+WIhui+qOeOh+WIh+aNou+8mueCuemAiemakOiXjyAjdmlldy1zZWxlY3Qg55qE5a+55bqU6YCJ6aG544CCICovXG4gICAgb25QcmV2aWV3RGV2aWNlKHRoaXM6IGFueSwgZGV2aWNlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5wcmV2aWV3RGV2aWNlID0gZGV2aWNlO1xuICAgICAgICBjb25zdCBlbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyN2aWV3LXNlbGVjdCcpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICAgICAgaWYgKCFlbCkgcmV0dXJuO1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3ZhbHVlJywgZGV2aWNlKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IGVsLnF1ZXJ5U2VsZWN0b3IoJyNuYW1lJykgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICAgICAgICBpZiAobmFtZSkgKG5hbWUgYXMgSFRNTEVsZW1lbnQpLnRleHRDb250ZW50ID0gZGV2aWNlO1xuICAgICAgICBlbC5xdWVyeVNlbGVjdG9yQWxsPEhUTUxFbGVtZW50PignLm9wdGlvbnMgbGknKS5mb3JFYWNoKChsaSkgPT4ge1xuICAgICAgICAgICAgaWYgKGxpLmdldEF0dHJpYnV0ZSgnZGF0YS1kZXZpY2UnKSA9PT0gZGV2aWNlKSB7XG4gICAgICAgICAgICAgICAgbGkuY2xhc3NMaXN0LmFkZCgnc2VsZWN0ZWQnKTtcbiAgICAgICAgICAgICAgICBsaS5kaXNwYXRjaEV2ZW50KG5ldyBNb3VzZUV2ZW50KCdtb3VzZWRvd24nLCB7IGJ1YmJsZXM6IHRydWUsIGNhbmNlbGFibGU6IHRydWUgfSkpO1xuICAgICAgICAgICAgICAgIGxpLmRpc3BhdGNoRXZlbnQobmV3IE1vdXNlRXZlbnQoJ21vdXNldXAnLCB7IGJ1YmJsZXM6IHRydWUsIGNhbmNlbGFibGU6IHRydWUgfSkpO1xuICAgICAgICAgICAgICAgIGxpLmRpc3BhdGNoRXZlbnQobmV3IE1vdXNlRXZlbnQoJ2NsaWNrJywgeyBidWJibGVzOiB0cnVlLCBjYW5jZWxhYmxlOiB0cnVlIH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbGkuY2xhc3NMaXN0LnJlbW92ZSgnc2VsZWN0ZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIOmdouadv+WGhSBTdWJGcmFtZSDmqKHlvI/lvJXmk47nlLvluIPot5/pmo8gI0dhbWVEaXYg5a655Zmo5bC65a+477yM6K6+5aSH5YiH5o2i6ZyA5Zyo5q2k6K6+5a655Zmo5q+U5L6L77yMXG4gICAgICAgIC8vIOWQpuWImSBwcmV2aWV3LWFwcCDlj6rmlLkgc2NyZWVuLndpbmRvd1NpemUg5LiN5Lqn55Sf6KeG6KeJ5Y+Y5YyW77yI55yf5a6eIEg1IOaJjeeUn+aViO+8ieOAglxuICAgICAgICB0aGlzLmFwcGx5RGV2aWNlVmlld3BvcnQoZGV2aWNlKTtcbiAgICB9LFxuICAgIC8qKiDorr7lpIcv57yp5pS+6KeG5Y+j77ya5oqKICNHYW1lRGl2IOiuvuaIkCDorr7lpIfmr5Tkvosgw5cg57yp5pS+5Zug5a2QIOeahOecn+WunuWwuuWvuOW5tuWxheS4reOAglxuICAgICAqICDlvJXmk44gU3ViRnJhbWUg5qih5byP5oyJICNHYW1lRGl2IOWunumZheWwuuWvuOmHjeW7uueUu+W4g++8jOWboOatpOeUu+mdouavlOS+i+S4jui+k+WFpeaYoOWwhOWni+e7iOS4gOiHtO+8jFxuICAgICAqICDku7vmhI/nvKnmlL7mr5TkuIvngrnlh7vpg73kuI3kvJrplJnkvY3jgILmqKrnq5blsY/mlrnlkJHvvIhwcmV2aWV3Um90YXRlZO+8ieS6pOaNouWuvemrmOOAglxuICAgICAqICDpnZ7lsLrlr7jmmKDlsITvvIhGdWxsU2NyZWVuL1dlYnBhZ2XvvInlm57liLDpk7rmu6HjgIHkuI3lupTnlKjnvKnmlL7jgIIgKi9cbiAgICBhcHBseURldmljZVZpZXdwb3J0KHRoaXM6IGFueSwgZGV2aWNlOiBzdHJpbmcsIHpvb20gPSB0aGlzLnByZXZpZXdab29tKSB7XG4gICAgICAgIGNvbnN0IGdkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ0dhbWVEaXYnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgICAgIGlmICghZ2QpIHJldHVybjtcbiAgICAgICAgbGV0IGQgPSBERVZJQ0VfU0laRVNbZGV2aWNlXTtcbiAgICAgICAgY29uc3QgaG9zdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd5eWthLWdhbWUtaG9zdCcpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICAgICAgaWYgKCFkIHx8ICFob3N0KSB7XG4gICAgICAgICAgICBnZC5zdHlsZS53aWR0aCA9ICcnO1xuICAgICAgICAgICAgZ2Quc3R5bGUuaGVpZ2h0ID0gJyc7XG4gICAgICAgICAgICBnZC5zdHlsZS5tYXJnaW4gPSAnJztcbiAgICAgICAgICAgIHdpbmRvdy5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgncmVzaXplJykpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZXZpY2UgPT09ICdEZWZhdWx0Jykge1xuICAgICAgICAgICAgLy8g6K6+6K6h5YiG6L6o546H5Y+W6aG555uu55yf5a6e6YWN572u77yI5Yu/55So5Zu65a6aIDk2MMOXNjQw77yJXG4gICAgICAgICAgICBjb25zdCBwZCA9IHRoaXMucHJlZkRlc2lnbigpO1xuICAgICAgICAgICAgZCA9IHsgdzogcGQudywgaDogcGQuaCwgbGFiZWw6ICforr7orqHliIbovqjnjocnIH07XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGR3ID0gZC53LCBkaCA9IGQuaDtcbiAgICAgICAgaWYgKHRoaXMucHJldmlld1JvdGF0ZWQpIHtcbiAgICAgICAgICAgIGR3ID0gZC5oOyBkaCA9IGQudzsgLy8g56uW5bGPIOKGlCDmqKrlsY/vvIzkuqTmjaLlrr3pq5hcbiAgICAgICAgfVxuICAgICAgICAvLyDpooTop4jljLrvvIguZ2FtZS12aWV377yJ5Z+65YeG77yM562J5q+U5pS+5YWl6K+l6K6+5aSH77yIem9vbT0xIOaBsOWlveaUvuWFpe+8ieOAglxuICAgICAgICAvLyDorr7lpIfmqKHlvI/lj6rnlZkgMTJweCDlpJbovrnot53vvIzlpJblo7PlsL3ph4/lpKfvvIzorqnmuLjmiI/nqpflj6PmkpHmu6Hlo7PlhoXpg6jjgIHlm5vop5LooqvlnIbop5Loo4HliIfmiJDlhajpnaLlsY/vvJtcbiAgICAgICAgLy8gRGVmYXVsdCDnlZkgMzJweOOAglxuICAgICAgICBjb25zdCBpc0RldiA9IGRldmljZSAhPT0gJ0RlZmF1bHQnICYmICEhZDtcbiAgICAgICAgY29uc3QgcGFkID0gaXNEZXYgPyAxMiA6IDMyO1xuICAgICAgICBjb25zdCBhdyA9IE1hdGgubWF4KDEsIGhvc3QuY2xpZW50V2lkdGggLSBwYWQpO1xuICAgICAgICBjb25zdCBhaCA9IE1hdGgubWF4KDEsIGhvc3QuY2xpZW50SGVpZ2h0IC0gcGFkKTtcbiAgICAgICAgbGV0IHcgPSBhdywgaCA9IGF3ICogKGRoIC8gZHcpO1xuICAgICAgICBpZiAoaCA+IGFoKSB7XG4gICAgICAgICAgICBoID0gYWg7IHcgPSBhaCAqIChkdyAvIGRoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB6ID0gTWF0aC5tYXgoMC4yLCBNYXRoLm1pbig4LCB6b29tKSk7XG4gICAgICAgIGNvbnN0IHdpblcgPSBNYXRoLm1heCgxMCwgdyAqIHopLCB3aW5IID0gTWF0aC5tYXgoMTAsIGggKiB6KTtcbiAgICAgICAgY29uc3QgZnJhbWUgPSBob3N0LnF1ZXJ5U2VsZWN0b3IoJy5kZXZpY2UtZnJhbWUnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgICAgIGNvbnN0IGlzRGV2aWNlID0gISFkICYmIGRldmljZSAhPT0gJ0RlZmF1bHQnO1xuICAgICAgICBpZiAoZnJhbWUpIGZyYW1lLmNsYXNzTGlzdC50b2dnbGUoJ2RldmljZScsIGlzRGV2aWNlKTtcbiAgICAgICAgaWYgKGlzRGV2aWNlICYmIGZyYW1lKSB7XG4gICAgICAgICAgICAvLyDnnJ/mnLrmr5TkvovvvJrlsY/luZXvvIgjR2FtZURpdu+8ieaMieiuvuWkh+WuvemrmOavlOWwvemHj+aUvuWkp+WxheS4re+8m+WkluWjs+i3n+maj+Wxj+W5le+8jFxuICAgICAgICAgICAgLy8g6L655qGG6LS0552A5bGP5bmV5Zub5ZGo5LiA6LW357yp5pS+77yI5aSW5aOz5bC65a+4ID0g5bGP5bmVICsg57uG6L655qGG77yJ44CCXG4gICAgICAgICAgICAvLyDml4vovazvvIhwcmV2aWV3Um90YXRlZO+8ieW3suWcqCBkdy9kaCDkuqTmjaLov4fvvIzlm6DmraTlpJblo7PlvaLnirbkvJrpmo/mqKrnq5blsY/lj5jljJbjgIJcbiAgICAgICAgICAgIGNvbnN0IGJlelggPSA0MiwgYmV6WSA9IDU0OyAvLyDpooTnlZnkvZnph4/vvJrlpJblo7PmlbTkvZPlnKjpooTop4jljLrlhoXnvKnkuIDlnIjvvIzlm5vlkajpnLLlh7rog4zmma/vvIzpgb/lhY3otLTlubPmiJBcIuW5s+mdolwiXG4gICAgICAgICAgICBjb25zdCBtdyA9IGhvc3QuY2xpZW50V2lkdGgsIG1oID0gaG9zdC5jbGllbnRIZWlnaHQ7XG4gICAgICAgICAgICBsZXQgc3cgPSBtdyAtIGJlelgsIHNoID0gc3cgKiAoZGggLyBkdyk7XG4gICAgICAgICAgICBpZiAoc2ggPiBtaCAtIGJlelkpIHtcbiAgICAgICAgICAgICAgICBzaCA9IG1oIC0gYmV6WTtcbiAgICAgICAgICAgICAgICBzdyA9IHNoICogKGR3IC8gZGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGZ3ID0gc3cgKiB6LCBmaCA9IHNoICogejtcbiAgICAgICAgICAgIC8vIOe8qeaUvuS4iumZkO+8muaUvuWkp+aXtuaVtOS9k+S4jei2heWHuumihOiniOinhuWPo++8jOWbm+WRqOeVmSBlZmZQYWQg5L2Z5Zyw77yM562J5q+U5pS257yp6Ziy5rqi5Ye6XG4gICAgICAgICAgICBjb25zdCBlZmZQYWQgPSAxMjtcbiAgICAgICAgICAgIGNvbnN0IG1heFcgPSBtdyAtIGVmZlBhZCwgbWF4SCA9IG1oIC0gZWZmUGFkO1xuICAgICAgICAgICAgaWYgKGZ3ID4gbWF4VyB8fCBmaCA+IG1heEgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByID0gTWF0aC5taW4obWF4VyAvIGZ3LCBtYXhIIC8gZmgpO1xuICAgICAgICAgICAgICAgIGZ3ICo9IHI7IGZoICo9IHI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmcmFtZS5zdHlsZS53aWR0aCA9IE1hdGgubWF4KDIwLCBNYXRoLnJvdW5kKGZ3KSkgKyAncHgnO1xuICAgICAgICAgICAgZnJhbWUuc3R5bGUuaGVpZ2h0ID0gTWF0aC5tYXgoMjAsIE1hdGgucm91bmQoZmgpKSArICdweCc7XG4gICAgICAgICAgICBmcmFtZS5zdHlsZS5tYXJnaW4gPSAnYXV0byc7XG4gICAgICAgICAgICBnZC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICAgICAgICAgIGdkLnN0eWxlLmhlaWdodCA9ICcxMDAlJztcbiAgICAgICAgICAgIGdkLnN0eWxlLm1hcmdpbiA9ICcwJztcbiAgICAgICAgICAgIC8vIOeBteWKqOWym+maj+e8qeaUvuiBlOWKqO+8muWPluacuui6q+efrei+ueeahOS4gOWumuavlOS+i+S9nOS4uuWuveW6pu+8jFxuICAgICAgICAgICAgLy8g5qiq56uW5bGP77yI55+t6L655LiN5Y+Y77yJ5bC65a+456iz5a6a77yM57yp5pS+5aSn5bCP5pe25ZCM5q2l57yp5pS+77yI5L2/55So5YOP57Sg6YG/5YWN5qiq5bGP55u45a+55pS+5aSn77yJ44CCXG4gICAgICAgICAgICBjb25zdCBpc28gPSBmcmFtZS5xdWVyeVNlbGVjdG9yKCcuZHluYW1pYy1pc2xhbmQnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgICAgICAgICBpZiAoaXNvKSB7XG4gICAgICAgICAgICAgICAgaXNvLnN0eWxlLndpZHRoID0gTWF0aC5tYXgoMjQsIE1hdGgucm91bmQoTWF0aC5taW4oZncsIGZoKSAqIDAuMjYpKSArICdweCc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyDmma7pgJovRGVmYXVsdCDop4blj6PvvJrmjInorr7orqHliIbovqjnjofnrYnmr5TlsYXkuK3vvIzlkIzmoLfpmZDluYXkuI3otoXop4blj6PlubbnlZnovrnot53jgIJcbiAgICAgICAgICAgIC8vIOWwuuWvuOi9veS9k+eUqCAuZGV2aWNlLWZyYW1lIOWkluWjs+iAjOmdniAjR2FtZURpdu+8mumdouadvyBDU1Mg5a+5ICNHYW1lRGl2IOaciVxuICAgICAgICAgICAgLy8gd2lkdGgvaGVpZ2h0OjEwMCUhaW1wb3J0YW5077yM5YaZ5Zyo5YW25LiK55qE5YaF6IGU5YOP57Sg5LiN55Sf5pWI77yb6Iul5aSW5aOz5L+d5oyBXG4gICAgICAgICAgICAvLyBtYXgtY29udGVudO+8jOaVtOadoemTvuS8muWbnuiQveaIkCBjYW52YXMg5YWD57Sg5Zu65pyJ5bC65a+477yI5byV5pOO5oqKIGNhbnZhcy53aWR0aFxuICAgICAgICAgICAgLy8g6K6+5oiQIHNjcmVlbi53aW5kb3dTaXplID0gI0dhbWVEaXYuY2xpZW50V2lkdGjDl2Rwcu+8jGRwcj4xIOaXtuS4jeaWreaUvuWkp++8ie+8jFxuICAgICAgICAgICAgLy8g5a+86Ie05ri45oiP56qX5Y+j5q+U6KeG5Y+j5aSn44CB6KKr6KOB5Ymq44CC57uZ5aSW5aOz5YaZ56Gu5a6a55qEIGZpdCDlg4/ntKDlkI4gI0dhbWVEaXY9MTAwJVxuICAgICAgICAgICAgLy8g6Lef6ZqP77yM5bC65a+45a6M5YWo56Gu5a6a77yM5LiN5YaN5pyJIG1heC1jb250ZW50IOWPjemmiOaUvuWkp++8iOS4juiuvuWkh+aooeW8j+WQjOaehO+8ieOAglxuICAgICAgICAgICAgY29uc3QgZWZmUGFkID0gMzI7XG4gICAgICAgICAgICBjb25zdCBtYXhXID0gaG9zdC5jbGllbnRXaWR0aCAtIGVmZlBhZCwgbWF4SCA9IGhvc3QuY2xpZW50SGVpZ2h0IC0gZWZmUGFkO1xuICAgICAgICAgICAgbGV0IHdpblcyID0gdyAqIHosIHdpbkgyID0gaCAqIHo7XG4gICAgICAgICAgICBpZiAod2luVzIgPiBtYXhXIHx8IHdpbkgyID4gbWF4SCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBNYXRoLm1pbihtYXhXIC8gd2luVzIsIG1heEggLyB3aW5IMik7XG4gICAgICAgICAgICAgICAgd2luVzIgKj0gcjsgd2luSDIgKj0gcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHB4VyA9IE1hdGgubWF4KDIwLCBNYXRoLnJvdW5kKHdpblcyKSkgKyAncHgnO1xuICAgICAgICAgICAgY29uc3QgcHhIID0gTWF0aC5tYXgoMjAsIE1hdGgucm91bmQod2luSDIpKSArICdweCc7XG4gICAgICAgICAgICBpZiAoZnJhbWUpIHtcbiAgICAgICAgICAgICAgICBmcmFtZS5zdHlsZS53aWR0aCA9IHB4VztcbiAgICAgICAgICAgICAgICBmcmFtZS5zdHlsZS5oZWlnaHQgPSBweEg7XG4gICAgICAgICAgICAgICAgZnJhbWUuc3R5bGUubWFyZ2luID0gJ2F1dG8nO1xuICAgICAgICAgICAgICAgIGdkLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgICAgICAgICAgICAgIGdkLnN0eWxlLmhlaWdodCA9ICcxMDAlJztcbiAgICAgICAgICAgICAgICBnZC5zdHlsZS5tYXJnaW4gPSAnMCc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGdkLnN0eWxlLndpZHRoID0gcHhXO1xuICAgICAgICAgICAgICAgIGdkLnN0eWxlLmhlaWdodCA9IHB4SDtcbiAgICAgICAgICAgICAgICBnZC5zdHlsZS5tYXJnaW4gPSAnYXV0byc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8g5byV5pOO55S76Z2i6ZO65ruh562W55Wl77ya6K6+5aSH5qih5byP57K+56Gu6ZO65ruh77yI5bGP5bmV6aG25ruh6L655qGG5YaF57yY77yM5peg5YaF6YOo6buR6L6577yJ77yMXG4gICAgICAgIC8vIOaZrumAmi9EZWZhdWx0IOS/neaMgeetieavlOmAgumFjeOAgnNjcmVlbi5fZXhhY3RGaXRTY3JlZW4g55SxIENvY29zIFN1YkZyYW1lIGFkYXB0ZXIg6K+75Y+W44CCXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBjY3cgPSAod2luZG93IGFzIGFueSkuY2MgfHwgKHdpbmRvdyBhcyBhbnkpLmNjbGVnYWN5O1xuICAgICAgICAgICAgY29uc3Qgc2M6IGFueSA9IGNjdyAmJiAoY2N3LnNjcmVlbiB8fCAoY2N3LmdhbWUgJiYgY2N3LmdhbWUuc2NyZWVuKSk7XG4gICAgICAgICAgICBjb25zdCB0YXJnZXRzOiBhbnlbXSA9IHNjID8gW3NjLCBzYy5zY3JlZW5BZGFwdGVyXSA6IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCB0IG9mIHRhcmdldHMpIHtcbiAgICAgICAgICAgICAgICBpZiAodCAmJiAnX2V4YWN0Rml0U2NyZWVuJyBpbiB0KSB0Ll9leGFjdEZpdFNjcmVlbiA9ICEhaXNEZXZpY2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICAgIC8qIOW8leaTjuacquWwsee7quaXtuW/veeVpSAqL1xuICAgICAgICB9XG4gICAgICAgIHdpbmRvdy5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgncmVzaXplJykpO1xuICAgIH0sXG4gICAgLyoqIOW8uuWItui1sCBTdWJGcmFtZSDop4blj6PvvIjnlLvluIPot5/pmo8gI0dhbWVEaXYg5bC65a+477yM6YG/5YWN55So5pW056qX5bC65a+455Sf5oiQ6L+H5aSn55qE55S75biD5a+86Ie0XG4gICAgICogIOeUu+mdouavlOinhuWPo+Wkpy/ooqvoo4HliarvvInjgILmibnph4/opobnm5bmiYDmnInlt7Lnn6Ugc2NyZWVuQWRhcHRlciDmnaXmupDvvIzlubbph43or5XnrYnlvoUgU3lzdGVtIOW8guatpVxuICAgICAqICDmqKHlnZflsLHnu6rvvJvmr4/miJDlip/opobnm5bkuIDmrKHljbPph43mlL7op4blj6MgKyDop6blj5EgcmVzaXplIOmHjeeul+OAgiAqL1xuICAgIGFzeW5jIGZvcmNlU3ViRnJhbWVWaWV3cG9ydCh0aGlzOiBhbnksIGFsaXZlOiAoKSA9PiBib29sZWFuKSB7XG4gICAgICAgIGNvbnN0IGFwcGx5ID0gKGFkYXB0ZXI6IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKGFkYXB0ZXIgJiYgJ19leGFjdEZpdFNjcmVlbicgaW4gYWRhcHRlciAmJiBhZGFwdGVyLl9leGFjdEZpdFNjcmVlbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBhZGFwdGVyLl9leGFjdEZpdFNjcmVlbiA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICAvLyAxKSDlkIzmraXmnaXmupDvvJp3aW5kb3cuY2Muc2NyZWVuIOWPiuWFtiBzY3JlZW5BZGFwdGVyXG4gICAgICAgIGNvbnN0IGNjdyA9ICh3aW5kb3cgYXMgYW55KS5jYyB8fCAod2luZG93IGFzIGFueSkuY2NsZWdhY3k7XG4gICAgICAgIGlmIChjY3cgJiYgY2N3LnNjcmVlbikge1xuICAgICAgICAgICAgYXBwbHkoY2N3LnNjcmVlbik7XG4gICAgICAgICAgICBhcHBseShjY3cuc2NyZWVuLnNjcmVlbkFkYXB0ZXIpO1xuICAgICAgICAgICAgYXBwbHkoY2N3LmdhbWUgJiYgY2N3LmdhbWUuc2NyZWVuKTtcbiAgICAgICAgICAgIGFwcGx5KGNjdy5nYW1lICYmIGNjdy5nYW1lLnNjcmVlbi5zY3JlZW5BZGFwdGVyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyAyKSDlvILmraXmnaXmupDvvJpTeXN0ZW0uaW1wb3J0IOW+l+WIsOeahOecn+WuniBzY3JlZW5BZGFwdGVy77yM6YeN6K+V55u06Iez5Y+v55So5oiW6LaF5pe277yI5Yi35paw5YmN6L+U5Zue77yJXG4gICAgICAgIGNvbnN0IFN5c01vZCA9ICh3aW5kb3cgYXMgYW55KS5TeXN0ZW07XG4gICAgICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIDMwMDA7XG4gICAgICAgIHdoaWxlIChhbGl2ZSgpICYmIERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgICAgICAgbGV0IGdvdCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKFN5c01vZCAmJiB0eXBlb2YgU3lzTW9kLmltcG9ydCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNhTW9kID0gYXdhaXQgU3lzTW9kLmltcG9ydChcbiAgICAgICAgICAgICAgICAgICAgICAgICdxLWJ1bmRsZWQ6Ly8vZnMvcGFsL3NjcmVlbi1hZGFwdGVyL3dlYi9zY3JlZW4tYWRhcHRlci5qcydcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2EgPSAoc2FNb2QgJiYgKHNhTW9kLnNjcmVlbkFkYXB0ZXIgfHwgKHNhTW9kLmRlZmF1bHQgJiYgc2FNb2QuZGVmYXVsdC5zY3JlZW5BZGFwdGVyKSkpIHx8IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzYSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXBwbHkoc2EpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZ290ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgICAgICAvKiDmqKHlnZfmnKrlsLHnu6rvvIznu6fnu63ph43or5UgKi9cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZ290KSBicmVhaztcbiAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDEyMCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhbGl2ZSgpKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGx5RGV2aWNlVmlld3BvcnQodGhpcy5wcmV2aWV3RGV2aWNlIHx8ICdEZWZhdWx0Jyk7XG4gICAgICAgICAgICB3aW5kb3cuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ3Jlc2l6ZScpKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgb25QcmV2aWV3Um90YXRlKHRoaXM6IGFueSkge1xuICAgICAgICBjb25zdCBidG4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYnRuLXJvdGF0ZScpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICAgICAgaWYgKGJ0bikgYnRuLmNsaWNrKCk7XG4gICAgICAgIHRoaXMucHJldmlld1JvdGF0ZWQgPSAhdGhpcy5wcmV2aWV3Um90YXRlZDsgLy8g6Z2i5p2/5L6n6KeG6KeJ5oyH56S6XG4gICAgICAgIC8vIOiuvuWkhy/pu5jorqTop4blj6PmqKHlvI/kuIvml4vovazlkI7mjInmlrDmlrnlkJHph43nrpcgI0dhbWVEaXYg5q+U5L6LXG4gICAgICAgIGlmICh0aGlzLnByZXZpZXdEZXZpY2UgJiYgREVWSUNFX1NJWkVTW3RoaXMucHJldmlld0RldmljZV0pIHtcbiAgICAgICAgICAgIHRoaXMuYXBwbHlEZXZpY2VWaWV3cG9ydCh0aGlzLnByZXZpZXdEZXZpY2UpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3luY1ByZXZpZXdTdGF0ZSgpO1xuICAgIH0sXG4gICAgLyoqIOW4p+eOh+S4iumZkOiuvue9ru+8muWGmemakOiXjyAjaW5wdXQtc2V0LWZwcyDlubbmtL7lj5EgaW5wdXQvY2hhbmdl44CCICovXG4gICAgb25QcmV2aWV3RnBzKHRoaXM6IGFueSwgdmFsOiB1bmtub3duKSB7XG4gICAgICAgIGNvbnN0IG4gPSBNYXRoLm1heCgxLCBNYXRoLm1pbigyNDAsIE51bWJlcih2YWwpIHx8IDYwKSk7XG4gICAgICAgIHRoaXMucHJldmlld0ZwcyA9IG47XG4gICAgICAgIGNvbnN0IGlucCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNpbnB1dC1zZXQtZnBzJykgYXMgSFRNTElucHV0RWxlbWVudCB8IG51bGw7XG4gICAgICAgIGlmIChpbnApIHtcbiAgICAgICAgICAgIGlucC52YWx1ZSA9IFN0cmluZyhuKTtcbiAgICAgICAgICAgIGlucC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnaW5wdXQnLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgICAgICAgaW5wLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdjaGFuZ2UnLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICAvKiog5pi+56S6RlBT5byA5YWz77ya6Kem5Y+R6ZqQ6JePICNidG4tc2hvdy1mcHMg5bm25Zue6K+75r+A5rS75oCB44CCICovXG4gICAgb25QcmV2aWV3U2hvd0Zwcyh0aGlzOiBhbnkpIHtcbiAgICAgICAgY29uc3QgYnRuID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2J0bi1zaG93LWZwcycpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICAgICAgaWYgKGJ0bikgYnRuLmNsaWNrKCk7XG4gICAgICAgIHRoaXMuc3luY1ByZXZpZXdTdGF0ZSgpO1xuICAgIH0sXG4gICAgLyoqIOaaguWBnC/nu6fnu63vvJrop6blj5HpmpDol48gI2J0bi1wYXVzZeOAgiAqL1xuICAgIG9uUHJldmlld1BhdXNlKHRoaXM6IGFueSkge1xuICAgICAgICBjb25zdCBidG4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYnRuLXBhdXNlJykgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICAgICAgICBpZiAoYnRuKSBidG4uY2xpY2soKTtcbiAgICAgICAgdGhpcy5zeW5jUHJldmlld1N0YXRlKCk7XG4gICAgfSxcbiAgICAvKiog5q2l6L+b5LiA5bin77ya5LuF5pqC5YGc5oCB5Y+v55So77yM6Kem5Y+R6ZqQ6JePICNidG4tc3RlcOOAgiAqL1xuICAgIG9uUHJldmlld1N0ZXAodGhpczogYW55KSB7XG4gICAgICAgIGNvbnN0IGJ0biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNidG4tc3RlcCcpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICAgICAgaWYgKGJ0bikgYnRuLmNsaWNrKCk7XG4gICAgfSxcbiAgICAvLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAg56qX5ZuX57qn5YWo5bGA6Z2Z6Z+z77yIZGVmYXVsdCAvIOmihOiniOmdouadv+WFseS6q++8ieKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgIG9uUHJldmlld011dGUodGhpczogYW55KSB7XG4gICAgICAgIHRoaXMucHJldmlld011dGVkID0gIXRoaXMucHJldmlld011dGVkO1xuICAgICAgICB0aGlzLl9hcHBseU11dGUoKTtcbiAgICB9LFxuICAgIC8qKiDnoa7kv50gY29udGV4dCDmnIkgbWFzdGVyIGdhaW7vvIjlpoLml6DliJnms6jlhaXvvInvvIzlubbov5Tlm57lroPjgIIgKi9cbiAgICBfZW5zdXJlTWFzdGVyKHRoaXM6IGFueSwgYzogYW55KSB7XG4gICAgICAgIGlmICghYyB8fCBjLl9feXlrYU1hc3RlcikgcmV0dXJuIGMgJiYgYy5fX3l5a2FNYXN0ZXI7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBtZyA9IGMuY3JlYXRlR2FpbigpO1xuICAgICAgICAgICAgYy5fX3l5a2FNYXN0ZXIgPSBtZztcbiAgICAgICAgICAgIGNvbnN0IGxpc3QgPSB0aGlzLl9fbXV0ZUN0eHMoKTtcbiAgICAgICAgICAgIGlmIChsaXN0LmluZGV4T2YoYykgPCAwKSBsaXN0LnB1c2goYyk7XG4gICAgICAgICAgICByZXR1cm4gbWc7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHsgcmV0dXJuIG51bGw7IH1cbiAgICB9LFxuICAgIC8qKiBjb250ZXh0IOmHh+mbhuWIl+ihqO+8iOaooeWdl+e6p++8jOaNouWcuuaZry/ph43muLLmn5Pkv53mjIHvvInjgIIgKi9cbiAgICBfX211dGVDdHhzKHRoaXM6IGFueSk6IGFueVtdIHtcbiAgICAgICAgY29uc3Qga2V5ID0gJ19feXlrYUF1ZGlvQ3R4cyc7XG4gICAgICAgIGNvbnN0IHcgPSB3aW5kb3cgYXMgYW55O1xuICAgICAgICBpZiAoIXdba2V5XSkgd1trZXldID0gW107XG4gICAgICAgIHJldHVybiB3W2tleV07XG4gICAgfSxcbiAgICAvKiog5YWo5bGA6Z2Z6Z+z5qCH5b+X77ya6L+b5YWl6Z2Z6Z+z5YmN5YWI5oqK5b2T5YmN5a6e5L6L54q25oCB5YaZ6L+b5YWo5bGA77yM5L6bIGNvbm5lY3Qg5Yqr5oyB6K+75Y+W44CCICovXG4gICAgX19tdXRlR2xvYmFsKHRoaXM6IGFueSkge1xuICAgICAgICBjb25zdCBrZXkgPSAnX195eWthR2xvYmFsTXV0ZSc7XG4gICAgICAgIGNvbnN0IHcgPSB3aW5kb3cgYXMgYW55O1xuICAgICAgICByZXR1cm4geyBnZXQ6ICgpID0+ICEhd1trZXldLCBzZXQ6ICh2OiBib29sZWFuKSA9PiB7IHdba2V5XSA9IHY7IH0gfTtcbiAgICB9LFxuICAgIC8qKiDlupTnlKjpnZnpn7PliLDljZXkuKogY29udGV4dO+8mm1hc3RlciBnYWluIOWunuaXtuW8gOWFs++8iGc9MCDml6Dlo7AgLyBnPTEg5pyJ5aOw77yJ44CCICovXG4gICAgX2FwcGx5TXV0ZVRvQ3R4KHRoaXM6IGFueSwgYzogYW55LCBtdXRlZDogYm9vbGVhbikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKCFjKSByZXR1cm47XG4gICAgICAgICAgICBpZiAoYy5fX3l5a2FNYXN0ZXIpIHtcbiAgICAgICAgICAgICAgICBjLl9feXlrYU1hc3Rlci5nYWluLnZhbHVlID0gbXV0ZWQgPyAwIDogMTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYy5jcmVhdGVHYWluKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWcgPSB0aGlzLl9lbnN1cmVNYXN0ZXIoYyk7XG4gICAgICAgICAgICAgICAgaWYgKG1nKSB7XG4gICAgICAgICAgICAgICAgICAgIG1nLmdhaW4udmFsdWUgPSBtdXRlZCA/IDAgOiAxO1xuICAgICAgICAgICAgICAgICAgICB0cnkgeyBtZy5jb25uZWN0KGMuZGVzdGluYXRpb24pOyB9IGNhdGNoIChfKSB7IC8qIGlnbm9yZSAqLyB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFtdXRlZCAmJiB0eXBlb2YgYy5yZXN1bWUgPT09ICdmdW5jdGlvbicgJiYgYy5zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICB0cnkgeyBjLnJlc3VtZSgpOyB9IGNhdGNoIChfKSB7IC8qIGlnbm9yZSAqLyB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKF8pIHsgLyogaWdub3JlICovIH1cbiAgICB9LFxuICAgIC8qKiDlupTnlKjlhajlsYDpnZnpn7PvvJrlhpnmoIflv5cgKyDlvJXmk47pn7Pph48gKyDlhajpg6ggY29udGV4dCBtYXN0ZXIgZ2FpbiArIOWqkuS9k+WFg+e0oOOAguaXoOi9ruivouOAgiAqL1xuICAgIF9hcHBseU11dGUodGhpczogYW55KSB7XG4gICAgICAgIGNvbnN0IG11dGVkID0gISF0aGlzLnByZXZpZXdNdXRlZDtcbiAgICAgICAgdGhpcy5fX211dGVHbG9iYWwoKS5zZXQobXV0ZWQpO1xuICAgICAgICBjb25zdCBsZyA9ICh3aW5kb3cgYXMgYW55KS5jYyB8fCAod2luZG93IGFzIGFueSkuY2NsZWdhY3k7XG4gICAgICAgIGNvbnN0IGFlID0gbGcgJiYgKGxnLkF1ZGlvRW5naW5lIHx8IChsZy5hdWRpbyAmJiBsZy5hdWRpby5BdWRpb0VuZ2luZSkpO1xuICAgICAgICBpZiAoYWUpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhZS5zZXRNdXNpY1ZvbHVtZSA9PT0gJ2Z1bmN0aW9uJykgYWUuc2V0TXVzaWNWb2x1bWUobXV0ZWQgPyAwIDogMSk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhZS5zZXRFZmZlY3RzVm9sdW1lID09PSAnZnVuY3Rpb24nKSBhZS5zZXRFZmZlY3RzVm9sdW1lKG11dGVkID8gMCA6IDEpO1xuICAgICAgICAgICAgfSBjYXRjaCAoXykgeyAvKiBpZ25vcmUgKi8gfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGN0eHMgPSB0aGlzLl9fbXV0ZUN0eHMoKTtcbiAgICAgICAgZm9yIChjb25zdCBjIG9mIGN0eHMpIHRoaXMuX2FwcGx5TXV0ZVRvQ3R4KGMsIG11dGVkKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2F1ZGlvLCB2aWRlbycpLmZvckVhY2goKGVsOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICB0cnkgeyBlbC5tdXRlZCA9IG11dGVkOyBpZiAobXV0ZWQpIGVsLnBhdXNlKCk7IGVsc2UgZWwucGxheSgpLmNhdGNoKCgpID0+IHt9KTsgfSBjYXRjaCAoXykgeyAvKiBpZ25vcmUgKi8gfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHsgLyogaWdub3JlICovIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOWuieijheeql+Wbl+e6p+mfs+mikemdmemfsyBob29r77yI5LqL5Lu26amx5Yqo77yM5peg6L2u6K+i77yJ77yaXG4gICAgICogMSkg5YyF6KOFIEF1ZGlvQ29udGV4dCDmnoTpgKDlmajvvJrmlrDlu7rljbPmjIIgbWFzdGVyIOW5tumHh+mbhu+8m1xuICAgICAqIDIpIOWKq+aMgSBBdWRpb05vZGUucHJvdG90eXBlLmNvbm5lY3TvvJrku7vkvZXoioLngrnov57liLAgY29udGV4dC5kZXN0aW5hdGlvbiDml7bmjqXov5sgbWFzdGVyIGdhaW7jgIJcbiAgICAgKiAgICDljbPkvb/lvJXmk47lpI3nlKjmqKHlnZfnuqfnvJPlrZjnmoTljp/lp4sgY29udGV4dCDljZXkvovvvIxjb25uZWN0IOaXtuS5n+S8muWKqOaAgeazqOWFpSBtYXN0ZXLvvIxcbiAgICAgKiAgICDlo7Dpn7Plv4Xnu48gbWFzdGVy77yMZz0wIOeri+WNs+aXoOWjsO+8iOaUu+WHu+mfs+aViOeerOaXtuWTke+8jOaXoOmcgOi9ruivou+8ieOAglxuICAgICAqL1xuICAgIF9ob29rQXVkaW9DdHgodGhpczogYW55KSB7XG4gICAgICAgIGNvbnN0IHcgPSB3aW5kb3cgYXMgYW55O1xuICAgICAgICBjb25zdCBzZWxmUmVmID0gdGhpcztcbiAgICAgICAgY29uc3QgaGlqYWNrQ29ubmVjdCA9IChOb2RlQ3RvcjogYW55KSA9PiB7XG4gICAgICAgICAgICBpZiAoIU5vZGVDdG9yIHx8IE5vZGVDdG9yLl9feXlrYUNvbm5Ib29rKSByZXR1cm47XG4gICAgICAgICAgICBOb2RlQ3Rvci5fX3l5a2FDb25uSG9vayA9IHRydWU7XG4gICAgICAgICAgICBjb25zdCBvcmlnID0gTm9kZUN0b3IucHJvdG90eXBlLmNvbm5lY3Q7XG4gICAgICAgICAgICBOb2RlQ3Rvci5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uIChkZXN0OiBhbnksIC4uLnJlc3Q6IGFueVtdKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcyAmJiB0aGlzLmNvbnRleHQ7XG4gICAgICAgICAgICAgICAgICAgIC8vIG1hc3RlciDoioLngrnoh6rouqvov57liLDovpPlh7rml7bopoHmlL7ooYzvvIjnm7Tov54gZGVzdGluYXRpb27vvInvvIzlkKbliJnkvJrmioroh6rlt7FcbiAgICAgICAgICAgICAgICAgICAgLy8g6YeN5a6a5ZCR5Yiw6Ieq6Lqr5b2i5oiQ6Ieq6L+e77yM6Z+z6aKR5Zu+6KKr56C05Z2P4oaS5rC45LmF6Z2Z6Z+z77yI5peg6K665byA5YWz54q25oCB77yJ44CCXG4gICAgICAgICAgICAgICAgICAgIGlmIChjdHggJiYgdGhpcyA9PT0gY3R4Ll9feXlrYU1hc3Rlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9yaWcuYXBwbHkodGhpcywgW2Rlc3QsIC4uLnJlc3RdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoY3R4ICYmIGN0eC5kZXN0aW5hdGlvbiAmJiBkZXN0ID09PSBjdHguZGVzdGluYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBtZyA9IGN0eC5fX3l5a2FNYXN0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1nICYmIGN0eC5jcmVhdGVHYWluKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWcgPSBjdHguY3JlYXRlR2FpbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5fX3l5a2FNYXN0ZXIgPSBtZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsaXN0ID0gc2VsZlJlZi5fX211dGVDdHhzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3QuaW5kZXhPZihjdHgpIDwgMCkgbGlzdC5wdXNoKGN0eCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsgb3JpZy5jYWxsKG1nLCBjdHguZGVzdGluYXRpb24pOyB9IGNhdGNoIChfKSB7IC8qIGlnbm9yZSAqLyB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobWcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZy5nYWluLnZhbHVlID0gc2VsZlJlZi5fX211dGVHbG9iYWwoKS5nZXQoKSA/IDAgOiAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3QgPSBtZztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKF8pIHsgLyogaWdub3JlICovIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZy5hcHBseSh0aGlzLCBbZGVzdCwgLi4ucmVzdF0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgQXVkaW9Ob2RlQ3RvciA9IHcuQXVkaW9Ob2RlO1xuICAgICAgICBpZiAoQXVkaW9Ob2RlQ3RvcikgeyB0cnkgeyBoaWphY2tDb25uZWN0KEF1ZGlvTm9kZUN0b3IpOyB9IGNhdGNoIChfKSB7IC8qIGlnbm9yZSAqLyB9IH1cbiAgICAgICAgY29uc3Qgd3JhcEN0b3IgPSAoQ3RvcjogYW55LCBuYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGlmICghQ3RvciB8fCBDdG9yLl9fcGF0Y2hZeWthKSByZXR1cm47XG4gICAgICAgICAgICBjb25zdCBPbGQgPSBDdG9yO1xuICAgICAgICAgICAgY29uc3QgU2VsZiA9IGZ1bmN0aW9uICguLi5hOiBhbnlbXSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGMgPSBuZXcgT2xkKC4uLmEpO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1nID0gc2VsZlJlZi5fZW5zdXJlTWFzdGVyKGMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobWcpIHsgbWcuY29ubmVjdChjLmRlc3RpbmF0aW9uKTsgbWcuZ2Fpbi52YWx1ZSA9IHNlbGZSZWYuX19tdXRlR2xvYmFsKCkuZ2V0KCkgPyAwIDogMTsgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKF8pIHsgLyogaWdub3JlICovIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYztcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAoU2VsZiBhcyBhbnkpLnByb3RvdHlwZSA9IE9sZC5wcm90b3R5cGU7XG4gICAgICAgICAgICAoU2VsZiBhcyBhbnkpLl9fcGF0Y2hZeWthID0gdHJ1ZTtcbiAgICAgICAgICAgIHdbbmFtZV0gPSBTZWxmO1xuICAgICAgICB9O1xuICAgICAgICB3cmFwQ3Rvcih3LkF1ZGlvQ29udGV4dCwgJ0F1ZGlvQ29udGV4dCcpO1xuICAgICAgICB3cmFwQ3Rvcih3LndlYmtpdEF1ZGlvQ29udGV4dCwgJ3dlYmtpdEF1ZGlvQ29udGV4dCcpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgT0UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50LmJpbmQoZG9jdW1lbnQpO1xuICAgICAgICAgICAgKGRvY3VtZW50IGFzIGFueSkuY3JlYXRlRWxlbWVudCA9IGZ1bmN0aW9uICh0YWc6IHN0cmluZywgLi4ucmVzdDogYW55W10pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbCA9IE9FKHRhZywgLi4ucmVzdCk7XG4gICAgICAgICAgICAgICAgY29uc3QgdCA9IFN0cmluZyh0YWcpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgaWYgKHQgPT09ICdhdWRpbycgfHwgdCA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICB0cnkgeyBpZiAoc2VsZlJlZi5fX211dGVHbG9iYWwoKS5nZXQoKSkgKGVsIGFzIGFueSkubXV0ZWQgPSB0cnVlOyB9IGNhdGNoIChfKSB7IC8qIGlnbm9yZSAqLyB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBlbDtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKF8pIHsgLyogaWdub3JlICovIH1cbiAgICB9LFxuICAgIC8qKiDliLfmlrDpooTop4jvvJrph43nva7nvKnmlL7lubbph43mlrDmuLLmn5PjgIIgKi9cbiAgICBkb1JlZnJlc2hQcmV2aWV3KHRoaXM6IGFueSkge1xuICAgICAgICB0aGlzLnByZXZpZXdab29tID0gMTtcbiAgICAgICAgdGhpcy5wcmV2aWV3TG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHJldmlld1JlbmRlckVyciA9ICcnO1xuICAgICAgICB0aGlzLnJlbmRlclByZXZpZXcoKTtcbiAgICB9LFxuICAgIC8qKiDph43muLLmn5PliY3mi4bop6PkuIrkuIDmrKHmuLjmiI/lrp7kvovvvJrlgZzkuLvlvqrnjq/jgIHmuIXosIPluqblmajvvIjorqHml7blmagvdXBkYXRl77yJ44CB5YGc6Z+z6aKR44CB6YeK5pS+6LWE5rqQ44CCXG4gICAgICogIOmdouadv+WGheaXoOazleWDj+a1j+iniOWZqOmihOiniOmCo+agt+aVtOmhtSByZWxvYWTvvIxjYyDlhajlsYDmmK/ljZXkvovvvIzml6flrp7kvovoi6XkuI3muIXnkIbvvIxcbiAgICAgKiAg5Yi35paw5ZCO6Z+z5LmQL+iuoeaXtuWZqC/kuLvlvqrnjq/kvJrmrovnlZnlj6DliqDjgIHkuI3lhbPpl63pnaLmnb/lsLHml6Dms5XlpI3ljp/jgIJcbiAgICAgKiAg5q+P5q2l5Y2V54usIHRyeS9jYXRjaCDku6XpmLLmn5AgQVBJIOe8uuWksS/miqXplJnpmLvmlq3ph43ovb3mtYHnqIvjgIIgKi9cbiAgICB0ZWFyZG93blByZXZpZXcodGhpczogYW55KSB7XG4gICAgICAgIGNvbnN0IGxnID0gKHdpbmRvdyBhcyBhbnkpLmNjIHx8ICh3aW5kb3cgYXMgYW55KS5jY2xlZ2FjeTtcbiAgICAgICAgaWYgKCFsZyB8fCAhbGcuZ2FtZSkgcmV0dXJuOyAvLyDpppbmrKHmuLLmn5PlsJrml6Dlrp7kvovvvIzot7Pov4dcbiAgICAgICAgY29uc3Qgc3RvcCA9IChmbjogKCkgPT4gdm9pZCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgICAgICAgIC8qIOW/veeVpeWNleS4qua4heeQhuWksei0pSAqL1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICAvLyDlgZzkuLvlvqrnjq/mm7TmlrDvvIjmmoLlgZwgdXBkYXRlL+a4uOaIj+mAu+i+ke+8iVxuICAgICAgICBjb25zdCBnID0gbGcuZ2FtZTtcbiAgICAgICAgc3RvcCgoKSA9PiBnLnBhdXNlICYmIGcucGF1c2UoKSk7XG4gICAgICAgIHN0b3AoKCkgPT4gZy5wYXVzZUJ5RW5naW5lICYmIGcucGF1c2VCeUVuZ2luZSgpKTtcbiAgICAgICAgLy8g5YGcIGRpcmVjdG9yIOabtOaWsFxuICAgICAgICBjb25zdCBkaXIgPSBsZy5kaXJlY3RvcjtcbiAgICAgICAgc3RvcCgoKSA9PiBkaXIucGF1c2UgJiYgZGlyLnBhdXNlKCkpO1xuICAgICAgICAvLyDmuIXosIPluqblmajvvJrpobnnm67nlKggc2NoZWR1bGVPbmNlL3NldFRpbWVvdXQg562J5a6a5pe25ZmoXG4gICAgICAgIHN0b3AoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc2NoID0gZGlyICYmIGRpci5nZXRTY2hlZHVsZXIgJiYgZGlyLmdldFNjaGVkdWxlcigpO1xuICAgICAgICAgICAgc2NoICYmIHNjaC51bnNjaGVkdWxlQWxsICYmIHNjaC51bnNjaGVkdWxlQWxsKCk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDlgZzmraLpn7PpopHvvIjpobnnm67pn7PkuZAv6Z+z5pWI77yMQXVkaW9FbmdpbmUg5YWo5bGAIGNsb3NlIOWBnOWFqOmDqO+8iVxuICAgICAgICBzdG9wKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFlID0gbGcuQXVkaW9FbmdpbmUgfHwgKGxnLmF1ZGlvICYmIGxnLmF1ZGlvLkF1ZGlvRW5naW5lKTtcbiAgICAgICAgICAgIGFlICYmIGFlLmNsb3NlICYmIGFlLmNsb3NlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDph4rmlL7lt7LliqDovb3otYTmupDvvIzpgb/lhY3mlrDlnLrmma/lpI3nlKjml6fotYTmupDlj6Xmn4TpgKDmiJDlj6DliqBcbiAgICAgICAgc3RvcCgoKSA9PiBsZy5hc3NldE1hbmFnZXIgJiYgbGcuYXNzZXRNYW5hZ2VyLnJlbGVhc2VBbGwgJiYgbGcuYXNzZXRNYW5hZ2VyLnJlbGVhc2VBbGwoKSk7XG4gICAgfSxcbiAgICAvKiog5LuO6ZqQ6JePIEg1IOW3peWFt+adoeWbnuivu+eKtuaAge+8jOWQjOatpemdouadv+aMiemSrua/gOa0u+aAge+8iGxvYWRpbmcg5a6M5pW05ZCO6LCD55So5LiA5qyhICsg5q+P5qyh5pON5L2c5ZCO77yJ44CCICovXG4gICAgc3luY1ByZXZpZXdTdGF0ZSh0aGlzOiBhbnkpIHtcbiAgICAgICAgY29uc3Qgc2hvd1JlYWR5ID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc2hvdyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNidG4tc2hvdy1mcHMnKTtcbiAgICAgICAgICAgIGNvbnN0IHBhdXNlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2J0bi1wYXVzZScpO1xuICAgICAgICAgICAgY29uc3Qgc3RlcCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNidG4tc3RlcCcpO1xuICAgICAgICAgICAgbGV0IHBhdXNlZCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKHBhdXNlKSBwYXVzZWQgPSBwYXVzZS5jbGFzc0xpc3QuY29udGFpbnMoJ2NoZWNrZWQnKTtcbiAgICAgICAgICAgIGlmICghcGF1c2VkICYmIHN0ZXApIHBhdXNlZCA9IGdldENvbXB1dGVkU3R5bGUoc3RlcCkuZGlzcGxheSAhPT0gJ25vbmUnO1xuICAgICAgICAgICAgdGhpcy5wcmV2aWV3U2hvd0ZwcyA9ICEhKHNob3cgJiYgc2hvdy5jbGFzc0xpc3QuY29udGFpbnMoJ2NoZWNrZWQnKSk7XG4gICAgICAgICAgICB0aGlzLnByZXZpZXdQYXVzZWQgPSBwYXVzZWQ7XG4gICAgICAgIH07XG4gICAgICAgIC8vIOetieW+hSAjR2FtZUNhbnZhcyDlsLHnu6rlkI7lho3or7vvvJvlrr/kuLvph43lu7rnnqzpl7Tlj6/og73lj5bliLDnqbogRE9NXG4gICAgICAgIGNvbnN0IHdhaXRGb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2J0bi1wYXVzZScpKSB7XG4gICAgICAgICAgICAgICAgc2hvd1JlYWR5KCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KHdhaXRGb3IsIDYwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgd2FpdEZvcigpO1xuICAgIH0sXG4gICAgLyoqIOmihOiniOWMuua7mui9rue8qeaUvu+8muiwg+aVtOe8qeaUvuWboOWtkOW5tumHjeeulyAjR2FtZURpdiDnnJ/lrp7lsLrlr7jvvIjnrYnmr5TmlL7lpKfnvKnlsI/vvIzlsYXkuK3vvInjgIJcbiAgICAgKiAg55So5a+556ew5LmY5rOV5q2l6L+b77yI5pS+5aSnIMOXMS4xMiAvIOe8qeWwjyDDtzEuMTLvvInkv53or4Hlj6/pgIbvvJvlvJXmk47mjInlrrnlmajlsLrlr7jph43lu7rnlLvluIPvvIxcbiAgICAgKiAg5Zug5q2k5pS+5aSn57yp5bCP6L+H56iL6L6T5YWl5pig5bCE5aeL57uI5q2j56Gu77yM5LiN5Lya5Ye6546w5pS+5aSn5LqG54K55LiN5Yiw55qE5oOF5Ya144CCICovXG4gICAgb25QcmV2aWV3V2hlZWwodGhpczogYW55LCBlOiBXaGVlbEV2ZW50KSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgLy8g5YWz6ZSu77ya5oum5oiq5rua6L2u5Lyg5pKt44CC5ZCm5YiZ5LqL5Lu26L+Y5Lya57un57ut5Lyg5Yiw5pys5o+S5Lu25Yqg6L2955qE57yW6L6R5ZmoIHByZXZpZXctYXBwXG4gICAgICAgIC8vIFVp77yI5YW25rua6L2u5aSE55CG5Zmo5Lya5oqK6K6+6K6h5YiG6L6o546H6YeN572u5oiQ6buY6K6k5qiq5bGPIDk2MMOXNjQw77yM5a+86Ie056uW5bGP5Y+Y5qiq5bGP77yJ44CCXG4gICAgICAgIC8vIOi/memHjOWcqOaNleiOt+mYtuautemYu+atouWGkuazoeWIsOWGheWuueWxgu+8jOS/neivgeWPqueUseaIkeS7rOiHquW3seeahCBhcHBseURldmljZVZpZXdwb3J0IOaOp+WItue8qeaUvuOAglxuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgICBpZiAoIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdHYW1lRGl2JykpIHJldHVybjtcbiAgICAgICAgY29uc3Qgem9vbUluID0gZS5kZWx0YVkgPCAwO1xuICAgICAgICBjb25zdCBzdGVwID0gTWF0aC5wb3coMS4xMiwgem9vbUluID8gMSA6IC0xKTtcbiAgICAgICAgdGhpcy5wcmV2aWV3Wm9vbSA9IE1hdGgubWluKDgsIE1hdGgubWF4KDAuMiwgTWF0aC5yb3VuZCh0aGlzLnByZXZpZXdab29tICogc3RlcCAqIDEwMCkgLyAxMDApKTtcbiAgICAgICAgLy8g5LuF5a+55bC65a+45pig5bCE55qE6K6+5aSHL+m7mOiupOinhuWPo+W6lOeUqOe8qeaUvu+8iEZ1bGxTY3JlZW4vV2VicGFnZSDpk7rmu6HkuI3nvKnmlL7vvIlcbiAgICAgICAgY29uc3QgZGV2ID0gdGhpcy5wcmV2aWV3RGV2aWNlIHx8ICdEZWZhdWx0JztcbiAgICAgICAgaWYgKERFVklDRV9TSVpFU1tkZXZdKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGx5RGV2aWNlVmlld3BvcnQoZGV2KTtcbiAgICAgICAgfVxuICAgICAgICAvLyDlhZzlupXvvJrnvJbovpHlmaggcHJldmlldy1hcHAgVWkg5Y+v6IO95Zyo5ZCM5LiA5qyh5rua6L2uL3Jlc2l6ZSDph4zlvILmraXmiororr7orqHliIbovqjnjofph43nva7miJBcbiAgICAgICAgLy8g6buY6K6k5qiq5bGP77yIOTYww5c2NDDvvInjgILkuIvkuIDluKflho3ph43mlL7kuIDmrKHop4blj6PvvIjnrYnmr5QgKyBfZXhhY3RGaXRTY3JlZW49ZmFsc2XvvInvvIxcbiAgICAgICAgLy8g5oqK6K6+5aSHL+m7mOiupOiuvuiuoeWIhui+qOeOh+W8uuWItuaLieWbnumhueebruecn+WunuerluWxj+avlOS+i+OAglxuICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLl93aGVlbFJlYXBwbHkpO1xuICAgICAgICB0aGlzLl93aGVlbFJlYXBwbHkgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fd2hlZWxSZWFwcGx5ID0gMDtcbiAgICAgICAgICAgIGNvbnN0IGRldjAgPSB0aGlzLnByZXZpZXdEZXZpY2UgfHwgJ0RlZmF1bHQnO1xuICAgICAgICAgICAgaWYgKERFVklDRV9TSVpFU1tkZXYwXSkgdGhpcy5hcHBseURldmljZVZpZXdwb3J0KGRldjApO1xuICAgICAgICB9KTtcbiAgICB9LFxuICAgIC8qKiDmiornm7jlr7kv57ud5a+56Lev5b6E5ou85Yiw6aKE6KeI5pyN5YqhIG9yaWdpbiDkuIrvvIjpnaLmnb8gb3JpZ2luIOino+aekOS8miA0MDTvvInjgIIgKi9cbiAgICBhYnModGhpczogYW55LCBwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBiYXNlID0gKHRoaXMucHJldmlld1VybCB8fCAnJykudHJpbSgpLnJlcGxhY2UoL1xcLyskLywgJycpIHx8ICdodHRwOi8vbG9jYWxob3N0Ojc0NTYnO1xuICAgICAgICBpZiAoL14oaHR0cHM/Oik/XFwvXFwvL2kudGVzdChwYXRoKSB8fCBwYXRoLnN0YXJ0c1dpdGgoJ2RhdGE6JykgfHwgcGF0aC5zdGFydHNXaXRoKCdibG9iOicpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGF0aDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYmFzZSArIChwYXRoLnN0YXJ0c1dpdGgoJy8nKSA/IHBhdGggOiAnLycgKyBwYXRoKTtcbiAgICB9LFxuICAgIC8qKiDmuLjmiI/lrr/kuLvlrrnlmajvvJrliJvlu7rlnKjpobblsYIgZG9jdW1lbnQuYm9keSDkuIrjgILpnaLmnb/lhoXlrrnlj6/og73muLLmn5PlnKggc2hhZG93IERPTSDkuK1cbiAgICAgKiAg77yIQ29jb3MgdWktcGFuZWwg5py65Yi277yJ77yMVWkg5p6E6YCg55qEIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ig5peg5rOV56m/6YCPIHNoYWRvdyByb29077yMXG4gICAgICogIOWboOatpOa4uOaIjyBET00g5b+F6aG75oyC5Zyo6aG25bGCIGRvY3VtZW50IOS4iuaJjeiDveiiq+aJvuWIsOOAgiAqL1xuICAgIGVuc3VyZUdhbWVIb3N0KHRoaXM6IGFueSk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgbGV0IGhvc3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneXlrYS1nYW1lLWhvc3QnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgICAgIGlmICghaG9zdCkge1xuICAgICAgICAgICAgaG9zdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgaG9zdC5pZCA9ICd5eWthLWdhbWUtaG9zdCc7XG4gICAgICAgICAgICAvLyBmbGV4IGNvbHVtbu+8mnRvb2xiYXIg6ZqQ6JeP5ZCOIGNvbnRlbnQoZmxleDphdXRvKSDmiY3og73mkpHmu6Hlrr/kuLvpq5jluqZcbiAgICAgICAgICAgIC8vIHotaW5kZXggNDDvvJrnm5bkvY/pnaLmnb/kuLvkvZPlhoXlrrnvvIh6LWluZGV4IOKJpCAxMO+8ie+8jFxuICAgICAgICAgICAgLy8g5L2G5L2O5LqOIC5tY3AtbWFzayg1MCkvLm5vZGUtcGlja2VyLW1hc2soOTk5OSnvvIzpgb/lhY3pga7nm5bpnaLmnb/lvLnlsYJcbiAgICAgICAgICAgIGhvc3Quc3R5bGUuY3NzVGV4dCA9XG4gICAgICAgICAgICAgICAgJ3Bvc2l0aW9uOmZpeGVkO3otaW5kZXg6NDA7b3ZlcmZsb3c6aGlkZGVuO2JhY2tncm91bmQ6IzE3MTcxNztkaXNwbGF5Om5vbmU7JyArXG4gICAgICAgICAgICAgICAgJ2ZsZXgtZGlyZWN0aW9uOmNvbHVtbjthbGlnbi1pdGVtczpzdHJldGNoOyc7XG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGhvc3QpO1xuICAgICAgICB9XG4gICAgICAgIC8vIOa7mui9rue8qeaUvu+8mua4uOaIj+aUvuWkp+WQjiAjR2FtZURpdiDkvJrotoXlh7rpooTop4jljLrvvIzoi6Xmioogd2hlZWwg57uR5Zyo5a6/5Li75LiK77yMXG4gICAgICAgIC8vIOW9k+m8oOagh+aCrOWBnOWcqOa6ouWHuueahOeUu+mdouWMuuWfn+aXtuS6i+S7tuWPr+iDveiiq+WtkOWFg+e0oOaLpuaIqi/kuKLlpLHvvIzlr7zoh7TmlL7lpKfkuobnvKnkuI3lm57mnaXjgIJcbiAgICAgICAgLy8g5oyC5ZyoIGRvY3VtZW5077yId2luZG93IOaNleiOt++8ieeahOaNleiOt+mYtuaute+8jOS/neivgem8oOagh+iQveWcqOa4uOaIj+Wuv+S4u+WGheS7u+aEj+WFg+e0oO+8iOWQq+a6ouWHuumDqOWIhu+8iVxuICAgICAgICAvLyDpg73og73op6blj5HvvJvkuJTlnKjnvJbovpHlmaggcHJldmlldy1hcHAgVWkg55qE5Lu75L2V5rua6L2u5aSE55CG5Zmo5LmL5YmN5YWI5omn6KGM77yI6KeBIG9uUHJldmlld1doZWVs77yJ44CCXG4gICAgICAgIC8vIOeUqCB0aGlzLl9kb2Nab29tQm91bmQg6Ziy6YeN5aSN57uR5a6a77yId2luZG93IOW4uOmpu++8jGhvc3Qg5Y+v5Y+N5aSN6YeN5bu677yJ44CCXG4gICAgICAgIGlmICghdGhpcy5fZG9jWm9vbUJvdW5kKSB7XG4gICAgICAgICAgICB0aGlzLl9kb2Nab29tQm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgJ3doZWVsJyxcbiAgICAgICAgICAgICAgICAoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBoID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3l5a2EtZ2FtZS1ob3N0Jyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChoICYmIChoLmNvbnRhaW5zKGUudGFyZ2V0IGFzIE5vZGUpIHx8IGUudGFyZ2V0ID09PSBoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vblByZXZpZXdXaGVlbChlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgeyBjYXB0dXJlOiB0cnVlLCBwYXNzaXZlOiBmYWxzZSB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBob3N0O1xuICAgIH0sXG4gICAgLyoqIOiuqea4uOaIj+Wuv+S4u+i3n+maj+mdouadv+mihOiniOWMuuWfn++8iC5nYW1lLXZpZXfvvInnmoTop4blj6PkvY3nva7kuI7lsLrlr7jjgIJcbiAgICAgKiAgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IOWvuSBzaGFkb3cgRE9NIOWGheWFg+e0oOWQjOagt+i/lOWbnuinhuWPo+WdkOagh++8jOmFjeWQiCBmaXhlZCDlrprkvY3lj6/nsr7noa7opobnm5bjgIJcbiAgICAgKiAg6Z2i5p2/6KKr5ouW5YqoL+WIh+i1sC/lvLnnqpfpga7mjKHml7blrr/kuLvlv4Xpobvot5/pmo/miJbpmpDol4/vvIzlkKbliJnkvJrjgIzmvILmta7jgI3lnKjlsY/luZXkuIrnm5bkvY/lhbblroPnqpflj6PjgIIgKi9cbiAgICBzeW5jR2FtZUhvc3QodGhpczogYW55KSB7XG4gICAgICAgIGNvbnN0IGhvc3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneXlrYS1nYW1lLWhvc3QnKTtcbiAgICAgICAgaWYgKCFob3N0KSByZXR1cm47XG4gICAgICAgIGNvbnN0IHJlZiA9ICh0aGlzLiRyZWZzLmdhbWVWaWV3IGFzIEhUTUxFbGVtZW50IHwgbnVsbCkgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmdhbWUtdmlldycpO1xuICAgICAgICBpZiAoIXJlZikgcmV0dXJuO1xuICAgICAgICBjb25zdCByID0gcmVmLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBjb25zdCB2dyA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgICAgICBjb25zdCB2aCA9IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICAgICAgLy8g5bC65a+45Li6IDDvvIh2LXNob3cg6ZqQ6JeP77yJ5oiW5a6M5YWo56e75Ye66KeG5Y+j77yI6Z2i5p2/5ouW5YqoL+eLrOeri+aIkOeql++8ieaXtumakOiXj+Wuv+S4u++8jOmBv+WFjea8gua1rumBruaMoVxuICAgICAgICBjb25zdCBvZmZzY3JlZW4gPSByLndpZHRoIDw9IDEgfHwgci5oZWlnaHQgPD0gMSB8fCByLmxlZnQgPj0gdncgfHwgci50b3AgPj0gdmggfHwgci5sZWZ0ICsgci53aWR0aCA8PSAwIHx8IHIudG9wICsgci5oZWlnaHQgPD0gMDtcbiAgICAgICAgY29uc3QgZGlzcGxheSA9IG9mZnNjcmVlbiA/ICdub25lJyA6ICdmbGV4JztcbiAgICAgICAgLy8g5LuF5Zyo54q25oCB5Y+Y5YyW5pe25YaZ5qC35byP77yM6YG/5YWN5a6a5pyf6L2u6K+i6YCg5oiQ5peg6LCT6YeN5o6SXG4gICAgICAgIGlmICh0aGlzLl9ob3N0RGlzcGxheSA9PT0gZGlzcGxheSAmJiB0aGlzLl9ob3N0TGVmdCA9PT0gci5sZWZ0ICYmIHRoaXMuX2hvc3RUb3AgPT09IHIudG9wICYmXG4gICAgICAgICAgICB0aGlzLl9ob3N0VyA9PT0gci53aWR0aCAmJiB0aGlzLl9ob3N0SCA9PT0gci5oZWlnaHQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9ob3N0RGlzcGxheSA9IGRpc3BsYXk7XG4gICAgICAgIHRoaXMuX2hvc3RMZWZ0ID0gci5sZWZ0O1xuICAgICAgICB0aGlzLl9ob3N0VG9wID0gci50b3A7XG4gICAgICAgIHRoaXMuX2hvc3RXID0gci53aWR0aDtcbiAgICAgICAgdGhpcy5faG9zdEggPSByLmhlaWdodDtcbiAgICAgICAgaG9zdC5zdHlsZS5kaXNwbGF5ID0gZGlzcGxheTsgLy8g5LiOIGNzc1RleHQg55qEIGZsZXggY29sdW1uIOW4g+WxgOS4gOiHtFxuICAgICAgICBpZiAoZGlzcGxheSA9PT0gJ25vbmUnKSByZXR1cm47XG4gICAgICAgIGhvc3Quc3R5bGUubGVmdCA9IHIubGVmdCArICdweCc7XG4gICAgICAgIGhvc3Quc3R5bGUudG9wID0gci50b3AgKyAncHgnO1xuICAgICAgICBob3N0LnN0eWxlLndpZHRoID0gci53aWR0aCArICdweCc7XG4gICAgICAgIGhvc3Quc3R5bGUuaGVpZ2h0ID0gci5oZWlnaHQgKyAncHgnO1xuICAgIH0sXG4gICAgLyoqIOWBnOatouWumuacn+Wuv+S4u+WQjOatpe+8iOa4suafk+iiq+WPluS7o+aIlumdouadv+WFs+mXreaXtuiwg+eUqO+8ieOAgiAqL1xuICAgIHN0b3BIb3N0U3luYyh0aGlzOiBhbnkpIHtcbiAgICAgICAgaWYgKHRoaXMuX2hvc3RTeW5jVGltZXIpIHtcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMuX2hvc3RTeW5jVGltZXIpO1xuICAgICAgICAgICAgdGhpcy5faG9zdFN5bmNUaW1lciA9IDA7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8qKiDnm5HlkKzpooTop4jljLrln5/lsLrlr7gv5pi+6ZqQ5Y+Y5YyW77yM6Ieq5Yqo5ZCM5q2l5ri45oiP5a6/5Li75L2N572u77yI5YiG6ZqU5p2h5ouW5ou944CB56qX5Y+j57yp5pS+44CBdi1zaG93IOWIh+aNou+8ieOAgiAqL1xuICAgIG9ic2VydmVHYW1lSG9zdCh0aGlzOiBhbnkpIHtcbiAgICAgICAgaWYgKHRoaXMuX2hvc3RPYnNlcnZlZCkgcmV0dXJuO1xuICAgICAgICB0aGlzLl9ob3N0T2JzZXJ2ZWQgPSB0cnVlO1xuICAgICAgICBjb25zdCByZWYgPSAodGhpcy4kcmVmcy5nYW1lVmlldyBhcyBIVE1MRWxlbWVudCB8IG51bGwpIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5nYW1lLXZpZXcnKTtcbiAgICAgICAgaWYgKCFyZWYgfHwgdHlwZW9mIFJlc2l6ZU9ic2VydmVyID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuICAgICAgICBjb25zdCBybyA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB0aGlzLnN5bmNHYW1lSG9zdCgpKTtcbiAgICAgICAgcm8ub2JzZXJ2ZShyZWYpO1xuICAgIH0sXG4gICAgLyoqIOaehOW7uuWujOaVtOa4uOaIjyBET03vvIh0b29sYmFyIOaOp+S7tuadoSArIGNvbnRlbnQvR2FtZURpdi9jYW52YXMvc3BsYXNoL2J1bGxldGluL2Vycm9y77yJ77yMXG4gICAgICogIOaMgui9veWIsOmhtuWxgiBkb2N1bWVudCDnmoTmuLjmiI/lrr/kuLvkuIrvvIzlubblkIzmraXlrprkvY3liLDpnaLmnb/pooTop4jljLrln5/jgIJcbiAgICAgKiAgVWkg5p6E6YCg55qEIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNHYW1lQ2FudmFzJykg5L6d6LWW6L+Z5Lqb5YWD57Sg5Zyo6aG25bGCIGRvY3VtZW50IOWPr+ingeOAgiAqL1xuICAgIGJ1aWxkR2FtZURvbSh0aGlzOiBhbnkpIHtcbiAgICAgICAgY29uc3QgaG9zdCA9IHRoaXMuZW5zdXJlR2FtZUhvc3QoKTtcbiAgICAgICAgaG9zdC5pbm5lckhUTUwgPSAnJztcbiAgICAgICAgY29uc3QgZWwgPSAodGFnOiBzdHJpbmcsIGNscyA9ICcnLCBpZCA9ICcnKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpO1xuICAgICAgICAgICAgaWYgKGNscykgZS5jbGFzc05hbWUgPSBjbHM7XG4gICAgICAgICAgICBpZiAoaWQpIGUuaWQgPSBpZDtcbiAgICAgICAgICAgIHJldHVybiBlO1xuICAgICAgICB9O1xuICAgICAgICAvLyDlhoXogZTmoLflvI/vvJrnrYnku7fpooTop4jmqKHmnb8gaW5kZXguY3NzIOeahOWFs+mUruW4g+WxgO+8iOWPquS9nOeUqOS6jiAjeXlrYS1nYW1lLWhvc3Qg5YaF6YOo77yJ44CCXG4gICAgICAgIC8vIOe8uuWwkei/meS6m+agt+W8j+S8muWvvOiHtO+8mnRvb2xiYXIg6KO45aWU5pi+56S677yI5biD5bGA5Lmx77yJ44CBXG4gICAgICAgIC8vICNHYW1lRGl2LyNDb2NvczNkR2FtZUNvbnRhaW5lci8jR2FtZUNhbnZhcyDloYzpmbfkuLogMCDlsLrlr7jvvIjpu5HlsY/vvInjgIJcbiAgICAgICAgY29uc3Qgc3R5bGUgPSBlbCgnc3R5bGUnKTtcbiAgICAgICAgc3R5bGUudGV4dENvbnRlbnQgPSBgXG4gICAgICAgICAgICAjeXlrYS1nYW1lLWhvc3QsICN5eWthLWdhbWUtaG9zdCAqIHsgYm94LXNpemluZzogYm9yZGVyLWJveDsgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTsgdXNlci1zZWxlY3Q6IG5vbmU7IH1cbiAgICAgICAgICAgICN5eWthLWdhbWUtaG9zdCAudG9vbGJhciB7IGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDsgfSAvKiDpnaLmnb/lhoXkuI3pnIDopoHpooTop4jlmajmjqfku7bmnaEgKi9cbiAgICAgICAgICAgICN5eWthLWdhbWUtaG9zdCAuY29udGVudCB7XG4gICAgICAgICAgICAgICAgZmxleDogYXV0bzsgbWluLWhlaWdodDogMDtcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgICAgICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogY2VudGVyOyBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgI3l5a2EtZ2FtZS1ob3N0IC5jb250ZW50V3JhcCB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICN5eWthLWdhbWUtaG9zdCAjR2FtZURpdixcbiAgICAgICAgICAgICN5eWthLWdhbWUtaG9zdCAjQ29jb3MzZEdhbWVDb250YWluZXIsXG4gICAgICAgICAgICAjeXlrYS1nYW1lLWhvc3QgI0dhbWVDYW52YXMgeyB3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlOyB9XG4gICAgICAgICAgICAjeXlrYS1nYW1lLWhvc3QgI0dhbWVEaXYgeyBvdmVyZmxvdzogaGlkZGVuOyBwb3NpdGlvbjogcmVsYXRpdmU7IH1cbiAgICAgICAgICAgICN5eWthLWdhbWUtaG9zdCAud3JhcHBlciB7IHBvc2l0aW9uOiByZWxhdGl2ZTsgfVxuICAgICAgICAgICAgLyog6K6+5aSH5aSW5aOz5a655Zmo77ya6buY6K6k5Y+q5L2c5bGF5Lit5YyF6KO577yb6YCJ5Lit6K6+5aSH5pe25YqgIC5kZXZpY2Ug5ZGI546w5omL5py65bGP5bmV5aSW6KeCICovXG4gICAgICAgICAgICAjeXlrYS1nYW1lLWhvc3QgLmRldmljZS1mcmFtZSB7XG4gICAgICAgICAgICAgICAgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7IHdpZHRoOiBtYXgtY29udGVudDsgaGVpZ2h0OiBtYXgtY29udGVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qIOaJi+acuuWkluWjs++8iOWFqOmdouWxj++8ie+8mueqhOi+ueS4reahhiArIOWchuinkuijgeWJqu+8iOa4uOaIj+eql+WPo+ebtOinkuiiq+WchuinkumBruaOie+8jOWRiOWFqOmdouWxj++8ie+8jFxuICAgICAgICAgICAgICAgIOmhtumDqOaMluWtlOWxj+iDtuWbiuWImOa1tyArIOW6lemDqOS4i+W3tCAqL1xuICAgICAgICAgICAgI3l5a2EtZ2FtZS1ob3N0IC5kZXZpY2UtZnJhbWUuZGV2aWNlIHtcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMThweDtcbiAgICAgICAgICAgICAgICBwYWRkaW5nOiAwO1xuICAgICAgICAgICAgICAgIG92ZXJmbG93OiBoaWRkZW47IC8qIOiuqeWGhemDqOa4uOaIj+eql+WPo+ebtOinkuiiq+WchuinkuijgeWIhyAqL1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxNjBkZWcsICMzYTNmNDcgMCUsICMyMzI2MmIgNDUlLCAjMTQxNjE5IDEwMCUpO1xuICAgICAgICAgICAgICAgIGNvbG9yOiAjZmZmO1xuICAgICAgICAgICAgICAgIGJveC1zaGFkb3c6XG4gICAgICAgICAgICAgICAgICAgIGluc2V0IDAgMCAwIDFweCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMDYpLFxuICAgICAgICAgICAgICAgICAgICAwIDJweCA1cHggcmdiYSgwLCAwLCAwLCAwLjUpLFxuICAgICAgICAgICAgICAgICAgICAwIDEycHggMjZweCByZ2JhKDAsIDAsIDAsIDAuNDUpLFxuICAgICAgICAgICAgICAgICAgICAwIDI2cHggNTJweCByZ2JhKDAsIDAsIDAsIDAuNTUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLyog6L655qGG6KaG55uW5bGC77ya5Y+g5Zyo5bGP5bmV5LmL5LiK77yI5LiN6IO95ZyoIGJhY2tncm91bmQvYm94LXNoYWRvdyDnlLvvvIzpgqPkupvkvJrooqvlrZDlhYPntKDlsY/luZXnm5bkvY/vvInvvIxcbiAgICAgICAgICAgICAgICDkuK3lpK7pgI/mmI7pgI/lh7rlsY/luZXvvIzlm5vovrnmnLrouqvoibLlvaLmiJDlj6/op4HnmoTmiYvmnLrovrnmoYbvvIzlnIbop5Lot5/pmo/lpJblo7MgKi9cbiAgICAgICAgICAgICN5eWthLWdhbWUtaG9zdCAuZGV2aWNlLWZyYW1lLmRldmljZTo6YmVmb3JlIHtcbiAgICAgICAgICAgICAgICBjb250ZW50OiBcIlwiOyBwb3NpdGlvbjogYWJzb2x1dGU7IGluc2V0OiAwOyB6LWluZGV4OiA1OyBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgICAgICAgICAgICBib3JkZXI6IDZweCBzb2xpZCAjMjYyOTJmO1xuICAgICAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDE2cHg7XG4gICAgICAgICAgICAgICAgYm94LXNoYWRvdzpcbiAgICAgICAgICAgICAgICAgICAgaW5zZXQgMCAxcHggMCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMTgpLFxuICAgICAgICAgICAgICAgICAgICBpbnNldCAwIC0xcHggMCByZ2JhKDAsIDAsIDAsIDAuNTUpLFxuICAgICAgICAgICAgICAgICAgICBpbnNldCAwIDAgMCAxcHggcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjA2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qIOW6lemDqOeCueS6ruadoe+8iOWPoOWcqOi+ueahhuS4i+aWue+8jOWDjyBob21lIOmUruWFieadoe+8iSAqL1xuICAgICAgICAgICAgI3l5a2EtZ2FtZS1ob3N0IC5kZXZpY2UtZnJhbWUuZGV2aWNlOjphZnRlciB7XG4gICAgICAgICAgICAgICAgY29udGVudDogXCJcIjsgcG9zaXRpb246IGFic29sdXRlOyBib3R0b206IDJweDsgbGVmdDogNTAlOyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSk7XG4gICAgICAgICAgICAgICAgd2lkdGg6IDQ2cHg7IGhlaWdodDogMnB4OyBib3JkZXItcmFkaXVzOiAycHg7IGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4xNik7XG4gICAgICAgICAgICAgICAgei1pbmRleDogNjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qIOeBteWKqOWym+aMluWtlOmVnOWktO+8muiuvuWkh+aooeW8j+S4i+imhuebluWcqOWxj+W5lemhtumDqOS4reWkru+8jOWchuinkuiDtuWbiuWkluinguOAglxuICAgIOWwuuWvuOeUqOebuOWvueWAvO+8iOWuveW6puWPluWxj+W5leWuveeahOS4gOWumueahOeZvuWIhuavlO+8ie+8jOmaj+WkluWjs+aVtOS9k+e8qeaUvuWQjOatpeWPmOWMlu+8jFxuICAgIOmBv+WFjee8qeaUvuaXtuacuui6q+aUvuWkp+iAjOeBteWKqOWym+S/neaMgeWbuuWumuWDj+e0oOWvvOiHtOKAnOebuOWvueWPmOWwjy/lj43lkJHigJ3nmoTnjrDosaHjgIIgKi9cbiAgICAgICAgICAgICN5eWthLWdhbWUtaG9zdCAuZGV2aWNlLWZyYW1lIC5keW5hbWljLWlzbGFuZCB7XG4gICAgICAgICAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogNCU7IGxlZnQ6IDUwJTsgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC01MCUpO1xuICAgICAgICAgICAgICAgIHdpZHRoOiAyNiU7IGFzcGVjdC1yYXRpbzogNCAvIDE7IGJvcmRlci1yYWRpdXM6IDk5OXB4OyBiYWNrZ3JvdW5kOiAjMDAwO1xuICAgICAgICAgICAgICAgIHotaW5kZXg6IDY7IHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgICAgICAgICAgICAgIGJveC1zaGFkb3c6XG4gICAgICAgICAgICAgICAgICAgIGluc2V0IDAgMCAwIDFweCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMDYpLFxuICAgICAgICAgICAgICAgICAgICBpbnNldCAwIDAgNnB4IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4wNSksXG4gICAgICAgICAgICAgICAgICAgIDAgMnB4IDhweCByZ2JhKDAsIDAsIDAsIDAuNSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAjeXlrYS1nYW1lLWhvc3QgLmRldmljZS1mcmFtZS5kZXZpY2UgLmR5bmFtaWMtaXNsYW5kIHsgZGlzcGxheTogYmxvY2s7IH1cbiAgICAgICAgICAgICN5eWthLWdhbWUtaG9zdCAjc3BsYXNoIHsgcG9zaXRpb246IGFic29sdXRlOyB0b3A6IDA7IGxlZnQ6IDA7IHdpZHRoOiAxMDAlOyBoZWlnaHQ6IDEwMCU7IG92ZXJmbG93OiBoaWRkZW47IHZpc2liaWxpdHk6IGhpZGRlbjsgfVxuICAgICAgICAgICAgI3l5a2EtZ2FtZS1ob3N0ICNidWxsZXRpbiB7IHBvc2l0aW9uOiBhYnNvbHV0ZTsgbGVmdDogNTAlOyB0b3A6IDUwJTsgZGlzcGxheTogbm9uZTsgfVxuICAgICAgICAgICAgI3l5a2EtZ2FtZS1ob3N0IC5lcnJvciB7XG4gICAgICAgICAgICAgICAgY29sb3I6ICNmZmY7IHBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IDcwJTsgbWF4LXdpZHRoOiA5NjBweDsgdG9wOiA1dmg7IHJpZ2h0OiAwOyBsZWZ0OiAwO1xuICAgICAgICAgICAgICAgIG1hcmdpbjogYXV0bzsgZGlzcGxheTogbm9uZTsgei1pbmRleDogMjsgYmFja2dyb3VuZDogIzE3MTcxNzsgcGFkZGluZzogMTZweDtcbiAgICAgICAgICAgICAgICBib3JkZXItcmFkaXVzOiA0cHg7IHdvcmQtYnJlYWs6IGJyZWFrLWFsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICN5eWthLWdhbWUtaG9zdCBjYW52YXMgeyBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDsgb3V0bGluZTogbm9uZTsgfVxuICAgICAgICBgO1xuICAgICAgICBob3N0LmFwcGVuZENoaWxkKHN0eWxlKTtcbiAgICAgICAgLy8g6aKE6KeI5ZmoIFVJIOaOp+S7tuadoe+8mlVpIOaehOmAoOWHveaVsOeUqCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yIOW8uuS+nei1lui/meS6m+WFg+e0oO+8jOe8uuWkseWNs+aKm1xuICAgICAgICAvLyBcIlVJIGVsZW1lbnQgeHh4IGRvZXNuJ3QgZXhpc3RcIuOAguaYvuekuuWxgumdoueUsSBDU1Mg6ZqQ6JeP44CCXG4gICAgICAgIGNvbnN0IHRvb2xiYXIgPSBlbCgnZGl2JywgJ3Rvb2xiYXIgZGlzYWJsZWQnKTtcbiAgICAgICAgLy8g6K6+5aSH5YiX6KGoIGRhdGEtZGV2aWNlIOS4juecn+WunumihOiniOacjeWKoea4suafk+eahOWujOWFqOS4gOiHtO+8jHByZXZpZXctYXBwIOaNruatpOmUruW6lOeUqOWIhui+qOeOh+OAglxuICAgICAgICB0b29sYmFyLmlubmVySFRNTCA9IGBcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtXCI+PGRpdiBpZD1cInZpZXctc2VsZWN0XCIgY2xhc3M9XCJ2aWV3LXNlbGVjdC1jb250YWluZXJcIiB2YWx1ZT1cIkRlZmF1bHRcIiB0YWJpbmRleD1cIi0xXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZpZXctc2VsZWN0XCI+PGRpdiBjbGFzcz1cImxhYmVsXCI+PHNwYW4gaWQ9XCJuYW1lXCI+PC9zcGFuPjwvZGl2PjxpIGNsYXNzPVwiYXJyb3ctdHJpYW5nbGVcIj48L2k+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9wdGlvbnNcIj48dWw+XG4gICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInNlbGVjdGVkXCIgZGF0YS1kZXZpY2U9XCJEZWZhdWx0XCI+6K6+6K6h5YiG6L6o546HICg5NjBYNjQwKTwvbGk+XG4gICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cIlwiIGRhdGEtZGV2aWNlPVwiRnVsbFNjcmVlblwiPuWFqOWxjzwvbGk+XG4gICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cIlwiIGRhdGEtZGV2aWNlPVwiV2VicGFnZUZ1bGxTY3JlZW5cIj7nvZHpobXlhajlsY88L2xpPlxuICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJzZXBhcmF0b3JcIj48L2xpPlxuICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJcIiBkYXRhLWRldmljZT1cIkFwcGxlIGlQaG9uZSAxMjsgMTM7IDE0OyAxMi8xMyBQcm9cIj5pUGhvbmUgMTIvMTMvMTQgKDM5MFg4NDQpPC9saT5cbiAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwiXCIgZGF0YS1kZXZpY2U9XCJBcHBsZSBpUGhvbmUgMTQgUHJvXCI+aVBob25lIDE0IFBybyAoMzkzWDg1Mik8L2xpPlxuICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJcIiBkYXRhLWRldmljZT1cIkFwcGxlIGlQaG9uZSAxMi8xMyBQcm8gTWF4OyAxNCBQbHVzXCI+aVBob25lIFBybyBNYXgvMTQgUGx1cyAoNDI4WDkyNik8L2xpPlxuICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJcIiBkYXRhLWRldmljZT1cIkFwcGxlIGlQaG9uZSBYUjsgMTFcIj5pUGhvbmUgWFIvMTEgKDQxNFg4OTYpPC9saT5cbiAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwiXCIgZGF0YS1kZXZpY2U9XCJBcHBsZSBpUGhvbmUgWDsgWFM7IDExIFBybzsgMTIvMTMgTWluaVwiPmlQaG9uZSBYL1hTICgzNzVYODEyKTwvbGk+XG4gICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cIlwiIGRhdGEtZGV2aWNlPVwiQXBwbGUgaVBhZCAxMC4yXCI+aVBhZCAxMC4yICgxNjIwWDIxNjApPC9saT5cbiAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwiXCIgZGF0YS1kZXZpY2U9XCJIVUFXRUkgTWF0ZSA0MCBQcm9cIj5IVUFXRUkgTWF0ZSA0MCBQcm8gKDQ0OFg5MjQpPC9saT5cbiAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwiXCIgZGF0YS1kZXZpY2U9XCJPUFBPIFJlbm8gMlwiPk9QUE8gUmVubyAyICgzNjBYODAwKTwvbGk+XG4gICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cIlwiIGRhdGEtZGV2aWNlPVwiWGlhb21pIFJlZG1pIDhcIj5YaWFvbWkgUmVkbWkgOCAoMzYwWDc2MCk8L2xpPlxuICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJcIiBkYXRhLWRldmljZT1cIkxlbm92byBMZWdpb24gMiBQcm9cIj5MZW5vdm8gTGVnaW9uIDIgUHJvICgzNjBYODIwKTwvbGk+XG4gICAgICAgICAgICAgICAgPC91bD48L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW1cIj48YnV0dG9uIGlkPVwiYnRuLXJvdGF0ZVwiIGNsYXNzPVwiY2hlY2tlZFwiPlJvdGF0ZTwvYnV0dG9uPjwvZGl2PlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpdGVtXCI+RGVidWcgTW9kZTo8L3NwYW4+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbVwiPjxzZWxlY3QgaWQ9XCJvcHRzLWRlYnVnLW1vZGVcIiB2YWx1ZT1cIklORk9cIj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiTk9ORVwiPk5vbmU8L29wdGlvbj48b3B0aW9uIHZhbHVlPVwiVkVSQk9TRVwiPlZlcmJvc2U8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiSU5GT1wiPkluZm88L29wdGlvbj48b3B0aW9uIHZhbHVlPVwiV0FSTlwiPldhcm48L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiRVJST1JcIj5FcnJvcjwvb3B0aW9uPjxvcHRpb24gdmFsdWU9XCJJTkZPX0ZPUl9XRUJfUEFHRVwiPkluZm8gRm9yIFdlYiBQYWdlPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIldBUk5fRk9SX1dFQl9QQUdFXCI+V2FybiBGb3IgV2ViIFBhZ2U8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiRVJST1JfRk9SX1dFQl9QQUdFXCI+RXJyb3IgRm9yIFdlYiBQYWdlPC9vcHRpb24+XG4gICAgICAgICAgICA8L3NlbGVjdD48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtXCI+PGJ1dHRvbiBpZD1cImJ0bi1zaG93LWZwc1wiIGNsYXNzPVwiXCI+U2hvdyBGUFM8L2J1dHRvbj48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtXCI+PHNwYW4+RlBTOjwvc3Bhbj48aW5wdXQgaWQ9XCJpbnB1dC1zZXQtZnBzXCIgdHlwZT1cIm51bWJlclwiIHZhbHVlPVwiNjBcIiAvPjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBpZD1cInN0ZXAtbGVuZ3RoXCI+PHNwYW4+U3RlcCBMZW5ndGg6IDwvc3Bhbj48aW5wdXQgdHlwZT1cInRleHRcIiB2YWx1ZT1cIjFcIj48c3Bhbj5tczwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtXCI+PGJ1dHRvbiBpZD1cImJ0bi1wYXVzZVwiPlBhdXNlPC9idXR0b24+PGJ1dHRvbiBpZD1cImJ0bi1zdGVwXCIgc3R5bGU9XCJkaXNwbGF5Om5vbmU7XCI+U3RlcDwvYnV0dG9uPjwvZGl2PmA7XG4gICAgICAgIGhvc3QuYXBwZW5kQ2hpbGQodG9vbGJhcik7XG4gICAgICAgIGNvbnN0IGdhbWVEaXYgPSBlbCgnZGl2JywgJ3dyYXBwZXInLCAnR2FtZURpdicpO1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSBlbCgnZGl2JywgJycsICdDb2NvczNkR2FtZUNvbnRhaW5lcicpO1xuICAgICAgICBjb25zdCBjYW52YXMgPSBlbCgnY2FudmFzJywgJycsICdHYW1lQ2FudmFzJyk7XG4gICAgICAgIGNhbnZhcy50YWJJbmRleCA9IC0xO1xuICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoY2FudmFzKTtcbiAgICAgICAgZ2FtZURpdi5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuICAgICAgICBjb25zdCBzcGxhc2ggPSBlbCgnZGl2JywgJycsICdzcGxhc2gnKTtcbiAgICAgICAgY29uc3QgYmFyID0gZWwoJ2RpdicsICdwcm9ncmVzcy1iYXIgc3RyaXBlcycpO1xuICAgICAgICBiYXIuaW5uZXJIVE1MID0gJzxzcGFuPjwvc3Bhbj4nO1xuICAgICAgICBzcGxhc2guYXBwZW5kQ2hpbGQoYmFyKTtcbiAgICAgICAgZ2FtZURpdi5hcHBlbmRDaGlsZChzcGxhc2gpO1xuICAgICAgICBjb25zdCBidWxsZXRpbiA9IGVsKCdkaXYnLCAnJywgJ2J1bGxldGluJyk7XG4gICAgICAgIGNvbnN0IGVtcHR5ID0gZWwoJ2RpdicsICdpbm5lcicsICdzY2VuZUlzRW1wdHknKTtcbiAgICAgICAgZW1wdHkudGV4dENvbnRlbnQgPSAn6aKE6KeI5Zy65pmv5Lit5ZWl6YO95rKh5pyJ77yM5Yqg54K55LuA5LmI77yM5oiW5Zyo57yW6L6R5Zmo5Lit5omT5byA5YW25a6D5Zy65pmv5ZCnJztcbiAgICAgICAgYnVsbGV0aW4uYXBwZW5kQ2hpbGQoZW1wdHkpO1xuICAgICAgICBnYW1lRGl2LmFwcGVuZENoaWxkKGJ1bGxldGluKTtcbiAgICAgICAgY29uc3QgZXJyID0gZWwoJ2RpdicsICdlcnJvcicsICdlcnJvcicpO1xuICAgICAgICBlcnIuYXBwZW5kQ2hpbGQoZWwoJ2RpdicsICd0aXRsZScpKS50ZXh0Q29udGVudCA9ICdFcnJvciAoUGxlYXNlIG9wZW4gdGhlIGNvbnNvbGUgdG8gc2VlIGRldGFpbGVkIGVycm9ycyknO1xuICAgICAgICBlcnIuYXBwZW5kQ2hpbGQoZWwoJ2RpdicsICdlcnJvci1tYWluJykpO1xuICAgICAgICBlcnIuYXBwZW5kQ2hpbGQoZWwoJ2RpdicsICdlcnJvci1zdGFjaycpKTtcbiAgICAgICAgZ2FtZURpdi5hcHBlbmRDaGlsZChlcnIpO1xuICAgICAgICBjb25zdCBmcmFtZSA9IGVsKCdkaXYnLCAnZGV2aWNlLWZyYW1lJyk7IC8vIOaJi+acuuWkluWjs+WuueWZqO+8mumAieS4reiuvuWkh+aXtuWRiOeOsOaJi+acuuWxj+W5leagt+W8j1xuICAgICAgICBmcmFtZS5hcHBlbmRDaGlsZChnYW1lRGl2KTtcbiAgICAgICAgZnJhbWUuYXBwZW5kQ2hpbGQoZWwoJ2RpdicsICdkeW5hbWljLWlzbGFuZCcpKTsgLy8g54G15Yqo5bKb5oyW5a2U5pGE5YOP5aS077yI6KaG55uW5bGP5bmV5LmL5LiK77yJXG4gICAgICAgIGNvbnN0IHdyYXAgPSBlbCgnZGl2JywgJ2NvbnRlbnRXcmFwJyk7XG4gICAgICAgIHdyYXAuYXBwZW5kQ2hpbGQoZnJhbWUpO1xuICAgICAgICBjb25zdCBjb250ZW50ID0gZWwoJ2RpdicsICdjb250ZW50Jyk7XG4gICAgICAgIGNvbnRlbnQuYXBwZW5kQ2hpbGQod3JhcCk7XG4gICAgICAgIGhvc3QuYXBwZW5kQ2hpbGQoY29udGVudCk7XG4gICAgICAgIC8vIOehruiupCAjR2FtZUNhbnZhcyDlt7LmjILovb3liLDpobblsYIgZG9jdW1lbnTvvIhVaSDmnoTpgKDkvp3otZbvvIlcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNHYW1lQ2FudmFzJykpIHtcbiAgICAgICAgICAgIHRoaXMubG9ncy5wdXNoKHsgZXZ0OiAnc3lzJywgbXNnOiAnW+mihOiniF0g5ri45oiPIERPTSDlsLHnu6ogKCNHYW1lQ2FudmFzIOW3suaMgui9veWIsOmhtuWxgiBkb2N1bWVudCknIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5sb2dzLnB1c2goeyBldnQ6ICdzeXMnLCBtc2c6ICdb6aKE6KeIXSDorablkYo6ICNHYW1lQ2FudmFzIOacquaMgui9veWIsOmhtuWxgiBkb2N1bWVudCcgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zeW5jR2FtZUhvc3QoKTtcbiAgICAgICAgdGhpcy5vYnNlcnZlR2FtZUhvc3QoKTtcbiAgICB9LFxuICAgIC8qKiDms6jlhaXooaXlhYUgaW1wb3J0LW1hcO+8mnByZXZpZXctYXBwIOWGhemDqOehrOe8lueggSBpbXBvcnQoXCIvc29ja2V0LmlvL3NvY2tldC5pby5qc1wiKe+8jFxuICAgICAqICDor6Xot6/lvoTln7rkuo7pnaLmnb8gb3JpZ2luIOino+aekOS8miA0MDTvvIzpnIDmmKDlsITliLDpooTop4jmnI3liqHnu53lr7nlnLDlnYDjgIJcbiAgICAgKiAg5b+F6aG75ZyoIHN5c3RlbS5qcyDliqDovb3liY3ms6jlhaXvvIxTeXN0ZW1KUyDliJ3lp4vljJbml7bmiY3kvJrmlLbpm4bjgIIgKi9cbiAgICBpbmplY3RFeHRyYUltcG9ydE1hcCh0aGlzOiBhbnkpIHtcbiAgICAgICAgY29uc3QgaW5qID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICAgIGluai50eXBlID0gJ3N5c3RlbWpzLWltcG9ydG1hcCc7XG4gICAgICAgIGluai50ZXh0Q29udGVudCA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIGltcG9ydHM6IHtcbiAgICAgICAgICAgICAgICAnL3NvY2tldC5pby9zb2NrZXQuaW8uanMnOiB0aGlzLmFicygnL3NvY2tldC5pby9zb2NrZXQuaW8uanMnKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGluaik7XG4gICAgfSxcbiAgICAvKiog5ZyoIC9zb2NrZXQuaW8vc29ja2V0LmlvLmpz77yI5pig5bCE5ZCO55qE57ud5a+55Zyw5Z2A77yJ5rOo5YaMIFN5c3RlbUpTIHN0dWIg5qih5Z2X44CCXG4gICAgICogIOW/hemhu+WcqCBzeXN0ZW0uanMg5Yqg6L295LmL5ZCO44CBU3lzdGVtLmltcG9ydChwcmV2aWV3LWFwcCkg5LmL5YmN6LCD55So44CCICovXG4gICAgcmVnaXN0ZXJTb2NrZXRJb1N0dWIodGhpczogYW55KSB7XG4gICAgICAgIGNvbnN0IFN5cyA9ICh3aW5kb3cgYXMgYW55KS5TeXN0ZW07XG4gICAgICAgIGNvbnN0IHNvY2tldFVybCA9IHRoaXMuYWJzKCcvc29ja2V0LmlvL3NvY2tldC5pby5qcycpO1xuICAgICAgICBpZiAoIVN5cyB8fCB0eXBlb2YgU3lzLnJlZ2lzdGVyICE9PSAnZnVuY3Rpb24nIHx8IFN5cy5oYXMoc29ja2V0VXJsKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIFN5cy5yZWdpc3Rlcihzb2NrZXRVcmwsIFtdLCAoX2V4cG9ydDogYW55KSA9PiAoe1xuICAgICAgICAgICAgLy8g5rOo5oSP77yaZXhlY3V0ZSDkuI3lvpfov5Tlm57nnJ/lgLzvvIhfZXhwb3J0IOeahOi/lOWbnuWAvOaYr+WvvOWHuueahOWAvO+8jOWmgiBzb2NrZXRJb1N0dWIg5Ye95pWw77yJ44CCXG4gICAgICAgICAgICAvLyBTeXN0ZW1KUyDnmoQgZG9FeGVjIOWvueecn+WAvOebtOaOpeiwgyBleGVjUHJvbWlzZS50aGVuKC4uLinvvIzpnZ4gUHJvbWlzZSDljbPmiptcbiAgICAgICAgICAgIC8vIFwiZXhlY1Byb21pc2UudGhlbiBpcyBub3QgYSBmdW5jdGlvblwi77yb6L+U5ZueIHVuZGVmaW5lZCDotbDlkIzmraXlrozmiJDliIbmlK/jgIJcbiAgICAgICAgICAgIGV4ZWN1dGU6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBfZXhwb3J0KCdkZWZhdWx0Jywgc29ja2V0SW9TdHViKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pKTtcbiAgICAgICAgdGhpcy5sb2dzLnB1c2goeyBldnQ6ICdzeXMnLCBtc2c6IGBb6aKE6KeIXSBzb2NrZXQuaW8gc3R1YiDlt7Lms6jlhowgKCR7c29ja2V0VXJsfSlgIH0pO1xuICAgIH0sXG4gICAgLyoqIOmihOiniOeOr+Wig+ihpem9kO+8mumdouadv+i/kOihjOWcqOe8lui+keWZqCBFbGVjdHJvbiDnqpflj6PlhoXvvIzlvJXmk44gY2MvZW52IOaooeWdl+eUqFxuICAgICAqICB0cnlEZWZpbmVHbG9iYWwoJ0NDX0VESVRPUicsIOaOoua1iyBlbGVjdHJvbiBwcm9jZXNzKSDkvJrmioogRURJVE9SIOivr+WIpOS4uiB0cnVl77yMXG4gICAgICogIOS7juiAjOi1sOi/m+e8lui+keWZqOahpeaOpeWIhuaUr+W5tuW8leeUqOacquWumuS5ieeahCBFZGl0b3JFeHRlbmRzIOWFqOWxgOWvvOiHtOW0qea6g1xuICAgICAqICDvvIjnnJ/lrp7mtY/op4jlmajpooTop4jml6AgcHJvY2Vzc++8jEVESVRPUj1mYWxzZSDmlYXmraPluLjvvInjgILlv4XpobvlnKjlvJXmk44gYnVuZGxlIOWKoOi9veWJjVxuICAgICAqICDpooTnva7mraPnoa7nmoTpooTop4jmoIflv5cgKyBFZGl0b3JFeHRlbmRzIOahqeOAgiAqL1xuICAgIHBhdGNoUHJldmlld0Vudih0aGlzOiBhbnkpIHtcbiAgICAgICAgLy8g6aKE572u546v5aKD5qCH5b+X77yaY2MvZW52IOeahCB0cnlEZWZpbmVHbG9iYWwg5LyY5YWI6K+7IHdpbmRvdyDkuIrnmoTlkIzlkI3lhajlsYBcbiAgICAgICAgKHdpbmRvdyBhcyBhbnkpLkNDX0VESVRPUiA9IGZhbHNlO1xuICAgICAgICAod2luZG93IGFzIGFueSkuQ0NfUFJFVklFVyA9IHRydWU7XG4gICAgICAgICh3aW5kb3cgYXMgYW55KS5DQ19ERVYgPSB0cnVlO1xuICAgICAgICAod2luZG93IGFzIGFueSkuQ0NfSlNCID0gZmFsc2U7XG4gICAgICAgIC8vIEVkaXRvckV4dGVuZHMg5qGp77ya5YWc5L2P5byV5pOO5Lit5pegIEVESVRPUiDlrojljavnmoTlvJXnlKhcbiAgICAgICAgLy8g77yI5aaCIE5vZGUuX3JlZ2lzdGVySWZBdHRhY2hlZCDnmoQgYGlmIChFZGl0b3JFeHRlbmRzLk5vZGUgJiYgLi4uKWDvvInvvIxcbiAgICAgICAgLy8g5ZCE5oiQ5ZGY5Li6IG5vLW9w77yM6YG/5YWNIFJlZmVyZW5jZUVycm9yL1R5cGVFcnJvcu+8jOS5n+S4jeS6p+eUn+e8lui+keWZqOWJr+S9nOeUqOOAglxuICAgICAgICAod2luZG93IGFzIGFueSkuRWRpdG9yRXh0ZW5kcyA9IHtcbiAgICAgICAgICAgIE5vZGU6IHsgYWRkKCkge30sIHJlbW92ZSgpIHt9LCBnZXROb2RlKCkgeyByZXR1cm4gbnVsbDsgfSwgZW1pdCgpIHt9IH0sXG4gICAgICAgICAgICBDb21wb25lbnQ6IHsgYWRkKCkge30sIHJlbW92ZSgpIHt9LCBhZGRNZW51KCkge30sIHJlbW92ZU1lbnUoKSB7fSB9LFxuICAgICAgICAgICAgUHJlZmFiVXRpbHM6IHsgYWRkUHJlZmFiSW5zdGFuY2UoKSB7fSB9LFxuICAgICAgICAgICAgc2VyaWFsaXplOiB7IGFzQXNzZXQoKSB7IHJldHVybiBudWxsOyB9IH0sXG4gICAgICAgICAgICBVdWlkVXRpbHM6IHsgaXNVdWlkKCkgeyByZXR1cm4gZmFsc2U7IH0sIGRlY29tcHJlc3NVdWlkKCkgeyByZXR1cm4gbnVsbDsgfSB9LFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmxvZ3MucHVzaCh7IGV2dDogJ3N5cycsIG1zZzogJ1vpooTop4hdIOmihOiniOeOr+Wig+W3suihpem9kCAoQ0NfRURJVE9SPWZhbHNlLCBFZGl0b3JFeHRlbmRzIHN0dWIpJyB9KTtcbiAgICB9LFxuICAgIC8qKiDljIXoo4Ugd2luZG93LmZldGNoICsgWE1MSHR0cFJlcXVlc3TvvJrorrDlvZXpooTop4jmnI3liqEob3JpZ2luIOWMuemFjSnor7fmsYLnmoTpnZ4gMnh4IOWTjeW6lO+8jFxuICAgICAqICDpnaLmnb/lhoXnnIvkuI3liLDnvZHnu5zpnaLmnb/ml7bnmoTosIPor5XlhZzlupXvvJvnvJbovpHlmajoh6rouqvor7fmsYLkuI3lj5flvbHlk43jgIJcbiAgICAgKiAg5byV5pOOIEFzc2V0TWFuYWdlciDpg6jliIbkuIvovb3otbAgWEhS77yM5Y+q5YyF6KOFIGZldGNoIOS8mua8j+aOiei1hOa6kOWKoOi9veWksei0peOAglxuICAgICAqICDms6jmhI/vvJrmr4/mrKHmuLLmn5Ppg73osIPnlKjmnKzmlrnms5Xph43oo4XvvIzkvYbln7rkuo4gd2luZG93IOS4iuS/neWtmOeahOOAjOWOn+Wni+W8leeUqOOAjemHjeaWsOWMheijhVxuICAgICAqICDvvIhfX3l5a2FSYXdJbyDlj6rlrZjkuIDmrKHvvInvvIzml6Lkv53or4HmnIDmlrDniYjmnKzpgLvovpHnlJ/mlYjvvIzlj4jpgb/lhY3lsYLlsYLltYzlpZfjgIIgKi9cbiAgICBob29rRmV0Y2hMb2dnZXIodGhpczogYW55KSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBjb25zdCB3ID0gd2luZG93IGFzIGFueTtcbiAgICAgICAgLy8g5Y6f5aeLIElPIOW8leeUqOWPquS/neWtmOS4gOasoe+8muaXp+eJiOacrOayoeacieatpOagh+iusOaXtummluasoeWPluOAjOW9k+WJjeWunueOsOOAje+8iOWPr+iDveaYr+aXp+WMheijhe+8ie+8jFxuICAgICAgICAvLyDlip/og73nrYnku7fvvJtXZWJDb250ZW50cyDph43lu7rlkI4gd2luZG93IOWFqOaWsO+8jOi/memHjOWPluWIsOWOn+eUn+WunueOsOOAglxuICAgICAgICBpZiAoIXcuX195eWthUmF3SW8pIHtcbiAgICAgICAgICAgIHcuX195eWthUmF3SW8gPSB7XG4gICAgICAgICAgICAgICAgZmV0Y2g6IHcuZmV0Y2guYmluZCh3KSxcbiAgICAgICAgICAgICAgICB4aHJPcGVuOiBYTUxIdHRwUmVxdWVzdC5wcm90b3R5cGUub3BlbixcbiAgICAgICAgICAgICAgICB4aHJTZW5kOiBYTUxIdHRwUmVxdWVzdC5wcm90b3R5cGUuc2VuZCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmF3ID0gdy5fX3l5a2FSYXdJbyBhcyB7XG4gICAgICAgICAgICBmZXRjaDogdHlwZW9mIHdpbmRvdy5mZXRjaDtcbiAgICAgICAgICAgIHhock9wZW46IHR5cGVvZiBYTUxIdHRwUmVxdWVzdC5wcm90b3R5cGUub3BlbjtcbiAgICAgICAgICAgIHhoclNlbmQ6IHR5cGVvZiBYTUxIdHRwUmVxdWVzdC5wcm90b3R5cGUuc2VuZDtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgYmFzZSA9ICh0aGlzLnByZXZpZXdVcmwgfHwgJycpLnRyaW0oKS5yZXBsYWNlKC9cXC8rJC8sICcnKTtcbiAgICAgICAgY29uc3QgaW5QcmV2aWV3ID0gKHU6IHN0cmluZykgPT4gISFiYXNlICYmIHUuaW5kZXhPZihiYXNlKSA9PT0gMDtcbiAgICAgICAgLy8g5Y+q6K6w5b2V5YWz6ZSu6K+35rGC77ya6Z2eIDIwMO+8iOWksei0pS9DT1JTIOaLpuaIqiBzdGF0dXM9MO+8ieaIliBVUkwg5ZCrIC9zY2VuZS/vvIjlnLrmma/liqDovb3nu5PmnpzvvIlcbiAgICAgICAgY29uc3Qgc2hvdWxkTG9nID0gKHU6IHN0cmluZywgc3RhdHVzOiBudW1iZXIpID0+IHN0YXR1cyAhPT0gMjAwIHx8IC9cXC9zY2VuZVxcLy9pLnRlc3QodSk7XG4gICAgICAgIC8vIOe6r+ebuOWvuei3r+W+hO+8iOaXoCBzY2hlbWXjgIHkuI3ku6UgLyDmiJYgLy8g5byA5aS077yJ5Zyo57yW6L6R5ZmoIGRvY3VtZW50IOS4i+S8muino+aekOWIsOe8lui+keWZqCBvcmlnaW7vvIxcbiAgICAgICAgLy8g6ICMIHByZXZpZXctYXBwL+W8leaTjuS7peebuOWvuei3r+W+hOivt+axguWcuuaZr+S4jui1hOa6kO+8iHNjZW5lL3h4eC5qc29u44CBYXNzZXRzL2dlbmVyYWwvaW1wb3J0Ly4uLu+8ieOAglxuICAgICAgICAvLyDmtY/op4jlmajpooTop4jpobXpnaLlsLHlnKjpooTop4ggb3JpZ2luIOS4i+aJgOS7peato+W4uO+8m+mdouadv+WGheW/hemhu+aUueWGmeaIkOmihOiniOacjeWKoee7neWvueWcsOWdgO+8jFxuICAgICAgICAvLyDlkKbliJnlnLrmma8gSlNPTiA0MDQg4oaSIG5vLXNjZW5lIOm7keWxj+OAglxuICAgICAgICAvLyDnibnliKvms6jmhI/vvJrlvJXmk44gd2FzbSDotbDmoLnnm7jlr7kgL2VuZ2luZV9leHRlcm5hbC8/dXJsPWV4dGVybmFsOi4uLu+8iHdhc20td2ViLnRz77yJ77yMXG4gICAgICAgIC8vIOaMiemdouadvyBvcmlnaW4g6Kej5p6Q5Lya5aSx6LSl77yM5LiU6K+lIGZldGNoIOeahCBjYXRjaCDmmK/nqbrlrp7njrDvvIhwcm9taXNlIOawuOS4jSByZXNvbHZl77yJ77yMXG4gICAgICAgIC8vIOWvvOiHtCBnYW1lLmluaXQg5rC45LmF5oyC6LW3IOKGkiBuby1zY2VuZSDpu5HlsY/kuJTml6Dku7vkvZXmiqXplJnjgILlv4XpobvkuIDlubbmlLnlhpnkuLrpooTop4jmnI3liqEgb3JpZ2lu44CCXG4gICAgICAgIGNvbnN0IHRvQWJzID0gKHU6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gICAgICAgICAgICBpZiAoL15bYS16XVthLXowLTkrLi1dKjovaS50ZXN0KHUpIHx8IHUuc3RhcnRzV2l0aCgnLy8nKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHUuc3RhcnRzV2l0aCgnL2VuZ2luZV9leHRlcm5hbC8nKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLmFicyh1KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB1LnN0YXJ0c1dpdGgoJy8nKSA/IHUgOiBzZWxmLmFicyh1KTtcbiAgICAgICAgfTtcbiAgICAgICAgdy5mZXRjaCA9IChpbnB1dDogUmVxdWVzdEluZm8gfCBVUkwsIGluaXQ/OiBSZXF1ZXN0SW5pdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmF3MCA9IGlucHV0O1xuICAgICAgICAgICAgY29uc3QgcmVhbElucHV0ID0gdHlwZW9mIHJhdzAgPT09ICdzdHJpbmcnID8gdG9BYnMocmF3MCkgOiByYXcwO1xuICAgICAgICAgICAgY29uc3QgcmVhbFN0ciA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIHJlYWxJbnB1dCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICAgICAgICAgPyByZWFsSW5wdXRcbiAgICAgICAgICAgICAgICAgICAgOiByZWFsSW5wdXQgaW5zdGFuY2VvZiBVUkxcbiAgICAgICAgICAgICAgICAgICAgICAgID8gcmVhbElucHV0LmhyZWZcbiAgICAgICAgICAgICAgICAgICAgICAgIDogU3RyaW5nKChyZWFsSW5wdXQgJiYgKHJlYWxJbnB1dCBhcyBhbnkpLnVybCkgfHwgJycpO1xuICAgICAgICAgICAgcmV0dXJuIHJhdy5mZXRjaChyZWFsSW5wdXQsIGluaXQpXG4gICAgICAgICAgICAgICAgLnRoZW4oKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluUHJldmlldyhyZWFsU3RyKSAmJiBzaG91bGRMb2cocmVhbFN0ciwgcmVzLnN0YXR1cykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubG9ncy5wdXNoKHsgZXZ0OiAnc3lzJywgbXNnOiBgW+mihOiniOe9kee7nF0gZmV0Y2ggJHtyZXMuc3RhdHVzfSAke3JlYWxTdHJ9YCB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8g5byV5pOO55qEIHdhc20gZmV0Y2gg6Z2Z6buY5ZCe6ZSZ77yM6L+Z6YeM6KGl5pel5b+X5a6a5L2N5Yqg6L295aSx6LSl55qE55yf5a6eIFVSTFxuICAgICAgICAgICAgICAgICAgICBpZiAoaW5QcmV2aWV3KHJlYWxTdHIpIHx8IC9cXC9lbmdpbmVfZXh0ZXJuYWxcXC8vaS50ZXN0KHJlYWxTdHIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxvZ3MucHVzaCh7IGV2dDogJ3N5cycsIG1zZzogYFvpooTop4jnvZHnu5xdIGZldGNoIOWksei0pSAke3JlYWxTdHJ9OiAke1N0cmluZygoZSAmJiBlLm1lc3NhZ2UpIHx8IGUpfWAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gWEhS77ya5pS55YaZ55u45a+56Lev5b6EICsg6K6w5b2V5YWz6ZSu6K+35rGC77yI5Zy65pmvL+e6ueeQhi/pn7PpopHnrYnvvIlcbiAgICAgICAgWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbiAodGhpczogYW55LCBtZXRob2Q6IHN0cmluZywgdXJsOiBzdHJpbmcsIC4uLnJlc3Q6IGFueVtdKSB7XG4gICAgICAgICAgICBjb25zdCB1ID0gdG9BYnMoU3RyaW5nKHVybCkpO1xuICAgICAgICAgICAgdGhpcy5fX3l5a2FVcmwgPSB1O1xuICAgICAgICAgICAgcmV0dXJuIHJhdy54aHJPcGVuLmFwcGx5KHRoaXMsIFttZXRob2QsIHUsIC4uLnJlc3RdIGFzIGFueSk7XG4gICAgICAgIH07XG4gICAgICAgIFhNTEh0dHBSZXF1ZXN0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKHRoaXM6IGFueSwgLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB1ID0gdGhpcy5fX3l5a2FVcmwgfHwgJyc7XG4gICAgICAgICAgICAgICAgaWYgKGluUHJldmlldyh1KSAmJiBzaG91bGRMb2codSwgdGhpcy5zdGF0dXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYubG9ncy5wdXNoKHsgZXZ0OiAnc3lzJywgbXNnOiBgW+mihOiniOe9kee7nF0gWEhSICR7dGhpcy5zdGF0dXN9ICR7dX1gIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB1ID0gdGhpcy5fX3l5a2FVcmwgfHwgJyc7XG4gICAgICAgICAgICAgICAgaWYgKGluUHJldmlldyh1KSkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmxvZ3MucHVzaCh7IGV2dDogJ3N5cycsIG1zZzogYFvpooTop4jnvZHnu5xdIFhIUiDlpLHotKUgJHt1fWAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcmF3LnhoclNlbmQuYXBwbHkodGhpcywgYXJncyBhcyBhbnkpO1xuICAgICAgICB9O1xuICAgICAgICAvLyDlvJXmk47nurnnkIYv5Zu+54mH55SoIEltYWdlIOWFg+e0oOWKoOi9ve+8jOebuOWvuSBzcmMg5ZCM5qC35Z+65LqOIGRvY3VtZW50IGJhc2Ug6Kej5p6Q77yM5LiA5bm25pS55YaZ44CCXG4gICAgICAgIC8vIOWQjOaXtuW8uuWItui3qOa6kOWbvueJh+W4piBjcm9zc09yaWdpbj0nYW5vbnltb3VzJ++8muW8leaTjueahCBkb3dubG9hZC1kb20taW1hZ2Ug5Y+q5ZyoXG4gICAgICAgIC8vIGxvY2F0aW9uLnByb3RvY29sICE9PSAnZmlsZTonIOaXtuiuvue9ru+8jOmdouadvy9maWxlOi8vIOetiei3qOa6kOWcuuaZr+S4i+a8j+iuvuS8muWvvOiHtFxuICAgICAgICAvLyBXZWJHTCDnurnnkIbkuIrkvKDlpLHotKXvvIh0ZXhTdWJJbWFnZTJEIFNlY3VyaXR5RXJyb3Ig4oaSIOeyieiJsui0tOWbvu+8ieOAglxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc3JjRGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoSFRNTEltYWdlRWxlbWVudC5wcm90b3R5cGUsICdzcmMnKTtcbiAgICAgICAgICAgIGlmIChzcmNEZXNjICYmIHNyY0Rlc2Muc2V0KSB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEhUTUxJbWFnZUVsZW1lbnQucHJvdG90eXBlLCAnc3JjJywge1xuICAgICAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICh0aGlzOiBIVE1MSW1hZ2VFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3JjRGVzYy5nZXQhLmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHRoaXM6IEhUTUxJbWFnZUVsZW1lbnQsIHY6IHN0cmluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbnYgPSB0eXBlb2YgdiA9PT0gJ3N0cmluZycgPyB0b0Ficyh2KSA6IHY7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG52ID09PSAnc3RyaW5nJyAmJiAvXmh0dHBzPzovaS50ZXN0KG52KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3Jvc3NPcmlnaW4gPSAnYW5vbnltb3VzJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzcmNEZXNjLnNldCEuY2FsbCh0aGlzLCBudik7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgICAgLyogaWdub3JlICovXG4gICAgICAgIH1cbiAgICAgICAgLy8g5byV5pOOIGJ1bmRsZSDohJrmnKzvvIhhc3NldHMvaW50ZXJuYWwvaW5kZXguanPjgIFhc3NldHMvbWFpbi9pbmRleC5qcyDnrYnvvInnlLEgZG93bmxvYWRTY3JpcHRcbiAgICAgICAgLy8g55u05o6l6K6+IHNjcmlwdC5zcmPvvIjnm7jlr7not6/lvoTvvInvvIzkuI3nu4/ov4cgZmV0Y2gvWEhS77yM5b+F6aG75ZCM5qC35pS55YaZ5Li66aKE6KeI5pyN5Yqh57ud5a+55Zyw5Z2A77yMXG4gICAgICAgIC8vIOWQpuWImeaMiemdouadvyBvcmlnaW4g6Kej5p6QIDQwNCDihpIgbG9hZEJ1aWx0aW5Bc3NldHMg5aSx6LSlIOKGkiBnYW1lLmluaXQg5oyC6LW3IOKGkiBuby1zY2VuZeOAglxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc2NyaXB0RGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoSFRNTFNjcmlwdEVsZW1lbnQucHJvdG90eXBlLCAnc3JjJyk7XG4gICAgICAgICAgICBpZiAoc2NyaXB0RGVzYyAmJiBzY3JpcHREZXNjLnNldCkge1xuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShIVE1MU2NyaXB0RWxlbWVudC5wcm90b3R5cGUsICdzcmMnLCB7XG4gICAgICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKHRoaXM6IEhUTUxTY3JpcHRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0RGVzYy5nZXQhLmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHRoaXM6IEhUTUxTY3JpcHRFbGVtZW50LCB2OiBzdHJpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHREZXNjLnNldCEuY2FsbCh0aGlzLCB0eXBlb2YgdiA9PT0gJ3N0cmluZycgPyB0b0Ficyh2KSA6IHYpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICAgIC8qIGlnbm9yZSAqL1xuICAgICAgICB9XG4gICAgfSxcbiAgICAvKiog5YWo6YeP6L2s5Y+RIGNvbnNvbGUg6L6T5Ye677yIbG9nL2luZm8vd2Fybi9lcnJvci9kZWJ1Z++8ieWIsOmdouadv+aXpeW/l+agj+OAglxuICAgICAqICDlv4XpobvlnKjliqDovb3lvJXmk47ohJrmnKzliY3lronoo4XvvJpwcmV2aWV3LWFwcCDnmoQgYm9vdHN0cmFwIOaYryBmaXJlLWFuZC1mb3JnZXQg55qEXG4gICAgICogIGFzeW5jIOWHveaVsO+8jOWGhemDqOavj+S4gOatpe+8iFVpIOaehOmAoC9TeXN0ZW0uaW1wb3J0KFwiY2NcIikvZ2FtZS5pbml0L2dhbWUucnVuL29uU3RhcnTvvIlcbiAgICAgKiAg5oqb6ZSZ6YO96KKr5YaF5bGCIGNhdGNoIOeUqCBjb25zb2xlLmVycm9yIOWQnuaOie+8jOiAjCBvblN0YXJ0IOeahOWcuuaZr+WKoOi9veWPiOWcqFxuICAgICAqICBib290Rm4g6L+U5Zue5ZCO5omN6LeR4oCU4oCU6Iul6L2s5Y+R6KOF5b6X5aSq5pma77yM5Zy65pmv5Yqg6L295aSx6LSl55qE55yf5a6e5Y6f5Zug5a6M5YWo5LiN5Y+v6KeB44CCXG4gICAgICogIOW8leaTjuWGhemDqOaKpemUmeWQjOagt+i1sCBjb25zb2xlLmVycm9y77yI5LiN6Kem5Y+RIHdpbmRvdy5vbmVycm9y77yJ44CCXG4gICAgICogIOavj+asoea4suafk+WfuuS6jiB3aW5kb3cg5L+d5a2Y55qE44CM5Y6f5aeL5pa55rOV5byV55So44CN6YeN5paw5YyF6KOF77yM6YC76L6R5pyA5paw5LiU5LiN5bGC5bGC5bWM5aWX77ybXG4gICAgICogIOebuOWQjOa2iOaBryAxMCDnp5LlhoXlkIjlubborqHmlbDvvIjlpoIgXCJmb28gKHgzKVwi77yJ6Ziy5q+P5bin5Yi35bGP44CCICovXG4gICAgaG9va0NvbnNvbGVGb3J3YXJkKHRoaXM6IGFueSkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgY29uc3QgdyA9IHdpbmRvdyBhcyBhbnk7XG4gICAgICAgIGlmICghdy5fX3l5a2FSYXdDb25zb2xlKSB7XG4gICAgICAgICAgICBjb25zdCBvOiBSZWNvcmQ8c3RyaW5nLCAoLi4uYTogYW55W10pID0+IHZvaWQ+ID0ge307XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG0gb2YgWydsb2cnLCAnaW5mbycsICd3YXJuJywgJ2Vycm9yJywgJ2RlYnVnJ10pIHtcbiAgICAgICAgICAgICAgICBvW21dID0gKGNvbnNvbGUgYXMgYW55KVttXS5iaW5kKGNvbnNvbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdy5fX3l5a2FSYXdDb25zb2xlID0gbztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByYXcgPSB3Ll9feXlrYVJhd0NvbnNvbGUgYXMgUmVjb3JkPHN0cmluZywgKC4uLmE6IGFueVtdKSA9PiB2b2lkPjtcbiAgICAgICAgZm9yIChjb25zdCBtIG9mIFsnbG9nJywgJ2luZm8nLCAnd2FybicsICdlcnJvcicsICdkZWJ1ZyddKSB7XG4gICAgICAgICAgICAoY29uc29sZSBhcyBhbnkpW21dID0gKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGV4dCA9IGFyZ3NcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgoYSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGEgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhLnN0YWNrIHx8IGEubWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcyA9IEpTT04uc3RyaW5naWZ5KGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzID09PSB1bmRlZmluZWQgPyBTdHJpbmcoYSkgOiBzO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmcoYSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5qb2luKCcgJyk7XG4gICAgICAgICAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSBgJHttfXwke3RleHR9YDtcbiAgICAgICAgICAgICAgICBjb25zdCBsYXN0ID0gc2VsZi5fY29uc29sZURlZHVwICYmIHNlbGYuX2NvbnNvbGVEZWR1cC5nZXQoa2V5KTtcbiAgICAgICAgICAgICAgICBpZiAobGFzdCAmJiBub3cgLSBsYXN0LnQgPCAxMDAwMCkge1xuICAgICAgICAgICAgICAgICAgICBsYXN0Lm4rKztcbiAgICAgICAgICAgICAgICAgICAgbGFzdC50ID0gbm93O1xuICAgICAgICAgICAgICAgICAgICAvLyDlt7LlkIjlubbnmoTmtojmga/lj6rmm7TmlrDorqHmlbDvvIjmlbDnu4TlsL7lhYPntKDvvInvvIzkuI3lho3mlrDlop7mnaHnm65cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXJyID0gc2VsZi5sb2dzO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gYXJyLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpdCA9IGFycltpXSBhcyBhbnk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXQgJiYgaXQuZXZ0ID09PSAnY29uc29sZScgJiYgaXQua2V5ID09PSBrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdC50ZXh0ID0gaXQuYmFzZSArIGAgKHgke2xhc3Qubn0pYDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdC50ID0gbm93O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzZWxmLl9jb25zb2xlRGVkdXAgfHwgc2VsZi5fY29uc29sZURlZHVwLnNpemUgPiAzMDAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDph43muLLmn5Mv6ZW/5pe26Ze06L+Q6KGM5ZCO5riF55CG5Y676YeN54q25oCB77yM6Ziy5q2iIE1hcCDml6DpmZDlop7plb9cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnNvbGVEZWR1cCA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb25zb2xlRGVkdXAuc2V0KGtleSwgeyBuOiAxLCB0OiBub3cgfSk7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYubG9ncy5wdXNoKHsgZXZ0OiAnY29uc29sZScsIGxldmVsOiBtLCBrZXksIGJhc2U6IHRleHQsIHRleHQsIHQ6IG5vdyB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8g5LiK6ZmQ5L+d5oqk77ya5pel5b+X5qCP5riy5p+T5oCn6IO9XG4gICAgICAgICAgICAgICAgd2hpbGUgKHNlbGYubG9ncy5sZW5ndGggPiAzMDAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYubG9ncy5zaGlmdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBvcmlnID0gcmF3W21dO1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnISguLi5hcmdzKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8qKiDliqDovb3ljZXkuKrlpJbpg6johJrmnKzvvIzov5Tlm54gUHJvbWlzZe+8iG9ubG9hZCAvIG9uZXJyb3IgLyDotoXml7blhZzlupXvvInjgIIgKi9cbiAgICBsb2FkU2NyaXB0KHRoaXM6IGFueSwgc3JjOiBzdHJpbmcsIGF0dHJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge30pOiBQcm9taXNlPEhUTUxTY3JpcHRFbGVtZW50PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICAgICAgICBzLnNyYyA9IHNyYztcbiAgICAgICAgICAgIGZvciAoY29uc3QgayBpbiBhdHRycykge1xuICAgICAgICAgICAgICAgIHMuc2V0QXR0cmlidXRlKGssIGF0dHJzW2tdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcign6ISa5pys5Yqg6L296LaF5pe2OiAnICsgc3JjKSksIDIwMDAwKTtcbiAgICAgICAgICAgIHMub25sb2FkID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUocyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcy5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ+iEmuacrOWKoOi9veWksei0pTogJyArIHNyYykpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQocyk7XG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgLyoqIOS7peWOn+eUnyA8c2NyaXB0IHR5cGU9XCJzeXN0ZW1qcy1pbXBvcnRtYXBcIiBzcmM9Li4uPiDliqDovb0gaW1wb3J0LW1hcO+8iOS4jiBkb2NzL3ZpZXcuaHRtbCDkuIDoh7TvvInjgIJcbiAgICAgKiDnlLEgU3lzdGVtSlMg6Ieq5bexIGZldGNoIOW5tuaMieOAjG1hcCDoh6rouqsgVVJM44CN6Kej5p6Q55u45a+555uu5qCH5LiO6ZO+5byP6KO46K+05piO56ym77yMXG4gICAgICog5LuO6ICM5L+d5oyB5byV5pOOIGJ1bmRsZSDlhoUgcS1idW5kbGVkOi8vLyDlkb3lkI3mqKHlnZfnmoTnm7jlr7kgaW1wb3J0IOS4iuS4i+aWh+ato+ehruOAglxuICAgICAqXG4gICAgICog5pep5pyf5a6e546w5pS55Li644CM6Z2i5p2/IGZldGNoICsg6YeN5YaZICsg5YaF6IGU5rOo5YWlIEpTT07jgI3vvJrmiYvliqjmioogLi/jgIEv6LW35aeL6Lev5b6E57ud5a+55YyW77yMXG4gICAgICog56C05Z2P5LqGIFN5c3RlbUpTIOWvuSBidW5kbGUg5YaF54mp55CGL+e9keagvCBsb2FkZXIg55u45a+5IGltcG9ydFxuICAgICAqICguLi8uLi8uLi8uLi92aXJ0dWFsL2V4dGVybmFsJTI1M0EuLi53YXNtLndhc20uanMpIOeahOino+aekOKAlOKAlOiiq+mUgeaIkOe9kee7nFxuICAgICAqIC92aXJ0dWFsLy4uLiAoNDA0LCBFcnJvciMzKe+8jOS4lCBxLWJ1bmRsZWQ6Ly8vdmlydHVhbC8uLi4g6Jma5ouf5qih5Z2X5rOo5YaM5LiK5LiL5paH5Lii5aSxXG4gICAgICogKGhhc+KGkmZhbHNlKeOAguWOn+eUnyBzcmMg5Yqg6L295a6M5YWo5aSN5Yi7IHZpZXcuaHRtbCDnmoTlt6XkvZzpk77ot6/jgIJcbiAgICAgKi9cbiAgICBhc3luYyBhcHBseUltcG9ydE1hcCh0aGlzOiBhbnksIHNyYzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHVybCA9IHRoaXMuYWJzKHNyYyk7XG4gICAgICAgIGNvbnN0IGluaiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICBpbmoudHlwZSA9ICdzeXN0ZW1qcy1pbXBvcnRtYXAnO1xuICAgICAgICBpbmouc3JjID0gdXJsO1xuICAgICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGluaik7XG4gICAgICAgIHRoaXMubG9ncy5wdXNoKHsgZXZ0OiAnc3lzJywgbXNnOiBgW+mihOiniF0gJHtzcmN9IGltcG9ydC1tYXAg5Lul5Y6f55SfIHNyYyDms6jlhaUgKOeUsSBTeXN0ZW1KUyDliqDovb0pYCB9KTtcbiAgICB9LFxuICAgIC8qKiDpnaLmnb/lhoXnm7TmjqXmuLLmn5PmuLjmiI/vvIjml6AgaWZyYW1l77yJ44CC5q+P5LiA5q2l57uT5p6c5YaZ5YWl5pel5b+X5qCP77yM5L6/5LqO5a6a5L2N5aSx6LSl546v6IqC44CCICovXG4gICAgYXN5bmMgcmVuZGVyUHJldmlldyh0aGlzOiBhbnkpIHtcbiAgICAgICAgY29uc3Qgc2VxID0gKHRoaXMuX3JlbmRlclNlcSA9ICh0aGlzLl9yZW5kZXJTZXEgfHwgMCkgKyAxKTsgLy8g5paw5riy5p+T5Y+W5Luj5pen5riy5p+T77yM5pen55qE56uL5Y2z5YGc5q2iXG4gICAgICAgIHRoaXMuc3RvcEhvc3RTeW5jKCk7IC8vIOa4heeQhuS4iuS4gOasoea4suafk+eahOWumuacn+Wuv+S4u+WQjOatpVxuICAgICAgICAvLyDliLfmlrDml7blhYjmi4bop6Pml6fmuLjmiI/lrp7kvovvvIzpgb/lhY3pn7PkuZAv6K6h5pe25ZmoL+S4u+W+queOr+aui+eVmeWPoOWKoFxuICAgICAgICB0aGlzLnRlYXJkb3duUHJldmlldygpO1xuICAgICAgICBjb25zdCB1cmwgPSAodGhpcy5wcmV2aWV3VXJsIHx8ICcnKS50cmltKCk7XG4gICAgICAgIGlmICghdXJsKSB7XG4gICAgICAgICAgICB0aGlzLnByZXZpZXdSZW5kZXJFcnIgPSAn5pyq6YWN572u6aKE6KeI5Zyw5Z2AJztcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBsb2cgPSAobXNnOiBzdHJpbmcpID0+IHRoaXMubG9ncy5wdXNoKHsgZXZ0OiAnc3lzJywgbXNnOiBgW+mihOiniF0gJHttc2d9YCB9KTtcbiAgICAgICAgY29uc3QgYWxpdmUgPSAoKSA9PiB0aGlzLl9yZW5kZXJTZXEgPT09IHNlcTtcbiAgICAgICAgLy8g5a6J6KOF56qX5Y+j57qn6Z+z6aKR6Z2Z6Z+zIGhvb2vvvIjkuovku7bpqbHliqjjgIHluYLnrYnvvInvvIzlnKjlvJXmk47ohJrmnKzliqDovb3liY3kv53or4HpnZnpn7Popobnm5bmiYDmnInmkq3mlL7ot6/lvoRcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuX2hvb2tBdWRpb0N0eCgpO1xuICAgICAgICB9IGNhdGNoIChfKSB7IC8qIGlnbm9yZSAqLyB9XG4gICAgICAgIC8vIOeJiOacrOagh+ivhu+8muaXpeW/l+W8gOWktOebtOaOpeehruiupOmdouadv+WKoOi9veeahOaYr+WTquS4queJiOacrO+8jOmBv+WFjeaXp+S6p+eJqeivr+WIpFxuICAgICAgICBsb2coYOa4suafkyB2JHtwYWNrYWdlSlNPTi52ZXJzaW9ufWApO1xuICAgICAgICAvLyDnjq/looPor4rmlq3vvJrnoa7orqTpnaLmnb8gb3JpZ2lu77yIZmlsZTov6Ieq5a6a5LmJ5Y2P6K6u5Yaz5a6a5byV5pOO5a+5IGNyb3NzT3JpZ2luL2xvY2F0aW9uIOeahOWkhOeQhui3r+W+hO+8iVxuICAgICAgICBsb2coXG4gICAgICAgICAgICBg546v5aKDIGhyZWY9JHt3aW5kb3cubG9jYXRpb24uaHJlZn0gYmFzZT0ke2RvY3VtZW50LmJhc2VVUkl9IHByb3RvPSR7d2luZG93LmxvY2F0aW9uLnByb3RvY29sfSBgICtcbiAgICAgICAgICAgIGB0cmFjZT0keyEhKHdpbmRvdyBhcyBhbnkpLl9feXlrYVRyYWNlSW5zdGFsbGVkfSByYXdJbz0keyEhKHdpbmRvdyBhcyBhbnkpLl9feXlrYVJhd0lvfWBcbiAgICAgICAgKTtcbiAgICAgICAgLy8g5YWo5bGA6ZSZ6K+v5o2V6I6377ya5ou/5Yiw5a6M5pW05aCG5qCI77yM5a6a5L2N5byV5pOO5Yid5aeL5YyW5aSx6LSl55qE55yf5a6e5qih5Z2X44CCXG4gICAgICAgIC8vIOagh+iusOaUviB3aW5kb3cg5LiK6ICM6Z2e5a6e5L6L5a2X5q6177ya5o+S5Lu26YeN6L29L+mdouadv+WkjeeUqOWPr+iDvemBl+eVmeWunuS+iyB0cnVl77yMXG4gICAgICAgIC8vIOWvvOiHtOaWsOeJiOacrOS7o+eggei3s+i/h+Wuieijhe+8iOabvuWPkeeUn++8mnYxLjAuMTU2KyDnmoQgL2VuZ2luZV9leHRlcm5hbC/jgIFzY3JpcHQuc3Jj44CBXG4gICAgICAgIC8vIGNyb3NzT3JpZ2luIOmSqeWtkOS7juacqueUn+aViO+8jOmdouadv+erryB3YXNtIOS7jemdmem7mOaMgui1t++8ieOAglxuICAgICAgICBpZiAoISh3aW5kb3cgYXMgYW55KS5fX3l5a2FFcnJIb29rZWQpIHtcbiAgICAgICAgICAgICh3aW5kb3cgYXMgYW55KS5fX3l5a2FFcnJIb29rZWQgPSB0cnVlO1xuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgKGV2OiBFcnJvckV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbSA9IGV2LmVycm9yID8gZXYuZXJyb3Iuc3RhY2sgfHwgZXYuZXJyb3IubWVzc2FnZSB8fCBTdHJpbmcoZXYuZXJyb3IpIDogZXYubWVzc2FnZTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ3MucHVzaCh7IGV2dDogJ3N5cycsIG1zZzogYFvpooTop4jplJnor69dICR7bX1gIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndW5oYW5kbGVkcmVqZWN0aW9uJywgKGV2OiBQcm9taXNlUmVqZWN0aW9uRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByID0gZXYucmVhc29uO1xuICAgICAgICAgICAgICAgIHRoaXMubG9ncy5wdXNoKHsgZXZ0OiAnc3lzJywgbXNnOiBgW+mihOiniOmUmeivr10gdW5oYW5kbGVkcmVqZWN0aW9uOiAke3IgJiYgci5zdGFjayA/IHIuc3RhY2sgOiBTdHJpbmcocil9YCB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIOavj+asoea4suafk+W8uuWItumHjeijheacgOaWsOeJiOmSqeWtkO+8muWGhemDqOWfuuS6juWFqOWxgOWOn+Wni+W8leeUqOmHjeaWsOWMheijhe+8jOW5guetieS4lOS4jeWxguWxguW1jOWll1xuICAgICAgICB0aGlzLmhvb2tGZXRjaExvZ2dlcigpO1xuICAgICAgICBsb2coJ+e9kee7nCBob29rIOW3suWuieijhSAoZmV0Y2gvWEhSL0ltYWdlL3NjcmlwdCDot6/lvoTph43lhpkgKyDor7fmsYLnu5PmnpzorrDlvZUpJyk7XG4gICAgICAgIC8vIGNvbnNvbGUg5YWo6YeP6L2s5Y+R5ZCM5qC35o+Q5YmN5a6J6KOF77yacHJldmlldy1hcHAgYm9vdHN0cmFwIOWGhemDqOmUmeivr+i1sCBjb25zb2xlLmVycm9yIOiiq+WQnu+8jFxuICAgICAgICAvLyDkuJTlnLrmma/liqDovb0ob25TdGFydCnlnKggYm9vdEZuIOi/lOWbnuWQjuaJjei3ke+8jOi9rOWPkeijheaZmuS6huS8mua8j+aOieWksei0peeahOecn+WunuWOn+WboFxuICAgICAgICB0aGlzLmhvb2tDb25zb2xlRm9yd2FyZCgpO1xuICAgICAgICBsb2coJ2NvbnNvbGUg6L2s5Y+R5bey5a6J6KOFICjlvJXmk44vcHJldmlldy1hcHAg6L6T5Ye65YWo6YeP5Y+v6KeBKScpO1xuICAgICAgICAvLyDms6jlhaUgPGJhc2UgaHJlZj7vvJpTeXN0ZW1KUyDnmoQgYmFzZVVybCDor7vlj5YgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYmFzZVtocmVmXScp77yMXG4gICAgICAgIC8vIGV4dGVybmFsOmVtc2NyaXB0ZW4vLi4uIOiZmuaLnyB3YXNtIOaooeWdl+aMiSBiYXNlIOino+aekO+8jOmdouadvyBiYXNlIOaYryBmaWxlOi8vIOWvvOiHtFxuICAgICAgICAvLyDop6PmnpDliLDkuI3lrZjlnKjnmoTmnKzlnLDot6/lvoTogIzliqDovb3lpLHotKXvvIhidC5EYnZ0QnJvYWRwaGFzZV9uZXcgaXMgbm90IGEgZnVuY3Rpb24g5qC55Zug77yJ77yMXG4gICAgICAgIC8vIOaUueWIsOmihOiniOacjeWKoSBvcmlnaW4g5ZCO5ZG95Lit5YW2IHZpcnR1YWwgaGFuZGxlclxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IGJhc2VFbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Jhc2VbaHJlZl0nKSBhcyBIVE1MQmFzZUVsZW1lbnQgfCBudWxsO1xuICAgICAgICAgICAgaWYgKCFiYXNlRWwpIHtcbiAgICAgICAgICAgICAgICBiYXNlRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdiYXNlJyk7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChiYXNlRWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYmFzZUVsLmhyZWYgPSAodGhpcy5wcmV2aWV3VXJsIHx8ICdodHRwOi8vbG9jYWxob3N0Ojc0NTYvJykudHJpbSgpLnJlcGxhY2UoL1xcLyskLywgJycpICsgJy8nO1xuICAgICAgICAgICAgbG9nKGA8YmFzZSBocmVmPiDlt7Lms6jlhaUgKCR7YmFzZUVsLmhyZWZ9KWApO1xuICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgICAvKiBpZ25vcmUgKi9cbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5jaGVja1ByZXZpZXcoKTsgLy8g5b+r6YCf5o6i5rWL5Zyo57q/54q25oCB77yI5YaF6YOo6IqC5rWB77yJXG4gICAgICAgICAgICB0aGlzLnByZXZpZXdSZW5kZXJFcnIgPSAnJztcbiAgICAgICAgICAgIHRoaXMucHJldmlld0xvYWRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgbG9nKCflvIDlp4vliqDovb3lvJXmk47ohJrmnKzigKYnKTtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5sb2FkU2NyaXB0KHRoaXMuYWJzKCcvc2NyaXB0aW5nL3BvbHlmaWxscy9idW5kbGUuanMnKSk7XG4gICAgICAgICAgICBpZiAoIWFsaXZlKCkpIHJldHVybjtcbiAgICAgICAgICAgIGxvZygncG9seWZpbGxzIOKckycpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5hcHBseUltcG9ydE1hcCgnL3NjcmlwdGluZy9lbmdpbmUvYmluLy5jYWNoZS9kZXYvcHJldmlldy9pbXBvcnQtbWFwLmpzb24nKTtcbiAgICAgICAgICAgIGlmICghYWxpdmUoKSkgcmV0dXJuO1xuICAgICAgICAgICAgbG9nKCflvJXmk44gaW1wb3J0LW1hcCDinJMnKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuYXBwbHlJbXBvcnRNYXAoJy9zY3JpcHRpbmcveC9pbXBvcnQtbWFwLmpzb24nKTtcbiAgICAgICAgICAgIGlmICghYWxpdmUoKSkgcmV0dXJuO1xuICAgICAgICAgICAgbG9nKCfpobnnm64gaW1wb3J0LW1hcCDinJMnKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuYXBwbHlJbXBvcnRNYXAoJy9zY3JpcHRpbmcvaW1wb3J0LW1hcC1nbG9iYWwnKTtcbiAgICAgICAgICAgIGlmICghYWxpdmUoKSkgcmV0dXJuO1xuICAgICAgICAgICAgbG9nKCdjYyBpbXBvcnQtbWFwIOKckycpO1xuICAgICAgICAgICAgLy8g6KGl5YWF5pig5bCE77yIc29ja2V0LmlvIOetiSBwcmV2aWV3LWFwcCDnoaznvJbnoIHot6/lvoTvvInvvIzpobvlnKggc3lzdGVtLmpzIOS5i+WJjeazqOWFpVxuICAgICAgICAgICAgdGhpcy5pbmplY3RFeHRyYUltcG9ydE1hcCgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5sb2FkU2NyaXB0KHRoaXMuYWJzKCcvc2NyaXB0aW5nL3N5c3RlbWpzL3N5c3RlbS5qcycpKTtcbiAgICAgICAgICAgIGlmICghYWxpdmUoKSkgcmV0dXJuO1xuICAgICAgICAgICAgbG9nKCdzeXN0ZW1qcyDinJMnKTtcbiAgICAgICAgICAgIC8vIHNvY2tldC5pbyBzdHVi77yacHJldmlldy1hcHAgYm9vdHN0cmFwIOS8miBpbXBvcnQoJy9zb2NrZXQuaW8vc29ja2V0LmlvLmpzJykg5bm26LCD55SoIG4uZGVmYXVsdCgp44CCXG4gICAgICAgICAgICAvLyDpnaLmnb/lhoXot6jln58gKyDph43lpI3muLLmn5Pml7YgU3lzdGVtSlMg55qE5YWo5bGA5o6i5rWL5LiN5Y+v6Z2g77yIaW8g5YWo5bGA5bey5a2Y5Zyo5YiZ5o6i5rWL5LiN5Yiw5paw5YWo5bGA77yMZGVmYXVsdCDnvLrlpLHvvInvvIxcbiAgICAgICAgICAgIC8vIOebtOaOpeWcqOivpei3r+W+hOazqOWGjCBzdHViIOaooeWdl++8jOS/neivgSBuLmRlZmF1bHQoKSDlv4Xlrprlj6/nlKjkuJTkuI3lj5HotbfnnJ/lrp4gc29ja2V0LmlvIOi/nuaOpeOAglxuICAgICAgICAgICAgdGhpcy5yZWdpc3RlclNvY2tldElvU3R1YigpO1xuICAgICAgICAgICAgaWYgKCFhbGl2ZSgpKSByZXR1cm47XG5cbiAgICAgICAgICAgIC8vIOazqOaEj++8muS4jeiuviBTeXN0ZW0uY29uZmlnKHtiYXNlVVJMfSnjgIHkuI3ljIXoo4UgU3lzdGVtLmltcG9ydOOAglxuICAgICAgICAgICAgLy8g6L+Z5Lik5qC35pivIHZpZXcuaHRtbCDmiYDmsqHmnInnmoTpop3lpJbnvJbmjpLvvIzkvJrlubLmibAgZW5naW5lIGJ1bmRsZSDlhoVcbiAgICAgICAgICAgIC8vIHEtYnVuZGxlZDovLy8g5ZG95ZCN5qih5Z2X55qE55u45a+5IGltcG9ydCDop6PmnpDvvIguLi8uLi8uLi8uLi92aXJ0dWFsLy4uLiDooqvmi4notbdcbiAgICAgICAgICAgIC8vIOaIkOe9kee7nCAvdmlydHVhbC8gNDA044CBaGFz4oaSZmFsc2XvvInjgILlrozlhajlpI3liLsgdmlldy5odG1s77ya5Y+q6Z2gIDxiYXNlIGhyZWY+44CCXG4gICAgICAgICAgICAvLyDliIbovqjnjofnu4boioLmmKDlsITvvIjot6jln58gZmV0Y2jvvIzlpLHotKXkvJrlj43mmKDliLDlkK/liqjplJnor6/vvIlcbiAgICAgICAgICAgIGNvbnN0IFN5cyA9ICh3aW5kb3cgYXMgYW55KS5TeXN0ZW07XG4gICAgICAgICAgICBpZiAoU3lzICYmIHR5cGVvZiBTeXMuc2V0UmVzb2x1dGlvbkRldGFpbE1hcENhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgU3lzLnNldFJlc29sdXRpb25EZXRhaWxNYXBDYWxsYmFjaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHUgPSB0aGlzLmFicygnL3NjcmlwdGluZy94L3Jlc29sdXRpb24tZGV0YWlsLW1hcC5qc29uJyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaCh1KS50aGVuKChyKSA9PiByLmpzb24oKSkudGhlbigoanNvbikgPT4gKHsganNvbiwgdXJsOiB1IH0pKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIOWIhui+qOeOh+e7huiKguaYoOWwhOW3suWcqOS4iuaWuSBzZXRSZXNvbHV0aW9uRGV0YWlsTWFwQ2FsbGJhY2sg6K6+572u44CCXG4gICAgICAgICAgICAvLyDms6jmhI/vvJp2aWV3Lmh0bWwg5LiN5YyF6KOFIFN5c3RlbS5pbXBvcnTvvJvov5nph4zkuZ/kuI3lgZrvvIzkv53mjIHkuI4gdmlldy5odG1sIOS4gOiHtOeahOWKoOi9vemTvui3r+OAglxuICAgICAgICAgICAgLy8g5byV5pOOIGJ1bmRsZSDliqDovb3liY3nva7lpb3njq/looPvvIhDQ19FRElUT1I9ZmFsc2UgKyBFZGl0b3JFeHRlbmRzIOahqe+8ie+8jFxuICAgICAgICAgICAgLy8g5ZCm5YiZ57yW6L6R5ZmoIEVsZWN0cm9uIOeql+WPo+WGhSBFRElUT1Ig6K+v5Yik5Li6IHRydWUg5Lya6Kem5Y+RIEVkaXRvckV4dGVuZHMg5bSp5rqDXG4gICAgICAgICAgICB0aGlzLnBhdGNoUHJldmlld0VudigpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5sb2FkU2NyaXB0KHRoaXMuYWJzKCcvc2NyaXB0aW5nL2VuZ2luZS9iaW4vLmNhY2hlL2Rldi9wcmV2aWV3L2J1bmRsZWQvaW5kZXguanMnKSk7XG4gICAgICAgICAgICBpZiAoIWFsaXZlKCkpIHJldHVybjtcbiAgICAgICAgICAgIGxvZygn5byV5pOOIGJ1bmRsZSDinJMnKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMubG9hZFNjcmlwdCh0aGlzLmFicygnL3NldHRpbmdzLmpzP3NjZW5lPWN1cnJlbnRfc2NlbmUnKSk7XG4gICAgICAgICAgICBpZiAoIWFsaXZlKCkpIHJldHVybjtcbiAgICAgICAgICAgIGxvZygnc2V0dGluZ3Mg4pyTJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNldHRpbmdzID0gKHdpbmRvdyBhcyBhbnkpLl9DQ1NldHRpbmdzO1xuICAgICAgICAgICAgLy8g5by65Yi2IFN1YkZyYW1lIOWwuuWvuOaooeW8j++8mlNjcmVlbkFkYXB0ZXIg55qEIF93aW5kb3dUeXBlIOWcqCBleGFjdEZpdFNjcmVlbj10cnVlXG4gICAgICAgICAgICAvLyDml7botbAgQnJvd3NlcldpbmRvdyDliIbmlK/vvIznlKggd2luZG93LmlubmVyV2lkdGgvSGVpZ2h077yI57yW6L6R5Zmo56qX5Y+j5bC65a+477yM6Z2e6aKE6KeI5Yy65Z+f77yJXG4gICAgICAgICAgICAvLyDorr7nva4gI0dhbWVEaXYg5LiO55S75biDIGJ1ZmZlcu+8jOWvvOiHtOW4g+WxgOmUmeS9jSArIOm7keWxj+OAglxuICAgICAgICAgICAgLy8gZXhhY3RGaXRTY3JlZW49ZmFsc2Ug4oaSIFN1YkZyYW1lIOKGkiDlsLrlr7jmjIkgI0dhbWVEaXYg5a6e6ZmF5bC65a+4KGNsaWVudFdpZHRoL0hlaWdodCnorqHnrpfjgIJcbiAgICAgICAgICAgIC8vIOmhtuWxguWtl+autei1sCBfY29tcGF0aWJsZVdpdGhPbGRQYXJhbXMg6L2sIG92ZXJyaWRlU2V0dGluZ3PvvIxzY3JlZW4g5a2X5q616LWwIHNldHRpbmdzLmpzb27jgIJcbiAgICAgICAgICAgIGlmIChzZXR0aW5ncyAmJiB0eXBlb2Ygc2V0dGluZ3MgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgc2V0dGluZ3MuZXhhY3RGaXRTY3JlZW4gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBzZXR0aW5ncy5zY3JlZW4gPSBzZXR0aW5ncy5zY3JlZW4gfHwge307XG4gICAgICAgICAgICAgICAgc2V0dGluZ3Muc2NyZWVuLmV4YWN0Rml0U2NyZWVuID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgbG9nKCdleGFjdEZpdFNjcmVlbj1mYWxzZSAoU3ViRnJhbWUg5bC65a+45qih5byPKScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8g5byV5pOO6ISa5pys5YWo6YOo5bCx57uq5ZCO77yMVnVlIOa4suafk+W/heeEtuW3suWujOaIkO+8muatpOWIu+ehruS/nea4uOaIjyBET00g5bCx5L2N77yMXG4gICAgICAgICAgICAvLyDkv53or4EgVWkg5p6E6YCg55qEIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNHYW1lQ2FudmFzJykg5b+F5a6a5ZG95LitXG4gICAgICAgICAgICB0aGlzLmJ1aWxkR2FtZURvbSgpO1xuICAgICAgICAgICAgaWYgKCFhbGl2ZSgpKSByZXR1cm47XG4gICAgICAgICAgICAvLyDov5DooYzmnJ/ot5/ouKrvvJrljIXoo4UgZ2FtZS5ydW4vbG9hZFdpdGhKc29uL3J1blNjZW5lSW1tZWRpYXRlIOW5tui9rOWPkSBjb25zb2xlIOmUmeivr++8jFxuICAgICAgICAgICAgLy8g57K+56Gu5a6a5L2N5Zy65pmv5Yqg6L295Y2h54K577yI5b+F6aG75ZyoIHByZXZpZXctYXBwIOiwg+eUqOS5i+WJjeWuieijhe+8iVxuICAgICAgICAgICAgdGhpcy5pbnN0YWxsUHJldmlld1RyYWNlKCk7XG4gICAgICAgICAgICBpZiAoIWFsaXZlKCkpIHJldHVybjtcbiAgICAgICAgICAgIGxvZygn5ZCv5Yqo6aKE6KeI5bqU55So4oCmJyk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1vZCA9IGF3YWl0ICh3aW5kb3cgYXMgYW55KS5TeXN0ZW0uaW1wb3J0KHRoaXMuYWJzKCcvcHJldmlldy1hcHAvaW5kZXguanMnKSArICc/X190PScgKyBzZXEpO1xuICAgICAgICAgICAgICAgIC8vIOWFvOWuuSB7IGJvb3RzdHJhcCB9IOS4jiB7IGRlZmF1bHQ6IHsgYm9vdHN0cmFwIH0gfSDkuKTnp43lr7zlh7rnu5PmnoRcbiAgICAgICAgICAgICAgICBjb25zdCBib290Rm4gPVxuICAgICAgICAgICAgICAgICAgICAobW9kICYmIHR5cGVvZiBtb2QuYm9vdHN0cmFwID09PSAnZnVuY3Rpb24nICYmIG1vZC5ib290c3RyYXApIHx8XG4gICAgICAgICAgICAgICAgICAgIChtb2QgJiYgbW9kLmRlZmF1bHQgJiYgdHlwZW9mIG1vZC5kZWZhdWx0LmJvb3RzdHJhcCA9PT0gJ2Z1bmN0aW9uJyAmJiBtb2QuZGVmYXVsdC5ib290c3RyYXApO1xuICAgICAgICAgICAgICAgIGlmICghYm9vdEZuKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigncHJldmlldy1hcHAg5pyq5a+85Ye6IGJvb3RzdHJhcCDlh73mlbDvvIzmqKHlnZfnu5PmnoQ6ICcgKyBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyhtb2QgfHwge30pKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghYWxpdmUoKSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIC8vIOWPjOS/nemZqe+8muaXoOiuuiBwcmV2aWV3LWFwcCDku6XkvZXnp43mlrnlvI/kvKAgY29uZmlnIOe7mSBnYW1lLmluaXTvvIxcbiAgICAgICAgICAgICAgICAvLyDpg73noa7kv50gU2NyZWVuQWRhcHRlciDotbAgU3ViRnJhbWUg5bC65a+45qih5byP44CCXG4gICAgICAgICAgICAgICAgLy8gcXVlcnlTZXR0aW5ncyDkvJjlhYjor7sgc2V0dGluZ3MuX292ZXJyaWRl77yM5YaN6K+7IHNldHRpbmdzLmpzb27vvJtcbiAgICAgICAgICAgICAgICAvLyBzZXR0aW5ncy5pbml0IOWPquS8mumAkOmhuSBzZXQgb3ZlcnJpZGVTZXR0aW5nc++8jOS4jeS8muaVtOS9k+imhuebluW3suaciemUruOAglxuICAgICAgICAgICAgICAgIGNvbnN0IGxlZ2FjeSA9ICh3aW5kb3cgYXMgYW55KS5jYyB8fCAod2luZG93IGFzIGFueSkuY2NsZWdhY3k7XG4gICAgICAgICAgICAgICAgaWYgKGxlZ2FjeSAmJiBsZWdhY3kuc2V0dGluZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgbGVnYWN5LnNldHRpbmdzLl9vdmVycmlkZSA9IGxlZ2FjeS5zZXR0aW5ncy5fb3ZlcnJpZGUgfHwge307XG4gICAgICAgICAgICAgICAgICAgIGxlZ2FjeS5zZXR0aW5ncy5fb3ZlcnJpZGUuc2NyZWVuID0gbGVnYWN5LnNldHRpbmdzLl9vdmVycmlkZS5zY3JlZW4gfHwge307XG4gICAgICAgICAgICAgICAgICAgIGxlZ2FjeS5zZXR0aW5ncy5fb3ZlcnJpZGUuc2NyZWVuLmV4YWN0Rml0U2NyZWVuID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIGRldmljZXMg5Li6IFVpIOaOp+S7tuadoeW8uuS+nei1lu+8iOiuvuWkh+WIl+ihqO+8ie+8jOe8uuS6hiBVaSDmnoTpgKDkvJrnm7TmjqXltKnmuoPvvIjorr7lpIfooajlv4XpobtcbiAgICAgICAgICAgICAgICAvLyDljIXlkKvlt6XlhbfmoI8gbGkg6YeM5Ye6546w55qE5YWo6YOoIGRhdGEtZGV2aWNl77yb5ryP6K6+5aSH5oqbIHVuZGVmaW5lZC5uYW1l77yJ44CCXG4gICAgICAgICAgICAgICAgY29uc3QgX3BkID0gdGhpcy5wcmVmRGVzaWduKCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgYm9vdEZuKHtcbiAgICAgICAgICAgICAgICAgICAgZW5naW5lQmFzZVVybDogdGhpcy5hYnMoJy9zY3JpcHRpbmcvZW5naW5lJyksXG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmdzLFxuICAgICAgICAgICAgICAgICAgICBkZXZpY2VzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAnRGVmYXVsdCc6IHsgbmFtZTogYOiuvuiuoeWIhui+qOeOhyAoJHtfcGQud33DlyR7X3BkLmh9KWAsIHdpZHRoOiBfcGQudywgaGVpZ2h0OiBfcGQuaCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgJ0Z1bGxTY3JlZW4nOiB7IG5hbWU6ICflhajlsY8nLCB3aWR0aDogX3BkLncsIGhlaWdodDogX3BkLmggfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICdXZWJwYWdlRnVsbFNjcmVlbic6IHsgbmFtZTogJ+e9kemhteWFqOWxjycsIHdpZHRoOiBfcGQudywgaGVpZ2h0OiBfcGQuaCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgLi4uT2JqZWN0LmVudHJpZXMoREVWSUNFX1NJWkVTIGFzIFJlY29yZDxzdHJpbmcsIHsgdzogbnVtYmVyOyBoOiBudW1iZXI7IGxhYmVsOiBzdHJpbmcgfT4pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZpbHRlcigoW2tdKSA9PiAhWydEZWZhdWx0JywgJ0Z1bGxTY3JlZW4nLCAnV2VicGFnZUZ1bGxTY3JlZW4nXS5pbmNsdWRlcyhrKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVkdWNlKChhY2MsIFtrLCB2XSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nba10gPSB7IG5hbWU6IHYubGFiZWwsIHdpZHRoOiB2LncsIGhlaWdodDogdi5oIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwge30gYXMgUmVjb3JkPHN0cmluZywgeyBuYW1lOiBzdHJpbmc7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0+KSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLnByZXZpZXdMb2FkZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMucHJldmlld1pvb20gPSAxOyAvLyDmlrDkuIDmrKHmuLLmn5Pku44gMTAwJSDnvKnmlL7lvIDlp4tcbiAgICAgICAgICAgICAgICB0aGlzLnN5bmNQcmV2aWV3U3RhdGUoKTsgLy8g5ZCM5q2l5bel5YW35p2h5r+A5rS75oCBXG4gICAgICAgICAgICAgICAgbG9nKCfmuLjmiI/lt7LlkK/liqgg4pyTJyk7XG4gICAgICAgICAgICAgICAgLy8g5YWI5a6a5L2N5bm25pi+56S65ri45oiP5a6/5Li777yIZGlzcGxheTpub25lIOKGkiBmbGV477yJ77yM6K6pICNHYW1lRGl2IOaLpeacieecn+WunuWwuuWvuO+8m1xuICAgICAgICAgICAgICAgIC8vIOW/hemhu+WcqCBzY3JlZW5BZGFwdGVyIOazqOWFpeeahCByZXNpemUg5LmL5YmN5a6M5oiQ77yM5ZCm5YiZIHJlc2l6ZSDml7blrrnlmajlsLrlr7jkuLogMO+8jFxuICAgICAgICAgICAgICAgIC8vIOeUu+W4gyBidWZmZXIg5Lya5oyJIDAg5bC65a+46K6h566X77yI6KGo546w5Li6IGJ1ZiDov5zlsI/kuo7lrp7pmYXljLrln5/vvInjgIJcbiAgICAgICAgICAgICAgICB0aGlzLnN5bmNHYW1lSG9zdCgpO1xuICAgICAgICAgICAgICAgIC8vIOm7mOiupOaMieW9k+WJjeiuvuWkhy/orr7orqHliIbovqjnjofnrYnmr5TlsYXkuK3mmL7npLrvvIjpgb/lhY3nlLvpnaLooqvmi4nkvLjmiJDmlrnlvaLvvInjgIJcbiAgICAgICAgICAgICAgICAvLyDpnIDlnKjlrr/kuLvlt7LlrprkvY3jgIFFbmdpbmUgcmVzaXplIOWFnOW6leS5i+WJjeW6lOeUqO+8jCNHYW1lRGl2IOaJjeaLv+WIsOecn+WunuWuueWZqOWwuuWvuOOAglxuICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlEZXZpY2VWaWV3cG9ydCh0aGlzLnByZXZpZXdEZXZpY2UgfHwgJ0RlZmF1bHQnKTtcbiAgICAgICAgICAgICAgICAvLyA9PT09PSBleGFjdEZpdFNjcmVlbiDmnIDnu4jlhZzlupXvvJrnm7TmjqXmlLkgU2NyZWVuQWRhcHRlciDlrp7kvovlrZfmrrUgPT09PT1cbiAgICAgICAgICAgICAgICAvLyDkuInlsYIgc2V0dGluZ3Mg6KaG55uW77yIX0NDU2V0dGluZ3MgLyBzY3JlZW4g5a2X5q61IC8gX292ZXJyaWRl77yJ6YO95L6d6LWWIHByZXZpZXctYXBwXG4gICAgICAgICAgICAgICAgLy8g5aaC5L2V5oqKIHNldHRpbmdzIOS8oOe7mSBnYW1lLmluaXQg5LiOIFNldHRpbmdzLmluaXQg55qEIG92ZXJyaWRlIOWQiOW5tuaWueW8j++8jFxuICAgICAgICAgICAgICAgIC8vIOWunua1i+acqueUn+aViO+8iHdpbiDku43mmK/nvJbovpHlmajnqpflj6PlsLrlr7gvZHBy77yJ44CC55u05o6l5pS55a6e5L6L5a2X5q615pyA5Y+v6Z2g77yaXG4gICAgICAgICAgICAgICAgLy8gX3dpbmRvd1R5cGUgPSBfZXhhY3RGaXRTY3JlZW4gPyBCcm93c2VyV2luZG93IDogU3ViRnJhbWXvvIxcbiAgICAgICAgICAgICAgICAvLyDmlLkgZmFsc2Ug5ZCO6Kem5Y+RIHJlc2l6ZSDotbAgU3ViRnJhbWUg5YiG5pSv5oyJICNHYW1lRGl2IOWunumZheWwuuWvuOmHjeeul+eUu+W4g+OAglxuICAgICAgICAgICAgICAgIC8vIFN5c3RlbS5pbXBvcnQg5piv5byC5q2l55qE77yM5Yi35paw6YKj5LiA5Yi75Y+v6IO96L+Y5rKhIHJlc29sdmUg5bCx5byA5aeL5riy5p+TIOKGkiDnlLvluIPku43mmK9cbiAgICAgICAgICAgICAgICAvLyDmtY/op4jlmajnqpflj6PlsLrlr7jvvIjmr5TpooTop4jop4blj6PlpKfvvInjgILov5nph4znlKjph43or5Xlvqrnjq/nrYnliLAgYWRhcHRlciDlsLHnu6rvvIzlubblnKjmr4/mrKFcbiAgICAgICAgICAgICAgICAvLyDmiJDlip/lkI7ph43mlL7op4blj6PvvIznoa7kv50gU3ViRnJhbWXvvIjot5/pmo8gI0dhbWVEaXYg5bC65a+477yJ5Zyo5riy5p+T5YmN5b+F54S255Sf5pWI44CCXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5mb3JjZVN1YkZyYW1lVmlld3BvcnQoYWxpdmUpO1xuICAgICAgICAgICAgICAgIC8vIOWFnOW6leazqOWFpeWPr+iDveaKiiBfZXhhY3RGaXRTY3JlZW4g5by65Yi25oiQIGZhbHNl77yI5L6bIERlZmF1bHQg6ZO65ruh77yJ77yMXG4gICAgICAgICAgICAgICAgLy8g5Lya6KaG55uW5o6J5LiK6Z2iIGFwcGx5RGV2aWNlVmlld3BvcnQg5Li66K6+5aSH5qih5byP6K6+55qEIHRydWXvvIzlr7zoh7TnlLvpnaLkuI3mjInlvZPliY3liIbovqjnjocv57yp5pS+5pi+56S677ybXG4gICAgICAgICAgICAgICAgLy8g6L+Z6YeM5Zyo5rOo5YWl5LmL5ZCO5oyJ5b2T5YmN6K6+5aSH5LiO57yp5pS+6YeN5pS+5LiA5qyh77yM5oGi5aSN5q2j56Gu6KeG5Y+j44CCXG4gICAgICAgICAgICAgICAgdGhpcy5hcHBseURldmljZVZpZXdwb3J0KHRoaXMucHJldmlld0RldmljZSB8fCAnRGVmYXVsdCcpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3luY0dhbWVIb3N0KCk7XG4gICAgICAgICAgICAgICAgLy8g5Zy65pmv5Yqg6L296Lef6Liq77ya6Iul5Zy65pmv5Yqg6L295a6M5oiQL+Wksei0pe+8jOaXpeW/l+agj+WPr+ingVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxlZ2FjeTIgPSAod2luZG93IGFzIGFueSkuY2MgfHwgKHdpbmRvdyBhcyBhbnkpLmNjbGVnYWN5O1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkaXJlY3RvciA9IGxlZ2FjeTIgJiYgbGVnYWN5Mi5kaXJlY3RvcjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRpcmVjdG9yICYmIHR5cGVvZiBkaXJlY3Rvci5vbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXZ0ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGVnYWN5Mi5EaXJlY3RvciAmJiBsZWdhY3kyLkRpcmVjdG9yLkVWRU5UX0FGVEVSX1NDRU5FX0xBVU5DSCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGlyZWN0b3JfYWZ0ZXJfc2NlbmVfbGF1bmNoJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdG9yLm9uKGV2dCwgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhbGl2ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNjID0gZGlyZWN0b3IuZ2V0U2NlbmUgJiYgZGlyZWN0b3IuZ2V0U2NlbmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKGDlnLrmma/lt7LliqDovb06ICR7KHNjICYmIHNjLm5hbWUpIHx8ICc/J31gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8g5Zy65pmv5r+A5rS75ZCO5omN6YeN5bu65pyA57uI55S75biDL+ebuOacuuinhuWPo++8m+atpOaXtumHjeaUvuinhuWPo+W5tuinpuWPkSByZXNpemXvvIxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8g6K6p55u45py65oyJICNHYW1lRGl2IOacgOe7iOWwuuWvuOiuoeeulyB2aWV3cG9ydO+8iOetieaViOS6jueUqOaIt+a7mui9ru+8ie+8jFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyDkv67lpI3liLfmlrDlkI7nm7jmnLrop4bop5Lot5HlgY/jgIJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseURldmljZVZpZXdwb3J0KHRoaXMucHJldmlld0RldmljZSB8fCAnRGVmYXVsdCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN5bmNHYW1lSG9zdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBsb2coJ+WcuuaZr+ebkeWQrOazqOWGjOWksei0pTogJyArIFN0cmluZygoZSBhcyBFcnJvcik/Lm1lc3NhZ2UgfHwgZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyDlnLrmma/liqDovb3nnIvpl6jni5fvvJrml6DlnLrmma/ml7blkajmnJ/mgKfovpPlh7rlvJXmk47nirbmgIHlv6vnhafvvIzlrprkvY3kuLvlvqrnjq8v6LWE5rqQ566h57q/5Y2h54K5XG4gICAgICAgICAgICAgICAgdGhpcy5zdGFydFNjZW5lV2F0Y2hkb2coKTtcbiAgICAgICAgICAgICAgICAvLyDlrprmnJ/lkIzmraXvvJrpnaLmnb/mi5bliqgv56qX5Y+j56e75YqoL+W4g+WxgOWPmOWMluaXtiBSZXNpemVPYnNlcnZlciDlj6/og73mvI/miqVcbiAgICAgICAgICAgICAgICAvLyDvvIjlj6rnm5HlkKzlsLrlr7jkuI3nm5HlkKzkvY3nva7vvInvvIzova7or6LlhZzlupXkv53or4Hlrr/kuLvkuI3jgIzmvILmta7jgI1cbiAgICAgICAgICAgICAgICB0aGlzLl9ob3N0U3luY1RpbWVyID0gd2luZG93LnNldEludGVydmFsKCgpID0+IHRoaXMuc3luY0dhbWVIb3N0KCksIDMwMCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBtc2cgPSBTdHJpbmcoKGVyciBhcyBFcnJvcik/Lm1lc3NhZ2UgfHwgZXJyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnByZXZpZXdMb2FkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLnByZXZpZXdSZW5kZXJFcnIgPSBtc2c7XG4gICAgICAgICAgICAgICAgbG9nKCflkK/liqjlpLHotKUg4pyXICcgKyBtc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnN0IG1zZyA9IFN0cmluZygoZXJyIGFzIEVycm9yKT8ubWVzc2FnZSB8fCBlcnIpO1xuICAgICAgICAgICAgdGhpcy5wcmV2aWV3UmVuZGVyRXJyID0gbXNnO1xuICAgICAgICAgICAgbG9nKCfliqDovb3lpLHotKUg4pyXICcgKyBtc2cpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICAvKiog6L+Q6KGM5pyf6Lef6Liq77yI5b+F6aG75ZyoIHByZXZpZXctYXBwIOiwg+eUqCBnYW1lLnJ1biDkuYvliY3lronoo4XvvInvvJpcbiAgICAgKiAg5YyF6KOFIGdhbWUucnVuL29uU3RhcnTjgIFwYXVzZS9yZXN1bWXjgIFsb2FkV2l0aEpzb27jgIFydW5TY2VuZUltbWVkaWF0Ze+8jFxuICAgICAqICDlubbmioogY29uc29sZS5sb2cvaW5mby93YXJuL2Vycm9yL2RlYnVnIOWFqOmHj+i9rOWPkeWIsOmdouadv+aXpeW/l+OAguWcuuaZr+WKoOi9vem7keWxj+aXtlxuICAgICAqICDlj6/nm7TmjqXku47ml6Xlv5fmoI/lrprkvY3ljaHngrnvvJrkuLvlvqrnjq/mnKrlkK/liqjvvIhvblN0YXJ0IOacquaJp+ihjO+8iS8g5Zy65pmvIEpTT04g6K+35rGCIC9cbiAgICAgKiAg5L6d6LWW5Yqg6L29IC8g5Y+N5bqP5YiX5YyW44CCXG4gICAgICogIOazqOaEj++8muW8leaTjiBidW5kbGUg5pivIFN5c3RlbS5yZWdpc3RlciDmqKHlnZfvvIw8c2NyaXB0PiDliqDovb3lj6rms6jlhozkuI3miafooYzvvIxcbiAgICAgKiAgd2luZG93LmNjIOimgeetiSBTeXN0ZW0uaW1wb3J0KHByZXZpZXctYXBwKSDmiY3lsLHnu6rvvJvlm6DmraTov5nph4zova7or6LnrYnlvoXlronoo4Xnqpflj6PvvIxcbiAgICAgKiAg6YG/5YWN5ryP5o6JIGdhbWUucnVuL2xvYWRXaXRoSnNvbiDnmoTljIXoo4XvvIhwcmV2aWV3LWFwcCDnmoQgZ2FtZS5pbml0IOaYr+W8guatpeeahO+8jFxuICAgICAqICAyNW1zIOi9ruivoui2s+Wkn+i1tuWcqCBnYW1lLnJ1biDkuYvliY3oo4XkuIrvvInjgIIgKi9cbiAgICBpbnN0YWxsUHJldmlld1RyYWNlKHRoaXM6IGFueSkge1xuICAgICAgICBpZiAodGhpcy5fdHJhY2VJbnN0YWxsZWQpIHJldHVybjtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIGNvbnN0IGxvZyA9IChtc2c6IHN0cmluZykgPT4gc2VsZi5sb2dzLnB1c2goeyBldnQ6ICdzeXMnLCBtc2c6IGBb6aKE6KeI6Lef6LiqXSAke21zZ31gIH0pO1xuICAgICAgICBjb25zdCBpbnN0YWxsTm93ID0gKCk6IGJvb2xlYW4gPT4ge1xuICAgICAgICAgICAgY29uc3QgbGVnYWN5ID0gKHdpbmRvdyBhcyBhbnkpLmNjIHx8ICh3aW5kb3cgYXMgYW55KS5jY2xlZ2FjeTtcbiAgICAgICAgICAgIGlmICghbGVnYWN5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2VsZi5fdHJhY2VJbnN0YWxsZWQgPSB0cnVlO1xuICAgICAgICBjb25zdCBnID0gbGVnYWN5LmdhbWU7XG4gICAgICAgIGlmIChnKSB7XG4gICAgICAgICAgICBjb25zdCBvcmlnUnVuID0gZy5ydW4gJiYgZy5ydW4uYmluZChnKTtcbiAgICAgICAgICAgIGlmIChvcmlnUnVuKSB7XG4gICAgICAgICAgICAgICAgZy5ydW4gPSAob25TdGFydD86IEZ1bmN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxvZygnZ2FtZS5ydW4g6KKr6LCD55SoJyk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdyYXBwZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2coJ29uU3RhcnQg5byA5aeL77yI5Zy65pmv5Yqg6L295rWB56iL5ZCv5Yqo77yJJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBvblN0YXJ0ICYmIG9uU3RhcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAociAmJiB0eXBlb2YgKHIgYXMgYW55KS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyIGFzIGFueSkudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgpID0+IGxvZygnb25TdGFydCDlrozmiJAnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlOiBhbnkpID0+IGxvZygnb25TdGFydCDlvILluLg6ICcgKyBTdHJpbmcoKGUgJiYgKGUubWVzc2FnZSB8fCBlKSkgfHwgZSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZygnb25TdGFydCDlkIzmraXlvILluLg6ICcgKyBTdHJpbmcoKGUgYXMgRXJyb3IpPy5tZXNzYWdlIHx8IGUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ1J1bih3cmFwcGVkKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBtIG9mIFsncGF1c2UnLCAncmVzdW1lJywgJ3BhdXNlQnlFbmdpbmUnLCAncmVzdW1lQnlFbmdpbmUnXSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9yaWcgPSBnW21dICYmIGdbbV0uYmluZChnKTtcbiAgICAgICAgICAgICAgICBpZiAoIW9yaWcpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGdbbV0gPSAoLi4uYXJnczogYW55W10pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nKGBnYW1lLiR7bX0oKWApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3JpZyguLi5hcmdzKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFtID0gbGVnYWN5LmFzc2V0TWFuYWdlcjtcbiAgICAgICAgaWYgKGFtICYmIGFtLmxvYWRXaXRoSnNvbikge1xuICAgICAgICAgICAgY29uc3Qgb3JpZyA9IGFtLmxvYWRXaXRoSnNvbi5iaW5kKGFtKTtcbiAgICAgICAgICAgIGFtLmxvYWRXaXRoSnNvbiA9IChqc29uOiBhbnksIG9wdGlvbnM6IGFueSwgb25Qcm9ncmVzcz86IEZ1bmN0aW9uLCBvbkNvbXBsZXRlPzogRnVuY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICBsb2coYGxvYWRXaXRoSnNvbiDlvIDlp4sgaWQ9JHtvcHRpb25zICYmIG9wdGlvbnMuYXNzZXRJZH1gKTtcbiAgICAgICAgICAgICAgICBjb25zdCB3UHJvZ3Jlc3MgPSAoZmluaXNoZWQ6IG51bWJlciwgdG90YWw6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsb2coYGxvYWRXaXRoSnNvbiDov5vluqYgJHtmaW5pc2hlZH0vJHt0b3RhbH1gKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9uUHJvZ3Jlc3MpIG9uUHJvZ3Jlc3MoZmluaXNoZWQsIHRvdGFsKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNvbnN0IHdDb21wbGV0ZSA9IChlcnI6IGFueSwgZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxvZyhcbiAgICAgICAgICAgICAgICAgICAgICAgIGBsb2FkV2l0aEpzb24g5a6M5oiQIGVycj0ke2VyciA/IFN0cmluZygoZXJyIGFzIEVycm9yKT8ubWVzc2FnZSB8fCBlcnIpIDogJ+aXoCd9IGAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYHNjZW5lPSR7ZGF0YSAmJiBkYXRhLnNjZW5lID8gKGRhdGEuc2NlbmUubmFtZSB8fCBkYXRhLnNjZW5lLl9uYW1lKSA6ICc/J31gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvbkNvbXBsZXRlKSBvbkNvbXBsZXRlKGVyciwgZGF0YSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZyhqc29uLCBvcHRpb25zLCB3UHJvZ3Jlc3MsIHdDb21wbGV0ZSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRyID0gbGVnYWN5LmRpcmVjdG9yO1xuICAgICAgICBpZiAoZHIgJiYgZHIucnVuU2NlbmVJbW1lZGlhdGUpIHtcbiAgICAgICAgICAgIGNvbnN0IG9yaWcgPSBkci5ydW5TY2VuZUltbWVkaWF0ZS5iaW5kKGRyKTtcbiAgICAgICAgICAgIGRyLnJ1blNjZW5lSW1tZWRpYXRlID0gKHNjZW5lOiBhbnksIG9uQmVmb3JlTG9hZFNjZW5lPzogRnVuY3Rpb24sIG9uTGF1bmNoZWQ/OiBGdW5jdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIGxvZyhgcnVuU2NlbmVJbW1lZGlhdGUg6LCD55SoIHNjZW5lPSR7c2NlbmUgJiYgKHNjZW5lLm5hbWUgfHwgc2NlbmUuX25hbWUpfWApO1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnKHNjZW5lLCBvbkJlZm9yZUxvYWRTY2VuZSwgb25MYXVuY2hlZCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbnNvbGUg5YWo6YeP6L2s5Y+R5bey55SxIGhvb2tDb25zb2xlRm9yd2FyZCDlnKjmuLLmn5Pml6nmnJ/lronoo4XvvIzmraTlpITkuI3lho3ph43lpI3ljIXoo4VcbiAgICAgICAgICAgIGxvZygn6L+Q6KGM5pyf6Lef6Liq5bey5a6J6KOFIChnYW1lLnJ1bi9sb2FkV2l0aEpzb24vcnVuU2NlbmVJbW1lZGlhdGUpJyk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGluc3RhbGxOb3coKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIFN5c3RlbS5yZWdpc3RlciDmg7DmgKfmiafooYzvvJp3aW5kb3cuY2Mg5bCa5pyq5bCx57uq77yM6L2u6K+i562J5b6F77yI5pyA5aSa57qmIDEwc++8iVxuICAgICAgICBsZXQgdHJpZXMgPSAwO1xuICAgICAgICBjb25zdCB0aW1lciA9IHdpbmRvdy5zZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICB0cmllcysrO1xuICAgICAgICAgICAgaWYgKGluc3RhbGxOb3coKSB8fCB0cmllcyA+IDQwMCkge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRpbWVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgMjUpO1xuICAgIH0sXG4gICAgLyoqIOWcuuaZr+WKoOi9veeci+mXqOeLl++8mmJvb3RGbiDmiJDlip/lkI7mr48gMiDnp5Lmo4Dmn6XkuIDmrKEgZGlyZWN0b3IuZ2V0U2NlbmUoKe+8jFxuICAgICAqICDoi6Xplb/ml7bpl7Tml6DlnLrmma/liJnovpPlh7rlvJXmk47nirbmgIHlv6vnhafvvIhwYXVzZWQvcGFjZXIvYXNzZXRz77yJ77yM5Yy65YiGXG4gICAgICogIOOAjOS4u+W+queOr+acqui/kOihjOOAjeS4juOAjOi1hOa6kOeuoee6v+aMgui1t+OAjeS4pOexu+WNoeeCueOAgumHjea4suafk+aXtuiHquWKqOWkseaViOOAgiAqL1xuICAgIHN0YXJ0U2NlbmVXYXRjaGRvZyh0aGlzOiBhbnkpIHtcbiAgICAgICAgY29uc3Qgc2VxID0gdGhpcy5fcmVuZGVyU2VxO1xuICAgICAgICBjb25zdCBsb2cgPSAobXNnOiBzdHJpbmcpID0+IHRoaXMubG9ncy5wdXNoKHsgZXZ0OiAnc3lzJywgbXNnOiBgW+mihOiniOi3n+i4ql0gJHttc2d9YCB9KTtcbiAgICAgICAgY29uc3QgbGVnYWN5ID0gKHdpbmRvdyBhcyBhbnkpLmNjIHx8ICh3aW5kb3cgYXMgYW55KS5jY2xlZ2FjeTtcbiAgICAgICAgbGV0IHdhaXRlZCA9IDA7XG4gICAgICAgIGNvbnN0IE1BWF9USU1FT1VUX0xPRyA9IDI7IC8vIOWcuuaZr+S5heS4jeWHuueOsOaXtuacgOWkmuaPkOekuuWHoOi9ru+8jOmBv+WFjeWumuaXtuWZqOaMgee7reWIt+Wxj1xuICAgICAgICBsZXQgdGltZW91dExvZ3MgPSAwO1xuICAgICAgICBjb25zdCB0aW1lciA9IHdpbmRvdy5zZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5fcmVuZGVyU2VxICE9PSBzZXEgfHwgIXRoaXMucHJldmlld0xvYWRlZCkge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRpbWVyKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3YWl0ZWQgKz0gMjtcbiAgICAgICAgICAgIGxldCBzYzogYW55ID0gbnVsbDtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgc2MgPSBsZWdhY3k/LmRpcmVjdG9yPy5nZXRTY2VuZT8uKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgICAgICAgLyogaWdub3JlICovXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2MpIHtcbiAgICAgICAgICAgICAgICBsb2coYOWcuuaZr+W3suWHuueOsDogJHtzYy5uYW1lIHx8IHNjLl9uYW1lIHx8ICc/J31gKTtcbiAgICAgICAgICAgICAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbCh0aW1lcik7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHdhaXRlZCA+PSAyNCAmJiB0aW1lb3V0TG9ncyA8IE1BWF9USU1FT1VUX0xPRykge1xuICAgICAgICAgICAgICAgIGxldCBwYXVzZWQgPSAnPyc7XG4gICAgICAgICAgICAgICAgbGV0IHBhY2VyID0gJz8nO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGdnID0gbGVnYWN5Py5nYW1lO1xuICAgICAgICAgICAgICAgICAgICBwYXVzZWQgPSBTdHJpbmcoISEoZ2cgJiYgZ2cuX3BhdXNlZCkpO1xuICAgICAgICAgICAgICAgICAgICBwYWNlciA9IGdnICYmIGdnLl9wYWNlciA/IFN0cmluZyghIWdnLl9wYWNlci5faXNQbGF5aW5nKSA6ICfml6BwYWNlcic7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgICAgICAgICAgICAvKiBpZ25vcmUgKi9cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGFzc2V0cyA9IDA7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXNzZXRzID0gbGVnYWN5Py5hc3NldE1hbmFnZXI/LmFzc2V0cz8uY291bnQgfHwgMDtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgICAgICAgICAgIC8qIGlnbm9yZSAqL1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aW1lb3V0TG9ncysrO1xuICAgICAgICAgICAgICAgIGxvZyhg5Zy65pmv562J5b6F6LaF5pe2ICR7d2FpdGVkfXM6IHBhdXNlZD0ke3BhdXNlZH0gcGFjZXI9JHtwYWNlcn0gYXNzZXRzPSR7YXNzZXRzfWApO1xuICAgICAgICAgICAgICAgIGlmICh0aW1lb3V0TG9ncyA+PSBNQVhfVElNRU9VVF9MT0cpIHtcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGltZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgMjAwMCk7XG4gICAgfSxcbiAgICAvKiog5o6i5rWL6aKE6KeI5pyN5Yqh5piv5ZCm5Zyo57q/77yIbm8tY29ycyDor7fmsYLvvIzot6jln5/lj6rliKTov57pgJrmgKfvvIzkuI3or7vlhoXlrrnvvInjgIIgKi9cbiAgICBhc3luYyBjaGVja1ByZXZpZXcodGhpczogYW55KSB7XG4gICAgICAgIGlmICh0aGlzLnByZXZpZXdDaGVja2luZykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIOiKgua1ge+8muiHs+WwkSAzIOenkuaOoua1i+S4gOasoVxuICAgICAgICBpZiAoRGF0ZS5ub3coKSAtIHRoaXMucHJldmlld0NoZWNrQXQgPCAzMDAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcmV2aWV3Q2hlY2tpbmcgPSB0cnVlO1xuICAgICAgICBjb25zdCB1cmwgPSAodGhpcy5wcmV2aWV3VXJsIHx8ICcnKS50cmltKCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIXVybCkge1xuICAgICAgICAgICAgICAgIHRoaXMucHJldmlld09ubGluZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGN0bCA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICAgICAgICAgIGNvbnN0IHRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4gY3RsLmFib3J0KCksIDYwMDApO1xuICAgICAgICAgICAgYXdhaXQgZmV0Y2godXJsLCB7IG1ldGhvZDogJ0dFVCcsIG1vZGU6ICduby1jb3JzJywgY2FjaGU6ICduby1zdG9yZScsIHNpZ25hbDogY3RsLnNpZ25hbCB9KTtcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgdGhpcy5wcmV2aWV3T25saW5lID0gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICB0aGlzLnByZXZpZXdPbmxpbmUgPSBmYWxzZTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMucHJldmlld0NoZWNrQXQgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgdGhpcy5wcmV2aWV3Q2hlY2tpbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgb25SZXNpemUodGhpczogYW55KSB7XG4gICAgICAgIGlmICh0aGlzLnNob3dQZXJmKSB7XG4gICAgICAgICAgICB0aGlzLmRyYXdQZXJmKCk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHN0YXJ0RHJhZyh0aGlzOiBhbnksIGtpbmQ6ICdsZWZ0JyB8ICdyaWdodCcsIGU6IFBvaW50ZXJFdmVudCkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IGVsID0gZS5jdXJyZW50VGFyZ2V0IGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICAgICAgaWYgKGVsICYmIGVsLnNldFBvaW50ZXJDYXB0dXJlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGVsLnNldFBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICAgICAgICAvKiDmjZXojrflpLHotKXkuZ/kuI3lvbHlk40gd2luZG93IOe6p+ebkeWQrCAqL1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUudXNlclNlbGVjdCA9ICdub25lJztcbiAgICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3IgPSAnY29sLXJlc2l6ZSc7XG4gICAgICAgIHRoaXMuZHJhZyA9IHtcbiAgICAgICAgICAgIGtpbmQsXG4gICAgICAgICAgICBzdGFydFg6IGUuY2xpZW50WCxcbiAgICAgICAgICAgIHN0YXJ0Vzoga2luZCA9PT0gJ2xlZnQnID8gdGhpcy50cmVlV2lkdGggOiB0aGlzLmRldGFpbFdpZHRoLFxuICAgICAgICAgICAgcG9pbnRlcklkOiBlLnBvaW50ZXJJZCxcbiAgICAgICAgICAgIGVsLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgb25EcmFnTW92ZSh0aGlzOiBhbnksIGU6IFBvaW50ZXJFdmVudCkge1xuICAgICAgICBpZiAoIXRoaXMuZHJhZykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGR4ID0gZS5jbGllbnRYIC0gdGhpcy5kcmFnLnN0YXJ0WDtcbiAgICAgICAgY29uc3QgdyA9IHRoaXMuZHJhZy5raW5kID09PSAnbGVmdCcgPyB0aGlzLmRyYWcuc3RhcnRXICsgZHggOiB0aGlzLmRyYWcuc3RhcnRXIC0gZHg7XG4gICAgICAgIGNvbnN0IGNsYW1wZWQgPSBNYXRoLm1heCgxNDAsIE1hdGgubWluKDQ4MCwgdykpO1xuICAgICAgICBpZiAodGhpcy5kcmFnLmtpbmQgPT09ICdsZWZ0Jykge1xuICAgICAgICAgICAgdGhpcy50cmVlV2lkdGggPSBjbGFtcGVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kZXRhaWxXaWR0aCA9IGNsYW1wZWQ7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGVuZERyYWcodGhpczogYW55KSB7XG4gICAgICAgIGlmICghdGhpcy5kcmFnKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZHJhZy5lbCAmJiB0aGlzLmRyYWcuZWwuaGFzUG9pbnRlckNhcHR1cmUgJiYgdGhpcy5kcmFnLmVsLmhhc1BvaW50ZXJDYXB0dXJlKHRoaXMuZHJhZy5wb2ludGVySWQpKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRoaXMuZHJhZy5lbC5yZWxlYXNlUG9pbnRlckNhcHR1cmUodGhpcy5kcmFnLnBvaW50ZXJJZCk7XG4gICAgICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgICAgICAgLyogaWdub3JlICovXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS51c2VyU2VsZWN0ID0gJyc7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUuY3Vyc29yID0gJyc7XG4gICAgICAgIHRoaXMuZHJhZyA9IG51bGw7XG4gICAgfSxcbn07XG4iXX0=
|