217 lines
32 KiB
JavaScript
217 lines
32 KiB
JavaScript
"use strict";
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
exports.MCPToolTester = void 0;
|
||
/**
|
||
* MCP 工具测试器 - 直接测试通过 WebSocket 的 MCP 工具
|
||
*/
|
||
class MCPToolTester {
|
||
constructor() {
|
||
this.ws = null;
|
||
this.messageId = 0;
|
||
this.responseHandlers = new Map();
|
||
}
|
||
async connect(port) {
|
||
return new Promise((resolve) => {
|
||
try {
|
||
this.ws = new WebSocket(`ws://localhost:${port}`);
|
||
this.ws.onopen = () => {
|
||
console.log('WebSocket 连接成功');
|
||
resolve(true);
|
||
};
|
||
this.ws.onerror = (error) => {
|
||
console.error('WebSocket 连接错误:', error);
|
||
resolve(false);
|
||
};
|
||
this.ws.onmessage = (event) => {
|
||
try {
|
||
const response = JSON.parse(event.data);
|
||
if (response.id && this.responseHandlers.has(response.id)) {
|
||
const handler = this.responseHandlers.get(response.id);
|
||
this.responseHandlers.delete(response.id);
|
||
handler === null || handler === void 0 ? void 0 : handler(response);
|
||
}
|
||
}
|
||
catch (error) {
|
||
console.error('处理响应时出错:', error);
|
||
}
|
||
};
|
||
}
|
||
catch (error) {
|
||
console.error('创建 WebSocket 时出错:', error);
|
||
resolve(false);
|
||
}
|
||
});
|
||
}
|
||
async callTool(tool, args = {}) {
|
||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
||
throw new Error('WebSocket 未连接');
|
||
}
|
||
return new Promise((resolve, reject) => {
|
||
const id = ++this.messageId;
|
||
const request = {
|
||
jsonrpc: '2.0',
|
||
id,
|
||
method: 'tools/call',
|
||
params: {
|
||
name: tool,
|
||
arguments: args
|
||
}
|
||
};
|
||
const timeout = setTimeout(() => {
|
||
this.responseHandlers.delete(id);
|
||
reject(new Error('请求超时'));
|
||
}, 10000);
|
||
this.responseHandlers.set(id, (response) => {
|
||
clearTimeout(timeout);
|
||
if (response.error) {
|
||
reject(new Error(response.error.message));
|
||
}
|
||
else {
|
||
resolve(response.result);
|
||
}
|
||
});
|
||
this.ws.send(JSON.stringify(request));
|
||
});
|
||
}
|
||
async listTools() {
|
||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
||
throw new Error('WebSocket 未连接');
|
||
}
|
||
return new Promise((resolve, reject) => {
|
||
const id = ++this.messageId;
|
||
const request = {
|
||
jsonrpc: '2.0',
|
||
id,
|
||
method: 'tools/list'
|
||
};
|
||
const timeout = setTimeout(() => {
|
||
this.responseHandlers.delete(id);
|
||
reject(new Error('请求超时'));
|
||
}, 10000);
|
||
this.responseHandlers.set(id, (response) => {
|
||
clearTimeout(timeout);
|
||
if (response.error) {
|
||
reject(new Error(response.error.message));
|
||
}
|
||
else {
|
||
resolve(response.result);
|
||
}
|
||
});
|
||
this.ws.send(JSON.stringify(request));
|
||
});
|
||
}
|
||
async testMCPTools() {
|
||
var _a, _b;
|
||
console.log('\n=== 测试 MCP 工具(通过 WebSocket)===');
|
||
try {
|
||
// 0. 获取工具列表
|
||
console.log('\n0. 获取工具列表...');
|
||
const toolsList = await this.listTools();
|
||
console.log(`找到 ${((_a = toolsList.tools) === null || _a === void 0 ? void 0 : _a.length) || 0} 个工具:`);
|
||
if (toolsList.tools) {
|
||
for (const tool of toolsList.tools.slice(0, 10)) { // 只显示前10个
|
||
console.log(` - ${tool.name}: ${tool.description}`);
|
||
}
|
||
if (toolsList.tools.length > 10) {
|
||
console.log(` ... 还有 ${toolsList.tools.length - 10} 个工具`);
|
||
}
|
||
}
|
||
// 1. 测试场景工具
|
||
console.log('\n1. 测试当前场景信息...');
|
||
const sceneInfo = await this.callTool('scene_get_current_scene');
|
||
console.log('场景信息:', JSON.stringify(sceneInfo).substring(0, 100) + '...');
|
||
// 2. 测试场景列表
|
||
console.log('\n2. 测试场景列表...');
|
||
const sceneList = await this.callTool('scene_get_scene_list');
|
||
console.log('场景列表:', JSON.stringify(sceneList).substring(0, 100) + '...');
|
||
// 3. 测试节点创建
|
||
console.log('\n3. 测试创建节点...');
|
||
const createResult = await this.callTool('node_create_node', {
|
||
name: 'MCPTestNode_' + Date.now(),
|
||
nodeType: 'cc.Node',
|
||
position: { x: 0, y: 0, z: 0 }
|
||
});
|
||
console.log('创建节点结果:', createResult);
|
||
// 解析创建节点的结果
|
||
let nodeUuid = null;
|
||
if (createResult.content && createResult.content[0] && createResult.content[0].text) {
|
||
try {
|
||
const resultData = JSON.parse(createResult.content[0].text);
|
||
if (resultData.success && resultData.data && resultData.data.uuid) {
|
||
nodeUuid = resultData.data.uuid;
|
||
console.log('成功获取节点UUID:', nodeUuid);
|
||
}
|
||
}
|
||
catch (e) {
|
||
}
|
||
}
|
||
if (nodeUuid) {
|
||
// 4. 测试查询节点
|
||
console.log('\n4. 测试查询节点...');
|
||
const queryResult = await this.callTool('node_get_node_info', {
|
||
uuid: nodeUuid
|
||
});
|
||
console.log('节点信息:', JSON.stringify(queryResult).substring(0, 100) + '...');
|
||
// 5. 测试删除节点
|
||
console.log('\n5. 测试删除节点...');
|
||
const removeResult = await this.callTool('node_delete_node', {
|
||
uuid: nodeUuid
|
||
});
|
||
console.log('删除结果:', removeResult);
|
||
}
|
||
else {
|
||
console.log('无法从创建结果获取节点UUID,尝试通过名称查找...');
|
||
// 备用方案:通过名称查找刚创建的节点
|
||
const findResult = await this.callTool('node_find_node_by_name', {
|
||
name: 'MCPTestNode_' + Date.now()
|
||
});
|
||
if (findResult.content && findResult.content[0] && findResult.content[0].text) {
|
||
try {
|
||
const findData = JSON.parse(findResult.content[0].text);
|
||
if (findData.success && findData.data && findData.data.uuid) {
|
||
nodeUuid = findData.data.uuid;
|
||
console.log('通过名称查找成功获取UUID:', nodeUuid);
|
||
}
|
||
}
|
||
catch (e) {
|
||
}
|
||
}
|
||
if (!nodeUuid) {
|
||
console.log('所有方式都无法获取节点UUID,跳过后续节点操作测试');
|
||
}
|
||
}
|
||
// 6. 测试项目工具
|
||
console.log('\n6. 测试项目信息...');
|
||
const projectInfo = await this.callTool('project_get_project_info');
|
||
console.log('项目信息:', JSON.stringify(projectInfo).substring(0, 100) + '...');
|
||
// 7. 测试预制体工具
|
||
console.log('\n7. 测试预制体列表...');
|
||
const prefabResult = await this.callTool('prefab_get_prefab_list', {
|
||
folder: 'db://assets'
|
||
});
|
||
console.log('找到预制体:', ((_b = prefabResult.data) === null || _b === void 0 ? void 0 : _b.length) || 0);
|
||
// 8. 测试组件工具
|
||
console.log('\n8. 测试可用组件...');
|
||
const componentsResult = await this.callTool('component_get_available_components');
|
||
console.log('可用组件:', JSON.stringify(componentsResult).substring(0, 100) + '...');
|
||
// 9. 测试调试工具
|
||
console.log('\n9. 测试编辑器信息...');
|
||
const editorInfo = await this.callTool('debug_get_editor_info');
|
||
console.log('编辑器信息:', JSON.stringify(editorInfo).substring(0, 100) + '...');
|
||
}
|
||
catch (error) {
|
||
console.error('MCP 工具测试失败:', error);
|
||
}
|
||
}
|
||
disconnect() {
|
||
if (this.ws) {
|
||
this.ws.close();
|
||
this.ws = null;
|
||
}
|
||
this.responseHandlers.clear();
|
||
}
|
||
}
|
||
exports.MCPToolTester = MCPToolTester;
|
||
// 导出到全局方便测试
|
||
global.MCPToolTester = MCPToolTester;
|
||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXRvb2wtdGVzdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc291cmNlL3Rlc3QvbWNwLXRvb2wtdGVzdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBOztHQUVHO0FBQ0gsTUFBYSxhQUFhO0lBQTFCO1FBQ1ksT0FBRSxHQUFxQixJQUFJLENBQUM7UUFDNUIsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUNkLHFCQUFnQixHQUFHLElBQUksR0FBRyxFQUFtQyxDQUFDO0lBK04xRSxDQUFDO0lBN05HLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBWTtRQUN0QixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDM0IsSUFBSSxDQUFDO2dCQUNELElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxTQUFTLENBQUMsa0JBQWtCLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBRWxELElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRTtvQkFDbEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO29CQUM5QixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2xCLENBQUMsQ0FBQztnQkFFRixJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sR0FBRyxDQUFDLEtBQUssRUFBRSxFQUFFO29CQUN4QixPQUFPLENBQUMsS0FBSyxDQUFDLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxDQUFDO29CQUN4QyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ25CLENBQUMsQ0FBQztnQkFFRixJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsR0FBRyxDQUFDLEtBQUssRUFBRSxFQUFFO29CQUMxQixJQUFJLENBQUM7d0JBQ0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ3hDLElBQUksUUFBUSxDQUFDLEVBQUUsSUFBSSxJ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QUM7WUFDOUIsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsb0NBQW9DLENBQUMsQ0FBQztZQUNuRixPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQztZQUVqRixZQUFZO1lBQ1osT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQy9CLE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1lBQ2hFLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQztRQUVoRixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hDLENBQUM7SUFDTCxDQUFDO0lBRUQsVUFBVTtRQUNOLElBQUksSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ1YsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQztRQUNuQixDQUFDO1FBQ0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2xDLENBQUM7Q0FDSjtBQWxPRCxzQ0FrT0M7QUFFRCxZQUFZO0FBQ1gsTUFBYyxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJkZWNsYXJlIGNvbnN0IEVkaXRvcjogYW55O1xyXG5cclxuLyoqXHJcbiAqIE1DUCDlt6XlhbfmtYvor5XlmaggLSDnm7TmjqXmtYvor5XpgJrov4cgV2ViU29ja2V0IOeahCBNQ1Ag5bel5YW3XHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgTUNQVG9vbFRlc3RlciB7XHJcbiAgICBwcml2YXRlIHdzOiBXZWJTb2NrZXQgfCBudWxsID0gbnVsbDtcclxuICAgIHByaXZhdGUgbWVzc2FnZUlkID0gMDtcclxuICAgIHByaXZhdGUgcmVzcG9uc2VIYW5kbGVycyA9IG5ldyBNYXA8bnVtYmVyLCAocmVzcG9uc2U6IGFueSkgPT4gdm9pZD4oKTtcclxuXHJcbiAgICBhc3luYyBjb25uZWN0KHBvcnQ6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy53cyA9IG5ldyBXZWJTb2NrZXQoYHdzOi8vbG9jYWxob3N0OiR7cG9ydH1gKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy53cy5vbm9wZW4gPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1dlYlNvY2tldCDov57mjqXmiJDlip8nKTtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy53cy5vbmVycm9yID0gKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignV2ViU29ja2V0IOi/nuaOpemUmeivrzonLCBlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICB0aGlzLndzLm9ubWVzc2FnZSA9IChldmVudCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gSlNPTi5wYXJzZShldmVudC5kYXRhKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmlkICYmIHRoaXMucmVzcG9uc2VIYW5kbGVycy5oYXMocmVzcG9uc2UuaWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5yZXNwb25zZUhhbmRsZXJzLmdldChyZXNwb25zZS5pZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc3BvbnNlSGFuZGxlcnMuZGVsZXRlKHJlc3BvbnNlLmlkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXI/LihyZXNwb25zZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCflpITnkIblk43lupTml7blh7rplJk6JywgZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCfliJvlu7ogV2ViU29ja2V0IOaXtuWHuumUmTonLCBlcnJvcik7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGNhbGxUb29sKHRvb2w6IHN0cmluZywgYXJnczogYW55ID0ge30pOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIGlmICghdGhpcy53cyB8fCB0aGlzLndzLnJlYWR5U3RhdGUgIT09IFdlYlNvY2tldC5PUEVOKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignV2ViU29ja2V0IOacqui/nuaOpScpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgaWQgPSArK3RoaXMubWVzc2FnZUlkO1xyXG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0ge1xyXG4gICAgICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXHJcbiAgICAgICAgICAgICAgICBpZCxcclxuICAgICAgICAgICAgICAgIG1ldGhvZDogJ3Rvb2xzL2NhbGwnLFxyXG4gICAgICAgICAgICAgICAgcGFyYW1zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogdG9vbCxcclxuICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHM6IGFyZ3NcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVzcG9uc2VIYW5kbGVycy5kZWxldGUoaWQpO1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcign6K+35rGC6LaF5pe2JykpO1xyXG4gICAgICAgICAgICB9LCAxMDAwMCk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnJlc3BvbnNlSGFuZGxlcnMuc2V0KGlkLCAocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcclxuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5lcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IocmVzcG9uc2UuZXJyb3IubWVzc2FnZSkpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3BvbnNlLnJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgdGhpcy53cyEuc2VuZChKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgbGlzdFRvb2xzKCk6IFByb21pc2U8YW55PiB7XHJcbiAgICAgICAgaWYgKCF0aGlzLndzIHx8IHRoaXMud3MucmVhZHlTdGF0ZSAhPT0gV2ViU29ja2V0Lk9QRU4pIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJTb2NrZXQg5pyq6L+e5o6lJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBpZCA9ICsrdGhpcy5tZXNzYWdlSWQ7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSB7XHJcbiAgICAgICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcclxuICAgICAgICAgICAgICAgIGlkLFxyXG4gICAgICAgICAgICAgICAgbWV0aG9kOiAndG9vbHMvbGlzdCdcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVzcG9uc2VIYW5kbGVycy5kZWxldGUoaWQpO1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcign6K+35rGC6LaF5pe2JykpO1xyXG4gICAgICAgICAgICB9LCAxMDAwMCk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnJlc3BvbnNlSGFuZGxlcnMuc2V0KGlkLCAocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcclxuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5lcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IocmVzcG9uc2UuZXJyb3IubWVzc2FnZSkpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3BvbnNlLnJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgdGhpcy53cyEuc2VuZChKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgdGVzdE1DUFRvb2xzKCkge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKCdcXG49PT0g5rWL6K+VIE1DUCDlt6XlhbfvvIjpgJrov4cgV2ViU29ja2V077yJPT09Jyk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgLy8gMC4g6I635Y+W5bel5YW35YiX6KGoXHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdcXG4wLiDojrflj5blt6XlhbfliJfooaguLi4nKTtcclxuICAgICAgICAgICAgY29uc3QgdG9vbHNMaXN0ID0gYXdhaXQgdGhpcy5saXN0VG9vbHMoKTtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coYOaJvuWIsCAke3Rvb2xzTGlzdC50b29scz8ubGVuZ3RoIHx8IDB9IOS4quW3peWFtzpgKTtcclxuICAgICAgICAgICAgaWYgKHRvb2xzTGlzdC50b29scykge1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCB0b29sIG9mIHRvb2xzTGlzdC50b29scy5zbGljZSgwLCAxMCkpIHsgLy8g5Y+q5pi+56S65YmNMTDkuKpcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgICAtICR7dG9vbC5uYW1lfTogJHt0b29sLmRlc2NyaXB0aW9ufWApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRvb2xzTGlzdC50b29scy5sZW5ndGggPiAxMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGAgIC4uLiDov5jmnIkgJHt0b29sc0xpc3QudG9vbHMubGVuZ3RoIC0gMTB9IOS4quW3peWFt2ApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyAxLiDmtYvor5XlnLrmma/lt6XlhbdcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ1xcbjEuIOa1i+ivleW9k+WJjeWcuuaZr+S/oeaBry4uLicpO1xyXG4gICAgICAgICAgICBjb25zdCBzY2VuZUluZm8gPSBhd2FpdCB0aGlzLmNhbGxUb29sKCdzY2VuZV9nZXRfY3VycmVudF9zY2VuZScpO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygn5Zy65pmv5L+h5oGvOicsIEpTT04uc3RyaW5naWZ5KHNjZW5lSW5mbykuc3Vic3RyaW5nKDAsIDEwMCkgKyAnLi4uJyk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyAyLiDmtYvor5XlnLrmma/liJfooahcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ1xcbjIuIOa1i+ivleWcuuaZr+WIl+ihqC4uLicpO1xyXG4gICAgICAgICAgICBjb25zdCBzY2VuZUxpc3QgPSBhd2FpdCB0aGlzLmNhbGxUb29sKCdzY2VuZV9nZXRfc2NlbmVfbGlzdCcpO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygn5Zy65pmv5YiX6KGoOicsIEpTT04uc3RyaW5naWZ5KHNjZW5lTGlzdCkuc3Vic3RyaW5nKDAsIDEwMCkgKyAnLi4uJyk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyAzLiDmtYvor5XoioLngrnliJvlu7pcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ1xcbjMuIOa1i+ivleWIm+W7uuiKgueCuS4uLicpO1xyXG4gICAgICAgICAgICBjb25zdCBjcmVhdGVSZXN1bHQgPSBhd2FpdCB0aGlzLmNhbGxUb29sKCdub2RlX2NyZWF0ZV9ub2RlJywge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogJ01DUFRlc3ROb2RlXycgKyBEYXRlLm5vdygpLFxyXG4gICAgICAgICAgICAgICAgbm9kZVR5cGU6ICdjYy5Ob2RlJyxcclxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiB7IHg6IDAsIHk6IDAsIHo6IDAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ+WIm+W7uuiKgueCuee7k+aenDonLCBjcmVhdGVSZXN1bHQpO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8g6Kej5p6Q5Yib5bu66IqC54K555qE57uT5p6cXHJcbiAgICAgICAgICAgIGxldCBub2RlVXVpZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmIChjcmVhdGVSZXN1bHQuY29udGVudCAmJiBjcmVhdGVSZXN1bHQuY29udGVudFswXSAmJiBjcmVhdGVSZXN1bHQuY29udGVudFswXS50ZXh0KSB7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdERhdGEgPSBKU09OLnBhcnNlKGNyZWF0ZVJlc3VsdC5jb250ZW50WzBdLnRleHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHREYXRhLnN1Y2Nlc3MgJiYgcmVzdWx0RGF0YS5kYXRhICYmIHJlc3VsdERhdGEuZGF0YS51dWlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVVdWlkID0gcmVzdWx0RGF0YS5kYXRhLnV1aWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCfmiJDlip/ojrflj5boioLngrlVVUlEOicsIG5vZGVVdWlkKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGlmIChub2RlVXVpZCkge1xyXG4gICAgICAgICAgICAgICAgLy8gNC4g5rWL6K+V5p+l6K+i6IqC54K5XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnXFxuNC4g5rWL6K+V5p+l6K+i6IqC54K5Li4uJyk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBxdWVyeVJlc3VsdCA9IGF3YWl0IHRoaXMuY2FsbFRvb2woJ25vZGVfZ2V0X25vZGVfaW5mbycsIHtcclxuICAgICAgICAgICAgICAgICAgICB1dWlkOiBub2RlVXVpZFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygn6IqC54K55L+h5oGvOicsIEpTT04uc3RyaW5naWZ5KHF1ZXJ5UmVzdWx0KS5zdWJzdHJpbmcoMCwgMTAwKSArICcuLi4nKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgLy8gNS4g5rWL6K+V5Yig6Zmk6IqC54K5XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnXFxuNS4g5rWL6K+V5Yig6Zmk6IqC54K5Li4uJyk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZW1vdmVSZXN1bHQgPSBhd2FpdCB0aGlzLmNhbGxUb29sKCdub2RlX2RlbGV0ZV9ub2RlJywge1xyXG4gICAgICAgICAgICAgICAgICAgIHV1aWQ6IG5vZGVVdWlkXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCfliKDpmaTnu5Pmnpw6JywgcmVtb3ZlUmVzdWx0KTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCfml6Dms5Xku47liJvlu7rnu5Pmnpzojrflj5boioLngrlVVUlE77yM5bCd6K+V6YCa6L+H5ZCN56ew5p+l5om+Li4uJyk7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIC8vIOWkh+eUqOaWueahiO+8mumAmui/h+WQjeensOafpeaJvuWImuWIm+W7uueahOiKgueCuVxyXG4gICAgICAgICAgICAgICAgY29uc3QgZmluZFJlc3VsdCA9IGF3YWl0IHRoaXMuY2FsbFRvb2woJ25vZGVfZmluZF9ub2RlX2J5X25hbWUnLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ01DUFRlc3ROb2RlXycgKyBEYXRlLm5vdygpXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgaWYgKGZpbmRSZXN1bHQuY29udGVudCAmJiBmaW5kUmVzdWx0LmNvbnRlbnRbMF0gJiYgZmluZFJlc3VsdC5jb250ZW50WzBdLnRleHQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5kRGF0YSA9IEpTT04ucGFyc2UoZmluZFJlc3VsdC5jb250ZW50WzBdLnRleHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluZERhdGEuc3VjY2VzcyAmJiBmaW5kRGF0YS5kYXRhICYmIGZpbmREYXRhLmRhdGEudXVpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVV1aWQgPSBmaW5kRGF0YS5kYXRhLnV1aWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygn6YCa6L+H5ZCN56ew5p+l5om+5oiQ5Yqf6I635Y+WVVVJRDonLCBub2RlVXVpZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBpZiAoIW5vZGVVdWlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ+aJgOacieaWueW8j+mDveaXoOazleiOt+WPluiKgueCuVVVSUTvvIzot7Pov4flkI7nu63oioLngrnmk43kvZzmtYvor5UnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gNi4g5rWL6K+V6aG555uu5bel5YW3XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdcXG42LiDmtYvor5Xpobnnm67kv6Hmga8uLi4nKTtcclxuICAgICAgICAgICAgY29uc3QgcHJvamVjdEluZm8gPSBhd2FpdCB0aGlzLmNhbGxUb29sKCdwcm9qZWN0X2dldF9wcm9qZWN0X2luZm8nKTtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ+mhueebruS/oeaBrzonLCBKU09OLnN0cmluZ2lmeShwcm9qZWN0SW5mbykuc3Vic3RyaW5nKDAsIDEwMCkgKyAnLi4uJyk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyA3LiDmtYvor5XpooTliLbkvZPlt6XlhbdcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ1xcbjcuIOa1i+ivlemihOWItuS9k+WIl+ihqC4uLicpO1xyXG4gICAgICAgICAgICBjb25zdCBwcmVmYWJSZXN1bHQgPSBhd2FpdCB0aGlzLmNhbGxUb29sKCdwcmVmYWJfZ2V0X3ByZWZhYl9saXN0Jywge1xyXG4gICAgICAgICAgICAgICAgZm9sZGVyOiAnZGI6Ly9hc3NldHMnXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygn5om+5Yiw6aKE5Yi25L2TOicsIHByZWZhYlJlc3VsdC5kYXRhPy5sZW5ndGggfHwgMCk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyA4LiDmtYvor5Xnu4Tku7blt6XlhbdcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ1xcbjguIOa1i+ivleWPr+eUqOe7hOS7ti4uLicpO1xyXG4gICAgICAgICAgICBjb25zdCBjb21wb25lbnRzUmVzdWx0ID0gYXdhaXQgdGhpcy5jYWxsVG9vbCgnY29tcG9uZW50X2dldF9hdmFpbGFibGVfY29tcG9uZW50cycpO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygn5Y+v55So57uE5Lu2OicsIEpTT04uc3RyaW5naWZ5KGNvbXBvbmVudHNSZXN1bHQpLnN1YnN0cmluZygwLCAxMDApICsgJy4uLicpO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gOS4g5rWL6K+V6LCD6K+V5bel5YW3XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdcXG45LiDmtYvor5XnvJbovpHlmajkv6Hmga8uLi4nKTtcclxuICAgICAgICAgICAgY29uc3QgZWRpdG9ySW5mbyA9IGF3YWl0IHRoaXMuY2FsbFRvb2woJ2RlYnVnX2dldF9lZGl0b3JfaW5mbycpO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygn57yW6L6R5Zmo5L+h5oGvOicsIEpTT04uc3RyaW5naWZ5KGVkaXRvckluZm8pLnN1YnN0cmluZygwLCAxMDApICsgJy4uLicpO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdNQ1Ag5bel5YW35rWL6K+V5aSx6LSlOicsIGVycm9yKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZGlzY29ubmVjdCgpIHtcclxuICAgICAgICBpZiAodGhpcy53cykge1xyXG4gICAgICAgICAgICB0aGlzLndzLmNsb3NlKCk7XHJcbiAgICAgICAgICAgIHRoaXMud3MgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnJlc3BvbnNlSGFuZGxlcnMuY2xlYXIoKTtcclxuICAgIH1cclxufVxyXG5cclxuLy8g5a+85Ye65Yiw5YWo5bGA5pa55L6/5rWL6K+VXHJcbihnbG9iYWwgYXMgYW55KS5NQ1BUb29sVGVzdGVyID0gTUNQVG9vbFRlc3RlcjsiXX0=
|