You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
20 KiB
152 lines
20 KiB
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.WsServer = void 0;
|
|
const events_1 = require("events");
|
|
const ws_1 = require("ws");
|
|
function parseClientInfo(url) {
|
|
const m = /[?&]client=([^&]*)/.exec(url !== null && url !== void 0 ? url : '');
|
|
const type = m ? decodeURIComponent(m[1]) : 'unknown';
|
|
const id = `${type}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 7)}`;
|
|
return { id, type };
|
|
}
|
|
/**
|
|
* 主进程内嵌的 WebSocket 服务。
|
|
* 游戏侧注入的桥接脚本作为客户端连上来,面板/主进程通过该服务与之通信。
|
|
* 单客户端模型:同一时刻只保留最新连接,新连接会顶替旧连接(旧连接收到 4002 关闭码)。
|
|
*/
|
|
class WsServer extends events_1.EventEmitter {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.srv = null;
|
|
this.port = 0;
|
|
this._token = '';
|
|
this.active = null;
|
|
this.activeInfo = null;
|
|
}
|
|
get isRunning() {
|
|
return !!this.srv;
|
|
}
|
|
get boundPort() {
|
|
return this.port;
|
|
}
|
|
/** 当前活跃客户端数量(0 或 1)。 */
|
|
get clients() {
|
|
return this.active && this.active.readyState === ws_1.WebSocket.OPEN ? 1 : 0;
|
|
}
|
|
/** 当前活跃客户端信息(未连接时为 null)。 */
|
|
get clientInfo() {
|
|
return this.active && this.active.readyState === ws_1.WebSocket.OPEN ? this.activeInfo : null;
|
|
}
|
|
/** 连接令牌:非空时仅放行携带相同 token 的客户端。 */
|
|
get token() {
|
|
return this._token;
|
|
}
|
|
set token(v) {
|
|
this._token = v;
|
|
}
|
|
/** 启动监听,返回实际绑定端口(若端口被占用则抛错)。 */
|
|
start(port) {
|
|
return new Promise((resolve, reject) => {
|
|
if (this.srv) {
|
|
resolve(this.port);
|
|
return;
|
|
}
|
|
this.port = port;
|
|
const srv = new ws_1.WebSocketServer({ port });
|
|
srv.on('error', (err) => reject(err));
|
|
srv.on('listening', () => {
|
|
this.emit('listening');
|
|
});
|
|
srv.on('connection', (ws, req) => {
|
|
// 注意:ws 库服务端连接对象的 ws.url 为 undefined,必须从握手请求 req.url
|
|
// 取路径+query(如 /?token=xxx&client=h5),否则 client 类型解析不到。
|
|
const reqUrl = (req && req.url) || ws.url || '';
|
|
// 连接鉴权:设置了 token 时,校验 URL query 中的 token
|
|
if (this._token) {
|
|
const m = /[?&]token=([^&]*)/.exec(reqUrl);
|
|
const got = m ? decodeURIComponent(m[1]) : '';
|
|
if (got !== this._token) {
|
|
// 供主进程记录日志:客户端带什么 token,服务端期望什么 token,一目了然
|
|
this.emit('auth-fail', got || '(无token)', reqUrl);
|
|
ws.close(4001, 'token mismatch');
|
|
return;
|
|
}
|
|
}
|
|
// 单客户端:顶替旧连接(4002 = 被新连接替换),避免多实例数据混流
|
|
if (this.active && this.active.readyState === ws_1.WebSocket.OPEN) {
|
|
const old = this.active;
|
|
const oldInfo = this.activeInfo;
|
|
this.active = null;
|
|
this.activeInfo = null;
|
|
try {
|
|
old.close(4002, 'replaced by new client');
|
|
}
|
|
catch (_a) {
|
|
/* ignore */
|
|
}
|
|
this.emit('disconnect', old, oldInfo);
|
|
}
|
|
const { id, type } = parseClientInfo(reqUrl);
|
|
this.active = ws;
|
|
this.activeInfo = { id, type, url: reqUrl, connectedAt: Date.now() };
|
|
this.emit('connection', ws, this.activeInfo);
|
|
ws.on('message', (raw) => {
|
|
let data = raw;
|
|
try {
|
|
data = JSON.parse(raw.toString());
|
|
}
|
|
catch (_a) {
|
|
/* 非 JSON,原样保留 */
|
|
}
|
|
this.emit('message', ws, data);
|
|
});
|
|
ws.on('close', () => {
|
|
if (this.active === ws) {
|
|
this.active = null;
|
|
this.activeInfo = null;
|
|
}
|
|
this.emit('disconnect', ws, this.activeInfo);
|
|
});
|
|
ws.on('error', (err) => this.emit('client-error', ws, err));
|
|
});
|
|
this.srv = srv;
|
|
resolve(this.port);
|
|
});
|
|
}
|
|
stop() {
|
|
return new Promise((resolve) => {
|
|
if (!this.srv) {
|
|
resolve();
|
|
return;
|
|
}
|
|
const srv = this.srv;
|
|
for (const c of srv.clients) {
|
|
try {
|
|
c.close();
|
|
}
|
|
catch (_a) {
|
|
/* ignore */
|
|
}
|
|
}
|
|
this.srv = null;
|
|
this.active = null;
|
|
this.activeInfo = null;
|
|
this.port = 0;
|
|
srv.close(() => resolve());
|
|
});
|
|
}
|
|
/** 向当前活跃客户端发送一条 JSON 消息。 */
|
|
broadcast(obj) {
|
|
if (!this.srv || !this.active || this.active.readyState !== ws_1.WebSocket.OPEN) {
|
|
return;
|
|
}
|
|
try {
|
|
this.active.send(JSON.stringify(obj));
|
|
}
|
|
catch (_a) {
|
|
/* ignore */
|
|
}
|
|
}
|
|
}
|
|
exports.WsServer = WsServer;
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3Mtc2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc291cmNlL3dzLXNlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBc0M7QUFDdEMsMkJBQWdEO0FBVWhELFNBQVMsZUFBZSxDQUFDLEdBQVc7SUFDaEMsTUFBTSxDQUFDLEdBQUcsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEdBQUcsYUFBSCxHQUFHLGNBQUgsR0FBRyxHQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUN0RCxNQUFNLEVBQUUsR0FBRyxHQUFHLElBQUksSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQzFGLE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDeEIsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFhLFFBQVMsU0FBUSxxQkFBWTtJQUExQzs7UUFDWSxRQUFHLEdBQTJCLElBQUksQ0FBQztRQUNuQyxTQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ1QsV0FBTSxHQUFHLEVBQUUsQ0FBQztRQUNaLFdBQU0sR0FBcUIsSUFBSSxDQUFDO1FBQ2hDLGVBQVUsR0FBd0IsSUFBSSxDQUFDO0lBa0luRCxDQUFDO0lBaElHLElBQUksU0FBUztRQUNULE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDdEIsQ0FBQztJQUVELElBQUksU0FBUztRQUNULE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQztJQUNyQixDQUFDO0lBRUQs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QUcsQ0FBQyxDQUFDO1lBQ2QsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQy9CLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELDRCQUE0QjtJQUM1QixTQUFTLENBQUMsR0FBWTtRQUNsQixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEtBQUssY0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3pFLE9BQU87UUFDWCxDQUFDO1FBQ0QsSUFBSSxDQUFDO1lBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzFDLENBQUM7UUFBQyxXQUFNLENBQUM7WUFDTCxZQUFZO1FBQ2hCLENBQUM7SUFDTCxDQUFDO0NBQ0o7QUF2SUQsNEJBdUlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRzJztcbmltcG9ydCB7IFdlYlNvY2tldFNlcnZlciwgV2ViU29ja2V0IH0gZnJvbSAnd3MnO1xuXG4vKiog5b2T5YmN5rS76LeD5a6i5oi356uv5YWD5L+h5oGv44CCICovXG5leHBvcnQgaW50ZXJmYWNlIFdzQ2xpZW50SW5mbyB7XG4gICAgaWQ6IHN0cmluZztcbiAgICB0eXBlOiBzdHJpbmc7XG4gICAgdXJsOiBzdHJpbmc7XG4gICAgY29ubmVjdGVkQXQ6IG51bWJlcjtcbn1cblxuZnVuY3Rpb24gcGFyc2VDbGllbnRJbmZvKHVybDogc3RyaW5nKTogeyBpZDogc3RyaW5nOyB0eXBlOiBzdHJpbmcgfSB7XG4gICAgY29uc3QgbSA9IC9bPyZdY2xpZW50PShbXiZdKikvLmV4ZWModXJsID8/ICcnKTtcbiAgICBjb25zdCB0eXBlID0gbSA/IGRlY29kZVVSSUNvbXBvbmVudChtWzFdKSA6ICd1bmtub3duJztcbiAgICBjb25zdCBpZCA9IGAke3R5cGV9LSR7RGF0ZS5ub3coKS50b1N0cmluZygzNil9LSR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgNyl9YDtcbiAgICByZXR1cm4geyBpZCwgdHlwZSB9O1xufVxuXG4vKipcbiAqIOS4u+i/m+eoi+WGheW1jOeahCBXZWJTb2NrZXQg5pyN5Yqh44CCXG4gKiDmuLjmiI/kvqfms6jlhaXnmoTmoaXmjqXohJrmnKzkvZzkuLrlrqLmiLfnq6/ov57kuIrmnaXvvIzpnaLmnb8v5Li76L+b56iL6YCa6L+H6K+l5pyN5Yqh5LiO5LmL6YCa5L+h44CCXG4gKiDljZXlrqLmiLfnq6/mqKHlnovvvJrlkIzkuIDml7bliLvlj6rkv53nlZnmnIDmlrDov57mjqXvvIzmlrDov57mjqXkvJrpobbmm7/ml6fov57mjqXvvIjml6fov57mjqXmlLbliLAgNDAwMiDlhbPpl63noIHvvInjgIJcbiAqL1xuZXhwb3J0IGNsYXNzIFdzU2VydmVyIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcbiAgICBwcml2YXRlIHNydjogV2ViU29ja2V0U2VydmVyIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBwb3J0ID0gMDtcbiAgICBwcml2YXRlIF90b2tlbiA9ICcnO1xuICAgIHByaXZhdGUgYWN0aXZlOiBXZWJTb2NrZXQgfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIGFjdGl2ZUluZm86IFdzQ2xpZW50SW5mbyB8IG51bGwgPSBudWxsO1xuXG4gICAgZ2V0IGlzUnVubmluZygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5zcnY7XG4gICAgfVxuXG4gICAgZ2V0IGJvdW5kUG9ydCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5wb3J0O1xuICAgIH1cblxuICAgIC8qKiDlvZPliY3mtLvot4PlrqLmiLfnq6/mlbDph4/vvIgwIOaIliAx77yJ44CCICovXG4gICAgZ2V0IGNsaWVudHMoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZlICYmIHRoaXMuYWN0aXZlLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOID8gMSA6IDA7XG4gICAgfVxuXG4gICAgLyoqIOW9k+WJjea0u+i3g+WuouaIt+err+S/oeaBr++8iOacqui/nuaOpeaXtuS4uiBudWxs77yJ44CCICovXG4gICAgZ2V0IGNsaWVudEluZm8oKTogV3NDbGllbnRJbmZvIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLmFjdGl2ZSAmJiB0aGlzLmFjdGl2ZS5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTiA/IHRoaXMuYWN0aXZlSW5mbyA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqIOi/nuaOpeS7pOeJjO+8mumdnuepuuaXtuS7heaUvuihjOaQuuW4puebuOWQjCB0b2tlbiDnmoTlrqLmiLfnq6/jgIIgKi9cbiAgICBnZXQgdG9rZW4oKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rva2VuO1xuICAgIH1cblxuICAgIHNldCB0b2tlbih2OiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5fdG9rZW4gPSB2O1xuICAgIH1cblxuICAgIC8qKiDlkK/liqjnm5HlkKzvvIzov5Tlm57lrp7pmYXnu5Hlrprnq6/lj6PvvIjoi6Xnq6/lj6PooqvljaDnlKjliJnmipvplJnvvInjgIIgKi9cbiAgICBzdGFydChwb3J0OiBudW1iZXIpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3J2KSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh0aGlzLnBvcnQpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucG9ydCA9IHBvcnQ7XG4gICAgICAgICAgICBjb25zdCBzcnYgPSBuZXcgV2ViU29ja2V0U2VydmVyKHsgcG9ydCB9KTtcbiAgICAgICAgICAgIHNydi5vbignZXJyb3InLCAoZXJyOiBFcnJvcikgPT4gcmVqZWN0KGVycikpO1xuICAgICAgICAgICAgc3J2Lm9uKCdsaXN0ZW5pbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdsaXN0ZW5pbmcnKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3J2Lm9uKCdjb25uZWN0aW9uJywgKHdzOiBXZWJTb2NrZXQsIHJlcSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIOazqOaEj++8mndzIOW6k+acjeWKoeerr+i/nuaOpeWvueixoeeahCB3cy51cmwg5Li6IHVuZGVmaW5lZO+8jOW/hemhu+S7juaPoeaJi+ivt+axgiByZXEudXJsXG4gICAgICAgICAgICAgICAgLy8g5Y+W6Lev5b6EK3F1ZXJ577yI5aaCIC8/dG9rZW49eHh4JmNsaWVudD1oNe+8ie+8jOWQpuWImSBjbGllbnQg57G75Z6L6Kej5p6Q5LiN5Yiw44CCXG4gICAgICAgICAgICAgICAgY29uc3QgcmVxVXJsID0gKHJlcSAmJiAocmVxIGFzIGFueSkudXJsKSB8fCAod3MgYXMgYW55KS51cmwgfHwgJyc7XG4gICAgICAgICAgICAgICAgLy8g6L+e5o6l6Ym05p2D77ya6K6+572u5LqGIHRva2VuIOaXtu+8jOagoemqjCBVUkwgcXVlcnkg5Lit55qEIHRva2VuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3Rva2VuKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG0gPSAvWz8mXXRva2VuPShbXiZdKikvLmV4ZWMocmVxVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ290ID0gbSA/IGRlY29kZVVSSUNvbXBvbmVudChtWzFdKSA6ICcnO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZ290ICE9PSB0aGlzLl90b2tlbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g5L6b5Li76L+b56iL6K6w5b2V5pel5b+X77ya5a6i5oi356uv5bim5LuA5LmIIHRva2Vu77yM5pyN5Yqh56uv5pyf5pyb5LuA5LmIIHRva2Vu77yM5LiA55uu5LqG54S2XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2F1dGgtZmFpbCcsIGdvdCB8fCAnKOaXoHRva2VuKScsIHJlcVVybCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB3cy5jbG9zZSg0MDAxLCAndG9rZW4gbWlzbWF0Y2gnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyDljZXlrqLmiLfnq6/vvJrpobbmm7/ml6fov57mjqXvvIg0MDAyID0g6KKr5paw6L+e5o6l5pu/5o2i77yJ77yM6YG/5YWN5aSa5a6e5L6L5pWw5o2u5re35rWBXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuYWN0aXZlICYmIHRoaXMuYWN0aXZlLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9sZCA9IHRoaXMuYWN0aXZlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRJbmZvID0gdGhpcy5hY3RpdmVJbmZvO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlSW5mbyA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGQuY2xvc2UoNDAwMiwgJ3JlcGxhY2VkIGJ5IG5ldyBjbGllbnQnKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBpZ25vcmUgKi9cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2Rpc2Nvbm5lY3QnLCBvbGQsIG9sZEluZm8pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCB7IGlkLCB0eXBlIH0gPSBwYXJzZUNsaWVudEluZm8ocmVxVXJsKTtcbiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZSA9IHdzO1xuICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlSW5mbyA9IHsgaWQsIHR5cGUsIHVybDogcmVxVXJsLCBjb25uZWN0ZWRBdDogRGF0ZS5ub3coKSB9O1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgnY29ubmVjdGlvbicsIHdzLCB0aGlzLmFjdGl2ZUluZm8pO1xuICAgICAgICAgICAgICAgIHdzLm9uKCdtZXNzYWdlJywgKHJhdykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgZGF0YTogdW5rbm93biA9IHJhdztcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBKU09OLnBhcnNlKHJhdy50b1N0cmluZygpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvKiDpnZ4gSlNPTu+8jOWOn+agt+S/neeVmSAqL1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIHdzLCBkYXRhKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB3cy5vbignY2xvc2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmFjdGl2ZSA9PT0gd3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlSW5mbyA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdkaXNjb25uZWN0Jywgd3MsIHRoaXMuYWN0aXZlSW5mbyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgd3Mub24oJ2Vycm9yJywgKGVycikgPT4gdGhpcy5lbWl0KCdjbGllbnQtZXJyb3InLCB3cywgZXJyKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuc3J2ID0gc3J2O1xuICAgICAgICAgICAgcmVzb2x2ZSh0aGlzLnBvcnQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zcnYpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc3J2ID0gdGhpcy5zcnY7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGMgb2Ygc3J2LmNsaWVudHMpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjLmNsb3NlKCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgIC8qIGlnbm9yZSAqL1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3J2ID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlSW5mbyA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnBvcnQgPSAwO1xuICAgICAgICAgICAgc3J2LmNsb3NlKCgpID0+IHJlc29sdmUoKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKiDlkJHlvZPliY3mtLvot4PlrqLmiLfnq6/lj5HpgIHkuIDmnaEgSlNPTiDmtojmga/jgIIgKi9cbiAgICBicm9hZGNhc3Qob2JqOiB1bmtub3duKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5zcnYgfHwgIXRoaXMuYWN0aXZlIHx8IHRoaXMuYWN0aXZlLnJlYWR5U3RhdGUgIT09IFdlYlNvY2tldC5PUEVOKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlLnNlbmQoSlNPTi5zdHJpbmdpZnkob2JqKSk7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLyogaWdub3JlICovXG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=
|