diff --git a/assets/RuntimeBridge.ts b/assets/RuntimeBridge.ts new file mode 100644 index 0000000..f4af6f8 --- /dev/null +++ b/assets/RuntimeBridge.ts @@ -0,0 +1,1844 @@ +// ============================================================================ +// yyka-runtime-inspector —— 游戏侧桥接脚本(常驻节点版,供用户安装进项目 assets) +// +// 特性: +// · 常驻节点:onLoad 时 director.addPersistRootNode(this.node),跨场景存活。 +// · 自动连接:脚本被加载后,监听场景启动并自动创建常驻节点,无需手动摆放节点 +// 也无需手动调用 connect()。若想手动控制,可放置节点后设 autoConnect=false。 +// · 自动重连:连接断开后按 reconnectDelay 自动重连。 +// +// 用法(两种任选其一): +// A. 推荐:让安装按钮把本脚本装进 assets 后,脚本会在首次场景自动创建常驻节点。 +// B. 手动:新建空节点,挂上 RuntimeBridge 组件,配置 host/port/autoConnect。 +// 局域网真机时把 host 设为电脑 IP。 +// +// 端口默认 33000,与插件主进程内嵌的 WS 服务一致。 +// ============================================================================ +import { + _decorator, + Asset, + assetManager, + AudioSource, + Canvas, + Color, + Collider, + Collider2D, + Component, + Director, + director, + EventTouch, + game, + Graphics, + Layers, + Material, + Node, + PhysicsSystem, + profiler, + Quat, + Rect, + RenderRoot2D, + RigidBody, + RigidBody2D, + Size, + sys, + SystemEvent, + Touch, + UITransform, + Vec2, + Vec3, + Vec4, +} from 'cc'; + +const { ccclass, property, menu } = _decorator; + +const DEFAULT_HOST = '127.0.0.1'; +const DEFAULT_PORT = 33000; +/** 固定连接令牌:与插件静态令牌一致,不做动态生成、不依赖组件属性。 */ +const TOKEN = 'www.yyka.cn'; +/** 自动引导时创建的常驻节点名 */ +const PERSIST_NODE_NAME = '__yyka_runtime_bridge__'; +/** 桥接脚本版本:面板据此判断游戏侧是否在跑旧脚本 */ +const BRIDGE_VERSION = '1.0.254'; + +// ============================================================================ +// 全局 console 拦截:把游戏里的 log/warn/error 转发给插件面板。 +// 未连接时先积压到 consoleQueue,连接建立后再补发,避免丢日志。 +// ============================================================================ +const _origLog = console.log.bind(console); +const _origWarn = console.warn.bind(console); +const _origError = console.error.bind(console); +const consoleQueue: { evt: string; level: string; text: string; t: number }[] = []; + +function fmtConsoleArgs(args: any[]): string { + return args + .map((a) => { + try { + if (typeof a === 'string') { + return a; + } + if (a instanceof Error) { + return a.stack || String(a); + } + const s = JSON.stringify(a); + return s === undefined ? String(a) : s; + } catch { + return String(a); + } + }) + .join(' '); +} + +/** 已知的引擎内部告警噪音:变量填空类型时 getComponent 会警告「Type must be non-nil」, + * 纯属引擎内部提示、无业务价值。判定命中则既不打印到游戏控制台也不转发给面板。 */ +function isEngineNoise(args: any[]): boolean { + const text = fmtConsoleArgs(args); + return /getComponent: Type must be non-nil/.test(text); +} + +function pushConsole(level: string, args: any[]): void { + const item = { evt: 'console', level, text: fmtConsoleArgs(args), t: Date.now() }; + const inst = RuntimeBridge._instance; + if (inst) { + inst.sendConsoleMsg(item); + } else { + consoleQueue.push(item); + if (consoleQueue.length > 200) { + consoleQueue.shift(); + } + } +} + +function hookConsole(): void { + if ((console as any).__yykaHooked) { + return; + } + (console as any).__yykaHooked = true; + const wrap = (orig: (...a: any[]) => void, level: string) => (...args: any[]) => { + if (isEngineNoise(args)) { + return; // 引擎内部告警:不打印到真实控制台,也不转发 + } + orig(...args); + pushConsole(level, args); + }; + console.log = wrap(_origLog, 'log'); + console.warn = wrap(_origWarn, 'warn'); + console.error = wrap(_origError, 'error'); +} + +/** 捕获未被 console 覆盖的全局异常/未处理 Promise 拒绝。 */ +function hookGlobalErrors(): void { + try { + const g: any = globalThis as any; + if (g.__yykaErrHooked) { + return; + } + g.__yykaErrHooked = true; + if (typeof g.addEventListener === 'function') { + g.addEventListener('error', (e: any) => { + const err = e && e.error; + const text = e && e.message ? String(e.message) : (err ? String(err) : '未知错误'); + const stack = err && err.stack ? `\n${err.stack}` : ''; + pushConsole('error', [`[window.error] ${text}${stack}`]); + }); + g.addEventListener('unhandledrejection', (e: any) => { + const r = e && e.reason; + const text = r && r.stack ? r.stack : (r && r.message ? String(r.message) : String(r)); + pushConsole('error', [`[unhandledrejection] ${text}`]); + }); + } + } catch { + /* ignore */ + } +} + +// 模块求值即启用日志拦截,尽可能早地捕获游戏日志与报错 +hookConsole(); +hookGlobalErrors(); +hookApi(); + +/** 拦截空类型组件查询:getComponent/getComponentsInChildren 传入 undefined/空串时, + * 引擎会在内部反复打印 `getComponent: Type must be non-nil` 刷屏(走引擎自有告警通道, + * 不经过 console 钩子)。这里在 API 入口短路空类型,从源头消除告警, + * 行为与引擎返回 undefined / [] 一致(仅不再报警)。 */ +function hookApi(): void { + try { + if ((Node.prototype as any).__yykaApiHooked) { + return; + } + (Node.prototype as any).__yykaApiHooked = true; + const origGet = Node.prototype.getComponent; + const origGetInChildren = Node.prototype.getComponentsInChildren; + const empty = (t: any) => + t === null || t === undefined || (typeof t === 'string' && !t.trim()); + Node.prototype.getComponent = function (type: any, ...rest: any[]) { + if (empty(type)) return null; + return origGet.call(this, type, ...rest); + } as any; + Node.prototype.getComponentsInChildren = function (type: any) { + if (empty(type)) return []; + return origGetInChildren.call(this, type); + } as any; + } catch { + /* ignore */ + } +} + +/** 识别当前运行环境类型,随连接 URL 上报给插件,供面板显示客户端来源。 */ +function detectClientType(): string { + try { + if (sys.isNative) { + const p = sys.platform; + if (p === sys.Platform.ANDROID || p === sys.Platform.IOS) { + return 'device'; + } + return 'simulator'; + } + if (sys.isBrowser) { + const ua = (typeof navigator !== 'undefined' && navigator.userAgent) || ''; + // 编辑器内置预览运行于 Electron 环境 + if (/electron|cocoscreator/i.test(ua)) { + return 'editor'; + } + return 'h5'; + } + } catch { + /* 检测失败按未知处理 */ + } + return 'unknown'; +} + + +@ccclass('RuntimeBridge') +@menu('Debug/RuntimeBridge') +export class RuntimeBridge extends Component { + /** 全局单例,避免重复实例 */ + static _instance: RuntimeBridge | null = null; + + @property({ tooltip: '加载后是否自动连接' }) + autoConnect = true; + + @property({ tooltip: 'WS 服务地址' }) + host = '192.168.2.17'; + + @property({ tooltip: 'WS 服务端口' }) + port = DEFAULT_PORT; + + @property({ tooltip: '断开后自动重连延迟(秒)' }) + reconnectDelay = 2; + + @property({ tooltip: '启用时以该帧率向插件推送预览画面(0 表示关闭)' }) + previewFps = 0; + + private _ws: WebSocket | null = null; + private _timer: ReturnType | null = null; + private _reconnectTimer: ReturnType | null = null; + private _frameTimer: ReturnType | null = null; + private _manualClose = false; + /** 本次连接是否成功建立过(用于区分"被拒/不通"与"正常断开") */ + private _everOpened = false; + /** 从未成功建立连接的连续失败次数,防止无限重连刷屏 */ + private _failCount = 0; + /** 实际连接的地址(候选列表中当前项) */ + private _connHost = DEFAULT_HOST; + /** 候选连接地址:用户配置优先,失败自动尝试模拟器/真机常见的宿主机地址 */ + private _addrCandidates: string[] = []; + private _addrIdx = 0; + private _muted = false; + private _resVol = new WeakMap(); + private _frameCount = 0; + private _lastStatsT = 0; + private _highlightOverlay: Node | null = null; + // ===== 画面抓帧缓存 ===== + // WebGL 画布未开 preserveDrawingBuffer 时,present 后缓冲区即被清空,非渲染时机 + // 对 #GameCanvas 调 toDataURL 只能得到纯黑。因此改在导演每次绘帧完成(EVENT_AFTER_DRAW, + // 此时默认缓冲仍持有本帧内容)时把画面缓存起来;截图/预览直接喂缓存帧,保证非黑。 + private _lastFrame: string | null = null; + private _capStamp = 0; + private _capHooked = false; + /** 最近一次场景启动时记录的场景名(H5 早期 getScene() 可能为 null,用缓存兜底)。 */ + private _sceneName = ''; + + /** 当前场景名:优先实时取 director.getScene(),取不到/为空时用缓存兜底,再无名字时给占位名。 */ + private currentSceneName(): string { + const scene: any = director.getScene(); + const live = scene && (scene.name || scene._name || ''); + return String(live || this._sceneName || 'main'); + } + + onLoad() { + if (RuntimeBridge._instance) { + // 已存在实例,销毁多余节点,避免重复连接 + this.node.destroy(); + return; + } + RuntimeBridge._instance = this; + // 常驻:跨场景存活 + if (!director.isPersistRootNode(this.node)) { + director.addPersistRootNode(this.node); + } + // 记录当前场景名,供 query-tree 在 getScene() 尚未就绪时兜底 + this._sceneName = director.getScene()?.name ?? ''; + // 安装绘帧完成钩子:让截图/预览在 AFTER_DRAW 拿到非黑画面(WebGL 缓冲会被清)。 + this.installFrameHook(); + if (this.autoConnect && !this._ws) { + this.connect(); + } + // 帧计数:用于统计 fps + director.on(Director.EVENT_AFTER_UPDATE, this.onFrame, this); + } + + private onFrame(): void { + this._frameCount++; + } + + /** 渲染/内存统计:drawCall / 三角形 / fps / 堆内存(MB)。 */ + private collectStats(): { drawCall: number; triangles: number; fps: number; memUsed: number; memTotal: number } { + // profiler.stats 里的字段可能是 PerfCounter 对象(带 value 属性),统一转成数字 + const toNum = (v: any): number => { + if (typeof v === 'number' && isFinite(v)) { + return v; + } + if (v && typeof v === 'object' && typeof v.value === 'number' && isFinite(v.value)) { + return v.value; + } + return 0; + }; + let drawCall = 0; + let triangles = 0; + try { + // 最优先:gfx 设备统计(director.root.device.numDrawCalls / numTris), + // 不依赖 profiler 模块是否被功能裁剪,数据源与 profiler 一致 + const root: any = (director as any).root; + const dev = root && root.device; + if (dev) { + const dc = toNum(dev.numDrawCalls); + const tri = toNum(dev.numTris); + if (dc || tri) { + drawCall = dc; + triangles = tri; + } + } + // 其次:新版引擎的 profiler 统计(cc.profiler.stats: draws / tricount) + // 注意 3.x 里字段名是 draws 而不是 drawCall + if (!drawCall && !triangles) { + const prof: any = (profiler as any) || (globalThis as any).cc?.profiler; + const pst = prof && prof.stats; + if (pst) { + const dc = toNum(pst.draws ?? pst.drawCall ?? 0); + const tri = toNum(pst.tricount ?? pst.triangles ?? 0); + if (dc || tri) { + drawCall = dc; + triangles = tri; + } + } + } + // 再次:RenderScene 统计(默认关闭,需先 setStatistics(true)) + if (!drawCall && !triangles) { + const scene: any = director.getScene(); + const rs: any = scene && scene.getRenderScene ? scene.getRenderScene() : null; + if (rs) { + try { + rs.setStatistics && rs.setStatistics(true); + } catch (e) { + /* ignore */ + } + const st = rs.statistics; + if (st) { + const dc = toNum(st.drawCall ?? st.drawCalls ?? st.draws ?? 0); + const tri = toNum(st.triangle ?? st.triangles ?? st.triangleCount ?? 0); + if (dc || tri) { + drawCall = dc; + triangles = tri; + } + } + } + } + // 兜底:director.getStats()(部分版本可用) + if (!drawCall && !triangles) { + const d: any = director as any; + const stats: any = typeof d.getStats === 'function' ? d.getStats() : null; + if (stats) { + drawCall = toNum(stats.drawCall ?? stats.draws ?? 0); + triangles = toNum(stats.triangles ?? stats.trianglesCount ?? 0); + } + } + } catch (e) { + drawCall = 0; + triangles = 0; + } + // 堆内存(MB):浏览器预览可用 performance.memory;原生/无此接口则为 0 + let memUsed = 0; + let memTotal = 0; + try { + const pm: any = (globalThis as any).performance && (globalThis as any).performance.memory; + if (pm) { + memUsed = Math.round(pm.usedJSHeapSize / 1048576); + memTotal = Math.round(pm.totalJSHeapSize / 1048576); + } + } catch (e) { + memUsed = 0; + memTotal = 0; + } + const now = Date.now(); + const dtSec = this._lastStatsT ? (now - this._lastStatsT) / 1000 : 1; + const fps = dtSec > 0 ? Math.round(this._frameCount / dtSec) : 0; + this._frameCount = 0; + this._lastStatsT = now; + return { drawCall, triangles, fps, memUsed, memTotal }; + } + + /** 资源/对象统计:场景节点与组件数 + assetManager 中各类资源数量。 */ + private getResourceStats(): any { + const out: any = { + nodes: 0, + components: 0, + textures: 0, + sprites: 0, + materials: 0, + meshes: 0, + audioClips: 0, + animations: 0, + prefabs: 0, + spriteAtlases: 0, + jsons: 0, + texts: 0, + others: 0, + totalAssets: 0, + }; + const scene = director.getScene(); + if (scene) { + scene.walk(() => { + out.nodes++; + }); + try { + out.components = scene.getComponentsInChildren(Component).length; + } catch { + /* ignore */ + } + } + try { + const am: any = assetManager as any; + const assets: any = am && am.assets; + if (assets && typeof assets.forEach === 'function') { + out.totalAssets = 0; + assets.forEach((asset: any) => { + out.totalAssets++; + const cls = asset && asset.constructor ? asset.constructor.name : ''; + switch (cls) { + case 'Texture2D': out.textures++; break; + case 'SpriteFrame': out.sprites++; break; + case 'Material': out.materials++; break; + case 'Mesh': out.meshes++; break; + case 'AudioClip': out.audioClips++; break; + case 'AnimationClip': out.animations++; break; + case 'Prefab': out.prefabs++; break; + case 'SpriteAtlas': out.spriteAtlases++; break; + case 'JsonAsset': out.jsons++; break; + case 'TextAsset': out.texts++; break; + default: out.others++; break; + } + }); + } + } catch { + /* ignore */ + } + return out; + } + + /** 列出已加载资产(面板资产选择弹层用)。payload: { type?: string } */ + private listAssets(payload: any): any { + const out: any[] = []; + const typeSet = new Set(); + const filter = payload && payload.type ? String(payload.type) : ''; + try { + const am: any = assetManager as any; + const assets: any = am && am.assets; + if (assets && typeof assets.forEach === 'function') { + assets.forEach((asset: any) => { + if (!asset) { + return; + } + const cls = asset.constructor?.name ?? (asset as any).__classname__ ?? ''; + if (cls) { + typeSet.add(cls); + } + if (filter && cls !== filter) { + return; + } + out.push({ + name: String((asset as any).name ?? ''), + uuid: String((asset as any).uuid ?? (asset as any)._id ?? ''), + type: cls, + }); + }); + } + } catch { + /* ignore */ + } + out.sort((a: any, b: any) => (a.name || '').localeCompare(b.name || '')); + return { assets: out, types: [...typeSet].sort() }; + } + + /** 按 uuid 从已加载资产中查找资产对象。 */ + private findAsset(uuid: string): any { + if (!uuid) { + return null; + } + try { + const am: any = assetManager as any; + const assets: any = am && am.assets; + let found: any = null; + if (assets && typeof assets.forEach === 'function') { + assets.forEach((asset: any) => { + if (found) { + return; + } + if (asset && String((asset as any).uuid ?? (asset as any)._id ?? '') === uuid) { + found = asset; + } + }); + } + return found; + } catch { + return null; + } + } + + onDestroy() { + if (RuntimeBridge._instance === this) { + RuntimeBridge._instance = null; + } + director.off(Director.EVENT_AFTER_UPDATE, this.onFrame, this); + this._manualClose = true; + this.stopPreview(); + this.clearHighlight(); + this.disconnect(); + } + + /** 固定连接地址:不做多地址尝试/排队,始终用界面配置的 host(默认 127.0.0.1)。 */ + private buildAddrCandidates(): string[] { + return [(this.host || '').trim() || DEFAULT_HOST]; + } + + /** 建立(或重建)连接。 */ + connect() { + this._manualClose = false; + this._everOpened = false; + if (this._ws && this._ws.readyState === WebSocket.OPEN) { + return; + } + this.clearReconnect(); + if (this._addrCandidates.length === 0) { + this._addrCandidates = this.buildAddrCandidates(); + this._addrIdx = 0; + } + this._connHost = this._addrCandidates[this._addrIdx] || this.host || DEFAULT_HOST; + const q = `?token=${encodeURIComponent(TOKEN)}`; + const ctype = detectClientType(); + const sep = '&'; + this._ws = new WebSocket(`ws://${this._connHost}:${this.port}${q}${sep}client=${ctype}`); + + this._ws.onopen = () => { + this._everOpened = true; + this._failCount = 0; + this._addrIdx = 0; + console.log('[yyka-runtime-inspector] 已连接:', this._connHost + ':' + this.port); + this.flushConsole(); + this.send({ evt: 'hello', nodeCount: this.countNodes() }); + if (this.previewFps > 0) { + this.startPreview(this.previewFps); + } + // 定时上报,验证全链路 + this._timer = setInterval(() => { + this.send({ + evt: 'ping', + t: Date.now(), + ver: BRIDGE_VERSION, + scene: this.currentSceneName(), + nodeCount: this.countNodes(), + }); + }, 1000); + }; + + this._ws.onmessage = (evt: MessageEvent) => { + this.onMessage(evt); + }; + + this._ws.onclose = (evt: CloseEvent) => { + this.clearTimer(); + this._ws = null; + // 原生(libwebsockets)的失败信息主要在 onclose 里(不一定先触发 onerror), + // 尽量提取 code/reason,打印出来辅助诊断。 + const closeCode = evt && typeof evt.code === 'number' ? evt.code : -1; + const closeReason = evt && evt.reason ? String(evt.reason) : ''; + if (closeCode === 4001) { + console.error('[yyka-runtime-inspector] 连接被拒绝:令牌(token)与插件不一致,请检查'); + return; + } + if (closeCode === 4002) { + // 被新连接顶替:本实例降级为"待机",不再自动重连,避免互踢循环 + console.warn('[yyka-runtime-inspector] 已被新的游戏连接顶替,本实例停止自动重连'); + return; + } + // 1000=正常关闭、1005=未收到关闭码,跳过;其余视为异常关闭,打印细节 + if (closeCode !== 1000 && closeCode !== 1005) { + console.warn( + '[yyka-runtime-inspector] 连接关闭: ' + this._connHost + ':' + this.port + + ' | code=' + closeCode + + ' | reason=' + (closeReason || '(空)') + + (this._everOpened ? '' : '(从未成功建立连接)') + ); + } + if (!this._manualClose) { + if (!this._everOpened) { + // 从未成功建立连接就断开:换下一个候选地址重试(覆盖模拟器/真机网络差异) + this._addrIdx++; + if (this._addrIdx >= this._addrCandidates.length) { + console.warn('[yyka-runtime-inspector] 连接失败,停止自动重连'); + this._addrIdx = 0; + return; + } + const next = this._addrCandidates[this._addrIdx]; + console.warn('[yyka-runtime-inspector] ' + this._connHost + ':' + this.port + ' 连接失败,尝试 ' + next + ':' + this.port); + } + this.scheduleReconnect(); + } + }; + + this._ws.onerror = (err) => { + // 尽量把错误对象转成可读字符串:浏览器/原生(libwebsockets)传的事件对象结构不同, + // 兼容 字符串 / Error / {message,reason,error,type,code,name} / 其他对象(JSON 兜底)。 + let reason = ''; + try { + const e: any = err; + if (typeof err === 'string') { + reason = err; + } else if (err instanceof Error) { + reason = err.message || err.stack || String(err); + } else if (err && typeof err === 'object') { + reason = e.message || e.reason || e.error || e.type || e.code || e.name || e.target?.url || ''; + if (!reason) { + try { + const keys = Object.keys(e); + reason = keys.length ? JSON.stringify(e) : String(err); + } catch { + reason = String(err); + } + } + } else { + reason = String(err); + } + } catch { + reason = String(err); + } + if (!reason) { + reason = String(err); + } + console.warn('[yyka-runtime-inspector] 连接失败: ' + this._connHost + ':' + this.port + + ' | 原因=' + reason); + }; + } + + /** 供全局 console 拦截器调用:连接已建立时直接转发一条控制台消息。 */ + sendConsoleMsg(item: { evt: string; level: string; text: string; t: number }): void { + if (this._ws && this._ws.readyState === WebSocket.OPEN) { + this.send(item); + } else { + consoleQueue.push(item); + if (consoleQueue.length > 200) { + consoleQueue.shift(); + } + } + } + + /** 连接建立后补发积压的 console 日志。 */ + private flushConsole(): void { + while (consoleQueue.length) { + const it = consoleQueue.shift(); + if (it) { + this.send(it); + } + } + } + + /** 断开连接(不再自动重连)。 */ + disconnect() { + this.clearReconnect(); + this.clearTimer(); + if (this._ws) { + this._ws.close(); + this._ws = null; + } + } + + private scheduleReconnect() { + if (this._manualClose) { + return; + } + this._reconnectTimer = setTimeout(() => this.connect(), this.reconnectDelay * 1000); + } + + private clearReconnect() { + if (this._reconnectTimer) { + clearTimeout(this._reconnectTimer); + this._reconnectTimer = null; + } + } + + private clearTimer() { + if (this._timer) { + clearInterval(this._timer); + this._timer = null; + } + } + + /** 接收来自插件的命令。可带 requestId(需回包),也可 fire-and-forget。 */ + private onMessage(evt: MessageEvent): void { + let msg: any = null; + try { + msg = JSON.parse(String(evt.data)); + } catch { + return; + } + if (!msg || typeof msg.cmd !== 'string') { + return; + } + let data: any; + try { + data = this.handleCommand(msg.cmd, msg.payload ?? {}); + } catch (e: any) { + data = { error: String(e?.message ?? e) }; + } + // 带 requestId 的命令需要回包;否则忽略结果 + if (typeof msg.requestId === 'number') { + this.send({ requestId: msg.requestId, evt: 'response', data }); + } + } + + /** 分发命令并同步返回结果。 */ + private handleCommand(cmd: string, payload: any): any { + switch (cmd) { + case 'query-tree': + return this.buildTree(payload); + case 'get-inspector': + return this.getInspector(payload); + case 'set-property': + return this.setProperty(payload); + case 'set-preview': { + const enabled = !!payload?.enabled; + const fps = payload?.fps || this.previewFps || 10; + if (enabled) { + this.startPreview(fps); + } else { + this.stopPreview(); + } + return { ok: true, preview: enabled, fps }; + } + case 'set-mute': { + this.setMute(!!payload?.muted); + return { ok: true, muted: this._muted }; + } + case 'get-stats': { + return this.collectStats(); + } + case 'capture-frame': { + const data = this.captureFrame(); + return data ? { ok: true, data } : { error: '捕获画面失败' }; + } + case 'get-resource-stats': { + return this.getResourceStats(); + } + case 'set-physics-debug': { + this.setPhysicsDebug(!!payload?.enabled); + return { ok: true, physicsDebug: !!payload?.enabled }; + } + case 'query-physics': { + return this.queryPhysics(); + } + case 'simulate-click': { + return this.simulateClick(payload); + } + case 'highlight': { + return this.setHighlight(payload); + } + case 'list-scenes': { + return this.listScenes(); + } + case 'load-scene': { + return this.loadScene(payload); + } + case 'list-assets': { + return this.listAssets(payload); + } + default: + return { error: `未知命令: ${cmd}` }; + } + } + + /** 启动预览抓帧推送。 */ + private startPreview(fps: number): void { + this.stopPreview(); + const period = Math.max(50, Math.round(1000 / fps)); + this._frameTimer = setInterval(() => { + const data = this.captureFrame(); + if (data) { + this.send({ evt: 'frame', data }); + } + }, period); + } + + private stopPreview(): void { + if (this._frameTimer) { + clearInterval(this._frameTimer); + this._frameTimer = null; + } + } + + /** 静音/恢复:遍历当前场景所有 AudioSource,记录原音量并置 0 或恢复。 */ + private setMute(muted: boolean): void { + this._muted = muted; + this.applyMute(); + } + + private applyMute(): void { + const scene = director.getScene(); + if (!scene) { + return; + } + const sources = scene.getComponentsInChildren(AudioSource) as AudioSource[]; + for (const s of sources) { + if (!this._resVol.has(s)) { + this._resVol.set(s, s.volume); + } + s.volume = this._muted ? 0 : (this._resVol.get(s) ?? 1); + } + } + + /** 开启/关闭物理调试绘制(3D 物理系统的 debug draw)。 */ + private setPhysicsDebug(enabled: boolean): void { + const PS: any = PhysicsSystem as any; + try { + const ps = PS && PS.instance; + if (!ps) { + return; + } + ps.enable = true; + if (enabled) { + const flagsCls = PS.DebugDrawFlags; + const shape = flagsCls?.SHAPE ?? 1; + const joint = flagsCls?.JOINT ?? 2; + const constraint = flagsCls?.CONSTRAINT ?? 4; + ps.debugDrawFlags = shape | joint | constraint; + } else { + ps.debugDrawFlags = (PS.DebugDrawFlags?.NONE) ?? 0; + } + } catch (e: any) { + console.error('[yyka-runtime-inspector] setPhysicsDebug 失败:', e); + } + } + + /** 查询当前物理系统状态与场景内刚体/碰撞体数量。 */ + private queryPhysics(): any { + const out: any = { + enabled: false, + debugDrawFlags: 0, + gravity: null, + bodies: 0, + colliders: 0, + bodies2d: 0, + colliders2d: 0, + }; + const PS: any = PhysicsSystem as any; + try { + const ps = PS && PS.instance; + if (ps) { + out.enabled = !!ps.enable; + out.debugDrawFlags = ps.debugDrawFlags ?? 0; + const g = ps.gravity; + out.gravity = g ? { x: g.x, y: g.y, z: g.z } : null; + } + } catch { + /* 忽略:物理模块未启用或版本差异 */ + } + const scene = director.getScene(); + if (scene) { + try { + out.bodies = scene.getComponentsInChildren(RigidBody).length; + out.colliders = scene.getComponentsInChildren(Collider).length; + } catch { + /* 忽略 */ + } + try { + out.bodies2d = scene.getComponentsInChildren(RigidBody2D).length; + out.colliders2d = scene.getComponentsInChildren(Collider2D).length; + } catch { + /* 忽略 */ + } + } + return out; + } + + /** 抓取当前游戏画面,编码为 JPEG base64。失败返回 null。 + * 直接对 WebGL 画布 toDataURL 在非渲染时机是纯黑(缓冲被清), + * 因此优先返回 AFTER_DRAW 钩子缓存的本帧画面;无缓存或非 WebGL 时才即时抓。 */ + private captureFrame(): string | null { + try { + if (this._lastFrame) { + return this._lastFrame; + } + const canvas: HTMLCanvasElement = (game as any).canvas; + if (!canvas) { + return null; + } + return canvas.toDataURL('image/jpeg', 0.6); + } catch { + return null; + } + } + + /** 安装绘帧完成钩子:渲染后把画面存入缓存(节流,避免每帧都做 JPEG 编码)。 + * 必须在导演每帧的 AFTER_DRAW 触发才能拿到非黑画面。 */ + private installFrameHook(): void { + if (this._capHooked) { + return; + } + this._capHooked = true; + try { + director.on(Director.EVENT_AFTER_DRAW, this._afterDrawCb); + } catch { + /* 引擎未就绪/事件名差异时忽略 */ + } + } + + private _afterDrawCb = (): void => { + const now = Date.now(); + if (now - this._capStamp < 80) { + return; // 节流 ~12fps,够截图与低帧预览用,避免每帧 JPEG 编码开销 + } + this._capStamp = now; + try { + const canvas: HTMLCanvasElement = (game as any).canvas; + if (canvas) { + this._lastFrame = canvas.toDataURL('image/jpeg', 0.6); + } + } catch { + /* 单帧失败不致命 */ + } + }; + + /** 返回单个节点的核心属性 + 组件列表及其可编辑属性。payload: { id } */ + private getInspector(payload: any): any { + const node = this.findNode(payload?.id); + if (!node) { + return { error: `未找到节点: ${payload?.id}` }; + } + const p = node.position; + const e = node.eulerAngles ?? node.rotation; + const s = node.scale; + const w = node.worldPosition; + const components = (node.components || []).map((c: any) => { + const type: string = c.__classname__ ?? c.constructor?.name ?? 'Component'; + const data: any = { + type, + enabled: c.enabled ?? true, + props: this.enumerateEditable(c), + }; + // Widget 专属:输出对齐状态,供面板渲染官方风格的对齐面板 + if (type === 'cc.Widget' || type === 'Widget') { + const w: any = c; + data.widget = { + alignMode: typeof w.alignMode === 'number' ? w.alignMode : 0, + targetName: w.target && typeof w.target === 'object' ? String((w.target as any).name ?? '') : '', + left: w.left ?? 0, + right: w.right ?? 0, + top: w.top ?? 0, + bottom: w.bottom ?? 0, + isAbsLeft: !!w.isAbsLeft, + isAbsRight: !!w.isAbsRight, + isAbsTop: !!w.isAbsTop, + isAbsBottom: !!w.isAbsBottom, + isAlignLeft: !!w.isAlignLeft, + isAlignRight: !!w.isAlignRight, + isAlignTop: !!w.isAlignTop, + isAlignBottom: !!w.isAlignBottom, + isAlignHorizontalCenter: !!w.isAlignHorizontalCenter, + isAlignVerticalCenter: !!w.isAlignVerticalCenter, + }; + } + return data; + }); + return { + id: (node as any)._id ?? '', + name: node.name, + props: { + active: { t: 'bool', v: !!node.active, editable: true }, + layer: { t: 'number', v: node.layer, editable: true }, + position: { t: 'vec3', v: { x: p.x, y: p.y, z: p.z }, editable: true }, + euler: { t: 'vec3', v: { x: e.x, y: e.y, z: e.z }, editable: true }, + scale: { t: 'vec3', v: { x: s.x, y: s.y, z: s.z }, editable: true }, + worldPosition: { t: 'vec3', v: { x: w.x, y: w.y, z: w.z }, editable: false }, + }, + components, + }; + } + + /** 写回一条属性。payload 见下 */ + private setProperty(payload: any): any { + const node = this.findNode(payload?.id); + if (!node) { + return { error: `未找到节点: ${payload?.id}` }; + } + const v = payload?.value; + try { + const field = payload?.field; + const detail = (extra: any = {}) => ({ ok: true, node: node.name, ...extra }); + if (field === 'position') { + node.setPosition(new Vec3(v.x ?? 0, v.y ?? 0, v.z ?? 0)); + this.syncRigidBody(node); + return detail({ field, value: v }); + } + if (field === 'euler') { + node.setRotationFromEuler(v.x ?? 0, v.y ?? 0, v.z ?? 0); + this.syncRigidBody(node); + return detail({ field, value: v }); + } + if (field === 'scale') { + node.setScale(new Vec3(v.x ?? 1, v.y ?? 1, v.z ?? 1)); + this.syncRigidBody(node); + return detail({ field, value: v }); + } + if (field === 'active') { + node.active = !!v; + return detail({ field, value: !!v }); + } + if (field === 'layer') { + node.layer = Number(v) || 0; + return detail({ field, value: node.layer }); + } + // 组件属性:payload.includes { comp: 索引, key: 属性名, value: 原始值 } + if (typeof payload?.comp === 'number' && node.components) { + const comp: any = node.components[payload.comp]; + if (!comp) { + return { error: `组件索引越界: ${payload.comp}` }; + } + if (payload.key === '__enabled') { + comp.enabled = !!v; + return detail({ key: '__enabled', value: !!v }); + } + const cur = comp[payload.key]; + const compType: string = comp.__classname__ ?? comp.constructor?.name ?? ''; + // Widget 对齐属性:写回后立即触发对齐计算 + if ((compType === 'cc.Widget' || compType === 'Widget') && + ['left', 'right', 'top', 'bottom', 'isAbsLeft', 'isAbsRight', 'isAbsTop', 'isAbsBottom', + 'isAlignLeft', 'isAlignRight', 'isAlignTop', 'isAlignBottom', + 'isAlignHorizontalCenter', 'isAlignVerticalCenter', 'alignMode'].includes(payload.key)) { + comp[payload.key] = v; + try { + comp.updateAlignment?.(); + } catch { + /* ignore */ + } + return detail({ key: payload.key, value: v }); + } + // Widget 对齐目标:按运行时节点 id 赋 target + if ((compType === 'cc.Widget' || compType === 'Widget') && payload.key === '__widget_target') { + const target = v ? this.findNode(String(v)) : null; + comp.target = target ?? null; + try { + comp.updateAlignment?.(); + } catch { + /* ignore */ + } + return detail({ key: '__widget_target', value: target ? String((target as any).name ?? '') : '' }); + } + // 引用写回:value 携带运行时节点 id + 组件类型,从节点上取组件赋给引用 + if (v && typeof v === 'object' && v.__refNode && cur && typeof cur === 'object') { + const n = this.findNode(String(v.__refNode)); + if (!n) { + return { error: `未找到引用节点: ${v.__refNode}` }; + } + const target = v.componentType === 'cc.Node' ? n : (n as any).getComponent?.(v.componentType); + if (!target) { + return { error: `节点 ${n.name} 上不存在组件 ${v.componentType}` }; + } + comp[payload.key] = target; + return detail({ key: payload.key, value: v }); + } + // 资产引用写回:value 携带资产 uuid(spriteFrame / material 等),从已加载资产中查找赋给引用 + if (v && typeof v === 'object' && v.__refAsset) { + const asset = this.findAsset(String(v.__refAsset)); + if (!asset) { + return { error: `未找到资产: ${v.__refAsset}` }; + } + if (Array.isArray(cur) && typeof payload.index === 'number') { + const idx = payload.index; + if (idx < 0 || idx >= cur.length) { + return { error: `数组下标越界: ${idx}/${cur.length}` }; + } + cur[idx] = asset; + return detail({ key: payload.key, index: idx, value: v }); + } + comp[payload.key] = asset; + return detail({ key: payload.key, value: v }); + } + // 材质参数写回:payload.key='__material_prop',value={ propKey, value } + // index 为数字时定位 sharedMaterials 数组项,否则用 customMaterial / material + if (payload.key === '__material_prop') { + let mat: any = null; + if (typeof payload.index === 'number' && Array.isArray(comp.sharedMaterials)) { + mat = comp.sharedMaterials[payload.index]; + } else if (comp.customMaterial) { + mat = comp.customMaterial; + } else if (comp.material) { + mat = comp.material; + } + if (!mat || typeof mat.setProperty !== 'function') { + return { error: '材质不可用或不可编辑' }; + } + const info = payload.value || {}; + const pv = info.value; + let setVal: any = pv; + if (pv && typeof pv === 'object') { + if ('r' in pv) { + setVal = new Color((pv.r ?? 0) / 255, (pv.g ?? 0) / 255, (pv.b ?? 0) / 255, (pv.a ?? 255) / 255); + } else if ('w' in pv) { + setVal = new Vec4(pv.x ?? 0, pv.y ?? 0, pv.z ?? 0, pv.w ?? 0); + } else if ('z' in pv) { + setVal = new Vec3(pv.x ?? 0, pv.y ?? 0, pv.z ?? 0); + } else { + setVal = new Vec2(pv.x ?? 0, pv.y ?? 0); + } + } + try { + mat.setProperty(String(info.propKey), setVal); + } catch (e) { + return { error: `设置材质参数失败: ${e}` }; + } + return detail({ key: '__material_prop', value: String(info.propKey) }); + } + // 数组项写回:payload.index 指明下标 + if (Array.isArray(cur) && typeof payload.index === 'number') { + const idx = payload.index; + if (idx < 0 || idx >= cur.length) { + return { error: `数组下标越界: ${idx}/${cur.length}` }; + } + const item = cur[idx]; + if (item instanceof Vec3 && v && typeof v === 'object') { + item.set(v.x ?? 0, v.y ?? 0, v.z ?? 0); + } else if (item instanceof Vec2 && v && typeof v === 'object') { + item.set(v.x ?? 0, v.y ?? 0); + } else if (item instanceof Color && v && typeof v === 'object') { + item.set((v.r ?? 0) / 255, (v.g ?? 0) / 255, (v.b ?? 0) / 255, (v.a ?? 255) / 255); + } else if (item instanceof Quat && v && typeof v === 'object') { + item.set(v.x ?? 0, v.y ?? 0, v.z ?? 0, v.w ?? 1); + } else if (item instanceof Vec4 && v && typeof v === 'object') { + item.set(v.x ?? 0, v.y ?? 0, v.z ?? 0, v.w ?? 0); + } else if (item instanceof Rect && v && typeof v === 'object') { + item.set(v.x ?? 0, v.y ?? 0, v.w ?? 0, v.h ?? 0); + } else if (item instanceof Size && v && typeof v === 'object') { + item.set(v.w ?? 0, v.h ?? 0); + } else { + cur[idx] = v; + } + return detail({ key: payload.key, index: idx, value: v }); + } + // 引用置空:原值是 cc 对象,写入 null + if (v === null && cur && typeof cur === 'object') { + comp[payload.key] = null; + return detail({ key: payload.key, value: null }); + } + if (cur instanceof Vec3 && v && typeof v === 'object') { + cur.set(v.x ?? 0, v.y ?? 0, v.z ?? 0); + } else if (cur instanceof Vec2 && v && typeof v === 'object') { + cur.set(v.x ?? 0, v.y ?? 0); + } else if (cur instanceof Color && v && typeof v === 'object') { + // 面板按 0-255 传输,Color 内部为 0-1 + cur.set((v.r ?? 0) / 255, (v.g ?? 0) / 255, (v.b ?? 0) / 255, (v.a ?? 255) / 255); + } else if (cur instanceof Quat && v && typeof v === 'object') { + cur.set(v.x ?? 0, v.y ?? 0, v.z ?? 0, v.w ?? 1); + } else if (cur instanceof Vec4 && v && typeof v === 'object') { + cur.set(v.x ?? 0, v.y ?? 0, v.z ?? 0, v.w ?? 0); + } else if (cur instanceof Rect && v && typeof v === 'object') { + cur.set(v.x ?? 0, v.y ?? 0, v.w ?? 0, v.h ?? 0); + } else if (cur instanceof Size && v && typeof v === 'object') { + cur.set(v.w ?? 0, v.h ?? 0); + } else { + comp[payload.key] = v; + } + return detail({ key: payload.key, value: v }); + } + return { error: '无法识别的 set-property 载荷' }; + } catch (err: any) { + return { error: `写回失败: ${String(err?.message ?? err)}` }; + } + } + + /** 写回节点变换后同步刚体:清零速度并唤醒,避免物理模拟立即把变换拉回去。 */ + private syncRigidBody(node: Node): void { + const rb3 = node.getComponent(RigidBody); + if (rb3) { + try { + rb3.wakeUp(); + rb3.setLinearVelocity(new Vec3(0, 0, 0)); + rb3.setAngularVelocity(new Vec3(0, 0, 0)); + (rb3 as any).syncFromNode?.(); + } catch { + /* ignore */ + } + return; + } + const rb2 = node.getComponent(RigidBody2D); + if (rb2) { + try { + rb2.wakeUp(); + rb2.linearVelocity = new Vec2(0, 0); + rb2.angularVelocity = 0; + (rb2 as any).syncFromNode?.(); + } catch { + /* ignore */ + } + } + } + + /** 枚举组件上由 @property 声明(装饰器生成的 __props__ 元数据)的可编辑属性。 + * 相比 Object.keys 运行时反射,只显示显式声明的字段,更贴近编辑器属性面板。 */ + private enumerateEditable(comp: any): any[] { + if (!comp) { + return []; + } + const out: any[] = []; + const seen = new Set(); + // 白名单:引擎内部序列化字段 → 公开访问器(如 Renderable 的 _materials → sharedMaterials), + // 避免把 _node/_parent/_children 等内部结构字段暴露出来。 + const PUBLIC_MAP: Record = { _materials: 'sharedMaterials' }; + // 沿原型链收集静态 __props__(CCObject 起,含系统组件继承的属性) + let cls: any = comp.constructor; + let guard = 0; + while (cls && cls !== Object && guard++ < 20) { + if (Array.isArray(cls.__props__)) { + const propTypes: any[] = Array.isArray(cls.__propTypes__) ? cls.__propTypes__ : []; + for (const name of cls.__props__) { + if (typeof name !== 'string' || !name) { + continue; + } + const mappedKey = PUBLIC_MAP[name] ?? ''; + if (!mappedKey && name.startsWith('_')) { + continue; // 非白名单的下划线内部字段 + } + const displayKey = mappedKey || name; + if (seen.has(displayKey)) { + continue; // 同一公开属性只显示一次(如 _materials 与 sharedMaterials 并存时) + } + seen.add(displayKey); + if (name === 'enabled' || name === 'node') { + continue; // 结构性只读属性不参与编辑:enabled 由组件头部开关负责,node 是组件挂载节点 + } + let value: any; + try { + value = comp[mappedKey || name]; + } catch { + continue; + } + // 值为空的资产引用(如未赋值的 spriteFrame):按 __propTypes__ 推断类型,仍显示为可选择的空资产 + if (value === null || value === undefined) { + const idx = cls.__props__.indexOf(name); + const pt = idx >= 0 ? propTypes[idx] : null; + const typeName = this.assetTypeName(pt); + if (typeName) { + out.push({ + key: mappedKey || name, + t: 'asset', + v: { type: typeName, name: '', uuid: '', settable: true }, + editable: true, + }); + } + continue; + } + let d: any = null; + // 枚举:值为 number 且 __propTypes__ 对应当前字段的类型是枚举对象 + if (typeof value === 'number' && propTypes.length) { + const idx = cls.__props__.indexOf(name); + const pt = idx >= 0 ? propTypes[idx] : null; + const opts = this.tryEnumOptions(pt); + if (opts) { + d = { t: 'enum', v: value, options: opts, editable: true }; + } + } + if (!d) { + d = this.toDescriptor(value); + } + if (!d) { + continue; + } + out.push({ key: mappedKey || name, ...d }); + } + } + cls = Object.getPrototypeOf(cls); + } + return out; + } + + /** 尝试把运行时枚举对象展开为 {name,value} 列表;非枚举返回 null。 */ + private tryEnumOptions(enumObj: any): { name: string; value: number }[] | null { + if (!enumObj || (typeof enumObj !== 'object' && typeof enumObj !== 'function')) { + return null; + } + const out: { name: string; value: number }[] = []; + let anyNum = false; + try { + for (const k of Object.keys(enumObj)) { + const v = enumObj[k]; + if (typeof v === 'number') { + out.push({ name: k, value: v }); + anyNum = true; + } + } + } catch { + return null; + } + return anyNum ? out : null; + } + + /** 判断 __propTypes__ 项是否为 Asset 子类,返回类名(如 SpriteFrame);非资产类型返回空串。 */ + private assetTypeName(pt: any): string { + try { + if (!pt) { + return ''; + } + const cls = typeof pt === 'function' ? pt : pt.constructor; + if (!cls || !cls.prototype) { + return ''; + } + let proto = cls.prototype; + while (proto) { + if (proto === Asset.prototype) { + return String(cls.name ?? ''); + } + proto = Object.getPrototypeOf(proto); + } + return ''; + } catch { + return ''; + } + } + + /** 把运行时值转成可 JSON 序列化、可编辑的表述;不可编辑对象返回 null。 */ + private toDescriptor(value: any): any | null { + if (value === null || value === undefined) { + return null; + } + if (typeof value === 'number') { + return { t: 'number', v: value, editable: true }; + } + if (typeof value === 'string') { + return { t: 'string', v: value, editable: true }; + } + if (typeof value === 'boolean') { + return { t: 'bool', v: value, editable: true }; + } + if (value instanceof Vec3) { + return { t: 'vec3', v: { x: value.x, y: value.y, z: value.z }, editable: true }; + } + if (value instanceof Vec2) { + return { t: 'vec2', v: { x: value.x, y: value.y }, editable: true }; + } + if (value instanceof Quat) { + return { t: 'quat', v: { x: value.x, y: value.y, z: value.z, w: value.w }, editable: true }; + } + if (value instanceof Vec4) { + return { t: 'vec4', v: { x: value.x, y: value.y, z: value.z, w: value.w }, editable: true }; + } + if (value instanceof Rect) { + return { t: 'rect', v: { x: value.x, y: value.y, w: value.width, h: value.height }, editable: true }; + } + if (value instanceof Size) { + return { t: 'size', v: { w: value.width, h: value.height }, editable: true }; + } + if (value instanceof Color) { + return { + t: 'color', + v: { r: Math.round(value.r * 255), g: Math.round(value.g * 255), b: Math.round(value.b * 255), a: Math.round(value.a * 255) }, + editable: true, + }; + } + if (Array.isArray(value)) { + const items: any[] = value.slice(0, 8).map((it) => { + const d = this.toDescriptor(it); + return d || { t: 'raw', v: this.rawPreview(it), editable: false }; + }); + return { t: 'array', v: items, len: value.length, editable: true }; + } + // 资产引用(SpriteFrame / Material / Texture2D / Prefab 等):官方 ui-asset 风格显示 + if (value instanceof Asset) { + const clsName = (value as any).__classname__ ?? value.constructor?.name ?? ''; + const d: any = { + t: 'asset', + v: { + type: String(clsName), + name: String((value as any).name ?? ''), + uuid: String((value as any).uuid ?? ''), + settable: true, + }, + editable: true, // 允许置空 + }; + // 材质实例:附带可编辑参数(mainColor / float / vec 等),面板展开编辑 + if (value instanceof Material) { + d.t = 'material'; + d.v.props = this.serializeMaterialProps(value); + } + return d; + } + // Cocos 对象引用(Node / Component;Vec3 等已在上方处理) + if (value && typeof value === 'object' && (value as any).__classname__) { + const clsName = (value as any).__classname__ ?? value.constructor?.name ?? ''; + const refName = (value as any).name ?? ''; + const refUuid = (value as any).uuid ?? (value as any)._id ?? ''; + const compType = (value as any).__classname__ ?? ''; + return { + t: 'ref', + v: { + type: String(clsName), + name: String(refName), + uuid: String(refUuid), + componentType: String(compType), + settable: true, // 可写回为场景内另一节点的组件/节点 + }, + editable: true, // 允许置空 + }; + } + return null; // 其他对象暂不编辑 + } + + /** 数组/对象项的紧凑预览文本。 */ + private rawPreview(v: any): string { + try { + const s = JSON.stringify(v); + return s === undefined ? String(v) : s; + } catch { + return String(v); + } + } + + /** 序列化材质实例的可编辑参数(material.properties)。 */ + private serializeMaterialProps(m: any): any[] { + const out: any[] = []; + try { + const props: any = (m as any).properties; + if (!props || typeof props !== 'object') { + return out; + } + for (const k of Object.keys(props)) { + const p = props[k]; + if (!p || !('value' in p)) { + continue; + } + const val = p.value; + let d: any = null; + if (typeof val === 'number') { + d = { t: 'float', v: val }; + } else if (val instanceof Color) { + d = { + t: 'color', + v: { r: Math.round(val.r * 255), g: Math.round(val.g * 255), b: Math.round(val.b * 255), a: Math.round(val.a * 255) }, + }; + } else if (val instanceof Vec4) { + d = { t: 'vec4', v: { x: val.x, y: val.y, z: val.z, w: val.w } }; + } else if (val instanceof Vec3) { + d = { t: 'vec3', v: { x: val.x, y: val.y, z: val.z } }; + } else if (val instanceof Vec2) { + d = { t: 'vec2', v: { x: val.x, y: val.y } }; + } else if (val && typeof val === 'object' && (val as any).__classname__) { + // 纹理等资产参数:只读显示 + d = { + t: 'texture', + v: { + type: String((val as any).__classname__ ?? ''), + name: String((val as any).name ?? ''), + }, + }; + } + if (d) { + out.push({ key: k, type: String(p.type ?? ''), ...d }); + } + } + } catch { + /* ignore */ + } + return out; + } + + /** 序列化场景节点树。payload: { filter?: string } */ + private buildTree(payload: any): any { + const scene = director.getScene(); + const sceneName = this.currentSceneName(); + const filter = payload && payload.filter ? String(payload.filter).toLowerCase() : ''; + const roots: any[] = []; + if (scene) { + for (const c of scene.children) { + const sub = this.serializeNode(c, filter); + if (sub) { + roots.push(sub); + } + } + } + return { scene: sceneName, filter, roots }; + } + + private serializeNode(node: Node, filter: string): any | null { + const name = node.name ?? ''; + // 隐藏插件内部节点(如高亮线框覆盖层),避免混入节点树 + if (name === '__yyka_highlight__') { + return null; + } + const children: any[] = []; + if (node.children && node.children.length) { + for (const c of node.children) { + const sub = this.serializeNode(c, filter); + if (sub) { + children.push(sub); + } + } + } + const selfMatch = !filter || name.toLowerCase().includes(filter); + if (children.length === 0 && !selfMatch) { + return null; + } + return { + id: (node as any)._id ?? '', + name, + active: !!node.activeInHierarchy, + layer: node.layer, + comps: node.components ? node.components.length : 0, + type: this.nodeType(node), + children, + }; + } + + /** 按优先级取节点主组件类名(供面板显示类型图标)。 */ + private nodeType(node: Node): string { + const ICONED = [ + 'cc.Camera', 'cc.Canvas', 'cc.Label', 'cc.Sprite', 'cc.Button', 'cc.Mask', + 'cc.Graphics', 'cc.RichText', 'cc.Layout', 'cc.ScrollView', 'cc.ScrollBar', + 'cc.PageView', 'cc.PageViewIndicator', 'cc.EditBox', 'cc.Toggle', + 'cc.ToggleContainer', 'cc.ProgressBar', 'cc.Slider', 'cc.Widget', + 'cc.SafeArea', 'cc.VideoPlayer', 'cc.WebView', 'cc.MeshRenderer', + 'cc.SkinnedMeshRenderer', 'cc.SkinnedMeshBatchRenderer', 'cc.ParticleSystem', + 'cc.ParticleSystem2D', 'cc.Terrain', 'cc.TiledMap', 'cc.DirectionalLight', + 'cc.PointLight', 'cc.SpotLight', 'cc.SphereLight', 'cc.RangedDirectionalLight', + 'cc.AudioSource', 'cc.Animation', 'cc.SkeletalAnimation', + 'cc.animation.AnimationController', 'cc.RigidBody', 'cc.RigidBody2D', + 'cc.BoxCollider', 'cc.BoxCollider2D', 'cc.CircleCollider2D', + 'cc.PolygonCollider2D', 'cc.MeshCollider', 'cc.SphereCollider', + 'cc.CapsuleCollider', 'cc.ConeCollider', 'cc.CylinderCollider', + 'cc.PlaneCollider', 'cc.SimplexCollider', 'cc.TerrainCollider', 'cc.Line', + 'cc.MotionStreak', 'cc.UIMeshRenderer', 'cc.Billboard', 'cc.LODGroup', + 'cc.ReflectionProbe', 'cc.LightProbeGroup', 'dragonBones.ArmatureDisplay', + 'sp.Skeleton', + ]; + const set = new Set(ICONED); + if (node.components) { + for (const c of node.components) { + const cls: string = (c as any).__classname__ ?? (c as any).constructor?.name ?? ''; + const full = cls.includes('.') ? cls : `cc.${cls}`; + if (set.has(full)) { + return full; + } + } + } + return ''; + } + + /** 按引擎 _id 查找场景中的节点。 */ + private findNode(id: string): Node | null { + const scene = director.getScene(); + if (!scene) { + return null; + } + const stack: Node[] = scene.children.slice(); + while (stack.length) { + const n = stack.pop()!; + if ((n as any)._id === id) { + return n; + } + if (n.children && n.children.length) { + stack.push(...n.children); + } + } + return null; + } + + /** 高亮/遮罩指定节点。payload: { id, mode: 'highlight'|'mask' }。id 为空串则清除覆盖层。 */ + private setHighlight(payload: any): any { + this.clearHighlight(); + const id = typeof payload?.id === 'string' ? payload.id : ''; + if (!id) { + return { ok: true, cleared: true }; + } + const node = this.findNode(id); + if (!node) { + return { error: `未找到节点: ${id}` }; + } + if (!node.activeInHierarchy) { + return { error: `节点 ${node.name} 未激活,无法高亮` }; + } + const ut = node.getComponent(UITransform); + if (!ut || ut.contentSize.width <= 0 || ut.contentSize.height <= 0) { + return { error: `节点 ${node.name} 没有有效 UITransform,无法高亮` }; + } + const canvas = this.findCanvasRoot(); + if (!canvas) { + return { error: '场景中未找到 Canvas/RenderRoot2D,无法渲染高亮' }; + } + const bb = ut.getBoundingBoxToWorld(); + const mode = payload?.mode === 'mask' ? 'mask' : 'highlight'; + + // 覆盖层挂在 Canvas 下(RenderRoot2D 提供渲染),UI_2D 层、置为最后一个子节点 + const overlay = new Node('__yyka_highlight__'); + overlay.layer = Layers.Enum.UI_2D; + canvas.addChild(overlay); + const g = overlay.addComponent(Graphics); + + // 目标节点世界包围盒 → Canvas 本地坐标 + const canvasUt = canvas.getComponent(UITransform); + const localMin = canvasUt ? canvasUt.convertToNodeSpaceAR(new Vec3(bb.x, bb.y, 0)) : new Vec3(bb.x, bb.y, 0); + const localMax = canvasUt + ? canvasUt.convertToNodeSpaceAR(new Vec3(bb.x + bb.width, bb.y + bb.height, 0)) + : new Vec3(bb.x + bb.width, bb.y + bb.height, 0); + + if (mode === 'mask') { + // 遮罩:Canvas 外圈半透明黑框,目标区域挖空 + const cs = canvasUt ? canvasUt.contentSize : new Size(0, 0); + const w = cs.width; + const h = cs.height; + const minX = localMin.x; + const minY = localMin.y; + const maxX = localMax.x; + const maxY = localMax.y; + g.fillColor = new Color(0, 0, 0, 170); + g.rect(-w / 2, maxY, w, h / 2 - maxY); // 上 + g.rect(-w / 2, -h / 2, w, minY + h / 2); // 下 + g.rect(-w / 2, minY, minX + w / 2, maxY - minY); // 左 + g.rect(maxX, minY, w / 2 - maxX, maxY - minY); // 右 + g.fill(); + } else { + // 高亮:亮蓝色描边 + 半透明填充 + g.lineWidth = 3; + g.strokeColor = new Color(59, 130, 246, 255); + g.fillColor = new Color(59, 130, 246, 40); + g.rect(localMin.x, localMin.y, localMax.x - localMin.x, localMax.y - localMin.y); + g.stroke(); + g.fill(); + } + this._highlightOverlay = overlay; + return { ok: true, mode, node: node.name }; + } + + /** 移除当前高亮覆盖层(如有)。 */ + private clearHighlight(): void { + if (this._highlightOverlay) { + const ov = this._highlightOverlay; + this._highlightOverlay = null; + if (ov.isValid) { + ov.destroy(); + } + } + } + + /** 查找场景中可作为 UI 渲染根的节点(带 Canvas 或 RenderRoot2D 组件)。 */ + private findCanvasRoot(): Node | null { + const scene = director.getScene(); + if (!scene) { + return null; + } + const stack: Node[] = scene.children.slice(); + while (stack.length) { + const n = stack.pop()!; + if (n.getComponent(Canvas) || n.getComponent(RenderRoot2D)) { + return n; + } + if (n.children && n.children.length) { + stack.push(...n.children); + } + } + return null; + } + + /** 模拟一次触摸点击:按 id 取节点 UI 中心点,或按 x/y 坐标命中最上层 UI 节点,再派发 TOUCH_START/TOUCH_END。 */ + private simulateClick(payload: any): any { + const scene = director.getScene(); + if (!scene) { + return { error: '场景不存在' }; + } + let target: Node | null = null; + const point = new Vec2(); + if (typeof payload?.id === 'string' && payload.id) { + target = this.findNode(payload.id); + if (!target) { + return { error: `未找到节点: ${payload.id}` }; + } + const ut = target.getComponent(UITransform); + if (!ut) { + return { error: `节点 ${target.name} 没有 UITransform,无法确定点击位置` }; + } + const w = target.worldPosition; + point.set(w.x, w.y); + } else if (typeof payload?.x === 'number' && typeof payload?.y === 'number') { + point.set(payload.x, payload.y); + target = this.hitTestUI(point); + } else { + return { error: '需要参数 id(节点 id)或 x/y(UI 坐标)' }; + } + if (!target) { + return { error: `坐标 (${point.x}, ${point.y}) 未命中任何 UI 节点` }; + } + const touch = new Touch(); + touch.setTouchInfo(0, point.x, point.y); + const start = new EventTouch([touch], true, SystemEvent.EventType.TOUCH_START); + target.dispatchEvent(start); + const end = new EventTouch([touch], true, SystemEvent.EventType.TOUCH_END); + target.dispatchEvent(end); + return { ok: true, node: target.name, x: point.x, y: point.y }; + } + + /** 节点是否挂在 Canvas/RenderRoot2D 下的 UI 树中。不在 UI 渲染根下的 UITransform 取包围盒会触发引擎崩溃。 */ + private hasUiRoot(n: Node): boolean { + let cur: Node | null = n; + while (cur) { + if (cur.getComponent(Canvas) || cur.getComponent(RenderRoot2D)) { + return true; + } + cur = cur.parent; + } + return false; + } + + /** 按 UI 坐标找命中的最上层节点(遍历顺序靠后的视为更上层)。 */ + private hitTestUI(point: Vec2): Node | null { + const scene = director.getScene(); + if (!scene) { + return null; + } + let hit: Node | null = null; + scene.walk((n: Node) => { + if (!n.activeInHierarchy || !this.hasUiRoot(n)) { + return; + } + const ut = n.getComponent(UITransform); + if (!ut || ut.contentSize.width <= 0 || ut.contentSize.height <= 0) { + return; + } + try { + if (ut.getBoundingBoxToWorld().contains(point)) { + hit = n; + } + } catch { + /* 个别节点包围盒计算异常,跳过即可,不影响命中判断 */ + } + }); + return hit; + } + + /** 列出当前场景及已加载场景名。 */ + private listScenes(): any { + const current = this.currentSceneName(); + const map = (director as any)._loadedSceneMap; + const scenes: string[] = []; + if (map && typeof map === 'object') { + for (const k of Object.keys(map)) { + if (k && !scenes.includes(k)) { + scenes.push(k); + } + } + } + if (current && !scenes.includes(current)) { + scenes.unshift(current); + } + return { current, scenes }; + } + + /** 运行时加载指定场景(跳转)。 */ + private loadScene(payload: any): any { + const name = String(payload?.name ?? ''); + if (!name) { + return { error: '缺少场景名' }; + } + const ok = director.loadScene(name); + return ok ? { ok: true, scene: name } : { error: `场景加载失败或不存在: ${name}` }; + } + + /** 发送一条 JSON 消息给插件。 */ + private send(obj: unknown): void { + if (this._ws && this._ws.readyState === WebSocket.OPEN) { + let payload: string; + try { + payload = JSON.stringify(obj); + } catch { + // 序列化失败(如循环引用)时降级为字符串,避免在消息回调里抛异常 + payload = JSON.stringify(String(obj)); + } + if (payload !== undefined) { + this._ws.send(payload); + } + } + } + + private countNodes(): number { + const scene = director.getScene(); + if (!scene) { + return 0; + } + let n = 0; + scene.walk(() => { + n++; + }); + return n; + } +} + +// ---- 自动引导:脚本被加载后,在场景启动时创建常驻节点,无需手动摆放/调用 ---- +// 注意:预览对脚本做热重载时,本模块会重新求值,但 director 中的常驻节点仍在。 +// 因此一律按名字查重,已存在同名节点就跳过,绝不再新建,避免常驻节点重复累积。 +(function bootstrap() { + /** 递归查找场景中是否存在指定名字的节点。 */ + function findByName(root: Node, name: string): Node | null { + if (!root) { + return null; + } + if (root.name === name) { + return root; + } + const children = root.children; + if (children) { + for (const c of children) { + const found = findByName(c, name); + if (found) { + return found; + } + } + } + return null; + } + + director.on(Director.EVENT_AFTER_SCENE_LAUNCH, () => { + const scene: any = director.getScene(); + const sceneName = String((scene && (scene.name || scene._name)) || ''); + if (RuntimeBridge._instance) { + // 场景切换后刷新场景名缓存,供 getScene() 未就绪时兜底 + RuntimeBridge._instance._sceneName = sceneName; + return; + } + if (!scene) { + return; + } + // 已存在同名常驻节点(可能是本模块之前的实例,或热重载前遗留)则跳过 + if (findByName(scene, PERSIST_NODE_NAME)) { + return; + } + const node = new Node(PERSIST_NODE_NAME); + scene.addChild(node); + const inst = node.addComponent(RuntimeBridge) as RuntimeBridge; // onLoad 中会 addPersistRootNode 并 connect + if (sceneName && !inst._sceneName) { + inst._sceneName = sceneName; // onLoad 时 getScene() 可能尚未就绪,补上本次回调已拿到的场景名 + } + }); +})(); \ No newline at end of file diff --git a/assets/RuntimeBridge.ts.meta b/assets/RuntimeBridge.ts.meta new file mode 100644 index 0000000..7175fdf --- /dev/null +++ b/assets/RuntimeBridge.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "8ee138cf-ab76-449a-8b25-5ef56e1fe190", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/scene/main.scene b/assets/scene/main.scene index edebd74..dd611fa 100644 --- a/assets/scene/main.scene +++ b/assets/scene/main.scene @@ -18,12 +18,15 @@ "_children": [ { "__id__": 2 + }, + { + "__id__": 111 } ], "_active": true, "_components": [], "_prefab": { - "__id__": 111 + "__id__": 113 }, "_lpos": { "__type__": "cc.Vec3", @@ -54,7 +57,7 @@ }, "autoReleaseAssets": false, "_globals": { - "__id__": 112 + "__id__": 114 }, "_id": "89cd0565-e1e7-4d4c-b1f5-8a3061282934" }, @@ -3094,6 +3097,68 @@ "_lockFlags": 0, "_id": "c5V1EV8IpMtrIvY1OE9t2u" }, + { + "__type__": "cc.Node", + "_name": "__yyka_runtime_bridge__", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 112 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "10Wutln0FALLw7Ag4OGxu6" + }, + { + "__type__": "8ee13jPq3ZEmoslXvVuH+GQ", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 111 + }, + "_enabled": true, + "__prefab": null, + "autoConnect": true, + "host": "192.168.2.17", + "port": 33000, + "reconnectDelay": 2, + "previewFps": 0, + "_id": "8cJOa28jFPzKVV0UycbPQZ" + }, { "__type__": "cc.PrefabInfo", "root": null, @@ -3113,28 +3178,28 @@ { "__type__": "cc.SceneGlobals", "ambient": { - "__id__": 113 + "__id__": 115 }, "shadows": { - "__id__": 114 + "__id__": 116 }, "_skybox": { - "__id__": 115 + "__id__": 117 }, "fog": { - "__id__": 116 + "__id__": 118 }, "octree": { - "__id__": 117 + "__id__": 119 }, "skin": { - "__id__": 118 + "__id__": 120 }, "lightProbeInfo": { - "__id__": 119 + "__id__": 121 }, "postSettings": { - "__id__": 120 + "__id__": 122 }, "bakedWithStationaryMainLight": false, "bakedWithHighpLightmap": false diff --git a/extensions/YYKA运行时工作台/.release-sig b/extensions/YYKA运行时工作台/.release-sig new file mode 100644 index 0000000..5f76d35 --- /dev/null +++ b/extensions/YYKA运行时工作台/.release-sig @@ -0,0 +1 @@ +bc52de6deb41df5b03ab84d33014e35c \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/README.txt b/extensions/YYKA运行时工作台/README.txt new file mode 100644 index 0000000..5aa4bad --- /dev/null +++ b/extensions/YYKA运行时工作台/README.txt @@ -0,0 +1,5 @@ +yyka-runtime-inspector 1.0.254 +---------------------------------------- +将整个目录作为 Cocos Creator 扩展安装(或复制到扩展目录)。 +依赖已随目录复制(node_modules),无需额外 npm install。 +游戏侧桥接脚本样例见 runtime-bridge-sample(未打包,需从源码取)。 \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/dist/main.js b/extensions/YYKA运行时工作台/dist/main.js new file mode 100644 index 0000000..ffb807c --- /dev/null +++ b/extensions/YYKA运行时工作台/dist/main.js @@ -0,0 +1,615 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.methods = void 0; +exports.load = load; +exports.unload = unload; +// @ts-ignore +const package_json_1 = __importDefault(require("../package.json")); +const fs_extra_1 = require("fs-extra"); +const path_1 = require("path"); +const os_1 = require("os"); +const ws_server_1 = require("./ws-server"); +const mcp_server_1 = require("./mcp-server"); +const DEFAULT_PORT = 33000; +/** 固定静态连接令牌:不做动态生成,保证脚本/节点令牌与插件始终一致。 */ +const STATIC_TOKEN = 'www.yyka.cn'; +let server = null; +let logBuffer = []; +/** 面板已消费到的缓冲位置:queryLog 改为增量取走而非清空,避免饿死 MCP 的非破坏性 getLogs。 */ +let logCursor = 0; +const serverToken = STATIC_TOKEN; +let mcpHost = null; +const pending = new Map(); +let requestSeq = 0; +function ensureServer() { + if (!server) { + server = new ws_server_1.WsServer(); + } + return server; +} +function getServerState() { + var _a, _b, _c, _d, _e, _f; + const info = (_a = server === null || server === void 0 ? void 0 : server.clientInfo) !== null && _a !== void 0 ? _a : null; + return { + running: (_b = server === null || server === void 0 ? void 0 : server.isRunning) !== null && _b !== void 0 ? _b : false, + port: (_c = server === null || server === void 0 ? void 0 : server.boundPort) !== null && _c !== void 0 ? _c : 0, + clients: (_d = server === null || server === void 0 ? void 0 : server.clients) !== null && _d !== void 0 ? _d : 0, + clientType: (_e = info === null || info === void 0 ? void 0 : info.type) !== null && _e !== void 0 ? _e : '', + clientUrl: (_f = info === null || info === void 0 ? void 0 : info.url) !== null && _f !== void 0 ? _f : '', + }; +} +function pushLog(item) { + logBuffer.push(item); + while (logBuffer.length > 200) { + logBuffer.shift(); + if (logCursor > 0) { + logCursor--; + } + } +} +/** 客户端类型 → 中文标签(日志用)。 */ +function typeLabel(type) { + switch (type) { + case 'h5': + return '浏览器预览'; + case 'editor': + return '编辑器预览'; + case 'simulator': + return '模拟器'; + case 'device': + return '真机'; + case 'unknown': + default: + return '未知来源'; + } +} +/** 从项目 settings 中递归查找数值端口。 */ +function findNumericPort(cfg) { + if (!cfg || typeof cfg !== 'object') { + return 0; + } + if (typeof cfg.port === 'number' && cfg.port > 0) { + return cfg.port; + } + if (typeof cfg.port === 'string' && !Number.isNaN(Number(cfg.port))) { + return Number(cfg.port); + } + for (const k of Object.keys(cfg)) { + const v = cfg[k]; + if (v && typeof v === 'object') { + const p = findNumericPort(v); + if (p > 0) { + return p; + } + } + } + return 0; +} +/** + * 读取当前项目的预览配置,得出浏览器预港口/URL。 + * 用于面板内嵌 iframe 预览的默认地址。 + */ +function getPreviewInfo() { + var _a; + const projectPath = (_a = Editor.Project) === null || _a === void 0 ? void 0 : _a.path; + const candidates = ['settings/preview.json', 'settings/v2/packages/preview.json']; + if (projectPath) { + for (const rel of candidates) { + try { + const p = (0, path_1.join)(projectPath, rel); + if (!(0, fs_extra_1.existsSync)(p)) { + continue; + } + const cfg = (0, fs_extra_1.readJsonSync)(p); + const port = findNumericPort(cfg); + if (port > 0) { + return { host: 'localhost', port, url: `http://localhost:${port}/`, found: p }; + } + } + catch (_b) { + // 忽略解析失败,尝试下一个候选文件 + } + } + } + return { host: 'localhost', port: 7456, url: 'http://localhost:7456/', found: '' }; +} +/** 处理来自游戏侧的消息:优先匹配 pending 请求,否则进入日志缓冲。 */ +function handleIncoming(data) { + var _a; + const m = data && typeof data === 'object' ? data : null; + if (m && typeof m.requestId === 'number' && pending.has(m.requestId)) { + const p = pending.get(m.requestId); + pending.delete(m.requestId); + if (p.timer) + clearTimeout(p.timer); + p.resolve((_a = m.data) !== null && _a !== void 0 ? _a : m); + return; + } + // 命令回包/握手等内部协议消息不进入日志,避免 requestId/response/hello 刷屏 + if (m && (m.evt === 'response' || m.evt === 'request' || m.evt === 'hello')) { + return; + } + pushLog(data); +} +/** 按限制条数与级别读取最近日志(不清空缓冲,供面板/MCP 使用)。 */ +function getLogsInternal(limit, level) { + const items = []; + for (let i = logBuffer.length - 1; i >= 0 && items.length < limit; i--) { + const it = logBuffer[i]; + if (!it || typeof it !== 'object') { + continue; + } + // 过滤掉心跳/握手/预览帧等噪声,只保留控制台与系统消息 + if (it.evt !== 'console' && it.evt !== 'sys') { + continue; + } + if (level && it.evt === 'console' && it.level !== level) { + continue; + } + items.unshift(it); + } + return items; +} +/** 返回 MCP 服务状态与连接配置(URL + 令牌)。 */ +function getMcpState() { + var _a, _b; + return { + running: (_a = mcpHost === null || mcpHost === void 0 ? void 0 : mcpHost.isRunning) !== null && _a !== void 0 ? _a : false, + port: (_b = mcpHost === null || mcpHost === void 0 ? void 0 : mcpHost.boundPort) !== null && _b !== void 0 ? _b : 0, + token: serverToken, + url: (mcpHost === null || mcpHost === void 0 ? void 0 : mcpHost.isRunning) ? `http://127.0.0.1:${mcpHost.boundPort}/mcp` : '', + }; +} +/** 向游戏侧桥接脚本发送一条请求,并等待其回包。 */ +function callGame(cmd, payload, timeout = 5000) { + return new Promise((resolve, reject) => { + if (!server || !server.isRunning) { + reject(new Error('WS 服务未运行,请先启动服务')); + return; + } + const requestId = ++requestSeq; + const timer = setTimeout(() => { + if (pending.has(requestId)) { + pending.delete(requestId); + reject(new Error(`命令超时(>${timeout}ms): ${cmd}`)); + } + }, timeout); + pending.set(requestId, { resolve, reject, timer }); + server.broadcast({ requestId, cmd, payload }); + }); +} +/** 获取宿主机第一个非内网 IPv4 地址(用于注入桥接脚本,供模拟器/真机通过局域网连上插件服务)。 */ +function getHostLanIP() { + var _a; + // 优先返回内网私有段地址(Wi-Fi/有线网卡),避免选到虚拟机或 VPN 虚拟网卡导致真机连不通 + let fallback = ''; + try { + for (const name of Object.keys((0, os_1.networkInterfaces)())) { + for (const net of (_a = (0, os_1.networkInterfaces)()[name]) !== null && _a !== void 0 ? _a : []) { + if (net.family === 'IPv4' && !net.internal) { + const a = net.address.split('.').map(Number); + const isPrivate = a[0] === 10 || + (a[0] === 172 && a[1] >= 16 && a[1] <= 31) || + (a[0] === 192 && a[1] === 168); + if (isPrivate) { + return net.address; + } + if (!fallback) { + fallback = net.address; + } + } + } + } + } + catch (_b) { + /* ignore */ + } + return fallback; +} +/** + * @zh 为扩展的主进程的注册方法 + */ +/** 收集目录下所有 .scene 文件。 */ +function collectSceneFiles(dir, out) { + let entries; + try { + entries = (0, fs_extra_1.readdirSync)(dir, { withFileTypes: true }); + } + catch (_a) { + return; + } + for (const e of entries) { + const p = (0, path_1.join)(dir, e.name); + if (e.isDirectory()) { + collectSceneFiles(p, out); + } + else if (e.isFile() && e.name.endsWith('.scene')) { + out.push(p); + } + } +} +/** 遍历场景 JSON 中的节点树,对匹配指定脚本 uuid 的组件执行回调。 */ +function walkSceneComponents(sceneJson, compUuid, cb) { + const walkNode = (node) => { + if (!node || typeof node !== 'object') { + return; + } + if (node.__type__ === 'cc.Node') { + for (const c of node._components || []) { + if (c && c.__type__ === compUuid) { + cb(c); + } + } + for (const ch of node._children || []) { + walkNode(ch); + } + } + }; + walkNode(sceneJson && sceneJson.scene); +} +exports.methods = { + openPanel() { + Editor.Panel.open(package_json_1.default.name); + }, + openPreviewPanel() { + Editor.Panel.open(`${package_json_1.default.name}.preview`); + }, + /** + * 启动 WS 服务。返回当前服务状态。 + */ + async startServer(port = DEFAULT_PORT) { + const ws = ensureServer(); + ws.token = serverToken; + try { + if (!ws.isRunning) { + ws.on('message', (_client, data) => handleIncoming(data)); + ws.on('connection', (_client, info) => pushLog({ evt: 'sys', msg: `客户端已连接 (${typeLabel(info === null || info === void 0 ? void 0 : info.type)})` })); + ws.on('disconnect', (_client, info) => pushLog({ evt: 'sys', msg: `客户端已断开 (${typeLabel(info === null || info === void 0 ? void 0 : info.type)})` })); + ws.on('auth-fail', (got, url) => pushLog({ evt: 'sys', msg: `连接被拒绝:客户端令牌(${got}) ≠ 服务端令牌(${serverToken})` })); + await ws.start(port); + } + } + catch (err) { + pushLog({ evt: 'sys', msg: `启动服务失败: ${String(err)}` }); + } + return getServerState(); + }, + /** + * 停止 WS 服务。返回当前服务状态。 + */ + async stopServer() { + if (server) { + await server.stop(); + } + return getServerState(); + }, + getServerState() { + return getServerState(); + }, + /** + * 返回固定连接令牌(静态 token)。 + */ + getToken() { + return serverToken; + }, + /** + * 读取当前项目预览配置得出的预港口/URL(供面板内嵌 iframe 用)。 + */ + getPreviewInfo() { + return getPreviewInfo(); + }, + /** + * 读取当前项目设计分辨率(Project Settings → general.designResolution)。 + * 首选编辑器内置 `project/query-config`(实时读配置缓存),多模块/按键都试一遍; + * 失败再退回到读 settings/v2/packages/project.json 文件,兜底 960×640。 + */ + async getProjectsSettings() { + var _a; + try { + const modules = ['general', 'engine', 'project']; + for (const mod of modules) { + try { + const d = await Editor.Message.request('project', 'query-config', mod, 'designResolution'); + if (d && Number(d.width) > 0 && Number(d.height) > 0) { + return { designResolution: { width: Number(d.width), height: Number(d.height) } }; + } + } + catch (_b) { + // 该模块无此配置,尝试下一个 + } + } + } + catch (_c) { + // 继续走文件兜底 + } + const projectPath = (_a = Editor.Project) === null || _a === void 0 ? void 0 : _a.path; + const candidates = [ + 'settings/v2/packages/project.json', + 'settings/project.json', + ]; + if (projectPath) { + for (const rel of candidates) { + try { + const p = (0, path_1.join)(projectPath, rel); + if (!(0, fs_extra_1.existsSync)(p)) + continue; + const cfg = (0, fs_extra_1.readJsonSync)(p); + const d = cfg && cfg.general && cfg.general.designResolution; + if (d && Number(d.width) > 0 && Number(d.height) > 0) { + return { designResolution: { width: Number(d.width), height: Number(d.height) } }; + } + } + catch (_d) { + // 忽略解析失败,尝试下一个候选文件 + } + } + } + return { designResolution: { width: 960, height: 640 } }; + }, + /** + * 面板向游戏侧桥接脚本广播一条 fire-and-forget 命令。 + * args: { cmd: string, payload?: any } + */ + sendCommand(args) { + if (server) { + server.broadcast({ cmd: args === null || args === void 0 ? void 0 : args.cmd, payload: args === null || args === void 0 ? void 0 : args.payload }); + } + return getServerState(); + }, + /** + * 面板请求游戏侧数据:向游戏发带 requestId 的命令并等待回包。 + * args: { cmd: string, payload?: any, timeout?: number } + */ + async queryCommand(args) { + var _a; + const r = await callGame(args === null || args === void 0 ? void 0 : args.cmd, args === null || args === void 0 ? void 0 : args.payload, (_a = args === null || args === void 0 ? void 0 : args.timeout) !== null && _a !== void 0 ? _a : 5000); + return r; + }, + /** + * 取回自上次查询以来收到的消息(游戏 → 面板)。按游标增量读取,不破坏缓冲。 + */ + queryLog() { + const batch = logBuffer.slice(logCursor); + logCursor = logBuffer.length; + return batch; + }, + /** + * 读取最近日志(不清空缓冲),供 MCP/AI Agent 使用。 + * args: { limit?: number, level?: 'all'|'log'|'warn'|'error' } + */ + getLogs(args) { + const limit = Math.max(1, Math.min(200, Number(args === null || args === void 0 ? void 0 : args.limit) || 50)); + const level = (args === null || args === void 0 ? void 0 : args.level) === 'log' || (args === null || args === void 0 ? void 0 : args.level) === 'warn' || (args === null || args === void 0 ? void 0 : args.level) === 'error' ? args.level : ''; + return getLogsInternal(limit, level); + }, + /** + * 启动 MCP 服务(HTTP Streamable,供 Codex 等 AI Agent 连接)。 + */ + async startMcp(port = mcp_server_1.MCP_DEFAULT_PORT) { + if (!mcpHost) { + mcpHost = new mcp_server_1.McpHttpServer(); + } + try { + if (!mcpHost.isRunning) { + const token = serverToken; + await mcpHost.start(port, token, { + callGame, + getServerState, + getToken: () => serverToken, + getLogs: (l, lv) => getLogsInternal(l, lv), + }); + pushLog({ evt: 'sys', msg: `MCP 服务已启动: http://127.0.0.1:${mcpHost.boundPort}/mcp` }); + } + } + catch (err) { + pushLog({ evt: 'sys', msg: `MCP 服务启动失败: ${String(err)}` }); + } + return getMcpState(); + }, + /** + * 停止 MCP 服务。 + */ + async stopMcp() { + if (mcpHost) { + await mcpHost.stop(); + pushLog({ evt: 'sys', msg: 'MCP 服务已停止' }); + } + return getMcpState(); + }, + /** + * 返回 MCP 服务状态与连接配置(URL + 令牌)。 + */ + getMcpState() { + return getMcpState(); + }, + /** + * 把游戏侧桥接脚本 RuntimeBridge.ts 自动安装到当前项目的 assets 目录。 + */ + async installBridge() { + var _a; + const projectPath = (_a = Editor.Project) === null || _a === void 0 ? void 0 : _a.path; + if (!projectPath) { + return { ok: false, msg: '无法获取项目路径(Editor.Project.path 为空)' }; + } + const src = (0, path_1.join)(__dirname, '../runtime-bridge-sample/RuntimeBridge.ts'); + const assetsDir = (0, path_1.join)(projectPath, 'assets'); + if (!(0, fs_extra_1.existsSync)(src)) { + return { ok: false, msg: `未找到桥接脚本模板: ${src}` }; + } + if (!(0, fs_extra_1.existsSync)(assetsDir)) { + return { ok: false, msg: `找不到项目的 assets 目录: ${assetsDir}` }; + } + const dest = (0, path_1.join)(assetsDir, 'RuntimeBridge.ts'); + const overwrote = (0, fs_extra_1.existsSync)(dest); + const currentToken = serverToken; + // 保留用户自定义 host/port(如真机调试时改为电脑 IP),避免每次覆盖被重置。 + // 优先取场景中已存在常驻节点组件的现值(用户最近可能直接在节点上配置), + // 其次取已安装脚本文件里的默认值。 + let keepHost = ''; + let keepPort = 0; + if (overwrote) { + try { + const oldContent = (0, fs_extra_1.readFileSync)(dest, 'utf-8'); + const hm = /host\s*=\s*'([^']*)'/.exec(oldContent); + const pm = /port\s*=\s*(\d+)/.exec(oldContent); + if (hm) { + keepHost = hm[1]; + } + if (pm) { + keepPort = Number(pm[1]); + } + } + catch (_b) { + /* 读取失败则用模板默认值 */ + } + } + // 解析桥接脚本组件 uuid,用于在场景文件中定位已存在的 RuntimeBridge 组件 + let compUuid = ''; + const metaPath = dest + '.meta'; + try { + if ((0, fs_extra_1.existsSync)(metaPath)) { + const meta = (0, fs_extra_1.readJsonSync)(metaPath); + compUuid = (meta && meta.uuid) || ''; + } + } + catch (_c) { + /* 忽略 meta 读取失败 */ + } + let sceneFiles = []; + if (compUuid) { + try { + collectSceneFiles(assetsDir, sceneFiles); + // 第一遍:以已存在常驻节点组件上的 host/port 为准(用户配置),覆盖脚本旧值 + for (const sp of sceneFiles) { + try { + const sj = (0, fs_extra_1.readJsonSync)(sp); + walkSceneComponents(sj, compUuid, (comp) => { + if (typeof comp.host === 'string' && comp.host) { + keepHost = comp.host; + } + if (typeof comp.port === 'number' && comp.port > 0) { + keepPort = comp.port; + } + }); + } + catch (_d) { + /* 单个场景解析失败跳过 */ + } + } + } + catch (_e) { + /* 扫描失败则跳过场景同步 */ + } + } + // 桥接脚本内置固定令牌 www.yyka.cn,无需注入; + // 仅把 BRIDGE_VERSION 同步为插件版本号,避免面板显示过时版本 + const srcContent = (0, fs_extra_1.readFileSync)(src, 'utf-8'); + let injected = srcContent.replace(/BRIDGE_VERSION = '[^']*'/, `BRIDGE_VERSION = '${package_json_1.default.version}'`); + // 默认连接地址:用户配置过 host 则保留(如真机调试时自定义的电脑 IP); + // 否则自动注入宿主机局域网 IP —— 固定 127.0.0.1 时真机/模拟器连的是设备自身回环,无法接通插件服务 + const lanIP = getHostLanIP(); + if (keepHost) { + injected = injected.replace('host = DEFAULT_HOST;', `host = '${keepHost}';`); + } + else if (lanIP) { + injected = injected.replace('host = DEFAULT_HOST;', `host = '${lanIP}';`); + } + if (keepPort) { + injected = injected.replace('port = DEFAULT_PORT;', `port = ${keepPort};`); + } + (0, fs_extra_1.writeFileSync)(dest, injected, 'utf-8'); + try { + await Editor.Message.request('asset-db', 'refresh-asset', dest); + } + catch (err) { + console.warn('[yyka-runtime-inspector] refresh-asset failed:', err); + } + // 第二遍:把已存在常驻节点的 host/port 同步为最新配置; + // token 已改为脚本内置常量,顺带清掉旧版本场景里残留的 token 字段,避免误导 + if (compUuid) { + for (const sp of sceneFiles) { + try { + const sj = (0, fs_extra_1.readJsonSync)(sp); + let changed = false; + walkSceneComponents(sj, compUuid, (comp) => { + if (keepHost) { + comp.host = keepHost; + } + if (keepPort) { + comp.port = keepPort; + } + if (typeof comp.token !== 'undefined') { + delete comp.token; + changed = true; + } + if (keepHost || keepPort) { + changed = true; + } + }); + if (changed) { + (0, fs_extra_1.writeJsonSync)(sp, sj, { spaces: 2 }); + console.log(`[yyka-runtime-inspector] 已同步常驻节点属性: ${sp}`); + try { + await Editor.Message.request('asset-db', 'refresh-asset', sp); + } + catch (_f) { + /* ignore */ + } + } + } + catch (_g) { + /* 单个场景同步失败跳过 */ + } + } + } + return { ok: true, path: dest, overwrote, token: currentToken, scenes: sceneFiles.length }; + }, + /** + * 通知游戏侧高亮/遮罩指定节点。id 为空串则清除。 + */ + async highlightNode(id, mode = 'highlight') { + try { + const res = await callGame('highlight', { id: id || '', mode: mode === 'mask' ? 'mask' : 'highlight' }, 3000); + return res; + } + catch (err) { + return { error: String(err) }; + } + }, +}; +/** + * @zh 扩展启动时自动拉起 WS 服务,便于游戏侧随时连接。 + */ +function load() { + console.log('[yyka-runtime-inspector] load, starting ws server...'); + // 令牌为固定静态值,服务启动时自动带上鉴权 + exports.methods.startServer(); + // 每次打开插件自动安装最新桥接脚本(保留用户自定义 host/port),保证游戏侧脚本与插件版本同步 + exports.methods.installBridge().then((res) => { + if (res && res.ok) { + pushLog({ evt: 'sys', msg: `桥接脚本${res.overwrote ? '已更新' : '已安装'}: ${res.path}` }); + } + else if (res && res.msg) { + console.warn('[yyka-runtime-inspector] auto installBridge skipped:', res.msg); + } + }).catch((err) => { + console.warn('[yyka-runtime-inspector] auto installBridge failed:', err); + }); +} +/** + * @zh 卸载扩展时关闭 WS 服务。 + */ +function unload() { + if (server) { + server.stop(); + server = null; + } + if (mcpHost) { + mcpHost.stop(); + mcpHost = null; + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NvdXJjZS9tYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQWdsQkEsb0JBY0M7QUFLRCx3QkFTQztBQTVtQkQsYUFBYTtBQUNiLG1FQUEwQztBQUMxQyx1Q0FBNkc7QUFDN0csK0JBQTRCO0FBQzVCLDJCQUF1QztBQUN2QywyQ0FBdUM7QUFDdkMsNkNBQStEO0FBRS9ELE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQztBQUUzQix3Q0FBd0M7QUFDeEMsTUFBTSxZQUFZLEdBQUcsYUFBYSxDQUFDO0FBRW5DLElBQUksTUFBTSxHQUFvQixJQUFJLENBQUM7QUFDbkMsSUFBSSxTQUFTLEdBQWMsRUFBRSxDQUFDO0FBQzlCLDhEQUE4RDtBQUM5RCxJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUM7QUFDbEIsTUFBTSxXQUFXLEdBQUcsWUFBWSxDQUFDO0FBQ2pDLElBQUksT0FBTyxHQUF5QixJQUFJLENBQUM7QUFRekMsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQXNCLENBQUM7QUFDOUMsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDO0FBRW5CLFNBQVMsWUFBWTtJQUNqQixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDVixNQUFNLEdBQUcsSUFBSSxvQkFBUSxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2xCLENBQUM7QUFFRCxTQUFTLGNBQWM7O0lBQ25CLE1BQU0sSUFBSSxHQUFHLE1BQUEsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLFVBQVUsbUNBQUksSUFBSSxDQUFDO0lBQ3hDLE9BQU87UUFDSCxPQUFPLEVBQUUsTUFBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsU0FBUyxtQ0FBSSxLQUFLO1FBQ25DLElBQUksRUFBRSxNQUFBLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxTQUFTLG1DQUFJLENB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QUMsS0FBSyxDQUFDLENBQUMsR0FBWSxFQUFFLEVBQUU7UUFDdEIsT0FBTyxDQUFDLElBQUksQ0FBQyxxREFBcUQsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUM3RSxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLE1BQU07SUFDbEIsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUNULE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNkLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDbEIsQ0FBQztJQUNELElBQUksT0FBTyxFQUFFLENBQUM7UUFDVixPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDZixPQUFPLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWlnbm9yZVxuaW1wb3J0IHBhY2thZ2VKU09OIGZyb20gJy4uL3BhY2thZ2UuanNvbic7XG5pbXBvcnQgeyBleGlzdHNTeW5jLCByZWFkRmlsZVN5bmMsIHJlYWRKc29uU3luYywgcmVhZGRpclN5bmMsIHdyaXRlRmlsZVN5bmMsIHdyaXRlSnNvblN5bmMgfSBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBuZXR3b3JrSW50ZXJmYWNlcyB9IGZyb20gJ29zJztcbmltcG9ydCB7IFdzU2VydmVyIH0gZnJvbSAnLi93cy1zZXJ2ZXInO1xuaW1wb3J0IHsgTWNwSHR0cFNlcnZlciwgTUNQX0RFRkFVTFRfUE9SVCB9IGZyb20gJy4vbWNwLXNlcnZlcic7XG5cbmNvbnN0IERFRkFVTFRfUE9SVCA9IDMzMDAwO1xuXG4vKiog5Zu65a6a6Z2Z5oCB6L+e5o6l5Luk54mM77ya5LiN5YGa5Yqo5oCB55Sf5oiQ77yM5L+d6K+B6ISa5pysL+iKgueCueS7pOeJjOS4juaPkuS7tuWni+e7iOS4gOiHtOOAgiAqL1xuY29uc3QgU1RBVElDX1RPS0VOID0gJ3d3dy55eWthLmNuJztcblxubGV0IHNlcnZlcjogV3NTZXJ2ZXIgfCBudWxsID0gbnVsbDtcbmxldCBsb2dCdWZmZXI6IHVua25vd25bXSA9IFtdO1xuLyoqIOmdouadv+W3sua2iOi0ueWIsOeahOe8k+WGsuS9jee9ru+8mnF1ZXJ5TG9nIOaUueS4uuWinumHj+WPlui1sOiAjOmdnua4heepuu+8jOmBv+WFjemlv+atuyBNQ1Ag55qE6Z2e56C05Z2P5oCnIGdldExvZ3PjgIIgKi9cbmxldCBsb2dDdXJzb3IgPSAwO1xuY29uc3Qgc2VydmVyVG9rZW4gPSBTVEFUSUNfVE9LRU47XG5sZXQgbWNwSG9zdDogTWNwSHR0cFNlcnZlciB8IG51bGwgPSBudWxsO1xuXG4vLyDor7fmsYIv5ZON5bqU77ya6Z2i5p2/5Y+R5Ye65bimIHJlcXVlc3RJZCDnmoTlkb3ku6TvvIznrYnmuLjmiI/kvqfmoaXmjqXohJrmnKzlm57ljIXlkI4gcmVzb2x2ZeOAglxuaW50ZXJmYWNlIFBlbmRpbmdSZXEge1xuICAgIHJlc29sdmU6ICh2OiBhbnkpID0+IHZvaWQ7XG4gICAgcmVqZWN0OiAoZTogRXJyb3IpID0+IHZvaWQ7XG4gICAgdGltZXI6IGFueTtcbn1cbmNvbnN0IHBlbmRpbmcgPSBuZXcgTWFwPG51bWJlciwgUGVuZGluZ1JlcT4oKTtcbmxldCByZXF1ZXN0U2VxID0gMDtcblxuZnVuY3Rpb24gZW5zdXJlU2VydmVyKCk6IFdzU2VydmVyIHtcbiAgICBpZiAoIXNlcnZlcikge1xuICAgICAgICBzZXJ2ZXIgPSBuZXcgV3NTZXJ2ZXIoKTtcbiAgICB9XG4gICAgcmV0dXJuIHNlcnZlcjtcbn1cblxuZnVuY3Rpb24gZ2V0U2VydmVyU3RhdGUoKSB7XG4gICAgY29uc3QgaW5mbyA9IHNlcnZlcj8uY2xpZW50SW5mbyA/PyBudWxsO1xuICAgIHJldHVybiB7XG4gICAgICAgIHJ1bm5pbmc6IHNlcnZlcj8uaXNSdW5uaW5nID8/IGZhbHNlLFxuICAgICAgICBwb3J0OiBzZXJ2ZXI/LmJvdW5kUG9ydCA/PyAwLFxuICAgICAgICBjbGllbnRzOiBzZXJ2ZXI/LmNsaWVudHMgPz8gMCxcbiAgICAgICAgY2xpZW50VHlwZTogaW5mbz8udHlwZSA/PyAnJyxcbiAgICAgICAgY2xpZW50VXJsOiBpbmZvPy51cmwgPz8gJycsXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gcHVzaExvZyhpdGVtOiB1bmtub3duKSB7XG4gICAgbG9nQnVmZmVyLnB1c2goaXRlbSk7XG4gICAgd2hpbGUgKGxvZ0J1ZmZlci5sZW5ndGggPiAyMDApIHtcbiAgICAgICAgbG9nQnVmZmVyLnNoaWZ0KCk7XG4gICAgICAgIGlmIChsb2dDdXJzb3IgPiAwKSB7XG4gICAgICAgICAgICBsb2dDdXJzb3ItLTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqIOWuouaIt+err+exu+WeiyDihpIg5Lit5paH5qCH562+77yI5pel5b+X55So77yJ44CCICovXG5mdW5jdGlvbiB0eXBlTGFiZWwodHlwZT86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgIGNhc2UgJ2g1JzpcbiAgICAgICAgICAgIHJldHVybiAn5rWP6KeI5Zmo6aKE6KeIJztcbiAgICAgICAgY2FzZSAnZWRpdG9yJzpcbiAgICAgICAgICAgIHJldHVybiAn57yW6L6R5Zmo6aKE6KeIJztcbiAgICAgICAgY2FzZSAnc2ltdWxhdG9yJzpcbiAgICAgICAgICAgIHJldHVybiAn5qih5ouf5ZmoJztcbiAgICAgICAgY2FzZSAnZGV2aWNlJzpcbiAgICAgICAgICAgIHJldHVybiAn55yf5py6JztcbiAgICAgICAgY2FzZSAndW5rbm93bic6XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gJ+acquefpeadpea6kCc7XG4gICAgfVxufVxuXG4vKiog5LuO6aG555uuIHNldHRpbmdzIOS4remAkuW9kuafpeaJvuaVsOWAvOerr+WPo+OAgiAqL1xuZnVuY3Rpb24gZmluZE51bWVyaWNQb3J0KGNmZzogYW55KTogbnVtYmVyIHtcbiAgICBpZiAoIWNmZyB8fCB0eXBlb2YgY2ZnICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBjZmcucG9ydCA9PT0gJ251bWJlcicgJiYgY2ZnLnBvcnQgPiAwKSB7XG4gICAgICAgIHJldHVybiBjZmcucG9ydDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBjZmcucG9ydCA9PT0gJ3N0cmluZycgJiYgIU51bWJlci5pc05hTihOdW1iZXIoY2ZnLnBvcnQpKSkge1xuICAgICAgICByZXR1cm4gTnVtYmVyKGNmZy5wb3J0KTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBrIG9mIE9iamVjdC5rZXlzKGNmZykpIHtcbiAgICAgICAgY29uc3QgdiA9IGNmZ1trXTtcbiAgICAgICAgaWYgKHYgJiYgdHlwZW9mIHYgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBjb25zdCBwID0gZmluZE51bWVyaWNQb3J0KHYpO1xuICAgICAgICAgICAgaWYgKHAgPiAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIDA7XG59XG5cbi8qKlxuICog6K+75Y+W5b2T5YmN6aG555uu55qE6aKE6KeI6YWN572u77yM5b6X5Ye65rWP6KeI5Zmo6aKE5riv5Y+jL1VSTOOAglxuICog55So5LqO6Z2i5p2/5YaF5bWMIGlmcmFtZSDpooTop4jnmoTpu5jorqTlnLDlnYDjgIJcbiAqL1xuZnVuY3Rpb24gZ2V0UHJldmlld0luZm8oKTogeyBob3N0OiBzdHJpbmc7IHBvcnQ6IG51bWJlcjsgdXJsOiBzdHJpbmc7IGZvdW5kOiBzdHJpbmcgfSB7XG4gICAgY29uc3QgcHJvamVjdFBhdGggPSAoRWRpdG9yIGFzIGFueSkuUHJvamVjdD8ucGF0aDtcbiAgICBjb25zdCBjYW5kaWRhdGVzID0gWydzZXR0aW5ncy9wcmV2aWV3Lmpzb24nLCAnc2V0dGluZ3MvdjIvcGFja2FnZXMvcHJldmlldy5qc29uJ107XG4gICAgaWYgKHByb2plY3RQYXRoKSB7XG4gICAgICAgIGZvciAoY29uc3QgcmVsIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcCA9IGpvaW4ocHJvamVjdFBhdGgsIHJlbCk7XG4gICAgICAgICAgICAgICAgaWYgKCFleGlzdHNTeW5jKHApKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBjZmcgPSByZWFkSnNvblN5bmMocCk7XG4gICAgICAgICAgICAgICAgY29uc3QgcG9ydCA9IGZpbmROdW1lcmljUG9ydChjZmcpO1xuICAgICAgICAgICAgICAgIGlmIChwb3J0ID4gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBob3N0OiAnbG9jYWxob3N0JywgcG9ydCwgdXJsOiBgaHR0cDovL2xvY2FsaG9zdDoke3BvcnR9L2AsIGZvdW5kOiBwIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgLy8g5b+955Wl6Kej5p6Q5aSx6LSl77yM5bCd6K+V5LiL5LiA5Liq5YCZ6YCJ5paH5Lu2XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgaG9zdDogJ2xvY2FsaG9zdCcsIHBvcnQ6IDc0NTYsIHVybDogJ2h0dHA6Ly9sb2NhbGhvc3Q6NzQ1Ni8nLCBmb3VuZDogJycgfTtcbn1cblxuLyoqIOWkhOeQhuadpeiHqua4uOaIj+S+p+eahOa2iOaBr++8muS8mOWFiOWMuemFjSBwZW5kaW5nIOivt+axgu+8jOWQpuWImei/m+WFpeaXpeW/l+e8k+WGsuOAgiAqL1xuZnVuY3Rpb24gaGFuZGxlSW5jb21pbmcoZGF0YTogdW5rbm93bikge1xuICAgIGNvbnN0IG0gPSBkYXRhICYmIHR5cGVvZiBkYXRhID09PSAnb2JqZWN0JyA/IChkYXRhIGFzIGFueSkgOiBudWxsO1xuICAgIGlmIChtICYmIHR5cGVvZiBtLnJlcXVlc3RJZCA9PT0gJ251bWJlcicgJiYgcGVuZGluZy5oYXMobS5yZXF1ZXN0SWQpKSB7XG4gICAgICAgIGNvbnN0IHAgPSBwZW5kaW5nLmdldChtLnJlcXVlc3RJZCkhO1xuICAgICAgICBwZW5kaW5nLmRlbGV0ZShtLnJlcXVlc3RJZCk7XG4gICAgICAgIGlmIChwLnRpbWVyKSBjbGVhclRpbWVvdXQocC50aW1lcik7XG4gICAgICAgIHAucmVzb2x2ZShtLmRhdGEgPz8gbSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8g5ZG95Luk5Zue5YyFL+aPoeaJi+etieWGhemDqOWNj+iurua2iOaBr+S4jei/m+WFpeaXpeW/l++8jOmBv+WFjSByZXF1ZXN0SWQvcmVzcG9uc2UvaGVsbG8g5Yi35bGPXG4gICAgaWYgKG0gJiYgKG0uZXZ0ID09PSAncmVzcG9uc2UnIHx8IG0uZXZ0ID09PSAncmVxdWVzdCcgfHwgbS5ldnQgPT09ICdoZWxsbycpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcHVzaExvZyhkYXRhKTtcbn1cblxuLyoqIOaMiemZkOWItuadoeaVsOS4jue6p+WIq+ivu+WPluacgOi/keaXpeW/l++8iOS4jea4heepuue8k+WGsu+8jOS+m+mdouadvy9NQ1Ag5L2/55So77yJ44CCICovXG5mdW5jdGlvbiBnZXRMb2dzSW50ZXJuYWwobGltaXQ6IG51bWJlciwgbGV2ZWw6IHN0cmluZyk6IHVua25vd25bXSB7XG4gICAgY29uc3QgaXRlbXM6IHVua25vd25bXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSBsb2dCdWZmZXIubGVuZ3RoIC0gMTsgaSA+PSAwICYmIGl0ZW1zLmxlbmd0aCA8IGxpbWl0OyBpLS0pIHtcbiAgICAgICAgY29uc3QgaXQ6IGFueSA9IGxvZ0J1ZmZlcltpXTtcbiAgICAgICAgaWYgKCFpdCB8fCB0eXBlb2YgaXQgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyDov4fmu6Tmjonlv4Pot7Mv5o+h5omLL+mihOiniOW4p+etieWZquWjsO+8jOWPquS/neeVmeaOp+WItuWPsOS4juezu+e7n+a2iOaBr1xuICAgICAgICBpZiAoaXQuZXZ0ICE9PSAnY29uc29sZScgJiYgaXQuZXZ0ICE9PSAnc3lzJykge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxldmVsICYmIGl0LmV2dCA9PT0gJ2NvbnNvbGUnICYmIGl0LmxldmVsICE9PSBsZXZlbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaXRlbXMudW5zaGlmdChpdCk7XG4gICAgfVxuICAgIHJldHVybiBpdGVtcztcbn1cblxuLyoqIOi/lOWbniBNQ1Ag5pyN5Yqh54q25oCB5LiO6L+e5o6l6YWN572u77yIVVJMICsg5Luk54mM77yJ44CCICovXG5mdW5jdGlvbiBnZXRNY3BTdGF0ZSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBydW5uaW5nOiBtY3BIb3N0Py5pc1J1bm5pbmcgPz8gZmFsc2UsXG4gICAgICAgIHBvcnQ6IG1jcEhvc3Q/LmJvdW5kUG9ydCA/PyAwLFxuICAgICAgICB0b2tlbjogc2VydmVyVG9rZW4sXG4gICAgICAgIHVybDogbWNwSG9zdD8uaXNSdW5uaW5nID8gYGh0dHA6Ly8xMjcuMC4wLjE6JHttY3BIb3N0LmJvdW5kUG9ydH0vbWNwYCA6ICcnLFxuICAgIH07XG59XG5cbi8qKiDlkJHmuLjmiI/kvqfmoaXmjqXohJrmnKzlj5HpgIHkuIDmnaHor7fmsYLvvIzlubbnrYnlvoXlhbblm57ljIXjgIIgKi9cbmZ1bmN0aW9uIGNhbGxHYW1lKGNtZDogc3RyaW5nLCBwYXlsb2FkPzogdW5rbm93biwgdGltZW91dCA9IDUwMDApOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGlmICghc2VydmVyIHx8ICFzZXJ2ZXIuaXNSdW5uaW5nKSB7XG4gICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdXUyDmnI3liqHmnKrov5DooYzvvIzor7flhYjlkK/liqjmnI3liqEnKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVxdWVzdElkID0gKytyZXF1ZXN0U2VxO1xuICAgICAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHBlbmRpbmcuaGFzKHJlcXVlc3RJZCkpIHtcbiAgICAgICAgICAgICAgICBwZW5kaW5nLmRlbGV0ZShyZXF1ZXN0SWQpO1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYOWRveS7pOi2heaXtig+JHt0aW1lb3V0fW1zKTogJHtjbWR9YCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgcGVuZGluZy5zZXQocmVxdWVzdElkLCB7IHJlc29sdmUsIHJlamVjdCwgdGltZXIgfSk7XG4gICAgICAgIHNlcnZlci5icm9hZGNhc3QoeyByZXF1ZXN0SWQsIGNtZCwgcGF5bG9hZCB9KTtcbiAgICB9KTtcbn1cblxuLyoqIOiOt+WPluWuv+S4u+acuuesrOS4gOS4qumdnuWGhee9kSBJUHY0IOWcsOWdgO+8iOeUqOS6juazqOWFpeahpeaOpeiEmuacrO+8jOS+m+aooeaLn+WZqC/nnJ/mnLrpgJrov4flsYDln5/nvZHov57kuIrmj5Lku7bmnI3liqHvvInjgIIgKi9cbmZ1bmN0aW9uIGdldEhvc3RMYW5JUCgpOiBzdHJpbmcge1xuICAgIC8vIOS8mOWFiOi/lOWbnuWGhee9keengeacieauteWcsOWdgO+8iFdpLUZpL+aciee6v+e9keWNoe+8ie+8jOmBv+WFjemAieWIsOiZmuaLn+acuuaIliBWUE4g6Jma5ouf572R5Y2h5a+86Ie055yf5py66L+e5LiN6YCaXG4gICAgbGV0IGZhbGxiYWNrID0gJyc7XG4gICAgdHJ5IHtcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKG5ldHdvcmtJbnRlcmZhY2VzKCkpKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5ldCBvZiBuZXR3b3JrSW50ZXJmYWNlcygpW25hbWVdID8/IFtdKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5ldC5mYW1pbHkgPT09ICdJUHY0JyAmJiAhbmV0LmludGVybmFsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGEgPSBuZXQuYWRkcmVzcy5zcGxpdCgnLicpLm1hcChOdW1iZXIpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpc1ByaXZhdGUgPVxuICAgICAgICAgICAgICAgICAgICAgICAgYVswXSA9PT0gMTAgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIChhWzBdID09PSAxNzIgJiYgYVsxXSA+PSAxNiAmJiBhWzFdIDw9IDMxKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgKGFbMF0gPT09IDE5MiAmJiBhWzFdID09PSAxNjgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNQcml2YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV0LmFkZHJlc3M7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFmYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmFsbGJhY2sgPSBuZXQuYWRkcmVzcztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgICAvKiBpZ25vcmUgKi9cbiAgICB9XG4gICAgcmV0dXJuIGZhbGxiYWNrO1xufVxuXG4vKipcbiAqIEB6aCDkuLrmianlsZXnmoTkuLvov5vnqIvnmoTms6jlhozmlrnms5VcbiAqL1xuLyoqIOaUtumbhuebruW9leS4i+aJgOaciSAuc2NlbmUg5paH5Lu244CCICovXG5mdW5jdGlvbiBjb2xsZWN0U2NlbmVGaWxlcyhkaXI6IHN0cmluZywgb3V0OiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGxldCBlbnRyaWVzO1xuICAgIHRyeSB7XG4gICAgICAgIGVudHJpZXMgPSByZWFkZGlyU3luYyhkaXIsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGUgb2YgZW50cmllcykge1xuICAgICAgICBjb25zdCBwID0gam9pbihkaXIsIGUubmFtZSk7XG4gICAgICAgIGlmIChlLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgICAgIGNvbGxlY3RTY2VuZUZpbGVzKHAsIG91dCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZS5pc0ZpbGUoKSAmJiBlLm5hbWUuZW5kc1dpdGgoJy5zY2VuZScpKSB7XG4gICAgICAgICAgICBvdXQucHVzaChwKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqIOmBjeWOhuWcuuaZryBKU09OIOS4reeahOiKgueCueagke+8jOWvueWMuemFjeaMh+WumuiEmuacrCB1dWlkIOeahOe7hOS7tuaJp+ihjOWbnuiwg+OAgiAqL1xuZnVuY3Rpb24gd2Fsa1NjZW5lQ29tcG9uZW50cyhzY2VuZUpzb246IGFueSwgY29tcFV1aWQ6IHN0cmluZywgY2I6IChjb21wOiBhbnkpID0+IHZvaWQpOiB2b2lkIHtcbiAgICBjb25zdCB3YWxrTm9kZSA9IChub2RlOiBhbnkpID0+IHtcbiAgICAgICAgaWYgKCFub2RlIHx8IHR5cGVvZiBub2RlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub2RlLl9fdHlwZV9fID09PSAnY2MuTm9kZScpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgYyBvZiBub2RlLl9jb21wb25lbnRzIHx8IFtdKSB7XG4gICAgICAgICAgICAgICAgaWYgKGMgJiYgYy5fX3R5cGVfXyA9PT0gY29tcFV1aWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY2IoYyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBjaCBvZiBub2RlLl9jaGlsZHJlbiB8fCBbXSkge1xuICAgICAgICAgICAgICAgIHdhbGtOb2RlKGNoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgd2Fsa05vZGUoc2NlbmVKc29uICYmIHNjZW5lSnNvbi5zY2VuZSk7XG59XG5cbmV4cG9ydCBjb25zdCBtZXRob2RzOiB7IFtrZXk6IHN0cmluZ106ICguLi5hbnk6IGFueSkgPT4gYW55IH0gPSB7XG4gICAgb3BlblBhbmVsKCkge1xuICAgICAgICBFZGl0b3IuUGFuZWwub3BlbihwYWNrYWdlSlNPTi5uYW1lKTtcbiAgICB9LFxuXG4gICAgb3BlblByZXZpZXdQYW5lbCgpIHtcbiAgICAgICAgRWRpdG9yLlBhbmVsLm9wZW4oYCR7cGFja2FnZUpTT04ubmFtZX0ucHJldmlld2ApO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiDlkK/liqggV1Mg5pyN5Yqh44CC6L+U5Zue5b2T5YmN5pyN5Yqh54q25oCB44CCXG4gICAgICovXG4gICAgYXN5bmMgc3RhcnRTZXJ2ZXIocG9ydDogbnVtYmVyID0gREVGQVVMVF9QT1JUKSB7XG4gICAgICAgIGNvbnN0IHdzID0gZW5zdXJlU2VydmVyKCk7XG4gICAgICAgIHdzLnRva2VuID0gc2VydmVyVG9rZW47XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIXdzLmlzUnVubmluZykge1xuICAgICAgICAgICAgICAgIHdzLm9uKCdtZXNzYWdlJywgKF9jbGllbnQsIGRhdGEpID0+IGhhbmRsZUluY29taW5nKGRhdGEpKTtcbiAgICAgICAgICAgICAgICB3cy5vbignY29ubmVjdGlvbicsIChfY2xpZW50LCBpbmZvKSA9PiBwdXNoTG9nKHsgZXZ0OiAnc3lzJywgbXNnOiBg5a6i5oi356uv5bey6L+e5o6lICgke3R5cGVMYWJlbChpbmZvPy50eXBlKX0pYCB9KSk7XG4gICAgICAgICAgICAgICAgd3Mub24oJ2Rpc2Nvbm5lY3QnLCAoX2NsaWVudCwgaW5mbykgPT4gcHVzaExvZyh7IGV2dDogJ3N5cycsIG1zZzogYOWuouaIt+err+W3suaWreW8gCAoJHt0eXBlTGFiZWwoaW5mbz8udHlwZSl9KWAgfSkpO1xuICAgICAgICAgICAgICAgIHdzLm9uKCdhdXRoLWZhaWwnLCAoZ290OiBzdHJpbmcsIHVybDogc3RyaW5nKSA9PlxuICAgICAgICAgICAgICAgICAgICBwdXNoTG9nKHsgZXZ0OiAnc3lzJywgbXNnOiBg6L+e5o6l6KKr5ouS57ud77ya5a6i5oi356uv5Luk54mMKCR7Z290fSkg4omgIOacjeWKoeerr+S7pOeJjCgke3NlcnZlclRva2VufSlgIH0pKTtcbiAgICAgICAgICAgICAgICBhd2FpdCB3cy5zdGFydChwb3J0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBwdXNoTG9nKHsgZXZ0OiAnc3lzJywgbXNnOiBg5ZCv5Yqo5pyN5Yqh5aSx6LSlOiAke1N0cmluZyhlcnIpfWAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGdldFNlcnZlclN0YXRlKCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIOWBnOatoiBXUyDmnI3liqHjgILov5Tlm57lvZPliY3mnI3liqHnirbmgIHjgIJcbiAgICAgKi9cbiAgICBhc3luYyBzdG9wU2VydmVyKCkge1xuICAgICAgICBpZiAoc2VydmVyKSB7XG4gICAgICAgICAgICBhd2FpdCBzZXJ2ZXIuc3RvcCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnZXRTZXJ2ZXJTdGF0ZSgpO1xuICAgIH0sXG5cbiAgICBnZXRTZXJ2ZXJTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIGdldFNlcnZlclN0YXRlKCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIOi/lOWbnuWbuuWumui/nuaOpeS7pOeJjO+8iOmdmeaAgSB0b2tlbu+8ieOAglxuICAgICAqL1xuICAgIGdldFRva2VuKCkge1xuICAgICAgICByZXR1cm4gc2VydmVyVG9rZW47XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIOivu+WPluW9k+WJjemhueebrumihOiniOmFjee9ruW+l+WHuueahOmihOa4r+WPoy9VUkzvvIjkvpvpnaLmnb/lhoXltYwgaWZyYW1lIOeUqO+8ieOAglxuICAgICAqL1xuICAgIGdldFByZXZpZXdJbmZvKCkge1xuICAgICAgICByZXR1cm4gZ2V0UHJldmlld0luZm8oKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICog6K+75Y+W5b2T5YmN6aG555uu6K6+6K6h5YiG6L6o546H77yIUHJvamVjdCBTZXR0aW5ncyDihpIgZ2VuZXJhbC5kZXNpZ25SZXNvbHV0aW9u77yJ44CCXG4gICAgICog6aaW6YCJ57yW6L6R5Zmo5YaF572uIGBwcm9qZWN0L3F1ZXJ5LWNvbmZpZ2DvvIjlrp7ml7bor7vphY3nva7nvJPlrZjvvInvvIzlpJrmqKHlnZcv5oyJ6ZSu6YO96K+V5LiA6YGN77ybXG4gICAgICog5aSx6LSl5YaN6YCA5Zue5Yiw6K+7IHNldHRpbmdzL3YyL3BhY2thZ2VzL3Byb2plY3QuanNvbiDmlofku7bvvIzlhZzlupUgOTYww5c2NDDjgIJcbiAgICAgKi9cbiAgICBhc3luYyBnZXRQcm9qZWN0c1NldHRpbmdzKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgbW9kdWxlcyA9IFsnZ2VuZXJhbCcsICdlbmdpbmUnLCAncHJvamVjdCddO1xuICAgICAgICAgICAgZm9yIChjb25zdCBtb2Qgb2YgbW9kdWxlcykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGQgPSBhd2FpdCBFZGl0b3IuTWVzc2FnZS5yZXF1ZXN0KCdwcm9qZWN0JyBhcyBhbnksICdxdWVyeS1jb25maWcnIGFzIGFueSwgbW9kLCAnZGVzaWduUmVzb2x1dGlvbicpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZCAmJiBOdW1iZXIoZC53aWR0aCkgPiAwICYmIE51bWJlcihkLmhlaWdodCkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBkZXNpZ25SZXNvbHV0aW9uOiB7IHdpZHRoOiBOdW1iZXIoZC53aWR0aCksIGhlaWdodDogTnVtYmVyKGQuaGVpZ2h0KSB9IH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g6K+l5qih5Z2X5peg5q2k6YWN572u77yM5bCd6K+V5LiL5LiA5LiqXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIOe7p+e7rei1sOaWh+S7tuWFnOW6lVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb2plY3RQYXRoID0gKEVkaXRvciBhcyBhbnkpLlByb2plY3Q/LnBhdGg7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZXMgPSBbXG4gICAgICAgICAgICAnc2V0dGluZ3MvdjIvcGFja2FnZXMvcHJvamVjdC5qc29uJyxcbiAgICAgICAgICAgICdzZXR0aW5ncy9wcm9qZWN0Lmpzb24nLFxuICAgICAgICBdO1xuICAgICAgICBpZiAocHJvamVjdFBhdGgpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVsIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwID0gam9pbihwcm9qZWN0UGF0aCwgcmVsKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFleGlzdHNTeW5jKHApKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2ZnID0gcmVhZEpzb25TeW5jKHApO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkID0gY2ZnICYmIGNmZy5nZW5lcmFsICYmIGNmZy5nZW5lcmFsLmRlc2lnblJlc29sdXRpb247XG4gICAgICAgICAgICAgICAgICAgIGlmIChkICYmIE51bWJlcihkLndpZHRoKSA+IDAgJiYgTnVtYmVyKGQuaGVpZ2h0KSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IGRlc2lnblJlc29sdXRpb246IHsgd2lkdGg6IE51bWJlcihkLndpZHRoKSwgaGVpZ2h0OiBOdW1iZXIoZC5oZWlnaHQpIH0gfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgICAgICAvLyDlv73nlaXop6PmnpDlpLHotKXvvIzlsJ3or5XkuIvkuIDkuKrlgJnpgInmlofku7ZcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgZGVzaWduUmVzb2x1dGlvbjogeyB3aWR0aDogOTYwLCBoZWlnaHQ6IDY0MCB9IH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIOmdouadv+WQkea4uOaIj+S+p+ahpeaOpeiEmuacrOW5v+aSreS4gOadoSBmaXJlLWFuZC1mb3JnZXQg5ZG95Luk44CCXG4gICAgICogYXJnczogeyBjbWQ6IHN0cmluZywgcGF5bG9hZD86IGFueSB9XG4gICAgICovXG4gICAgc2VuZENvbW1hbmQoYXJnczogeyBjbWQ6IHN0cmluZzsgcGF5bG9hZD86IHVua25vd24gfSkge1xuICAgICAgICBpZiAoc2VydmVyKSB7XG4gICAgICAgICAgICBzZXJ2ZXIuYnJvYWRjYXN0KHsgY21kOiBhcmdzPy5jbWQsIHBheWxvYWQ6IGFyZ3M/LnBheWxvYWQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGdldFNlcnZlclN0YXRlKCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIOmdouadv+ivt+axgua4uOaIj+S+p+aVsOaNru+8muWQkea4uOaIj+WPkeW4piByZXF1ZXN0SWQg55qE5ZG95Luk5bm2562J5b6F5Zue5YyF44CCXG4gICAgICogYXJnczogeyBjbWQ6IHN0cmluZywgcGF5bG9hZD86IGFueSwgdGltZW91dD86IG51bWJlciB9XG4gICAgICovXG4gICAgYXN5bmMgcXVlcnlDb21tYW5kKGFyZ3M6IHsgY21kOiBzdHJpbmc7IHBheWxvYWQ/OiB1bmtub3duOyB0aW1lb3V0PzogbnVtYmVyIH0pIHtcbiAgICAgICAgY29uc3QgciA9IGF3YWl0IGNhbGxHYW1lKGFyZ3M/LmNtZCwgYXJncz8ucGF5bG9hZCwgYXJncz8udGltZW91dCA/PyA1MDAwKTtcbiAgICAgICAgcmV0dXJuIHI7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIOWPluWbnuiHquS4iuasoeafpeivouS7peadpeaUtuWIsOeahOa2iOaBr++8iOa4uOaIjyDihpIg6Z2i5p2/77yJ44CC5oyJ5ri45qCH5aKe6YeP6K+75Y+W77yM5LiN56C05Z2P57yT5Yay44CCXG4gICAgICovXG4gICAgcXVlcnlMb2coKSB7XG4gICAgICAgIGNvbnN0IGJhdGNoID0gbG9nQnVmZmVyLnNsaWNlKGxvZ0N1cnNvcik7XG4gICAgICAgIGxvZ0N1cnNvciA9IGxvZ0J1ZmZlci5sZW5ndGg7XG4gICAgICAgIHJldHVybiBiYXRjaDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICog6K+75Y+W5pyA6L+R5pel5b+X77yI5LiN5riF56m657yT5Yay77yJ77yM5L6bIE1DUC9BSSBBZ2VudCDkvb/nlKjjgIJcbiAgICAgKiBhcmdzOiB7IGxpbWl0PzogbnVtYmVyLCBsZXZlbD86ICdhbGwnfCdsb2cnfCd3YXJuJ3wnZXJyb3InIH1cbiAgICAgKi9cbiAgICBnZXRMb2dzKGFyZ3M6IHsgbGltaXQ/OiBudW1iZXI7IGxldmVsPzogc3RyaW5nIH0pIHtcbiAgICAgICAgY29uc3QgbGltaXQgPSBNYXRoLm1heCgxLCBNYXRoLm1pbigyMDAsIE51bWJlcihhcmdzPy5saW1pdCkgfHwgNTApKTtcbiAgICAgICAgY29uc3QgbGV2ZWwgPSBhcmdzPy5sZXZlbCA9PT0gJ2xvZycgfHwgYXJncz8ubGV2ZWwgPT09ICd3YXJuJyB8fCBhcmdzPy5sZXZlbCA9PT0gJ2Vycm9yJyA/IGFyZ3MubGV2ZWwgOiAnJztcbiAgICAgICAgcmV0dXJuIGdldExvZ3NJbnRlcm5hbChsaW1pdCwgbGV2ZWwpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiDlkK/liqggTUNQIOacjeWKoe+8iEhUVFAgU3RyZWFtYWJsZe+8jOS+myBDb2RleCDnrYkgQUkgQWdlbnQg6L+e5o6l77yJ44CCXG4gICAgICovXG4gICAgYXN5bmMgc3RhcnRNY3AocG9ydDogbnVtYmVyID0gTUNQX0RFRkFVTFRfUE9SVCkge1xuICAgICAgICBpZiAoIW1jcEhvc3QpIHtcbiAgICAgICAgICAgIG1jcEhvc3QgPSBuZXcgTWNwSHR0cFNlcnZlcigpO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIW1jcEhvc3QuaXNSdW5uaW5nKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9rZW4gPSBzZXJ2ZXJUb2tlbjtcbiAgICAgICAgICAgICAgICBhd2FpdCBtY3BIb3N0LnN0YXJ0KHBvcnQsIHRva2VuLCB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxHYW1lLFxuICAgICAgICAgICAgICAgICAgICBnZXRTZXJ2ZXJTdGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgZ2V0VG9rZW46ICgpID0+IHNlcnZlclRva2VuLFxuICAgICAgICAgICAgICAgICAgICBnZXRMb2dzOiAobDogbnVtYmVyLCBsdjogc3RyaW5nKSA9PiBnZXRMb2dzSW50ZXJuYWwobCwgbHYpLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHB1c2hMb2coeyBldnQ6ICdzeXMnLCBtc2c6IGBNQ1Ag5pyN5Yqh5bey5ZCv5YqoOiBodHRwOi8vMTI3LjAuMC4xOiR7bWNwSG9zdC5ib3VuZFBvcnR9L21jcGAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgcHVzaExvZyh7IGV2dDogJ3N5cycsIG1zZzogYE1DUCDmnI3liqHlkK/liqjlpLHotKU6ICR7U3RyaW5nKGVycil9YCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZ2V0TWNwU3RhdGUoKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICog5YGc5q2iIE1DUCDmnI3liqHjgIJcbiAgICAgKi9cbiAgICBhc3luYyBzdG9wTWNwKCkge1xuICAgICAgICBpZiAobWNwSG9zdCkge1xuICAgICAgICAgICAgYXdhaXQgbWNwSG9zdC5zdG9wKCk7XG4gICAgICAgICAgICBwdXNoTG9nKHsgZXZ0OiAnc3lzJywgbXNnOiAnTUNQIOacjeWKoeW3suWBnOatoicgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGdldE1jcFN0YXRlKCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIOi/lOWbniBNQ1Ag5pyN5Yqh54q25oCB5LiO6L+e5o6l6YWN572u77yIVVJMICsg5Luk54mM77yJ44CCXG4gICAgICovXG4gICAgZ2V0TWNwU3RhdGUoKSB7XG4gICAgICAgIHJldHVybiBnZXRNY3BTdGF0ZSgpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiDmiormuLjmiI/kvqfmoaXmjqXohJrmnKwgUnVudGltZUJyaWRnZS50cyDoh6rliqjlronoo4XliLDlvZPliY3pobnnm67nmoQgYXNzZXRzIOebruW9leOAglxuICAgICAqL1xuICAgIGFzeW5jIGluc3RhbGxCcmlkZ2UoKSB7XG4gICAgICAgIGNvbnN0IHByb2plY3RQYXRoID0gKEVkaXRvciBhcyBhbnkpLlByb2plY3Q/LnBhdGg7XG4gICAgICAgIGlmICghcHJvamVjdFBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgbXNnOiAn5peg5rOV6I635Y+W6aG555uu6Lev5b6E77yIRWRpdG9yLlByb2plY3QucGF0aCDkuLrnqbrvvIknIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3JjID0gam9pbihfX2Rpcm5hbWUsICcuLi9ydW50aW1lLWJyaWRnZS1zYW1wbGUvUnVudGltZUJyaWRnZS50cycpO1xuICAgICAgICBjb25zdCBhc3NldHNEaXIgPSBqb2luKHByb2plY3RQYXRoLCAnYXNzZXRzJyk7XG4gICAgICAgIGlmICghZXhpc3RzU3luYyhzcmMpKSB7XG4gICAgICAgICAgICByZXR1cm4geyBvazogZmFsc2UsIG1zZzogYOacquaJvuWIsOahpeaOpeiEmuacrOaooeadvzogJHtzcmN9YCB9O1xuICAgICAgICB9XG4gICAgICAgIGlmICghZXhpc3RzU3luYyhhc3NldHNEaXIpKSB7XG4gICAgICAgICAgICByZXR1cm4geyBvazogZmFsc2UsIG1zZzogYOaJvuS4jeWIsOmhueebrueahCBhc3NldHMg55uu5b2VOiAke2Fzc2V0c0Rpcn1gIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGVzdCA9IGpvaW4oYXNzZXRzRGlyLCAnUnVudGltZUJyaWRnZS50cycpO1xuICAgICAgICBjb25zdCBvdmVyd3JvdGUgPSBleGlzdHNTeW5jKGRlc3QpO1xuICAgICAgICBjb25zdCBjdXJyZW50VG9rZW4gPSBzZXJ2ZXJUb2tlbjtcbiAgICAgICAgLy8g5L+d55WZ55So5oi36Ieq5a6a5LmJIGhvc3QvcG9ydO+8iOWmguecn+acuuiwg+ivleaXtuaUueS4uueUteiEkSBJUO+8ie+8jOmBv+WFjeavj+asoeimhuebluiiq+mHjee9ruOAglxuICAgICAgICAvLyDkvJjlhYjlj5blnLrmma/kuK3lt7LlrZjlnKjluLjpqbvoioLngrnnu4Tku7bnmoTnjrDlgLzvvIjnlKjmiLfmnIDov5Hlj6/og73nm7TmjqXlnKjoioLngrnkuIrphY3nva7vvInvvIxcbiAgICAgICAgLy8g5YW25qyh5Y+W5bey5a6J6KOF6ISa5pys5paH5Lu26YeM55qE6buY6K6k5YC844CCXG4gICAgICAgIGxldCBrZWVwSG9zdCA9ICcnO1xuICAgICAgICBsZXQga2VlcFBvcnQgPSAwO1xuICAgICAgICBpZiAob3Zlcndyb3RlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZENvbnRlbnQgPSByZWFkRmlsZVN5bmMoZGVzdCwgJ3V0Zi04Jyk7XG4gICAgICAgICAgICAgICAgY29uc3QgaG0gPSAvaG9zdFxccyo9XFxzKicoW14nXSopJy8uZXhlYyhvbGRDb250ZW50KTtcbiAgICAgICAgICAgICAgICBjb25zdCBwbSA9IC9wb3J0XFxzKj1cXHMqKFxcZCspLy5leGVjKG9sZENvbnRlbnQpO1xuICAgICAgICAgICAgICAgIGlmIChobSkge1xuICAgICAgICAgICAgICAgICAgICBrZWVwSG9zdCA9IGhtWzFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocG0pIHtcbiAgICAgICAgICAgICAgICAgICAga2VlcFBvcnQgPSBOdW1iZXIocG1bMV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgIC8qIOivu+WPluWksei0peWImeeUqOaooeadv+m7mOiupOWAvCAqL1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIOino+aekOahpeaOpeiEmuacrOe7hOS7tiB1dWlk77yM55So5LqO5Zyo5Zy65pmv5paH5Lu25Lit5a6a5L2N5bey5a2Y5Zyo55qEIFJ1bnRpbWVCcmlkZ2Ug57uE5Lu2XG4gICAgICAgIGxldCBjb21wVXVpZCA9ICcnO1xuICAgICAgICBjb25zdCBtZXRhUGF0aCA9IGRlc3QgKyAnLm1ldGEnO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKGV4aXN0c1N5bmMobWV0YVBhdGgpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWV0YSA9IHJlYWRKc29uU3luYyhtZXRhUGF0aCk7XG4gICAgICAgICAgICAgICAgY29tcFV1aWQgPSAobWV0YSAmJiBtZXRhLnV1aWQpIHx8ICcnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8qIOW/veeVpSBtZXRhIOivu+WPluWksei0pSAqL1xuICAgICAgICB9XG4gICAgICAgIGxldCBzY2VuZUZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICBpZiAoY29tcFV1aWQpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29sbGVjdFNjZW5lRmlsZXMoYXNzZXRzRGlyLCBzY2VuZUZpbGVzKTtcbiAgICAgICAgICAgICAgICAvLyDnrKzkuIDpgY3vvJrku6Xlt7LlrZjlnKjluLjpqbvoioLngrnnu4Tku7bkuIrnmoQgaG9zdC9wb3J0IOS4uuWHhu+8iOeUqOaIt+mFjee9ru+8ie+8jOimhuebluiEmuacrOaXp+WAvFxuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgc3Agb2Ygc2NlbmVGaWxlcykge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2ogPSByZWFkSnNvblN5bmMoc3ApO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2Fsa1NjZW5lQ29tcG9uZW50cyhzaiwgY29tcFV1aWQsIChjb21wKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjb21wLmhvc3QgPT09ICdzdHJpbmcnICYmIGNvbXAuaG9zdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwSG9zdCA9IGNvbXAuaG9zdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjb21wLnBvcnQgPT09ICdudW1iZXInICYmIGNvbXAucG9ydCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcFBvcnQgPSBjb21wLnBvcnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgICAgICAgICAgLyog5Y2V5Liq5Zy65pmv6Kej5p6Q5aSx6LSl6Lez6L+HICovXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgICAvKiDmiavmj4/lpLHotKXliJnot7Pov4flnLrmma/lkIzmraUgKi9cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyDmoaXmjqXohJrmnKzlhoXnva7lm7rlrprku6TniYwgd3d3Lnl5a2EuY27vvIzml6DpnIDms6jlhaXvvJtcbiAgICAgICAgLy8g5LuF5oqKIEJSSURHRV9WRVJTSU9OIOWQjOatpeS4uuaPkuS7tueJiOacrOWPt++8jOmBv+WFjemdouadv+aYvuekuui/h+aXtueJiOacrFxuICAgICAgICBjb25zdCBzcmNDb250ZW50ID0gcmVhZEZpbGVTeW5jKHNyYywgJ3V0Zi04Jyk7XG4gICAgICAgIGxldCBpbmplY3RlZCA9IHNyY0NvbnRlbnQucmVwbGFjZSgvQlJJREdFX1ZFUlNJT04gPSAnW14nXSonLywgYEJSSURHRV9WRVJTSU9OID0gJyR7cGFja2FnZUpTT04udmVyc2lvbn0nYCk7XG4gICAgICAgIC8vIOm7mOiupOi/nuaOpeWcsOWdgO+8mueUqOaIt+mFjee9rui/hyBob3N0IOWImeS/neeVme+8iOWmguecn+acuuiwg+ivleaXtuiHquWumuS5ieeahOeUteiEkSBJUO+8ie+8m1xuICAgICAgICAvLyDlkKbliJnoh6rliqjms6jlhaXlrr/kuLvmnLrlsYDln5/nvZEgSVAg4oCU4oCUIOWbuuWumiAxMjcuMC4wLjEg5pe255yf5py6L+aooeaLn+WZqOi/nueahOaYr+iuvuWkh+iHqui6q+WbnueOr++8jOaXoOazleaOpemAmuaPkuS7tuacjeWKoVxuICAgICAgICBjb25zdCBsYW5JUCA9IGdldEhvc3RMYW5JUCgpO1xuICAgICAgICBpZiAoa2VlcEhvc3QpIHtcbiAgICAgICAgICAgIGluamVjdGVkID0gaW5qZWN0ZWQucmVwbGFjZSgnaG9zdCA9IERFRkFVTFRfSE9TVDsnLCBgaG9zdCA9ICcke2tlZXBIb3N0fSc7YCk7XG4gICAgICAgIH0gZWxzZSBpZiAobGFuSVApIHtcbiAgICAgICAgICAgIGluamVjdGVkID0gaW5qZWN0ZWQucmVwbGFjZSgnaG9zdCA9IERFRkFVTFRfSE9TVDsnLCBgaG9zdCA9ICcke2xhbklQfSc7YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGtlZXBQb3J0KSB7XG4gICAgICAgICAgICBpbmplY3RlZCA9IGluamVjdGVkLnJlcGxhY2UoJ3BvcnQgPSBERUZBVUxUX1BPUlQ7JywgYHBvcnQgPSAke2tlZXBQb3J0fTtgKTtcbiAgICAgICAgfVxuICAgICAgICB3cml0ZUZpbGVTeW5jKGRlc3QsIGluamVjdGVkLCAndXRmLTgnKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IEVkaXRvci5NZXNzYWdlLnJlcXVlc3QoJ2Fzc2V0LWRiJywgJ3JlZnJlc2gtYXNzZXQnLCBkZXN0KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1t5eWthLXJ1bnRpbWUtaW5zcGVjdG9yXSByZWZyZXNoLWFzc2V0IGZhaWxlZDonLCBlcnIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIOesrOS6jOmBje+8muaKiuW3suWtmOWcqOW4uOmpu+iKgueCueeahCBob3N0L3BvcnQg5ZCM5q2l5Li65pyA5paw6YWN572u77ybXG4gICAgICAgIC8vIHRva2VuIOW3suaUueS4uuiEmuacrOWGhee9ruW4uOmHj++8jOmhuuW4pua4heaOieaXp+eJiOacrOWcuuaZr+mHjOaui+eVmeeahCB0b2tlbiDlrZfmrrXvvIzpgb/lhY3or6/lr7xcbiAgICAgICAgaWYgKGNvbXBVdWlkKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNwIG9mIHNjZW5lRmlsZXMpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaiA9IHJlYWRKc29uU3luYyhzcCk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHdhbGtTY2VuZUNvbXBvbmVudHMoc2osIGNvbXBVdWlkLCAoY29tcCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtlZXBIb3N0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcC5ob3N0ID0ga2VlcEhvc3Q7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2VlcFBvcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wLnBvcnQgPSBrZWVwUG9ydDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29tcC50b2tlbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgY29tcC50b2tlbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZWVwSG9zdCB8fCBrZWVwUG9ydCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoYW5nZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlSnNvblN5bmMoc3AsIHNqLCB7IHNwYWNlczogMiB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbeXlrYS1ydW50aW1lLWluc3BlY3Rvcl0g5bey5ZCM5q2l5bi46am76IqC54K55bGe5oCnOiAke3NwfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBFZGl0b3IuTWVzc2FnZS5yZXF1ZXN0KCdhc3NldC1kYicsICdyZWZyZXNoLWFzc2V0Jywgc3ApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaWdub3JlICovXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgICAgICAgLyog5Y2V5Liq5Zy65pmv5ZCM5q2l5aSx6LSl6Lez6L+HICovXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IG9rOiB0cnVlLCBwYXRoOiBkZXN0LCBvdmVyd3JvdGUsIHRva2VuOiBjdXJyZW50VG9rZW4sIHNjZW5lczogc2NlbmVGaWxlcy5sZW5ndGggfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICog6YCa55+l5ri45oiP5L6n6auY5LquL+mBrue9qeaMh+WumuiKgueCueOAgmlkIOS4uuepuuS4suWImea4hemZpOOAglxuICAgICAqL1xuICAgIGFzeW5jIGhpZ2hsaWdodE5vZGUoaWQ6IHN0cmluZywgbW9kZTogc3RyaW5nID0gJ2hpZ2hsaWdodCcpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGNhbGxHYW1lKCdoaWdobGlnaHQnLCB7IGlkOiBpZCB8fCAnJywgbW9kZTogbW9kZSA9PT0gJ21hc2snID8gJ21hc2snIDogJ2hpZ2hsaWdodCcgfSwgMzAwMCk7XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGVycm9yOiBTdHJpbmcoZXJyKSB9O1xuICAgICAgICB9XG4gICAgfSxcbn07XG5cbi8qKlxuICogQHpoIOaJqeWxleWQr+WKqOaXtuiHquWKqOaLiei1tyBXUyDmnI3liqHvvIzkvr/kuo7muLjmiI/kvqfpmo/ml7bov57mjqXjgIJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvYWQoKSB7XG4gICAgY29uc29sZS5sb2coJ1t5eWthLXJ1bnRpbWUtaW5zcGVjdG9yXSBsb2FkLCBzdGFydGluZyB3cyBzZXJ2ZXIuLi4nKTtcbiAgICAvLyDku6TniYzkuLrlm7rlrprpnZnmgIHlgLzvvIzmnI3liqHlkK/liqjml7boh6rliqjluKbkuIrpibTmnYNcbiAgICBtZXRob2RzLnN0YXJ0U2VydmVyKCk7XG4gICAgLy8g5q+P5qyh5omT5byA5o+S5Lu26Ieq5Yqo5a6J6KOF5pyA5paw5qGl5o6l6ISa5pys77yI5L+d55WZ55So5oi36Ieq5a6a5LmJIGhvc3QvcG9ydO+8ie+8jOS/neivgea4uOaIj+S+p+iEmuacrOS4juaPkuS7tueJiOacrOWQjOatpVxuICAgIG1ldGhvZHMuaW5zdGFsbEJyaWRnZSgpLnRoZW4oKHJlczogeyBvaz86IGJvb2xlYW47IG92ZXJ3cm90ZT86IGJvb2xlYW47IHBhdGg/OiBzdHJpbmc7IG1zZz86IHN0cmluZyB9KSA9PiB7XG4gICAgICAgIGlmIChyZXMgJiYgcmVzLm9rKSB7XG4gICAgICAgICAgICBwdXNoTG9nKHsgZXZ0OiAnc3lzJywgbXNnOiBg5qGl5o6l6ISa5pysJHtyZXMub3Zlcndyb3RlID8gJ+W3suabtOaWsCcgOiAn5bey5a6J6KOFJ306ICR7cmVzLnBhdGh9YCB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXMgJiYgcmVzLm1zZykge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdbeXlrYS1ydW50aW1lLWluc3BlY3Rvcl0gYXV0byBpbnN0YWxsQnJpZGdlIHNraXBwZWQ6JywgcmVzLm1zZyk7XG4gICAgICAgIH1cbiAgICB9KS5jYXRjaCgoZXJyOiB1bmtub3duKSA9PiB7XG4gICAgICAgIGNvbnNvbGUud2FybignW3l5a2EtcnVudGltZS1pbnNwZWN0b3JdIGF1dG8gaW5zdGFsbEJyaWRnZSBmYWlsZWQ6JywgZXJyKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBAemgg5Y246L295omp5bGV5pe25YWz6ZetIFdTIOacjeWKoeOAglxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5sb2FkKCkge1xuICAgIGlmIChzZXJ2ZXIpIHtcbiAgICAgICAgc2VydmVyLnN0b3AoKTtcbiAgICAgICAgc2VydmVyID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKG1jcEhvc3QpIHtcbiAgICAgICAgbWNwSG9zdC5zdG9wKCk7XG4gICAgICAgIG1jcEhvc3QgPSBudWxsO1xuICAgIH1cbn0iXX0= \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/dist/mcp-server.js b/extensions/YYKA运行时工作台/dist/mcp-server.js new file mode 100644 index 0000000..b440c77 --- /dev/null +++ b/extensions/YYKA运行时工作台/dist/mcp-server.js @@ -0,0 +1,517 @@ +"use strict"; +var __asyncValues = (this && this.__asyncValues) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.McpHttpServer = exports.MCP_DEFAULT_PORT = void 0; +const http_1 = __importDefault(require("http")); +const zod_1 = require("zod"); +const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js"); +const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/server/streamableHttp.js"); +/** MCP 服务默认端口(HTTP Streamable)。 */ +exports.MCP_DEFAULT_PORT = 33010; +const text = (s, isError = false) => ({ + content: [{ type: 'text', text: s }], + isError, +}); +const json = (v, isError = false) => ({ + content: [{ type: 'text', text: JSON.stringify(v, null, 2) }], + isError, +}); +/** 统计节点树总节点数。 */ +function countNodes(roots) { + let n = 0; + const walk = (list) => { + for (const r of list) { + n++; + if (Array.isArray(r.children)) { + walk(r.children); + } + } + }; + walk(roots !== null && roots !== void 0 ? roots : []); + return n; +} +/** 把节点树裁剪到指定深度(在序列化结果上处理,无需改桥接脚本)。 */ +function pruneTree(roots, maxDepth) { + const walk = (list, depth) => { + return (list !== null && list !== void 0 ? list : []).map((r) => { + const out = { + id: r.id, + name: r.name, + active: r.active, + layer: r.layer, + comps: r.comps, + }; + if (Array.isArray(r.children) && depth < maxDepth) { + out.children = walk(r.children, depth + 1); + } + else if (Array.isArray(r.children) && r.children.length) { + out.children = `...${r.children.length} 个子节点(超出 max_depth)`; + } + return out; + }); + }; + return walk(roots !== null && roots !== void 0 ? roots : [], 0); +} +function fmtT(ts) { + const d = new Date(ts); + const p = (n) => String(n).padStart(2, '0'); + return `${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`; +} +/** + * 内嵌在主进程的 MCP 服务(Streamable HTTP)。 + * 工具直接代理到游戏侧桥接脚本(query-tree / get-inspector / set-property / capture-frame 等), + * 供 Codex 等 AI Agent 连接并观察、操作正在运行的游戏。 + */ +class McpHttpServer { + constructor() { + this.srv = null; + this.port = 0; + this.token = ''; + this.deps = null; + /** 每个会话持有独立的 McpServer 实例(SDK 限制一个 Protocol 只能连接一个 Transport)。 */ + this.sessions = new Map(); + } + get isRunning() { + return !!this.srv; + } + get boundPort() { + return this.port; + } + checkAuth(req) { + if (!this.token) { + return true; + } + return req.headers.authorization === `Bearer ${this.token}`; + } + async readBody(req, maxBytes = 1024 * 1024) { + var _a, e_1, _b, _c; + const chunks = []; + let size = 0; + try { + for (var _d = true, req_1 = __asyncValues(req), req_1_1; req_1_1 = await req_1.next(), _a = req_1_1.done, !_a; _d = true) { + _c = req_1_1.value; + _d = false; + const chunk = _c; + const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)); + size += buf.length; + if (size > maxBytes) { + throw new Error('body too large'); + } + chunks.push(buf); + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (!_d && !_a && (_b = req_1.return)) await _b.call(req_1); + } + finally { if (e_1) throw e_1.error; } + } + const raw = Buffer.concat(chunks).toString('utf-8'); + if (!raw) { + return undefined; + } + try { + return JSON.parse(raw); + } + catch (_e) { + return raw; + } + } + async handle(req, res) { + var _a; + if (!this.checkAuth(req)) { + res.writeHead(401, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ error: 'unauthorized' })); + return; + } + const url = (_a = req.url) !== null && _a !== void 0 ? _a : ''; + if (!url.startsWith('/mcp')) { + res.writeHead(404, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ error: 'not found' })); + return; + } + const sessionId = req.headers['mcp-session-id']; + let session = sessionId ? this.sessions.get(sessionId) : undefined; + if (sessionId && !session) { + res.writeHead(404, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ error: 'invalid session id' })); + return; + } + try { + if (!session) { + // 新会话:为每个会话创建独立的 McpServer 实例,避免 Protocol 重复连接报错 + const deps = this.deps; + if (!deps) { + res.writeHead(503, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ error: 'server not ready' })); + return; + } + const transport = new streamableHttp_js_1.StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + const sid = transport.sessionId; + const mcp = this.buildServer(deps); + session = { transport, mcp }; + this.sessions.set(sid, session); + transport.onclose = () => { + if (this.sessions.get(sid) === session) { + this.sessions.delete(sid); + } + }; + await mcp.connect(transport); + } + const parsedBody = req.method === 'POST' ? await this.readBody(req) : undefined; + await session.transport.handleRequest(req, res, parsedBody); + } + catch (err) { + try { + if (!res.headersSent) { + res.writeHead(500, { 'Content-Type': 'application/json' }); + } + res.end(JSON.stringify({ error: String(err) })); + } + catch (_b) { + /* ignore */ + } + } + } + /** 注册工具集。 */ + buildServer(deps) { + const mcp = new mcp_js_1.McpServer({ name: 'yyka-runtime-inspector', version: '1.0.0' }); + const noClient = () => { + const st = deps.getServerState(); + return !st.running || st.clients === 0; + }; + mcp.registerTool('get_runtime_info', { + title: '获取运行时信息', + description: '获取当前连接的游戏实例信息:连接状态、场景名、节点数量、FPS、DrawCall、三角形数、内存占用、物理系统状态、桥接版本。游戏未连接时返回错误。', + inputSchema: zod_1.z.object({}), + }, async () => { + var _a; + if (noClient()) { + return text('游戏未连接:请先启动 WS 服务、运行游戏并确认桥接脚本已连接。', true); + } + try { + const [stats, tree] = await Promise.all([ + deps.callGame('get-stats', undefined, 4000), + deps.callGame('query-tree', {}, 4000), + ]); + const st = deps.getServerState(); + return json({ + connected: true, + clients: st.clients, + wsPort: st.port, + scene: (_a = tree === null || tree === void 0 ? void 0 : tree.scene) !== null && _a !== void 0 ? _a : '', + nodeCount: countNodes(tree === null || tree === void 0 ? void 0 : tree.roots), + stats: stats !== null && stats !== void 0 ? stats : {}, + }); + } + catch (err) { + return text(`获取运行时信息失败: ${String(err)}`, true); + } + }); + mcp.registerTool('get_node_tree', { + title: '获取节点树', + description: '获取当前场景的运行时节点树(名称/激活/层级/组件数)。可用 filter 按节点名筛选;max_depth 限制展开深度避免输出过大。', + inputSchema: zod_1.z.object({ + filter: zod_1.z.string().optional().describe('按节点名关键字筛选(可选)'), + max_depth: zod_1.z.number().optional().describe('最大展开深度,默认 20(可选)'), + }), + }, async (args) => { + var _a, _b; + if (noClient()) { + return text('游戏未连接。', true); + } + try { + const tree = await deps.callGame('query-tree', { filter: (_a = args === null || args === void 0 ? void 0 : args.filter) !== null && _a !== void 0 ? _a : '' }, 8000); + if (tree && Array.isArray(tree.roots)) { + const depth = typeof (args === null || args === void 0 ? void 0 : args.max_depth) === 'number' ? Math.max(1, Math.min(50, args.max_depth)) : 20; + return json({ scene: (_b = tree.scene) !== null && _b !== void 0 ? _b : '', roots: pruneTree(tree.roots, depth) }); + } + return text('获取节点树失败。', true); + } + catch (err) { + return text(`获取节点树失败: ${String(err)}`, true); + } + }); + mcp.registerTool('get_node_info', { + title: '获取节点信息', + description: '按节点 id 获取节点详情:位置/旋转/缩放/激活/层级等 Transform 属性,以及所有组件及其可编辑属性(含枚举、数组、向量、颜色、引用等)。', + inputSchema: zod_1.z.object({ + id: zod_1.z.string().describe('节点 id(来自 get_node_tree)'), + }), + }, async (args) => { + if (noClient()) { + return text('游戏未连接。', true); + } + if (!(args === null || args === void 0 ? void 0 : args.id)) { + return text('缺少参数 id。', true); + } + try { + const r = await deps.callGame('get-inspector', { id: args.id }, 8000); + if (r && r.error) { + return text(String(r.error), true); + } + return json(r !== null && r !== void 0 ? r : {}); + } + catch (err) { + return text(`获取节点信息失败: ${String(err)}`, true); + } + }); + mcp.registerTool('set_node_property', { + title: '修改运行时属性', + description: '修改运行中节点的属性。节点级:field 取 position/euler/scale(value 为 {x,y,z})、active(value 为 boolean)、layer(value 为 number)。组件级:传 comp 组件索引(0 起)与 key 属性名,value 为属性值(向量/颜色传对象,枚举传数字)。', + inputSchema: zod_1.z.object({ + id: zod_1.z.string().describe('节点 id(来自 get_node_tree)'), + field: zod_1.z.string().optional().describe('节点级字段:position | euler | scale | active | layer'), + value: zod_1.z.any().optional().describe('要写入的值'), + comp: zod_1.z.number().optional().describe('组件索引(0 起,与 get_node_info 的 components 顺序一致)'), + key: zod_1.z.string().optional().describe('组件属性名'), + }), + }, async (args) => { + if (noClient()) { + return text('游戏未连接。', true); + } + if (!(args === null || args === void 0 ? void 0 : args.id)) { + return text('缺少参数 id。', true); + } + try { + const payload = { id: args.id }; + if (typeof args.field === 'string') { + payload.field = args.field; + payload.value = args.value; + } + if (typeof args.comp === 'number') { + payload.comp = args.comp; + payload.key = args.key; + payload.value = args.value; + } + const r = await deps.callGame('set-property', payload, 8000); + if (r && r.error) { + return text(String(r.error), true); + } + return json(r !== null && r !== void 0 ? r : { ok: true }); + } + catch (err) { + return text(`修改属性失败: ${String(err)}`, true); + } + }); + mcp.registerTool('get_screenshot', { + title: '获取游戏截图', + description: '抓取当前游戏画面并返回图片(JPEG),用于视觉验证游戏状态。', + inputSchema: zod_1.z.object({}), + }, async () => { + if (noClient()) { + return text('游戏未连接。', true); + } + try { + const r = await deps.callGame('capture-frame', {}, 6000); + const dataUrl = r && typeof r.data === 'string' ? r.data : ''; + const base64 = dataUrl.includes(',') ? dataUrl.split(',')[1] : dataUrl; + if (!base64) { + return text('截图失败:游戏侧未能捕获画面。', true); + } + return { + content: [{ type: 'image', data: base64, mimeType: 'image/jpeg' }], + }; + } + catch (err) { + return text(`截图失败: ${String(err)}`, true); + } + }); + mcp.registerTool('get_logs', { + title: '获取运行时日志', + description: '获取游戏侧最近的控制台日志(console.log/warn/error)。level 可选 log/warn/error,默认全部。', + inputSchema: zod_1.z.object({ + limit: zod_1.z.number().optional().describe('返回条数,默认 50'), + level: zod_1.z.string().optional().describe('过滤级别:all | log | warn | error'), + }), + }, async (args) => { + const limit = typeof (args === null || args === void 0 ? void 0 : args.limit) === 'number' ? Math.max(1, Math.min(200, args.limit)) : 50; + const level = typeof (args === null || args === void 0 ? void 0 : args.level) === 'string' ? args.level : 'all'; + const items = deps.getLogs(limit, level); + if (!items.length) { + return text('(暂无日志)'); + } + const lines = items.map((it) => { + var _a, _b; + if (it && it.evt === 'console') { + const tag = it.level === 'error' ? 'ERROR' : it.level === 'warn' ? 'WARN ' : 'LOG '; + return `${fmtT(it.t)} [${tag}] ${it.text}`; + } + if (it && it.evt === 'sys') { + return `${fmtT((_a = it.t) !== null && _a !== void 0 ? _a : Date.now())} [SYS] ${(_b = it.msg) !== null && _b !== void 0 ? _b : ''}`; + } + return JSON.stringify(it); + }); + return text(lines.join('\n')); + }); + mcp.registerTool('wait', { + title: '等待', + description: '等待指定毫秒(1-60000),常用于等待游戏状态变化后再查询。', + inputSchema: zod_1.z.object({ + ms: zod_1.z.number().describe('毫秒数,1-60000'), + }), + }, async (args) => { + const ms = Math.max(1, Math.min(60000, Number(args === null || args === void 0 ? void 0 : args.ms) || 0)); + await new Promise((r) => setTimeout(r, ms)); + return text(`已等待 ${ms}ms`); + }); + mcp.registerTool('execute_command', { + title: '执行游戏命令', + description: '向游戏侧桥接脚本发送任意命令。常用:get-stats、get-resource-stats、query-physics、set-preview({enabled,fps})、set-mute({muted})、set-physics-debug({enabled})。', + inputSchema: zod_1.z.object({ + cmd: zod_1.z.string().describe('命令名'), + payload: zod_1.z.any().optional().describe('命令参数(可选)'), + }), + }, async (args) => { + if (noClient()) { + return text('游戏未连接。', true); + } + if (!(args === null || args === void 0 ? void 0 : args.cmd)) { + return text('缺少参数 cmd。', true); + } + try { + const r = await deps.callGame(String(args.cmd), args.payload, 8000); + return json(r !== null && r !== void 0 ? r : {}); + } + catch (err) { + return text(`命令执行失败: ${String(err)}`, true); + } + }); + mcp.registerTool('click', { + title: '模拟点击', + description: '模拟一次触摸点击。传 id 则点击该节点(取其 UI 中心点);传 x/y 则点击屏幕(UI 坐标)上命中的最上层节点。常用于触发按钮、开始游戏等操作。', + inputSchema: zod_1.z.object({ + id: zod_1.z.string().optional().describe('节点 id(来自 get_node_tree)'), + x: zod_1.z.number().optional().describe('UI 横坐标(与 id 二选一)'), + y: zod_1.z.number().optional().describe('UI 纵坐标(与 id 二选一)'), + }), + }, async (args) => { + if (noClient()) { + return text('游戏未连接。', true); + } + if (!(args === null || args === void 0 ? void 0 : args.id) && (typeof (args === null || args === void 0 ? void 0 : args.x) !== 'number' || typeof (args === null || args === void 0 ? void 0 : args.y) !== 'number')) { + return text('需要参数 id(节点 id)或 x/y(UI 坐标)。', true); + } + try { + const payload = {}; + if (typeof args.id === 'string' && args.id) { + payload.id = args.id; + } + else { + payload.x = args.x; + payload.y = args.y; + } + const r = await deps.callGame('simulate-click', payload, 8000); + if (r && r.error) { + return text(String(r.error), true); + } + return json(r !== null && r !== void 0 ? r : { ok: true }); + } + catch (err) { + return text(`模拟点击失败: ${String(err)}`, true); + } + }); + mcp.registerTool('list_scenes', { + title: '列出场景', + description: '列出当前运行场景及已加载场景名,用于确认跳转目标。', + inputSchema: zod_1.z.object({}), + }, async () => { + if (noClient()) { + return text('游戏未连接。', true); + } + try { + const r = await deps.callGame('list-scenes', {}, 6000); + return json(r !== null && r !== void 0 ? r : { current: '', scenes: [] }); + } + catch (err) { + return text(`列出场景失败: ${String(err)}`, true); + } + }); + mcp.registerTool('load_scene', { + title: '跳转场景', + description: '运行时加载指定名称的场景(场景跳转)。场景名可先通过 list_scenes 查看。', + inputSchema: zod_1.z.object({ + name: zod_1.z.string().describe('场景名'), + }), + }, async (args) => { + if (noClient()) { + return text('游戏未连接。', true); + } + if (!(args === null || args === void 0 ? void 0 : args.name)) { + return text('缺少参数 name。', true); + } + try { + const r = await deps.callGame('load-scene', { name: String(args.name) }, 6000); + if (r && r.error) { + return text(String(r.error), true); + } + return json(r !== null && r !== void 0 ? r : { ok: true }); + } + catch (err) { + return text(`跳转场景失败: ${String(err)}`, true); + } + }); + return mcp; + } + /** 启动 HTTP 服务。port 被占用时抛错。 */ + async start(port, token, deps) { + if (this.srv) { + return; + } + this.token = token; + this.deps = deps; + const srv = http_1.default.createServer((req, res) => { + this.handle(req, res).catch(() => { + /* handled inside */ + }); + }); + await new Promise((resolve, reject) => { + const onError = (err) => { + srv.removeListener('listening', onListening); + reject(err); + }; + const onListening = () => { + srv.removeListener('error', onError); + resolve(); + }; + srv.once('error', onError); + srv.once('listening', onListening); + srv.listen(port, '127.0.0.1'); + }); + this.srv = srv; + this.port = port; + } + /** 停止服务并关闭所有会话。 */ + async stop() { + const srv = this.srv; + this.srv = null; + this.port = 0; + this.deps = null; + for (const { transport } of this.sessions.values()) { + try { + await transport.close(); + } + catch (_a) { + /* ignore */ + } + } + this.sessions.clear(); + if (srv) { + await new Promise((resolve) => srv.close(() => resolve())); + } + } +} +exports.McpHttpServer = McpHttpServer; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NvdXJjZS9tY3Atc2VydmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFBQSxnREFBd0I7QUFDeEIsNkJBQXdCO0FBQ3hCLG9FQUFvRTtBQUNwRSwwRkFBbUc7QUFFbkcsbUNBQW1DO0FBQ3RCLFFBQUEsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0FBb0J0QyxNQUFNLElBQUksR0FBRyxDQUFDLENBQVMsRUFBRSxPQUFPLEdBQUcsS0FBSyxFQUFjLEVBQUUsQ0FBQyxDQUFDO0lBQ3RELE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDcEMsT0FBTztDQUNWLENBQUMsQ0FBQztBQUVILE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBVSxFQUFFLE9BQU8sR0FBRyxLQUFLLEVBQWMsRUFBRSxDQUFDLENBQUM7SUFDdkQsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUM3RCxPQUFPO0NBQ1YsQ0FBQyxDQUFDO0FBRUgsaUJBQWlCO0FBQ2pCLFNBQVMsVUFBVSxDQUFDLEtBQVk7SUFDNUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFXLEVBQUUsRUFBRTtRQUN6QixLQUFLLE1BQU0sQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ25CLENBQUMsRUFBRSxDQUFDO1lBQ0osSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUM1QixJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3JCLENBQUM7UUFDTCxDQUFDO0lB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SUFBSSxDQUFDO2dCQUNELE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzVCLENBQUM7WUFBQyxXQUFNLENBQUM7Z0JBQ0wsWUFBWTtZQUNoQixDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNOLE1BQU0sSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLENBQUM7SUFDTCxDQUFDO0NBQ0o7QUE5ZEQsc0NBOGRDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcbmltcG9ydCB7IE1jcFNlcnZlciB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc2VydmVyL21jcC5qcyc7XG5pbXBvcnQgeyBTdHJlYW1hYmxlSFRUUFNlcnZlclRyYW5zcG9ydCB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc2VydmVyL3N0cmVhbWFibGVIdHRwLmpzJztcblxuLyoqIE1DUCDmnI3liqHpu5jorqTnq6/lj6PvvIhIVFRQIFN0cmVhbWFibGXvvInjgIIgKi9cbmV4cG9ydCBjb25zdCBNQ1BfREVGQVVMVF9QT1JUID0gMzMwMTA7XG5cbi8qKiDkuLvov5vnqIvlkJEgTUNQIOacjeWKoeaPkOS+m+eahOS+nei1luiDveWKm+OAgiAqL1xuZXhwb3J0IGludGVyZmFjZSBNY3BEZXBzIHtcbiAgICAvKiog5ZCR5ri45oiP5L6n5qGl5o6l6ISa5pys5Y+R5ZG95Luk5bm2562J5b6F5Zue5YyF44CCICovXG4gICAgY2FsbEdhbWU6IChjbWQ6IHN0cmluZywgcGF5bG9hZD86IHVua25vd24sIHRpbWVvdXQ/OiBudW1iZXIpID0+IFByb21pc2U8YW55PjtcbiAgICAvKiog5b2T5YmNIFdTIOacjeWKoeeKtuaAgeOAgiAqL1xuICAgIGdldFNlcnZlclN0YXRlOiAoKSA9PiB7IHJ1bm5pbmc6IGJvb2xlYW47IHBvcnQ6IG51bWJlcjsgY2xpZW50czogbnVtYmVyIH07XG4gICAgLyoqIOW9k+WJjei/nuaOpeS7pOeJjOOAgiAqL1xuICAgIGdldFRva2VuOiAoKSA9PiBzdHJpbmc7XG4gICAgLyoqIOivu+WPluacgOi/keaXpeW/l++8iOS4jea4heepuue8k+WGsu+8ieOAgiAqL1xuICAgIGdldExvZ3M6IChsaW1pdDogbnVtYmVyLCBsZXZlbDogc3RyaW5nKSA9PiB1bmtub3duW107XG59XG5cbmludGVyZmFjZSBUb29sUmVzdWx0IHtcbiAgICBjb250ZW50OiAoeyB0eXBlOiAndGV4dCc7IHRleHQ6IHN0cmluZyB9IHwgeyB0eXBlOiAnaW1hZ2UnOyBkYXRhOiBzdHJpbmc7IG1pbWVUeXBlOiBzdHJpbmcgfSlbXTtcbiAgICBpc0Vycm9yPzogYm9vbGVhbjtcbiAgICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xufVxuXG5jb25zdCB0ZXh0ID0gKHM6IHN0cmluZywgaXNFcnJvciA9IGZhbHNlKTogVG9vbFJlc3VsdCA9PiAoe1xuICAgIGNvbnRlbnQ6IFt7IHR5cGU6ICd0ZXh0JywgdGV4dDogcyB9XSxcbiAgICBpc0Vycm9yLFxufSk7XG5cbmNvbnN0IGpzb24gPSAodjogdW5rbm93biwgaXNFcnJvciA9IGZhbHNlKTogVG9vbFJlc3VsdCA9PiAoe1xuICAgIGNvbnRlbnQ6IFt7IHR5cGU6ICd0ZXh0JywgdGV4dDogSlNPTi5zdHJpbmdpZnkodiwgbnVsbCwgMikgfV0sXG4gICAgaXNFcnJvcixcbn0pO1xuXG4vKiog57uf6K6h6IqC54K55qCR5oC76IqC54K55pWw44CCICovXG5mdW5jdGlvbiBjb3VudE5vZGVzKHJvb3RzOiBhbnlbXSk6IG51bWJlciB7XG4gICAgbGV0IG4gPSAwO1xuICAgIGNvbnN0IHdhbGsgPSAobGlzdDogYW55W10pID0+IHtcbiAgICAgICAgZm9yIChjb25zdCByIG9mIGxpc3QpIHtcbiAgICAgICAgICAgIG4rKztcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHIuY2hpbGRyZW4pKSB7XG4gICAgICAgICAgICAgICAgd2FsayhyLmNoaWxkcmVuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgd2Fsayhyb290cyA/PyBbXSk7XG4gICAgcmV0dXJuIG47XG59XG5cbi8qKiDmioroioLngrnmoJHoo4HliarliLDmjIflrprmt7HluqbvvIjlnKjluo/liJfljJbnu5PmnpzkuIrlpITnkIbvvIzml6DpnIDmlLnmoaXmjqXohJrmnKzvvInjgIIgKi9cbmZ1bmN0aW9uIHBydW5lVHJlZShyb290czogYW55W10sIG1heERlcHRoOiBudW1iZXIpOiBhbnlbXSB7XG4gICAgY29uc3Qgd2FsayA9IChsaXN0OiBhbnlbXSwgZGVwdGg6IG51bWJlcik6IGFueVtdID0+IHtcbiAgICAgICAgcmV0dXJuIChsaXN0ID8/IFtdKS5tYXAoKHIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG91dDogYW55ID0ge1xuICAgICAgICAgICAgICAgIGlkOiByLmlkLFxuICAgICAgICAgICAgICAgIG5hbWU6IHIubmFtZSxcbiAgICAgICAgICAgICAgICBhY3RpdmU6IHIuYWN0aXZlLFxuICAgICAgICAgICAgICAgIGxheWVyOiByLmxheWVyLFxuICAgICAgICAgICAgICAgIGNvbXBzOiByLmNvbXBzLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHIuY2hpbGRyZW4pICYmIGRlcHRoIDwgbWF4RGVwdGgpIHtcbiAgICAgICAgICAgICAgICBvdXQuY2hpbGRyZW4gPSB3YWxrKHIuY2hpbGRyZW4sIGRlcHRoICsgMSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoci5jaGlsZHJlbikgJiYgci5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvdXQuY2hpbGRyZW4gPSBgLi4uJHtyLmNoaWxkcmVuLmxlbmd0aH0g5Liq5a2Q6IqC54K577yI6LaF5Ye6IG1heF9kZXB0aO+8iWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb3V0O1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiB3YWxrKHJvb3RzID8/IFtdLCAwKTtcbn1cblxuZnVuY3Rpb24gZm10VCh0czogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBjb25zdCBkID0gbmV3IERhdGUodHMpO1xuICAgIGNvbnN0IHAgPSAobjogbnVtYmVyKSA9PiBTdHJpbmcobikucGFkU3RhcnQoMiwgJzAnKTtcbiAgICByZXR1cm4gYCR7cChkLmdldEhvdXJzKCkpfToke3AoZC5nZXRNaW51dGVzKCkpfToke3AoZC5nZXRTZWNvbmRzKCkpfWA7XG59XG5cbi8qKlxuICog5YaF5bWM5Zyo5Li76L+b56iL55qEIE1DUCDmnI3liqHvvIhTdHJlYW1hYmxlIEhUVFDvvInjgIJcbiAqIOW3peWFt+ebtOaOpeS7o+eQhuWIsOa4uOaIj+S+p+ahpeaOpeiEmuacrO+8iHF1ZXJ5LXRyZWUgLyBnZXQtaW5zcGVjdG9yIC8gc2V0LXByb3BlcnR5IC8gY2FwdHVyZS1mcmFtZSDnrYnvvInvvIxcbiAqIOS+myBDb2RleCDnrYkgQUkgQWdlbnQg6L+e5o6l5bm26KeC5a+f44CB5pON5L2c5q2j5Zyo6L+Q6KGM55qE5ri45oiP44CCXG4gKi9cbmV4cG9ydCBjbGFzcyBNY3BIdHRwU2VydmVyIHtcbiAgICBwcml2YXRlIHNydjogaHR0cC5TZXJ2ZXIgfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIHBvcnQgPSAwO1xuICAgIHByaXZhdGUgdG9rZW4gPSAnJztcbiAgICBwcml2YXRlIGRlcHM6IE1jcERlcHMgfCBudWxsID0gbnVsbDtcbiAgICAvKiog5q+P5Liq5Lya6K+d5oyB5pyJ54us56uL55qEIE1jcFNlcnZlciDlrp7kvovvvIhTREsg6ZmQ5Yi25LiA5LiqIFByb3RvY29sIOWPquiDvei/nuaOpeS4gOS4qiBUcmFuc3BvcnTvvInjgIIgKi9cbiAgICBwcml2YXRlIHNlc3Npb25zID0gbmV3IE1hcDxzdHJpbmcsIHsgdHJhbnNwb3J0OiBTdHJlYW1hYmxlSFRUUFNlcnZlclRyYW5zcG9ydDsgbWNwOiBNY3BTZXJ2ZXIgfT4oKTtcblxuICAgIGdldCBpc1J1bm5pbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuc3J2O1xuICAgIH1cblxuICAgIGdldCBib3VuZFBvcnQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9ydDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNoZWNrQXV0aChyZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghdGhpcy50b2tlbikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb24gPT09IGBCZWFyZXIgJHt0aGlzLnRva2VufWA7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZWFkQm9keShyZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlLCBtYXhCeXRlcyA9IDEwMjQgKiAxMDI0KTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgICAgIGNvbnN0IGNodW5rczogQnVmZmVyW10gPSBbXTtcbiAgICAgICAgbGV0IHNpemUgPSAwO1xuICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IGNodW5rIG9mIHJlcSkge1xuICAgICAgICAgICAgY29uc3QgYnVmID0gQnVmZmVyLmlzQnVmZmVyKGNodW5rKSA/IGNodW5rIDogQnVmZmVyLmZyb20oU3RyaW5nKGNodW5rKSk7XG4gICAgICAgICAgICBzaXplICs9IGJ1Zi5sZW5ndGg7XG4gICAgICAgICAgICBpZiAoc2l6ZSA+IG1heEJ5dGVzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdib2R5IHRvbyBsYXJnZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2h1bmtzLnB1c2goYnVmKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByYXcgPSBCdWZmZXIuY29uY2F0KGNodW5rcykudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICAgIGlmICghcmF3KSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShyYXcpO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHJldHVybiByYXc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGhhbmRsZShyZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlLCByZXM6IGh0dHAuU2VydmVyUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKCF0aGlzLmNoZWNrQXV0aChyZXEpKSB7XG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDQwMSwgeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pO1xuICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiAndW5hdXRob3JpemVkJyB9KSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJsID0gcmVxLnVybCA/PyAnJztcbiAgICAgICAgaWYgKCF1cmwuc3RhcnRzV2l0aCgnL21jcCcpKSB7XG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDQwNCwgeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pO1xuICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiAnbm90IGZvdW5kJyB9KSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gcmVxLmhlYWRlcnNbJ21jcC1zZXNzaW9uLWlkJ10gYXMgc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgc2Vzc2lvbiA9IHNlc3Npb25JZCA/IHRoaXMuc2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCkgOiB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChzZXNzaW9uSWQgJiYgIXNlc3Npb24pIHtcbiAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoNDA0LCB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgICAgICAgICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KHsgZXJyb3I6ICdpbnZhbGlkIHNlc3Npb24gaWQnIH0pKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgLy8g5paw5Lya6K+d77ya5Li65q+P5Liq5Lya6K+d5Yib5bu654us56uL55qEIE1jcFNlcnZlciDlrp7kvovvvIzpgb/lhY0gUHJvdG9jb2wg6YeN5aSN6L+e5o6l5oql6ZSZXG4gICAgICAgICAgICAgICAgY29uc3QgZGVwcyA9IHRoaXMuZGVwcztcbiAgICAgICAgICAgICAgICBpZiAoIWRlcHMpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzLndyaXRlSGVhZCg1MDMsIHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IGVycm9yOiAnc2VydmVyIG5vdCByZWFkeScgfSkpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHRyYW5zcG9ydCA9IG5ldyBTdHJlYW1hYmxlSFRUUFNlcnZlclRyYW5zcG9ydCh7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZEdlbmVyYXRvcjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNpZCA9IHRyYW5zcG9ydC5zZXNzaW9uSWQgYXMgc3RyaW5nO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1jcCA9IHRoaXMuYnVpbGRTZXJ2ZXIoZGVwcyk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbiA9IHsgdHJhbnNwb3J0LCBtY3AgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb25zLnNldChzaWQsIHNlc3Npb24pO1xuICAgICAgICAgICAgICAgIHRyYW5zcG9ydC5vbmNsb3NlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9ucy5nZXQoc2lkKSA9PT0gc2Vzc2lvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9ucy5kZWxldGUoc2lkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgYXdhaXQgbWNwLmNvbm5lY3QodHJhbnNwb3J0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZEJvZHkgPSByZXEubWV0aG9kID09PSAnUE9TVCcgPyBhd2FpdCB0aGlzLnJlYWRCb2R5KHJlcSkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBhd2FpdCBzZXNzaW9uLnRyYW5zcG9ydC5oYW5kbGVSZXF1ZXN0KHJlcSwgcmVzLCBwYXJzZWRCb2R5KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoNTAwLCB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogU3RyaW5nKGVycikgfSkpO1xuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgLyogaWdub3JlICovXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiog5rOo5YaM5bel5YW36ZuG44CCICovXG4gICAgcHJpdmF0ZSBidWlsZFNlcnZlcihkZXBzOiBNY3BEZXBzKTogTWNwU2VydmVyIHtcbiAgICAgICAgY29uc3QgbWNwID0gbmV3IE1jcFNlcnZlcih7IG5hbWU6ICd5eWthLXJ1bnRpbWUtaW5zcGVjdG9yJywgdmVyc2lvbjogJzEuMC4wJyB9KTtcbiAgICAgICAgY29uc3Qgbm9DbGllbnQgPSAoKTogYm9vbGVhbiA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdCA9IGRlcHMuZ2V0U2VydmVyU3RhdGUoKTtcbiAgICAgICAgICAgIHJldHVybiAhc3QucnVubmluZyB8fCBzdC5jbGllbnRzID09PSAwO1xuICAgICAgICB9O1xuXG4gICAgICAgIG1jcC5yZWdpc3RlclRvb2woXG4gICAgICAgICAgICAnZ2V0X3J1bnRpbWVfaW5mbycsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICfojrflj5bov5DooYzml7bkv6Hmga8nLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAn6I635Y+W5b2T5YmN6L+e5o6l55qE5ri45oiP5a6e5L6L5L+h5oGv77ya6L+e5o6l54q25oCB44CB5Zy65pmv5ZCN44CB6IqC54K55pWw6YeP44CBRlBT44CBRHJhd0NhbGzjgIHkuInop5LlvaLmlbDjgIHlhoXlrZjljaDnlKjjgIHniannkIbns7vnu5/nirbmgIHjgIHmoaXmjqXniYjmnKzjgILmuLjmiI/mnKrov57mjqXml7bov5Tlm57plJnor6/jgIInLFxuICAgICAgICAgICAgICAgIGlucHV0U2NoZW1hOiB6Lm9iamVjdCh7fSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub0NsaWVudCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfmuLjmiI/mnKrov57mjqXvvJror7flhYjlkK/liqggV1Mg5pyN5Yqh44CB6L+Q6KGM5ri45oiP5bm256Gu6K6k5qGl5o6l6ISa5pys5bey6L+e5o6l44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IFtzdGF0cywgdHJlZV0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXBzLmNhbGxHYW1lKCdnZXQtc3RhdHMnLCB1bmRlZmluZWQsIDQwMDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVwcy5jYWxsR2FtZSgncXVlcnktdHJlZScsIHt9LCA0MDAwKSxcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0ID0gZGVwcy5nZXRTZXJ2ZXJTdGF0ZSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ganNvbih7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0ZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRzOiBzdC5jbGllbnRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgd3NQb3J0OiBzdC5wb3J0LFxuICAgICAgICAgICAgICAgICAgICAgICAgc2NlbmU6IHRyZWU/LnNjZW5lID8/ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUNvdW50OiBjb3VudE5vZGVzKHRyZWU/LnJvb3RzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRzOiBzdGF0cyA/PyB7fSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KGDojrflj5bov5DooYzml7bkv6Hmga/lpLHotKU6ICR7U3RyaW5nKGVycil9YCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBtY3AucmVnaXN0ZXJUb29sKFxuICAgICAgICAgICAgJ2dldF9ub2RlX3RyZWUnLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRpdGxlOiAn6I635Y+W6IqC54K55qCRJyxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICAgICAgICAgJ+iOt+WPluW9k+WJjeWcuuaZr+eahOi/kOihjOaXtuiKgueCueagke+8iOWQjeensC/mv4DmtLsv5bGC57qnL+e7hOS7tuaVsO+8ieOAguWPr+eUqCBmaWx0ZXIg5oyJ6IqC54K55ZCN562b6YCJ77ybbWF4X2RlcHRoIOmZkOWItuWxleW8gOa3seW6pumBv+WFjei+k+WHuui/h+Wkp+OAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ+aMieiKgueCueWQjeWFs+mUruWtl+etm+mAie+8iOWPr+mAie+8iScpLFxuICAgICAgICAgICAgICAgICAgICBtYXhfZGVwdGg6IHoubnVtYmVyKCkub3B0aW9uYWwoKS5kZXNjcmliZSgn5pyA5aSn5bGV5byA5rex5bqm77yM6buY6K6kIDIw77yI5Y+v6YCJ77yJJyksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXN5bmMgKGFyZ3M6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub0NsaWVudCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfmuLjmiI/mnKrov57mjqXjgIInLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJlZSA9IGF3YWl0IGRlcHMuY2FsbEdhbWUoJ3F1ZXJ5LXRyZWUnLCB7IGZpbHRlcjogYXJncz8uZmlsdGVyID8/ICcnIH0sIDgwMDApO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHJlZSAmJiBBcnJheS5pc0FycmF5KHRyZWUucm9vdHMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZXB0aCA9IHR5cGVvZiBhcmdzPy5tYXhfZGVwdGggPT09ICdudW1iZXInID8gTWF0aC5tYXgoMSwgTWF0aC5taW4oNTAsIGFyZ3MubWF4X2RlcHRoKSkgOiAyMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBqc29uKHsgc2NlbmU6IHRyZWUuc2NlbmUgPz8gJycsIHJvb3RzOiBwcnVuZVRyZWUodHJlZS5yb290cywgZGVwdGgpIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfojrflj5boioLngrnmoJHlpLHotKXjgIInLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoYOiOt+WPluiKgueCueagkeWksei0pTogJHtTdHJpbmcoZXJyKX1gLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIG1jcC5yZWdpc3RlclRvb2woXG4gICAgICAgICAgICAnZ2V0X25vZGVfaW5mbycsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICfojrflj5boioLngrnkv6Hmga8nLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAn5oyJ6IqC54K5IGlkIOiOt+WPluiKgueCueivpuaDhe+8muS9jee9ri/ml4vovawv57yp5pS+L+a/gOa0uy/lsYLnuqfnrYkgVHJhbnNmb3JtIOWxnuaAp++8jOS7peWPiuaJgOaciee7hOS7tuWPiuWFtuWPr+e8lui+keWxnuaAp++8iOWQq+aemuS4vuOAgeaVsOe7hOOAgeWQkemHj+OAgeminOiJsuOAgeW8leeUqOetie+8ieOAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IHouc3RyaW5nKCkuZGVzY3JpYmUoJ+iKgueCuSBpZO+8iOadpeiHqiBnZXRfbm9kZV90cmVl77yJJyksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXN5bmMgKGFyZ3M6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub0NsaWVudCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfmuLjmiI/mnKrov57mjqXjgIInLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFhcmdzPy5pZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dCgn57y65bCR5Y+C5pWwIGlk44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBkZXBzLmNhbGxHYW1lKCdnZXQtaW5zcGVjdG9yJywgeyBpZDogYXJncy5pZCB9LCA4MDAwKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHIgJiYgci5lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoU3RyaW5nKHIuZXJyb3IpLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ganNvbihyID8/IHt9KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoYOiOt+WPluiKgueCueS/oeaBr+Wksei0pTogJHtTdHJpbmcoZXJyKX1gLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIG1jcC5yZWdpc3RlclRvb2woXG4gICAgICAgICAgICAnc2V0X25vZGVfcHJvcGVydHknLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRpdGxlOiAn5L+u5pS56L+Q6KGM5pe25bGe5oCnJyxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICAgICAgICAgJ+S/ruaUuei/kOihjOS4reiKgueCueeahOWxnuaAp+OAguiKgueCuee6p++8mmZpZWxkIOWPliBwb3NpdGlvbi9ldWxlci9zY2FsZe+8iHZhbHVlIOS4uiB7eCx5LHp977yJ44CBYWN0aXZl77yIdmFsdWUg5Li6IGJvb2xlYW7vvInjgIFsYXllcu+8iHZhbHVlIOS4uiBudW1iZXLvvInjgILnu4Tku7bnuqfvvJrkvKAgY29tcCDnu4Tku7bntKLlvJXvvIgwIOi1t++8ieS4jiBrZXkg5bGe5oCn5ZCN77yMdmFsdWUg5Li65bGe5oCn5YC877yI5ZCR6YePL+minOiJsuS8oOWvueixoe+8jOaemuS4vuS8oOaVsOWtl++8ieOAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IHouc3RyaW5nKCkuZGVzY3JpYmUoJ+iKgueCuSBpZO+8iOadpeiHqiBnZXRfbm9kZV90cmVl77yJJyksXG4gICAgICAgICAgICAgICAgICAgIGZpZWxkOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ+iKgueCuee6p+Wtl+aute+8mnBvc2l0aW9uIHwgZXVsZXIgfCBzY2FsZSB8IGFjdGl2ZSB8IGxheWVyJyksXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB6LmFueSgpLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ+imgeWGmeWFpeeahOWAvCcpLFxuICAgICAgICAgICAgICAgICAgICBjb21wOiB6Lm51bWJlcigpLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ+e7hOS7tue0ouW8le+8iDAg6LW377yM5LiOIGdldF9ub2RlX2luZm8g55qEIGNvbXBvbmVudHMg6aG65bqP5LiA6Ie077yJJyksXG4gICAgICAgICAgICAgICAgICAgIGtleTogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKCfnu4Tku7blsZ7mgKflkI0nKSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhc3luYyAoYXJnczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vQ2xpZW50KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoJ+a4uOaIj+acqui/nuaOpeOAgicsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWFyZ3M/LmlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfnvLrlsJHlj4LmlbAgaWTjgIInLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZDogYW55ID0geyBpZDogYXJncy5pZCB9O1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFyZ3MuZmllbGQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXlsb2FkLmZpZWxkID0gYXJncy5maWVsZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBhcmdzLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXJncy5jb21wID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5jb21wID0gYXJncy5jb21wO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5rZXkgPSBhcmdzLmtleTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQudmFsdWUgPSBhcmdzLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBkZXBzLmNhbGxHYW1lKCdzZXQtcHJvcGVydHknLCBwYXlsb2FkLCA4MDAwKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHIgJiYgci5lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoU3RyaW5nKHIuZXJyb3IpLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ganNvbihyID8/IHsgb2s6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KGDkv67mlLnlsZ7mgKflpLHotKU6ICR7U3RyaW5nKGVycil9YCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBtY3AucmVnaXN0ZXJUb29sKFxuICAgICAgICAgICAgJ2dldF9zY3JlZW5zaG90JyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ+iOt+WPlua4uOaIj+aIquWbvicsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICfmipPlj5blvZPliY3muLjmiI/nlLvpnaLlubbov5Tlm57lm77niYfvvIhKUEVH77yJ77yM55So5LqO6KeG6KeJ6aqM6K+B5ri45oiP54q25oCB44CCJyxcbiAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe30pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobm9DbGllbnQoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dCgn5ri45oiP5pyq6L+e5o6l44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBkZXBzLmNhbGxHYW1lKCdjYXB0dXJlLWZyYW1lJywge30sIDYwMDApO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkYXRhVXJsID0gciAmJiB0eXBlb2Ygci5kYXRhID09PSAnc3RyaW5nJyA/IHIuZGF0YSA6ICcnO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBiYXNlNjQgPSBkYXRhVXJsLmluY2x1ZGVzKCcsJykgPyBkYXRhVXJsLnNwbGl0KCcsJylbMV0gOiBkYXRhVXJsO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWJhc2U2NCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoJ+aIquWbvuWksei0pe+8mua4uOaIj+S+p+acquiDveaNleiOt+eUu+mdouOAgicsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBbeyB0eXBlOiAnaW1hZ2UnLCBkYXRhOiBiYXNlNjQsIG1pbWVUeXBlOiAnaW1hZ2UvanBlZycgfV0sXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KGDmiKrlm77lpLHotKU6ICR7U3RyaW5nKGVycil9YCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBtY3AucmVnaXN0ZXJUb29sKFxuICAgICAgICAgICAgJ2dldF9sb2dzJyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ+iOt+WPlui/kOihjOaXtuaXpeW/lycsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICfojrflj5bmuLjmiI/kvqfmnIDov5HnmoTmjqfliLblj7Dml6Xlv5fvvIhjb25zb2xlLmxvZy93YXJuL2Vycm9y77yJ44CCbGV2ZWwg5Y+v6YCJIGxvZy93YXJuL2Vycm9y77yM6buY6K6k5YWo6YOo44CCJyxcbiAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgICAgICBsaW1pdDogei5udW1iZXIoKS5vcHRpb25hbCgpLmRlc2NyaWJlKCfov5Tlm57mnaHmlbDvvIzpu5jorqQgNTAnKSxcbiAgICAgICAgICAgICAgICAgICAgbGV2ZWw6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZSgn6L+H5ruk57qn5Yir77yaYWxsIHwgbG9nIHwgd2FybiB8IGVycm9yJyksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXN5bmMgKGFyZ3M6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxpbWl0ID0gdHlwZW9mIGFyZ3M/LmxpbWl0ID09PSAnbnVtYmVyJyA/IE1hdGgubWF4KDEsIE1hdGgubWluKDIwMCwgYXJncy5saW1pdCkpIDogNTA7XG4gICAgICAgICAgICAgICAgY29uc3QgbGV2ZWwgPSB0eXBlb2YgYXJncz8ubGV2ZWwgPT09ICdzdHJpbmcnID8gYXJncy5sZXZlbCA6ICdhbGwnO1xuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW1zID0gZGVwcy5nZXRMb2dzKGxpbWl0LCBsZXZlbCk7XG4gICAgICAgICAgICAgICAgaWYgKCFpdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoJ++8iOaaguaXoOaXpeW/l++8iScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBsaW5lcyA9IGl0ZW1zLm1hcCgoaXQ6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXQgJiYgaXQuZXZ0ID09PSAnY29uc29sZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhZyA9IGl0LmxldmVsID09PSAnZXJyb3InID8gJ0VSUk9SJyA6IGl0LmxldmVsID09PSAnd2FybicgPyAnV0FSTiAnIDogJ0xPRyAgJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtmbXRUKGl0LnQpfSBbJHt0YWd9XSAke2l0LnRleHR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoaXQgJiYgaXQuZXZ0ID09PSAnc3lzJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke2ZtdFQoaXQudCA/PyBEYXRlLm5vdygpKX0gW1NZU10gJHtpdC5tc2cgPz8gJyd9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoaXQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KGxpbmVzLmpvaW4oJ1xcbicpKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgbWNwLnJlZ2lzdGVyVG9vbChcbiAgICAgICAgICAgICd3YWl0JyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ+etieW+hScsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICfnrYnlvoXmjIflrprmr6vnp5LvvIgxLTYwMDAw77yJ77yM5bi455So5LqO562J5b6F5ri45oiP54q25oCB5Y+Y5YyW5ZCO5YaN5p+l6K+i44CCJyxcbiAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgICAgICBtczogei5udW1iZXIoKS5kZXNjcmliZSgn5q+r56eS5pWw77yMMS02MDAwMCcpLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFzeW5jIChhcmdzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBtcyA9IE1hdGgubWF4KDEsIE1hdGgubWluKDYwMDAwLCBOdW1iZXIoYXJncz8ubXMpIHx8IDApKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBtcykpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KGDlt7LnrYnlvoUgJHttc31tc2ApO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICBtY3AucmVnaXN0ZXJUb29sKFxuICAgICAgICAgICAgJ2V4ZWN1dGVfY29tbWFuZCcsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICfmiafooYzmuLjmiI/lkb3ku6QnLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAn5ZCR5ri45oiP5L6n5qGl5o6l6ISa5pys5Y+R6YCB5Lu75oSP5ZG95Luk44CC5bi455So77yaZ2V0LXN0YXRz44CBZ2V0LXJlc291cmNlLXN0YXRz44CBcXVlcnktcGh5c2ljc+OAgXNldC1wcmV2aWV3KHtlbmFibGVkLGZwc30p44CBc2V0LW11dGUoe211dGVkfSnjgIFzZXQtcGh5c2ljcy1kZWJ1Zyh7ZW5hYmxlZH0p44CCJyxcbiAgICAgICAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgICAgICBjbWQ6IHouc3RyaW5nKCkuZGVzY3JpYmUoJ+WRveS7pOWQjScpLFxuICAgICAgICAgICAgICAgICAgICBwYXlsb2FkOiB6LmFueSgpLm9wdGlvbmFsKCkuZGVzY3JpYmUoJ+WRveS7pOWPguaVsO+8iOWPr+mAie+8iScpLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFzeW5jIChhcmdzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobm9DbGllbnQoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dCgn5ri45oiP5pyq6L+e5o6l44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghYXJncz8uY21kKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfnvLrlsJHlj4LmlbAgY21k44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBkZXBzLmNhbGxHYW1lKFN0cmluZyhhcmdzLmNtZCksIGFyZ3MucGF5bG9hZCwgODAwMCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBqc29uKHIgPz8ge30pO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dChg5ZG95Luk5omn6KGM5aSx6LSlOiAke1N0cmluZyhlcnIpfWAsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgbWNwLnJlZ2lzdGVyVG9vbChcbiAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICfmqKHmi5/ngrnlh7snLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAn5qih5ouf5LiA5qyh6Kem5pG454K55Ye744CC5LygIGlkIOWImeeCueWHu+ivpeiKgueCue+8iOWPluWFtiBVSSDkuK3lv4PngrnvvInvvJvkvKAgeC95IOWImeeCueWHu+Wxj+W5le+8iFVJIOWdkOagh++8ieS4iuWRveS4reeahOacgOS4iuWxguiKgueCueOAguW4uOeUqOS6juinpuWPkeaMiemSruOAgeW8gOWni+a4uOaIj+etieaTjeS9nOOAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZSgn6IqC54K5IGlk77yI5p2l6IeqIGdldF9ub2RlX3RyZWXvvIknKSxcbiAgICAgICAgICAgICAgICAgICAgeDogei5udW1iZXIoKS5vcHRpb25hbCgpLmRlc2NyaWJlKCdVSSDmqKrlnZDmoIfvvIjkuI4gaWQg5LqM6YCJ5LiA77yJJyksXG4gICAgICAgICAgICAgICAgICAgIHk6IHoubnVtYmVyKCkub3B0aW9uYWwoKS5kZXNjcmliZSgnVUkg57q15Z2Q5qCH77yI5LiOIGlkIOS6jOmAieS4gO+8iScpLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFzeW5jIChhcmdzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobm9DbGllbnQoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dCgn5ri45oiP5pyq6L+e5o6l44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghYXJncz8uaWQgJiYgKHR5cGVvZiBhcmdzPy54ICE9PSAnbnVtYmVyJyB8fCB0eXBlb2YgYXJncz8ueSAhPT0gJ251bWJlcicpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfpnIDopoHlj4LmlbAgaWTvvIjoioLngrkgaWTvvInmiJYgeC9577yIVUkg5Z2Q5qCH77yJ44CCJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQ6IGFueSA9IHt9O1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFyZ3MuaWQgPT09ICdzdHJpbmcnICYmIGFyZ3MuaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQuaWQgPSBhcmdzLmlkO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC54ID0gYXJncy54O1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC55ID0gYXJncy55O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSBhd2FpdCBkZXBzLmNhbGxHYW1lKCdzaW11bGF0ZS1jbGljaycsIHBheWxvYWQsIDgwMDApO1xuICAgICAgICAgICAgICAgICAgICBpZiAociAmJiByLmVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dChTdHJpbmcoci5lcnJvciksIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBqc29uKHIgPz8geyBvazogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoYOaooeaLn+eCueWHu+Wksei0pTogJHtTdHJpbmcoZXJyKX1gLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIG1jcC5yZWdpc3RlclRvb2woXG4gICAgICAgICAgICAnbGlzdF9zY2VuZXMnLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRpdGxlOiAn5YiX5Ye65Zy65pmvJyxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ+WIl+WHuuW9k+WJjei/kOihjOWcuuaZr+WPiuW3suWKoOi9veWcuuaZr+WQje+8jOeUqOS6juehruiupOi3s+i9rOebruagh+OAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHt9KSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vQ2xpZW50KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoJ+a4uOaIj+acqui/nuaOpeOAgicsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByID0gYXdhaXQgZGVwcy5jYWxsR2FtZSgnbGlzdC1zY2VuZXMnLCB7fSwgNjAwMCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBqc29uKHIgPz8geyBjdXJyZW50OiAnJywgc2NlbmVzOiBbXSB9KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRleHQoYOWIl+WHuuWcuuaZr+Wksei0pTogJHtTdHJpbmcoZXJyKX1gLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIG1jcC5yZWdpc3RlclRvb2woXG4gICAgICAgICAgICAnbG9hZF9zY2VuZScsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICfot7PovazlnLrmma8nLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAn6L+Q6KGM5pe25Yqg6L295oyH5a6a5ZCN56ew55qE5Zy65pmv77yI5Zy65pmv6Lez6L2s77yJ44CC5Zy65pmv5ZCN5Y+v5YWI6YCa6L+HIGxpc3Rfc2NlbmVzIOafpeeci+OAgicsXG4gICAgICAgICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogei5zdHJpbmcoKS5kZXNjcmliZSgn5Zy65pmv5ZCNJyksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXN5bmMgKGFyZ3M6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub0NsaWVudCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfmuLjmiI/mnKrov57mjqXjgIInLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFhcmdzPy5uYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KCfnvLrlsJHlj4LmlbAgbmFtZeOAgicsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByID0gYXdhaXQgZGVwcy5jYWxsR2FtZSgnbG9hZC1zY2VuZScsIHsgbmFtZTogU3RyaW5nKGFyZ3MubmFtZSkgfSwgNjAwMCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyICYmIHIuZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0KFN0cmluZyhyLmVycm9yKSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGpzb24ociA/PyB7IG9rOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dChg6Lez6L2s5Zy65pmv5aSx6LSlOiAke1N0cmluZyhlcnIpfWAsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIG1jcDtcbiAgICB9XG5cbiAgICAvKiog5ZCv5YqoIEhUVFAg5pyN5Yqh44CCcG9ydCDooqvljaDnlKjml7bmipvplJnjgIIgKi9cbiAgICBhc3luYyBzdGFydChwb3J0OiBudW1iZXIsIHRva2VuOiBzdHJpbmcsIGRlcHM6IE1jcERlcHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMuc3J2KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50b2tlbiA9IHRva2VuO1xuICAgICAgICB0aGlzLmRlcHMgPSBkZXBzO1xuICAgICAgICBjb25zdCBzcnYgPSBodHRwLmNyZWF0ZVNlcnZlcigocmVxLCByZXMpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlKHJlcSwgcmVzKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgLyogaGFuZGxlZCBpbnNpZGUgKi9cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb25FcnJvciA9IChlcnI6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgc3J2LnJlbW92ZUxpc3RlbmVyKCdsaXN0ZW5pbmcnLCBvbkxpc3RlbmluZyk7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3Qgb25MaXN0ZW5pbmcgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgc3J2LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzcnYub25jZSgnZXJyb3InLCBvbkVycm9yKTtcbiAgICAgICAgICAgIHNydi5vbmNlKCdsaXN0ZW5pbmcnLCBvbkxpc3RlbmluZyk7XG4gICAgICAgICAgICBzcnYubGlzdGVuKHBvcnQsICcxMjcuMC4wLjEnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc3J2ID0gc3J2O1xuICAgICAgICB0aGlzLnBvcnQgPSBwb3J0O1xuICAgIH1cblxuICAgIC8qKiDlgZzmraLmnI3liqHlubblhbPpl63miYDmnInkvJror53jgIIgKi9cbiAgICBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBzcnYgPSB0aGlzLnNydjtcbiAgICAgICAgdGhpcy5zcnYgPSBudWxsO1xuICAgICAgICB0aGlzLnBvcnQgPSAwO1xuICAgICAgICB0aGlzLmRlcHMgPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IHsgdHJhbnNwb3J0IH0gb2YgdGhpcy5zZXNzaW9ucy52YWx1ZXMoKSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgIC8qIGlnbm9yZSAqL1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2Vzc2lvbnMuY2xlYXIoKTtcbiAgICAgICAgaWYgKHNydikge1xuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHNydi5jbG9zZSgoKSA9PiByZXNvbHZlKCkpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/dist/panels/default/computed.js b/extensions/YYKA运行时工作台/dist/panels/default/computed.js new file mode 100644 index 0000000..c5b07ac --- /dev/null +++ b/extensions/YYKA运行时工作台/dist/panels/default/computed.js @@ -0,0 +1,69 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = { + flatTree() { + var _a; + const out = []; + this.flatten((_a = this.tree.roots) !== null && _a !== void 0 ? _a : [], 0, out); + return out; + }, + /** 节点选择弹层:全部节点(不依赖展开状态)+ 搜索过滤。 */ + pickerRows() { + var _a; + const out = []; + const walk = (nodes, depth) => { + for (const n of nodes) { + const row = n; + row.depth = depth; + row.hasChildren = !!(n.children && n.children.length); + out.push(row); + if (row.hasChildren) { + walk(n.children, depth + 1); + } + } + }; + walk((_a = this.tree.roots) !== null && _a !== void 0 ? _a : [], 0); + const f = (this.nodePicker.filter || '').trim().toLowerCase(); + return f ? out.filter((r) => r.name.toLowerCase().includes(f)) : out; + }, + /** 资产选择弹层:按类型过滤 + 搜索过滤。 */ + assetRows() { + let rows = this.assetPicker.list; + if (this.assetPicker.type) { + rows = rows.filter((r) => r.type === this.assetPicker.type); + } + const f = (this.assetPicker.filter || '').trim().toLowerCase(); + if (f) { + rows = rows.filter((r) => (r.name || '').toLowerCase().includes(f) || (r.type || '').toLowerCase().includes(f)); + } + return rows; + }, + filteredLogs() { + const f = this.logFilter; + if (f === 'all') { + return this.logs; + } + return this.logs.filter((l) => { + const m = l && typeof l === 'object' ? l : null; + if (m && m.evt === 'console') { + return m.level === f; + } + return true; // 非 console 消息(sys/写回提示)始终显示 + }); + }, + clientTypeMeta() { + switch (this.state.clientType) { + case 'h5': + return { label: '浏览器', cls: 'h5' }; + case 'editor': + return { label: '编辑器', cls: 'editor' }; + case 'simulator': + return { label: '模拟器', cls: 'simulator' }; + case 'device': + return { label: '真机', cls: 'device' }; + default: + return { label: '未知?', cls: 'unknown' }; + } + }, +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcHV0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zb3VyY2UvcGFuZWxzL2RlZmF1bHQvY29tcHV0ZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSxrQkFBZTtJQUNYLFFBQVE7O1FBQ0osTUFBTSxHQUFHLEdBQWMsRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssbUNBQUksRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUM1QyxPQUFPLEdBQUcsQ0FBQztJQUNmLENBQUM7SUFDRCxrQ0FBa0M7SUFDbEMsVUFBVTs7UUFDTixNQUFNLEdBQUcsR0FBYyxFQUFFLENBQUM7UUFDMUIsTUFBTSxJQUFJLEdBQUcsQ0FBQyxLQUFpQixFQUFFLEtBQWEsRUFBRSxFQUFFO1lBQzlDLEtBQUssTUFBTSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sR0FBRyxHQUFHLENBQVksQ0FBQztnQkFDekIsR0FBRyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7Z0JBQ2xCLEdBQUcsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN0RCxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNkLElBQUksR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUNsQixJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hDLENBQUM7WUFDTCxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLE1BQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLG1DQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvQixNQUFNLENBQUMsR0FBRyxD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SixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBUcmVlTm9kZSwgVHJlZVJvdyB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgZmxhdFRyZWUodGhpczogYW55KTogVHJlZVJvd1tdIHtcbiAgICAgICAgY29uc3Qgb3V0OiBUcmVlUm93W10gPSBbXTtcbiAgICAgICAgdGhpcy5mbGF0dGVuKHRoaXMudHJlZS5yb290cyA/PyBbXSwgMCwgb3V0KTtcbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9LFxuICAgIC8qKiDoioLngrnpgInmi6nlvLnlsYLvvJrlhajpg6joioLngrnvvIjkuI3kvp3otZblsZXlvIDnirbmgIHvvIkrIOaQnOe0oui/h+a7pOOAgiAqL1xuICAgIHBpY2tlclJvd3ModGhpczogYW55KTogVHJlZVJvd1tdIHtcbiAgICAgICAgY29uc3Qgb3V0OiBUcmVlUm93W10gPSBbXTtcbiAgICAgICAgY29uc3Qgd2FsayA9IChub2RlczogVHJlZU5vZGVbXSwgZGVwdGg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgZm9yIChjb25zdCBuIG9mIG5vZGVzKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgcm93ID0gbiBhcyBUcmVlUm93O1xuICAgICAgICAgICAgICAgIHJvdy5kZXB0aCA9IGRlcHRoO1xuICAgICAgICAgICAgICAgIHJvdy5oYXNDaGlsZHJlbiA9ICEhKG4uY2hpbGRyZW4gJiYgbi5jaGlsZHJlbi5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIG91dC5wdXNoKHJvdyk7XG4gICAgICAgICAgICAgICAgaWYgKHJvdy5oYXNDaGlsZHJlbikge1xuICAgICAgICAgICAgICAgICAgICB3YWxrKG4uY2hpbGRyZW4sIGRlcHRoICsgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB3YWxrKHRoaXMudHJlZS5yb290cyA/PyBbXSwgMCk7XG4gICAgICAgIGNvbnN0IGYgPSAodGhpcy5ub2RlUGlja2VyLmZpbHRlciB8fCAnJykudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiBmID8gb3V0LmZpbHRlcigocikgPT4gci5uYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoZikpIDogb3V0O1xuICAgIH0sXG4gICAgLyoqIOi1hOS6p+mAieaLqeW8ueWxgu+8muaMieexu+Wei+i/h+a7pCArIOaQnOe0oui/h+a7pOOAgiAqL1xuICAgIGFzc2V0Um93cyh0aGlzOiBhbnkpOiB7IG5hbWU6IHN0cmluZzsgdXVpZDogc3RyaW5nOyB0eXBlOiBzdHJpbmcgfVtdIHtcbiAgICAgICAgbGV0IHJvd3M6IHsgbmFtZTogc3RyaW5nOyB1dWlkOiBzdHJpbmc7IHR5cGU6IHN0cmluZyB9W10gPSB0aGlzLmFzc2V0UGlja2VyLmxpc3Q7XG4gICAgICAgIGlmICh0aGlzLmFzc2V0UGlja2VyLnR5cGUpIHtcbiAgICAgICAgICAgIHJvd3MgPSByb3dzLmZpbHRlcigocikgPT4gci50eXBlID09PSB0aGlzLmFzc2V0UGlja2VyLnR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGYgPSAodGhpcy5hc3NldFBpY2tlci5maWx0ZXIgfHwgJycpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoZikge1xuICAgICAgICAgICAgcm93cyA9IHJvd3MuZmlsdGVyKChyKSA9PiAoci5uYW1lIHx8ICcnKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGYpIHx8IChyLnR5cGUgfHwgJycpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoZikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByb3dzO1xuICAgIH0sXG4gICAgZmlsdGVyZWRMb2dzKHRoaXM6IGFueSk6IHVua25vd25bXSB7XG4gICAgICAgIGNvbnN0IGYgPSB0aGlzLmxvZ0ZpbHRlcjtcbiAgICAgICAgaWYgKGYgPT09ICdhbGwnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sb2dzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmxvZ3MuZmlsdGVyKChsOiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtID0gbCAmJiB0eXBlb2YgbCA9PT0gJ29iamVjdCcgPyAobCBhcyBhbnkpIDogbnVsbDtcbiAgICAgICAgICAgIGlmIChtICYmIG0uZXZ0ID09PSAnY29uc29sZScpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbS5sZXZlbCA9PT0gZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlOyAvLyDpnZ4gY29uc29sZSDmtojmga/vvIhzeXMv5YaZ5Zue5o+Q56S677yJ5aeL57uI5pi+56S6XG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgY2xpZW50VHlwZU1ldGEodGhpczogYW55KTogeyBsYWJlbDogc3RyaW5nOyBjbHM6IHN0cmluZyB9IHtcbiAgICAgICAgc3dpdGNoICh0aGlzLnN0YXRlLmNsaWVudFR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2g1JzpcbiAgICAgICAgICAgICAgICByZXR1cm4geyBsYWJlbDogJ+a1j+iniOWZqCcsIGNsczogJ2g1JyB9O1xuICAgICAgICAgICAgY2FzZSAnZWRpdG9yJzpcbiAgICAgICAgICAgICAgICByZXR1cm4geyBsYWJlbDogJ+e8lui+keWZqCcsIGNsczogJ2VkaXRvcicgfTtcbiAgICAgICAgICAgIGNhc2UgJ3NpbXVsYXRvcic6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgbGFiZWw6ICfmqKHmi5/lmagnLCBjbHM6ICdzaW11bGF0b3InIH07XG4gICAgICAgICAgICBjYXNlICdkZXZpY2UnOlxuICAgICAgICAgICAgICAgIHJldHVybiB7IGxhYmVsOiAn55yf5py6JywgY2xzOiAnZGV2aWNlJyB9O1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4geyBsYWJlbDogJ+acquefpT8nLCBjbHM6ICd1bmtub3duJyB9O1xuICAgICAgICB9XG4gICAgfSxcbn07XG4iXX0= \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/dist/panels/default/index.js b/extensions/YYKA运行时工作台/dist/panels/default/index.js new file mode 100644 index 0000000..5b049fc --- /dev/null +++ b/extensions/YYKA运行时工作台/dist/panels/default/index.js @@ -0,0 +1,65 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs_extra_1 = require("fs-extra"); +const path_1 = require("path"); +const vue_1 = require("vue"); +const state_1 = __importDefault(require("./state")); +const computed_1 = __importDefault(require("./computed")); +const watch_1 = __importDefault(require("./watch")); +const lifecycle_1 = require("./lifecycle"); +const utils_1 = __importDefault(require("./methods/utils")); +const tree_1 = __importDefault(require("./methods/tree")); +const inspector_1 = __importDefault(require("./methods/inspector")); +const pickers_1 = __importDefault(require("./methods/pickers")); +const logs_1 = __importDefault(require("./methods/logs")); +const perf_1 = __importDefault(require("./methods/perf")); +const res_1 = __importDefault(require("./methods/res")); +const preview_1 = __importDefault(require("./methods/preview")); +const mcp_1 = __importDefault(require("./methods/mcp")); +const server_1 = __importDefault(require("./methods/server")); +const panelDataMap = new WeakMap(); +/** 根组件:由各功能域模块组合而成(状态/计算/监听/生命周期/方法全部拆分到独立文件)。 */ +const rootComponent = (0, vue_1.defineComponent)({ + data: state_1.default, + computed: computed_1.default, + watch: watch_1.default, + mounted: lifecycle_1.mounted, + beforeUnmount: lifecycle_1.beforeUnmount, + methods: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, utils_1.default), tree_1.default), inspector_1.default), pickers_1.default), logs_1.default), perf_1.default), res_1.default), preview_1.default), mcp_1.default), server_1.default), + template: (0, fs_extra_1.readFileSync)((0, path_1.join)(__dirname, '../../../static/template/default/app.html'), 'utf-8'), +}); +module.exports = Editor.Panel.define({ + listeners: { + show() { + console.log('show'); + }, + hide() { + console.log('hide'); + }, + }, + template: (0, fs_extra_1.readFileSync)((0, path_1.join)(__dirname, '../../../static/template/default/index.html'), 'utf-8'), + style: (0, fs_extra_1.readFileSync)((0, path_1.join)(__dirname, '../../../static/style/default/index.css'), 'utf-8'), + $: { + app: '#app', + }, + methods: {}, + ready() { + if (this.$.app) { + const app = (0, vue_1.createApp)(rootComponent); + app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('ui-'); + app.mount(this.$.app); + panelDataMap.set(this, app); + } + }, + beforeClose() { }, + close() { + const app = panelDataMap.get(this); + if (app) { + app.unmount(); + } + }, +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zb3VyY2UvcGFuZWxzL2RlZmF1bHQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSx1Q0FBd0M7QUFDeEMsK0JBQTRCO0FBQzVCLDZCQUFzRDtBQUV0RCxvREFBZ0M7QUFDaEMsMERBQWtDO0FBQ2xDLG9EQUE0QjtBQUM1QiwyQ0FBcUQ7QUFDckQsNERBQW9DO0FBQ3BDLDBEQUFrQztBQUNsQyxvRUFBNEM7QUFDNUMsZ0VBQXdDO0FBQ3hDLDBEQUFrQztBQUNsQywwREFBa0M7QUFDbEMsd0RBQWdDO0FBQ2hDLGdFQUF3QztBQUN4Qyx3REFBZ0M7QUFDaEMsOERBQXNDO0FBRXRDLE1BQU0sWUFBWSxHQUFHLElBQUksT0FBTyxFQUFZLENBQUM7QUFFN0Msa0RBQWtEO0FBQ2xELE1BQU0sYUFBYSxHQUFHLElBQUEscUJBQWUsRUFBQztJQUNsQyxJQUFJLEVBQUUsZUFBUztJQUNmLFFBQVEsRUFBUixrQkFBUTtJQUNSLEtBQUssRUFBTCxlQUFLO0lBQ0wsT0FBTyxFQUFQLG1CQUFPO0lBQ1AsYUFBYSxFQUFiLHlCQUFhO0lBQ2IsT0FBTyxrSkFDQSxlQUFLLEdBQ0wsY0FBSSxHQUNKLG1CQUFTLEdBQ1QsaUJBQU8sR0FDUCxjQUFJLEdBQ0osY0FBSSxHQUNKLGFBQUcsR0FDSCxpQkFBTyxHQUNQLGFBQUcsR0FDSCxnQkFBTSxDQUNaO0lBQ0QsUUFBUSxFQUFFLElBQUEsdUJBQVksRUFBQyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsMkNBQTJDLENBQUMsRUFBRSxPQUFPLENBQUM7Q0FDaEcsQ0FBQyxDQUFDO0FBRUgsTUFBTSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztJQUNqQyxTQUFTLEVBQUU7UUFDUCxJQUFJO1lBQ0EsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4QixDQUFDO1FBQ0QsSUFBSTtZQUNBLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEIsQ0FBQztLQUNKO0lBQ0QsUUFBUSxFQUFFLElBQUEsdUJBQVksRUFBQyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsNkNBQTZDLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDL0YsS0FBSyxFQUFFLElBQUEsdUJBQVksRUFBQyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUseUNBQXlDLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDeEYsQ0FBQyxFQUFFO1FBQ0MsR0FBRyxFQUFFLE1BQU07S0FDZDtJQUNELE9BQU8sRUFBRSxFQUFFO0lBQ1gsS0FBSztRQUNELElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNiLE1BQU0sR0FBRyxHQUFHLElBQUEsZUFBUyxFQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3JDLEdBQUcsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLGVBQWUsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM1RSxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdEIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDaEMsQ0FBQztJQUNMLENBQUM7SUFDRCxXQUFXLEtBQUksQ0FBQztJQUNoQixLQUFLO1FBQ0QsTUFBTSxHQUFHLEdBQUcsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQ04sR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2xCLENBQUM7SUFDTCxDQUFDO0NBQ0osQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgY3JlYXRlQXBwLCBBcHAsIGRlZmluZUNvbXBvbmVudCB9IGZyb20gJ3Z1ZSc7XG5cbmltcG9ydCBzdGF0ZURhdGEgZnJvbSAnLi9zdGF0ZSc7XG5pbXBvcnQgY29tcHV0ZWQgZnJvbSAnLi9jb21wdXRlZCc7XG5pbXBvcnQgd2F0Y2ggZnJvbSAnLi93YXRjaCc7XG5pbXBvcnQgeyBtb3VudGVkLCBiZWZvcmVVbm1vdW50IH0gZnJvbSAnLi9saWZlY3ljbGUnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4vbWV0aG9kcy91dGlscyc7XG5pbXBvcnQgdHJlZSBmcm9tICcuL21ldGhvZHMvdHJlZSc7XG5pbXBvcnQgaW5zcGVjdG9yIGZyb20gJy4vbWV0aG9kcy9pbnNwZWN0b3InO1xuaW1wb3J0IHBpY2tlcnMgZnJvbSAnLi9tZXRob2RzL3BpY2tlcnMnO1xuaW1wb3J0IGxvZ3MgZnJvbSAnLi9tZXRob2RzL2xvZ3MnO1xuaW1wb3J0IHBlcmYgZnJvbSAnLi9tZXRob2RzL3BlcmYnO1xuaW1wb3J0IHJlcyBmcm9tICcuL21ldGhvZHMvcmVzJztcbmltcG9ydCBwcmV2aWV3IGZyb20gJy4vbWV0aG9kcy9wcmV2aWV3JztcbmltcG9ydCBtY3AgZnJvbSAnLi9tZXRob2RzL21jcCc7XG5pbXBvcnQgc2VydmVyIGZyb20gJy4vbWV0aG9kcy9zZXJ2ZXInO1xuXG5jb25zdCBwYW5lbERhdGFNYXAgPSBuZXcgV2Vha01hcDxhbnksIEFwcD4oKTtcblxuLyoqIOaguee7hOS7tu+8mueUseWQhOWKn+iDveWfn+aooeWdl+e7hOWQiOiAjOaIkO+8iOeKtuaAgS/orqHnrpcv55uR5ZCsL+eUn+WRveWRqOacny/mlrnms5Xlhajpg6jmi4bliIbliLDni6znq4vmlofku7bvvInjgIIgKi9cbmNvbnN0IHJvb3RDb21wb25lbnQgPSBkZWZpbmVDb21wb25lbnQoe1xuICAgIGRhdGE6IHN0YXRlRGF0YSxcbiAgICBjb21wdXRlZCxcbiAgICB3YXRjaCxcbiAgICBtb3VudGVkLFxuICAgIGJlZm9yZVVubW91bnQsXG4gICAgbWV0aG9kczoge1xuICAgICAgICAuLi51dGlscyxcbiAgICAgICAgLi4udHJlZSxcbiAgICAgICAgLi4uaW5zcGVjdG9yLFxuICAgICAgICAuLi5waWNrZXJzLFxuICAgICAgICAuLi5sb2dzLFxuICAgICAgICAuLi5wZXJmLFxuICAgICAgICAuLi5yZXMsXG4gICAgICAgIC4uLnByZXZpZXcsXG4gICAgICAgIC4uLm1jcCxcbiAgICAgICAgLi4uc2VydmVyLFxuICAgIH0sXG4gICAgdGVtcGxhdGU6IHJlYWRGaWxlU3luYyhqb2luKF9fZGlybmFtZSwgJy4uLy4uLy4uL3N0YXRpYy90ZW1wbGF0ZS9kZWZhdWx0L2FwcC5odG1sJyksICd1dGYtOCcpLFxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gRWRpdG9yLlBhbmVsLmRlZmluZSh7XG4gICAgbGlzdGVuZXJzOiB7XG4gICAgICAgIHNob3coKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnc2hvdycpO1xuICAgICAgICB9LFxuICAgICAgICBoaWRlKCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ2hpZGUnKTtcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIHRlbXBsYXRlOiByZWFkRmlsZVN5bmMoam9pbihfX2Rpcm5hbWUsICcuLi8uLi8uLi9zdGF0aWMvdGVtcGxhdGUvZGVmYXVsdC9pbmRleC5odG1sJyksICd1dGYtOCcpLFxuICAgIHN0eWxlOiByZWFkRmlsZVN5bmMoam9pbihfX2Rpcm5hbWUsICcuLi8uLi8uLi9zdGF0aWMvc3R5bGUvZGVmYXVsdC9pbmRleC5jc3MnKSwgJ3V0Zi04JyksXG4gICAgJDoge1xuICAgICAgICBhcHA6ICcjYXBwJyxcbiAgICB9LFxuICAgIG1ldGhvZHM6IHt9LFxuICAgIHJlYWR5KCkge1xuICAgICAgICBpZiAodGhpcy4kLmFwcCkge1xuICAgICAgICAgICAgY29uc3QgYXBwID0gY3JlYXRlQXBwKHJvb3RDb21wb25lbnQpO1xuICAgICAgICAgICAgYXBwLmNvbmZpZy5jb21waWxlck9wdGlvbnMuaXNDdXN0b21FbGVtZW50ID0gKHRhZykgPT4gdGFnLnN0YXJ0c1dpdGgoJ3VpLScpO1xuICAgICAgICAgICAgYXBwLm1vdW50KHRoaXMuJC5hcHApO1xuICAgICAgICAgICAgcGFuZWxEYXRhTWFwLnNldCh0aGlzLCBhcHApO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBiZWZvcmVDbG9zZSgpIHt9LFxuICAgIGNsb3NlKCkge1xuICAgICAgICBjb25zdCBhcHAgPSBwYW5lbERhdGFNYXAuZ2V0KHRoaXMpO1xuICAgICAgICBpZiAoYXBwKSB7XG4gICAgICAgICAgICBhcHAudW5tb3VudCgpO1xuICAgICAgICB9XG4gICAgfSxcbn0pO1xuIl19 \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/dist/panels/default/lifecycle.js b/extensions/YYKA运行时工作台/dist/panels/default/lifecycle.js new file mode 100644 index 0000000..55fe32e --- /dev/null +++ b/extensions/YYKA运行时工作台/dist/panels/default/lifecycle.js @@ -0,0 +1,56 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mounted = mounted; +exports.beforeUnmount = beforeUnmount; +/** 一次性清理:幂等,可安全地被卸载流程 + 窗口 unload 事件重复触发。 + * 拖出为浮窗后关闭时,Cocos 不一定会调用面板 close()/unmount(), + * 因此额外监听 pagehide/beforeunload 兜底,避免预览引擎、游戏 DOM、定时器残留。 */ +function doDispose() { + if (this._disposed) + return; + this._disposed = true; + window.clearInterval(this.interval); + window.clearInterval(this.perfTimer); + window.clearInterval(this.resTimer); + window.clearTimeout(this.filterTimer); + window.clearTimeout(this.copyTimer); + window.clearTimeout(this.mcpCopyTimer); + if (this.stopHostSync) + this.stopHostSync(); // 停止游戏宿主定期同步 + if (this.teardownPreview) + this.teardownPreview(); // 停主循环/调度器/音频、释放资源 + try { + const host = document.getElementById('yyka-game-host'); + if (host) + host.remove(); // 移除顶层游戏 DOM,避免浮窗关闭后画面残留 + } + catch (_) { /* ignore */ } + window.removeEventListener('pointermove', this.onDragMove); + window.removeEventListener('pointerup', this.endDrag); + window.removeEventListener('pointercancel', this.endDrag); + window.removeEventListener('resize', this.onResize); + window.removeEventListener('pagehide', this._onPageHide); + window.removeEventListener('beforeunload', this._onPageHide); +} +async function mounted() { + this.ensureServer(); + this.refresh(); + await this.initPreviewInfo(); + this.$nextTick(() => this.renderPreview()); + this.loadMcpState(); + this.interval = window.setInterval(() => this.refresh(), 1000); + window.addEventListener('pointermove', this.onDragMove); + window.addEventListener('pointerup', this.endDrag); + window.addEventListener('pointercancel', this.endDrag); + window.addEventListener('resize', this.onResize); + // 拖出为独立浮窗后直接关窗时,仅关窗口不触发下文的 beforeUnmount,需在此兜底清理 + this._onPageHide = () => doDispose.call(this); + window.addEventListener('pagehide', this._onPageHide); + window.addEventListener('beforeunload', this._onPageHide); +} +function beforeUnmount() { + window.removeEventListener('pagehide', this._onPageHide); + window.removeEventListener('beforeunload', this._onPageHide); + doDispose.call(this); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlmZWN5Y2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc291cmNlL3BhbmVscy9kZWZhdWx0L2xpZmVjeWNsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTBCQSwwQkFlQztBQUVELHNDQUlDO0FBL0NEOzsyREFFMkQ7QUFDM0QsU0FBUyxTQUFTO0lBQ2QsSUFBSSxJQUFJLENBQUMsU0FBUztRQUFFLE9BQU87SUFDM0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7SUFDdEIsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDcEMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDckMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDcEMsTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDdEMsTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDcEMsTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDdkMsSUFBSSxJQUFJLENBQUMsWUFBWTtRQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLGFBQWE7SUFDekQsSUFBSSxJQUFJLENBQUMsZUFBZTtRQUFFLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDLG1CQUFtQjtJQUNyRSxJQUFJLENBQUM7UUFDRCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDdkQsSUFBSSxJQUFJO1lBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMseUJBQXlCO0lBQ3RELENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDNUIsTUFBTSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDM0QsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDMUQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDcEQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDekQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDakUsQ0FBQztBQUVNLEtBQUssVUFBVSxPQUFPO0lBQ3pCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNwQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDZixNQUFNLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUM3QixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNwQixJQUFJLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQy9ELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3hELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ25ELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2pELGlEQUFpRDtJQUNqRCxJQUFJLENBQUMsV0FBVyxHQUFHLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDOUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDdEQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDOUQsQ0FBQztBQUVELFNBQWdCLGFBQWE7SUFDekIsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDekQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDN0QsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN6QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIOS4gOasoeaAp+a4heeQhu+8muW5guetie+8jOWPr+WuieWFqOWcsOiiq+WNuOi9vea1geeoiyArIOeql+WPoyB1bmxvYWQg5LqL5Lu26YeN5aSN6Kem5Y+R44CCXG4gKiAg5ouW5Ye65Li65rWu56qX5ZCO5YWz6Zet5pe277yMQ29jb3Mg5LiN5LiA5a6a5Lya6LCD55So6Z2i5p2/IGNsb3NlKCkvdW5tb3VudCgp77yMXG4gKiAg5Zug5q2k6aKd5aSW55uR5ZCsIHBhZ2VoaWRlL2JlZm9yZXVubG9hZCDlhZzlupXvvIzpgb/lhY3pooTop4jlvJXmk47jgIHmuLjmiI8gRE9N44CB5a6a5pe25Zmo5q6L55WZ44CCICovXG5mdW5jdGlvbiBkb0Rpc3Bvc2UodGhpczogYW55KSB7XG4gICAgaWYgKHRoaXMuX2Rpc3Bvc2VkKSByZXR1cm47XG4gICAgdGhpcy5fZGlzcG9zZWQgPSB0cnVlO1xuICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMuaW50ZXJ2YWwpO1xuICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMucGVyZlRpbWVyKTtcbiAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbCh0aGlzLnJlc1RpbWVyKTtcbiAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuZmlsdGVyVGltZXIpO1xuICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5jb3B5VGltZXIpO1xuICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5tY3BDb3B5VGltZXIpO1xuICAgIGlmICh0aGlzLnN0b3BIb3N0U3luYykgdGhpcy5zdG9wSG9zdFN5bmMoKTsgLy8g5YGc5q2i5ri45oiP5a6/5Li75a6a5pyf5ZCM5q2lXG4gICAgaWYgKHRoaXMudGVhcmRvd25QcmV2aWV3KSB0aGlzLnRlYXJkb3duUHJldmlldygpOyAvLyDlgZzkuLvlvqrnjq8v6LCD5bqm5ZmoL+mfs+mikeOAgemHiuaUvui1hOa6kFxuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGhvc3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneXlrYS1nYW1lLWhvc3QnKTtcbiAgICAgICAgaWYgKGhvc3QpIGhvc3QucmVtb3ZlKCk7IC8vIOenu+mZpOmhtuWxgua4uOaIjyBET03vvIzpgb/lhY3mta7nqpflhbPpl63lkI7nlLvpnaLmrovnlZlcbiAgICB9IGNhdGNoIChfKSB7IC8qIGlnbm9yZSAqLyB9XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgdGhpcy5vbkRyYWdNb3ZlKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5lbmREcmFnKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIHRoaXMuZW5kRHJhZyk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMub25SZXNpemUpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdwYWdlaGlkZScsIHRoaXMuX29uUGFnZUhpZGUpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdiZWZvcmV1bmxvYWQnLCB0aGlzLl9vblBhZ2VIaWRlKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1vdW50ZWQodGhpczogYW55KSB7XG4gICAgdGhpcy5lbnN1cmVTZXJ2ZXIoKTtcbiAgICB0aGlzLnJlZnJlc2goKTtcbiAgICBhd2FpdCB0aGlzLmluaXRQcmV2aWV3SW5mbygpO1xuICAgIHRoaXMuJG5leHRUaWNrKCgpID0+IHRoaXMucmVuZGVyUHJldmlldygpKTtcbiAgICB0aGlzLmxvYWRNY3BTdGF0ZSgpO1xuICAgIHRoaXMuaW50ZXJ2YWwgPSB3aW5kb3cuc2V0SW50ZXJ2YWwoKCkgPT4gdGhpcy5yZWZyZXNoKCksIDEwMDApO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIHRoaXMub25EcmFnTW92ZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIHRoaXMuZW5kRHJhZyk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJjYW5jZWwnLCB0aGlzLmVuZERyYWcpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLm9uUmVzaXplKTtcbiAgICAvLyDmi5blh7rkuLrni6znq4vmta7nqpflkI7nm7TmjqXlhbPnqpfml7bvvIzku4XlhbPnqpflj6PkuI3op6blj5HkuIvmlofnmoQgYmVmb3JlVW5tb3VudO+8jOmcgOWcqOatpOWFnOW6lea4heeQhlxuICAgIHRoaXMuX29uUGFnZUhpZGUgPSAoKSA9PiBkb0Rpc3Bvc2UuY2FsbCh0aGlzKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncGFnZWhpZGUnLCB0aGlzLl9vblBhZ2VIaWRlKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgdGhpcy5fb25QYWdlSGlkZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBiZWZvcmVVbm1vdW50KHRoaXM6IGFueSkge1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdwYWdlaGlkZScsIHRoaXMuX29uUGFnZUhpZGUpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdiZWZvcmV1bmxvYWQnLCB0aGlzLl9vblBhZ2VIaWRlKTtcbiAgICBkb0Rpc3Bvc2UuY2FsbCh0aGlzKTtcbn0iXX0= \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/dist/panels/default/methods/inspector.js b/extensions/YYKA运行时工作台/dist/panels/default/methods/inspector.js new file mode 100644 index 0000000..d761add --- /dev/null +++ b/extensions/YYKA运行时工作台/dist/panels/default/methods/inspector.js @@ -0,0 +1,376 @@ +"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")); +/** 属性检查器:读取/写回节点与组件属性。 */ +exports.default = { + async loadInspector() { + if (!this.selectedId) { + this.inspector = null; + return; + } + this.inspectorLoading = true; + try { + const res = await Editor.Message.request(package_json_1.default.name, 'query-command', { cmd: 'get-inspector', timeout: 2500, payload: { id: this.selectedId } }); + this.inspector = res && res.id ? res : { error: String((res && res.error) || '获取属性失败') }; + } + catch (err) { + this.inspector = { error: `获取属性失败: ${String(err)}` }; + } + finally { + this.inspectorLoading = false; + } + }, + async sendSet(payload) { + // 关键修复:payload 里可能混入 Vue reactive Proxy(如 vec3 属性对象), + // Editor.Message.request 经结构化克隆传参,Proxy 无法克隆会抛 + // "An object could not be cloned"。发送前深拷贝为纯对象。 + let plain; + try { + plain = JSON.parse(JSON.stringify(payload)); + } + catch (_a) { + plain = Object.assign({}, payload); + } + try { + const res = await Editor.Message.request(package_json_1.default.name, 'query-command', { cmd: 'set-property', timeout: 1500, payload: plain }); + if (!res || typeof res !== 'object') { + this.logs.push('[写回] 无响应:命令未到达游戏(检查桥接脚本版本)'); + return; + } + if (res.error) { + this.logs.push(`[写回] 游戏返回: ${res.error}`); + return; + } + const label = res.node ? `${res.node}` : (payload.field || payload.key || ''); + this.logs.push(`[写回] 已设置 ${label} = ${JSON.stringify(payload.value)}`); + // 单向语义:保留本地乐观值,不被游戏回读覆盖。 + // 仅做一次静默回读用于诊断——若游戏逻辑/动画后覆盖了设定值,只记日志提示, + // 不回写 UI,避免"双向绑定"把编辑框刷成游戏当前值。 + const e = this.inspector; + const localVal = this.getLocalValue(payload); + try { + const back = await Editor.Message.request(package_json_1.default.name, 'query-command', { cmd: 'get-inspector', timeout: 1500, payload: { id: this.selectedId } }); + const cur = back && back.props && !back.error ? this.pickValue(back, payload) : undefined; + if (cur !== undefined && localVal !== undefined) { + const a = JSON.stringify(cur); + const b = JSON.stringify(localVal); + if (a !== b) { + this.logs.push(`[写回] 注意:回读值 ${a} 与设定值 ${b} 不同,可能被游戏逻辑/动画/物理每帧覆盖`); + } + } + } + catch (_b) { + /* 静默回读失败不影响编辑 */ + } + finally { + // 恢复本地乐观值到 UI(若上面的回读请求把本地对象引用改了) + if (e && !e.error) { + this.applyLocalValue(e, payload, localVal); + } + } + } + catch (err) { + this.logs.push(`[写回] ${String(err)}`); + } + }, + onNodeBool(field, val) { + if (!this.inspector) { + return; + } + this.inspector.props[field].v = val; + this.sendSet({ id: this.selectedId, field, value: val }); + }, + onNodeNumber(field, raw) { + if (!this.inspector) { + return; + } + const v = this.toNum(raw); + this.inspector.props[field].v = v; + this.sendSet({ id: this.selectedId, field, value: v }); + }, + onNodeVec(field, axis, raw) { + if (!this.inspector || !this.inspector.props || !this.inspector.props[field]) { + return; + } + const cur = this.inspector.props[field].v; + cur[axis] = this.toNum(raw); + this.sendSet({ id: this.selectedId, field, value: cur }); + }, + onCompScalar(compIdx, key, raw, t) { + if (!this.inspector) { + return; + } + const prop = this.inspector.components[compIdx].props.find((p) => p.key === key); + let val = raw; + if (t === 'number') { + val = this.toNum(raw); + } + else if (t === 'bool') { + val = raw === true || raw === 'true'; + } + if (prop) { + prop.v = val; + } + this.sendSet({ id: this.selectedId, comp: compIdx, key, value: val }); + }, + onCompVec(compIdx, key, axis, raw) { + if (!this.inspector) { + return; + } + const prop = this.inspector.components[compIdx].props.find((p) => p.key === key); + prop.v[axis] = this.toNum(raw); + this.sendSet({ id: this.selectedId, comp: compIdx, key, value: prop.v }); + }, + onCompColor(compIdx, key, raw) { + if (!this.inspector) { + return; + } + const prop = this.inspector.components[compIdx].props.find((p) => p.key === key); + const v = this.arrToColor(raw); + if (prop) { + prop.v = v; + this.sendSet({ id: this.selectedId, comp: compIdx, key, value: v }); + } + }, + onCompArrayColor(compIdx, key, index, raw) { + if (!this.inspector) { + return; + } + const prop = this.inspector.components[compIdx].props.find((p) => p.key === key); + const v = this.arrToColor(raw); + if (prop && prop.v[index] && prop.v[index].v) { + prop.v[index].v = v; + this.sendSet({ id: this.selectedId, comp: compIdx, key, index, value: v }); + } + }, + onCompEnabled(compIdx, val) { + if (!this.inspector) { + return; + } + this.inspector.components[compIdx].enabled = val; + this.sendSet({ id: this.selectedId, comp: compIdx, key: '__enabled', value: val }); + }, + onCompEnum(compIdx, key, raw) { + if (!this.inspector) { + return; + } + const val = Number(raw); + const prop = this.inspector.components[compIdx].props.find((p) => p.key === key); + if (prop) { + prop.v = val; + } + this.sendSet({ id: this.selectedId, comp: compIdx, key, value: val }); + }, + onCompArray(compIdx, key, index, raw, t) { + if (!this.inspector) { + return; + } + let val = raw; + if (t === 'number') { + val = this.toNum(raw); + } + else if (t === 'bool') { + val = raw === true || raw === 'true'; + } + const prop = this.inspector.components[compIdx].props.find((p) => p.key === key); + if (prop && prop.v[index]) { + prop.v[index].v = val; + } + this.sendSet({ id: this.selectedId, comp: compIdx, key, index, value: val }); + }, + onCompArrayVec(compIdx, key, index, axis, raw) { + if (!this.inspector) { + return; + } + const prop = this.inspector.components[compIdx].props.find((p) => p.key === key); + if (prop && prop.v[index] && prop.v[index].v) { + prop.v[index].v[axis] = this.toNum(raw); + this.sendSet({ id: this.selectedId, comp: compIdx, key, index, value: prop.v[index].v }); + } + }, + onCompNull(compIdx, key) { + if (!this.inspector) { + return; + } + const prop = this.inspector.components[compIdx].props.find((p) => p.key === key); + if (prop) { + prop.v = null; + } + this.sendSet({ id: this.selectedId, comp: compIdx, key, value: null }); + }, + /** 数组项置空(资产引用数组,如 materials)。 */ + onCompArrayNull(compIdx, key, index) { + if (!this.inspector) { + return; + } + const prop = this.inspector.components[compIdx].props.find((p) => p.key === key); + if (prop && prop.v && prop.v[index]) { + prop.v[index] = { t: 'raw', v: null, editable: false }; + } + this.sendSet({ id: this.selectedId, comp: compIdx, key, index, value: null }); + }, + /** 材质参数写回:index 为数字时定位 sharedMaterials 数组项,undefined 用 customMaterial/material。 */ + onCompMaterialProp(compIdx, key, index, propKey, value) { + var _a; + if (!this.inspector) { + return; + } + const comp = this.inspector.components[compIdx]; + const prop = comp === null || comp === void 0 ? void 0 : comp.props.find((p) => p.key === key); + const holder = index === undefined ? prop : (_a = prop === null || prop === void 0 ? void 0 : prop.v) === null || _a === void 0 ? void 0 : _a[index]; + if (holder && holder.v && Array.isArray(holder.v.props)) { + const mp = holder.v.props.find((x) => x.key === propKey); + if (mp) { + mp.v = value; + } + } + this.sendSet({ id: this.selectedId, comp: compIdx, key: '__material_prop', index, value: { propKey, value } }); + }, + /** Widget 专属:写回对齐模式/边距/目标(数值字段先转数字)。 */ + onWidgetSet(compIdx, key, raw) { + if (!this.inspector) { + return; + } + const comp = this.inspector.components[compIdx]; + if (!comp || !comp.widget) { + return; + } + let val = raw; + if (key === 'left' || key === 'right' || key === 'top' || key === 'bottom') { + val = this.toNum(raw); + } + else if (key === 'alignMode') { + val = Number(raw); + } + comp.widget[key] = val; + if (key === '__widget_target') { + comp.widget.targetName = val ? String(val) : ''; + } + this.sendSet({ id: this.selectedId, comp: compIdx, key, value: val }); + }, + /** Widget 专属:切换对齐标志(center 同时切水平+垂直居中;角键同时切两个边)。 */ + onWidgetToggle(compIdx, key) { + if (!this.inspector) { + return; + } + const comp = this.inspector.components[compIdx]; + if (!comp || !comp.widget) { + return; + } + const cornerMap = { + __top_left: ['isAlignTop', 'isAlignLeft'], + __top_right: ['isAlignTop', 'isAlignRight'], + __bottom_left: ['isAlignBottom', 'isAlignLeft'], + __bottom_right: ['isAlignBottom', 'isAlignRight'], + }; + if (key === 'center') { + comp.widget.isAlignHorizontalCenter = !comp.widget.isAlignHorizontalCenter; + comp.widget.isAlignVerticalCenter = !comp.widget.isAlignVerticalCenter; + this.sendSet({ id: this.selectedId, comp: compIdx, key: 'isAlignHorizontalCenter', value: comp.widget.isAlignHorizontalCenter }); + this.sendSet({ id: this.selectedId, comp: compIdx, key: 'isAlignVerticalCenter', value: comp.widget.isAlignVerticalCenter }); + return; + } + const corner = cornerMap[key]; + if (corner) { + for (const k of corner) { + comp.widget[k] = !comp.widget[k]; + } + for (const k of corner) { + this.sendSet({ id: this.selectedId, comp: compIdx, key: k, value: comp.widget[k] }); + } + return; + } + comp.widget[key] = !comp.widget[key]; + this.sendSet({ id: this.selectedId, comp: compIdx, key, value: comp.widget[key] }); + }, + /** 兼容 ui-color 的不同输出格式,统一为 {r,g,b,a}(0-255)。 */ + arrToColor(raw) { + if (Array.isArray(raw)) { + return { + r: this.toNum(raw[0]), + g: this.toNum(raw[1]), + b: this.toNum(raw[2]), + a: raw[3] !== undefined ? this.toNum(raw[3]) : 255, + }; + } + if (raw && typeof raw === 'object' && 'r' in raw) { + return { + r: this.toNum(raw.r), + g: this.toNum(raw.g), + b: this.toNum(raw.b), + a: raw.a !== undefined ? this.toNum(raw.a) : 255, + }; + } + return this.parseColor(raw); + }, + /** ref 引用是否为节点引用(cc.Node);组件引用返回 false,用于区分 ui-node / ui-component 显示。 */ + isNodeRef(p) { + return !p || !p.componentType || p.componentType === 'cc.Node'; + }, + /** 从当前 inspector 中取正在编辑字段的本地乐观值(写回后不该被回读覆盖)。 */ + getLocalValue(payload) { + var _a, _b, _c, _d, _e, _f, _g, _h; + try { + if (payload.comp !== undefined) { + const comp = (_b = (_a = this.inspector) === null || _a === void 0 ? void 0 : _a.components) === null || _b === void 0 ? void 0 : _b[payload.comp]; + const p = (_c = comp === null || comp === void 0 ? void 0 : comp.props) === null || _c === void 0 ? void 0 : _c.find((x) => x.key === payload.key); + const v = p && (payload.index === undefined ? p.v : (_e = (_d = p.v) === null || _d === void 0 ? void 0 : _d[payload.index]) === null || _e === void 0 ? void 0 : _e.v); + return v === undefined ? undefined : JSON.parse(JSON.stringify(v)); + } + if (payload.field !== undefined) { + const v = (_h = (_g = (_f = this.inspector) === null || _f === void 0 ? void 0 : _f.props) === null || _g === void 0 ? void 0 : _g[payload.field]) === null || _h === void 0 ? void 0 : _h.v; + return v === undefined ? undefined : JSON.parse(JSON.stringify(v)); + } + } + catch ( /* ignore */_j) { /* ignore */ } + return undefined; + }, + /** 从回读结果中取同一字段实际值(对比诊断用)。 */ + pickValue(back, payload) { + var _a, _b, _c, _d, _e, _f; + try { + if (payload.comp !== undefined) { + const comp = (_a = back.components) === null || _a === void 0 ? void 0 : _a[payload.comp]; + const p = (_b = comp === null || comp === void 0 ? void 0 : comp.props) === null || _b === void 0 ? void 0 : _b.find((x) => x.key === payload.key); + const v = p && (payload.index === undefined ? p.v : (_d = (_c = p.v) === null || _c === void 0 ? void 0 : _c[payload.index]) === null || _d === void 0 ? void 0 : _d.v); + return v === undefined ? undefined : JSON.parse(JSON.stringify(v)); + } + if (payload.field !== undefined) { + const v = (_f = (_e = back.props) === null || _e === void 0 ? void 0 : _e[payload.field]) === null || _f === void 0 ? void 0 : _f.v; + return v === undefined ? undefined : JSON.parse(JSON.stringify(v)); + } + } + catch ( /* ignore */_g) { /* ignore */ } + return undefined; + }, + /** 把 UI 中正在编辑的字段恢复成本地乐观值(回读请求不改写编辑框)。 */ + applyLocalValue(insp, payload, val) { + var _a, _b, _c, _d; + if (val === undefined) { + return; + } + try { + if (payload.comp !== undefined) { + const comp = (_a = insp.components) === null || _a === void 0 ? void 0 : _a[payload.comp]; + const p = (_b = comp === null || comp === void 0 ? void 0 : comp.props) === null || _b === void 0 ? void 0 : _b.find((x) => x.key === payload.key); + if (p) { + if (payload.index === undefined) { + p.v = val; + } + else if ((_c = p.v) === null || _c === void 0 ? void 0 : _c[payload.index]) { + p.v[payload.index].v = val; + } + } + } + else if (payload.field !== undefined && ((_d = insp.props) === null || _d === void 0 ? void 0 : _d[payload.field])) { + insp.props[payload.field].v = val; + } + } + catch ( /* ignore */_e) { /* ignore */ } + }, +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zcGVjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc291cmNlL3BhbmVscy9kZWZhdWx0L21ldGhvZHMvaW5zcGVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsYUFBYTtBQUNiLDRFQUFtRDtBQUVuRCwwQkFBMEI7QUFDMUIsa0JBQWU7SUFDWCxLQUFLLENBQUMsYUFBYTtRQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7WUFDdEIsT0FBTztRQUNYLENBQUM7UUFDRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQzdCLElBQUksQ0FBQztZQUNELE1BQU0sR0FBRyxHQUFHLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQ3BDLHNCQUFXLENBQUMsSUFBVyxFQUN2QixlQUFzQixFQUN0QixFQUFFLEdBQUcsRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFTLENBQ25GLENBQUM7WUFDRixJQUFJLENBQUMsU0FBUyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUM3RixDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNYLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxLQUFLLEVBQUUsV0FBVyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3pELENBQUM7Z0JBQVMsQ0FBQztZQUNQLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFL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SSxDQUFDO1lBQ0QsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUM3QixNQUFNLElBQUksR0FBRyxNQUFBLElBQUksQ0FBQyxVQUFVLDBDQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDN0MsTUFBTSxDQUFDLEdBQUcsTUFBQSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsS0FBSywwQ0FBRSxJQUFJLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUMvRCxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNKLElBQUksT0FBTyxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQzt3QkFDOUIsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7b0JBQ2QsQ0FBQzt5QkFBTSxJQUFJLE1BQUEsQ0FBQyxDQUFDLENBQUMsMENBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7d0JBQzlCLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7b0JBQy9CLENBQUM7Z0JBQ0wsQ0FBQztZQUNMLENBQUM7aUJBQU0sSUFBSSxPQUFPLENBQUMsS0FBSyxLQUFLLFNBQVMsS0FBSSxNQUFBLElBQUksQ0FBQyxLQUFLLDBDQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQSxFQUFFLENBQUM7Z0JBQ3BFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7WUFDdEMsQ0FBQztRQUNMLENBQUM7UUFBQyxRQUFRLFlBQVksSUFBZCxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDNUIsQ0FBQztDQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtaWdub3JlXG5pbXBvcnQgcGFja2FnZUpTT04gZnJvbSAnLi4vLi4vLi4vLi4vcGFja2FnZS5qc29uJztcblxuLyoqIOWxnuaAp+ajgOafpeWZqO+8muivu+WPli/lhpnlm57oioLngrnkuI7nu4Tku7blsZ7mgKfjgIIgKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBhc3luYyBsb2FkSW5zcGVjdG9yKHRoaXM6IGFueSkge1xuICAgICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRJZCkge1xuICAgICAgICAgICAgdGhpcy5pbnNwZWN0b3IgPSBudWxsO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5zcGVjdG9yTG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBFZGl0b3IuTWVzc2FnZS5yZXF1ZXN0KFxuICAgICAgICAgICAgICAgIHBhY2thZ2VKU09OLm5hbWUgYXMgYW55LFxuICAgICAgICAgICAgICAgICdxdWVyeS1jb21tYW5kJyBhcyBhbnksXG4gICAgICAgICAgICAgICAgeyBjbWQ6ICdnZXQtaW5zcGVjdG9yJywgdGltZW91dDogMjUwMCwgcGF5bG9hZDogeyBpZDogdGhpcy5zZWxlY3RlZElkIH0gfSBhcyBhbnksXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5pbnNwZWN0b3IgPSByZXMgJiYgcmVzLmlkID8gcmVzIDogeyBlcnJvcjogU3RyaW5nKChyZXMgJiYgcmVzLmVycm9yKSB8fCAn6I635Y+W5bGe5oCn5aSx6LSlJykgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0aGlzLmluc3BlY3RvciA9IHsgZXJyb3I6IGDojrflj5blsZ7mgKflpLHotKU6ICR7U3RyaW5nKGVycil9YCB9O1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5pbnNwZWN0b3JMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIHNlbmRTZXQodGhpczogYW55LCBwYXlsb2FkOiBhbnkpIHtcbiAgICAgICAgLy8g5YWz6ZSu5L+u5aSN77yacGF5bG9hZCDph4zlj6/og73mt7flhaUgVnVlIHJlYWN0aXZlIFByb3h577yI5aaCIHZlYzMg5bGe5oCn5a+56LGh77yJ77yMXG4gICAgICAgIC8vIEVkaXRvci5NZXNzYWdlLnJlcXVlc3Qg57uP57uT5p6E5YyW5YWL6ZqG5Lyg5Y+C77yMUHJveHkg5peg5rOV5YWL6ZqG5Lya5oqbXG4gICAgICAgIC8vIFwiQW4gb2JqZWN0IGNvdWxkIG5vdCBiZSBjbG9uZWRcIuOAguWPkemAgeWJjea3seaLt+i0neS4uue6r+WvueixoeOAglxuICAgICAgICBsZXQgcGxhaW46IGFueTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHBsYWluID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShwYXlsb2FkKSk7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgcGxhaW4gPSB7IC4uLnBheWxvYWQgfTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgRWRpdG9yLk1lc3NhZ2UucmVxdWVzdChcbiAgICAgICAgICAgICAgICBwYWNrYWdlSlNPTi5uYW1lIGFzIGFueSxcbiAgICAgICAgICAgICAgICAncXVlcnktY29tbWFuZCcgYXMgYW55LFxuICAgICAgICAgICAgICAgIHsgY21kOiAnc2V0LXByb3BlcnR5JywgdGltZW91dDogMTUwMCwgcGF5bG9hZDogcGxhaW4gfSBhcyBhbnksXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKCFyZXMgfHwgdHlwZW9mIHJlcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ3MucHVzaCgnW+WGmeWbnl0g5peg5ZON5bqU77ya5ZG95Luk5pyq5Yiw6L6+5ri45oiP77yI5qOA5p+l5qGl5o6l6ISa5pys54mI5pys77yJJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJlcy5lcnJvcikge1xuICAgICAgICAgICAgICAgIHRoaXMubG9ncy5wdXNoKGBb5YaZ5ZueXSDmuLjmiI/ov5Tlm546ICR7cmVzLmVycm9yfWApO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGxhYmVsID0gcmVzLm5vZGUgPyBgJHtyZXMubm9kZX1gIDogKHBheWxvYWQuZmllbGQgfHwgcGF5bG9hZC5rZXkgfHwgJycpO1xuICAgICAgICAgICAgdGhpcy5sb2dzLnB1c2goYFvlhpnlm55dIOW3suiuvue9riAke2xhYmVsfSA9ICR7SlNPTi5zdHJpbmdpZnkocGF5bG9hZC52YWx1ZSl9YCk7XG4gICAgICAgICAgICAvLyDljZXlkJHor63kuYnvvJrkv53nlZnmnKzlnLDkuZDop4LlgLzvvIzkuI3ooqvmuLjmiI/lm57or7vopobnm5bjgIJcbiAgICAgICAgICAgIC8vIOS7heWBmuS4gOasoemdmem7mOWbnuivu+eUqOS6juiviuaWreKAlOKAlOiLpea4uOaIj+mAu+i+kS/liqjnlLvlkI7opobnm5bkuoborr7lrprlgLzvvIzlj6rorrDml6Xlv5fmj5DnpLrvvIxcbiAgICAgICAgICAgIC8vIOS4jeWbnuWGmSBVSe+8jOmBv+WFjVwi5Y+M5ZCR57uR5a6aXCLmiornvJbovpHmoYbliLfmiJDmuLjmiI/lvZPliY3lgLzjgIJcbiAgICAgICAgICAgIGNvbnN0IGUgPSB0aGlzLmluc3BlY3RvcjtcbiAgICAgICAgICAgIGNvbnN0IGxvY2FsVmFsID0gdGhpcy5nZXRMb2NhbFZhbHVlKHBheWxvYWQpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBiYWNrID0gYXdhaXQgRWRpdG9yLk1lc3NhZ2UucmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgcGFja2FnZUpTT04ubmFtZSBhcyBhbnksXG4gICAgICAgICAgICAgICAgICAgICdxdWVyeS1jb21tYW5kJyBhcyBhbnksXG4gICAgICAgICAgICAgICAgICAgIHsgY21kOiAnZ2V0LWluc3BlY3RvcicsIHRpbWVvdXQ6IDE1MDAsIHBheWxvYWQ6IHsgaWQ6IHRoaXMuc2VsZWN0ZWRJZCB9IH0gYXMgYW55LFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY29uc3QgY3VyID0gYmFjayAmJiBiYWNrLnByb3BzICYmICFiYWNrLmVycm9yID8gdGhpcy5waWNrVmFsdWUoYmFjaywgcGF5bG9hZCkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgaWYgKGN1ciAhPT0gdW5kZWZpbmVkICYmIGxvY2FsVmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYSA9IEpTT04uc3RyaW5naWZ5KGN1cik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGIgPSBKU09OLnN0cmluZ2lmeShsb2NhbFZhbCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhICE9PSBiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ3MucHVzaChgW+WGmeWbnl0g5rOo5oSP77ya5Zue6K+75YC8ICR7YX0g5LiO6K6+5a6a5YC8ICR7Yn0g5LiN5ZCM77yM5Y+v6IO96KKr5ri45oiP6YC76L6RL+WKqOeUuy/niannkIbmr4/luKfopobnm5ZgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgIC8qIOmdmem7mOWbnuivu+Wksei0peS4jeW9seWTjee8lui+kSAqL1xuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAvLyDmgaLlpI3mnKzlnLDkuZDop4LlgLzliLAgVUnvvIjoi6XkuIrpnaLnmoTlm57or7vor7fmsYLmiormnKzlnLDlr7nosaHlvJXnlKjmlLnkuobvvIlcbiAgICAgICAgICAgICAgICBpZiAoZSAmJiAhZS5lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcGx5TG9jYWxWYWx1ZShlLCBwYXlsb2FkLCBsb2NhbFZhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMubG9ncy5wdXNoKGBb5YaZ5ZueXSAke1N0cmluZyhlcnIpfWApO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBvbk5vZGVCb29sKHRoaXM6IGFueSwgZmllbGQ6IHN0cmluZywgdmFsOiBib29sZWFuKSB7XG4gICAgICAgIGlmICghdGhpcy5pbnNwZWN0b3IpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmluc3BlY3Rvci5wcm9wc1tmaWVsZF0udiA9IHZhbDtcbiAgICAgICAgdGhpcy5zZW5kU2V0KHsgaWQ6IHRoaXMuc2VsZWN0ZWRJZCwgZmllbGQsIHZhbHVlOiB2YWwgfSk7XG4gICAgfSxcbiAgICBvbk5vZGVOdW1iZXIodGhpczogYW55LCBmaWVsZDogc3RyaW5nLCByYXc6IHN0cmluZykge1xuICAgICAgICBpZiAoIXRoaXMuaW5zcGVjdG9yKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdiA9IHRoaXMudG9OdW0ocmF3KTtcbiAgICAgICAgdGhpcy5pbnNwZWN0b3IucHJvcHNbZmllbGRdLnYgPSB2O1xuICAgICAgICB0aGlzLnNlbmRTZXQoeyBpZDogdGhpcy5zZWxlY3RlZElkLCBmaWVsZCwgdmFsdWU6IHYgfSk7XG4gICAgfSxcbiAgICBvbk5vZGVWZWModGhpczogYW55LCBmaWVsZDogc3RyaW5nLCBheGlzOiBzdHJpbmcsIHJhdzogc3RyaW5nKSB7XG4gICAgICAgIGlmICghdGhpcy5pbnNwZWN0b3IgfHwgIXRoaXMuaW5zcGVjdG9yLnByb3BzIHx8ICF0aGlzLmluc3BlY3Rvci5wcm9wc1tmaWVsZF0pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjdXIgPSB0aGlzLmluc3BlY3Rvci5wcm9wc1tmaWVsZF0udjtcbiAgICAgICAgY3VyW2F4aXNdID0gdGhpcy50b051bShyYXcpO1xuICAgICAgICB0aGlzLnNlbmRTZXQoeyBpZDogdGhpcy5zZWxlY3RlZElkLCBmaWVsZCwgdmFsdWU6IGN1ciB9KTtcbiAgICB9LFxuICAgIG9uQ29tcFNjYWxhcih0aGlzOiBhbnksIGNvbXBJZHg6IG51bWJlciwga2V5OiBzdHJpbmcsIHJhdzogYW55LCB0OiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCF0aGlzLmluc3BlY3Rvcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb3AgPSB0aGlzLmluc3BlY3Rvci5jb21wb25lbnRzW2NvbXBJZHhdLnByb3BzLmZpbmQoKHA6IGFueSkgPT4gcC5rZXkgPT09IGtleSk7XG4gICAgICAgIGxldCB2YWwgPSByYXc7XG4gICAgICAgIGlmICh0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdmFsID0gdGhpcy50b051bShyYXcpO1xuICAgICAgICB9IGVsc2UgaWYgKHQgPT09ICdib29sJykge1xuICAgICAgICAgICAgdmFsID0gcmF3ID09PSB0cnVlIHx8IHJhdyA9PT0gJ3RydWUnO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgICAgICBwcm9wLnYgPSB2YWw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZW5kU2V0KHsgaWQ6IHRoaXMuc2VsZWN0ZWRJZCwgY29tcDogY29tcElkeCwga2V5LCB2YWx1ZTogdmFsIH0pO1xuICAgIH0sXG4gICAgb25Db21wVmVjKHRoaXM6IGFueSwgY29tcElkeDogbnVtYmVyLCBrZXk6IHN0cmluZywgYXhpczogc3RyaW5nLCByYXc6IHN0cmluZykge1xuICAgICAgICBpZiAoIXRoaXMuaW5zcGVjdG9yKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvcCA9IHRoaXMuaW5zcGVjdG9yLmNvbXBvbmVudHNbY29tcElkeF0ucHJvcHMuZmluZCgocDogYW55KSA9PiBwLmtleSA9PT0ga2V5KTtcbiAgICAgICAgcHJvcC52W2F4aXNdID0gdGhpcy50b051bShyYXcpO1xuICAgICAgICB0aGlzLnNlbmRTZXQoeyBpZDogdGhpcy5zZWxlY3RlZElkLCBjb21wOiBjb21wSWR4LCBrZXksIHZhbHVlOiBwcm9wLnYgfSk7XG4gICAgfSxcbiAgICBvbkNvbXBDb2xvcih0aGlzOiBhbnksIGNvbXBJZHg6IG51bWJlciwga2V5OiBzdHJpbmcsIHJhdzogYW55KSB7XG4gICAgICAgIGlmICghdGhpcy5pbnNwZWN0b3IpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9wID0gdGhpcy5pbnNwZWN0b3IuY29tcG9uZW50c1tjb21wSWR4XS5wcm9wcy5maW5kKChwOiBhbnkpID0+IHAua2V5ID09PSBrZXkpO1xuICAgICAgICBjb25zdCB2ID0gdGhpcy5hcnJUb0NvbG9yKHJhdyk7XG4gICAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgICAgICBwcm9wLnYgPSB2O1xuICAgICAgICAgICAgdGhpcy5zZW5kU2V0KHsgaWQ6IHRoaXMuc2VsZWN0ZWRJZCwgY29tcDogY29tcElkeCwga2V5LCB2YWx1ZTogdiB9KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgb25Db21wQXJyYXlDb2xvcih0aGlzOiBhbnksIGNvbXBJZHg6IG51bWJlciwga2V5OiBzdHJpbmcsIGluZGV4OiBudW1iZXIsIHJhdzogYW55KSB7XG4gICAgICAgIGlmICghdGhpcy5pbnNwZWN0b3IpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9wID0gdGhpcy5pbnNwZWN0b3IuY29tcG9uZW50c1tjb21wSWR4XS5wcm9wcy5maW5kKChwOiBhbnkpID0+IHAua2V5ID09PSBrZXkpO1xuICAgICAgICBjb25zdCB2ID0gdGhpcy5hcnJUb0NvbG9yKHJhdyk7XG4gICAgICAgIGlmIChwcm9wICYmIHByb3AudltpbmRleF0gJiYgcHJvcC52W2luZGV4XS52KSB7XG4gICAgICAgICAgICBwcm9wLnZbaW5kZXhdLnYgPSB2O1xuICAgICAgICAgICAgdGhpcy5zZW5kU2V0KHsgaWQ6IHRoaXMuc2VsZWN0ZWRJZCwgY29tcDogY29tcElkeCwga2V5LCBpbmRleCwgdmFsdWU6IHYgfSk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIG9uQ29tcEVuYWJsZWQodGhpczogYW55LCBjb21wSWR4OiBudW1iZXIsIHZhbDogYm9vbGVhbikge1xuICAgICAgICBpZiAoIXRoaXMuaW5zcGVjdG9yKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbnNwZWN0b3IuY29tcG9uZW50c1tjb21wSWR4XS5lbmFibGVkID0gdmFsO1xuICAgICAgICB0aGlzLnNlbmRTZXQoeyBpZDogdGhpcy5zZWxlY3RlZElkLCBjb21wOiBjb21wSWR4LCBrZXk6ICdfX2VuYWJsZWQnLCB2YWx1ZTogdmFsIH0pO1xuICAgIH0sXG4gICAgb25Db21wRW51bSh0aGlzOiBhbnksIGNvbXBJZHg6IG51bWJlciwga2V5OiBzdHJpbmcsIHJhdzogYW55KSB7XG4gICAgICAgIGlmICghdGhpcy5pbnNwZWN0b3IpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2YWwgPSBOdW1iZXIocmF3KTtcbiAgICAgICAgY29uc3QgcHJvcCA9IHRoaXMuaW5zcGVjdG9yLmNvbXBvbmVudHNbY29tcElkeF0ucHJvcHMuZmluZCgocDogYW55KSA9PiBwLmtleSA9PT0ga2V5KTtcbiAgICAgICAgaWYgKHByb3ApIHtcbiAgICAgICAgICAgIHByb3AudiA9IHZhbDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbmRTZXQoeyBpZDogdGhpcy5zZWxlY3RlZElkLCBjb21wOiBjb21wSWR4LCBrZXksIHZhbHVlOiB2YWwgfSk7XG4gICAgfSxcbiAgICBvbkNvbXBBcnJheSh0aGlzOiBhbnksIGNvbXBJZHg6IG51bWJlciwga2V5OiBzdHJpbmcsIGluZGV4OiBudW1iZXIsIHJhdzogYW55LCB0OiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCF0aGlzLmluc3BlY3Rvcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCB2YWwgPSByYXc7XG4gICAgICAgIGlmICh0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdmFsID0gdGhpcy50b051bShyYXcpO1xuICAgICAgICB9IGVsc2UgaWYgKHQgPT09ICdib29sJykge1xuICAgICAgICAgICAgdmFsID0gcmF3ID09PSB0cnVlIHx8IHJhdyA9PT0gJ3RydWUnO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb3AgPSB0aGlzLmluc3BlY3Rvci5jb21wb25lbnRzW2NvbXBJZHhdLnByb3BzLmZpbmQoKHA6IGFueSkgPT4gcC5rZXkgPT09IGtleSk7XG4gICAgICAgIGlmIChwcm9wICYmIHByb3AudltpbmRleF0pIHtcbiAgICAgICAgICAgIHByb3AudltpbmRleF0udiA9IHZhbDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbmRTZXQoeyBpZDogdGhpcy5zZWxlY3RlZElkLCBjb21wOiBjb21wSWR4LCBrZXksIGluZGV4LCB2YWx1ZTogdmFsIH0pO1xuICAgIH0sXG4gICAgb25Db21wQXJyYXlWZWModGhpczogYW55LCBjb21wSWR4OiBudW1iZXIsIGtleTogc3RyaW5nLCBpbmRleDogbnVtYmVyLCBheGlzOiBzdHJpbmcsIHJhdzogc3RyaW5nKSB7XG4gICAgICAgIGlmICghdGhpcy5pbnNwZWN0b3IpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9wID0gdGhpcy5pbnNwZWN0b3IuY29tcG9uZW50c1tjb21wSWR4XS5wcm9wcy5maW5kKChwOiBhbnkpID0+IHAua2V5ID09PSBrZXkpO1xuICAgICAgICBpZiAocHJvcCAmJiBwcm9wLnZbaW5kZXhdICYmIHByb3AudltpbmRleF0udikge1xuICAgICAgICAgICAgcHJvcC52W2luZGV4XS52W2F4aXNdID0gdGhpcy50b051bShyYXcpO1xuICAgICAgICAgICAgdGhpcy5zZW5kU2V0KHsgaWQ6IHRoaXMuc2VsZWN0ZWRJZCwgY29tcDogY29tcElkeCwga2V5LCBpbmRleCwgdmFsdWU6IHByb3AudltpbmRleF0udiB9KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgb25Db21wTnVsbCh0aGlzOiBhbnksIGNvbXBJZHg6IG51bWJlciwga2V5OiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCF0aGlzLmluc3BlY3Rvcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb3AgPSB0aGlzLmluc3BlY3Rvci5jb21wb25lbnRzW2NvbXBJZHhdLnByb3BzLmZpbmQoKHA6IGFueSkgPT4gcC5rZXkgPT09IGtleSk7XG4gICAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgICAgICBwcm9wLnYgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2VuZFNldCh7IGlkOiB0aGlzLnNlbGVjdGVkSWQsIGNvbXA6IGNvbXBJZHgsIGtleSwgdmFsdWU6IG51bGwgfSk7XG4gICAgfSxcbiAgICAvKiog5pWw57uE6aG5572u56m677yI6LWE5Lqn5byV55So5pWw57uE77yM5aaCIG1hdGVyaWFsc++8ieOAgiAqL1xuICAgIG9uQ29tcEFycmF5TnVsbCh0aGlzOiBhbnksIGNvbXBJZHg6IG51bWJlciwga2V5OiBzdHJpbmcsIGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgaWYgKCF0aGlzLmluc3BlY3Rvcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb3AgPSB0aGlzLmluc3BlY3Rvci5jb21wb25lbnRzW2NvbXBJZHhdLnByb3BzLmZpbmQoKHA6IGFueSkgPT4gcC5rZXkgPT09IGtleSk7XG4gICAgICAgIGlmIChwcm9wICYmIHByb3AudiAmJiBwcm9wLnZbaW5kZXhdKSB7XG4gICAgICAgICAgICBwcm9wLnZbaW5kZXhdID0geyB0OiAncmF3JywgdjogbnVsbCwgZWRpdGFibGU6IGZhbHNlIH07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZW5kU2V0KHsgaWQ6IHRoaXMuc2VsZWN0ZWRJZCwgY29tcDogY29tcElkeCwga2V5LCBpbmRleCwgdmFsdWU6IG51bGwgfSk7XG4gICAgfSxcbiAgICAvKiog5p2Q6LSo5Y+C5pWw5YaZ5Zue77yaaW5kZXgg5Li65pWw5a2X5pe25a6a5L2NIHNoYXJlZE1hdGVyaWFscyDmlbDnu4TpobnvvIx1bmRlZmluZWQg55SoIGN1c3RvbU1hdGVyaWFsL21hdGVyaWFs44CCICovXG4gICAgb25Db21wTWF0ZXJpYWxQcm9wKHRoaXM6IGFueSwgY29tcElkeDogbnVtYmVyLCBrZXk6IHN0cmluZywgaW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZCwgcHJvcEtleTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gICAgICAgIGlmICghdGhpcy5pbnNwZWN0b3IpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb21wID0gdGhpcy5pbnNwZWN0b3IuY29tcG9uZW50c1tjb21wSWR4XTtcbiAgICAgICAgY29uc3QgcHJvcCA9IGNvbXA/LnByb3BzLmZpbmQoKHA6IGFueSkgPT4gcC5rZXkgPT09IGtleSk7XG4gICAgICAgIGNvbnN0IGhvbGRlciA9IGluZGV4ID09PSB1bmRlZmluZWQgPyBwcm9wIDogcHJvcD8udj8uW2luZGV4XTtcbiAgICAgICAgaWYgKGhvbGRlciAmJiBob2xkZXIudiAmJiBBcnJheS5pc0FycmF5KGhvbGRlci52LnByb3BzKSkge1xuICAgICAgICAgICAgY29uc3QgbXAgPSBob2xkZXIudi5wcm9wcy5maW5kKCh4OiBhbnkpID0+IHgua2V5ID09PSBwcm9wS2V5KTtcbiAgICAgICAgICAgIGlmIChtcCkge1xuICAgICAgICAgICAgICAgIG1wLnYgPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbmRTZXQoeyBpZDogdGhpcy5zZWxlY3RlZElkLCBjb21wOiBjb21wSWR4LCBrZXk6ICdfX21hdGVyaWFsX3Byb3AnLCBpbmRleCwgdmFsdWU6IHsgcHJvcEtleSwgdmFsdWUgfSB9KTtcbiAgICB9LFxuICAgIC8qKiBXaWRnZXQg5LiT5bGe77ya5YaZ5Zue5a+56b2Q5qih5byPL+i+uei3nS/nm67moIfvvIjmlbDlgLzlrZfmrrXlhYjovazmlbDlrZfvvInjgIIgKi9cbiAgICBvbldpZGdldFNldCh0aGlzOiBhbnksIGNvbXBJZHg6IG51bWJlciwga2V5OiBzdHJpbmcsIHJhdzogYW55KSB7XG4gICAgICAgIGlmICghdGhpcy5pbnNwZWN0b3IpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb21wID0gdGhpcy5pbnNwZWN0b3IuY29tcG9uZW50c1tjb21wSWR4XTtcbiAgICAgICAgaWYgKCFjb21wIHx8ICFjb21wLndpZGdldCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCB2YWw6IGFueSA9IHJhdztcbiAgICAgICAgaWYgKGtleSA9PT0gJ2xlZnQnIHx8IGtleSA9PT0gJ3JpZ2h0JyB8fCBrZXkgPT09ICd0b3AnIHx8IGtleSA9PT0gJ2JvdHRvbScpIHtcbiAgICAgICAgICAgIHZhbCA9IHRoaXMudG9OdW0ocmF3KTtcbiAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09ICdhbGlnbk1vZGUnKSB7XG4gICAgICAgICAgICB2YWwgPSBOdW1iZXIocmF3KTtcbiAgICAgICAgfVxuICAgICAgICBjb21wLndpZGdldFtrZXldID0gdmFsO1xuICAgICAgICBpZiAoa2V5ID09PSAnX193aWRnZXRfdGFyZ2V0Jykge1xuICAgICAgICAgICAgY29tcC53aWRnZXQudGFyZ2V0TmFtZSA9IHZhbCA/IFN0cmluZyh2YWwpIDogJyc7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZW5kU2V0KHsgaWQ6IHRoaXMuc2VsZWN0ZWRJZCwgY29tcDogY29tcElkeCwga2V5LCB2YWx1ZTogdmFsIH0pO1xuICAgIH0sXG4gICAgLyoqIFdpZGdldCDkuJPlsZ7vvJrliIfmjaLlr7npvZDmoIflv5fvvIhjZW50ZXIg5ZCM5pe25YiH5rC05bmzK+WeguebtOWxheS4re+8m+inkumUruWQjOaXtuWIh+S4pOS4qui+ue+8ieOAgiAqL1xuICAgIG9uV2lkZ2V0VG9nZ2xlKHRoaXM6IGFueSwgY29tcElkeDogbnVtYmVyLCBrZXk6IHN0cmluZykge1xuICAgICAgICBpZiAoIXRoaXMuaW5zcGVjdG9yKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29tcCA9IHRoaXMuaW5zcGVjdG9yLmNvbXBvbmVudHNbY29tcElkeF07XG4gICAgICAgIGlmICghY29tcCB8fCAhY29tcC53aWRnZXQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb3JuZXJNYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHtcbiAgICAgICAgICAgIF9fdG9wX2xlZnQ6IFsnaXNBbGlnblRvcCcsICdpc0FsaWduTGVmdCddLFxuICAgICAgICAgICAgX190b3BfcmlnaHQ6IFsnaXNBbGlnblRvcCcsICdpc0FsaWduUmlnaHQnXSxcbiAgICAgICAgICAgIF9fYm90dG9tX2xlZnQ6IFsnaXNBbGlnbkJvdHRvbScsICdpc0FsaWduTGVmdCddLFxuICAgICAgICAgICAgX19ib3R0b21fcmlnaHQ6IFsnaXNBbGlnbkJvdHRvbScsICdpc0FsaWduUmlnaHQnXSxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGtleSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgIGNvbXAud2lkZ2V0LmlzQWxpZ25Ib3Jpem9udGFsQ2VudGVyID0gIWNvbXAud2lkZ2V0LmlzQWxpZ25Ib3Jpem9udGFsQ2VudGVyO1xuICAgICAgICAgICAgY29tcC53aWRnZXQuaXNBbGlnblZlcnRpY2FsQ2VudGVyID0gIWNvbXAud2lkZ2V0LmlzQWxpZ25WZXJ0aWNhbENlbnRlcjtcbiAgICAgICAgICAgIHRoaXMuc2VuZFNldCh7IGlkOiB0aGlzLnNlbGVjdGVkSWQsIGNvbXA6IGNvbXBJZHgsIGtleTogJ2lzQWxpZ25Ib3Jpem9udGFsQ2VudGVyJywgdmFsdWU6IGNvbXAud2lkZ2V0LmlzQWxpZ25Ib3Jpem9udGFsQ2VudGVyIH0pO1xuICAgICAgICAgICAgdGhpcy5zZW5kU2V0KHsgaWQ6IHRoaXMuc2VsZWN0ZWRJZCwgY29tcDogY29tcElkeCwga2V5OiAnaXNBbGlnblZlcnRpY2FsQ2VudGVyJywgdmFsdWU6IGNvbXAud2lkZ2V0LmlzQWxpZ25WZXJ0aWNhbENlbnRlciB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb3JuZXIgPSBjb3JuZXJNYXBba2V5XTtcbiAgICAgICAgaWYgKGNvcm5lcikge1xuICAgICAgICAgICAgZm9yIChjb25zdCBrIG9mIGNvcm5lcikge1xuICAgICAgICAgICAgICAgIGNvbXAud2lkZ2V0W2tdID0gIWNvbXAud2lkZ2V0W2tdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBrIG9mIGNvcm5lcikge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFNldCh7IGlkOiB0aGlzLnNlbGVjdGVkSWQsIGNvbXA6IGNvbXBJZHgsIGtleTogaywgdmFsdWU6IGNvbXAud2lkZ2V0W2tdIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbXAud2lkZ2V0W2tleV0gPSAhY29tcC53aWRnZXRba2V5XTtcbiAgICAgICAgdGhpcy5zZW5kU2V0KHsgaWQ6IHRoaXMuc2VsZWN0ZWRJZCwgY29tcDogY29tcElkeCwga2V5LCB2YWx1ZTogY29tcC53aWRnZXRba2V5XSB9KTtcbiAgICB9LFxuICAgIC8qKiDlhbzlrrkgdWktY29sb3Ig55qE5LiN5ZCM6L6T5Ye65qC85byP77yM57uf5LiA5Li6IHtyLGcsYixhfSgwLTI1NSnjgIIgKi9cbiAgICBhcnJUb0NvbG9yKHRoaXM6IGFueSwgcmF3OiBhbnkpOiB7IHI6IG51bWJlcjsgZzogbnVtYmVyOyBiOiBudW1iZXI7IGE6IG51bWJlciB9IHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmF3KSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICByOiB0aGlzLnRvTnVtKHJhd1swXSksXG4gICAgICAgICAgICAgICAgZzogdGhpcy50b051bShyYXdbMV0pLFxuICAgICAgICAgICAgICAgIGI6IHRoaXMudG9OdW0ocmF3WzJdKSxcbiAgICAgICAgICAgICAgICBhOiByYXdbM10gIT09IHVuZGVmaW5lZCA/IHRoaXMudG9OdW0ocmF3WzNdKSA6IDI1NSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJhdyAmJiB0eXBlb2YgcmF3ID09PSAnb2JqZWN0JyAmJiAncicgaW4gcmF3KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHI6IHRoaXMudG9OdW0ocmF3LnIpLFxuICAgICAgICAgICAgICAgIGc6IHRoaXMudG9OdW0ocmF3LmcpLFxuICAgICAgICAgICAgICAgIGI6IHRoaXMudG9OdW0ocmF3LmIpLFxuICAgICAgICAgICAgICAgIGE6IHJhdy5hICE9PSB1bmRlZmluZWQgPyB0aGlzLnRvTnVtKHJhdy5hKSA6IDI1NSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VDb2xvcihyYXcpO1xuICAgIH0sXG5cbiAgICAvKiogcmVmIOW8leeUqOaYr+WQpuS4uuiKgueCueW8leeUqO+8iGNjLk5vZGXvvInvvJvnu4Tku7blvJXnlKjov5Tlm54gZmFsc2XvvIznlKjkuo7ljLrliIYgdWktbm9kZSAvIHVpLWNvbXBvbmVudCDmmL7npLrjgIIgKi9cbiAgICBpc05vZGVSZWYodGhpczogYW55LCBwOiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICFwIHx8ICFwLmNvbXBvbmVudFR5cGUgfHwgcC5jb21wb25lbnRUeXBlID09PSAnY2MuTm9kZSc7XG4gICAgfSxcblxuICAgIC8qKiDku47lvZPliY0gaW5zcGVjdG9yIOS4reWPluato+WcqOe8lui+keWtl+auteeahOacrOWcsOS5kOinguWAvO+8iOWGmeWbnuWQjuS4jeivpeiiq+Wbnuivu+imhueblu+8ieOAgiAqL1xuICAgIGdldExvY2FsVmFsdWUodGhpczogYW55LCBwYXlsb2FkOiBhbnkpOiBhbnkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHBheWxvYWQuY29tcCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29tcCA9IHRoaXMuaW5zcGVjdG9yPy5jb21wb25lbnRzPy5bcGF5bG9hZC5jb21wXTtcbiAgICAgICAgICAgICAgICBjb25zdCBwID0gY29tcD8ucHJvcHM/LmZpbmQoKHg6IGFueSkgPT4geC5rZXkgPT09IHBheWxvYWQua2V5KTtcbiAgICAgICAgICAgICAgICBjb25zdCB2ID0gcCAmJiAocGF5bG9hZC5pbmRleCA9PT0gdW5kZWZpbmVkID8gcC52IDogcC52Py5bcGF5bG9hZC5pbmRleF0/LnYpO1xuICAgICAgICAgICAgICAgIHJldHVybiB2ID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHYpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwYXlsb2FkLmZpZWxkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2ID0gdGhpcy5pbnNwZWN0b3I/LnByb3BzPy5bcGF5bG9hZC5maWVsZF0/LnY7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHYgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIHsgLyogaWdub3JlICovIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9LFxuICAgIC8qKiDku47lm57or7vnu5PmnpzkuK3lj5blkIzkuIDlrZfmrrXlrp7pmYXlgLzvvIjlr7nmr5Tor4rmlq3nlKjvvInjgIIgKi9cbiAgICBwaWNrVmFsdWUodGhpczogYW55LCBiYWNrOiBhbnksIHBheWxvYWQ6IGFueSk6IGFueSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAocGF5bG9hZC5jb21wICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb21wID0gYmFjay5jb21wb25lbnRzPy5bcGF5bG9hZC5jb21wXTtcbiAgICAgICAgICAgICAgICBjb25zdCBwID0gY29tcD8ucHJvcHM/LmZpbmQoKHg6IGFueSkgPT4geC5rZXkgPT09IHBheWxvYWQua2V5KTtcbiAgICAgICAgICAgICAgICBjb25zdCB2ID0gcCAmJiAocGF5bG9hZC5pbmRleCA9PT0gdW5kZWZpbmVkID8gcC52IDogcC52Py5bcGF5bG9hZC5pbmRleF0/LnYpO1xuICAgICAgICAgICAgICAgIHJldHVybiB2ID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHYpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwYXlsb2FkLmZpZWxkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2ID0gYmFjay5wcm9wcz8uW3BheWxvYWQuZmllbGRdPy52O1xuICAgICAgICAgICAgICAgIHJldHVybiB2ID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHYpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCB7IC8qIGlnbm9yZSAqLyB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfSxcbiAgICAvKiog5oqKIFVJIOS4reato+WcqOe8lui+keeahOWtl+auteaBouWkjeaIkOacrOWcsOS5kOinguWAvO+8iOWbnuivu+ivt+axguS4jeaUueWGmee8lui+keahhu+8ieOAgiAqL1xuICAgIGFwcGx5TG9jYWxWYWx1ZSh0aGlzOiBhbnksIGluc3A6IGFueSwgcGF5bG9hZDogYW55LCB2YWw6IGFueSk6IHZvaWQge1xuICAgICAgICBpZiAodmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHBheWxvYWQuY29tcCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29tcCA9IGluc3AuY29tcG9uZW50cz8uW3BheWxvYWQuY29tcF07XG4gICAgICAgICAgICAgICAgY29uc3QgcCA9IGNvbXA/LnByb3BzPy5maW5kKCh4OiBhbnkpID0+IHgua2V5ID09PSBwYXlsb2FkLmtleSk7XG4gICAgICAgICAgICAgICAgaWYgKHApIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBheWxvYWQuaW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcC52ID0gdmFsO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHAudj8uW3BheWxvYWQuaW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwLnZbcGF5bG9hZC5pbmRleF0udiA9IHZhbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAocGF5bG9hZC5maWVsZCAhPT0gdW5kZWZpbmVkICYmIGluc3AucHJvcHM/LltwYXlsb2FkLmZpZWxkXSkge1xuICAgICAgICAgICAgICAgIGluc3AucHJvcHNbcGF5bG9hZC5maWVsZF0udiA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCB7IC8qIGlnbm9yZSAqLyB9XG4gICAgfSxcbn07XG4iXX0= \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/dist/panels/default/methods/logs.js b/extensions/YYKA运行时工作台/dist/panels/default/methods/logs.js new file mode 100644 index 0000000..22b13bd --- /dev/null +++ b/extensions/YYKA运行时工作台/dist/panels/default/methods/logs.js @@ -0,0 +1,66 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** 日志面板:格式化/过滤/自动滚动/复制/清空。 */ +exports.default = { + logClass(l) { + const m = l && typeof l === 'object' ? l : null; + return m && m.evt === 'console' ? `lv-${m.level}` : ''; + }, + logText(l) { + const m = l && typeof l === 'object' ? l : null; + if (m && m.evt === 'console') { + return m.text; + } + return this.fmt(l); + }, + logLevel(l) { + const m = l && typeof l === 'object' ? l : null; + return m && m.evt === 'console' ? String(m.level) : 'info'; + }, + logLevelText(l) { + return this.logLevel(l).toUpperCase(); + }, + logTime(l) { + const m = l && typeof l === 'object' ? l : null; + const t = m && typeof m.t === 'number' ? m.t : 0; + if (!t) { + return ''; + } + const d = new Date(t); + const p = (n) => String(n).padStart(2, '0'); + return `${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`; + }, + scrollLogToBottom() { + // 用户正在向上翻历史时暂停跟随 + if (this.logUserUp) { + return; + } + this.$nextTick(() => { + const el = this.$refs.logList; + if (!el) { + return; + } + el.scrollTop = el.scrollHeight; + }); + }, + onLogScroll() { + const el = this.$refs.logList; + if (!el) { + return; + } + // 主动滚离底部 → 记录;滚回底部附近 → 恢复自动跟随 + this.logUserUp = el.scrollHeight - el.scrollTop - el.clientHeight >= 40; + }, + async copyLogs() { + const text = this.filteredLogs.map((l) => this.logText(l)).join('\n'); + await this.writeClipboard(text); + }, + clearLogs() { + this.logs = []; + this.logUserUp = false; + }, + async copyLogLine(l) { + await this.writeClipboard(this.fmt(l)); + }, +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9ncy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NvdXJjZS9wYW5lbHMvZGVmYXVsdC9tZXRob2RzL2xvZ3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw4QkFBOEI7QUFDOUIsa0JBQWU7SUFDWCxRQUFRLENBQVksQ0FBVTtRQUMxQixNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBRSxDQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUN6RCxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUMzRCxDQUFDO0lBQ0QsT0FBTyxDQUFZLENBQVU7UUFDekIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUUsQ0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDekQsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMzQixPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDbEIsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2QixDQUFDO0lBQ0QsUUFBUSxDQUFZLENBQVU7UUFDMUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUUsQ0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDekQsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMvRCxDQUFDO0lBQ0QsWUFBWSxDQUFZLENBQVU7UUFDOUIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQzFDLENBQUM7SUFDRCxPQUFPLENBQVksQ0FBVTtRQUN6QixNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBRSxDQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUN6RCxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNMLE9BQU8sRUFBRSxDQUFDO1FBQ2QsQ0FBQztRQUNELE1BQU0sQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNwRCxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUMxRSxDQUFDO0lBQ0QsaUJBQWlCO1FBQ2IsaUJBQWlCO1FBQ2pCLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2pCLE9BQU87UUFDWCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDaEIsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFrQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDTixPQUFPO1lBQ1gsQ0FBQztZQUNELEVBQUUsQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQztRQUNuQyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFDRCxXQUFXO1FBQ1AsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFrQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNOLE9BQU87UUFDWCxDQUFDO1FBQ0QsOEJBQThCO1FBQzlCLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxZQUFZLElBQUksRUFBRSxDQUFDO0lBQzVFLENBQUM7SUFDRCxLQUFLLENBQUMsUUFBUTtRQUNWLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBVSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9FLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBQ0QsU0FBUztRQUNMLElBQUksQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ2YsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDM0IsQ0FBQztJQUNELEtBQUssQ0FBQyxXQUFXLENBQVksQ0FBVTtRQUNuQyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNDLENBQUM7Q0FDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIOaXpeW/l+mdouadv++8muagvOW8j+WMli/ov4fmu6Qv6Ieq5Yqo5rua5YqoL+WkjeWIti/muIXnqbrjgIIgKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBsb2dDbGFzcyh0aGlzOiBhbnksIGw6IHVua25vd24pOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBtID0gbCAmJiB0eXBlb2YgbCA9PT0gJ29iamVjdCcgPyAobCBhcyBhbnkpIDogbnVsbDtcbiAgICAgICAgcmV0dXJuIG0gJiYgbS5ldnQgPT09ICdjb25zb2xlJyA/IGBsdi0ke20ubGV2ZWx9YCA6ICcnO1xuICAgIH0sXG4gICAgbG9nVGV4dCh0aGlzOiBhbnksIGw6IHVua25vd24pOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBtID0gbCAmJiB0eXBlb2YgbCA9PT0gJ29iamVjdCcgPyAobCBhcyBhbnkpIDogbnVsbDtcbiAgICAgICAgaWYgKG0gJiYgbS5ldnQgPT09ICdjb25zb2xlJykge1xuICAgICAgICAgICAgcmV0dXJuIG0udGV4dDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5mbXQobCk7XG4gICAgfSxcbiAgICBsb2dMZXZlbCh0aGlzOiBhbnksIGw6IHVua25vd24pOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBtID0gbCAmJiB0eXBlb2YgbCA9PT0gJ29iamVjdCcgPyAobCBhcyBhbnkpIDogbnVsbDtcbiAgICAgICAgcmV0dXJuIG0gJiYgbS5ldnQgPT09ICdjb25zb2xlJyA/IFN0cmluZyhtLmxldmVsKSA6ICdpbmZvJztcbiAgICB9LFxuICAgIGxvZ0xldmVsVGV4dCh0aGlzOiBhbnksIGw6IHVua25vd24pOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2dMZXZlbChsKS50b1VwcGVyQ2FzZSgpO1xuICAgIH0sXG4gICAgbG9nVGltZSh0aGlzOiBhbnksIGw6IHVua25vd24pOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBtID0gbCAmJiB0eXBlb2YgbCA9PT0gJ29iamVjdCcgPyAobCBhcyBhbnkpIDogbnVsbDtcbiAgICAgICAgY29uc3QgdCA9IG0gJiYgdHlwZW9mIG0udCA9PT0gJ251bWJlcicgPyBtLnQgOiAwO1xuICAgICAgICBpZiAoIXQpIHtcbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkID0gbmV3IERhdGUodCk7XG4gICAgICAgIGNvbnN0IHAgPSAobjogbnVtYmVyKSA9PiBTdHJpbmcobikucGFkU3RhcnQoMiwgJzAnKTtcbiAgICAgICAgcmV0dXJuIGAke3AoZC5nZXRIb3VycygpKX06JHtwKGQuZ2V0TWludXRlcygpKX06JHtwKGQuZ2V0U2Vjb25kcygpKX1gO1xuICAgIH0sXG4gICAgc2Nyb2xsTG9nVG9Cb3R0b20odGhpczogYW55KSB7XG4gICAgICAgIC8vIOeUqOaIt+ato+WcqOWQkeS4iue/u+WOhuWPsuaXtuaaguWBnOi3n+maj1xuICAgICAgICBpZiAodGhpcy5sb2dVc2VyVXApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLiRuZXh0VGljaygoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbCA9IHRoaXMuJHJlZnMubG9nTGlzdCBhcyBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmICghZWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbC5zY3JvbGxUb3AgPSBlbC5zY3JvbGxIZWlnaHQ7XG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgb25Mb2dTY3JvbGwodGhpczogYW55KSB7XG4gICAgICAgIGNvbnN0IGVsID0gdGhpcy4kcmVmcy5sb2dMaXN0IGFzIEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkO1xuICAgICAgICBpZiAoIWVsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8g5Li75Yqo5rua56a75bqV6YOoIOKGkiDorrDlvZXvvJvmu5rlm57lupXpg6jpmYTov5Eg4oaSIOaBouWkjeiHquWKqOi3n+maj1xuICAgICAgICB0aGlzLmxvZ1VzZXJVcCA9IGVsLnNjcm9sbEhlaWdodCAtIGVsLnNjcm9sbFRvcCAtIGVsLmNsaWVudEhlaWdodCA+PSA0MDtcbiAgICB9LFxuICAgIGFzeW5jIGNvcHlMb2dzKHRoaXM6IGFueSkge1xuICAgICAgICBjb25zdCB0ZXh0ID0gdGhpcy5maWx0ZXJlZExvZ3MubWFwKChsOiB1bmtub3duKSA9PiB0aGlzLmxvZ1RleHQobCkpLmpvaW4oJ1xcbicpO1xuICAgICAgICBhd2FpdCB0aGlzLndyaXRlQ2xpcGJvYXJkKHRleHQpO1xuICAgIH0sXG4gICAgY2xlYXJMb2dzKHRoaXM6IGFueSkge1xuICAgICAgICB0aGlzLmxvZ3MgPSBbXTtcbiAgICAgICAgdGhpcy5sb2dVc2VyVXAgPSBmYWxzZTtcbiAgICB9LFxuICAgIGFzeW5jIGNvcHlMb2dMaW5lKHRoaXM6IGFueSwgbDogdW5rbm93bikge1xuICAgICAgICBhd2FpdCB0aGlzLndyaXRlQ2xpcGJvYXJkKHRoaXMuZm10KGwpKTtcbiAgICB9LFxufTtcbiJdfQ== \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/dist/panels/default/methods/mcp.js b/extensions/YYKA运行时工作台/dist/panels/default/methods/mcp.js new file mode 100644 index 0000000..5310843 --- /dev/null +++ b/extensions/YYKA运行时工作台/dist/panels/default/methods/mcp.js @@ -0,0 +1,81 @@ +"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")); +/** MCP 服务:配置弹窗 / 启停 / 端口修改 / 配置复制。 */ +exports.default = { + openMcpDialog() { + this.showMcpDialog = true; + this.mcpPort = this.mcp.port || 33010; + }, + closeMcpDialog() { + this.showMcpDialog = false; + }, + async toggleMcp() { + if (this.mcpBusy) { + return; + } + this.mcpBusy = true; + try { + if (this.mcp.running) { + await Editor.Message.request(package_json_1.default.name, 'stop-mcp'); + } + else { + await Editor.Message.request(package_json_1.default.name, 'start-mcp', this.mcpPort); + } + await this.loadMcpState(); + } + finally { + this.mcpBusy = false; + } + }, + /** 保存弹窗中修改的端口并重启 MCP 服务(端口变化时)。 */ + async applyMcpPort() { + const port = Math.max(1, Math.min(65535, Math.floor(Number(this.mcpPort) || 33010))); + this.mcpPort = port; + if (this.mcp.running && this.mcp.port !== port) { + this.mcpBusy = true; + try { + await Editor.Message.request(package_json_1.default.name, 'stop-mcp'); + await Editor.Message.request(package_json_1.default.name, 'start-mcp', port); + await this.loadMcpState(); + } + finally { + this.mcpBusy = false; + } + } + else if (!this.mcp.running) { + // 未运行则仅保存端口,供后续启动使用 + this.mcpPort = port; + } + }, + async loadMcpState() { + try { + const st = await Editor.Message.request(package_json_1.default.name, 'get-mcp-state'); + if (st && typeof st === 'object') { + this.mcp = { + running: !!st.running, + port: Number(st.port) || 0, + url: String(st.url || ''), + token: String(st.token || ''), + }; + } + } + catch (_a) { + /* 忽略 */ + } + }, + async copyMcpConfig() { + const text = `{\n "mcpServers": {\n "yyka-runtime-inspector": {\n "url": "${this.mcp.url}",\n "headers": { "Authorization": "Bearer ${this.mcp.token}" }\n }\n }\n}`; + await this.writeClipboard(text); + this.mcpCopied = true; + window.clearTimeout(this.mcpCopyTimer); + this.mcpCopyTimer = window.setTimeout(() => { + this.mcpCopied = false; + }, 1600); + }, +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc291cmNlL3BhbmVscy9kZWZhdWx0L21ldGhvZHMvbWNwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsYUFBYTtBQUNiLDRFQUFtRDtBQUVuRCxzQ0FBc0M7QUFDdEMsa0JBQWU7SUFDWCxhQUFhO1FBQ1QsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDMUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxLQUFLLENBQUM7SUFDMUMsQ0FBQztJQUNELGNBQWM7UUFDVixJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztJQUMvQixDQUFDO0lBQ0QsS0FBSyxDQUFDLFNBQVM7UUFDWCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNmLE9BQU87UUFDWCxDQUFDO1FBQ0QsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDcEIsSUFBSSxDQUFDO1lBQ0QsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNuQixNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLHNCQUFXLENBQUMsSUFBVyxFQUFFLFVBQWlCLENBQUMsQ0FBQztZQUM3RSxDQUFDO2lCQUFNLENBQUM7Z0JBQ0osTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxzQkFBVyxDQUFDLElBQVcsRUFBRSxXQUFrQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM1RixDQUFDO1lBQ0QsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDOUIsQ0FBQztnQkFBUyxDQUFDO1lBQ1AsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDekIsQ0FBQztJQUNMLENBQUM7SUFDRCxtQ0FBbUM7SUFDbkMsS0FBSyxDQUFDLFlBQVk7UUFDZCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JGLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDN0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7WUFDcEIsSUFBSSxDQUFDO2dCQUNELE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsc0JBQVcsQ0FBQyxJQUFXLEVBQUUsVUFBaUIsQ0FBQyxDQUFDO2dCQUN6RSxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLHNCQUFXLENBQUMsSUFBVyxFQUFFLFdBQWtCLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ2hGLE1BQU0sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQzlCLENBQUM7b0JBQVMsQ0FBQztnQkFDUCxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztZQUN6QixDQUFDO1FBQ0wsQ0FBQzthQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQzNCLG9CQUFvQjtZQUNwQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUN4QixDQUFDO0lBQ0wsQ0FBQztJQUNELEtBQUssQ0FBQyxZQUFZO1FBQ2QsSUFBSSxDQUFDO1lBQ0QsTUFBTSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxzQkFBVyxDQUFDLElBQVcsRUFBRSxlQUFzQixDQUFDLENBQUM7WUFDekYsSUFBSSxFQUFFLElBQUksT0FBTyxFQUFFLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQy9CLElBQUksQ0FBQyxHQUFHLEdBQUc7b0JBQ1AsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTztvQkFDckIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztvQkFDMUIsR0FBRyxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQztvQkFDekIsS0FBSyxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztpQkFDaEMsQ0FBQztZQUNOLENBQUM7UUFDTCxDQUFDO1FBQUMsV0FBTSxDQUFDO1lBQ0wsUUFBUTtRQUNaLENBQUM7SUFDTCxDQUFDO0lBQ0QsS0FBSyxDQUFDLGFBQWE7UUFDZixNQUFNLElBQUksR0FBRyx3RUFBd0UsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLG1EQUFtRCxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssb0JBQW9CLENBQUM7UUFDdkwsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxZQUFZLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDdkMsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDM0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2IsQ0FBQztDQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtaWdub3JlXG5pbXBvcnQgcGFja2FnZUpTT04gZnJvbSAnLi4vLi4vLi4vLi4vcGFja2FnZS5qc29uJztcblxuLyoqIE1DUCDmnI3liqHvvJrphY3nva7lvLnnqpcgLyDlkK/lgZwgLyDnq6/lj6Pkv67mlLkgLyDphY3nva7lpI3liLbjgIIgKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBvcGVuTWNwRGlhbG9nKHRoaXM6IGFueSkge1xuICAgICAgICB0aGlzLnNob3dNY3BEaWFsb2cgPSB0cnVlO1xuICAgICAgICB0aGlzLm1jcFBvcnQgPSB0aGlzLm1jcC5wb3J0IHx8IDMzMDEwO1xuICAgIH0sXG4gICAgY2xvc2VNY3BEaWFsb2codGhpczogYW55KSB7XG4gICAgICAgIHRoaXMuc2hvd01jcERpYWxvZyA9IGZhbHNlO1xuICAgIH0sXG4gICAgYXN5bmMgdG9nZ2xlTWNwKHRoaXM6IGFueSkge1xuICAgICAgICBpZiAodGhpcy5tY3BCdXN5KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5tY3BCdXN5ID0gdHJ1ZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICh0aGlzLm1jcC5ydW5uaW5nKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgRWRpdG9yLk1lc3NhZ2UucmVxdWVzdChwYWNrYWdlSlNPTi5uYW1lIGFzIGFueSwgJ3N0b3AtbWNwJyBhcyBhbnkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBFZGl0b3IuTWVzc2FnZS5yZXF1ZXN0KHBhY2thZ2VKU09OLm5hbWUgYXMgYW55LCAnc3RhcnQtbWNwJyBhcyBhbnksIHRoaXMubWNwUG9ydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmxvYWRNY3BTdGF0ZSgpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5tY3BCdXN5ID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8qKiDkv53lrZjlvLnnqpfkuK3kv67mlLnnmoTnq6/lj6Plubbph43lkK8gTUNQIOacjeWKoe+8iOerr+WPo+WPmOWMluaXtu+8ieOAgiAqL1xuICAgIGFzeW5jIGFwcGx5TWNwUG9ydCh0aGlzOiBhbnkpIHtcbiAgICAgICAgY29uc3QgcG9ydCA9IE1hdGgubWF4KDEsIE1hdGgubWluKDY1NTM1LCBNYXRoLmZsb29yKE51bWJlcih0aGlzLm1jcFBvcnQpIHx8IDMzMDEwKSkpO1xuICAgICAgICB0aGlzLm1jcFBvcnQgPSBwb3J0O1xuICAgICAgICBpZiAodGhpcy5tY3AucnVubmluZyAmJiB0aGlzLm1jcC5wb3J0ICE9PSBwb3J0KSB7XG4gICAgICAgICAgICB0aGlzLm1jcEJ1c3kgPSB0cnVlO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBFZGl0b3IuTWVzc2FnZS5yZXF1ZXN0KHBhY2thZ2VKU09OLm5hbWUgYXMgYW55LCAnc3RvcC1tY3AnIGFzIGFueSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgRWRpdG9yLk1lc3NhZ2UucmVxdWVzdChwYWNrYWdlSlNPTi5uYW1lIGFzIGFueSwgJ3N0YXJ0LW1jcCcgYXMgYW55LCBwb3J0KTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmxvYWRNY3BTdGF0ZSgpO1xuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICB0aGlzLm1jcEJ1c3kgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5tY3AucnVubmluZykge1xuICAgICAgICAgICAgLy8g5pyq6L+Q6KGM5YiZ5LuF5L+d5a2Y56uv5Y+j77yM5L6b5ZCO57ut5ZCv5Yqo5L2/55SoXG4gICAgICAgICAgICB0aGlzLm1jcFBvcnQgPSBwb3J0O1xuICAgICAgICB9XG4gICAgfSxcbiAgICBhc3luYyBsb2FkTWNwU3RhdGUodGhpczogYW55KSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzdCA9IGF3YWl0IEVkaXRvci5NZXNzYWdlLnJlcXVlc3QocGFja2FnZUpTT04ubmFtZSBhcyBhbnksICdnZXQtbWNwLXN0YXRlJyBhcyBhbnkpO1xuICAgICAgICAgICAgaWYgKHN0ICYmIHR5cGVvZiBzdCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1jcCA9IHtcbiAgICAgICAgICAgICAgICAgICAgcnVubmluZzogISFzdC5ydW5uaW5nLFxuICAgICAgICAgICAgICAgICAgICBwb3J0OiBOdW1iZXIoc3QucG9ydCkgfHwgMCxcbiAgICAgICAgICAgICAgICAgICAgdXJsOiBTdHJpbmcoc3QudXJsIHx8ICcnKSxcbiAgICAgICAgICAgICAgICAgICAgdG9rZW46IFN0cmluZyhzdC50b2tlbiB8fCAnJyksXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvKiDlv73nlaUgKi9cbiAgICAgICAgfVxuICAgIH0sXG4gICAgYXN5bmMgY29weU1jcENvbmZpZyh0aGlzOiBhbnkpIHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGB7XFxuICBcIm1jcFNlcnZlcnNcIjoge1xcbiAgICBcInl5a2EtcnVudGltZS1pbnNwZWN0b3JcIjoge1xcbiAgICAgIFwidXJsXCI6IFwiJHt0aGlzLm1jcC51cmx9XCIsXFxuICAgICAgXCJoZWFkZXJzXCI6IHsgXCJBdXRob3JpemF0aW9uXCI6IFwiQmVhcmVyICR7dGhpcy5tY3AudG9rZW59XCIgfVxcbiAgICB9XFxuICB9XFxufWA7XG4gICAgICAgIGF3YWl0IHRoaXMud3JpdGVDbGlwYm9hcmQodGV4dCk7XG4gICAgICAgIHRoaXMubWNwQ29waWVkID0gdHJ1ZTtcbiAgICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLm1jcENvcHlUaW1lcik7XG4gICAgICAgIHRoaXMubWNwQ29weVRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5tY3BDb3BpZWQgPSBmYWxzZTtcbiAgICAgICAgfSwgMTYwMCk7XG4gICAgfSxcbn07XG4iXX0= \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/dist/panels/default/methods/perf.js b/extensions/YYKA运行时工作台/dist/panels/default/methods/perf.js new file mode 100644 index 0000000..adf4eef --- /dev/null +++ b/extensions/YYKA运行时工作台/dist/panels/default/methods/perf.js @@ -0,0 +1,209 @@ +"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")); +/** 性能曲线:采样 + Canvas 自绘(无第三方图表依赖)。 */ +exports.default = { + stopPerfSampling() { + if (this.perfTimer) { + window.clearInterval(this.perfTimer); + this.perfTimer = 0; + } + }, + async samplePerf() { + var _a, _b, _c, _d, _e, _f; + if (this.state.clients <= 0) { + return; + } + try { + const s = (await Editor.Message.request(package_json_1.default.name, 'query-command', { cmd: 'get-stats' })); + if (s && typeof s === 'object') { + this.stats = { + drawCall: (_a = s.drawCall) !== null && _a !== void 0 ? _a : 0, + triangles: (_c = (_b = s.triangles) !== null && _b !== void 0 ? _b : s.triangle) !== null && _c !== void 0 ? _c : 0, + fps: (_d = s.fps) !== null && _d !== void 0 ? _d : 0, + memUsed: (_e = s.memUsed) !== null && _e !== void 0 ? _e : 0, + memTotal: (_f = s.memTotal) !== null && _f !== void 0 ? _f : 0, + }; + this.perf.push({ fps: this.stats.fps, dc: this.stats.drawCall }); + // 滑动窗口:满 400 条后移除最旧一条,数组恒定 400,绘制持续进行 + if (this.perf.length > 400) { + this.perf.shift(); + } + this.drawPerf(); + } + } + catch (_g) { + /* 忽略采样失败 */ + } + }, + drawPerf() { + const el = this.$refs.perfCanvas; + if (!el) { + return; + } + const dpr = window.devicePixelRatio || 1; + const cw = el.clientWidth; + const ch = el.clientHeight; + if (cw <= 0 || ch <= 0) { + return; + } + const W = Math.round(cw * dpr); + const H = Math.round(ch * dpr); + if (el.width !== W || el.height !== H) { + el.width = W; + el.height = H; + } + const ctx = el.getContext('2d'); + if (!ctx) { + return; + } + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + ctx.clearRect(0, 0, cw, ch); + const pts = this.perf; + // 绘图区:左右留刻度空间,顶部留 4,底部留 16 放 x 轴时间标签 + const plot = { l: 36, r: cw - 44, t: 6, b: ch - 16 }; + const pw = Math.max(1, plot.r - plot.l); + const ph = Math.max(1, plot.b - plot.t); + const start = Math.max(0, pts.length - 90); + const n = pts.length - start; + const stepX = pw / 90; + const xAt = (idx) => plot.l + (idx - start) * stepX; + const maxFps = 60; + const maxDc = Math.max(20, ...pts.map((p) => p.dc)) * 1.1; + const dcMax = Math.max(20, Math.ceil(maxDc / 20) * 20); + const yAt = (v, max) => plot.b - (Math.min(max, v) / max) * ph; + // ---- 网格 + 帧率轴刻度(左,绿 0/20/40/60) ---- + ctx.font = '10px sans-serif'; + ctx.textBaseline = 'middle'; + ctx.strokeStyle = 'rgba(128,128,128,0.18)'; + ctx.lineWidth = 1; + for (const v of [0, 20, 40, 60]) { + const y = Math.round(yAt(v, maxFps)) + 0.5; + ctx.beginPath(); + ctx.moveTo(plot.l, y); + ctx.lineTo(plot.r, y); + ctx.stroke(); + ctx.fillStyle = '#4ade80'; + ctx.textAlign = 'right'; + ctx.fillText(String(v), plot.l - 4, y); + } + // ---- 绘制调用轴刻度(右,黄 0/mid/max) ---- + for (const v of [0, Math.round(dcMax / 2), dcMax]) { + const y = Math.round(yAt(v, dcMax)) + 0.5; + ctx.beginPath(); + ctx.moveTo(plot.l, y); + ctx.lineTo(plot.r, y); + ctx.stroke(); + ctx.fillStyle = '#fbbf24'; + ctx.textAlign = 'left'; + ctx.fillText(String(v), plot.r + 4, y); + } + // ---- x 轴时间标签(底部) ---- + ctx.fillStyle = '#888'; + ctx.textAlign = 'center'; + ctx.fillText('-80s', xAt(start), plot.b + 9); + ctx.fillText('-60s', xAt(start + 30), plot.b + 9); + ctx.fillText('-40s', xAt(start + 60), plot.b + 9); + ctx.fillText('-20s', xAt(start + 80), plot.b + 9); + ctx.fillText('0s', plot.r, plot.b + 9); + if (n < 2) { + return; + } + // ---- Catmull-Rom → 三次贝塞尔平滑曲线 ---- + const drawSeries = (get, max, color) => { + ctx.strokeStyle = color; + ctx.lineWidth = 1.5; + ctx.lineJoin = 'round'; + ctx.lineCap = 'round'; + ctx.beginPath(); + ctx.moveTo(xAt(start), yAt(get(pts[start]), max)); + if (n === 2) { + ctx.lineTo(xAt(start + 1), yAt(get(pts[start + 1]), max)); + } + else { + for (let i = start; i < pts.length - 1; i++) { + const p0i = Math.max(start, i - 1); + const p2i = i + 1; + const p3i = Math.min(pts.length - 1, i + 2); + const cp1x = xAt(i) + (xAt(p2i) - xAt(p0i)) / 6; + const cp1y = yAt(get(pts[i]), max) + (yAt(get(pts[p2i]), max) - yAt(get(pts[p0i]), max)) / 6; + const cp2x = xAt(p2i) - (xAt(p3i) - xAt(i)) / 6; + const cp2y = yAt(get(pts[p2i]), max) - (yAt(get(pts[p3i]), max) - yAt(get(pts[i]), max)) / 6; + ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, xAt(p2i), yAt(get(pts[p2i]), max)); + } + } + ctx.stroke(); + }; + drawSeries((p) => p.fps, maxFps, '#4ade80'); + drawSeries((p) => p.dc, dcMax, '#fbbf24'); + // ---- 悬停/点击峰值:十字线 + 圆点 + 数值提示框 ---- + if (this.hoverIdx >= 0 && this.hoverIdx >= start && this.hoverIdx < pts.length) { + const p = pts[this.hoverIdx]; + const x = xAt(this.hoverIdx); + ctx.strokeStyle = 'rgba(255,255,255,0.35)'; + ctx.beginPath(); + ctx.moveTo(Math.round(x) + 0.5, plot.t); + ctx.lineTo(Math.round(x) + 0.5, plot.b); + ctx.stroke(); + const hoverSeries = [ + [(p) => p.fps, maxFps, '#4ade80'], + [(p) => p.dc, dcMax, '#fbbf24'], + ]; + for (const [get, max, color] of hoverSeries) { + ctx.fillStyle = color; + ctx.beginPath(); + ctx.arc(x, yAt(get(p), max), 3, 0, Math.PI * 2); + ctx.fill(); + } + const rel = this.hoverIdx - (pts.length - 1); + const lines = [`${rel}s`, `帧率 ${p.fps}`, `绘制调用 ${p.dc}`]; + const lineH = 14; + const boxW = 118; + const boxH = lines.length * lineH + 8; + let bx = plot.l + 4; + const by = plot.t + 4; + if (x + 140 > cw) { + bx = x - boxW - 8; + } + ctx.fillStyle = 'rgba(25,25,25,0.92)'; + ctx.strokeStyle = 'rgba(128,128,128,0.5)'; + ctx.fillRect(bx, by, boxW, boxH); + ctx.strokeRect(bx, by, boxW, boxH); + ctx.textAlign = 'left'; + lines.forEach((ln, i) => { + ctx.fillStyle = i === 0 ? '#aaa' : i === 1 ? '#4ade80' : '#fbbf24'; + ctx.fillText(ln, bx + 6, by + 10 + i * lineH); + }); + } + }, + onPerfMove(e) { + const el = this.$refs.perfCanvas; + if (!el || !this.perf.length) { + return; + } + const rect = el.getBoundingClientRect(); + const cw = el.clientWidth; + // 与 drawPerf 保持一致的绘图区换算 + const plotL = 36; + const plotR = cw - 44; + const stepX = Math.max(1, plotR - plotL) / 90; + const start = Math.max(0, this.perf.length - 90); + const idx = start + Math.round((e.clientX - rect.left - plotL) / stepX); + const clamped = Math.max(start, Math.min(this.perf.length - 1, idx)); + if (clamped !== this.hoverIdx) { + this.hoverIdx = clamped; + this.drawPerf(); + } + }, + onPerfLeave() { + if (this.hoverIdx !== -1) { + this.hoverIdx = -1; + this.drawPerf(); + } + }, +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVyZi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NvdXJjZS9wYW5lbHMvZGVmYXVsdC9tZXRob2RzL3BlcmYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxhQUFhO0FBQ2IsNEVBQW1EO0FBRW5ELHFDQUFxQztBQUNyQyxrQkFBZTtJQUNYLGdCQUFnQjtRQUNaLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2pCLE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7SUFDTCxDQUFDO0lBQ0QsS0FBSyxDQUFDLFVBQVU7O1FBQ1osSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMxQixPQUFPO1FBQ1gsQ0FBQztRQUNELElBQUksQ0FBQztZQUNELE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FDbkMsc0JBQVcsQ0FBQyxJQUFXLEVBQ3ZCLGVBQXNCLEVBQ3RCLEVBQUUsR0FBRyxFQUFFLFdBQVcsRUFBUyxDQUM5QixDQUFRLENBQUM7WUFDVixJQUFJLENBQUMsSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLEtBQUssR0FBRztvQkFDVCxRQUFRLEVBQUUsTUFBQSxDQUFDLENBQUMsUUFBUSxtQ0FBSSxDQUFDO29CQUN6QixTQUFTLEVBQUUsTUFBQSxNQUFBLENBQUMsQ0FBQyxTQUFTLG1DQUFJLENBQUMsQ0FBQyxRQUFRLG1DQUFJLENBQUM7b0JBQ3pDLEdBQUcsRUFBRSxNQUFBLENBQUMsQ0FBQyxHQUFHLG1DQUFJLENBQUM7b0JBQ2YsT0FBTyxFQUFFLE1BQUEsQ0FBQyxDQUFDLE9BQU8sbUNBQUksQ0FBQztvQkFDdkIsUUFBUSxFQUFFLE1BQUEsQ0FBQyxDQUFDLFFBQVEsbUNBQUksQ0FBQztpQkFDNUIsQ0FBQztnQkFDRixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO2dCQUNqRSxzQ0FBc0M7Z0JBQ3RDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUM7b0JBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3RCLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3BCLENBQUM7UUFDTCxDQUFDO1FBQUMsV0FBTSxDQUFDO1lBQ0wsWUFBWTtRQUNoQixDQUFDO0lBQ0wsQ0FBQztJQUNELFFBQVE7UUFDSixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQTJDLENBQUM7UUFDbEUsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ04sT0FBTztRQUNYLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxDQUFDO1FBQ3pDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUM7UUFDMUIsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQztRQUMzQixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3JCLE9BQU87UUFDWCxDQUFDO1FBQ0QsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDL0IsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDL0IsSUFBSSxFQUFFLENBQUMsS0FBSyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3BDLEVBQUUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ2IsRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDbEIsQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1AsT0FBTztRQUNYLENBQUM7UUFDRCxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDdkMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQ3RCLHFDQUFxQztRQUNyQyxNQUFNLElBQUksR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO1FBQ3JELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDM0MsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDN0IsTUFBTSxLQUFLLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUN0QixNQUFNLEdBQUcsR0FBRyxDQUFDLEdBQVcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUM7UUFDNUQsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQThCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztRQUN2RixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUN2RCxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQVMsRUFBRSxHQUFXLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFL0UsdUNBQXVDO1FBQ3ZDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsaUJBQWlCLENBQUM7UUFDN0IsR0FBRyxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUM7UUFDNUIsR0FBRyxDQUFDLFdBQVcsR0FBRyx3QkFBd0IsQ0FBQztRQUMzQyxHQUFHLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztRQUNsQixLQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUM5QixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsR0FBRyxHQUFHLENB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QUN0QixHQUFHLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDaEIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ2xELElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNWLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzlELENBQUM7aUJBQU0sQ0FBQztnQkFDSixLQUFLLElBQUksQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDMUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO29CQUNuQyxNQUFNLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNsQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztvQkFDNUMsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDaEQsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDN0YsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDaEQsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDN0YsR0FBRyxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDakYsQ0FBQztZQUNMLENBQUM7WUFDRCxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDakIsQ0FBQyxDQUFDO1FBQ0YsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztRQUM1QyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRTFDLHFDQUFxQztRQUNyQyxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzdFLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDN0IsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM3QixHQUFHLENBQUMsV0FBVyxHQUFHLHdCQUF3QixDQUFDO1lBQzNDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNoQixHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDYixNQUFNLFdBQVcsR0FBbUU7Z0JBQ2hGLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQztnQkFDakMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDO2FBQ2xDLENBQUM7WUFDRixLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUMxQyxHQUFHLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztnQkFDdEIsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNoQixHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDaEQsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2YsQ0FBQztZQUNELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzdDLE1BQU0sS0FBSyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3pELE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNqQixNQUFNLElBQUksR0FBRyxHQUFHLENBQUM7WUFDakIsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ3RDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3BCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3RCLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQztnQkFDZixFQUFFLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7WUFDdEIsQ0FBQztZQUNELEdBQUcsQ0FBQyxTQUFTLEdBQUcscUJBQXFCLENBQUM7WUFDdEMsR0FBRyxDQUFDLFdBQVcsR0FBRyx1QkFBdUIsQ0FBQztZQUMxQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2pDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDbkMsR0FBRyxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUM7WUFDdkIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDcEIsR0FBRyxDQUFDLFNBQVMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUNuRSxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDO1lBQ2xELENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQztJQUNMLENBQUM7SUFDRCxVQUFVLENBQVksQ0FBYTtRQUMvQixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQTJDLENBQUM7UUFDbEUsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDM0IsT0FBTztRQUNYLENBQUM7UUFDRCxNQUFNLElBQUksR0FBRyxFQUFFLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUN4QyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDO1FBQzFCLHdCQUF3QjtRQUN4QixNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDakIsTUFBTSxLQUFLLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUN0QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxLQUFLLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQzlDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sR0FBRyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDO1FBQ3hFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDckUsSUFBSSxPQUFPLEtBQUssSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1lBQ3hCLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNwQixDQUFDO0lBQ0wsQ0FBQztJQUNELFdBQVc7UUFDUCxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ25CLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNwQixDQUFDO0lBQ0wsQ0FBQztDQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtaWdub3JlXG5pbXBvcnQgcGFja2FnZUpTT04gZnJvbSAnLi4vLi4vLi4vLi4vcGFja2FnZS5qc29uJztcblxuLyoqIOaAp+iDveabsue6v++8mumHh+agtyArIENhbnZhcyDoh6rnu5jvvIjml6DnrKzkuInmlrnlm77ooajkvp3otZbvvInjgIIgKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBzdG9wUGVyZlNhbXBsaW5nKHRoaXM6IGFueSkge1xuICAgICAgICBpZiAodGhpcy5wZXJmVGltZXIpIHtcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMucGVyZlRpbWVyKTtcbiAgICAgICAgICAgIHRoaXMucGVyZlRpbWVyID0gMDtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgYXN5bmMgc2FtcGxlUGVyZih0aGlzOiBhbnkpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuY2xpZW50cyA8PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHMgPSAoYXdhaXQgRWRpdG9yLk1lc3NhZ2UucmVxdWVzdChcbiAgICAgICAgICAgICAgICBwYWNrYWdlSlNPTi5uYW1lIGFzIGFueSxcbiAgICAgICAgICAgICAgICAncXVlcnktY29tbWFuZCcgYXMgYW55LFxuICAgICAgICAgICAgICAgIHsgY21kOiAnZ2V0LXN0YXRzJyB9IGFzIGFueSxcbiAgICAgICAgICAgICkpIGFzIGFueTtcbiAgICAgICAgICAgIGlmIChzICYmIHR5cGVvZiBzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGRyYXdDYWxsOiBzLmRyYXdDYWxsID8/IDAsXG4gICAgICAgICAgICAgICAgICAgIHRyaWFuZ2xlczogcy50cmlhbmdsZXMgPz8gcy50cmlhbmdsZSA/PyAwLFxuICAgICAgICAgICAgICAgICAgICBmcHM6IHMuZnBzID8/IDAsXG4gICAgICAgICAgICAgICAgICAgIG1lbVVzZWQ6IHMubWVtVXNlZCA/PyAwLFxuICAgICAgICAgICAgICAgICAgICBtZW1Ub3RhbDogcy5tZW1Ub3RhbCA/PyAwLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5wZXJmLnB1c2goeyBmcHM6IHRoaXMuc3RhdHMuZnBzLCBkYzogdGhpcy5zdGF0cy5kcmF3Q2FsbCB9KTtcbiAgICAgICAgICAgICAgICAvLyDmu5Hliqjnqpflj6PvvJrmu6EgNDAwIOadoeWQjuenu+mZpOacgOaXp+S4gOadoe+8jOaVsOe7hOaBkuWumiA0MDDvvIznu5jliLbmjIHnu63ov5vooYxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wZXJmLmxlbmd0aCA+IDQwMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBlcmYuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5kcmF3UGVyZigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8qIOW/veeVpemHh+agt+Wksei0pSAqL1xuICAgICAgICB9XG4gICAgfSxcbiAgICBkcmF3UGVyZih0aGlzOiBhbnkpIHtcbiAgICAgICAgY29uc3QgZWwgPSB0aGlzLiRyZWZzLnBlcmZDYW52YXMgYXMgSFRNTENhbnZhc0VsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmICghZWwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkcHIgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyB8fCAxO1xuICAgICAgICBjb25zdCBjdyA9IGVsLmNsaWVudFdpZHRoO1xuICAgICAgICBjb25zdCBjaCA9IGVsLmNsaWVudEhlaWdodDtcbiAgICAgICAgaWYgKGN3IDw9IDAgfHwgY2ggPD0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IFcgPSBNYXRoLnJvdW5kKGN3ICogZHByKTtcbiAgICAgICAgY29uc3QgSCA9IE1hdGgucm91bmQoY2ggKiBkcHIpO1xuICAgICAgICBpZiAoZWwud2lkdGggIT09IFcgfHwgZWwuaGVpZ2h0ICE9PSBIKSB7XG4gICAgICAgICAgICBlbC53aWR0aCA9IFc7XG4gICAgICAgICAgICBlbC5oZWlnaHQgPSBIO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGN0eCA9IGVsLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgIGlmICghY3R4KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY3R4LnNldFRyYW5zZm9ybShkcHIsIDAsIDAsIGRwciwgMCwgMCk7XG4gICAgICAgIGN0eC5jbGVhclJlY3QoMCwgMCwgY3csIGNoKTtcbiAgICAgICAgY29uc3QgcHRzID0gdGhpcy5wZXJmO1xuICAgICAgICAvLyDnu5jlm77ljLrvvJrlt6blj7PnlZnliLvluqbnqbrpl7TvvIzpobbpg6jnlZkgNO+8jOW6lemDqOeVmSAxNiDmlL4geCDovbTml7bpl7TmoIfnrb5cbiAgICAgICAgY29uc3QgcGxvdCA9IHsgbDogMzYsIHI6IGN3IC0gNDQsIHQ6IDYsIGI6IGNoIC0gMTYgfTtcbiAgICAgICAgY29uc3QgcHcgPSBNYXRoLm1heCgxLCBwbG90LnIgLSBwbG90LmwpO1xuICAgICAgICBjb25zdCBwaCA9IE1hdGgubWF4KDEsIHBsb3QuYiAtIHBsb3QudCk7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gTWF0aC5tYXgoMCwgcHRzLmxlbmd0aCAtIDkwKTtcbiAgICAgICAgY29uc3QgbiA9IHB0cy5sZW5ndGggLSBzdGFydDtcbiAgICAgICAgY29uc3Qgc3RlcFggPSBwdyAvIDkwO1xuICAgICAgICBjb25zdCB4QXQgPSAoaWR4OiBudW1iZXIpID0+IHBsb3QubCArIChpZHggLSBzdGFydCkgKiBzdGVwWDtcbiAgICAgICAgY29uc3QgbWF4RnBzID0gNjA7XG4gICAgICAgIGNvbnN0IG1heERjID0gTWF0aC5tYXgoMjAsIC4uLnB0cy5tYXAoKHA6IHsgZnBzOiBudW1iZXI7IGRjOiBudW1iZXIgfSkgPT4gcC5kYykpICogMS4xO1xuICAgICAgICBjb25zdCBkY01heCA9IE1hdGgubWF4KDIwLCBNYXRoLmNlaWwobWF4RGMgLyAyMCkgKiAyMCk7XG4gICAgICAgIGNvbnN0IHlBdCA9ICh2OiBudW1iZXIsIG1heDogbnVtYmVyKSA9PiBwbG90LmIgLSAoTWF0aC5taW4obWF4LCB2KSAvIG1heCkgKiBwaDtcblxuICAgICAgICAvLyAtLS0tIOe9keagvCArIOW4p+eOh+i9tOWIu+W6pu+8iOW3pu+8jOe7vyAwLzIwLzQwLzYw77yJIC0tLS1cbiAgICAgICAgY3R4LmZvbnQgPSAnMTBweCBzYW5zLXNlcmlmJztcbiAgICAgICAgY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSAncmdiYSgxMjgsMTI4LDEyOCwwLjE4KSc7XG4gICAgICAgIGN0eC5saW5lV2lkdGggPSAxO1xuICAgICAgICBmb3IgKGNvbnN0IHYgb2YgWzAsIDIwLCA0MCwgNjBdKSB7XG4gICAgICAgICAgICBjb25zdCB5ID0gTWF0aC5yb3VuZCh5QXQodiwgbWF4RnBzKSkgKyAwLjU7XG4gICAgICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgICAgICBjdHgubW92ZVRvKHBsb3QubCwgeSk7XG4gICAgICAgICAgICBjdHgubGluZVRvKHBsb3QuciwgeSk7XG4gICAgICAgICAgICBjdHguc3Ryb2tlKCk7XG4gICAgICAgICAgICBjdHguZmlsbFN0eWxlID0gJyM0YWRlODAnO1xuICAgICAgICAgICAgY3R4LnRleHRBbGlnbiA9ICdyaWdodCc7XG4gICAgICAgICAgICBjdHguZmlsbFRleHQoU3RyaW5nKHYpLCBwbG90LmwgLSA0LCB5KTtcbiAgICAgICAgfVxuICAgICAgICAvLyAtLS0tIOe7mOWItuiwg+eUqOi9tOWIu+W6pu+8iOWPs++8jOm7hCAwL21pZC9tYXjvvIkgLS0tLVxuICAgICAgICBmb3IgKGNvbnN0IHYgb2YgWzAsIE1hdGgucm91bmQoZGNNYXggLyAyKSwgZGNNYXhdKSB7XG4gICAgICAgICAgICBjb25zdCB5ID0gTWF0aC5yb3VuZCh5QXQodiwgZGNNYXgpKSArIDAuNTtcbiAgICAgICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgICAgIGN0eC5tb3ZlVG8ocGxvdC5sLCB5KTtcbiAgICAgICAgICAgIGN0eC5saW5lVG8ocGxvdC5yLCB5KTtcbiAgICAgICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSAnI2ZiYmYyNCc7XG4gICAgICAgICAgICBjdHgudGV4dEFsaWduID0gJ2xlZnQnO1xuICAgICAgICAgICAgY3R4LmZpbGxUZXh0KFN0cmluZyh2KSwgcGxvdC5yICsgNCwgeSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gLS0tLSB4IOi9tOaXtumXtOagh+etvu+8iOW6lemDqO+8iSAtLS0tXG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSAnIzg4OCc7XG4gICAgICAgIGN0eC50ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICAgICAgY3R4LmZpbGxUZXh0KCctODBzJywgeEF0KHN0YXJ0KSwgcGxvdC5iICsgOSk7XG4gICAgICAgIGN0eC5maWxsVGV4dCgnLTYwcycsIHhBdChzdGFydCArIDMwKSwgcGxvdC5iICsgOSk7XG4gICAgICAgIGN0eC5maWxsVGV4dCgnLTQwcycsIHhBdChzdGFydCArIDYwKSwgcGxvdC5iICsgOSk7XG4gICAgICAgIGN0eC5maWxsVGV4dCgnLTIwcycsIHhBdChzdGFydCArIDgwKSwgcGxvdC5iICsgOSk7XG4gICAgICAgIGN0eC5maWxsVGV4dCgnMHMnLCBwbG90LnIsIHBsb3QuYiArIDkpO1xuXG4gICAgICAgIGlmIChuIDwgMikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIC0tLS0gQ2F0bXVsbC1Sb20g4oaSIOS4ieasoei0neWhnuWwlOW5s+a7keabsue6vyAtLS0tXG4gICAgICAgIGNvbnN0IGRyYXdTZXJpZXMgPSAoZ2V0OiAocDogeyBmcHM6IG51bWJlcjsgZGM6IG51bWJlciB9KSA9PiBudW1iZXIsIG1heDogbnVtYmVyLCBjb2xvcjogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSBjb2xvcjtcbiAgICAgICAgICAgIGN0eC5saW5lV2lkdGggPSAxLjU7XG4gICAgICAgICAgICBjdHgubGluZUpvaW4gPSAncm91bmQnO1xuICAgICAgICAgICAgY3R4LmxpbmVDYXAgPSAncm91bmQnO1xuICAgICAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICAgICAgY3R4Lm1vdmVUbyh4QXQoc3RhcnQpLCB5QXQoZ2V0KHB0c1tzdGFydF0pLCBtYXgpKTtcbiAgICAgICAgICAgIGlmIChuID09PSAyKSB7XG4gICAgICAgICAgICAgICAgY3R4LmxpbmVUbyh4QXQoc3RhcnQgKyAxKSwgeUF0KGdldChwdHNbc3RhcnQgKyAxXSksIG1heCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBwdHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHAwaSA9IE1hdGgubWF4KHN0YXJ0LCBpIC0gMSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHAyaSA9IGkgKyAxO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwM2kgPSBNYXRoLm1pbihwdHMubGVuZ3RoIC0gMSwgaSArIDIpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjcDF4ID0geEF0KGkpICsgKHhBdChwMmkpIC0geEF0KHAwaSkpIC8gNjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3AxeSA9IHlBdChnZXQocHRzW2ldKSwgbWF4KSArICh5QXQoZ2V0KHB0c1twMmldKSwgbWF4KSAtIHlBdChnZXQocHRzW3AwaV0pLCBtYXgpKSAvIDY7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNwMnggPSB4QXQocDJpKSAtICh4QXQocDNpKSAtIHhBdChpKSkgLyA2O1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjcDJ5ID0geUF0KGdldChwdHNbcDJpXSksIG1heCkgLSAoeUF0KGdldChwdHNbcDNpXSksIG1heCkgLSB5QXQoZ2V0KHB0c1tpXSksIG1heCkpIC8gNjtcbiAgICAgICAgICAgICAgICAgICAgY3R4LmJlemllckN1cnZlVG8oY3AxeCwgY3AxeSwgY3AyeCwgY3AyeSwgeEF0KHAyaSksIHlBdChnZXQocHRzW3AyaV0pLCBtYXgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdHguc3Ryb2tlKCk7XG4gICAgICAgIH07XG4gICAgICAgIGRyYXdTZXJpZXMoKHApID0+IHAuZnBzLCBtYXhGcHMsICcjNGFkZTgwJyk7XG4gICAgICAgIGRyYXdTZXJpZXMoKHApID0+IHAuZGMsIGRjTWF4LCAnI2ZiYmYyNCcpO1xuXG4gICAgICAgIC8vIC0tLS0g5oKs5YGcL+eCueWHu+WzsOWAvO+8muWNgeWtl+e6vyArIOWchueCuSArIOaVsOWAvOaPkOekuuahhiAtLS0tXG4gICAgICAgIGlmICh0aGlzLmhvdmVySWR4ID49IDAgJiYgdGhpcy5ob3ZlcklkeCA+PSBzdGFydCAmJiB0aGlzLmhvdmVySWR4IDwgcHRzLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgcCA9IHB0c1t0aGlzLmhvdmVySWR4XTtcbiAgICAgICAgICAgIGNvbnN0IHggPSB4QXQodGhpcy5ob3ZlcklkeCk7XG4gICAgICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSAncmdiYSgyNTUsMjU1LDI1NSwwLjM1KSc7XG4gICAgICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgICAgICBjdHgubW92ZVRvKE1hdGgucm91bmQoeCkgKyAwLjUsIHBsb3QudCk7XG4gICAgICAgICAgICBjdHgubGluZVRvKE1hdGgucm91bmQoeCkgKyAwLjUsIHBsb3QuYik7XG4gICAgICAgICAgICBjdHguc3Ryb2tlKCk7XG4gICAgICAgICAgICBjb25zdCBob3ZlclNlcmllczogWyhwOiB7IGZwczogbnVtYmVyOyBkYzogbnVtYmVyIH0pID0+IG51bWJlciwgbnVtYmVyLCBzdHJpbmddW10gPSBbXG4gICAgICAgICAgICAgICAgWyhwKSA9PiBwLmZwcywgbWF4RnBzLCAnIzRhZGU4MCddLFxuICAgICAgICAgICAgICAgIFsocCkgPT4gcC5kYywgZGNNYXgsICcjZmJiZjI0J10sXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBbZ2V0LCBtYXgsIGNvbG9yXSBvZiBob3ZlclNlcmllcykge1xuICAgICAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSBjb2xvcjtcbiAgICAgICAgICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgICAgICAgICAgY3R4LmFyYyh4LCB5QXQoZ2V0KHApLCBtYXgpLCAzLCAwLCBNYXRoLlBJICogMik7XG4gICAgICAgICAgICAgICAgY3R4LmZpbGwoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlbCA9IHRoaXMuaG92ZXJJZHggLSAocHRzLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgY29uc3QgbGluZXMgPSBbYCR7cmVsfXNgLCBg5bin546HICR7cC5mcHN9YCwgYOe7mOWItuiwg+eUqCAke3AuZGN9YF07XG4gICAgICAgICAgICBjb25zdCBsaW5lSCA9IDE0O1xuICAgICAgICAgICAgY29uc3QgYm94VyA9IDExODtcbiAgICAgICAgICAgIGNvbnN0IGJveEggPSBsaW5lcy5sZW5ndGggKiBsaW5lSCArIDg7XG4gICAgICAgICAgICBsZXQgYnggPSBwbG90LmwgKyA0O1xuICAgICAgICAgICAgY29uc3QgYnkgPSBwbG90LnQgKyA0O1xuICAgICAgICAgICAgaWYgKHggKyAxNDAgPiBjdykge1xuICAgICAgICAgICAgICAgIGJ4ID0geCAtIGJveFcgLSA4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9ICdyZ2JhKDI1LDI1LDI1LDAuOTIpJztcbiAgICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9ICdyZ2JhKDEyOCwxMjgsMTI4LDAuNSknO1xuICAgICAgICAgICAgY3R4LmZpbGxSZWN0KGJ4LCBieSwgYm94VywgYm94SCk7XG4gICAgICAgICAgICBjdHguc3Ryb2tlUmVjdChieCwgYnksIGJveFcsIGJveEgpO1xuICAgICAgICAgICAgY3R4LnRleHRBbGlnbiA9ICdsZWZ0JztcbiAgICAgICAgICAgIGxpbmVzLmZvckVhY2goKGxuLCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IGkgPT09IDAgPyAnI2FhYScgOiBpID09PSAxID8gJyM0YWRlODAnIDogJyNmYmJmMjQnO1xuICAgICAgICAgICAgICAgIGN0eC5maWxsVGV4dChsbiwgYnggKyA2LCBieSArIDEwICsgaSAqIGxpbmVIKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBvblBlcmZNb3ZlKHRoaXM6IGFueSwgZTogTW91c2VFdmVudCkge1xuICAgICAgICBjb25zdCBlbCA9IHRoaXMuJHJlZnMucGVyZkNhbnZhcyBhcyBIVE1MQ2FudmFzRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKCFlbCB8fCAhdGhpcy5wZXJmLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgY29uc3QgY3cgPSBlbC5jbGllbnRXaWR0aDtcbiAgICAgICAgLy8g5LiOIGRyYXdQZXJmIOS/neaMgeS4gOiHtOeahOe7mOWbvuWMuuaNoueul1xuICAgICAgICBjb25zdCBwbG90TCA9IDM2O1xuICAgICAgICBjb25zdCBwbG90UiA9IGN3IC0gNDQ7XG4gICAgICAgIGNvbnN0IHN0ZXBYID0gTWF0aC5tYXgoMSwgcGxvdFIgLSBwbG90TCkgLyA5MDtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBNYXRoLm1heCgwLCB0aGlzLnBlcmYubGVuZ3RoIC0gOTApO1xuICAgICAgICBjb25zdCBpZHggPSBzdGFydCArIE1hdGgucm91bmQoKGUuY2xpZW50WCAtIHJlY3QubGVmdCAtIHBsb3RMKSAvIHN0ZXBYKTtcbiAgICAgICAgY29uc3QgY2xhbXBlZCA9IE1hdGgubWF4KHN0YXJ0LCBNYXRoLm1pbih0aGlzLnBlcmYubGVuZ3RoIC0gMSwgaWR4KSk7XG4gICAgICAgIGlmIChjbGFtcGVkICE9PSB0aGlzLmhvdmVySWR4KSB7XG4gICAgICAgICAgICB0aGlzLmhvdmVySWR4ID0gY2xhbXBlZDtcbiAgICAgICAgICAgIHRoaXMuZHJhd1BlcmYoKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgb25QZXJmTGVhdmUodGhpczogYW55KSB7XG4gICAgICAgIGlmICh0aGlzLmhvdmVySWR4ICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5ob3ZlcklkeCA9IC0xO1xuICAgICAgICAgICAgdGhpcy5kcmF3UGVyZigpO1xuICAgICAgICB9XG4gICAgfSxcbn07XG4iXX0= \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/dist/panels/default/methods/pickers.js b/extensions/YYKA运行时工作台/dist/panels/default/methods/pickers.js new file mode 100644 index 0000000..7cd8e8d --- /dev/null +++ b/extensions/YYKA运行时工作台/dist/panels/default/methods/pickers.js @@ -0,0 +1,121 @@ +"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")); +/** 节点选择 / 资产选择弹层。 */ +exports.default = { + /** 打开节点选择弹层:mode='ref' 选择组件引用,mode='widget' 选择 Widget 对齐目标。 */ + openNodePicker(mode, compIdx, key, componentType) { + this.nodePicker = { + visible: true, + mode, + compIdx, + key, + componentType: componentType || 'cc.Node', + filter: '', + }; + }, + closeNodePicker() { + this.nodePicker.visible = false; + }, + /** 弹层选中运行时节点:ref 写组件引用,widget 写对齐目标。 */ + onNodePick(row) { + if (!this.inspector) { + return; + } + const comp = this.inspector.components[this.nodePicker.compIdx]; + if (!comp) { + this.nodePicker.visible = false; + return; + } + if (this.nodePicker.mode === 'ref') { + this.sendSet({ + id: this.selectedId, + comp: this.nodePicker.compIdx, + key: this.nodePicker.key, + value: { __refNode: row.id, componentType: this.nodePicker.componentType }, + }); + const prop = comp.props.find((p) => p.key === this.nodePicker.key); + if (prop && prop.v && typeof prop.v === 'object') { + prop.v = Object.assign(Object.assign({}, prop.v), { name: row.name }); + } + } + else { + this.sendSet({ id: this.selectedId, comp: this.nodePicker.compIdx, key: '__widget_target', value: row.id }); + if (comp.widget) { + comp.widget.targetName = row.name; + } + } + this.nodePicker.visible = false; + }, + /** 打开资产选择弹层:index>=0 时写回数组项(如 sharedMaterials[i])。 */ + async openAssetPicker(compIdx, key, index, curType) { + this.assetPicker = { + visible: true, + compIdx, + key, + index, + filter: '', + type: curType || '', + types: [], + list: [], + loading: true, + }; + try { + const res = (await Editor.Message.request(package_json_1.default.name, 'query-command', { cmd: 'list-assets', timeout: 2500, payload: { type: curType || '' } })); + if (res && Array.isArray(res.assets)) { + this.assetPicker.list = res.assets; + this.assetPicker.types = res.types || []; + } + else { + this.logs.push('[资产] ' + String((res && res.error) || '获取资产列表失败')); + } + } + catch (err) { + this.logs.push(`[资产] ${String(err)}`); + } + finally { + this.assetPicker.loading = false; + } + }, + closeAssetPicker() { + this.assetPicker.visible = false; + }, + /** 弹层选中资产:按 uuid 写回资产引用(属性或数组项)。 */ + async onAssetPick(row) { + if (!this.inspector) { + return; + } + const ap = this.assetPicker; + const comp = this.inspector.components[ap.compIdx]; + if (!comp) { + this.closeAssetPicker(); + return; + } + this.sendSet({ + id: this.selectedId, + comp: ap.compIdx, + key: ap.key, + index: ap.index >= 0 ? ap.index : undefined, + value: { __refAsset: row.uuid }, + }); + // 本地乐观更新:写回后 sendSet 会回读刷新,这里仅即时反馈 + const prop = comp.props.find((p) => p.key === ap.key); + if (prop && prop.v && typeof prop.v === 'object') { + if (ap.index >= 0 && Array.isArray(prop.v)) { + const it = prop.v[ap.index]; + if (it && it.v && typeof it.v === 'object') { + it.v = Object.assign(Object.assign({}, it.v), { name: row.name, type: row.type, uuid: row.uuid }); + } + } + else if (prop.v && typeof prop.v === 'object') { + prop.v = Object.assign(Object.assign({}, prop.v), { name: row.name, type: row.type, uuid: row.uuid }); + } + } + this.closeAssetPicker(); + }, +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGlja2Vycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NvdXJjZS9wYW5lbHMvZGVmYXVsdC9tZXRob2RzL3BpY2tlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxhQUFhO0FBQ2IsNEVBQW1EO0FBR25ELHFCQUFxQjtBQUNyQixrQkFBZTtJQUNYLCtEQUErRDtJQUMvRCxjQUFjLENBQVksSUFBc0IsRUFBRSxPQUFlLEVBQUUsR0FBVyxFQUFFLGFBQXFCO1FBQ2pHLElBQUksQ0FBQyxVQUFVLEdBQUc7WUFDZCxPQUFPLEVBQUUsSUFBSTtZQUNiLElBQUk7WUFDSixPQUFPO1lBQ1AsR0FBRztZQUNILGFBQWEsRUFBRSxhQUFhLElBQUksU0FBUztZQUN6QyxNQUFNLEVBQUUsRUFBRTtTQUNiLENBQUM7SUFDTixDQUFDO0lBQ0QsZUFBZTtRQUNYLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUNwQyxDQUFDO0lBQ0Qsd0NBQXdDO0lBQ3hDLFVBQVUsQ0FBWSxHQUFZO1FBQzlCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbEIsT0FBTztRQUNYLENBQUM7UUFDRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNSLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztZQUNoQyxPQUFPO1FBQ1gsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLE9BQU8sQ0FBQztnQkFDVCxFQUFFLEVBQUUsSUFBSSxDQUFDLFVBQVU7Z0JBQ25CLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU87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O1lBQy9DLElBQUksRUFBRSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDekMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzVCLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksT0FBTyxFQUFFLENBQUMsQ0FBQyxLQUFLLFFBQVEsRUFBRSxDQUFDO29CQUN6QyxFQUFFLENBQUMsQ0FBQyxtQ0FBUSxFQUFFLENBQUMsQ0FBQyxLQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxHQUFFLENBQUM7Z0JBQ3ZFLENBQUM7WUFDTCxDQUFDO2lCQUFNLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxPQUFPLElBQUksQ0FBQyxDQUFDLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQzlDLElBQUksQ0FBQyxDQUFDLG1DQUFRLElBQUksQ0FBQyxDQUFDLEtBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEdBQUUsQ0FBQztZQUMzRSxDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7Q0FDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWlnbm9yZVxuaW1wb3J0IHBhY2thZ2VKU09OIGZyb20gJy4uLy4uLy4uLy4uL3BhY2thZ2UuanNvbic7XG5pbXBvcnQgdHlwZSB7IFRyZWVSb3cgfSBmcm9tICcuLi90eXBlcyc7XG5cbi8qKiDoioLngrnpgInmi6kgLyDotYTkuqfpgInmi6nlvLnlsYLjgIIgKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICAvKiog5omT5byA6IqC54K56YCJ5oup5by55bGC77yabW9kZT0ncmVmJyDpgInmi6nnu4Tku7blvJXnlKjvvIxtb2RlPSd3aWRnZXQnIOmAieaLqSBXaWRnZXQg5a+56b2Q55uu5qCH44CCICovXG4gICAgb3Blbk5vZGVQaWNrZXIodGhpczogYW55LCBtb2RlOiAncmVmJyB8ICd3aWRnZXQnLCBjb21wSWR4OiBudW1iZXIsIGtleTogc3RyaW5nLCBjb21wb25lbnRUeXBlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5ub2RlUGlja2VyID0ge1xuICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIG1vZGUsXG4gICAgICAgICAgICBjb21wSWR4LFxuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgY29tcG9uZW50VHlwZTogY29tcG9uZW50VHlwZSB8fCAnY2MuTm9kZScsXG4gICAgICAgICAgICBmaWx0ZXI6ICcnLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgY2xvc2VOb2RlUGlja2VyKHRoaXM6IGFueSkge1xuICAgICAgICB0aGlzLm5vZGVQaWNrZXIudmlzaWJsZSA9IGZhbHNlO1xuICAgIH0sXG4gICAgLyoqIOW8ueWxgumAieS4rei/kOihjOaXtuiKgueCue+8mnJlZiDlhpnnu4Tku7blvJXnlKjvvIx3aWRnZXQg5YaZ5a+56b2Q55uu5qCH44CCICovXG4gICAgb25Ob2RlUGljayh0aGlzOiBhbnksIHJvdzogVHJlZVJvdykge1xuICAgICAgICBpZiAoIXRoaXMuaW5zcGVjdG9yKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29tcCA9IHRoaXMuaW5zcGVjdG9yLmNvbXBvbmVudHNbdGhpcy5ub2RlUGlja2VyLmNvbXBJZHhdO1xuICAgICAgICBpZiAoIWNvbXApIHtcbiAgICAgICAgICAgIHRoaXMubm9kZVBpY2tlci52aXNpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubm9kZVBpY2tlci5tb2RlID09PSAncmVmJykge1xuICAgICAgICAgICAgdGhpcy5zZW5kU2V0KHtcbiAgICAgICAgICAgICAgICBpZDogdGhpcy5zZWxlY3RlZElkLFxuICAgICAgICAgICAgICAgIGNvbXA6IHRoaXMubm9kZVBpY2tlci5jb21wSWR4LFxuICAgICAgICAgICAgICAgIGtleTogdGhpcy5ub2RlUGlja2VyLmtleSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogeyBfX3JlZk5vZGU6IHJvdy5pZCwgY29tcG9uZW50VHlwZTogdGhpcy5ub2RlUGlja2VyLmNvbXBvbmVudFR5cGUgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgcHJvcCA9IGNvbXAucHJvcHMuZmluZCgocDogYW55KSA9PiBwLmtleSA9PT0gdGhpcy5ub2RlUGlja2VyLmtleSk7XG4gICAgICAgICAgICBpZiAocHJvcCAmJiBwcm9wLnYgJiYgdHlwZW9mIHByb3AudiA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICBwcm9wLnYgPSB7IC4uLnByb3AudiwgbmFtZTogcm93Lm5hbWUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2VuZFNldCh7IGlkOiB0aGlzLnNlbGVjdGVkSWQsIGNvbXA6IHRoaXMubm9kZVBpY2tlci5jb21wSWR4LCBrZXk6ICdfX3dpZGdldF90YXJnZXQnLCB2YWx1ZTogcm93LmlkIH0pO1xuICAgICAgICAgICAgaWYgKGNvbXAud2lkZ2V0KSB7XG4gICAgICAgICAgICAgICAgY29tcC53aWRnZXQudGFyZ2V0TmFtZSA9IHJvdy5uYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMubm9kZVBpY2tlci52aXNpYmxlID0gZmFsc2U7XG4gICAgfSxcbiAgICAvKiog5omT5byA6LWE5Lqn6YCJ5oup5by55bGC77yaaW5kZXg+PTAg5pe25YaZ5Zue5pWw57uE6aG577yI5aaCIHNoYXJlZE1hdGVyaWFsc1tpXe+8ieOAgiAqL1xuICAgIGFzeW5jIG9wZW5Bc3NldFBpY2tlcih0aGlzOiBhbnksIGNvbXBJZHg6IG51bWJlciwga2V5OiBzdHJpbmcsIGluZGV4OiBudW1iZXIsIGN1clR5cGU6IHN0cmluZykge1xuICAgICAgICB0aGlzLmFzc2V0UGlja2VyID0ge1xuICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNvbXBJZHgsXG4gICAgICAgICAgICBrZXksXG4gICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgIGZpbHRlcjogJycsXG4gICAgICAgICAgICB0eXBlOiBjdXJUeXBlIHx8ICcnLFxuICAgICAgICAgICAgdHlwZXM6IFtdLFxuICAgICAgICAgICAgbGlzdDogW10sXG4gICAgICAgICAgICBsb2FkaW5nOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzID0gKGF3YWl0IEVkaXRvci5NZXNzYWdlLnJlcXVlc3QoXG4gICAgICAgICAgICAgICAgcGFja2FnZUpTT04ubmFtZSBhcyBhbnksXG4gICAgICAgICAgICAgICAgJ3F1ZXJ5LWNvbW1hbmQnIGFzIGFueSxcbiAgICAgICAgICAgICAgICB7IGNtZDogJ2xpc3QtYXNzZXRzJywgdGltZW91dDogMjUwMCwgcGF5bG9hZDogeyB0eXBlOiBjdXJUeXBlIHx8ICcnIH0gfSBhcyBhbnksXG4gICAgICAgICAgICApKSBhcyBhbnk7XG4gICAgICAgICAgICBpZiAocmVzICYmIEFycmF5LmlzQXJyYXkocmVzLmFzc2V0cykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFzc2V0UGlja2VyLmxpc3QgPSByZXMuYXNzZXRzO1xuICAgICAgICAgICAgICAgIHRoaXMuYXNzZXRQaWNrZXIudHlwZXMgPSByZXMudHlwZXMgfHwgW107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubG9ncy5wdXNoKCdb6LWE5LqnXSAnICsgU3RyaW5nKChyZXMgJiYgcmVzLmVycm9yKSB8fCAn6I635Y+W6LWE5Lqn5YiX6KGo5aSx6LSlJykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMubG9ncy5wdXNoKGBb6LWE5LqnXSAke1N0cmluZyhlcnIpfWApO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5hc3NldFBpY2tlci5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGNsb3NlQXNzZXRQaWNrZXIodGhpczogYW55KSB7XG4gICAgICAgIHRoaXMuYXNzZXRQaWNrZXIudmlzaWJsZSA9IGZhbHNlO1xuICAgIH0sXG4gICAgLyoqIOW8ueWxgumAieS4rei1hOS6p++8muaMiSB1dWlkIOWGmeWbnui1hOS6p+W8leeUqO+8iOWxnuaAp+aIluaVsOe7hOmhue+8ieOAgiAqL1xuICAgIGFzeW5jIG9uQXNzZXRQaWNrKHRoaXM6IGFueSwgcm93OiB7IG5hbWU6IHN0cmluZzsgdXVpZDogc3RyaW5nOyB0eXBlOiBzdHJpbmcgfSkge1xuICAgICAgICBpZiAoIXRoaXMuaW5zcGVjdG9yKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXAgPSB0aGlzLmFzc2V0UGlja2VyO1xuICAgICAgICBjb25zdCBjb21wID0gdGhpcy5pbnNwZWN0b3IuY29tcG9uZW50c1thcC5jb21wSWR4XTtcbiAgICAgICAgaWYgKCFjb21wKSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlQXNzZXRQaWNrZXIoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbmRTZXQoe1xuICAgICAgICAgICAgaWQ6IHRoaXMuc2VsZWN0ZWRJZCxcbiAgICAgICAgICAgIGNvbXA6IGFwLmNvbXBJZHgsXG4gICAgICAgICAgICBrZXk6IGFwLmtleSxcbiAgICAgICAgICAgIGluZGV4OiBhcC5pbmRleCA+PSAwID8gYXAuaW5kZXggOiB1bmRlZmluZWQsXG4gICAgICAgICAgICB2YWx1ZTogeyBfX3JlZkFzc2V0OiByb3cudXVpZCB9LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8g5pys5Zyw5LmQ6KeC5pu05paw77ya5YaZ5Zue5ZCOIHNlbmRTZXQg5Lya5Zue6K+75Yi35paw77yM6L+Z6YeM5LuF5Y2z5pe25Y+N6aaIXG4gICAgICAgIGNvbnN0IHByb3AgPSBjb21wLnByb3BzLmZpbmQoKHA6IGFueSkgPT4gcC5rZXkgPT09IGFwLmtleSk7XG4gICAgICAgIGlmIChwcm9wICYmIHByb3AudiAmJiB0eXBlb2YgcHJvcC52ID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgaWYgKGFwLmluZGV4ID49IDAgJiYgQXJyYXkuaXNBcnJheShwcm9wLnYpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaXQgPSBwcm9wLnZbYXAuaW5kZXhdO1xuICAgICAgICAgICAgICAgIGlmIChpdCAmJiBpdC52ICYmIHR5cGVvZiBpdC52ID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBpdC52ID0geyAuLi5pdC52LCBuYW1lOiByb3cubmFtZSwgdHlwZTogcm93LnR5cGUsIHV1aWQ6IHJvdy51dWlkIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChwcm9wLnYgJiYgdHlwZW9mIHByb3AudiA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICBwcm9wLnYgPSB7IC4uLnByb3AudiwgbmFtZTogcm93Lm5hbWUsIHR5cGU6IHJvdy50eXBlLCB1dWlkOiByb3cudXVpZCB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2xvc2VBc3NldFBpY2tlcigpO1xuICAgIH0sXG59O1xuIl19 \ No newline at end of file diff --git a/extensions/YYKA运行时工作台/dist/panels/default/methods/preview.js b/extensions/YYKA运行时工作台/dist/panels/default/methods/preview.js new file mode 100644 index 0000000..71eb3a1 --- /dev/null +++ b/extensions/YYKA运行时工作台/dist/panels/default/methods/preview.js @@ -0,0 +1,1658 @@ +"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. 按序加载引擎脚本(