"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.excelToJsonPlugin = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const os = __importStar(require("os")); const MembershipSet_1 = require("./MembershipSet"); /** 内置 xlsx 库,无需 npm install */ // eslint-disable-next-line @typescript-eslint/no-require-imports const XLSX = require(path.join(__dirname, '../lib/xlsx.js')); const DEFAULT_CONFIG = { excelPath: '配置表/excelList', jsonExportPath: 'assets/bundles/first/config', langJsonExportPath: 'assets/bundles/lang', tsExportPath: 'assets/script/interface', autoExport: true, }; class ExcelToJsonPlugin { constructor() { this.config = Object.assign(Object.assign({}, DEFAULT_CONFIG), { watcher: null }); this.fileWatcher = null; this.isExporting = false; this.exportQueue = []; /** 本次导出写入过的 JSON 目录,用于刷新 asset-db */ this.jsonRefreshPaths = (0, MembershipSet_1.createMembershipSet)(); // 消息处理 this.messages = { 'excel-to-json-ts:export-manual': () => { this.exportManual(); } }; } async load() { await this.exportAllExcel(); this.setupFileWatcher(); } /** 插件根目录(config.json 所在目录) */ getPluginRoot() { return path.join(__dirname, '..'); } /** 将 config.json 中的相对路径解析为绝对路径(相对项目根目录) */ resolveProjectPath(relativePath) { const projectRoot = Editor.Project.path; return path.normalize(path.join(projectRoot, relativePath.replace(/\\/g, '/').replace(/^\.\//, ''))); } /** 判断工作表是否需要导出:格式为 "描述|json文件名",且非默认 Sheet */ isExportableSheet(sheetName) { if (!sheetName || sheetName.startsWith('Sheet')) { return false; } const parts = sheetName.split('|'); return parts.length >= 2 && parts[1].trim().length > 0; } /** 获取工作表导出的 json 文件名(| 后第一段) */ getSheetExportName(sheetName) { return sheetName.split('|')[1].trim(); } /** 语言表:lang_cn / lang_en … */ isLangExportName(exportName) { return /^lang_[a-z]{2}$/i.test(exportName); } /** 解析 JSON 导出目录(语言表进对应语言包 bundle) */ resolveJsonExportDir(exportName) { if (this.isLangExportName(exportName)) { return path.join(this.config.langJsonExportPath, exportName, 'config'); } return this.config.jsonExportPath; } /** 清理 first 中遗留的语言表 JSON(历史路径) */ removeStaleLangJsonInFirst(jsonFileName) { const stalePath = path.join(this.config.jsonExportPath, jsonFileName); if (fs.existsSync(stalePath)) { fs.unlinkSync(stalePath); this.log(`[Excel插件] 已删除 first 中遗留语言表: ${jsonFileName}`); } const staleMeta = `${stalePath}.meta`; if (fs.existsSync(staleMeta)) { fs.unlinkSync(staleMeta); } } unload() { this.log('[Excel插件] 插件已卸载'); this.stopFileWatcher(); } /** 从插件根目录 config.json 加载配置,路径相对项目根目录 */ loadConfig() { var _a; const configPath = path.join(this.getPluginRoot(), 'config.json'); try { if (!fs.existsSync(configPath)) { fs.writeFileSync(configPath, JSON.stringify(DEFAULT_CONFIG, null, 4), 'utf-8'); this.warn(`[Excel插件] 已创建默认配置文件: ${configPath}`); } const raw = JSON.parse(fs.readFileSync(configPath, 'utf-8')); const merged = Object.assign(Object.assign({}, DEFAULT_CONFIG), raw); this.config.excelPath = this.resolveProjectPath(merged.excelPath); this.config.jsonExportPath = this.resolveProjectPath(merged.jsonExportPath); this.config.langJsonExportPath = this.resolveProjectPath((_a = merged.langJsonExportPath) !== null && _a !== void 0 ? _a : DEFAULT_CONFIG.langJsonExportPath); this.config.tsExportPath = this.resolveProjectPath(merged.tsExportPath); this.config.autoExport = merged.autoExport; this.log('[Excel插件] 配置已加载 (extensions/excel-to-json-ts/config.json)'); this.log(`[Excel插件] excelPath: ${this.config.excelPath}`); this.log(`[Excel插件] jsonPath: ${this.config.jsonExportPath}`); this.log(`[Excel插件] langJsonPath: ${this.config.langJsonExportPath}`); this.log(`[Excel插件] tsPath: ${this.config.tsExportPath}`); this.log(`[Excel插件] autoExport: ${this.config.autoExport}`); } catch (err) { this.error(`[Excel插件] 加载配置失败 (${configPath}): ${err}`); } } // 手动导出 exportManual() { this.exportAllExcel(); } // 导出所有Excel(增强健壮性) async exportAllExcel() { this.loadConfig(); if (!this.config.excelPath) { this.error('[Excel插件] Excel目录路径未配置'); return; } if (!fs.existsSync(this.config.excelPath)) { this.error(`[Excel插件] Excel目录不存在: ${this.config.excelPath}`); return; } try { (0, MembershipSet_1.membershipClear)(this.jsonRefreshPaths); // 确保导出目录存在 if (this.config.jsonExportPath && !fs.existsSync(this.config.jsonExportPath)) { fs.mkdirSync(this.config.jsonExportPath, { recursive: true }); } if (this.config.langJsonExportPath && !fs.existsSync(this.config.langJsonExportPath)) { fs.mkdirSync(this.config.langJsonExportPath, { recursive: true }); } if (this.config.tsExportPath && !fs.existsSync(this.config.tsExportPath)) { fs.mkdirSync(this.config.tsExportPath, { recursive: true }); } // 获取目录中所有Excel文件 const excelFiles = this.getExcelFilesInDirectory(this.config.excelPath); if (excelFiles.length === 0) { this.warn(`[Excel插件] 目录中没有找到Excel文件: ${this.config.excelPath}`); return; } this.log(`[Excel插件] 找到 ${excelFiles.length} 个Excel文件`); let successCount = 0; let errorCount = 0; // 处理每个Excel文件 for (const excelFile of excelFiles) { try { this.processExcelFile(excelFile); successCount++; } catch (err) { this.error(`[Excel插件] 处理文件失败 ${path.basename(excelFile)}: ${err}`); errorCount++; } } if (successCount > 0) { this.refreshAssetDatabase(); this.success(`[Excel插件] 导出完成,成功处理 ${successCount} 个文件,失败 ${errorCount} 个`); } else { this.error(`[Excel插件] 导出失败,没有成功处理任何文件`); } } catch (err) { this.error(`[Excel插件] 导出失败: ${err}`); } } // 获取目录中的所有Excel文件 getExcelFilesInDirectory(dirPath) { return fs.readdirSync(dirPath) .filter(file => { // 过滤隐藏文件(以点开头的文件) if (file.startsWith('.') || file.startsWith('~')) { return false; } const ext = path.extname(file).toLowerCase(); return (ext === '.xlsx' || ext === '.xls') && fs.statSync(path.join(dirPath, file)).isFile(); }) .map(file => path.join(dirPath, file)); } // 处理单个Excel文件 processExcelFile(filePath) { try { // 安全读取打开状态的Excel文件 const workbook = this.readExcelSafely(filePath); const sheetNames = workbook.SheetNames; // 导出每个工作表 for (const sheetName of sheetNames) { if (!this.isExportableSheet(sheetName)) { continue; } this.exportSheet(workbook, sheetName, filePath); } } catch (err) { throw new Error(`处理文件 ${path.basename(filePath)} 失败: ${err}`); } } /** 从 buffer 解析 Excel,避免 readFile 在 Windows 中文路径下失败 */ parseExcelBuffer(buffer) { return XLSX.read(buffer, { type: 'buffer' }); } /** 读取 Excel:优先直接读,失败时复制到 ASCII 临时文件再读 */ readExcelSafely(filePath) { // 1. 直接读取(文件未占用时最快) try { const buffer = fs.readFileSync(filePath); if (buffer.length > 0) { return this.parseExcelBuffer(buffer); } } catch (directErr) { this.warn(`[Excel插件] 直接读取失败,尝试复制后读取: ${path.basename(filePath)} (${directErr})`); } // 2. 复制到纯 ASCII 临时路径(避免中文文件名导致 xlsx 库无法访问) const tempPath = path.join(os.tmpdir(), `excel-temp-${Date.now()}-${process.pid}.xlsx`); try { fs.copyFileSync(filePath, tempPath); const tempStats = fs.statSync(tempPath); if (tempStats.size === 0) { throw new Error('临时文件大小为0,复制可能未完成'); } const buffer = fs.readFileSync(tempPath); return this.parseExcelBuffer(buffer); } catch (err) { throw new Error(`读取Excel失败: ${err.message || err}`); } finally { try { if (fs.existsSync(tempPath)) { fs.unlinkSync(tempPath); } } catch (e) { this.warn(`[Excel插件] 无法删除临时文件: ${tempPath} - ${e}`); } } } // 导出单个工作表 exportSheet(workbook, sheetName, filePath) { try { const worksheet = workbook.Sheets[sheetName]; const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); // 检查是否有足够的表头行(至少3行:字段名、类型、说明) if (jsonData.length < 3) { this.warn(`[Excel插件] 工作表 "${sheetName}" 数据不足,跳过导出 (文件: ${path.basename(filePath)})的${sheetName}`); return; } if (!this.isExportableSheet(sheetName)) { this.warn(`[Excel插件] 工作表 "${sheetName}" 名称格式错误,跳过导出 (文件: ${path.basename(filePath)})`); return; } const sName = this.getSheetExportName(sheetName); // 提取表头信息 const headers = { fields: jsonData[0], types: jsonData[1], descriptions: jsonData[2] }; // 从第4行开始是数据 const dataRows = jsonData.slice(3); // 生成JSON数据 const jsonResult = this.generateJsonData(dataRows, headers); // 生成TS接口 const tsInterface = this.generateTSInterface(sName, headers); // 生成文件名 const safeSheetName = this.makeSafeFileName(sName); const jsonFileName = `${safeSheetName}.json`; //const tsFileName = `ITable${safeSheetName}.ts`; const tsFileName = `AutoTable.ts`; const jsonExportDir = this.resolveJsonExportDir(sName); if (!fs.existsSync(jsonExportDir)) { fs.mkdirSync(jsonExportDir, { recursive: true }); } // 写入JSON文件 if (jsonExportDir) { const jsonPath = path.join(jsonExportDir, jsonFileName); fs.writeFileSync(jsonPath, JSON.stringify(jsonResult, null, 4), 'utf-8'); (0, MembershipSet_1.membershipAdd)(this.jsonRefreshPaths, jsonExportDir); if (this.isLangExportName(sName)) { this.removeStaleLangJsonInFirst(jsonFileName); } } // 写入TS文件 if (this.config.tsExportPath) { const tsPath = path.join(this.config.tsExportPath, tsFileName); let tsContent = ""; try { if (fs.existsSync(tsPath)) { tsContent = fs.readFileSync(tsPath, 'utf-8'); } } catch (err) { this.warn(`[Excel插件] 读取TS文件失败: ${err}`); } if (tsContent == "") { tsContent = "declare global {\n\n}\nexport { };"; } if (this.extractFullInterfaceBlock(tsContent, "ITable" + sName)) { tsContent = this.replaceInterfaceBlock(tsContent, "ITable" + sName, tsInterface); } else { tsContent = tsContent.replace(/\}\r?\nexport \{ \};$/, tsInterface + "}\nexport { };"); } tsContent = this.normalizeAutoTableBlankLines(tsContent); fs.writeFileSync(tsPath, tsContent, 'utf-8'); } } catch (err) { throw new Error(`工作表 "${sheetName}" 导出失败 (文件: ${path.basename(filePath)}): ${err}`); } } /** * 转义正则特殊字符 */ escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } /** * 精准查找接口声明行(全字匹配) */ findInterfaceDeclarationLine(fileContent, interfaceName) { // 使用单词边界 \b 确保全字匹配 const regex = new RegExp(`\\binterface\\s+${this.escapeRegExp(interfaceName)}\\b(?:\\s*<[^>]*>)?\\s*[\\{\\n]`, 'g'); let match; while ((match = regex.exec(fileContent)) !== null) { // 找到匹配位置,确定完整行 const matchStart = match.index; // 向前找到行开始 const lineStart = fileContent.lastIndexOf('\n', matchStart - 1) + 1; // 向后找到行结束 const lineEnd = fileContent.indexOf('\n', matchStart); const actualLineEnd = lineEnd === -1 ? fileContent.length : lineEnd; const lineContent = fileContent.substring(lineStart, actualLineEnd); // 验证:确保这一行确实是我们的目标接口 if (lineContent.trim().startsWith(`interface ${interfaceName}`)) { return { lineStart, lineEnd: actualLineEnd, lineContent }; } } return null; } /** * 提取完整的接口块(包括上方注释) */ extractFullInterfaceBlock(fileContent, interfaceName) { const interfaceLine = this.findInterfaceDeclarationLine(fileContent, interfaceName); if (!interfaceLine) { return null; } // === 向前查找连续的注释块 === let blockStart = interfaceLine.lineStart; let currentPos = interfaceLine.lineStart; while (currentPos > 0) { const prevLineEnd = currentPos - 1; const prevLineStart = fileContent.lastIndexOf('\n', prevLineEnd - 1) + 1; const prevLine = fileContent.substring(prevLineStart, prevLineEnd).trim(); // 检查是否为注释行或空行 if (prevLine === '' || prevLine.startsWith('//') || prevLine.startsWith('/*') || prevLine.startsWith('*')) { currentPos = prevLineStart; } else { blockStart = currentPos; break; } } if (currentPos === 0) { blockStart = 0; } // === 向后查找接口体结束 === // 找到 interface 行中的开括号位置 const openBraceIndex = interfaceLine.lineContent.indexOf('{'); let startPos = interfaceLine.lineStart; let braceCount = 0; if (openBraceIndex !== -1) { // 开括号在同一行 startPos = interfaceLine.lineStart + openBraceIndex; braceCount = 1; } else { // 开括号在下一行,找到第一个 { const nextOpenBrace = fileContent.indexOf('{', interfaceLine.lineEnd); if (nextOpenBrace === -1) return null; startPos = nextOpenBrace; braceCount = 1; } let pos = startPos + 1; // 跳过 { while (pos < fileContent.length && braceCount > 0) { if (fileContent[pos] === '{') { braceCount++; } else if (fileContent[pos] === '}') { braceCount--; } pos++; } if (braceCount !== 0) { return null; // 括号不匹配 } // 吞掉 } 后紧跟的换行,避免替换时 newBlock 再带 \n 导致空行累加 let blockEnd = pos; if (fileContent[blockEnd] === '\r') blockEnd++; if (fileContent[blockEnd] === '\n') blockEnd++; const fullContent = fileContent.substring(blockStart, blockEnd); return { start: blockStart, end: blockEnd, content: fullContent }; } /** * 去掉接口之间 / declare global 末尾多余空行(生成时易累加) */ normalizeAutoTableBlankLines(content) { let out = content.replace(/\r\n/g, '\n'); // 若误带入未解决冲突(通常是空行 vs 无空行),丢掉冲突标记 out = out.replace(/^<<<<<<< .+\n(?:.*\n)*?=======\n(?:.*\n)*?>>>>>>> .+\n/gm, ''); // 接口结束 } 后只保留一个换行,再接下一接口注释或 global 结束 } out = out.replace(/(\n {4}\})\n(?:[ \t]*\n)+(?=[ \t]*(?:\/\*\*|\}))/g, '$1\n'); // 文件末尾 export 前也不留空行 out = out.replace(/\n(?:[ \t]*\n)+(\}\nexport \{ \};)\s*$/g, '\n$1\n'); return out; } /** * 完全替换接口块(全字匹配,精准替换) */ replaceInterfaceBlock(fileContent, interfaceName, newInterfaceBlock) { const blockInfo = this.extractFullInterfaceBlock(fileContent, interfaceName); if (!blockInfo) { throw new Error(`❌ 接口 "${interfaceName}" 未找到!请检查名称是否正确。`); } // 验证:确保提取的块确实只包含目标接口 const interfaceLines = blockInfo.content.split('\n'); const interfaceDeclLines = interfaceLines.filter(line => line.trim().startsWith('interface ')); if (interfaceDeclLines.length !== 1) { throw new Error(`❌ 找到多个 interface 声明,可能匹配错误!`); } if (!interfaceDeclLines[0].includes(`interface ${interfaceName}`)) { throw new Error(`❌ 匹配到错误的接口名称!`); } //console.log(`✅ 精准匹配到接口 "${interfaceName}"`); return (fileContent.substring(0, blockInfo.start) + newInterfaceBlock + fileContent.substring(blockInfo.end)); } // 设置文件监听 setupFileWatcher() { this.stopFileWatcher(); this.loadConfig(); if (!this.config.autoExport) { this.log('[Excel插件] 自动导出已关闭,跳过文件监听'); return; } if (!this.config.excelPath) return; if (!fs.existsSync(this.config.excelPath)) { this.error(`[Excel插件] 监听目录不存在: ${this.config.excelPath}`); return; } try { // 使用更可靠的监听方式 this.fileWatcher = fs.watch(this.config.excelPath, { recursive: false, encoding: 'utf8' }, async (eventType, filename) => { if (!filename) return; this.loadConfig(); if (!this.config.autoExport) return; // 确保是字符串 const fileNameStr = typeof filename === 'string' ? filename : filename + ""; const ext = path.extname(fileNameStr).toLowerCase(); if (ext === '.xlsx' || ext === '.xls') { const filePath = path.join(this.config.excelPath, fileNameStr); // 额外验证:确保是文件且存在 try { if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) { this.log(`[Excel插件] 检测到文件变更: ${fileNameStr} (${eventType})`); // 使用终极重试机制 // 重试次数增加到8,基础延迟1秒 this.processExcelFileWithRetry(filePath, 8, 1000); } } catch (err) { this.warn(`[Excel插件] 验证文件状态时出错: ${err}`); } } }); // 处理监听错误 if (this.fileWatcher && typeof this.fileWatcher.on === 'function') { this.fileWatcher.on('error', (error) => { this.error(`[Excel插件] 文件监听错误: ${error}`); // 尝试重新设置监听 setTimeout(() => { this.stopFileWatcher(); this.setupFileWatcher(); }, 15000); }); } this.log('[Excel插件] 已启动Excel目录监听(终极版)'); } catch (err) { this.error(`[Excel插件] 目录监听失败: ${err}`); // 尝试重新设置监听 setTimeout(() => { this.stopFileWatcher(); this.setupFileWatcher(); }, 20000); } } // 带重试机制处理Excel文件(自动导出) processExcelFileWithRetry(filePath, maxRetries = 8, baseDelay = 1000) { this.enqueueExport(() => this.processExcelFileWithRetryInternal(filePath, maxRetries, baseDelay)); } /** 串行执行导出,避免并发写 AutoTable.ts */ enqueueExport(task) { this.exportQueue.push(task); if (!this.isExporting) { this.runNextExport(); } } runNextExport() { const task = this.exportQueue.shift(); if (!task) { this.isExporting = false; return; } this.isExporting = true; task(); } processExcelFileWithRetryInternal(filePath, maxRetries = 8, baseDelay = 1000) { let attempt = 0; const startTime = Date.now(); const tryProcess = () => { attempt++; const elapsed = Date.now() - startTime; const delay = baseDelay * Math.min(1.5 ** (attempt - 1), 4); // 指数退避,但上限为4倍基础延迟 this.log(`[Excel插件] 处理文件 "${path.basename(filePath)}" - 尝试 ${attempt}/${maxRetries} (延迟 ${Math.round(delay)}ms, 已耗时 ${Math.round(elapsed / 1000)}s)`); setTimeout(() => { try { // 额外检查文件是否可读 const stats = fs.statSync(filePath); if (stats.size === 0) { throw new Error("文件大小为0,可能仍在写入"); } // 检查文件最后修改时间,确保不是刚被修改 const now = Date.now(); const fileAge = now - stats.mtimeMs; if (fileAge < 2000) { // 文件修改时间少于2秒,可能还在写入 throw new Error(`文件刚被修改 (${Math.round(fileAge)}ms前),可能仍在写入`); } this.processExcelFile(filePath); const totalTime = Date.now() - startTime; this.refreshAssetDatabase(); this.success(`[Excel插件] 文件 "${path.basename(filePath)}" 自动导出成功 (总耗时 ${Math.round(totalTime / 1000)}s, 尝试 ${attempt}/${maxRetries})`); this.runNextExport(); } catch (err) { // 详细记录错误 this.warn(`[Excel插件] 尝试 ${attempt} 失败: ${err.message || err}`); // 检查是否是文件锁定或权限错误 const isFileLockError = err.message && (err.message.includes('EPERM') || err.message.includes('EBUSY') || err.message.includes('permission') || err.message.includes('locked') || err.message.includes('EACCES') || err.message.includes('file size 0') || err.message.includes('刚被修改')); if (isFileLockError && attempt < maxRetries) { // 计算下一次尝试的延迟(指数退避) const nextDelay = baseDelay * Math.min(1.5 ** attempt, 4); this.warn(`[Excel插件] 文件 "${path.basename(filePath)}" 可能仍在保存中,将在 ${Math.round(nextDelay)}ms 后重试 (尝试 ${attempt + 1}/${maxRetries})`); setTimeout(tryProcess, nextDelay); } else { const totalTime = Date.now() - startTime; this.error(`[Excel插件] 文件 "${path.basename(filePath)}" 自动导出失败 (总耗时 ${Math.round(totalTime / 1000)}s): ${err}`); // 如果是文件锁定错误但已达到最大重试次数,提供具体建议 if (isFileLockError) { this.error(`[Excel插件] 建议: 确保Excel完全保存后再进行修改,或增加重试次数和延迟`); } this.runNextExport(); } } }, delay); }; tryProcess(); } // 停止文件监听(更新) stopFileWatcher() { if (this.fileWatcher) { try { // 使用类型断言确保调用close方法 this.fileWatcher.close(); this.fileWatcher = null; } catch (e) { this.warn(`[Excel插件] 停止监听时出错: ${e}`); } if (this.config.watcher) { clearTimeout(this.config.watcher); this.config.watcher = null; } this.log('[Excel插件] 已停止Excel文件监听'); } } // 生成JSON数据 generateJsonData(dataRows, headers) { const result = []; for (const row of dataRows) { if (!this.isDataRow(row, headers.fields)) { continue; } const obj = {}; for (let i = 0; i < headers.fields.length; i++) { const field = headers.fields[i]; const type = headers.types[i]; if (field) { const value = row[i] !== undefined ? row[i] : this.getDefaultValue(type); obj[field] = this.convertValue(value, type); } } result.push(obj); } return result; } /** 跳过全空行 */ isDataRow(row, fields) { if (!row || row.length === 0) { return false; } for (let i = 0; i < fields.length; i++) { const field = fields[i]; if (!field) continue; const value = row[i]; if (value !== null && value !== undefined && String(value).trim() !== '') { return true; } } return false; } /** 判断单元格是否为空 */ isEmptyValue(value) { return value === null || value === undefined || (typeof value === 'string' && value.trim() === ''); } // 根据类型获取默认值 getDefaultValue(type) { if (!type) return null; const cleanType = type.toLowerCase().trim(); switch (cleanType) { case 'int': case 'float': return 0; case 'boolean': return false; case 'int[]': case 'float[]': case 'string[]': case 'any[]': return []; case 'string': return ''; default: return ''; } } // 类型转换 convertValue(value, type) { if (this.isEmptyValue(value)) { return this.getDefaultValue(type); } const cleanType = type.toLowerCase().trim(); try { switch (cleanType) { case 'int': { const n = parseInt(value, 10); return isNaN(n) ? 0 : n; } case 'float': { const n = parseFloat(value); return isNaN(n) ? 0 : n; } case 'json': return JSON.parse(value); case 'boolean': return value.toString().toLowerCase() === 'true' || value === 1; case 'int[]': return this.parseArray(value, 'int'); case 'float[]': return this.parseArray(value, 'float'); case 'string[]': return this.parseArray(value, 'string'); case 'any[]': return this.parseArray(value, 'any'); default: return value; } } catch (e) { this.warn(`[Excel插件] 类型转换失败 [${type}]: ${value} - ${e}`); return value; } } // 解析数组 parseArray(value, targetType) { if (Array.isArray(value)) return value; // 尝试分割字符串 let items = []; if (typeof value === 'string') { items = value.split(/[,;#\s]\s*/).filter(v => v); } else { items = [value]; } return items.map(item => { if (targetType === 'any') { // 自动识别类型 if (!isNaN(item)) { return !isNaN(parseFloat(item)) ? parseFloat(item) : parseInt(item); } if (item.toLowerCase() === 'true' || item.toLowerCase() === 'false') { return item.toLowerCase() === 'true'; } return item; } // 指定类型转换 switch (targetType) { case 'int': return parseInt(item); case 'float': return parseFloat(item); case 'string': return String(item); default: return item; } }); } generateTSInterfaceStart(sheetName) { const interfaceName = `ITable${sheetName}`; const safeSheetName = `${this.makeSafeFileName(sheetName)}`; let tsContent = ` /**\n * ${safeSheetName} 配置数据\n */\n`; tsContent += ` interface ${interfaceName} {\n`; return tsContent; } // 生成TS接口 generateTSInterface(sheetName, headers) { const interfaceName = `ITable${sheetName}`; const safeSheetName = `${this.makeSafeFileName(sheetName)}`; let tsContent = ` /**\n * ${safeSheetName} 配置数据\n */\n`; tsContent += ` interface ${interfaceName} {\n`; for (let i = 0; i < headers.fields.length; i++) { const field = headers.fields[i]; const type = headers.types[i]; const description = headers.descriptions[i] || '字段说明'; if (field) { tsContent += ` /** ${description} */\n`; tsContent += ` readonly ${field}: ${this.convertToTSType(type)};\n`; } } tsContent += ` }\n`; return tsContent; } // 转换为TS类型 convertToTSType(excelType) { if (!excelType) return 'any'; const type = excelType.toLowerCase().trim(); switch (type) { case 'string': return 'string'; case 'int': case 'float': return 'number'; case 'boolean': return 'boolean'; case 'int[]': return 'number[]'; case 'float[]': return 'number[]'; case 'string[]': return 'string[]'; case 'any[]': return '(number | string | boolean)[]'; default: return 'any'; } } // 转换为PascalCase toPascalCase(str) { return str.replace(/(\w)(\w*)/g, (_, g1, g2) => g1.toUpperCase() + g2.toLowerCase()).replace(/[^a-zA-Z0-9]/g, ''); } // 创建安全的文件名 makeSafeFileName(name) { return name.replace(/[^a-zA-Z0-9_]/g, '_'); } // 日志输出 log(message) { console.log(message); } error(message) { console.error(message); } warn(message) { console.warn(message); } success(message) { console.log(message); } // 刷新资源管理器 async refreshAssetDatabase() { try { const paths = (0, MembershipSet_1.membershipFromArray)([ ...(0, MembershipSet_1.membershipToArray)(this.jsonRefreshPaths), this.config.jsonExportPath, this.config.langJsonExportPath, ]); for (const systemPath of (0, MembershipSet_1.membershipToArray)(paths)) { const dbPath = this.convertToDbPath(systemPath); if (dbPath && dbPath.startsWith('db://')) { await Editor.Message.request('asset-db', 'refresh-asset', dbPath); } } const tsDbPath = this.convertToDbPath(this.config.tsExportPath); if (tsDbPath && tsDbPath.startsWith('db://')) { await Editor.Message.request('asset-db', 'refresh-asset', tsDbPath); } this.success('[Excel插件] 资源刷新请求已发送'); } catch (err) { this.error(`[Excel插件] 资源刷新失败: ${err}`); } } // 将系统路径转换为Cocos的db路径 convertToDbPath(systemPath) { if (!systemPath) return ''; try { // 获取项目路径 const projectPath = Editor.Project.path; // 规范化路径(统一使用正斜杠) systemPath = systemPath.replace(/\\/g, '/'); const normalizedProjectPath = projectPath.replace(/\\/g, '/'); // 确保路径以/结尾 const projectPathWithSlash = normalizedProjectPath.endsWith('/') ? normalizedProjectPath : normalizedProjectPath + '/'; // 检查是否在项目目录内 if (systemPath.startsWith(projectPathWithSlash)) { // 计算相对路径 const relativePath = systemPath.substring(projectPathWithSlash.length); return `db://${relativePath}`; } // 如果路径包含assets目录,尝试直接转换 if (systemPath.includes('/assets/') || systemPath.includes('\\assets\\')) { const assetsIndex = systemPath.toLowerCase().indexOf('/assets/'); if (assetsIndex !== -1) { const relativeToAssets = systemPath.substring(assetsIndex + 1); return `db://${relativeToAssets}`; } } this.warn(`[Excel插件] 路径不在项目内,可能无法正确刷新: ${systemPath}`); return systemPath; } catch (err) { this.error(`[Excel插件] 路径转换失败: ${err}`); return systemPath; } } } exports.excelToJsonPlugin = new ExcelToJsonPlugin(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhjZWwyanNvbkFuZFRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc291cmNlL2V4Y2VsMmpzb25BbmRUcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1Q0FBeUI7QUFDekIsMkNBQTZCO0FBQzdCLHVDQUF5QjtBQUN6QixtREFNeUI7QUFFekIsK0JBQStCO0FBQy9CLGlFQUFpRTtBQUNqRSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO0FBZTdELE1BQU0sY0FBYyxHQUFxQjtJQUNyQyxTQUFTLEVBQUUsZUFBZTtJQUMxQixjQUFjLEVBQUUsNkJBQTZCO0lBQzdDLGtCQUFrQixFQUFFLHFCQUFxQjtJQUN6QyxZQUFZLEVBQUUseUJBQXlCO0lBQ3ZDLFVBQVUsRUFBRSxJQUFJO0NBQ25CLENBQUM7QUFFRixNQUFNLGlCQUFpQjtJQUF2QjtRQUNZLFdBQU0sbUNBQXNCLGNBQWMsS0FBRSxPQUFPLEVBQUUsSUFBSSxJQUFHO1FBRTVELGdCQUFXLEdBQXdCLElBQUksQ0FBQztRQUN4QyxnQkFBVyxHQUFHLEtBQUssQ0FBQztRQUNwQixnQkFBVyxHQUFtQixFQUFFLENBQUM7UUFDekMscUNBQXFDO1FBQzdCLHFCQUFnQixHQUFHLElBQUEsbUNBQW1CLEdBQVUsQ0FBQztRQTg1QnpELE9BQU87UUFDUCxhQUFRLEdBQUc7WUFDUCxnQ0FBZ0MsRUFBRSxHQUFHLEVBQUU7Z0JBQ25DLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN4QixDQUFDO1NBQ0osQ0FBQTtJQXFFTCxDQUFDO0lBdCtCRyxLQUFLLENBQUMsSUFBSTtRQUNOLE1BQU0sSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCw4QkFB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cUJBQXFCLEdBQUcsR0FBRyxDQUFDO1lBRWxDLGFBQWE7WUFDYixJQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDO2dCQUM5QyxTQUFTO2dCQUNULE1BQU0sWUFBWSxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3ZFLE9BQU8sUUFBUSxZQUFZLEVBQUUsQ0FBQztZQUNsQyxDQUFDO1lBRUQsd0JBQXdCO1lBQ3hCLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxVQUFVLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZFLE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ2pFLElBQUksV0FBVyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQ3JCLE1BQU0sZ0JBQWdCLEdBQUcsVUFBVSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBQy9ELE9BQU8sUUFBUSxnQkFBZ0IsRUFBRSxDQUFDO2dCQUN0QyxDQUFDO1lBQ0wsQ0FBQztZQUVELElBQUksQ0FBQyxJQUFJLENBQUMsK0JBQStCLFVBQVUsRUFBRSxDQUFDLENBQUM7WUFDdkQsT0FBTyxVQUFVLENBQUM7UUFDdEIsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZDLE9BQU8sVUFBVSxDQUFDO1FBQ3RCLENBQUM7SUFDTCxDQUFDO0NBQ0o7QUFFWSxRQUFBLGlCQUFpQixHQUFHLElBQUksaUJBQWlCLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcclxuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcclxuaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xyXG5pbXBvcnQge1xyXG4gICAgY3JlYXRlTWVtYmVyc2hpcFNldCxcclxuICAgIG1lbWJlcnNoaXBBZGQsXHJcbiAgICBtZW1iZXJzaGlwQ2xlYXIsXHJcbiAgICBtZW1iZXJzaGlwRnJvbUFycmF5LFxyXG4gICAgbWVtYmVyc2hpcFRvQXJyYXksXHJcbn0gZnJvbSAnLi9NZW1iZXJzaGlwU2V0JztcclxuXHJcbi8qKiDlhoXnva4geGxzeCDlupPvvIzml6DpnIAgbnBtIGluc3RhbGwgKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcclxuY29uc3QgWExTWCA9IHJlcXVpcmUocGF0aC5qb2luKF9fZGlybmFtZSwgJy4uL2xpYi94bHN4LmpzJykpO1xyXG5cclxuaW50ZXJmYWNlIFBsdWdpbkNvbmZpZ0ZpbGUge1xyXG4gICAgZXhjZWxQYXRoOiBzdHJpbmc7XHJcbiAgICBqc29uRXhwb3J0UGF0aDogc3RyaW5nO1xyXG4gICAgLyoqIOivreiogOihqCBsYW5nXyog5a+85Ye65qC555uu5b2V77yM5a6e6ZmF6Lev5b6E5Li6IGB7bGFuZ0pzb25FeHBvcnRQYXRofS9sYW5nX3h4L2NvbmZpZy9gICovXHJcbiAgICBsYW5nSnNvbkV4cG9ydFBhdGg6IHN0cmluZztcclxuICAgIHRzRXhwb3J0UGF0aDogc3RyaW5nO1xyXG4gICAgYXV0b0V4cG9ydDogYm9vbGVhbjtcclxufVxyXG5cclxuaW50ZXJmYWNlIFBsdWdpbkNvbmZpZyBleHRlbmRzIFBsdWdpbkNvbmZpZ0ZpbGUge1xyXG4gICAgd2F0Y2hlcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsO1xyXG59XHJcblxyXG5jb25zdCBERUZBVUxUX0NPTkZJRzogUGx1Z2luQ29uZmlnRmlsZSA9IHtcclxuICAgIGV4Y2VsUGF0aDogJ+mFjee9ruihqC9leGNlbExpc3QnLFxyXG4gICAganNvbkV4cG9ydFBhdGg6ICdhc3NldHMvYnVuZGxlcy9maXJzdC9jb25maWcnLFxyXG4gICAgbGFuZ0pzb25FeHBvcnRQYXRoOiAnYXNzZXRzL2J1bmRsZXMvbGFuZycsXHJcbiAgICB0c0V4cG9ydFBhdGg6ICdhc3NldHMvc2NyaXB0L2ludGVyZmFjZScsXHJcbiAgICBhdXRvRXhwb3J0OiB0cnVlLFxyXG59O1xyXG5cclxuY2xhc3MgRXhjZWxUb0pzb25QbHVnaW4ge1xyXG4gICAgcHJpdmF0ZSBjb25maWc6IFBsdWdpbkNvbmZpZyA9IHsgLi4uREVGQVVMVF9DT05GSUcsIHdhdGNoZXI6IG51bGwgfTtcclxuXHJcbiAgICBwcml2YXRlIGZpbGVXYXRjaGVyOiBmcy5GU1dhdGNoZXIgfCBudWxsID0gbnVsbDtcclxuICAgIHByaXZhdGUgaXNFeHBvcnRpbmcgPSBmYWxzZTtcclxuICAgIHByaXZhdGUgZXhwb3J0UXVldWU6ICgoKSA9PiB2b2lkKVtdID0gW107XHJcbiAgICAvKiog5pys5qyh5a+85Ye65YaZ5YWl6L+H55qEIEpTT04g55uu5b2V77yM55So5LqO5Yi35pawIGFzc2V0LWRiICovXHJcbiAgICBwcml2YXRlIGpzb25SZWZyZXNoUGF0aHMgPSBjcmVhdGVNZW1iZXJzaGlwU2V0PHN0cmluZz4oKTtcclxuXHJcbiAgICBhc3luYyBsb2FkKCkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuZXhwb3J0QWxsRXhjZWwoKTtcclxuICAgICAgICB0aGlzLnNldHVwRmlsZVdhdGNoZXIoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiog5o+S5Lu25qC555uu5b2V77yIY29uZmlnLmpzb24g5omA5Zyo55uu5b2V77yJICovXHJcbiAgICBwcml2YXRlIGdldFBsdWdpblJvb3QoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIOWwhiBjb25maWcuanNvbiDkuK3nmoTnm7jlr7not6/lvoTop6PmnpDkuLrnu53lr7not6/lvoTvvIjnm7jlr7npobnnm67moLnnm67lvZXvvIkgKi9cclxuICAgIHByaXZhdGUgcmVzb2x2ZVByb2plY3RQYXRoKHJlbGF0aXZlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCBwcm9qZWN0Um9vdCA9IEVkaXRvci5Qcm9qZWN0LnBhdGg7XHJcbiAgICAgICAgcmV0dXJuIHBhdGgubm9ybWFsaXplKHBhdGguam9pbihwcm9qZWN0Um9vdCwgcmVsYXRpdmVQYXRoLnJlcGxhY2UoL1xcXFwvZywgJy8nKS5yZXBsYWNlKC9eXFwuXFwvLywgJycpKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIOWIpOaWreW3peS9nOihqOaYr+WQpumcgOimgeWvvOWHuu+8muagvOW8j+S4uiBcIuaPj+i/sHxqc29u5paH5Lu25ZCNXCLvvIzkuJTpnZ7pu5jorqQgU2hlZXQgKi9cclxuICAgIHByaXZhdGUgaXNFeHBvcnRhYmxlU2hlZXQoc2hlZXROYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAoIXNoZWV0TmFtZSB8fCBzaGVldE5hbWUuc3RhcnRzV2l0aCgnU2hlZXQnKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHBhcnRzID0gc2hlZXROYW1lLnNwbGl0KCd8Jyk7XHJcbiAgICAgICAgcmV0dXJuIHBhcnRzLmxlbmd0aCA+PSAyICYmIHBhcnRzWzFdLnRyaW0oKS5sZW5ndGggPiAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiDojrflj5blt6XkvZzooajlr7zlh7rnmoQganNvbiDmlofku7blkI3vvIh8IOWQjuesrOS4gOaute+8iSAqL1xyXG4gICAgcHJpdmF0ZSBnZXRTaGVldEV4cG9ydE5hbWUoc2hlZXROYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiBzaGVldE5hbWUuc3BsaXQoJ3wnKVsxXS50cmltKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIOivreiogOihqO+8mmxhbmdfY24gLyBsYW5nX2VuIOKApiAqL1xyXG4gICAgcHJpdmF0ZSBpc0xhbmdFeHBvcnROYW1lKGV4cG9ydE5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiAvXmxhbmdfW2Etel17Mn0kL2kudGVzdChleHBvcnROYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiog6Kej5p6QIEpTT04g5a+85Ye655uu5b2V77yI6K+t6KiA6KGo6L+b5a+55bqU6K+t6KiA5YyFIGJ1bmRsZe+8iSAqL1xyXG4gICAgcHJpdmF0ZSByZXNvbHZlSnNvbkV4cG9ydERpcihleHBvcnROYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmICh0aGlzLmlzTGFuZ0V4cG9ydE5hbWUoZXhwb3J0TmFtZSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHBhdGguam9pbih0aGlzLmNvbmZpZy5sYW5nSnNvbkV4cG9ydFBhdGgsIGV4cG9ydE5hbWUsICdjb25maWcnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmpzb25FeHBvcnRQYXRoO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiDmuIXnkIYgZmlyc3Qg5Lit6YGX55WZ55qE6K+t6KiA6KGoIEpTT07vvIjljoblj7Lot6/lvoTvvIkgKi9cclxuICAgIHByaXZhdGUgcmVtb3ZlU3RhbGVMYW5nSnNvbkluRmlyc3QoanNvbkZpbGVOYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBzdGFsZVBhdGggPSBwYXRoLmpvaW4odGhpcy5jb25maWcuanNvbkV4cG9ydFBhdGgsIGpzb25GaWxlTmFtZSk7XHJcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoc3RhbGVQYXRoKSkge1xyXG4gICAgICAgICAgICBmcy51bmxpbmtTeW5jKHN0YWxlUGF0aCk7XHJcbiAgICAgICAgICAgIHRoaXMubG9nKGBbRXhjZWzmj5Lku7ZdIOW3suWIoOmZpCBmaXJzdCDkuK3pgZfnlZnor63oqIDooag6ICR7anNvbkZpbGVOYW1lfWApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBzdGFsZU1ldGEgPSBgJHtzdGFsZVBhdGh9Lm1ldGFgO1xyXG4gICAgICAgIGlmIChmcy5leGlzdHNTeW5jKHN0YWxlTWV0YSkpIHtcclxuICAgICAgICAgICAgZnMudW5saW5rU3luYyhzdGFsZU1ldGEpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB1bmxvYWQoKSB7XHJcbiAgICAgICAgdGhpcy5sb2coJ1tFeGNlbOaPkuS7tl0g5o+S5Lu25bey5Y246L29Jyk7XHJcbiAgICAgICAgdGhpcy5zdG9wRmlsZVdhdGNoZXIoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiog5LuO5o+S5Lu25qC555uu5b2VIGNvbmZpZy5qc29uIOWKoOi9vemFjee9ru+8jOi3r+W+hOebuOWvuemhueebruagueebruW9lSAqL1xyXG4gICAgbG9hZENvbmZpZygpIHtcclxuICAgICAgICBjb25zdCBjb25maWdQYXRoID0gcGF0aC5qb2luKHRoaXMuZ2V0UGx1Z2luUm9vdCgpLCAnY29uZmlnLmpzb24nKTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoY29uZmlnUGF0aCkpIHtcclxuICAgICAgICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMoY29uZmlnUGF0aCwgSlNPTi5zdHJpbmdpZnkoREVGQVVMVF9DT05GSUcsIG51bGwsIDQpLCAndXRmLTgnKTtcclxuICAgICAgICAgICAgICAgIHRoaXMud2FybihgW0V4Y2Vs5o+S5Lu2XSDlt7LliJvlu7rpu5jorqTphY3nva7mlofku7Y6ICR7Y29uZmlnUGF0aH1gKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgcmF3ID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoY29uZmlnUGF0aCwgJ3V0Zi04JykpIGFzIFBhcnRpYWw8UGx1Z2luQ29uZmlnRmlsZT47XHJcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZCA9IHsgLi4uREVGQVVMVF9DT05GSUcsIC4uLnJhdyB9O1xyXG5cclxuICAgICAgICAgICAgdGhpcy5jb25maWcuZXhjZWxQYXRoID0gdGhpcy5yZXNvbHZlUHJvamVjdFBhdGgobWVyZ2VkLmV4Y2VsUGF0aCk7XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLmpzb25FeHBvcnRQYXRoID0gdGhpcy5yZXNvbHZlUHJvamVjdFBhdGgobWVyZ2VkLmpzb25FeHBvcnRQYXRoKTtcclxuICAgICAgICAgICAgdGhpcy5jb25maWcubGFuZ0pzb25FeHBvcnRQYXRoID0gdGhpcy5yZXNvbHZlUHJvamVjdFBhdGgoXHJcbiAgICAgICAgICAgICAgICBtZXJnZWQubGFuZ0pzb25FeHBvcnRQYXRoID8/IERFRkFVTFRfQ09ORklHLmxhbmdKc29uRXhwb3J0UGF0aCxcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgdGhpcy5jb25maWcudHNFeHBvcnRQYXRoID0gdGhpcy5yZXNvbHZlUHJvamVjdFBhdGgobWVyZ2VkLnRzRXhwb3J0UGF0aCk7XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLmF1dG9FeHBvcnQgPSBtZXJnZWQuYXV0b0V4cG9ydDtcclxuXHJcbiAgICAgICAgICAgIHRoaXMubG9nKCdbRXhjZWzmj5Lku7ZdIOmFjee9ruW3suWKoOi9vSAoZXh0ZW5zaW9ucy9leGNlbC10by1qc29uLXRzL2NvbmZpZy5qc29uKScpO1xyXG4gICAgICAgICAgICB0aGlzLmxvZyhgW0V4Y2Vs5o+S5Lu2XSBleGNlbFBhdGg6ICR7dGhpcy5jb25maWcuZXhjZWxQYXRofWApO1xyXG4gICAgICAgICAgICB0aGlzLmxvZyhgW0V4Y2Vs5o+S5Lu2XSBqc29uUGF0aDogJHt0aGlzLmNvbmZpZy5qc29uRXhwb3J0UGF0aH1gKTtcclxuICAgICAgICAgICAgdGhpcy5sb2coYFtFeGNlbOaPkuS7tl0gbGFuZ0pzb25QYXRoOiAke3RoaXMuY29uZmlnLmxhbmdKc29uRXhwb3J0UGF0aH1gKTtcclxuICAgICAgICAgICAgdGhpcy5sb2coYFtFeGNlbOaPkuS7tl0gdHNQYXRoOiAke3RoaXMuY29uZmlnLnRzRXhwb3J0UGF0aH1gKTtcclxuICAgICAgICAgICAgdGhpcy5sb2coYFtFeGNlbOaPkuS7tl0gYXV0b0V4cG9ydDogJHt0aGlzLmNvbmZpZy5hdXRvRXhwb3J0fWApO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICB0aGlzLmVycm9yKGBbRXhjZWzmj5Lku7ZdIOWKoOi9vemFjee9ruWksei0pSAoJHtjb25maWdQYXRofSk6ICR7ZXJyfWApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyDmiYvliqjlr7zlh7pcclxuICAgIGV4cG9ydE1hbnVhbCgpIHtcclxuICAgICAgICB0aGlzLmV4cG9ydEFsbEV4Y2VsKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5a+85Ye65omA5pyJRXhjZWzvvIjlop7lvLrlgaXlo67mgKfvvIlcclxuICAgIGFzeW5jIGV4cG9ydEFsbEV4Y2VsKCkge1xyXG4gICAgICAgIHRoaXMubG9hZENvbmZpZygpO1xyXG5cclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLmV4Y2VsUGF0aCkge1xyXG4gICAgICAgICAgICB0aGlzLmVycm9yKCdbRXhjZWzmj5Lku7ZdIEV4Y2Vs55uu5b2V6Lev5b6E5pyq6YWN572uJyk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyh0aGlzLmNvbmZpZy5leGNlbFBhdGgpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IoYFtFeGNlbOaPkuS7tl0gRXhjZWznm67lvZXkuI3lrZjlnKg6ICR7dGhpcy5jb25maWcuZXhjZWxQYXRofWApO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBtZW1iZXJzaGlwQ2xlYXIodGhpcy5qc29uUmVmcmVzaFBhdGhzKTtcclxuXHJcbiAgICAgICAgICAgIC8vIOehruS/neWvvOWHuuebruW9leWtmOWcqFxyXG4gICAgICAgICAgICBpZiAodGhpcy5jb25maWcuanNvbkV4cG9ydFBhdGggJiYgIWZzLmV4aXN0c1N5bmModGhpcy5jb25maWcuanNvbkV4cG9ydFBhdGgpKSB7XHJcbiAgICAgICAgICAgICAgICBmcy5ta2RpclN5bmModGhpcy5jb25maWcuanNvbkV4cG9ydFBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5sYW5nSnNvbkV4cG9ydFBhdGggJiYgIWZzLmV4aXN0c1N5bmModGhpcy5jb25maWcubGFuZ0pzb25FeHBvcnRQYXRoKSkge1xyXG4gICAgICAgICAgICAgICAgZnMubWtkaXJTeW5jKHRoaXMuY29uZmlnLmxhbmdKc29uRXhwb3J0UGF0aCwgeyByZWN1cnNpdmU6IHRydWUgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLnRzRXhwb3J0UGF0aCAmJiAhZnMuZXhpc3RzU3luYyh0aGlzLmNvbmZpZy50c0V4cG9ydFBhdGgpKSB7XHJcbiAgICAgICAgICAgICAgICBmcy5ta2RpclN5bmModGhpcy5jb25maWcudHNFeHBvcnRQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8g6I635Y+W55uu5b2V5Lit5omA5pyJRXhjZWzmlofku7ZcclxuICAgICAgICAgICAgY29uc3QgZXhjZWxGaWxlcyA9IHRoaXMuZ2V0RXhjZWxGaWxlc0luRGlyZWN0b3J5KHRoaXMuY29uZmlnLmV4Y2VsUGF0aCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoZXhjZWxGaWxlcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMud2FybihgW0V4Y2Vs5o+S5Lu2XSDnm67lvZXkuK3msqHmnInmib7liLBFeGNlbOaWh+S7tjogJHt0aGlzLmNvbmZpZy5leGNlbFBhdGh9YCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMubG9nKGBbRXhjZWzmj5Lku7ZdIOaJvuWIsCAke2V4Y2VsRmlsZXMubGVuZ3RofSDkuKpFeGNlbOaWh+S7tmApO1xyXG5cclxuICAgICAgICAgICAgbGV0IHN1Y2Nlc3NDb3VudCA9IDA7XHJcbiAgICAgICAgICAgIGxldCBlcnJvckNvdW50ID0gMDtcclxuXHJcbiAgICAgICAgICAgIC8vIOWkhOeQhuavj+S4qkV4Y2Vs5paH5Lu2XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgZXhjZWxGaWxlIG9mIGV4Y2VsRmlsZXMpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzRXhjZWxGaWxlKGV4Y2VsRmlsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NvdW50Kys7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yKGBbRXhjZWzmj5Lku7ZdIOWkhOeQhuaWh+S7tuWksei0pSAke3BhdGguYmFzZW5hbWUoZXhjZWxGaWxlKX06ICR7ZXJyfWApO1xyXG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ291bnQrKztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHN1Y2Nlc3NDb3VudCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVmcmVzaEFzc2V0RGF0YWJhc2UoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3VjY2VzcyhgW0V4Y2Vs5o+S5Lu2XSDlr7zlh7rlrozmiJDvvIzmiJDlip/lpITnkIYgJHtzdWNjZXNzQ291bnR9IOS4quaWh+S7tu+8jOWksei0pSAke2Vycm9yQ291bnR9IOS4qmApO1xyXG5cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IoYFtFeGNlbOaPkuS7tl0g5a+85Ye65aSx6LSl77yM5rKh5pyJ5oiQ5Yqf5aSE55CG5Lu75L2V5paH5Lu2YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvcihgW0V4Y2Vs5o+S5Lu2XSDlr7zlh7rlpLHotKU6ICR7ZXJyfWApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG4gICAgLy8g6I635Y+W55uu5b2V5Lit55qE5omA5pyJRXhjZWzmlofku7ZcclxuICAgIGdldEV4Y2VsRmlsZXNJbkRpcmVjdG9yeShkaXJQYXRoOiBzdHJpbmcpOiBzdHJpbmdbXSB7XHJcbiAgICAgICAgcmV0dXJuIGZzLnJlYWRkaXJTeW5jKGRpclBhdGgpXHJcbiAgICAgICAgICAgIC5maWx0ZXIoZmlsZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyDov4fmu6TpmpDol4/mlofku7bvvIjku6XngrnlvIDlpLTnmoTmlofku7bvvIlcclxuICAgICAgICAgICAgICAgIGlmIChmaWxlLnN0YXJ0c1dpdGgoJy4nKSB8fCBmaWxlLnN0YXJ0c1dpdGgoJ34nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnN0IGV4dCA9IHBhdGguZXh0bmFtZShmaWxlKS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIChleHQgPT09ICcueGxzeCcgfHwgZXh0ID09PSAnLnhscycpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgZnMuc3RhdFN5bmMocGF0aC5qb2luKGRpclBhdGgsIGZpbGUpKS5pc0ZpbGUoKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLm1hcChmaWxlID0+IHBhdGguam9pbihkaXJQYXRoLCBmaWxlKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5aSE55CG5Y2V5LiqRXhjZWzmlofku7ZcclxuICAgIHByb2Nlc3NFeGNlbEZpbGUoZmlsZVBhdGg6IHN0cmluZykge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIC8vIOWuieWFqOivu+WPluaJk+W8gOeKtuaAgeeahEV4Y2Vs5paH5Lu2XHJcbiAgICAgICAgICAgIGNvbnN0IHdvcmtib29rID0gdGhpcy5yZWFkRXhjZWxTYWZlbHkoZmlsZVBhdGgpO1xyXG4gICAgICAgICAgICBjb25zdCBzaGVldE5hbWVzID0gd29ya2Jvb2suU2hlZXROYW1lcztcclxuXHJcbiAgICAgICAgICAgIC8vIOWvvOWHuuavj+S4quW3peS9nOihqFxyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNoZWV0TmFtZSBvZiBzaGVldE5hbWVzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNFeHBvcnRhYmxlU2hlZXQoc2hlZXROYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5leHBvcnRTaGVldCh3b3JrYm9vaywgc2hlZXROYW1lLCBmaWxlUGF0aCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDlpITnkIbmlofku7YgJHtwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKX0g5aSx6LSlOiAke2Vycn1gKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIOS7jiBidWZmZXIg6Kej5p6QIEV4Y2Vs77yM6YG/5YWNIHJlYWRGaWxlIOWcqCBXaW5kb3dzIOS4reaWh+i3r+W+hOS4i+Wksei0pSAqL1xyXG4gICAgcHJpdmF0ZSBwYXJzZUV4Y2VsQnVmZmVyKGJ1ZmZlcjogQnVmZmVyKTogYW55IHtcclxuICAgICAgICByZXR1cm4gWExTWC5yZWFkKGJ1ZmZlciwgeyB0eXBlOiAnYnVmZmVyJyB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKiog6K+75Y+WIEV4Y2Vs77ya5LyY5YWI55u05o6l6K+777yM5aSx6LSl5pe25aSN5Yi25YiwIEFTQ0lJIOS4tOaXtuaWh+S7tuWGjeivuyAqL1xyXG4gICAgcmVhZEV4Y2VsU2FmZWx5KGZpbGVQYXRoOiBzdHJpbmcpOiBhbnkge1xyXG4gICAgICAgIC8vIDEuIOebtOaOpeivu+WPlu+8iOaWh+S7tuacquWNoOeUqOaXtuacgOW/q++8iVxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCk7XHJcbiAgICAgICAgICAgIGlmIChidWZmZXIubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VFeGNlbEJ1ZmZlcihidWZmZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBjYXRjaCAoZGlyZWN0RXJyKSB7XHJcbiAgICAgICAgICAgIHRoaXMud2FybihgW0V4Y2Vs5o+S5Lu2XSDnm7TmjqXor7vlj5blpLHotKXvvIzlsJ3or5XlpI3liLblkI7or7vlj5Y6ICR7cGF0aC5iYXNlbmFtZShmaWxlUGF0aCl9ICgke2RpcmVjdEVycn0pYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyAyLiDlpI3liLbliLDnuq8gQVNDSUkg5Li05pe26Lev5b6E77yI6YG/5YWN5Lit5paH5paH5Lu25ZCN5a+86Ie0IHhsc3gg5bqT5peg5rOV6K6/6Zeu77yJXHJcbiAgICAgICAgY29uc3QgdGVtcFBhdGggPSBwYXRoLmpvaW4ob3MudG1wZGlyKCksIGBleGNlbC10ZW1wLSR7RGF0ZS5ub3coKX0tJHtwcm9jZXNzLnBpZH0ueGxzeGApO1xyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBmcy5jb3B5RmlsZVN5bmMoZmlsZVBhdGgsIHRlbXBQYXRoKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHRlbXBTdGF0cyA9IGZzLnN0YXRTeW5jKHRlbXBQYXRoKTtcclxuICAgICAgICAgICAgaWYgKHRlbXBTdGF0cy5zaXplID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ+S4tOaXtuaWh+S7tuWkp+Wwj+S4ujDvvIzlpI3liLblj6/og73mnKrlrozmiJAnKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gZnMucmVhZEZpbGVTeW5jKHRlbXBQYXRoKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VFeGNlbEJ1ZmZlcihidWZmZXIpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg6K+75Y+WRXhjZWzlpLHotKU6ICR7ZXJyLm1lc3NhZ2UgfHwgZXJyfWApO1xyXG4gICAgICAgIH0gZmluYWxseSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyh0ZW1wUGF0aCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBmcy51bmxpbmtTeW5jKHRlbXBQYXRoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy53YXJuKGBbRXhjZWzmj5Lku7ZdIOaXoOazleWIoOmZpOS4tOaXtuaWh+S7tjogJHt0ZW1wUGF0aH0gLSAke2V9YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5a+85Ye65Y2V5Liq5bel5L2c6KGoXHJcbiAgICBleHBvcnRTaGVldCh3b3JrYm9vazogYW55LCBzaGVldE5hbWU6IHN0cmluZywgZmlsZVBhdGg6IHN0cmluZykge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHdvcmtzaGVldCA9IHdvcmtib29rLlNoZWV0c1tzaGVldE5hbWVdO1xyXG4gICAgICAgICAgICBjb25zdCBqc29uRGF0YSA9IFhMU1gudXRpbHMuc2hlZXRfdG9fanNvbih3b3Jrc2hlZXQsIHsgaGVhZGVyOiAxIH0pO1xyXG5cclxuICAgICAgICAgICAgLy8g5qOA5p+l5piv5ZCm5pyJ6Laz5aSf55qE6KGo5aS06KGM77yI6Iez5bCRM+ihjO+8muWtl+auteWQjeOAgeexu+Wei+OAgeivtOaYju+8iVxyXG4gICAgICAgICAgICBpZiAoanNvbkRhdGEubGVuZ3RoIDwgMykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy53YXJuKGBbRXhjZWzmj5Lku7ZdIOW3peS9nOihqCBcIiR7c2hlZXROYW1lfVwiIOaVsOaNruS4jei2s++8jOi3s+i/h+WvvOWHuiAo5paH5Lu2OiAke3BhdGguYmFzZW5hbWUoZmlsZVBhdGgpfSnnmoQke3NoZWV0TmFtZX1gKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzRXhwb3J0YWJsZVNoZWV0KHNoZWV0TmFtZSkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMud2FybihgW0V4Y2Vs5o+S5Lu2XSDlt6XkvZzooaggXCIke3NoZWV0TmFtZX1cIiDlkI3np7DmoLzlvI/plJnor6/vvIzot7Pov4flr7zlh7ogKOaWh+S7tjogJHtwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKX0pYCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHNOYW1lID0gdGhpcy5nZXRTaGVldEV4cG9ydE5hbWUoc2hlZXROYW1lKTtcclxuXHJcbiAgICAgICAgICAgIC8vIOaPkOWPluihqOWktOS/oeaBr1xyXG4gICAgICAgICAgICBjb25zdCBoZWFkZXJzID0ge1xyXG4gICAgICAgICAgICAgICAgZmllbGRzOiBqc29uRGF0YVswXSxcclxuICAgICAgICAgICAgICAgIHR5cGVzOiBqc29uRGF0YVsxXSxcclxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uczoganNvbkRhdGFbMl1cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8vIOS7juesrDTooYzlvIDlp4vmmK/mlbDmja5cclxuICAgICAgICAgICAgY29uc3QgZGF0YVJvd3MgPSBqc29uRGF0YS5zbGljZSgzKSBhcyBhbnlbXVtdO1xyXG5cclxuICAgICAgICAgICAgLy8g55Sf5oiQSlNPTuaVsOaNrlxyXG4gICAgICAgICAgICBjb25zdCBqc29uUmVzdWx0ID0gdGhpcy5nZW5lcmF0ZUpzb25EYXRhKGRhdGFSb3dzLCBoZWFkZXJzKTtcclxuXHJcbiAgICAgICAgICAgIC8vIOeUn+aIkFRT5o6l5Y+jXHJcbiAgICAgICAgICAgIGNvbnN0IHRzSW50ZXJmYWNlID0gdGhpcy5nZW5lcmF0ZVRTSW50ZXJmYWNlKHNOYW1lLCBoZWFkZXJzKTtcclxuXHJcbiAgICAgICAgICAgIC8vIOeUn+aIkOaWh+S7tuWQjVxyXG4gICAgICAgICAgICBjb25zdCBzYWZlU2hlZXROYW1lID0gdGhpcy5tYWtlU2FmZUZpbGVOYW1lKHNOYW1lKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGpzb25GaWxlTmFtZSA9IGAke3NhZmVTaGVldE5hbWV9Lmpzb25gO1xyXG4gICAgICAgICAgICAvL2NvbnN0IHRzRmlsZU5hbWUgPSBgSVRhYmxlJHtzYWZlU2hlZXROYW1lfS50c2A7XHJcbiAgICAgICAgICAgIGNvbnN0IHRzRmlsZU5hbWUgPSBgQXV0b1RhYmxlLnRzYDtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGpzb25FeHBvcnREaXIgPSB0aGlzLnJlc29sdmVKc29uRXhwb3J0RGlyKHNOYW1lKTtcclxuICAgICAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGpzb25FeHBvcnREaXIpKSB7XHJcbiAgICAgICAgICAgICAgICBmcy5ta2RpclN5bmMoanNvbkV4cG9ydERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIOWGmeWFpUpTT07mlofku7ZcclxuICAgICAgICAgICAgaWYgKGpzb25FeHBvcnREaXIpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGpzb25QYXRoID0gcGF0aC5qb2luKGpzb25FeHBvcnREaXIsIGpzb25GaWxlTmFtZSk7XHJcbiAgICAgICAgICAgICAgICBmcy53cml0ZUZpbGVTeW5jKGpzb25QYXRoLCBKU09OLnN0cmluZ2lmeShqc29uUmVzdWx0LCBudWxsLCA0KSwgJ3V0Zi04Jyk7XHJcbiAgICAgICAgICAgICAgICBtZW1iZXJzaGlwQWRkKHRoaXMuanNvblJlZnJlc2hQYXRocywganNvbkV4cG9ydERpcik7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0xhbmdFeHBvcnROYW1lKHNOYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlU3RhbGVMYW5nSnNvbkluRmlyc3QoanNvbkZpbGVOYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8g5YaZ5YWlVFPmlofku7ZcclxuICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLnRzRXhwb3J0UGF0aCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdHNQYXRoID0gcGF0aC5qb2luKHRoaXMuY29uZmlnLnRzRXhwb3J0UGF0aCwgdHNGaWxlTmFtZSk7XHJcbiAgICAgICAgICAgICAgICBsZXQgdHNDb250ZW50ID0gXCJcIjtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmModHNQYXRoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0c0NvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmModHNQYXRoLCAndXRmLTgnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLndhcm4oYFtFeGNlbOaPkuS7tl0g6K+75Y+WVFPmlofku7blpLHotKU6ICR7ZXJyfWApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRzQ29udGVudCA9PSBcIlwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHNDb250ZW50ID0gXCJkZWNsYXJlIGdsb2JhbCB7XFxuXFxufVxcbmV4cG9ydCB7IH07XCI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5leHRyYWN0RnVsbEludGVyZmFjZUJsb2NrKHRzQ29udGVudCwgXCJJVGFibGVcIiArIHNOYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRzQ29udGVudCA9IHRoaXMucmVwbGFjZUludGVyZmFjZUJsb2NrKHRzQ29udGVudCwgXCJJVGFibGVcIiArIHNOYW1lLCB0c0ludGVyZmFjZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRzQ29udGVudCA9IHRzQ29udGVudC5yZXBsYWNlKC9cXH1cXHI/XFxuZXhwb3J0IFxceyBcXH07JC8sIHRzSW50ZXJmYWNlICsgXCJ9XFxuZXhwb3J0IHsgfTtcIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0c0NvbnRlbnQgPSB0aGlzLm5vcm1hbGl6ZUF1dG9UYWJsZUJsYW5rTGluZXModHNDb250ZW50KTtcclxuICAgICAgICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmModHNQYXRoLCB0c0NvbnRlbnQsICd1dGYtOCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg5bel5L2c6KGoIFwiJHtzaGVldE5hbWV9XCIg5a+85Ye65aSx6LSlICjmlofku7Y6ICR7cGF0aC5iYXNlbmFtZShmaWxlUGF0aCl9KTogJHtlcnJ9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog6L2s5LmJ5q2j5YiZ54m55q6K5a2X56ymXHJcbiAgICAgKi9cclxuICAgIGVzY2FwZVJlZ0V4cChzdHI6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgJ1xcXFwkJicpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog57K+5YeG5p+l5om+5o6l5Y+j5aOw5piO6KGM77yI5YWo5a2X5Yy56YWN77yJXHJcbiAgICAgKi9cclxuICAgIGZpbmRJbnRlcmZhY2VEZWNsYXJhdGlvbkxpbmUoZmlsZUNvbnRlbnQ6IHN0cmluZywgaW50ZXJmYWNlTmFtZTogc3RyaW5nKToge1xyXG4gICAgICAgIGxpbmVTdGFydDogbnVtYmVyO1xyXG4gICAgICAgIGxpbmVFbmQ6IG51bWJlcjtcclxuICAgICAgICBsaW5lQ29udGVudDogc3RyaW5nO1xyXG4gICAgfSB8IG51bGwge1xyXG4gICAgICAgIC8vIOS9v+eUqOWNleivjei+ueeVjCBcXGIg56Gu5L+d5YWo5a2X5Yy56YWNXHJcbiAgICAgICAgY29uc3QgcmVnZXggPSBuZXcgUmVnRXhwKFxyXG4gICAgICAgICAgICBgXFxcXGJpbnRlcmZhY2VcXFxccyske3RoaXMuZXNjYXBlUmVnRXhwKGludGVyZmFjZU5hbWUpfVxcXFxiKD86XFxcXHMqPFtePl0qPik/XFxcXHMqW1xcXFx7XFxcXG5dYCxcclxuICAgICAgICAgICAgJ2cnXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgbGV0IG1hdGNoO1xyXG4gICAgICAgIHdoaWxlICgobWF0Y2ggPSByZWdleC5leGVjKGZpbGVDb250ZW50KSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgLy8g5om+5Yiw5Yy56YWN5L2N572u77yM56Gu5a6a5a6M5pW06KGMXHJcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoU3RhcnQgPSBtYXRjaC5pbmRleDtcclxuXHJcbiAgICAgICAgICAgIC8vIOWQkeWJjeaJvuWIsOihjOW8gOWni1xyXG4gICAgICAgICAgICBjb25zdCBsaW5lU3RhcnQgPSBmaWxlQ29udGVudC5sYXN0SW5kZXhPZignXFxuJywgbWF0Y2hTdGFydCAtIDEpICsgMTtcclxuXHJcbiAgICAgICAgICAgIC8vIOWQkeWQjuaJvuWIsOihjOe7k+adn1xyXG4gICAgICAgICAgICBjb25zdCBsaW5lRW5kID0gZmlsZUNvbnRlbnQuaW5kZXhPZignXFxuJywgbWF0Y2hTdGFydCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGFjdHVhbExpbmVFbmQgPSBsaW5lRW5kID09PSAtMSA/IGZpbGVDb250ZW50Lmxlbmd0aCA6IGxpbmVFbmQ7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBsaW5lQ29udGVudCA9IGZpbGVDb250ZW50LnN1YnN0cmluZyhsaW5lU3RhcnQsIGFjdHVhbExpbmVFbmQpO1xyXG5cclxuICAgICAgICAgICAgLy8g6aqM6K+B77ya56Gu5L+d6L+Z5LiA6KGM56Gu5a6e5piv5oiR5Lus55qE55uu5qCH5o6l5Y+jXHJcbiAgICAgICAgICAgIGlmIChsaW5lQ29udGVudC50cmltKCkuc3RhcnRzV2l0aChgaW50ZXJmYWNlICR7aW50ZXJmYWNlTmFtZX1gKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBsaW5lU3RhcnQsXHJcbiAgICAgICAgICAgICAgICAgICAgbGluZUVuZDogYWN0dWFsTGluZUVuZCxcclxuICAgICAgICAgICAgICAgICAgICBsaW5lQ29udGVudFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDmj5Dlj5blrozmlbTnmoTmjqXlj6PlnZfvvIjljIXmi6zkuIrmlrnms6jph4rvvIlcclxuICAgICAqL1xyXG4gICAgZXh0cmFjdEZ1bGxJbnRlcmZhY2VCbG9jayhmaWxlQ29udGVudDogc3RyaW5nLCBpbnRlcmZhY2VOYW1lOiBzdHJpbmcpOiB7XHJcbiAgICAgICAgc3RhcnQ6IG51bWJlcjtcclxuICAgICAgICBlbmQ6IG51bWJlcjtcclxuICAgICAgICBjb250ZW50OiBzdHJpbmc7XHJcbiAgICB9IHwgbnVsbCB7XHJcbiAgICAgICAgY29uc3QgaW50ZXJmYWNlTGluZSA9IHRoaXMuZmluZEludGVyZmFjZURlY2xhcmF0aW9uTGluZShmaWxlQ29udGVudCwgaW50ZXJmYWNlTmFtZSk7XHJcbiAgICAgICAgaWYgKCFpbnRlcmZhY2VMaW5lKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gPT09IOWQkeWJjeafpeaJvui/nue7reeahOazqOmHiuWdlyA9PT1cclxuICAgICAgICBsZXQgYmxvY2tTdGFydCA9IGludGVyZmFjZUxpbmUubGluZVN0YXJ0O1xyXG4gICAgICAgIGxldCBjdXJyZW50UG9zID0gaW50ZXJmYWNlTGluZS5saW5lU3RhcnQ7XHJcblxyXG4gICAgICAgIHdoaWxlIChjdXJyZW50UG9zID4gMCkge1xyXG4gICAgICAgICAgICBjb25zdCBwcmV2TGluZUVuZCA9IGN1cnJlbnRQb3MgLSAxO1xyXG4gICAgICAgICAgICBjb25zdCBwcmV2TGluZVN0YXJ0ID0gZmlsZUNvbnRlbnQubGFzdEluZGV4T2YoJ1xcbicsIHByZXZMaW5lRW5kIC0gMSkgKyAxO1xyXG4gICAgICAgICAgICBjb25zdCBwcmV2TGluZSA9IGZpbGVDb250ZW50LnN1YnN0cmluZyhwcmV2TGluZVN0YXJ0LCBwcmV2TGluZUVuZCkudHJpbSgpO1xyXG5cclxuICAgICAgICAgICAgLy8g5qOA5p+l5piv5ZCm5Li65rOo6YeK6KGM5oiW56m66KGMXHJcbiAgICAgICAgICAgIGlmIChwcmV2TGluZSA9PT0gJycgfHxcclxuICAgICAgICAgICAgICAgIHByZXZMaW5lLnN0YXJ0c1dpdGgoJy8vJykgfHxcclxuICAgICAgICAgICAgICAgIHByZXZMaW5lLnN0YXJ0c1dpdGgoJy8qJykgfHxcclxuICAgICAgICAgICAgICAgIHByZXZMaW5lLnN0YXJ0c1dpdGgoJyonKSkge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudFBvcyA9IHByZXZMaW5lU3RhcnQ7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBibG9ja1N0YXJ0ID0gY3VycmVudFBvcztcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoY3VycmVudFBvcyA9PT0gMCkge1xyXG4gICAgICAgICAgICBibG9ja1N0YXJ0ID0gMDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vID09PSDlkJHlkI7mn6Xmib7mjqXlj6PkvZPnu5PmnZ8gPT09XHJcbiAgICAgICAgLy8g5om+5YiwIGludGVyZmFjZSDooYzkuK3nmoTlvIDmi6zlj7fkvY3nva5cclxuICAgICAgICBjb25zdCBvcGVuQnJhY2VJbmRleCA9IGludGVyZmFjZUxpbmUubGluZUNvbnRlbnQuaW5kZXhPZigneycpO1xyXG4gICAgICAgIGxldCBzdGFydFBvcyA9IGludGVyZmFjZUxpbmUubGluZVN0YXJ0O1xyXG4gICAgICAgIGxldCBicmFjZUNvdW50ID0gMDtcclxuXHJcbiAgICAgICAgaWYgKG9wZW5CcmFjZUluZGV4ICE9PSAtMSkge1xyXG4gICAgICAgICAgICAvLyDlvIDmi6zlj7flnKjlkIzkuIDooYxcclxuICAgICAgICAgICAgc3RhcnRQb3MgPSBpbnRlcmZhY2VMaW5lLmxpbmVTdGFydCArIG9wZW5CcmFjZUluZGV4O1xyXG4gICAgICAgICAgICBicmFjZUNvdW50ID0gMTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyDlvIDmi6zlj7flnKjkuIvkuIDooYzvvIzmib7liLDnrKzkuIDkuKoge1xyXG4gICAgICAgICAgICBjb25zdCBuZXh0T3BlbkJyYWNlID0gZmlsZUNvbnRlbnQuaW5kZXhPZigneycsIGludGVyZmFjZUxpbmUubGluZUVuZCk7XHJcbiAgICAgICAgICAgIGlmIChuZXh0T3BlbkJyYWNlID09PSAtMSkgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgIHN0YXJ0UG9zID0gbmV4dE9wZW5CcmFjZTtcclxuICAgICAgICAgICAgYnJhY2VDb3VudCA9IDE7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgcG9zID0gc3RhcnRQb3MgKyAxOyAvLyDot7Pov4cge1xyXG5cclxuICAgICAgICB3aGlsZSAocG9zIDwgZmlsZUNvbnRlbnQubGVuZ3RoICYmIGJyYWNlQ291bnQgPiAwKSB7XHJcbiAgICAgICAgICAgIGlmIChmaWxlQ29udGVudFtwb3NdID09PSAneycpIHtcclxuICAgICAgICAgICAgICAgIGJyYWNlQ291bnQrKztcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChmaWxlQ29udGVudFtwb3NdID09PSAnfScpIHtcclxuICAgICAgICAgICAgICAgIGJyYWNlQ291bnQtLTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBwb3MrKztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChicmFjZUNvdW50ICE9PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyDmi6zlj7fkuI3ljLnphY1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIOWQnuaOiSB9IOWQjue0p+i3n+eahOaNouihjO+8jOmBv+WFjeabv+aNouaXtiBuZXdCbG9jayDlho3luKYgXFxuIOWvvOiHtOepuuihjOe0r+WKoFxyXG4gICAgICAgIGxldCBibG9ja0VuZCA9IHBvcztcclxuICAgICAgICBpZiAoZmlsZUNvbnRlbnRbYmxvY2tFbmRdID09PSAnXFxyJykgYmxvY2tFbmQrKztcclxuICAgICAgICBpZiAoZmlsZUNvbnRlbnRbYmxvY2tFbmRdID09PSAnXFxuJykgYmxvY2tFbmQrKztcclxuXHJcbiAgICAgICAgY29uc3QgZnVsbENvbnRlbnQgPSBmaWxlQ29udGVudC5zdWJzdHJpbmcoYmxvY2tTdGFydCwgYmxvY2tFbmQpO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBzdGFydDogYmxvY2tTdGFydCxcclxuICAgICAgICAgICAgZW5kOiBibG9ja0VuZCxcclxuICAgICAgICAgICAgY29udGVudDogZnVsbENvbnRlbnRcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog5Y675o6J5o6l5Y+j5LmL6Ze0IC8gZGVjbGFyZSBnbG9iYWwg5pyr5bC+5aSa5L2Z56m66KGM77yI55Sf5oiQ5pe25piT57Sv5Yqg77yJXHJcbiAgICAgKi9cclxuICAgIG5vcm1hbGl6ZUF1dG9UYWJsZUJsYW5rTGluZXMoY29udGVudDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBsZXQgb3V0ID0gY29udGVudC5yZXBsYWNlKC9cXHJcXG4vZywgJ1xcbicpO1xyXG4gICAgICAgIC8vIOiLpeivr+W4puWFpeacquino+WGs+WGsueqge+8iOmAmuW4uOaYr+epuuihjCB2cyDml6DnqbrooYzvvInvvIzkuKLmjonlhrLnqoHmoIforrBcclxuICAgICAgICBvdXQgPSBvdXQucmVwbGFjZSgvXjw8PDw8PDwgLitcXG4oPzouKlxcbikqPz09PT09PT1cXG4oPzouKlxcbikqPz4+Pj4+Pj4gLitcXG4vZ20sICcnKTtcclxuICAgICAgICAvLyDmjqXlj6Pnu5PmnZ8gfSDlkI7lj6rkv53nlZnkuIDkuKrmjaLooYzvvIzlho3mjqXkuIvkuIDmjqXlj6Pms6jph4rmiJYgZ2xvYmFsIOe7k+adnyB9XHJcbiAgICAgICAgb3V0ID0gb3V0LnJlcGxhY2UoLyhcXG4gezR9XFx9KVxcbig/OlsgXFx0XSpcXG4pKyg/PVsgXFx0XSooPzpcXC9cXCpcXCp8XFx9KSkvZywgJyQxXFxuJyk7XHJcbiAgICAgICAgLy8g5paH5Lu25pyr5bC+IGV4cG9ydCDliY3kuZ/kuI3nlZnnqbrooYxcclxuICAgICAgICBvdXQgPSBvdXQucmVwbGFjZSgvXFxuKD86WyBcXHRdKlxcbikrKFxcfVxcbmV4cG9ydCBcXHsgXFx9OylcXHMqJC9nLCAnXFxuJDFcXG4nKTtcclxuICAgICAgICByZXR1cm4gb3V0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog5a6M5YWo5pu/5o2i5o6l5Y+j5Z2X77yI5YWo5a2X5Yy56YWN77yM57K+5YeG5pu/5o2i77yJXHJcbiAgICAgKi9cclxuICAgIHJlcGxhY2VJbnRlcmZhY2VCbG9jayhcclxuICAgICAgICBmaWxlQ29udGVudDogc3RyaW5nLFxyXG4gICAgICAgIGludGVyZmFjZU5hbWU6IHN0cmluZyxcclxuICAgICAgICBuZXdJbnRlcmZhY2VCbG9jazogc3RyaW5nXHJcbiAgICApOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IGJsb2NrSW5mbyA9IHRoaXMuZXh0cmFjdEZ1bGxJbnRlcmZhY2VCbG9jayhmaWxlQ29udGVudCwgaW50ZXJmYWNlTmFtZSk7XHJcblxyXG4gICAgICAgIGlmICghYmxvY2tJbmZvKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg4p2MIOaOpeWPoyBcIiR7aW50ZXJmYWNlTmFtZX1cIiDmnKrmib7liLDvvIHor7fmo4Dmn6XlkI3np7DmmK/lkKbmraPnoa7jgIJgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIOmqjOivge+8muehruS/neaPkOWPlueahOWdl+ehruWunuWPquWMheWQq+ebruagh+aOpeWPo1xyXG4gICAgICAgIGNvbnN0IGludGVyZmFjZUxpbmVzID0gYmxvY2tJbmZvLmNvbnRlbnQuc3BsaXQoJ1xcbicpO1xyXG4gICAgICAgIGNvbnN0IGludGVyZmFjZURlY2xMaW5lcyA9IGludGVyZmFjZUxpbmVzLmZpbHRlcihsaW5lID0+XHJcbiAgICAgICAgICAgIGxpbmUudHJpbSgpLnN0YXJ0c1dpdGgoJ2ludGVyZmFjZSAnKVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGlmIChpbnRlcmZhY2VEZWNsTGluZXMubGVuZ3RoICE9PSAxKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg4p2MIOaJvuWIsOWkmuS4qiBpbnRlcmZhY2Ug5aOw5piO77yM5Y+v6IO95Yy56YWN6ZSZ6K+v77yBYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIWludGVyZmFjZURlY2xMaW5lc1swXS5pbmNsdWRlcyhgaW50ZXJmYWNlICR7aW50ZXJmYWNlTmFtZX1gKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOKdjCDljLnphY3liLDplJnor6/nmoTmjqXlj6PlkI3np7DvvIFgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vY29uc29sZS5sb2coYOKchSDnsr7lh4bljLnphY3liLDmjqXlj6MgXCIke2ludGVyZmFjZU5hbWV9XCJgKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgZmlsZUNvbnRlbnQuc3Vic3RyaW5nKDAsIGJsb2NrSW5mby5zdGFydCkgK1xyXG4gICAgICAgICAgICBuZXdJbnRlcmZhY2VCbG9jayArXHJcbiAgICAgICAgICAgIGZpbGVDb250ZW50LnN1YnN0cmluZyhibG9ja0luZm8uZW5kKVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g6K6+572u5paH5Lu255uR5ZCsXHJcbiAgICBzZXR1cEZpbGVXYXRjaGVyKCkge1xyXG4gICAgICAgIHRoaXMuc3RvcEZpbGVXYXRjaGVyKCk7XHJcbiAgICAgICAgdGhpcy5sb2FkQ29uZmlnKCk7XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcuYXV0b0V4cG9ydCkge1xyXG4gICAgICAgICAgICB0aGlzLmxvZygnW0V4Y2Vs5o+S5Lu2XSDoh6rliqjlr7zlh7rlt7LlhbPpl63vvIzot7Pov4fmlofku7bnm5HlkKwnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5leGNlbFBhdGgpIHJldHVybjtcclxuXHJcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHRoaXMuY29uZmlnLmV4Y2VsUGF0aCkpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvcihgW0V4Y2Vs5o+S5Lu2XSDnm5HlkKznm67lvZXkuI3lrZjlnKg6ICR7dGhpcy5jb25maWcuZXhjZWxQYXRofWApO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAvLyDkvb/nlKjmm7Tlj6/pnaDnmoTnm5HlkKzmlrnlvI9cclxuICAgICAgICAgICAgdGhpcy5maWxlV2F0Y2hlciA9IGZzLndhdGNoKHRoaXMuY29uZmlnLmV4Y2VsUGF0aCwge1xyXG4gICAgICAgICAgICAgICAgcmVjdXJzaXZlOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAndXRmOCdcclxuICAgICAgICAgICAgfSwgYXN5bmMgKGV2ZW50VHlwZSwgZmlsZW5hbWUpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghZmlsZW5hbWUpIHJldHVybjtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9hZENvbmZpZygpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5hdXRvRXhwb3J0KSByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgLy8g56Gu5L+d5piv5a2X56ym5LiyXHJcbiAgICAgICAgICAgICAgICBjb25zdCBmaWxlTmFtZVN0ciA9IHR5cGVvZiBmaWxlbmFtZSA9PT0gJ3N0cmluZycgPyBmaWxlbmFtZSA6IGZpbGVuYW1lICsgXCJcIjtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGV4dCA9IHBhdGguZXh0bmFtZShmaWxlTmFtZVN0cikudG9Mb3dlckNhc2UoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZXh0ID09PSAnLnhsc3gnIHx8IGV4dCA9PT0gJy54bHMnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4odGhpcy5jb25maWcuZXhjZWxQYXRoLCBmaWxlTmFtZVN0cik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIOmineWklumqjOivge+8muehruS/neaYr+aWh+S7tuS4lOWtmOWcqFxyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGZpbGVQYXRoKSAmJiBmcy5zdGF0U3luYyhmaWxlUGF0aCkuaXNGaWxlKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nKGBbRXhjZWzmj5Lku7ZdIOajgOa1i+WIsOaWh+S7tuWPmOabtDogJHtmaWxlTmFtZVN0cn0gKCR7ZXZlbnRUeXBlfSlgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyDkvb/nlKjnu4jmnoHph43or5XmnLrliLZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIOmHjeivleasoeaVsOWinuWKoOWIsDjvvIzln7rnoYDlu7bov58x56eSXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NFeGNlbEZpbGVXaXRoUmV0cnkoZmlsZVBhdGgsIDgsIDEwMDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2FybihgW0V4Y2Vs5o+S5Lu2XSDpqozor4Hmlofku7bnirbmgIHml7blh7rplJk6ICR7ZXJyfWApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAvLyDlpITnkIbnm5HlkKzplJnor69cclxuICAgICAgICAgICAgaWYgKHRoaXMuZmlsZVdhdGNoZXIgJiYgdHlwZW9mIHRoaXMuZmlsZVdhdGNoZXIub24gPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZmlsZVdhdGNoZXIub24oJ2Vycm9yJywgKGVycm9yOiBFcnJvcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IoYFtFeGNlbOaPkuS7tl0g5paH5Lu255uR5ZCs6ZSZ6K+vOiAke2Vycm9yfWApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyDlsJ3or5Xph43mlrDorr7nva7nm5HlkKxcclxuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdG9wRmlsZVdhdGNoZXIoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR1cEZpbGVXYXRjaGVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgMTUwMDApO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMubG9nKCdbRXhjZWzmj5Lku7ZdIOW3suWQr+WKqEV4Y2Vs55uu5b2V55uR5ZCs77yI57uI5p6B54mI77yJJyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IoYFtFeGNlbOaPkuS7tl0g55uu5b2V55uR5ZCs5aSx6LSlOiAke2Vycn1gKTtcclxuXHJcbiAgICAgICAgICAgIC8vIOWwneivlemHjeaWsOiuvue9ruebkeWQrFxyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RvcEZpbGVXYXRjaGVyKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldHVwRmlsZVdhdGNoZXIoKTtcclxuICAgICAgICAgICAgfSwgMjAwMDApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyDluKbph43or5XmnLrliLblpITnkIZFeGNlbOaWh+S7tu+8iOiHquWKqOWvvOWHuu+8iVxyXG4gICAgcHJvY2Vzc0V4Y2VsRmlsZVdpdGhSZXRyeShmaWxlUGF0aDogc3RyaW5nLCBtYXhSZXRyaWVzOiBudW1iZXIgPSA4LCBiYXNlRGVsYXk6IG51bWJlciA9IDEwMDApIHtcclxuICAgICAgICB0aGlzLmVucXVldWVFeHBvcnQoKCkgPT4gdGhpcy5wcm9jZXNzRXhjZWxGaWxlV2l0aFJldHJ5SW50ZXJuYWwoZmlsZVBhdGgsIG1heFJldHJpZXMsIGJhc2VEZWxheSkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiDkuLLooYzmiafooYzlr7zlh7rvvIzpgb/lhY3lubblj5HlhpkgQXV0b1RhYmxlLnRzICovXHJcbiAgICBwcml2YXRlIGVucXVldWVFeHBvcnQodGFzazogKCkgPT4gdm9pZCkge1xyXG4gICAgICAgIHRoaXMuZXhwb3J0UXVldWUucHVzaCh0YXNrKTtcclxuICAgICAgICBpZiAoIXRoaXMuaXNFeHBvcnRpbmcpIHtcclxuICAgICAgICAgICAgdGhpcy5ydW5OZXh0RXhwb3J0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgcnVuTmV4dEV4cG9ydCgpIHtcclxuICAgICAgICBjb25zdCB0YXNrID0gdGhpcy5leHBvcnRRdWV1ZS5zaGlmdCgpO1xyXG4gICAgICAgIGlmICghdGFzaykge1xyXG4gICAgICAgICAgICB0aGlzLmlzRXhwb3J0aW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5pc0V4cG9ydGluZyA9IHRydWU7XHJcbiAgICAgICAgdGFzaygpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgcHJvY2Vzc0V4Y2VsRmlsZVdpdGhSZXRyeUludGVybmFsKGZpbGVQYXRoOiBzdHJpbmcsIG1heFJldHJpZXM6IG51bWJlciA9IDgsIGJhc2VEZWxheTogbnVtYmVyID0gMTAwMCkge1xyXG4gICAgICAgIGxldCBhdHRlbXB0ID0gMDtcclxuICAgICAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xyXG5cclxuICAgICAgICBjb25zdCB0cnlQcm9jZXNzID0gKCkgPT4ge1xyXG4gICAgICAgICAgICBhdHRlbXB0Kys7XHJcbiAgICAgICAgICAgIGNvbnN0IGVsYXBzZWQgPSBEYXRlLm5vdygpIC0gc3RhcnRUaW1lO1xyXG4gICAgICAgICAgICBjb25zdCBkZWxheSA9IGJhc2VEZWxheSAqIE1hdGgubWluKDEuNSAqKiAoYXR0ZW1wdCAtIDEpLCA0KTsgLy8g5oyH5pWw6YCA6YG/77yM5L2G5LiK6ZmQ5Li6NOWAjeWfuuehgOW7tui/n1xyXG5cclxuICAgICAgICAgICAgdGhpcy5sb2coYFtFeGNlbOaPkuS7tl0g5aSE55CG5paH5Lu2IFwiJHtwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKX1cIiAtIOWwneivlSAke2F0dGVtcHR9LyR7bWF4UmV0cmllc30gKOW7tui/nyAke01hdGgucm91bmQoZGVsYXkpfW1zLCDlt7LogJfml7YgJHtNYXRoLnJvdW5kKGVsYXBzZWQgLyAxMDAwKX1zKWApO1xyXG5cclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIOmineWkluajgOafpeaWh+S7tuaYr+WQpuWPr+ivu1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXRzID0gZnMuc3RhdFN5bmMoZmlsZVBhdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0cy5zaXplID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIuaWh+S7tuWkp+Wwj+S4ujDvvIzlj6/og73ku43lnKjlhpnlhaVcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyDmo4Dmn6Xmlofku7bmnIDlkI7kv67mlLnml7bpl7TvvIznoa7kv53kuI3mmK/liJrooqvkv67mlLlcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbGVBZ2UgPSBub3cgLSBzdGF0cy5tdGltZU1zO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWxlQWdlIDwgMjAwMCkgeyAvLyDmlofku7bkv67mlLnml7bpl7TlsJHkuo4y56eS77yM5Y+v6IO96L+Y5Zyo5YaZ5YWlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg5paH5Lu25Yia6KKr5L+u5pS5ICgke01hdGgucm91bmQoZmlsZUFnZSl9bXPliY0p77yM5Y+v6IO95LuN5Zyo5YaZ5YWlYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NFeGNlbEZpbGUoZmlsZVBhdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvdGFsVGltZSA9IERhdGUubm93KCkgLSBzdGFydFRpbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZyZXNoQXNzZXREYXRhYmFzZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3VjY2VzcyhgW0V4Y2Vs5o+S5Lu2XSDmlofku7YgXCIke3BhdGguYmFzZW5hbWUoZmlsZVBhdGgpfVwiIOiHquWKqOWvvOWHuuaIkOWKnyAo5oC76ICX5pe2ICR7TWF0aC5yb3VuZCh0b3RhbFRpbWUgLyAxMDAwKX1zLCDlsJ3or5UgJHthdHRlbXB0fS8ke21heFJldHJpZXN9KWApO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucnVuTmV4dEV4cG9ydCgpO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8g6K+m57uG6K6w5b2V6ZSZ6K+vXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy53YXJuKGBbRXhjZWzmj5Lku7ZdIOWwneivlSAke2F0dGVtcHR9IOWksei0pTogJHtlcnIubWVzc2FnZSB8fCBlcnJ9YCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIOajgOafpeaYr+WQpuaYr+aWh+S7tumUgeWumuaIluadg+mZkOmUmeivr1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzRmlsZUxvY2tFcnJvciA9IGVyci5tZXNzYWdlICYmIChcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyLm1lc3NhZ2UuaW5jbHVkZXMoJ0VQRVJNJykgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyLm1lc3NhZ2UuaW5jbHVkZXMoJ0VCVVNZJykgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyLm1lc3NhZ2UuaW5jbHVkZXMoJ3Blcm1pc3Npb24nKSB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnIubWVzc2FnZS5pbmNsdWRlcygnbG9ja2VkJykgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyLm1lc3NhZ2UuaW5jbHVkZXMoJ0VBQ0NFUycpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlLmluY2x1ZGVzKCdmaWxlIHNpemUgMCcpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlLmluY2x1ZGVzKCfliJrooqvkv67mlLknKVxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0ZpbGVMb2NrRXJyb3IgJiYgYXR0ZW1wdCA8IG1heFJldHJpZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8g6K6h566X5LiL5LiA5qyh5bCd6K+V55qE5bu26L+f77yI5oyH5pWw6YCA6YG/77yJXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHREZWxheSA9IGJhc2VEZWxheSAqIE1hdGgubWluKDEuNSAqKiBhdHRlbXB0LCA0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53YXJuKGBbRXhjZWzmj5Lku7ZdIOaWh+S7tiBcIiR7cGF0aC5iYXNlbmFtZShmaWxlUGF0aCl9XCIg5Y+v6IO95LuN5Zyo5L+d5a2Y5Lit77yM5bCG5ZyoICR7TWF0aC5yb3VuZChuZXh0RGVsYXkpfW1zIOWQjumHjeivlSAo5bCd6K+VICR7YXR0ZW1wdCArIDF9LyR7bWF4UmV0cmllc30pYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQodHJ5UHJvY2VzcywgbmV4dERlbGF5KTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0b3RhbFRpbWUgPSBEYXRlLm5vdygpIC0gc3RhcnRUaW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yKGBbRXhjZWzmj5Lku7ZdIOaWh+S7tiBcIiR7cGF0aC5iYXNlbmFtZShmaWxlUGF0aCl9XCIg6Ieq5Yqo5a+85Ye65aSx6LSlICjmgLvogJfml7YgJHtNYXRoLnJvdW5kKHRvdGFsVGltZSAvIDEwMDApfXMpOiAke2Vycn1gKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOWmguaenOaYr+aWh+S7tumUgeWumumUmeivr+S9huW3sui+vuWIsOacgOWkp+mHjeivleasoeaVsO+8jOaPkOS+m+WFt+S9k+W7uuiurlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNGaWxlTG9ja0Vycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yKGBbRXhjZWzmj5Lku7ZdIOW7uuiurjog56Gu5L+dRXhjZWzlrozlhajkv53lrZjlkI7lho3ov5vooYzkv67mlLnvvIzmiJblop7liqDph43or5XmrKHmlbDlkozlu7bov59gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJ1bk5leHRFeHBvcnQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIGRlbGF5KTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB0cnlQcm9jZXNzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5YGc5q2i5paH5Lu255uR5ZCs77yI5pu05paw77yJXHJcbiAgICBzdG9wRmlsZVdhdGNoZXIoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZmlsZVdhdGNoZXIpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIC8vIOS9v+eUqOexu+Wei+aWreiogOehruS/neiwg+eUqGNsb3Nl5pa55rOVXHJcbiAgICAgICAgICAgICAgICAodGhpcy5maWxlV2F0Y2hlciBhcyBhbnkpLmNsb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZpbGVXYXRjaGVyID0gbnVsbDtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy53YXJuKGBbRXhjZWzmj5Lku7ZdIOWBnOatouebkeWQrOaXtuWHuumUmTogJHtlfWApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5jb25maWcud2F0Y2hlcikge1xyXG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuY29uZmlnLndhdGNoZXIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcud2F0Y2hlciA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5sb2coJ1tFeGNlbOaPkuS7tl0g5bey5YGc5q2iRXhjZWzmlofku7bnm5HlkKwnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8g55Sf5oiQSlNPTuaVsOaNrlxyXG4gICAgZ2VuZXJhdGVKc29uRGF0YShkYXRhUm93czogYW55W11bXSwgaGVhZGVyczogYW55KTogYW55W10ge1xyXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHJvdyBvZiBkYXRhUm93cykge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNEYXRhUm93KHJvdywgaGVhZGVycy5maWVsZHMpKSB7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3Qgb2JqOiBhbnkgPSB7fTtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGVhZGVycy5maWVsZHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGZpZWxkID0gaGVhZGVycy5maWVsZHNbaV07XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0eXBlID0gaGVhZGVycy50eXBlc1tpXTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZmllbGQpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHJvd1tpXSAhPT0gdW5kZWZpbmVkID8gcm93W2ldIDogdGhpcy5nZXREZWZhdWx0VmFsdWUodHlwZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JqW2ZpZWxkXSA9IHRoaXMuY29udmVydFZhbHVlKHZhbHVlLCB0eXBlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVzdWx0LnB1c2gob2JqKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIOi3s+i/h+WFqOepuuihjCAqL1xyXG4gICAgcHJpdmF0ZSBpc0RhdGFSb3cocm93OiBhbnlbXSwgZmllbGRzOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICghcm93IHx8IHJvdy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCBmaWVsZCA9IGZpZWxkc1tpXTtcclxuICAgICAgICAgICAgaWYgKCFmaWVsZCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gcm93W2ldO1xyXG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCAmJiBTdHJpbmcodmFsdWUpLnRyaW0oKSAhPT0gJycpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICAvKiog5Yik5pat5Y2V5YWD5qC85piv5ZCm5Li656m6ICovXHJcbiAgICBwcml2YXRlIGlzRW1wdHlWYWx1ZSh2YWx1ZTogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgfHwgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUudHJpbSgpID09PSAnJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5qC55o2u57G75Z6L6I635Y+W6buY6K6k5YC8XHJcbiAgICBnZXREZWZhdWx0VmFsdWUodHlwZTogc3RyaW5nKTogYW55IHtcclxuICAgICAgICBpZiAoIXR5cGUpIHJldHVybiBudWxsO1xyXG5cclxuICAgICAgICBjb25zdCBjbGVhblR5cGUgPSB0eXBlLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xyXG4gICAgICAgIHN3aXRjaCAoY2xlYW5UeXBlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgJ2ludCc6XHJcbiAgICAgICAgICAgIGNhc2UgJ2Zsb2F0JzpcclxuICAgICAgICAgICAgICAgIHJldHVybiAwO1xyXG4gICAgICAgICAgICBjYXNlICdib29sZWFuJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgY2FzZSAnaW50W10nOlxyXG4gICAgICAgICAgICBjYXNlICdmbG9hdFtdJzpcclxuICAgICAgICAgICAgY2FzZSAnc3RyaW5nW10nOlxyXG4gICAgICAgICAgICBjYXNlICdhbnlbXSc6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgICAgIGNhc2UgJ3N0cmluZyc6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvLyDnsbvlnovovazmjaJcclxuICAgIGNvbnZlcnRWYWx1ZSh2YWx1ZTogYW55LCB0eXBlOiBzdHJpbmcpOiBhbnkge1xyXG4gICAgICAgIGlmICh0aGlzLmlzRW1wdHlWYWx1ZSh2YWx1ZSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RGVmYXVsdFZhbHVlKHR5cGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgY2xlYW5UeXBlID0gdHlwZS50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgc3dpdGNoIChjbGVhblR5cGUpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgJ2ludCc6IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBuID0gcGFyc2VJbnQodmFsdWUsIDEwKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNOYU4obikgPyAwIDogbjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNhc2UgJ2Zsb2F0Jzoge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG4gPSBwYXJzZUZsb2F0KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNOYU4obikgPyAwIDogbjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNhc2UgJ2pzb24nOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIGNhc2UgJ2Jvb2xlYW4nOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJyB8fCB2YWx1ZSA9PT0gMTtcclxuICAgICAgICAgICAgICAgIGNhc2UgJ2ludFtdJzpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJzZUFycmF5KHZhbHVlLCAnaW50Jyk7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdmbG9hdFtdJzpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJzZUFycmF5KHZhbHVlLCAnZmxvYXQnKTtcclxuICAgICAgICAgICAgICAgIGNhc2UgJ3N0cmluZ1tdJzpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJzZUFycmF5KHZhbHVlLCAnc3RyaW5nJyk7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdhbnlbXSc6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VBcnJheSh2YWx1ZSwgJ2FueScpO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIHRoaXMud2FybihgW0V4Y2Vs5o+S5Lu2XSDnsbvlnovovazmjaLlpLHotKUgWyR7dHlwZX1dOiAke3ZhbHVlfSAtICR7ZX1gKTtcclxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyDop6PmnpDmlbDnu4RcclxuICAgIHBhcnNlQXJyYXkodmFsdWU6IGFueSwgdGFyZ2V0VHlwZTogc3RyaW5nKTogYW55W10ge1xyXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIHZhbHVlO1xyXG5cclxuICAgICAgICAvLyDlsJ3or5XliIblibLlrZfnrKbkuLJcclxuICAgICAgICBsZXQgaXRlbXMgPSBbXTtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBpdGVtcyA9IHZhbHVlLnNwbGl0KC9bLDsjXFxzXVxccyovKS5maWx0ZXIodiA9PiB2KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpdGVtcyA9IFt2YWx1ZV07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gaXRlbXMubWFwKGl0ZW0gPT4ge1xyXG4gICAgICAgICAgICBpZiAodGFyZ2V0VHlwZSA9PT0gJ2FueScpIHtcclxuICAgICAgICAgICAgICAgIC8vIOiHquWKqOivhuWIq+exu+Wei1xyXG4gICAgICAgICAgICAgICAgaWYgKCFpc05hTihpdGVtKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAhaXNOYU4ocGFyc2VGbG9hdChpdGVtKSkgPyBwYXJzZUZsb2F0KGl0ZW0pIDogcGFyc2VJbnQoaXRlbSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoaXRlbS50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZScgfHwgaXRlbS50b0xvd2VyQ2FzZSgpID09PSAnZmFsc2UnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0udG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW07XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIOaMh+Wumuexu+Wei+i9rOaNolxyXG4gICAgICAgICAgICBzd2l0Y2ggKHRhcmdldFR5cGUpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgJ2ludCc6IHJldHVybiBwYXJzZUludChpdGVtKTtcclxuICAgICAgICAgICAgICAgIGNhc2UgJ2Zsb2F0JzogcmV0dXJuIHBhcnNlRmxvYXQoaXRlbSk7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdzdHJpbmcnOiByZXR1cm4gU3RyaW5nKGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogcmV0dXJuIGl0ZW07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBnZW5lcmF0ZVRTSW50ZXJmYWNlU3RhcnQoc2hlZXROYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IGludGVyZmFjZU5hbWUgPSBgSVRhYmxlJHtzaGVldE5hbWV9YDtcclxuICAgICAgICBjb25zdCBzYWZlU2hlZXROYW1lID0gYCR7dGhpcy5tYWtlU2FmZUZpbGVOYW1lKHNoZWV0TmFtZSl9YDtcclxuXHJcbiAgICAgICAgbGV0IHRzQ29udGVudCA9IGAgICAgLyoqXFxuICAgICAqICR7c2FmZVNoZWV0TmFtZX0g6YWN572u5pWw5o2uXFxuICAgICovXFxuYDtcclxuICAgICAgICB0c0NvbnRlbnQgKz0gYCAgICBpbnRlcmZhY2UgJHtpbnRlcmZhY2VOYW1lfSB7XFxuYDtcclxuICAgICAgICByZXR1cm4gdHNDb250ZW50O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOeUn+aIkFRT5o6l5Y+jXHJcbiAgICBnZW5lcmF0ZVRTSW50ZXJmYWNlKHNoZWV0TmFtZTogc3RyaW5nLCBoZWFkZXJzOiBhbnkpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IGludGVyZmFjZU5hbWUgPSBgSVRhYmxlJHtzaGVldE5hbWV9YDtcclxuICAgICAgICBjb25zdCBzYWZlU2hlZXROYW1lID0gYCR7dGhpcy5tYWtlU2FmZUZpbGVOYW1lKHNoZWV0TmFtZSl9YDtcclxuXHJcbiAgICAgICAgbGV0IHRzQ29udGVudCA9IGAgICAgLyoqXFxuICAgICAqICR7c2FmZVNoZWV0TmFtZX0g6YWN572u5pWw5o2uXFxuICAgICovXFxuYDtcclxuICAgICAgICB0c0NvbnRlbnQgKz0gYCAgICBpbnRlcmZhY2UgJHtpbnRlcmZhY2VOYW1lfSB7XFxuYDtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoZWFkZXJzLmZpZWxkcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCBmaWVsZCA9IGhlYWRlcnMuZmllbGRzW2ldO1xyXG4gICAgICAgICAgICBjb25zdCB0eXBlID0gaGVhZGVycy50eXBlc1tpXTtcclxuICAgICAgICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSBoZWFkZXJzLmRlc2NyaXB0aW9uc1tpXSB8fCAn5a2X5q616K+05piOJztcclxuXHJcbiAgICAgICAgICAgIGlmIChmaWVsZCkge1xyXG4gICAgICAgICAgICAgICAgdHNDb250ZW50ICs9IGAgICAgICAgIC8qKiAke2Rlc2NyaXB0aW9ufSAqL1xcbmA7XHJcbiAgICAgICAgICAgICAgICB0c0NvbnRlbnQgKz0gYCAgICAgICAgcmVhZG9ubHkgJHtmaWVsZH06ICR7dGhpcy5jb252ZXJ0VG9UU1R5cGUodHlwZSl9O1xcbmA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRzQ29udGVudCArPSBgICAgIH1cXG5gO1xyXG4gICAgICAgIHJldHVybiB0c0NvbnRlbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g6L2s5o2i5Li6VFPnsbvlnotcclxuICAgIGNvbnZlcnRUb1RTVHlwZShleGNlbFR5cGU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgaWYgKCFleGNlbFR5cGUpIHJldHVybiAnYW55JztcclxuXHJcbiAgICAgICAgY29uc3QgdHlwZSA9IGV4Y2VsVHlwZS50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcclxuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcclxuICAgICAgICAgICAgY2FzZSAnc3RyaW5nJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiAnc3RyaW5nJztcclxuICAgICAgICAgICAgY2FzZSAnaW50JzpcclxuICAgICAgICAgICAgY2FzZSAnZmxvYXQnOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICdudW1iZXInO1xyXG4gICAgICAgICAgICBjYXNlICdib29sZWFuJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiAnYm9vbGVhbic7XHJcbiAgICAgICAgICAgIGNhc2UgJ2ludFtdJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiAnbnVtYmVyW10nO1xyXG4gICAgICAgICAgICBjYXNlICdmbG9hdFtdJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiAnbnVtYmVyW10nO1xyXG4gICAgICAgICAgICBjYXNlICdzdHJpbmdbXSc6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJ3N0cmluZ1tdJztcclxuICAgICAgICAgICAgY2FzZSAnYW55W10nOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICcobnVtYmVyIHwgc3RyaW5nIHwgYm9vbGVhbilbXSc7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJ2FueSc7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIOi9rOaNouS4ulBhc2NhbENhc2VcclxuICAgIHRvUGFzY2FsQ2FzZShzdHI6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKC8oXFx3KShcXHcqKS9nLCAoXywgZzEsIGcyKSA9PlxyXG4gICAgICAgICAgICBnMS50b1VwcGVyQ2FzZSgpICsgZzIudG9Mb3dlckNhc2UoKVxyXG4gICAgICAgICkucmVwbGFjZSgvW15hLXpBLVowLTldL2csICcnKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyDliJvlu7rlronlhajnmoTmlofku7blkI1cclxuICAgIG1ha2VTYWZlRmlsZU5hbWUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gbmFtZS5yZXBsYWNlKC9bXmEtekEtWjAtOV9dL2csICdfJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5pel5b+X6L6T5Ye6XHJcbiAgICBsb2cobWVzc2FnZTogc3RyaW5nKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2cobWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZXJyb3IobWVzc2FnZTogc3RyaW5nKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihtZXNzYWdlKTtcclxuICAgIH1cclxuXHJcbiAgICB3YXJuKG1lc3NhZ2U6IHN0cmluZykge1xyXG4gICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcclxuICAgIH1cclxuXHJcbiAgICBzdWNjZXNzKG1lc3NhZ2U6IHN0cmluZykge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOa2iOaBr+WkhOeQhlxyXG4gICAgbWVzc2FnZXMgPSB7XHJcbiAgICAgICAgJ2V4Y2VsLXRvLWpzb24tdHM6ZXhwb3J0LW1hbnVhbCc6ICgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5leHBvcnRNYW51YWwoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5Yi35paw6LWE5rqQ566h55CG5ZmoXHJcbiAgICBhc3luYyByZWZyZXNoQXNzZXREYXRhYmFzZSgpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCBwYXRocyA9IG1lbWJlcnNoaXBGcm9tQXJyYXkoW1xyXG4gICAgICAgICAgICAgICAgLi4ubWVtYmVyc2hpcFRvQXJyYXkodGhpcy5qc29uUmVmcmVzaFBhdGhzKSxcclxuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmpzb25FeHBvcnRQYXRoLFxyXG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcubGFuZ0pzb25FeHBvcnRQYXRoLFxyXG4gICAgICAgICAgICBdKTtcclxuXHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qgc3lzdGVtUGF0aCBvZiBtZW1iZXJzaGlwVG9BcnJheShwYXRocykpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGRiUGF0aCA9IHRoaXMuY29udmVydFRvRGJQYXRoKHN5c3RlbVBhdGgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGRiUGF0aCAmJiBkYlBhdGguc3RhcnRzV2l0aCgnZGI6Ly8nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IEVkaXRvci5NZXNzYWdlLnJlcXVlc3QoJ2Fzc2V0LWRiJywgJ3JlZnJlc2gtYXNzZXQnLCBkYlBhdGgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCB0c0RiUGF0aCA9IHRoaXMuY29udmVydFRvRGJQYXRoKHRoaXMuY29uZmlnLnRzRXhwb3J0UGF0aCk7XHJcbiAgICAgICAgICAgIGlmICh0c0RiUGF0aCAmJiB0c0RiUGF0aC5zdGFydHNXaXRoKCdkYjovLycpKSB7XHJcbiAgICAgICAgICAgICAgICBhd2FpdCBFZGl0b3IuTWVzc2FnZS5yZXF1ZXN0KCdhc3NldC1kYicsICdyZWZyZXNoLWFzc2V0JywgdHNEYlBhdGgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLnN1Y2Nlc3MoJ1tFeGNlbOaPkuS7tl0g6LWE5rqQ5Yi35paw6K+35rGC5bey5Y+R6YCBJyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3IoYFtFeGNlbOaPkuS7tl0g6LWE5rqQ5Yi35paw5aSx6LSlOiAke2Vycn1gKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5bCG57O757uf6Lev5b6E6L2s5o2i5Li6Q29jb3PnmoRkYui3r+W+hFxyXG4gICAgY29udmVydFRvRGJQYXRoKHN5c3RlbVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgaWYgKCFzeXN0ZW1QYXRoKSByZXR1cm4gJyc7XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIC8vIOiOt+WPlumhueebrui3r+W+hFxyXG4gICAgICAgICAgICBjb25zdCBwcm9qZWN0UGF0aCA9IEVkaXRvci5Qcm9qZWN0LnBhdGg7XHJcblxyXG4gICAgICAgICAgICAvLyDop4TojIPljJbot6/lvoTvvIjnu5/kuIDkvb/nlKjmraPmlpzmnaDvvIlcclxuICAgICAgICAgICAgc3lzdGVtUGF0aCA9IHN5c3RlbVBhdGgucmVwbGFjZSgvXFxcXC9nLCAnLycpO1xyXG4gICAgICAgICAgICBjb25zdCBub3JtYWxpemVkUHJvamVjdFBhdGggPSBwcm9qZWN0UGF0aC5yZXBsYWNlKC9cXFxcL2csICcvJyk7XHJcblxyXG4gICAgICAgICAgICAvLyDnoa7kv53ot6/lvoTku6Uv57uT5bC+XHJcbiAgICAgICAgICAgIGNvbnN0IHByb2plY3RQYXRoV2l0aFNsYXNoID0gbm9ybWFsaXplZFByb2plY3RQYXRoLmVuZHNXaXRoKCcvJylcclxuICAgICAgICAgICAgICAgID8gbm9ybWFsaXplZFByb2plY3RQYXRoXHJcbiAgICAgICAgICAgICAgICA6IG5vcm1hbGl6ZWRQcm9qZWN0UGF0aCArICcvJztcclxuXHJcbiAgICAgICAgICAgIC8vIOajgOafpeaYr+WQpuWcqOmhueebruebruW9leWGhVxyXG4gICAgICAgICAgICBpZiAoc3lzdGVtUGF0aC5zdGFydHNXaXRoKHByb2plY3RQYXRoV2l0aFNsYXNoKSkge1xyXG4gICAgICAgICAgICAgICAgLy8g6K6h566X55u45a+56Lev5b6EXHJcbiAgICAgICAgICAgICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBzeXN0ZW1QYXRoLnN1YnN0cmluZyhwcm9qZWN0UGF0aFdpdGhTbGFzaC5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGBkYjovLyR7cmVsYXRpdmVQYXRofWA7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIOWmguaenOi3r+W+hOWMheWQq2Fzc2V0c+ebruW9le+8jOWwneivleebtOaOpei9rOaNolxyXG4gICAgICAgICAgICBpZiAoc3lzdGVtUGF0aC5pbmNsdWRlcygnL2Fzc2V0cy8nKSB8fCBzeXN0ZW1QYXRoLmluY2x1ZGVzKCdcXFxcYXNzZXRzXFxcXCcpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhc3NldHNJbmRleCA9IHN5c3RlbVBhdGgudG9Mb3dlckNhc2UoKS5pbmRleE9mKCcvYXNzZXRzLycpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFzc2V0c0luZGV4ICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbGF0aXZlVG9Bc3NldHMgPSBzeXN0ZW1QYXRoLnN1YnN0cmluZyhhc3NldHNJbmRleCArIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgZGI6Ly8ke3JlbGF0aXZlVG9Bc3NldHN9YDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy53YXJuKGBbRXhjZWzmj5Lku7ZdIOi3r+W+hOS4jeWcqOmhueebruWGhe+8jOWPr+iDveaXoOazleato+ehruWIt+aWsDogJHtzeXN0ZW1QYXRofWApO1xyXG4gICAgICAgICAgICByZXR1cm4gc3lzdGVtUGF0aDtcclxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvcihgW0V4Y2Vs5o+S5Lu2XSDot6/lvoTovazmjaLlpLHotKU6ICR7ZXJyfWApO1xyXG4gICAgICAgICAgICByZXR1cm4gc3lzdGVtUGF0aDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBleGNlbFRvSnNvblBsdWdpbiA9IG5ldyBFeGNlbFRvSnNvblBsdWdpbigpOyJdfQ==