You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
393 lines
56 KiB
393 lines
56 KiB
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.onAfterBuild = exports.onBeforeBuild = exports.throwError = void 0;
|
|
/**
|
|
* 构建进程(独立 worker)加载的钩子脚本;custom-builder 的 configs.*.hooks 指向本文件。
|
|
* custom-builder.ts 会 re-export 本文件的钩子,供编辑器校验通过。
|
|
*/
|
|
const fs_1 = __importDefault(require("fs"));
|
|
const path_1 = __importDefault(require("path"));
|
|
const lz4js_1 = __importDefault(require("lz4js"));
|
|
const terser_1 = require("terser");
|
|
const MembershipSet_1 = require("./MembershipSet");
|
|
exports.throwError = true;
|
|
function readJson(filePath) {
|
|
const raw = fs_1.default.readFileSync(filePath, 'utf8');
|
|
return JSON.parse(raw);
|
|
}
|
|
function resolveConfigNameVersion(projectPath) {
|
|
var _a, _b, _c, _d, _e, _f;
|
|
const sdkConfigPath = path_1.default.join(projectPath, 'assets', 'script', 'sdk', 'sdkConfig.ts');
|
|
const sdkConfigContent = fs_1.default.readFileSync(sdkConfigPath, 'utf8');
|
|
const importRegex = /import\s+\{\s*(\w+)\s*\}\s+from\s+["']\.\/config\/([^"']+)["'];?/g;
|
|
const importMap = new Map();
|
|
let m = null;
|
|
while ((m = importRegex.exec(sdkConfigContent))) {
|
|
importMap.set(m[1], m[2]);
|
|
}
|
|
const configAssign = sdkConfigContent.match(/static\s+readonly\s+config\s*:\s*IConfigData\s*=\s*(\w+)\s*;/);
|
|
const symbol = (_a = configAssign === null || configAssign === void 0 ? void 0 : configAssign[1]) !== null && _a !== void 0 ? _a : 'DefaultConfig';
|
|
const relConfig = (_b = importMap.get(symbol)) !== null && _b !== void 0 ? _b : 'DefaultConfig';
|
|
const configPath = path_1.default.join(projectPath, 'assets', 'script', 'sdk', 'config', `${relConfig}.ts`);
|
|
const configContent = fs_1.default.readFileSync(configPath, 'utf8');
|
|
const name = (_d = (_c = configContent.match(/name\s*:\s*["']([^"']+)["']/)) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : 'config';
|
|
const vsion = (_f = (_e = configContent.match(/vsion\s*:\s*["']([^"']+)["']/)) === null || _e === void 0 ? void 0 : _e[1]) !== null && _f !== void 0 ? _f : '0.0.0';
|
|
return { name, vsion };
|
|
}
|
|
function encodeForRuntime(jsonObj) {
|
|
const jsonString = JSON.stringify(jsonObj);
|
|
const uint8 = new TextEncoder().encode(jsonString);
|
|
const compressed = Uint8Array.from(lz4js_1.default.compress(uint8));
|
|
const binary = Buffer.from(compressed).toString('latin1');
|
|
const base64 = Buffer.from(binary, 'latin1').toString('base64');
|
|
return Buffer.from(base64, 'latin1');
|
|
}
|
|
const HOT_UPDATE_TABLE_FILES = [
|
|
{ tableKey: 'Monster', fileName: 'Monster.json' },
|
|
{ tableKey: 'Const', fileName: 'Const.json' },
|
|
{ tableKey: 'Rank', fileName: 'Rank.json' },
|
|
{ tableKey: 'Item', fileName: 'Item.json' },
|
|
{ tableKey: 'Level', fileName: 'Level.json' },
|
|
{ tableKey: 'Skill', fileName: 'Skill.json' },
|
|
{ tableKey: 'Battlebuff', fileName: 'Battlebuff.json' },
|
|
{ tableKey: 'Weapon', fileName: 'Weapon.json' },
|
|
{ tableKey: 'Text', fileName: 'Text.json' },
|
|
{ tableKey: 'Hero', fileName: 'Hero.json' },
|
|
{ tableKey: 'Headicon', fileName: 'Headicon.json' },
|
|
];
|
|
function generateConfigBin() {
|
|
const projectPath = Editor.Project.path;
|
|
const configDir = path_1.default.join(projectPath, 'assets', 'bundles', 'first', 'config');
|
|
const mergeJson = {};
|
|
for (const { tableKey, fileName } of HOT_UPDATE_TABLE_FILES) {
|
|
const fp = path_1.default.join(configDir, fileName);
|
|
if (!fs_1.default.existsSync(fp)) {
|
|
console.warn(`[tools] skip bin generate: missing ${fileName}`);
|
|
return;
|
|
}
|
|
mergeJson[tableKey] = readJson(fp);
|
|
}
|
|
const { name, vsion } = resolveConfigNameVersion(projectPath);
|
|
const safeName = `${name}${vsion}`.replace(/[<>:"/\\|?*]+/g, '_');
|
|
const outDir = path_1.default.join(projectPath, 'bin');
|
|
const outFile = path_1.default.join(outDir, `${safeName}.bin`);
|
|
fs_1.default.mkdirSync(outDir, { recursive: true });
|
|
fs_1.default.writeFileSync(outFile, encodeForRuntime(mergeJson));
|
|
console.log(`[tools] generated config bin: ${outFile}`);
|
|
}
|
|
function collectJsFiles(dir, acc) {
|
|
if (!fs_1.default.existsSync(dir))
|
|
return;
|
|
const st = fs_1.default.statSync(dir);
|
|
if (!st.isDirectory())
|
|
return;
|
|
const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
|
|
for (const e of entries) {
|
|
const full = path_1.default.join(dir, e.name);
|
|
if (e.isDirectory()) {
|
|
collectJsFiles(full, acc);
|
|
}
|
|
else if (e.isFile() && e.name.endsWith('.js')) {
|
|
acc.push(full);
|
|
}
|
|
}
|
|
}
|
|
function collectStripRoots(options, result) {
|
|
var _a, _b, _c, _d;
|
|
const roots = (0, MembershipSet_1.createMembershipSet)();
|
|
const add = (p) => {
|
|
if (p == null || p === '')
|
|
return;
|
|
const s = path_1.default.normalize(String(p).replace(/\//g, path_1.default.sep));
|
|
try {
|
|
if (fs_1.default.existsSync(s)) {
|
|
const st = fs_1.default.statSync(s);
|
|
if (st.isDirectory())
|
|
(0, MembershipSet_1.membershipAdd)(roots, s);
|
|
}
|
|
}
|
|
catch (_a) {
|
|
/* ignore */
|
|
}
|
|
};
|
|
add(result === null || result === void 0 ? void 0 : result.dest);
|
|
add((_a = result === null || result === void 0 ? void 0 : result.paths) === null || _a === void 0 ? void 0 : _a.dir);
|
|
add((_b = result === null || result === void 0 ? void 0 : result.paths) === null || _b === void 0 ? void 0 : _b.assets);
|
|
add((_c = result === null || result === void 0 ? void 0 : result.paths) === null || _c === void 0 ? void 0 : _c.bundleScripts);
|
|
add((_d = result === null || result === void 0 ? void 0 : result.paths) === null || _d === void 0 ? void 0 : _d.subpackages);
|
|
const projectPath = Editor.Project.path;
|
|
if (projectPath && (options === null || options === void 0 ? void 0 : options.buildPath) && (options === null || options === void 0 ? void 0 : options.outputName)) {
|
|
let bp = String(options.buildPath);
|
|
if (bp.includes('project:')) {
|
|
bp = path_1.default.join(projectPath, bp.replace(/^project:\/\//, '').replace(/^project:/, ''));
|
|
}
|
|
add(path_1.default.join(bp, options.outputName));
|
|
}
|
|
return (0, MembershipSet_1.membershipToArray)(roots);
|
|
}
|
|
function collectAllJsFiles(roots) {
|
|
const files = (0, MembershipSet_1.createMembershipSet)();
|
|
for (const root of roots) {
|
|
const acc = [];
|
|
collectJsFiles(root, acc);
|
|
for (const f of acc)
|
|
(0, MembershipSet_1.membershipAdd)(files, path_1.default.normalize(f));
|
|
}
|
|
return (0, MembershipSet_1.membershipToArray)(files);
|
|
}
|
|
async function minifyStripConsole(src) {
|
|
const base = {
|
|
compress: {
|
|
drop_console: true,
|
|
drop_debugger: true,
|
|
passes: 2,
|
|
},
|
|
mangle: false,
|
|
format: { comments: 'some' },
|
|
ecma: 2020,
|
|
};
|
|
let out = await (0, terser_1.minify)(src, base);
|
|
if (out.code != null)
|
|
return out.code;
|
|
out = await (0, terser_1.minify)(src, Object.assign(Object.assign({}, base), { module: true }));
|
|
if (out.code != null)
|
|
return out.code;
|
|
throw new Error('terser returned empty');
|
|
}
|
|
async function stripConsoleFromBuildOutput(roots) {
|
|
const files = collectAllJsFiles(roots);
|
|
if (files.length === 0) {
|
|
console.warn('[tools] stripConsole: no .js under roots', roots);
|
|
return;
|
|
}
|
|
let ok = 0;
|
|
let fail = 0;
|
|
for (const file of files) {
|
|
try {
|
|
const src = fs_1.default.readFileSync(file, 'utf8');
|
|
const code = await minifyStripConsole(src);
|
|
fs_1.default.writeFileSync(file, code, 'utf8');
|
|
ok++;
|
|
}
|
|
catch (err) {
|
|
fail++;
|
|
console.warn(`[tools] stripConsole skip (terser error): ${file}`, err);
|
|
}
|
|
}
|
|
console.log(`[tools] stripConsole done: ok=${ok}, fail=${fail}, roots=${roots.join('; ')}`);
|
|
}
|
|
function shouldStripConsole(options) {
|
|
var _a, _b;
|
|
const v = (_b = (_a = options === null || options === void 0 ? void 0 : options.packages) === null || _a === void 0 ? void 0 : _a.tools) === null || _b === void 0 ? void 0 : _b.stripConsole;
|
|
if (v === true)
|
|
return true;
|
|
if (v === 'true' || v === 1)
|
|
return true;
|
|
return false;
|
|
}
|
|
/** Cocos engine-adapter 中 tt.createOffscreenVideo 鸿蒙暂不支持,构建后替换为带环境判断的调用 */
|
|
function patchEngineAdapterHarmony(engineAdapterPath) {
|
|
if (!fs_1.default.existsSync(engineAdapterPath)) {
|
|
return;
|
|
}
|
|
const needle = 'tt.createOffscreenVideo()';
|
|
let src = fs_1.default.readFileSync(engineAdapterPath, 'utf8');
|
|
if (!src.includes(needle)) {
|
|
console.warn(`[tools] harmony patch skip: ${needle} not found in ${engineAdapterPath}`);
|
|
return;
|
|
}
|
|
const replacement = '(function(t){try{var i=t.getSystemInfoSync(),p=String(i.platform||"").toLowerCase(),s=String(i.system||"").toLowerCase();'
|
|
+ 'if(p==="openharmony"||s.indexOf("openharmony")>=0)return null;var f=t["create"+"Offscreen"+"Video"];'
|
|
+ 'return typeof f==="function"?f.call(t):null}catch(e){return null}})(tt)';
|
|
src = src.replace(needle, replacement);
|
|
fs_1.default.writeFileSync(engineAdapterPath, src, 'utf8');
|
|
console.log(`[tools] harmony patch applied: ${engineAdapterPath}`);
|
|
}
|
|
function patchHarmonyEngineAdapter(roots) {
|
|
for (const root of roots) {
|
|
patchEngineAdapterHarmony(path_1.default.join(root, 'engine-adapter.js'));
|
|
}
|
|
}
|
|
/**
|
|
* 抖音:game.json subPackages 每项 root 下必须有 game.js。
|
|
* Cocos 3.8 开启 wasm 资源分包时会写入 `__ccWasmAssetSubpkg__` → `cocos-js/assets/`,
|
|
* 目录里通常只有 spine.js.mem*.bin,缺入口会导致开发者工具编译失败。
|
|
* @param roots 构建输出根目录列表
|
|
*/
|
|
function ensureBytedanceWasmSubpkgGameJs(roots) {
|
|
var _a, _b;
|
|
for (let r = 0; r < roots.length; r++) {
|
|
const root = roots[r];
|
|
const gameJsonPath = path_1.default.join(root, 'game.json');
|
|
if (!fs_1.default.existsSync(gameJsonPath))
|
|
continue;
|
|
let gameJson;
|
|
try {
|
|
gameJson = JSON.parse(fs_1.default.readFileSync(gameJsonPath, 'utf8'));
|
|
}
|
|
catch (err) {
|
|
console.warn('[tools] bytedance wasm subpkg: 无法解析 game.json', gameJsonPath, err);
|
|
continue;
|
|
}
|
|
const packs = gameJson.subpackages;
|
|
if (!packs || packs.length === 0)
|
|
continue;
|
|
for (let i = 0; i < packs.length; i++) {
|
|
const packRoot = String((_b = (_a = packs[i]) === null || _a === void 0 ? void 0 : _a.root) !== null && _b !== void 0 ? _b : '').replace(/\\/g, '/');
|
|
if (!packRoot)
|
|
continue;
|
|
// 仅补 wasm 资源分包;internal/main 由引擎生成完整入口
|
|
if (packRoot.indexOf('cocos-js/assets') < 0)
|
|
continue;
|
|
const dir = path_1.default.join(root, packRoot.replace(/\/+$/, ''));
|
|
if (!fs_1.default.existsSync(dir)) {
|
|
console.warn('[tools] bytedance wasm subpkg 目录不存在', dir);
|
|
continue;
|
|
}
|
|
const gameJsPath = path_1.default.join(dir, 'game.js');
|
|
if (fs_1.default.existsSync(gameJsPath))
|
|
continue;
|
|
fs_1.default.writeFileSync(gameJsPath, '// cocos wasm asset subpackage stub for bytedance\n', 'utf8');
|
|
console.log('[tools] bytedance wasm subpkg: 已补 game.js →', gameJsPath);
|
|
}
|
|
}
|
|
}
|
|
const WECHAT_ONLY_FALLBACK_FILES = ['Sdk30rWechat.ts', 'Sdk30rWechat.ts.meta'];
|
|
function getBuildPlatform(options) {
|
|
var _a, _b;
|
|
return String((_b = (_a = options === null || options === void 0 ? void 0 : options.platform) !== null && _a !== void 0 ? _a : options === null || options === void 0 ? void 0 : options.buildPlatform) !== null && _b !== void 0 ? _b : '');
|
|
}
|
|
function wechatOnlySdkPaths(projectPath) {
|
|
const srcDir = path_1.default.join(projectPath, 'tools', 'wechat-only');
|
|
const destDir = path_1.default.join(projectPath, 'assets', 'script', 'sdk');
|
|
return { srcDir, destDir };
|
|
}
|
|
/** wechat-only 目录下需复制的文件(跳过说明文档) */
|
|
function listWechatOnlyFiles(srcDir) {
|
|
if (!fs_1.default.existsSync(srcDir))
|
|
return [];
|
|
const names = fs_1.default.readdirSync(srcDir);
|
|
const out = [];
|
|
for (let i = 0; i < names.length; i++) {
|
|
const name = names[i];
|
|
if (name.endsWith('.md'))
|
|
continue;
|
|
const full = path_1.default.join(srcDir, name);
|
|
if (fs_1.default.statSync(full).isFile())
|
|
out.push(name);
|
|
}
|
|
return out;
|
|
}
|
|
/** 从 assets 删除微信独占脚本,避免残留进抖音/快手包 */
|
|
function removeWechatOnlySdkFromAssets(srcDir, destDir, platform) {
|
|
const names = listWechatOnlyFiles(srcDir);
|
|
for (let i = 0; i < WECHAT_ONLY_FALLBACK_FILES.length; i++) {
|
|
const n = WECHAT_ONLY_FALLBACK_FILES[i];
|
|
if (names.indexOf(n) < 0)
|
|
names.push(n);
|
|
}
|
|
let removed = 0;
|
|
for (let i = 0; i < names.length; i++) {
|
|
const dest = path_1.default.join(destDir, names[i]);
|
|
if (fs_1.default.existsSync(dest)) {
|
|
fs_1.default.unlinkSync(dest);
|
|
removed++;
|
|
}
|
|
}
|
|
if (removed > 0) {
|
|
console.log(`[tools] removed wechat-only 30r sdk from assets (${platform || 'unknown platform'})`);
|
|
}
|
|
}
|
|
/**
|
|
* 仅纯微信 wechatgame:把 tools/wechat-only 拷进 assets。
|
|
* 抖音/快手/B 站(勾选导出 biligame)不拷,避免 30r 进包。
|
|
*/
|
|
function syncWechatOnlySdk(options, mode) {
|
|
var _a, _b;
|
|
const projectPath = Editor.Project.path;
|
|
if (!projectPath)
|
|
return;
|
|
const { srcDir, destDir } = wechatOnlySdkPaths(projectPath);
|
|
const platform = getBuildPlatform(options);
|
|
const isWechat = platform === 'wechatgame';
|
|
const isBiliGame = !!((_b = (_a = options === null || options === void 0 ? void 0 : options.packages) === null || _a === void 0 ? void 0 : _a['biligame-builder']) === null || _b === void 0 ? void 0 : _b.isBiliGame);
|
|
if (mode === 'after' || !isWechat || isBiliGame) {
|
|
removeWechatOnlySdkFromAssets(srcDir, destDir, isBiliGame ? 'biligame' : platform);
|
|
return;
|
|
}
|
|
const files = listWechatOnlyFiles(srcDir);
|
|
if (files.length === 0) {
|
|
console.warn('[tools] wechat-only sdk missing:', srcDir);
|
|
return;
|
|
}
|
|
fs_1.default.mkdirSync(destDir, { recursive: true });
|
|
for (let i = 0; i < files.length; i++) {
|
|
const name = files[i];
|
|
fs_1.default.copyFileSync(path_1.default.join(srcDir, name), path_1.default.join(destDir, name));
|
|
}
|
|
console.log('[tools] copied wechat-only 30r sdk into assets/script/sdk');
|
|
}
|
|
function onBeforeBuild(options, _result) {
|
|
try {
|
|
syncWechatOnlySdk(options, 'before');
|
|
}
|
|
catch (err) {
|
|
console.error('[tools] onBeforeBuild syncWechatOnlySdk failed:', err);
|
|
}
|
|
try {
|
|
console.log('[tools] onBeforeBuild: generate config bin');
|
|
generateConfigBin();
|
|
}
|
|
catch (err) {
|
|
console.error('[tools] onBeforeBuild generate config bin failed:', err);
|
|
}
|
|
return true;
|
|
}
|
|
exports.onBeforeBuild = onBeforeBuild;
|
|
async function onAfterBuild(options, result) {
|
|
try {
|
|
// 产物已编译进包,assets 里的拷贝必须删掉,避免下次抖音/快手构建误打入
|
|
syncWechatOnlySdk(options, 'after');
|
|
}
|
|
catch (err) {
|
|
console.error('[tools] onAfterBuild syncWechatOnlySdk failed:', err);
|
|
}
|
|
try {
|
|
if (shouldStripConsole(options)) {
|
|
const roots = collectStripRoots(options, result);
|
|
if (roots.length === 0) {
|
|
console.warn('[tools] stripConsole 已勾选但未能解析构建输出目录(检查 result.dest / paths / buildPath+outputName)');
|
|
}
|
|
else {
|
|
console.log('[tools] onAfterBuild stripConsole →', roots.join(' | '));
|
|
await stripConsoleFromBuildOutput(roots);
|
|
}
|
|
}
|
|
}
|
|
catch (err) {
|
|
console.error('[tools] onAfterBuild stripConsole failed:', err);
|
|
}
|
|
try {
|
|
if (getBuildPlatform(options) === 'bytedance-mini-game') {
|
|
const roots = collectStripRoots(options, result);
|
|
patchHarmonyEngineAdapter(roots);
|
|
ensureBytedanceWasmSubpkgGameJs(roots);
|
|
}
|
|
}
|
|
catch (err) {
|
|
console.error('[tools] onAfterBuild bytedance patch failed:', err);
|
|
}
|
|
try {
|
|
console.log('[tools] onAfterBuild: generate config bin');
|
|
generateConfigBin();
|
|
}
|
|
catch (err) {
|
|
console.error('[tools] onAfterBuild generate config bin failed:', err);
|
|
}
|
|
return true;
|
|
}
|
|
exports.onAfterBuild = onAfterBuild;
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQtaG9va3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zb3VyY2UvYnVpbGQtaG9va3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7OztHQUdHO0FBQ0gsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUN4QixrREFBd0I7QUFDeEIsbUNBQWdDO0FBQ2hDLG1EQUl5QjtBQUVaLFFBQUEsVUFBVSxHQUFHLElBQUksQ0FBQztBQUUvQixTQUFTLFFBQVEsQ0FBQyxRQUFnQjtJQUM5QixNQUFNLEdBQUcsR0FBRyxZQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM5QyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0IsQ0FBQztBQUVELFNBQVMsd0JBQXdCLENBQUMsV0FBbUI7O0lBQ2pELE1BQU0sYUFBYSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ3hGLE1BQU0sZ0JBQWdCLEdBQUcsWUFBRSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFaEUsTUFBTSxXQUFXLEdBQUcsbUVBQW1FLENBQUM7SUFDeEYsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7SUFDNUMsSUFBSSxDQUFDLEdBQTJCLElBQUksQ0FBQztJQUNyQyxPQUFPLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxFQUFFO1FBQzdDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQzdCO0lBRUQsTUFBTSxZQUFZLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLDhEQUE4RCxDQUFDLENBQUM7SUFDNUcsTUFBTSxNQUFNLEdBQUcsTUFBQSxZQUFZLGFBQVosWUFBWSx1QkFBWixZQUFZLENBQUcsQ0FBQyxDQUFDLG1DQUFJLGVBQWUsQ0FBQztJQUNwRCxNQUFNLFNBQVMsR0FBRyxNQUFBLFNBQVMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLG1DQUFJLGVBQWUsQ0FBQztJQUMzRCxNQUFNLFVBQVUsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsR0FBRyxTQUFTLEtBQUssQ0FBQyxDQUFDO0lBQ2xHLE1BQU0sYUFBYSxHQUFHLFlBQUUsQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBRTFELE1BQU0sSUFBSSxHQUFHLE1BQUEsTUFBQSxhQUFhLENBQUMsS0FBSyxDQUFDLDZCQUE2QixDQUFDLDBDQUFHLENBQUMsQ0FBQyxtQ0FBSSxRQUFRLENBQUM7SUFDakYsTUFBTSxLQUFLLEdBQUcsTUFBQSxNQUFBLGFBQWEsQ0FBQyxLQUFLLENBQUMsOEJBQThCLENBQUMsMENBQUcsQ0FBQyxDQUFDLG1DQUFJLE9BQU8sQ0FBQztJQUNsRixPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDO0FBQzNCLENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUFDLE9BQVk7SUFDbEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMzQyxNQUFNLEtBQUssR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNuRCxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLGVBQUcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUV4RCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMxRCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDaEUsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztBQUN6QyxDQUFDO0FBRUQsTUFBTSxzQkFBc0IsR0FBNkM7SUFDckUsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUU7SUFDakQsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUU7SUFDN0MsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUU7SUFDM0MsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUU7SUFDM0MsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUU7SUFDN0MsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUU7SUFDN0MsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxpQkFBaUIsRUFBRTtJQUN2RCxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRTtJQUMvQyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRTtJQUMzQyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRTtJQUMzQyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRTtDQUN0RCxDQUFDO0FBRUYsU0FBUyxpQkFBaUI7SUFDdEIsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7SUFDeEMsTUFBTSxTQUFTLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFakYsTUFBTSxTQUFTLEdBQTRCLEVBQUUsQ0FBQztJQUM5QyxLQUFLLE1BQU0sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLElBQUksc0JBQXNCLEVBQUU7UUFDekQsTUFBTSxFQUFFLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLFlBQUUsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUU7WUFDcEIsT0FBTyxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUMvRCxPQUFPO1NBQ1Y7UUFDRCxTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0tBQ3RDO0lBRUQsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM5RCxNQUFNLFFBQVEsR0FBRyxHQUFHLElBQUksR0FBRyxLQUFLLEVBQUUsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDbEUsTUFBTSxNQUFNLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDN0MsTUFBTSxPQUFPLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxRQUFRLE1BQU0sQ0FBQyxDQUFDO0lBQ3JELFlBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDMUMsWUFBRSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztJQUN2RCxPQUFPLENBQUMsR0FBRyxDQUFDLGlDQUFpQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0FBQzVELENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxHQUFXLEVBQUUsR0FBYTtJQUM5QyxJQUFJLENBQUMsWUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7UUFBRSxPQUFPO0lBQ2hDLE1BQU0sRUFBRSxHQUFHLFlBQUUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUU7UUFBRSxPQUFPO0lBQzlCLE1BQU0sT0FBTyxHQUFHLFlBQUUsQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDN0QsS0FBSyxNQUFNLENBQUMsSUFBSSxPQUFPLEVBQUU7UUFDckIsTUFBTSxJQUFJLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFO1lBQ2pCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7U0FDN0I7YUFBTSxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUM3QyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ2xCO0tBQ0o7QUFDTCxDQUFDO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxPQUFZLEVBQUUsTUFBVzs7SUFDaEQsTUFBTSxLQUFLLEdBQUcsSUFBQSxtQ0FBbUIsR0FBVSxDQUFDO0lBQzVDLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBVSxFQUFFLEVBQUU7UUFDdkIsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQUUsT0FBTztRQUNsQyxNQUFNLENBQUMsR0FBRyxjQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLGNBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzdELElBQUk7WUFDQSxJQUFJLFlBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2xCLE1BQU0sRUFBRSxHQUFHLFlBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzFCLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtvQkFBRSxJQUFBLDZCQUFhLEVBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQ2pEO1NBQ0o7UUFBQyxXQUFNO1lBQ0osWUFBWTtTQUNmO0lBQ0wsQ0FBQyxDQUFDO0lBRUYsR0FBRyxDQUFDLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxJQUFJLENBQUMsQ0FBQztJQUNsQixHQUFHLENBQUMsTUFBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsS0FBSywwQ0FBRSxHQUFHLENBQUMsQ0FBQztJQUN4QixHQUFHLENBQUMsTUFBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsS0FBSywwQ0FBRSxNQUFNLENBQUMsQ0FBQztJQUMzQixHQUFHLENBQUMsTUFBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsS0FBSywwQ0FBRSxhQUFhLENBQUMsQ0FBQztJQUNsQyxHQUFHLENBQUMsTUFBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsS0FBSywwQ0FBRSxXQUFXLENBQUMsQ0FBQztJQUVoQyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztJQUN4QyxJQUFJLFdBQVcsS0FBSSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsU0FBUyxDQUFBLEtBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFVBQVUsQ0FBQSxFQUFFO1FBQzFELElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbkMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQ3pCLEVBQUUsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDekY7UUFDRCxHQUFHLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7S0FDMUM7SUFFRCxPQUFPLElBQUEsaUNBQWlCLEVBQUMsS0FBSyxDQUFDLENBQUM7QUFDcEMsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsS0FBZTtJQUN0QyxNQUFNLEtBQUssR0FBRyxJQUFBLG1DQUFtQixHQUFVLENBQUM7SUFDNUMsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7UUFDdEIsTUFBTSxHQUFHLEdBQWEsRUFBRSxDQUFDO1FBQ3pCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDMUIsS0FBSyxNQUFNLENBQUMsSUFBSSxHQUFHO1lBQUUsSUFBQSw2QkFBYSxFQUFDLEtBQUssRUFBRSxjQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDaEU7SUFDRCxPQUFPLElBQUEsaUNBQWlCLEVBQUMsS0FBSyxDQUFDLENBQUM7QUFDcEMsQ0FBQztBQUVELEtBQUssVUFBVSxrQkFBa0IsQ0FBQyxHQUFXO0lBQ3pDLE1BQU0sSUFBSSxHQUFHO1FBQ1QsUUFBUSxFQUFFO1lBQ04sWUFBWSxFQUFFLElBQUk7WUFDbEIsYUFBYSxFQUFFLElBQUk7WUFDbkIsTUFBTSxFQUFFLENBQUM7U0FDWjtRQUNELE1BQU0sRUFBRSxLQUFLO1FBQ2IsTUFBTSxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQWUsRUFBRTtRQUNyQyxJQUFJLEVBQUUsSUFBYTtLQUN0QixDQUFDO0lBQ0YsSUFBSSxHQUFHLEdBQUcsTUFBTSxJQUFBLGVBQU0sRUFBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDbEMsSUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLElBQUk7UUFBRSxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUM7SUFDdEMsR0FBRyxHQUFHLE1BQU0sSUFBQSxlQUFNLEVBQUMsR0FBRyxrQ0FBTyxJQUFJLEtBQUUsTUFBTSxFQUFFLElBQUksSUFBRyxDQUFDO0lBQ25ELElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxJQUFJO1FBQUUsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDO0lBQ3RDLE1BQU0sSUFBSSxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQztBQUM3QyxDQUFDO0FBRUQsS0FBSyxVQUFVLDJCQUEyQixDQUFDLEtBQWU7SUFDdEQsTUFBTSxLQUFLLEdBQUcsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUNwQixPQUFPLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hFLE9BQU87S0FDVjtJQUNELElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNYLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQztJQUNiLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO1FBQ3RCLElBQUk7WUFDQSxNQUFNLEdBQUcsR0FBRyxZQUFFLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMxQyxNQUFNLElBQUksR0FBRyxNQUFNLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzNDLFlBQUUsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNyQyxFQUFFLEVBQUUsQ0FBQztTQUNSO1FBQUMsT0FBTyxHQUFHLEVBQUU7WUFDVixJQUFJLEVBQUUsQ0FBQztZQUNQLE9BQU8sQ0FBQyxJQUFJLENBQUMsNkNBQTZDLElBQUksRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQzFFO0tBQ0o7SUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLGlDQUFpQyxFQUFFLFVBQVUsSUFBSSxXQUFXLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2hHLENBQUM7QUFFRCxTQUFTLGtCQUFrQixDQUFDLE9BQVk7O0lBQ3BDLE1BQU0sQ0FBQyxHQUFHLE1BQUEsTUFBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsUUFBUSwwQ0FBRSxLQUFLLDBDQUFFLFlBQVksQ0FBQztJQUNqRCxJQUFJLENBQUMsS0FBSyxJQUFJO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDNUIsSUFBSSxDQUFDLEtBQUssTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDekMsT0FBTyxLQUFLLENBQUM7QUFDakIsQ0FBQztBQUVELDJFQUEyRTtBQUMzRSxTQUFTLHlCQUF5QixDQUFDLGlCQUF5QjtJQUN4RCxJQUFJLENBQUMsWUFBRSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFO1FBQ25DLE9BQU87S0FDVjtJQUNELE1BQU0sTUFBTSxHQUFHLDJCQUEyQixDQUFDO0lBQzNDLElBQUksR0FBRyxHQUFHLFlBQUUsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDckQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDdkIsT0FBTyxDQUFDLElBQUksQ0FBQywrQkFBK0IsTUFBTSxpQkFBaUIsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBQ3hGLE9BQU87S0FDVjtJQUNELE1BQU0sV0FBVyxHQUNiLDJIQUEySDtVQUN6SCxzR0FBc0c7VUFDdEcseUVBQXlFLENBQUM7SUFDaEYsR0FBRyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZDLFlBQUUsQ0FBQyxhQUFhLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2pELE9BQU8sQ0FBQyxHQUFHLENBQUMsa0NBQWtDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztBQUN2RSxDQUFDO0FBRUQsU0FBUyx5QkFBeUIsQ0FBQyxLQUFlO0lBQzlDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO1FBQ3RCLHlCQUF5QixDQUFDLGNBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLG1CQUFtQixDQUFDLENBQUMsQ0FBQztLQUNuRTtBQUNMLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsK0JBQStCLENBQUMsS0FBZTs7SUFDcEQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDbkMsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sWUFBWSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxZQUFFLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQztZQUFFLFNBQVM7UUFDM0MsSUFBSSxRQUFtRSxDQUFDO1FBQ3hFLElBQUk7WUFDQSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFFLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1NBQ2hFO1FBQUMsT0FBTyxHQUFHLEVBQUU7WUFDVixPQUFPLENBQUMsSUFBSSxDQUFDLCtDQUErQyxFQUFFLFlBQVksRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNqRixTQUFTO1NBQ1o7UUFDRCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDO1FBQ25DLElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQUUsU0FBUztRQUMzQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNuQyxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsTUFBQSxNQUFBLEtBQUssQ0FBQyxDQUFDLENBQUMsMENBQUUsSUFBSSxtQ0FBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxRQUFRO2dCQUFFLFNBQVM7WUFDeEIsdUNBQXVDO1lBQ3ZDLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUM7Z0JBQUUsU0FBUztZQUN0RCxNQUFNLEdBQUcsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzFELElBQUksQ0FBQyxZQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUNyQixPQUFPLENBQUMsSUFBSSxDQUFDLHFDQUFxQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUN6RCxTQUFTO2FBQ1o7WUFDRCxNQUFNLFVBQVUsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUM3QyxJQUFJLFlBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO2dCQUFFLFNBQVM7WUFDeEMsWUFBRSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUscURBQXFELEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUYsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2Q0FBNkMsRUFBRSxVQUFVLENBQUMsQ0FBQztTQUMxRTtLQUNKO0FBQ0wsQ0FBQztBQUVELE1BQU0sMEJBQTBCLEdBQUcsQ0FBQyxpQkFBaUIsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO0FBRS9FLFNBQVMsZ0JBQWdCLENBQUMsT0FBWTs7SUFDbEMsT0FBTyxNQUFNLENBQUMsTUFBQSxNQUFBLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxRQUFRLG1DQUFJLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxhQUFhLG1DQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQ3JFLENBQUM7QUFFRCxTQUFTLGtCQUFrQixDQUFDLFdBQW1CO0lBQzNDLE1BQU0sTUFBTSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQztJQUM5RCxNQUFNLE9BQU8sR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ2xFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUM7QUFDL0IsQ0FBQztBQUVELG9DQUFvQztBQUNwQyxTQUFTLG1CQUFtQixDQUFDLE1BQWM7SUFDdkMsSUFBSSxDQUFDLFlBQUUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDdEMsTUFBTSxLQUFLLEdBQUcsWUFBRSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNyQyxNQUFNLEdBQUcsR0FBYSxFQUFFLENBQUM7SUFDekIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDbkMsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFBRSxTQUFTO1FBQ25DLE1BQU0sSUFBSSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3JDLElBQUksWUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUU7WUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ2xEO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDZixDQUFDO0FBRUQsb0NBQW9DO0FBQ3BDLFNBQVMsNkJBQTZCLENBQUMsTUFBYyxFQUFFLE9BQWUsRUFBRSxRQUFnQjtJQUNwRixNQUFNLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsMEJBQTBCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ3hELE1BQU0sQ0FBQyxHQUFHLDBCQUEwQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUMzQztJQUNELElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztJQUNoQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUNuQyxNQUFNLElBQUksR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxQyxJQUFJLFlBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDckIsWUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwQixPQUFPLEVBQUUsQ0FBQztTQUNiO0tBQ0o7SUFDRCxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUU7UUFDYixPQUFPLENBQUMsR0FBRyxDQUFDLG9EQUFvRCxRQUFRLElBQUksa0JBQWtCLEdBQUcsQ0FBQyxDQUFDO0tBQ3RHO0FBQ0wsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsaUJBQWlCLENBQUMsT0FBWSxFQUFFLElBQXdCOztJQUM3RCxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztJQUN4QyxJQUFJLENBQUMsV0FBVztRQUFFLE9BQU87SUFFekIsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM1RCxNQUFNLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMzQyxNQUFNLFFBQVEsR0FBRyxRQUFRLEtBQUssWUFBWSxDQUFDO0lBQzNDLE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFBLE1BQUEsTUFBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsUUFBUSwwQ0FBRyxrQkFBa0IsQ0FBQywwQ0FBRSxVQUFVLENBQUEsQ0FBQztJQUV6RSxJQUFJLElBQUksS0FBSyxPQUFPLElBQUksQ0FBQyxRQUFRLElBQUksVUFBVSxFQUFFO1FBQzdDLDZCQUE2QixDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ25GLE9BQU87S0FDVjtJQUVELE1BQU0sS0FBSyxHQUFHLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzFDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7UUFDcEIsT0FBTyxDQUFDLElBQUksQ0FBQyxrQ0FBa0MsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN6RCxPQUFPO0tBQ1Y7SUFDRCxZQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ25DLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixZQUFFLENBQUMsWUFBWSxDQUFDLGNBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFLGNBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7S0FDdEU7SUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLDJEQUEyRCxDQUFDLENBQUM7QUFDN0UsQ0FBQztBQUVELFNBQWdCLGFBQWEsQ0FBQyxPQUFZLEVBQUUsT0FBWTtJQUNwRCxJQUFJO1FBQ0EsaUJBQWlCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0tBQ3hDO0lBQUMsT0FBTyxHQUFHLEVBQUU7UUFDVixPQUFPLENBQUMsS0FBSyxDQUFDLGlEQUFpRCxFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBQ3pFO0lBQ0QsSUFBSTtRQUNBLE9BQU8sQ0FBQyxHQUFHLENBQUMsNENBQTRDLENBQUMsQ0FBQztRQUMxRCxpQkFBaUIsRUFBRSxDQUFDO0tBQ3ZCO0lBQUMsT0FBTyxHQUFHLEVBQUU7UUFDVixPQUFPLENBQUMsS0FBSyxDQUFDLG1EQUFtRCxFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBQzNFO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDaEIsQ0FBQztBQWJELHNDQWFDO0FBRU0sS0FBSyxVQUFVLFlBQVksQ0FBQyxPQUFZLEVBQUUsTUFBVztJQUN4RCxJQUFJO1FBQ0EseUNBQXlDO1FBQ3pDLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztLQUN2QztJQUFDLE9BQU8sR0FBRyxFQUFFO1FBQ1YsT0FBTyxDQUFDLEtBQUssQ0FBQyxnREFBZ0QsRUFBRSxHQUFHLENBQUMsQ0FBQztLQUN4RTtJQUNELElBQUk7UUFDQSxJQUFJLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzdCLE1BQU0sS0FBSyxHQUFHLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNqRCxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUNwQixPQUFPLENBQUMsSUFBSSxDQUNSLG9GQUFvRixDQUN2RixDQUFDO2FBQ0w7aUJBQU07Z0JBQ0gsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQ0FBcUMsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ3RFLE1BQU0sMkJBQTJCLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDNUM7U0FDSjtLQUNKO0lBQUMsT0FBTyxHQUFHLEVBQUU7UUFDVixPQUFPLENBQUMsS0FBSyxDQUFDLDJDQUEyQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBQ25FO0lBQ0QsSUFBSTtRQUNBLElBQUksZ0JBQWdCLENBQUMsT0FBTyxDQUFDLEtBQUsscUJBQXFCLEVBQUU7WUFDckQsTUFBTSxLQUFLLEdBQUcsaUJBQWlCLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ2pELHlCQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2pDLCtCQUErQixDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzFDO0tBQ0o7SUFBQyxPQUFPLEdBQUcsRUFBRTtRQUNWLE9BQU8sQ0FBQyxLQUFLLENBQUMsOENBQThDLEVBQUUsR0FBRyxDQUFDLENBQUM7S0FDdEU7SUFDRCxJQUFJO1FBQ0EsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO1FBQ3pELGlCQUFpQixFQUFFLENBQUM7S0FDdkI7SUFBQyxPQUFPLEdBQUcsRUFBRTtRQUNWLE9BQU8sQ0FBQyxLQUFLLENBQUMsa0RBQWtELEVBQUUsR0FBRyxDQUFDLENBQUM7S0FDMUU7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBdENELG9DQXNDQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiDmnoTlu7rov5vnqIvvvIjni6znq4sgd29ya2Vy77yJ5Yqg6L2955qE6ZKp5a2Q6ISa5pys77ybY3VzdG9tLWJ1aWxkZXIg55qEIGNvbmZpZ3MuKi5ob29rcyDmjIflkJHmnKzmlofku7bjgIJcclxuICogY3VzdG9tLWJ1aWxkZXIudHMg5LyaIHJlLWV4cG9ydCDmnKzmlofku7bnmoTpkqnlrZDvvIzkvpvnvJbovpHlmajmoKHpqozpgJrov4fjgIJcclxuICovXHJcbmltcG9ydCBmcyBmcm9tICdmcyc7XHJcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xyXG5pbXBvcnQgbHo0IGZyb20gJ2x6NGpzJztcclxuaW1wb3J0IHsgbWluaWZ5IH0gZnJvbSAndGVyc2VyJztcclxuaW1wb3J0IHtcclxuICAgIGNyZWF0ZU1lbWJlcnNoaXBTZXQsXHJcbiAgICBtZW1iZXJzaGlwQWRkLFxyXG4gICAgbWVtYmVyc2hpcFRvQXJyYXksXHJcbn0gZnJvbSAnLi9NZW1iZXJzaGlwU2V0JztcclxuXHJcbmV4cG9ydCBjb25zdCB0aHJvd0Vycm9yID0gdHJ1ZTtcclxuXHJcbmZ1bmN0aW9uIHJlYWRKc29uKGZpbGVQYXRoOiBzdHJpbmcpIHtcclxuICAgIGNvbnN0IHJhdyA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgJ3V0ZjgnKTtcclxuICAgIHJldHVybiBKU09OLnBhcnNlKHJhdyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlc29sdmVDb25maWdOYW1lVmVyc2lvbihwcm9qZWN0UGF0aDogc3RyaW5nKSB7XHJcbiAgICBjb25zdCBzZGtDb25maWdQYXRoID0gcGF0aC5qb2luKHByb2plY3RQYXRoLCAnYXNzZXRzJywgJ3NjcmlwdCcsICdzZGsnLCAnc2RrQ29uZmlnLnRzJyk7XHJcbiAgICBjb25zdCBzZGtDb25maWdDb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHNka0NvbmZpZ1BhdGgsICd1dGY4Jyk7XHJcblxyXG4gICAgY29uc3QgaW1wb3J0UmVnZXggPSAvaW1wb3J0XFxzK1xce1xccyooXFx3KylcXHMqXFx9XFxzK2Zyb21cXHMrW1wiJ11cXC5cXC9jb25maWdcXC8oW15cIiddKylbXCInXTs/L2c7XHJcbiAgICBjb25zdCBpbXBvcnRNYXAgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xyXG4gICAgbGV0IG06IFJlZ0V4cEV4ZWNBcnJheSB8IG51bGwgPSBudWxsO1xyXG4gICAgd2hpbGUgKChtID0gaW1wb3J0UmVnZXguZXhlYyhzZGtDb25maWdDb250ZW50KSkpIHtcclxuICAgICAgICBpbXBvcnRNYXAuc2V0KG1bMV0sIG1bMl0pO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGNvbmZpZ0Fzc2lnbiA9IHNka0NvbmZpZ0NvbnRlbnQubWF0Y2goL3N0YXRpY1xccytyZWFkb25seVxccytjb25maWdcXHMqOlxccypJQ29uZmlnRGF0YVxccyo9XFxzKihcXHcrKVxccyo7Lyk7XHJcbiAgICBjb25zdCBzeW1ib2wgPSBjb25maWdBc3NpZ24/LlsxXSA/PyAnRGVmYXVsdENvbmZpZyc7XHJcbiAgICBjb25zdCByZWxDb25maWcgPSBpbXBvcnRNYXAuZ2V0KHN5bWJvbCkgPz8gJ0RlZmF1bHRDb25maWcnO1xyXG4gICAgY29uc3QgY29uZmlnUGF0aCA9IHBhdGguam9pbihwcm9qZWN0UGF0aCwgJ2Fzc2V0cycsICdzY3JpcHQnLCAnc2RrJywgJ2NvbmZpZycsIGAke3JlbENvbmZpZ30udHNgKTtcclxuICAgIGNvbnN0IGNvbmZpZ0NvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoY29uZmlnUGF0aCwgJ3V0ZjgnKTtcclxuXHJcbiAgICBjb25zdCBuYW1lID0gY29uZmlnQ29udGVudC5tYXRjaCgvbmFtZVxccyo6XFxzKltcIiddKFteXCInXSspW1wiJ10vKT8uWzFdID8/ICdjb25maWcnO1xyXG4gICAgY29uc3QgdnNpb24gPSBjb25maWdDb250ZW50Lm1hdGNoKC92c2lvblxccyo6XFxzKltcIiddKFteXCInXSspW1wiJ10vKT8uWzFdID8/ICcwLjAuMCc7XHJcbiAgICByZXR1cm4geyBuYW1lLCB2c2lvbiB9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBlbmNvZGVGb3JSdW50aW1lKGpzb25PYmo6IGFueSkge1xyXG4gICAgY29uc3QganNvblN0cmluZyA9IEpTT04uc3RyaW5naWZ5KGpzb25PYmopO1xyXG4gICAgY29uc3QgdWludDggPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoanNvblN0cmluZyk7XHJcbiAgICBjb25zdCBjb21wcmVzc2VkID0gVWludDhBcnJheS5mcm9tKGx6NC5jb21wcmVzcyh1aW50OCkpO1xyXG5cclxuICAgIGNvbnN0IGJpbmFyeSA9IEJ1ZmZlci5mcm9tKGNvbXByZXNzZWQpLnRvU3RyaW5nKCdsYXRpbjEnKTtcclxuICAgIGNvbnN0IGJhc2U2NCA9IEJ1ZmZlci5mcm9tKGJpbmFyeSwgJ2xhdGluMScpLnRvU3RyaW5nKCdiYXNlNjQnKTtcclxuICAgIHJldHVybiBCdWZmZXIuZnJvbShiYXNlNjQsICdsYXRpbjEnKTtcclxufVxyXG5cclxuY29uc3QgSE9UX1VQREFURV9UQUJMRV9GSUxFUzogeyB0YWJsZUtleTogc3RyaW5nOyBmaWxlTmFtZTogc3RyaW5nIH1bXSA9IFtcclxuICAgIHsgdGFibGVLZXk6ICdNb25zdGVyJywgZmlsZU5hbWU6ICdNb25zdGVyLmpzb24nIH0sXHJcbiAgICB7IHRhYmxlS2V5OiAnQ29uc3QnLCBmaWxlTmFtZTogJ0NvbnN0Lmpzb24nIH0sXHJcbiAgICB7IHRhYmxlS2V5OiAnUmFuaycsIGZpbGVOYW1lOiAnUmFuay5qc29uJyB9LFxyXG4gICAgeyB0YWJsZUtleTogJ0l0ZW0nLCBmaWxlTmFtZTogJ0l0ZW0uanNvbicgfSxcclxuICAgIHsgdGFibGVLZXk6ICdMZXZlbCcsIGZpbGVOYW1lOiAnTGV2ZWwuanNvbicgfSxcclxuICAgIHsgdGFibGVLZXk6ICdTa2lsbCcsIGZpbGVOYW1lOiAnU2tpbGwuanNvbicgfSxcclxuICAgIHsgdGFibGVLZXk6ICdCYXR0bGVidWZmJywgZmlsZU5hbWU6ICdCYXR0bGVidWZmLmpzb24nIH0sXHJcbiAgICB7IHRhYmxlS2V5OiAnV2VhcG9uJywgZmlsZU5hbWU6ICdXZWFwb24uanNvbicgfSxcclxuICAgIHsgdGFibGVLZXk6ICdUZXh0JywgZmlsZU5hbWU6ICdUZXh0Lmpzb24nIH0sXHJcbiAgICB7IHRhYmxlS2V5OiAnSGVybycsIGZpbGVOYW1lOiAnSGVyby5qc29uJyB9LFxyXG4gICAgeyB0YWJsZUtleTogJ0hlYWRpY29uJywgZmlsZU5hbWU6ICdIZWFkaWNvbi5qc29uJyB9LFxyXG5dO1xyXG5cclxuZnVuY3Rpb24gZ2VuZXJhdGVDb25maWdCaW4oKSB7XHJcbiAgICBjb25zdCBwcm9qZWN0UGF0aCA9IEVkaXRvci5Qcm9qZWN0LnBhdGg7XHJcbiAgICBjb25zdCBjb25maWdEaXIgPSBwYXRoLmpvaW4ocHJvamVjdFBhdGgsICdhc3NldHMnLCAnYnVuZGxlcycsICdmaXJzdCcsICdjb25maWcnKTtcclxuXHJcbiAgICBjb25zdCBtZXJnZUpzb246IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XHJcbiAgICBmb3IgKGNvbnN0IHsgdGFibGVLZXksIGZpbGVOYW1lIH0gb2YgSE9UX1VQREFURV9UQUJMRV9GSUxFUykge1xyXG4gICAgICAgIGNvbnN0IGZwID0gcGF0aC5qb2luKGNvbmZpZ0RpciwgZmlsZU5hbWUpO1xyXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyhmcCkpIHtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKGBbdG9vbHNdIHNraXAgYmluIGdlbmVyYXRlOiBtaXNzaW5nICR7ZmlsZU5hbWV9YCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgbWVyZ2VKc29uW3RhYmxlS2V5XSA9IHJlYWRKc29uKGZwKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB7IG5hbWUsIHZzaW9uIH0gPSByZXNvbHZlQ29uZmlnTmFtZVZlcnNpb24ocHJvamVjdFBhdGgpO1xyXG4gICAgY29uc3Qgc2FmZU5hbWUgPSBgJHtuYW1lfSR7dnNpb259YC5yZXBsYWNlKC9bPD46XCIvXFxcXHw/Kl0rL2csICdfJyk7XHJcbiAgICBjb25zdCBvdXREaXIgPSBwYXRoLmpvaW4ocHJvamVjdFBhdGgsICdiaW4nKTtcclxuICAgIGNvbnN0IG91dEZpbGUgPSBwYXRoLmpvaW4ob3V0RGlyLCBgJHtzYWZlTmFtZX0uYmluYCk7XHJcbiAgICBmcy5ta2RpclN5bmMob3V0RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcclxuICAgIGZzLndyaXRlRmlsZVN5bmMob3V0RmlsZSwgZW5jb2RlRm9yUnVudGltZShtZXJnZUpzb24pKTtcclxuICAgIGNvbnNvbGUubG9nKGBbdG9vbHNdIGdlbmVyYXRlZCBjb25maWcgYmluOiAke291dEZpbGV9YCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNvbGxlY3RKc0ZpbGVzKGRpcjogc3RyaW5nLCBhY2M6IHN0cmluZ1tdKSB7XHJcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZGlyKSkgcmV0dXJuO1xyXG4gICAgY29uc3Qgc3QgPSBmcy5zdGF0U3luYyhkaXIpO1xyXG4gICAgaWYgKCFzdC5pc0RpcmVjdG9yeSgpKSByZXR1cm47XHJcbiAgICBjb25zdCBlbnRyaWVzID0gZnMucmVhZGRpclN5bmMoZGlyLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XHJcbiAgICBmb3IgKGNvbnN0IGUgb2YgZW50cmllcykge1xyXG4gICAgICAgIGNvbnN0IGZ1bGwgPSBwYXRoLmpvaW4oZGlyLCBlLm5hbWUpO1xyXG4gICAgICAgIGlmIChlLmlzRGlyZWN0b3J5KCkpIHtcclxuICAgICAgICAgICAgY29sbGVjdEpzRmlsZXMoZnVsbCwgYWNjKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGUuaXNGaWxlKCkgJiYgZS5uYW1lLmVuZHNXaXRoKCcuanMnKSkge1xyXG4gICAgICAgICAgICBhY2MucHVzaChmdWxsKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNvbGxlY3RTdHJpcFJvb3RzKG9wdGlvbnM6IGFueSwgcmVzdWx0OiBhbnkpOiBzdHJpbmdbXSB7XHJcbiAgICBjb25zdCByb290cyA9IGNyZWF0ZU1lbWJlcnNoaXBTZXQ8c3RyaW5nPigpO1xyXG4gICAgY29uc3QgYWRkID0gKHA6IHVua25vd24pID0+IHtcclxuICAgICAgICBpZiAocCA9PSBudWxsIHx8IHAgPT09ICcnKSByZXR1cm47XHJcbiAgICAgICAgY29uc3QgcyA9IHBhdGgubm9ybWFsaXplKFN0cmluZyhwKS5yZXBsYWNlKC9cXC8vZywgcGF0aC5zZXApKTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhzKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3QgPSBmcy5zdGF0U3luYyhzKTtcclxuICAgICAgICAgICAgICAgIGlmIChzdC5pc0RpcmVjdG9yeSgpKSBtZW1iZXJzaGlwQWRkKHJvb3RzLCBzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gY2F0Y2gge1xyXG4gICAgICAgICAgICAvKiBpZ25vcmUgKi9cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIGFkZChyZXN1bHQ/LmRlc3QpO1xyXG4gICAgYWRkKHJlc3VsdD8ucGF0aHM/LmRpcik7XHJcbiAgICBhZGQocmVzdWx0Py5wYXRocz8uYXNzZXRzKTtcclxuICAgIGFkZChyZXN1bHQ/LnBhdGhzPy5idW5kbGVTY3JpcHRzKTtcclxuICAgIGFkZChyZXN1bHQ/LnBhdGhzPy5zdWJwYWNrYWdlcyk7XHJcblxyXG4gICAgY29uc3QgcHJvamVjdFBhdGggPSBFZGl0b3IuUHJvamVjdC5wYXRoO1xyXG4gICAgaWYgKHByb2plY3RQYXRoICYmIG9wdGlvbnM/LmJ1aWxkUGF0aCAmJiBvcHRpb25zPy5vdXRwdXROYW1lKSB7XHJcbiAgICAgICAgbGV0IGJwID0gU3RyaW5nKG9wdGlvbnMuYnVpbGRQYXRoKTtcclxuICAgICAgICBpZiAoYnAuaW5jbHVkZXMoJ3Byb2plY3Q6JykpIHtcclxuICAgICAgICAgICAgYnAgPSBwYXRoLmpvaW4ocHJvamVjdFBhdGgsIGJwLnJlcGxhY2UoL15wcm9qZWN0OlxcL1xcLy8sICcnKS5yZXBsYWNlKC9ecHJvamVjdDovLCAnJykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBhZGQocGF0aC5qb2luKGJwLCBvcHRpb25zLm91dHB1dE5hbWUpKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbWVtYmVyc2hpcFRvQXJyYXkocm9vdHMpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb2xsZWN0QWxsSnNGaWxlcyhyb290czogc3RyaW5nW10pOiBzdHJpbmdbXSB7XHJcbiAgICBjb25zdCBmaWxlcyA9IGNyZWF0ZU1lbWJlcnNoaXBTZXQ8c3RyaW5nPigpO1xyXG4gICAgZm9yIChjb25zdCByb290IG9mIHJvb3RzKSB7XHJcbiAgICAgICAgY29uc3QgYWNjOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgICAgIGNvbGxlY3RKc0ZpbGVzKHJvb3QsIGFjYyk7XHJcbiAgICAgICAgZm9yIChjb25zdCBmIG9mIGFjYykgbWVtYmVyc2hpcEFkZChmaWxlcywgcGF0aC5ub3JtYWxpemUoZikpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG1lbWJlcnNoaXBUb0FycmF5KGZpbGVzKTtcclxufVxyXG5cclxuYXN5bmMgZnVuY3Rpb24gbWluaWZ5U3RyaXBDb25zb2xlKHNyYzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcclxuICAgIGNvbnN0IGJhc2UgPSB7XHJcbiAgICAgICAgY29tcHJlc3M6IHtcclxuICAgICAgICAgICAgZHJvcF9jb25zb2xlOiB0cnVlLFxyXG4gICAgICAgICAgICBkcm9wX2RlYnVnZ2VyOiB0cnVlLFxyXG4gICAgICAgICAgICBwYXNzZXM6IDIsXHJcbiAgICAgICAgfSxcclxuICAgICAgICBtYW5nbGU6IGZhbHNlLFxyXG4gICAgICAgIGZvcm1hdDogeyBjb21tZW50czogJ3NvbWUnIGFzIGNvbnN0IH0sXHJcbiAgICAgICAgZWNtYTogMjAyMCBhcyBjb25zdCxcclxuICAgIH07XHJcbiAgICBsZXQgb3V0ID0gYXdhaXQgbWluaWZ5KHNyYywgYmFzZSk7XHJcbiAgICBpZiAob3V0LmNvZGUgIT0gbnVsbCkgcmV0dXJuIG91dC5jb2RlO1xyXG4gICAgb3V0ID0gYXdhaXQgbWluaWZ5KHNyYywgeyAuLi5iYXNlLCBtb2R1bGU6IHRydWUgfSk7XHJcbiAgICBpZiAob3V0LmNvZGUgIT0gbnVsbCkgcmV0dXJuIG91dC5jb2RlO1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKCd0ZXJzZXIgcmV0dXJuZWQgZW1wdHknKTtcclxufVxyXG5cclxuYXN5bmMgZnVuY3Rpb24gc3RyaXBDb25zb2xlRnJvbUJ1aWxkT3V0cHV0KHJvb3RzOiBzdHJpbmdbXSkge1xyXG4gICAgY29uc3QgZmlsZXMgPSBjb2xsZWN0QWxsSnNGaWxlcyhyb290cyk7XHJcbiAgICBpZiAoZmlsZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgY29uc29sZS53YXJuKCdbdG9vbHNdIHN0cmlwQ29uc29sZTogbm8gLmpzIHVuZGVyIHJvb3RzJywgcm9vdHMpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBvayA9IDA7XHJcbiAgICBsZXQgZmFpbCA9IDA7XHJcbiAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXMpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCBzcmMgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZSwgJ3V0ZjgnKTtcclxuICAgICAgICAgICAgY29uc3QgY29kZSA9IGF3YWl0IG1pbmlmeVN0cmlwQ29uc29sZShzcmMpO1xyXG4gICAgICAgICAgICBmcy53cml0ZUZpbGVTeW5jKGZpbGUsIGNvZGUsICd1dGY4Jyk7XHJcbiAgICAgICAgICAgIG9rKys7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIGZhaWwrKztcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKGBbdG9vbHNdIHN0cmlwQ29uc29sZSBza2lwICh0ZXJzZXIgZXJyb3IpOiAke2ZpbGV9YCwgZXJyKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBjb25zb2xlLmxvZyhgW3Rvb2xzXSBzdHJpcENvbnNvbGUgZG9uZTogb2s9JHtva30sIGZhaWw9JHtmYWlsfSwgcm9vdHM9JHtyb290cy5qb2luKCc7ICcpfWApO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzaG91bGRTdHJpcENvbnNvbGUob3B0aW9uczogYW55KTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCB2ID0gb3B0aW9ucz8ucGFja2FnZXM/LnRvb2xzPy5zdHJpcENvbnNvbGU7XHJcbiAgICBpZiAodiA9PT0gdHJ1ZSkgcmV0dXJuIHRydWU7XHJcbiAgICBpZiAodiA9PT0gJ3RydWUnIHx8IHYgPT09IDEpIHJldHVybiB0cnVlO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG59XHJcblxyXG4vKiogQ29jb3MgZW5naW5lLWFkYXB0ZXIg5LitIHR0LmNyZWF0ZU9mZnNjcmVlblZpZGVvIOm4v+iSmeaaguS4jeaUr+aMge+8jOaehOW7uuWQjuabv+aNouS4uuW4pueOr+Wig+WIpOaWreeahOiwg+eUqCAqL1xyXG5mdW5jdGlvbiBwYXRjaEVuZ2luZUFkYXB0ZXJIYXJtb255KGVuZ2luZUFkYXB0ZXJQYXRoOiBzdHJpbmcpIHtcclxuICAgIGlmICghZnMuZXhpc3RzU3luYyhlbmdpbmVBZGFwdGVyUGF0aCkpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBuZWVkbGUgPSAndHQuY3JlYXRlT2Zmc2NyZWVuVmlkZW8oKSc7XHJcbiAgICBsZXQgc3JjID0gZnMucmVhZEZpbGVTeW5jKGVuZ2luZUFkYXB0ZXJQYXRoLCAndXRmOCcpO1xyXG4gICAgaWYgKCFzcmMuaW5jbHVkZXMobmVlZGxlKSkge1xyXG4gICAgICAgIGNvbnNvbGUud2FybihgW3Rvb2xzXSBoYXJtb255IHBhdGNoIHNraXA6ICR7bmVlZGxlfSBub3QgZm91bmQgaW4gJHtlbmdpbmVBZGFwdGVyUGF0aH1gKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCByZXBsYWNlbWVudCA9XHJcbiAgICAgICAgJyhmdW5jdGlvbih0KXt0cnl7dmFyIGk9dC5nZXRTeXN0ZW1JbmZvU3luYygpLHA9U3RyaW5nKGkucGxhdGZvcm18fFwiXCIpLnRvTG93ZXJDYXNlKCkscz1TdHJpbmcoaS5zeXN0ZW18fFwiXCIpLnRvTG93ZXJDYXNlKCk7J1xyXG4gICAgICAgICsgJ2lmKHA9PT1cIm9wZW5oYXJtb255XCJ8fHMuaW5kZXhPZihcIm9wZW5oYXJtb255XCIpPj0wKXJldHVybiBudWxsO3ZhciBmPXRbXCJjcmVhdGVcIitcIk9mZnNjcmVlblwiK1wiVmlkZW9cIl07J1xyXG4gICAgICAgICsgJ3JldHVybiB0eXBlb2YgZj09PVwiZnVuY3Rpb25cIj9mLmNhbGwodCk6bnVsbH1jYXRjaChlKXtyZXR1cm4gbnVsbH19KSh0dCknO1xyXG4gICAgc3JjID0gc3JjLnJlcGxhY2UobmVlZGxlLCByZXBsYWNlbWVudCk7XHJcbiAgICBmcy53cml0ZUZpbGVTeW5jKGVuZ2luZUFkYXB0ZXJQYXRoLCBzcmMsICd1dGY4Jyk7XHJcbiAgICBjb25zb2xlLmxvZyhgW3Rvb2xzXSBoYXJtb255IHBhdGNoIGFwcGxpZWQ6ICR7ZW5naW5lQWRhcHRlclBhdGh9YCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHBhdGNoSGFybW9ueUVuZ2luZUFkYXB0ZXIocm9vdHM6IHN0cmluZ1tdKSB7XHJcbiAgICBmb3IgKGNvbnN0IHJvb3Qgb2Ygcm9vdHMpIHtcclxuICAgICAgICBwYXRjaEVuZ2luZUFkYXB0ZXJIYXJtb255KHBhdGguam9pbihyb290LCAnZW5naW5lLWFkYXB0ZXIuanMnKSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiDmipbpn7PvvJpnYW1lLmpzb24gc3ViUGFja2FnZXMg5q+P6aG5IHJvb3Qg5LiL5b+F6aG75pyJIGdhbWUuanPjgIJcclxuICogQ29jb3MgMy44IOW8gOWQryB3YXNtIOi1hOa6kOWIhuWMheaXtuS8muWGmeWFpSBgX19jY1dhc21Bc3NldFN1YnBrZ19fYCDihpIgYGNvY29zLWpzL2Fzc2V0cy9g77yMXHJcbiAqIOebruW9lemHjOmAmuW4uOWPquaciSBzcGluZS5qcy5tZW0qLmJpbu+8jOe8uuWFpeWPo+S8muWvvOiHtOW8gOWPkeiAheW3peWFt+e8luivkeWksei0peOAglxyXG4gKiBAcGFyYW0gcm9vdHMg5p6E5bu66L6T5Ye65qC555uu5b2V5YiX6KGoXHJcbiAqL1xyXG5mdW5jdGlvbiBlbnN1cmVCeXRlZGFuY2VXYXNtU3VicGtnR2FtZUpzKHJvb3RzOiBzdHJpbmdbXSkge1xyXG4gICAgZm9yIChsZXQgciA9IDA7IHIgPCByb290cy5sZW5ndGg7IHIrKykge1xyXG4gICAgICAgIGNvbnN0IHJvb3QgPSByb290c1tyXTtcclxuICAgICAgICBjb25zdCBnYW1lSnNvblBhdGggPSBwYXRoLmpvaW4ocm9vdCwgJ2dhbWUuanNvbicpO1xyXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyhnYW1lSnNvblBhdGgpKSBjb250aW51ZTtcclxuICAgICAgICBsZXQgZ2FtZUpzb246IHsgc3VicGFja2FnZXM/OiBBcnJheTx7IG5hbWU/OiBzdHJpbmc7IHJvb3Q/OiBzdHJpbmcgfT4gfTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBnYW1lSnNvbiA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGdhbWVKc29uUGF0aCwgJ3V0ZjgnKSk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignW3Rvb2xzXSBieXRlZGFuY2Ugd2FzbSBzdWJwa2c6IOaXoOazleino+aekCBnYW1lLmpzb24nLCBnYW1lSnNvblBhdGgsIGVycik7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBwYWNrcyA9IGdhbWVKc29uLnN1YnBhY2thZ2VzO1xyXG4gICAgICAgIGlmICghcGFja3MgfHwgcGFja3MubGVuZ3RoID09PSAwKSBjb250aW51ZTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhY2tzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhY2tSb290ID0gU3RyaW5nKHBhY2tzW2ldPy5yb290ID8/ICcnKS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XHJcbiAgICAgICAgICAgIGlmICghcGFja1Jvb3QpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAvLyDku4XooaUgd2FzbSDotYTmupDliIbljIXvvJtpbnRlcm5hbC9tYWluIOeUseW8leaTjueUn+aIkOWujOaVtOWFpeWPo1xyXG4gICAgICAgICAgICBpZiAocGFja1Jvb3QuaW5kZXhPZignY29jb3MtanMvYXNzZXRzJykgPCAwKSBjb250aW51ZTtcclxuICAgICAgICAgICAgY29uc3QgZGlyID0gcGF0aC5qb2luKHJvb3QsIHBhY2tSb290LnJlcGxhY2UoL1xcLyskLywgJycpKTtcclxuICAgICAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGRpcikpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignW3Rvb2xzXSBieXRlZGFuY2Ugd2FzbSBzdWJwa2cg55uu5b2V5LiN5a2Y5ZyoJywgZGlyKTtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGdhbWVKc1BhdGggPSBwYXRoLmpvaW4oZGlyLCAnZ2FtZS5qcycpO1xyXG4gICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhnYW1lSnNQYXRoKSkgY29udGludWU7XHJcbiAgICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMoZ2FtZUpzUGF0aCwgJy8vIGNvY29zIHdhc20gYXNzZXQgc3VicGFja2FnZSBzdHViIGZvciBieXRlZGFuY2VcXG4nLCAndXRmOCcpO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnW3Rvb2xzXSBieXRlZGFuY2Ugd2FzbSBzdWJwa2c6IOW3suihpSBnYW1lLmpzIOKGkicsIGdhbWVKc1BhdGgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuY29uc3QgV0VDSEFUX09OTFlfRkFMTEJBQ0tfRklMRVMgPSBbJ1NkazMwcldlY2hhdC50cycsICdTZGszMHJXZWNoYXQudHMubWV0YSddO1xyXG5cclxuZnVuY3Rpb24gZ2V0QnVpbGRQbGF0Zm9ybShvcHRpb25zOiBhbnkpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIFN0cmluZyhvcHRpb25zPy5wbGF0Zm9ybSA/PyBvcHRpb25zPy5idWlsZFBsYXRmb3JtID8/ICcnKTtcclxufVxyXG5cclxuZnVuY3Rpb24gd2VjaGF0T25seVNka1BhdGhzKHByb2plY3RQYXRoOiBzdHJpbmcpIHtcclxuICAgIGNvbnN0IHNyY0RpciA9IHBhdGguam9pbihwcm9qZWN0UGF0aCwgJ3Rvb2xzJywgJ3dlY2hhdC1vbmx5Jyk7XHJcbiAgICBjb25zdCBkZXN0RGlyID0gcGF0aC5qb2luKHByb2plY3RQYXRoLCAnYXNzZXRzJywgJ3NjcmlwdCcsICdzZGsnKTtcclxuICAgIHJldHVybiB7IHNyY0RpciwgZGVzdERpciB9O1xyXG59XHJcblxyXG4vKiogd2VjaGF0LW9ubHkg55uu5b2V5LiL6ZyA5aSN5Yi255qE5paH5Lu277yI6Lez6L+H6K+05piO5paH5qGj77yJICovXHJcbmZ1bmN0aW9uIGxpc3RXZWNoYXRPbmx5RmlsZXMoc3JjRGlyOiBzdHJpbmcpOiBzdHJpbmdbXSB7XHJcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoc3JjRGlyKSkgcmV0dXJuIFtdO1xyXG4gICAgY29uc3QgbmFtZXMgPSBmcy5yZWFkZGlyU3luYyhzcmNEaXIpO1xyXG4gICAgY29uc3Qgb3V0OiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IG5hbWUgPSBuYW1lc1tpXTtcclxuICAgICAgICBpZiAobmFtZS5lbmRzV2l0aCgnLm1kJykpIGNvbnRpbnVlO1xyXG4gICAgICAgIGNvbnN0IGZ1bGwgPSBwYXRoLmpvaW4oc3JjRGlyLCBuYW1lKTtcclxuICAgICAgICBpZiAoZnMuc3RhdFN5bmMoZnVsbCkuaXNGaWxlKCkpIG91dC5wdXNoKG5hbWUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG91dDtcclxufVxyXG5cclxuLyoqIOS7jiBhc3NldHMg5Yig6Zmk5b6u5L+h54us5Y2g6ISa5pys77yM6YG/5YWN5q6L55WZ6L+b5oqW6Z+zL+W/q+aJi+WMhSAqL1xyXG5mdW5jdGlvbiByZW1vdmVXZWNoYXRPbmx5U2RrRnJvbUFzc2V0cyhzcmNEaXI6IHN0cmluZywgZGVzdERpcjogc3RyaW5nLCBwbGF0Zm9ybTogc3RyaW5nKSB7XHJcbiAgICBjb25zdCBuYW1lcyA9IGxpc3RXZWNoYXRPbmx5RmlsZXMoc3JjRGlyKTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgV0VDSEFUX09OTFlfRkFMTEJBQ0tfRklMRVMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCBuID0gV0VDSEFUX09OTFlfRkFMTEJBQ0tfRklMRVNbaV07XHJcbiAgICAgICAgaWYgKG5hbWVzLmluZGV4T2YobikgPCAwKSBuYW1lcy5wdXNoKG4pO1xyXG4gICAgfVxyXG4gICAgbGV0IHJlbW92ZWQgPSAwO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IGRlc3QgPSBwYXRoLmpvaW4oZGVzdERpciwgbmFtZXNbaV0pO1xyXG4gICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGRlc3QpKSB7XHJcbiAgICAgICAgICAgIGZzLnVubGlua1N5bmMoZGVzdCk7XHJcbiAgICAgICAgICAgIHJlbW92ZWQrKztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAocmVtb3ZlZCA+IDApIHtcclxuICAgICAgICBjb25zb2xlLmxvZyhgW3Rvb2xzXSByZW1vdmVkIHdlY2hhdC1vbmx5IDMwciBzZGsgZnJvbSBhc3NldHMgKCR7cGxhdGZvcm0gfHwgJ3Vua25vd24gcGxhdGZvcm0nfSlgKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIOS7hee6r+W+ruS/oSB3ZWNoYXRnYW1l77ya5oqKIHRvb2xzL3dlY2hhdC1vbmx5IOaLt+i/myBhc3NldHPjgIJcclxuICog5oqW6Z+zL+W/q+aJiy9CIOerme+8iOWLvumAieWvvOWHuiBiaWxpZ2FtZe+8ieS4jeaLt++8jOmBv+WFjSAzMHIg6L+b5YyF44CCXHJcbiAqL1xyXG5mdW5jdGlvbiBzeW5jV2VjaGF0T25seVNkayhvcHRpb25zOiBhbnksIG1vZGU6ICdiZWZvcmUnIHwgJ2FmdGVyJykge1xyXG4gICAgY29uc3QgcHJvamVjdFBhdGggPSBFZGl0b3IuUHJvamVjdC5wYXRoO1xyXG4gICAgaWYgKCFwcm9qZWN0UGF0aCkgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IHsgc3JjRGlyLCBkZXN0RGlyIH0gPSB3ZWNoYXRPbmx5U2RrUGF0aHMocHJvamVjdFBhdGgpO1xyXG4gICAgY29uc3QgcGxhdGZvcm0gPSBnZXRCdWlsZFBsYXRmb3JtKG9wdGlvbnMpO1xyXG4gICAgY29uc3QgaXNXZWNoYXQgPSBwbGF0Zm9ybSA9PT0gJ3dlY2hhdGdhbWUnO1xyXG4gICAgY29uc3QgaXNCaWxpR2FtZSA9ICEhb3B0aW9ucz8ucGFja2FnZXM/LlsnYmlsaWdhbWUtYnVpbGRlciddPy5pc0JpbGlHYW1lO1xyXG5cclxuICAgIGlmIChtb2RlID09PSAnYWZ0ZXInIHx8ICFpc1dlY2hhdCB8fCBpc0JpbGlHYW1lKSB7XHJcbiAgICAgICAgcmVtb3ZlV2VjaGF0T25seVNka0Zyb21Bc3NldHMoc3JjRGlyLCBkZXN0RGlyLCBpc0JpbGlHYW1lID8gJ2JpbGlnYW1lJyA6IHBsYXRmb3JtKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgZmlsZXMgPSBsaXN0V2VjaGF0T25seUZpbGVzKHNyY0Rpcik7XHJcbiAgICBpZiAoZmlsZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgY29uc29sZS53YXJuKCdbdG9vbHNdIHdlY2hhdC1vbmx5IHNkayBtaXNzaW5nOicsIHNyY0Rpcik7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgZnMubWtkaXJTeW5jKGRlc3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWxlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IG5hbWUgPSBmaWxlc1tpXTtcclxuICAgICAgICBmcy5jb3B5RmlsZVN5bmMocGF0aC5qb2luKHNyY0RpciwgbmFtZSksIHBhdGguam9pbihkZXN0RGlyLCBuYW1lKSk7XHJcbiAgICB9XHJcbiAgICBjb25zb2xlLmxvZygnW3Rvb2xzXSBjb3BpZWQgd2VjaGF0LW9ubHkgMzByIHNkayBpbnRvIGFzc2V0cy9zY3JpcHQvc2RrJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBvbkJlZm9yZUJ1aWxkKG9wdGlvbnM6IGFueSwgX3Jlc3VsdDogYW55KSB7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHN5bmNXZWNoYXRPbmx5U2RrKG9wdGlvbnMsICdiZWZvcmUnKTtcclxuICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1t0b29sc10gb25CZWZvcmVCdWlsZCBzeW5jV2VjaGF0T25seVNkayBmYWlsZWQ6JywgZXJyKTtcclxuICAgIH1cclxuICAgIHRyeSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coJ1t0b29sc10gb25CZWZvcmVCdWlsZDogZ2VuZXJhdGUgY29uZmlnIGJpbicpO1xyXG4gICAgICAgIGdlbmVyYXRlQ29uZmlnQmluKCk7XHJcbiAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdbdG9vbHNdIG9uQmVmb3JlQnVpbGQgZ2VuZXJhdGUgY29uZmlnIGJpbiBmYWlsZWQ6JywgZXJyKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0cnVlO1xyXG59XHJcblxyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25BZnRlckJ1aWxkKG9wdGlvbnM6IGFueSwgcmVzdWx0OiBhbnkpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgLy8g5Lqn54mp5bey57yW6K+R6L+b5YyF77yMYXNzZXRzIOmHjOeahOaLt+i0neW/hemhu+WIoOaOie+8jOmBv+WFjeS4i+asoeaKlumfsy/lv6vmiYvmnoTlu7ror6/miZPlhaVcclxuICAgICAgICBzeW5jV2VjaGF0T25seVNkayhvcHRpb25zLCAnYWZ0ZXInKTtcclxuICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1t0b29sc10gb25BZnRlckJ1aWxkIHN5bmNXZWNoYXRPbmx5U2RrIGZhaWxlZDonLCBlcnIpO1xyXG4gICAgfVxyXG4gICAgdHJ5IHtcclxuICAgICAgICBpZiAoc2hvdWxkU3RyaXBDb25zb2xlKG9wdGlvbnMpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJvb3RzID0gY29sbGVjdFN0cmlwUm9vdHMob3B0aW9ucywgcmVzdWx0KTtcclxuICAgICAgICAgICAgaWYgKHJvb3RzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgICAgICAgICAgICAgICdbdG9vbHNdIHN0cmlwQ29uc29sZSDlt7Lli77pgInkvYbmnKrog73op6PmnpDmnoTlu7rovpPlh7rnm67lvZXvvIjmo4Dmn6UgcmVzdWx0LmRlc3QgLyBwYXRocyAvIGJ1aWxkUGF0aCtvdXRwdXROYW1l77yJJyxcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnW3Rvb2xzXSBvbkFmdGVyQnVpbGQgc3RyaXBDb25zb2xlIOKGkicsIHJvb3RzLmpvaW4oJyB8ICcpKTtcclxuICAgICAgICAgICAgICAgIGF3YWl0IHN0cmlwQ29uc29sZUZyb21CdWlsZE91dHB1dChyb290cyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdbdG9vbHNdIG9uQWZ0ZXJCdWlsZCBzdHJpcENvbnNvbGUgZmFpbGVkOicsIGVycik7XHJcbiAgICB9XHJcbiAgICB0cnkge1xyXG4gICAgICAgIGlmIChnZXRCdWlsZFBsYXRmb3JtKG9wdGlvbnMpID09PSAnYnl0ZWRhbmNlLW1pbmktZ2FtZScpIHtcclxuICAgICAgICAgICAgY29uc3Qgcm9vdHMgPSBjb2xsZWN0U3RyaXBSb290cyhvcHRpb25zLCByZXN1bHQpO1xyXG4gICAgICAgICAgICBwYXRjaEhhcm1vbnlFbmdpbmVBZGFwdGVyKHJvb3RzKTtcclxuICAgICAgICAgICAgZW5zdXJlQnl0ZWRhbmNlV2FzbVN1YnBrZ0dhbWVKcyhyb290cyk7XHJcbiAgICAgICAgfVxyXG4gICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcignW3Rvb2xzXSBvbkFmdGVyQnVpbGQgYnl0ZWRhbmNlIHBhdGNoIGZhaWxlZDonLCBlcnIpO1xyXG4gICAgfVxyXG4gICAgdHJ5IHtcclxuICAgICAgICBjb25zb2xlLmxvZygnW3Rvb2xzXSBvbkFmdGVyQnVpbGQ6IGdlbmVyYXRlIGNvbmZpZyBiaW4nKTtcclxuICAgICAgICBnZW5lcmF0ZUNvbmZpZ0JpbigpO1xyXG4gICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcignW3Rvb2xzXSBvbkFmdGVyQnVpbGQgZ2VuZXJhdGUgY29uZmlnIGJpbiBmYWlsZWQ6JywgZXJyKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0cnVlO1xyXG59XHJcbiJdfQ==
|