/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // node_modules/.pnpm/obsidian-daily-notes-interf_8d9fc24b0fc622d94fd11fa5e9b185b3/node_modules/obsidian-daily-notes-interface/dist/main.js var require_main = __commonJS({ "node_modules/.pnpm/obsidian-daily-notes-interf_8d9fc24b0fc622d94fd11fa5e9b185b3/node_modules/obsidian-daily-notes-interface/dist/main.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var obsidian = require("obsidian"); var DEFAULT_DAILY_NOTE_FORMAT = "YYYY-MM-DD"; var DEFAULT_WEEKLY_NOTE_FORMAT = "gggg-[W]ww"; var DEFAULT_MONTHLY_NOTE_FORMAT = "YYYY-MM"; var DEFAULT_QUARTERLY_NOTE_FORMAT = "YYYY-[Q]Q"; var DEFAULT_YEARLY_NOTE_FORMAT = "YYYY"; function shouldUsePeriodicNotesSettings(periodicity) { var _a, _b; const periodicNotes = window.app.plugins.getPlugin("periodic-notes"); return periodicNotes && ((_b = (_a = periodicNotes.settings) == null ? void 0 : _a[periodicity]) == null ? void 0 : _b.enabled); } function getDailyNoteSettings() { var _a, _b, _c, _d; try { const { internalPlugins, plugins } = window.app; if (shouldUsePeriodicNotesSettings("daily")) { const { format: format2, folder: folder2, template: template2 } = ((_b = (_a = plugins.getPlugin("periodic-notes")) == null ? void 0 : _a.settings) == null ? void 0 : _b.daily) || {}; return { format: format2 || DEFAULT_DAILY_NOTE_FORMAT, folder: (folder2 == null ? void 0 : folder2.trim()) || "", template: (template2 == null ? void 0 : template2.trim()) || "" }; } const { folder, format, template } = ((_d = (_c = internalPlugins.getPluginById("daily-notes")) == null ? void 0 : _c.instance) == null ? void 0 : _d.options) || {}; return { format: format || DEFAULT_DAILY_NOTE_FORMAT, folder: (folder == null ? void 0 : folder.trim()) || "", template: (template == null ? void 0 : template.trim()) || "" }; } catch (err) { console.info("No custom daily note settings found!", err); } } function getWeeklyNoteSettings() { var _a, _b, _c, _d, _e, _f, _g; try { const pluginManager = window.app.plugins; const calendarSettings = (_a = pluginManager.getPlugin("calendar")) == null ? void 0 : _a.options; const periodicNotesSettings = (_c = (_b = pluginManager.getPlugin("periodic-notes")) == null ? void 0 : _b.settings) == null ? void 0 : _c.weekly; if (shouldUsePeriodicNotesSettings("weekly")) { return { format: periodicNotesSettings.format || DEFAULT_WEEKLY_NOTE_FORMAT, folder: ((_d = periodicNotesSettings.folder) == null ? void 0 : _d.trim()) || "", template: ((_e = periodicNotesSettings.template) == null ? void 0 : _e.trim()) || "" }; } const settings = calendarSettings || {}; return { format: settings.weeklyNoteFormat || DEFAULT_WEEKLY_NOTE_FORMAT, folder: ((_f = settings.weeklyNoteFolder) == null ? void 0 : _f.trim()) || "", template: ((_g = settings.weeklyNoteTemplate) == null ? void 0 : _g.trim()) || "" }; } catch (err) { console.info("No custom weekly note settings found!", err); } } function getMonthlyNoteSettings() { var _a, _b, _c, _d; const pluginManager = window.app.plugins; try { const settings = shouldUsePeriodicNotesSettings("monthly") && ((_b = (_a = pluginManager.getPlugin("periodic-notes")) == null ? void 0 : _a.settings) == null ? void 0 : _b.monthly) || {}; return { format: settings.format || DEFAULT_MONTHLY_NOTE_FORMAT, folder: ((_c = settings.folder) == null ? void 0 : _c.trim()) || "", template: ((_d = settings.template) == null ? void 0 : _d.trim()) || "" }; } catch (err) { console.info("No custom monthly note settings found!", err); } } function getQuarterlyNoteSettings() { var _a, _b, _c, _d; const pluginManager = window.app.plugins; try { const settings = shouldUsePeriodicNotesSettings("quarterly") && ((_b = (_a = pluginManager.getPlugin("periodic-notes")) == null ? void 0 : _a.settings) == null ? void 0 : _b.quarterly) || {}; return { format: settings.format || DEFAULT_QUARTERLY_NOTE_FORMAT, folder: ((_c = settings.folder) == null ? void 0 : _c.trim()) || "", template: ((_d = settings.template) == null ? void 0 : _d.trim()) || "" }; } catch (err) { console.info("No custom quarterly note settings found!", err); } } function getYearlyNoteSettings() { var _a, _b, _c, _d; const pluginManager = window.app.plugins; try { const settings = shouldUsePeriodicNotesSettings("yearly") && ((_b = (_a = pluginManager.getPlugin("periodic-notes")) == null ? void 0 : _a.settings) == null ? void 0 : _b.yearly) || {}; return { format: settings.format || DEFAULT_YEARLY_NOTE_FORMAT, folder: ((_c = settings.folder) == null ? void 0 : _c.trim()) || "", template: ((_d = settings.template) == null ? void 0 : _d.trim()) || "" }; } catch (err) { console.info("No custom yearly note settings found!", err); } } function join(...partSegments) { let parts = []; for (let i = 0, l = partSegments.length; i < l; i++) { parts = parts.concat(partSegments[i].split("/")); } const newParts = []; for (let i = 0, l = parts.length; i < l; i++) { const part = parts[i]; if (!part || part === ".") continue; else newParts.push(part); } if (parts[0] === "") newParts.unshift(""); return newParts.join("/"); } function basename(fullPath) { let base = fullPath.substring(fullPath.lastIndexOf("/") + 1); if (base.lastIndexOf(".") != -1) base = base.substring(0, base.lastIndexOf(".")); return base; } async function ensureFolderExists(path) { const dirs = path.replace(/\\/g, "/").split("/"); dirs.pop(); if (dirs.length) { const dir = join(...dirs); if (!window.app.vault.getAbstractFileByPath(dir)) { await window.app.vault.createFolder(dir); } } } async function getNotePath(directory, filename) { if (!filename.endsWith(".md")) { filename += ".md"; } const path = obsidian.normalizePath(join(directory, filename)); await ensureFolderExists(path); return path; } async function getTemplateInfo(template) { const { metadataCache, vault } = window.app; const templatePath = obsidian.normalizePath(template); if (templatePath === "/") { return Promise.resolve(["", null]); } try { const templateFile = metadataCache.getFirstLinkpathDest(templatePath, ""); const contents = await vault.cachedRead(templateFile); const IFoldInfo = window.app.foldManager.load(templateFile); return [contents, IFoldInfo]; } catch (err) { console.error(`Failed to read the daily note template '${templatePath}'`, err); new obsidian.Notice("Failed to read the daily note template"); return ["", null]; } } function getDateUID(date, granularity = "day") { const ts = date.clone().startOf(granularity).format(); return `${granularity}-${ts}`; } function removeEscapedCharacters(format) { return format.replace(/\[[^\]]*\]/g, ""); } function isFormatAmbiguous(format, granularity) { if (granularity === "week") { const cleanFormat = removeEscapedCharacters(format); return /w{1,2}/i.test(cleanFormat) && (/M{1,4}/.test(cleanFormat) || /D{1,4}/.test(cleanFormat)); } return false; } function getDateFromFile(file, granularity) { return getDateFromFilename(file.basename, granularity); } function getDateFromPath(path, granularity) { return getDateFromFilename(basename(path), granularity); } function getDateFromFilename(filename, granularity) { const getSettings = { day: getDailyNoteSettings, week: getWeeklyNoteSettings, month: getMonthlyNoteSettings, quarter: getQuarterlyNoteSettings, year: getYearlyNoteSettings }; const format = getSettings[granularity]().format.split("/").pop(); const noteDate = window.moment(filename, format, true); if (!noteDate.isValid()) { return null; } if (isFormatAmbiguous(format, granularity)) { if (granularity === "week") { const cleanFormat = removeEscapedCharacters(format); if (/w{1,2}/i.test(cleanFormat)) { return window.moment( filename, // If format contains week, remove day & month formatting format.replace(/M{1,4}/g, "").replace(/D{1,4}/g, ""), false ); } } } return noteDate; } var DailyNotesFolderMissingError = class extends Error { }; async function createDailyNote2(date) { const app = window.app; const { vault } = app; const moment2 = window.moment; const { template, format, folder } = getDailyNoteSettings(); const [templateContents, IFoldInfo] = await getTemplateInfo(template); const filename = date.format(format); const normalizedPath = await getNotePath(folder, filename); try { const createdFile = await vault.create(normalizedPath, templateContents.replace(/{{\s*date\s*}}/gi, filename).replace(/{{\s*time\s*}}/gi, moment2().format("HH:mm")).replace(/{{\s*title\s*}}/gi, filename).replace(/{{\s*(date|time)\s*(([+-]\d+)([yqmwdhs]))?\s*(:.+?)?}}/gi, (_, _timeOrDate, calc, timeDelta, unit, momentFormat) => { const now = moment2(); const currentDate = date.clone().set({ hour: now.get("hour"), minute: now.get("minute"), second: now.get("second") }); if (calc) { currentDate.add(parseInt(timeDelta, 10), unit); } if (momentFormat) { return currentDate.format(momentFormat.substring(1).trim()); } return currentDate.format(format); }).replace(/{{\s*yesterday\s*}}/gi, date.clone().subtract(1, "day").format(format)).replace(/{{\s*tomorrow\s*}}/gi, date.clone().add(1, "d").format(format))); app.foldManager.save(createdFile, IFoldInfo); return createdFile; } catch (err) { console.error(`Failed to create file: '${normalizedPath}'`, err); new obsidian.Notice("Unable to create new file."); } } function getDailyNote2(date, dailyNotes) { var _a; return (_a = dailyNotes[getDateUID(date, "day")]) != null ? _a : null; } function getAllDailyNotes2() { const { vault } = window.app; const { folder } = getDailyNoteSettings(); const dailyNotesFolder = vault.getAbstractFileByPath(obsidian.normalizePath(folder)); if (!dailyNotesFolder) { throw new DailyNotesFolderMissingError("Failed to find daily notes folder"); } const dailyNotes = {}; obsidian.Vault.recurseChildren(dailyNotesFolder, (note) => { if (note instanceof obsidian.TFile) { const date = getDateFromFile(note, "day"); if (date) { const dateString = getDateUID(date, "day"); dailyNotes[dateString] = note; } } }); return dailyNotes; } var WeeklyNotesFolderMissingError = class extends Error { }; function getDaysOfWeek() { const { moment: moment2 } = window; let weekStart = moment2.localeData()._week.dow; const daysOfWeek = [ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ]; while (weekStart) { daysOfWeek.push(daysOfWeek.shift()); weekStart--; } return daysOfWeek; } function getDayOfWeekNumericalValue(dayOfWeekName) { return getDaysOfWeek().indexOf(dayOfWeekName.toLowerCase()); } async function createWeeklyNote2(date) { const { vault } = window.app; const { template, format, folder } = getWeeklyNoteSettings(); const [templateContents, IFoldInfo] = await getTemplateInfo(template); const filename = date.format(format); const normalizedPath = await getNotePath(folder, filename); try { const createdFile = await vault.create(normalizedPath, templateContents.replace(/{{\s*(date|time)\s*(([+-]\d+)([yqmwdhs]))?\s*(:.+?)?}}/gi, (_, _timeOrDate, calc, timeDelta, unit, momentFormat) => { const now = window.moment(); const currentDate = date.clone().set({ hour: now.get("hour"), minute: now.get("minute"), second: now.get("second") }); if (calc) { currentDate.add(parseInt(timeDelta, 10), unit); } if (momentFormat) { return currentDate.format(momentFormat.substring(1).trim()); } return currentDate.format(format); }).replace(/{{\s*title\s*}}/gi, filename).replace(/{{\s*time\s*}}/gi, window.moment().format("HH:mm")).replace(/{{\s*(sunday|monday|tuesday|wednesday|thursday|friday|saturday)\s*:(.*?)}}/gi, (_, dayOfWeek, momentFormat) => { const day = getDayOfWeekNumericalValue(dayOfWeek); return date.weekday(day).format(momentFormat.trim()); })); window.app.foldManager.save(createdFile, IFoldInfo); return createdFile; } catch (err) { console.error(`Failed to create file: '${normalizedPath}'`, err); new obsidian.Notice("Unable to create new file."); } } function getWeeklyNote2(date, weeklyNotes) { var _a; return (_a = weeklyNotes[getDateUID(date, "week")]) != null ? _a : null; } function getAllWeeklyNotes2() { const weeklyNotes = {}; if (!appHasWeeklyNotesPluginLoaded()) { return weeklyNotes; } const { vault } = window.app; const { folder } = getWeeklyNoteSettings(); const weeklyNotesFolder = vault.getAbstractFileByPath(obsidian.normalizePath(folder)); if (!weeklyNotesFolder) { throw new WeeklyNotesFolderMissingError("Failed to find weekly notes folder"); } obsidian.Vault.recurseChildren(weeklyNotesFolder, (note) => { if (note instanceof obsidian.TFile) { const date = getDateFromFile(note, "week"); if (date) { const dateString = getDateUID(date, "week"); weeklyNotes[dateString] = note; } } }); return weeklyNotes; } var MonthlyNotesFolderMissingError = class extends Error { }; async function createMonthlyNote2(date) { const { vault } = window.app; const { template, format, folder } = getMonthlyNoteSettings(); const [templateContents, IFoldInfo] = await getTemplateInfo(template); const filename = date.format(format); const normalizedPath = await getNotePath(folder, filename); try { const createdFile = await vault.create(normalizedPath, templateContents.replace(/{{\s*(date|time)\s*(([+-]\d+)([yqmwdhs]))?\s*(:.+?)?}}/gi, (_, _timeOrDate, calc, timeDelta, unit, momentFormat) => { const now = window.moment(); const currentDate = date.clone().set({ hour: now.get("hour"), minute: now.get("minute"), second: now.get("second") }); if (calc) { currentDate.add(parseInt(timeDelta, 10), unit); } if (momentFormat) { return currentDate.format(momentFormat.substring(1).trim()); } return currentDate.format(format); }).replace(/{{\s*date\s*}}/gi, filename).replace(/{{\s*time\s*}}/gi, window.moment().format("HH:mm")).replace(/{{\s*title\s*}}/gi, filename)); window.app.foldManager.save(createdFile, IFoldInfo); return createdFile; } catch (err) { console.error(`Failed to create file: '${normalizedPath}'`, err); new obsidian.Notice("Unable to create new file."); } } function getMonthlyNote2(date, monthlyNotes) { var _a; return (_a = monthlyNotes[getDateUID(date, "month")]) != null ? _a : null; } function getAllMonthlyNotes2() { const monthlyNotes = {}; if (!appHasMonthlyNotesPluginLoaded()) { return monthlyNotes; } const { vault } = window.app; const { folder } = getMonthlyNoteSettings(); const monthlyNotesFolder = vault.getAbstractFileByPath(obsidian.normalizePath(folder)); if (!monthlyNotesFolder) { throw new MonthlyNotesFolderMissingError("Failed to find monthly notes folder"); } obsidian.Vault.recurseChildren(monthlyNotesFolder, (note) => { if (note instanceof obsidian.TFile) { const date = getDateFromFile(note, "month"); if (date) { const dateString = getDateUID(date, "month"); monthlyNotes[dateString] = note; } } }); return monthlyNotes; } var QuarterlyNotesFolderMissingError = class extends Error { }; async function createQuarterlyNote2(date) { const { vault } = window.app; const { template, format, folder } = getQuarterlyNoteSettings(); const [templateContents, IFoldInfo] = await getTemplateInfo(template); const filename = date.format(format); const normalizedPath = await getNotePath(folder, filename); try { const createdFile = await vault.create(normalizedPath, templateContents.replace(/{{\s*(date|time)\s*(([+-]\d+)([yqmwdhs]))?\s*(:.+?)?}}/gi, (_, _timeOrDate, calc, timeDelta, unit, momentFormat) => { const now = window.moment(); const currentDate = date.clone().set({ hour: now.get("hour"), minute: now.get("minute"), second: now.get("second") }); if (calc) { currentDate.add(parseInt(timeDelta, 10), unit); } if (momentFormat) { return currentDate.format(momentFormat.substring(1).trim()); } return currentDate.format(format); }).replace(/{{\s*date\s*}}/gi, filename).replace(/{{\s*time\s*}}/gi, window.moment().format("HH:mm")).replace(/{{\s*title\s*}}/gi, filename)); window.app.foldManager.save(createdFile, IFoldInfo); return createdFile; } catch (err) { console.error(`Failed to create file: '${normalizedPath}'`, err); new obsidian.Notice("Unable to create new file."); } } function getQuarterlyNote2(date, quarterly) { var _a; return (_a = quarterly[getDateUID(date, "quarter")]) != null ? _a : null; } function getAllQuarterlyNotes2() { const quarterly = {}; if (!appHasQuarterlyNotesPluginLoaded()) { return quarterly; } const { vault } = window.app; const { folder } = getQuarterlyNoteSettings(); const quarterlyFolder = vault.getAbstractFileByPath(obsidian.normalizePath(folder)); if (!quarterlyFolder) { throw new QuarterlyNotesFolderMissingError("Failed to find quarterly notes folder"); } obsidian.Vault.recurseChildren(quarterlyFolder, (note) => { if (note instanceof obsidian.TFile) { const date = getDateFromFile(note, "quarter"); if (date) { const dateString = getDateUID(date, "quarter"); quarterly[dateString] = note; } } }); return quarterly; } var YearlyNotesFolderMissingError = class extends Error { }; async function createYearlyNote2(date) { const { vault } = window.app; const { template, format, folder } = getYearlyNoteSettings(); const [templateContents, IFoldInfo] = await getTemplateInfo(template); const filename = date.format(format); const normalizedPath = await getNotePath(folder, filename); try { const createdFile = await vault.create(normalizedPath, templateContents.replace(/{{\s*(date|time)\s*(([+-]\d+)([yqmwdhs]))?\s*(:.+?)?}}/gi, (_, _timeOrDate, calc, timeDelta, unit, momentFormat) => { const now = window.moment(); const currentDate = date.clone().set({ hour: now.get("hour"), minute: now.get("minute"), second: now.get("second") }); if (calc) { currentDate.add(parseInt(timeDelta, 10), unit); } if (momentFormat) { return currentDate.format(momentFormat.substring(1).trim()); } return currentDate.format(format); }).replace(/{{\s*date\s*}}/gi, filename).replace(/{{\s*time\s*}}/gi, window.moment().format("HH:mm")).replace(/{{\s*title\s*}}/gi, filename)); window.app.foldManager.save(createdFile, IFoldInfo); return createdFile; } catch (err) { console.error(`Failed to create file: '${normalizedPath}'`, err); new obsidian.Notice("Unable to create new file."); } } function getYearlyNote2(date, yearlyNotes) { var _a; return (_a = yearlyNotes[getDateUID(date, "year")]) != null ? _a : null; } function getAllYearlyNotes2() { const yearlyNotes = {}; if (!appHasYearlyNotesPluginLoaded()) { return yearlyNotes; } const { vault } = window.app; const { folder } = getYearlyNoteSettings(); const yearlyNotesFolder = vault.getAbstractFileByPath(obsidian.normalizePath(folder)); if (!yearlyNotesFolder) { throw new YearlyNotesFolderMissingError("Failed to find yearly notes folder"); } obsidian.Vault.recurseChildren(yearlyNotesFolder, (note) => { if (note instanceof obsidian.TFile) { const date = getDateFromFile(note, "year"); if (date) { const dateString = getDateUID(date, "year"); yearlyNotes[dateString] = note; } } }); return yearlyNotes; } function appHasDailyNotesPluginLoaded() { var _a, _b; const { app } = window; const dailyNotesPlugin = app.internalPlugins.plugins["daily-notes"]; if (dailyNotesPlugin && dailyNotesPlugin.enabled) { return true; } const periodicNotes = app.plugins.getPlugin("periodic-notes"); return periodicNotes && ((_b = (_a = periodicNotes.settings) == null ? void 0 : _a.daily) == null ? void 0 : _b.enabled); } function appHasWeeklyNotesPluginLoaded() { var _a, _b; const { app } = window; if (app.plugins.getPlugin("calendar")) { return true; } const periodicNotes = app.plugins.getPlugin("periodic-notes"); return periodicNotes && ((_b = (_a = periodicNotes.settings) == null ? void 0 : _a.weekly) == null ? void 0 : _b.enabled); } function appHasMonthlyNotesPluginLoaded() { var _a, _b; const { app } = window; const periodicNotes = app.plugins.getPlugin("periodic-notes"); return periodicNotes && ((_b = (_a = periodicNotes.settings) == null ? void 0 : _a.monthly) == null ? void 0 : _b.enabled); } function appHasQuarterlyNotesPluginLoaded() { var _a, _b; const { app } = window; const periodicNotes = app.plugins.getPlugin("periodic-notes"); return periodicNotes && ((_b = (_a = periodicNotes.settings) == null ? void 0 : _a.quarterly) == null ? void 0 : _b.enabled); } function appHasYearlyNotesPluginLoaded() { var _a, _b; const { app } = window; const periodicNotes = app.plugins.getPlugin("periodic-notes"); return periodicNotes && ((_b = (_a = periodicNotes.settings) == null ? void 0 : _a.yearly) == null ? void 0 : _b.enabled); } function getPeriodicNoteSettings(granularity) { const getSettings = { day: getDailyNoteSettings, week: getWeeklyNoteSettings, month: getMonthlyNoteSettings, quarter: getQuarterlyNoteSettings, year: getYearlyNoteSettings }[granularity]; return getSettings(); } function createPeriodicNote(granularity, date) { const createFn = { day: createDailyNote2, month: createMonthlyNote2, week: createWeeklyNote2 }; return createFn[granularity](date); } exports.DEFAULT_DAILY_NOTE_FORMAT = DEFAULT_DAILY_NOTE_FORMAT; exports.DEFAULT_MONTHLY_NOTE_FORMAT = DEFAULT_MONTHLY_NOTE_FORMAT; exports.DEFAULT_QUARTERLY_NOTE_FORMAT = DEFAULT_QUARTERLY_NOTE_FORMAT; exports.DEFAULT_WEEKLY_NOTE_FORMAT = DEFAULT_WEEKLY_NOTE_FORMAT; exports.DEFAULT_YEARLY_NOTE_FORMAT = DEFAULT_YEARLY_NOTE_FORMAT; exports.appHasDailyNotesPluginLoaded = appHasDailyNotesPluginLoaded; exports.appHasMonthlyNotesPluginLoaded = appHasMonthlyNotesPluginLoaded; exports.appHasQuarterlyNotesPluginLoaded = appHasQuarterlyNotesPluginLoaded; exports.appHasWeeklyNotesPluginLoaded = appHasWeeklyNotesPluginLoaded; exports.appHasYearlyNotesPluginLoaded = appHasYearlyNotesPluginLoaded; exports.createDailyNote = createDailyNote2; exports.createMonthlyNote = createMonthlyNote2; exports.createPeriodicNote = createPeriodicNote; exports.createQuarterlyNote = createQuarterlyNote2; exports.createWeeklyNote = createWeeklyNote2; exports.createYearlyNote = createYearlyNote2; exports.getAllDailyNotes = getAllDailyNotes2; exports.getAllMonthlyNotes = getAllMonthlyNotes2; exports.getAllQuarterlyNotes = getAllQuarterlyNotes2; exports.getAllWeeklyNotes = getAllWeeklyNotes2; exports.getAllYearlyNotes = getAllYearlyNotes2; exports.getDailyNote = getDailyNote2; exports.getDailyNoteSettings = getDailyNoteSettings; exports.getDateFromFile = getDateFromFile; exports.getDateFromPath = getDateFromPath; exports.getDateUID = getDateUID; exports.getMonthlyNote = getMonthlyNote2; exports.getMonthlyNoteSettings = getMonthlyNoteSettings; exports.getPeriodicNoteSettings = getPeriodicNoteSettings; exports.getQuarterlyNote = getQuarterlyNote2; exports.getQuarterlyNoteSettings = getQuarterlyNoteSettings; exports.getTemplateInfo = getTemplateInfo; exports.getWeeklyNote = getWeeklyNote2; exports.getWeeklyNoteSettings = getWeeklyNoteSettings; exports.getYearlyNote = getYearlyNote2; exports.getYearlyNoteSettings = getYearlyNoteSettings; } }); // src/main.ts var main_exports = {}; __export(main_exports, { default: () => HomeBasePlugin }); module.exports = __toCommonJS(main_exports); var import_obsidian11 = require("obsidian"); // src/settings.ts var HomeBaseType = /* @__PURE__ */ ((HomeBaseType2) => { HomeBaseType2["File"] = "File"; HomeBaseType2["Workspace"] = "Workspace"; HomeBaseType2["Random"] = "Random file"; HomeBaseType2["RandomFolder"] = "Random in folder"; HomeBaseType2["Graph"] = "Graph view"; HomeBaseType2["None"] = "Nothing"; HomeBaseType2["Journal"] = "Journal"; HomeBaseType2["NewNote"] = "New note"; HomeBaseType2["DailyNote"] = "Daily Note"; HomeBaseType2["WeeklyNote"] = "Weekly Note"; HomeBaseType2["MonthlyNote"] = "Monthly Note"; HomeBaseType2["QuarterlyNote"] = "Quarterly Note"; HomeBaseType2["YearlyNote"] = "Yearly Note"; return HomeBaseType2; })(HomeBaseType || {}); var DEFAULT_SETTINGS = { // General homeBaseType: "File" /* File */, homeBaseValue: "", openOnStartup: true, openViewMode: "default", openMode: "replace-all", manualOpenMode: "retain", // Tab Behavior replaceNewTab: false, newTabMode: "only-when-empty", // Default: only replace when no tabs are open openWhenAllTabsClosed: true, // Default: open home base when all tabs are closed useDifferentFileForNewTab: false, newTabType: "File" /* File */, newTabValue: "", newTabSeparateMobile: false, mobileNewTabType: "File" /* File */, mobileNewTabValue: "", // UI Features showStickyHomeIcon: false, stickyIconName: "home", hideHomeTabHeader: false, replaceMobileNewTab: false, // Mobile separateMobile: false, mobileHomeBaseType: "File" /* File */, mobileHomeBaseValue: "", // Automation commandOnOpen: "", waitForGitSync: false, gitSyncTimeout: 3, // Default 3 seconds // View behavior revertView: false, autoScroll: false, hideReleaseNotes: false // OFF by default }; var VIEW_MODE_OPTIONS = { "default": "Default", "preview": "Reading view", "source": "Source mode", "live": "Live Preview" }; var NEW_TAB_MODE_OPTIONS = { "only-when-empty": "Only when no tabs are open", "always": "Always replace new tabs" }; var OPENING_MODE_OPTIONS = { "replace-all": "Replace all open notes", "replace-last": "Replace last note", "retain": "Keep open notes" }; var UNCHANGEABLE_TYPES = [ "Random file" /* Random */, "Graph view" /* Graph */, "Nothing" /* None */, "Daily Note" /* DailyNote */, "Weekly Note" /* WeeklyNote */, "Monthly Note" /* MonthlyNote */, "Quarterly Note" /* QuarterlyNote */, "Yearly Note" /* YearlyNote */ ]; // src/ui/settings-tab.ts var import_obsidian4 = require("obsidian"); // src/ui/file-suggest.ts var import_obsidian = require("obsidian"); var SUPPORTED_EXTENSIONS = ["md", "mdx", "canvas", "base"]; var FilePathSuggest = class extends import_obsidian.AbstractInputSuggest { constructor(app, inputEl) { super(app, inputEl); this.inputEl = inputEl; } getSuggestions(query) { const lowerQuery = query.toLowerCase(); const files = []; this.app.vault.getAllLoadedFiles().forEach((file) => { if (file instanceof import_obsidian.TFile) { if (SUPPORTED_EXTENSIONS.includes(file.extension)) { if (file.path.toLowerCase().includes(lowerQuery) || file.basename.toLowerCase().includes(lowerQuery)) { files.push(file); } } } }); files.sort((a, b) => { const aStartsWith = a.path.toLowerCase().startsWith(lowerQuery); const bStartsWith = b.path.toLowerCase().startsWith(lowerQuery); if (aStartsWith && !bStartsWith) return -1; if (!aStartsWith && bStartsWith) return 1; return a.path.localeCompare(b.path); }); return files.slice(0, 20); } renderSuggestion(file, el) { el.addClass("home-base-suggestion-item"); const titleEl = el.createEl("div", { cls: "suggestion-title" }); titleEl.createEl("span", { text: file.basename }); if (file.extension !== "md") { titleEl.createEl("span", { text: file.extension.toUpperCase(), cls: "suggestion-flair" }); } if (file.parent && file.parent.path !== "/") { el.createEl("div", { text: file.parent.path, cls: "suggestion-note" }); } } selectSuggestion(file) { this.inputEl.value = file.path; this.inputEl.trigger("input"); this.close(); } }; var FolderSuggest = class extends import_obsidian.AbstractInputSuggest { constructor(app, inputEl) { super(app, inputEl); this.inputEl = inputEl; } getSuggestions(query) { const lowerQuery = query.toLowerCase(); const folders = []; this.app.vault.getAllLoadedFiles().forEach((file) => { if (file instanceof import_obsidian.TFolder) { if (file.path.toLowerCase().includes(lowerQuery)) { folders.push(file); } } }); folders.sort((a, b) => a.path.localeCompare(b.path)); return folders.slice(0, 20); } renderSuggestion(folder, el) { el.createEl("div", { text: folder.path || "/" }); } selectSuggestion(folder) { this.inputEl.value = folder.path; this.inputEl.trigger("input"); this.close(); } }; var WorkspaceSuggest = class extends import_obsidian.AbstractInputSuggest { constructor(app, inputEl) { super(app, inputEl); this.inputEl = inputEl; } getSuggestions(query) { var _a, _b, _c; const workspacesPlugin = (_b = (_a = this.app.internalPlugins) == null ? void 0 : _a.plugins) == null ? void 0 : _b.workspaces; if (!(workspacesPlugin == null ? void 0 : workspacesPlugin.enabled) || !((_c = workspacesPlugin.instance) == null ? void 0 : _c.workspaces)) { return []; } const workspaces = Object.keys(workspacesPlugin.instance.workspaces); const lowerQuery = query.toLowerCase(); return workspaces.filter( (workspace) => workspace.toLowerCase().includes(lowerQuery) ); } renderSuggestion(workspace, el) { el.createEl("div", { text: workspace }); } selectSuggestion(workspace) { this.inputEl.value = workspace; this.inputEl.trigger("input"); this.close(); } }; // src/ui/command-suggest.ts var import_obsidian2 = require("obsidian"); var CommandSuggest = class extends import_obsidian2.AbstractInputSuggest { constructor(app, inputEl) { super(app, inputEl); this.inputEl = inputEl; } getSuggestions(query) { var _a; const lowerQuery = query.toLowerCase(); const commands = []; const appWithCommands = this.app; const allCommands = (_a = appWithCommands.commands) == null ? void 0 : _a.commands; if (allCommands) { for (const command of Object.values(allCommands)) { if (command.name.toLowerCase().includes(lowerQuery) || command.id.toLowerCase().includes(lowerQuery)) { commands.push(command); } } } commands.sort((a, b) => a.name.localeCompare(b.name)); return commands.slice(0, 30); } renderSuggestion(command, el) { el.createEl("div", { text: command.name, cls: "suggestion-title" }); el.createEl("small", { text: command.id, cls: "suggestion-note" }); } selectSuggestion(command) { this.inputEl.value = command.id; this.inputEl.trigger("input"); this.close(); } }; function getCommandById(app, commandId) { var _a; const appWithCommands = app; const commands = (_a = appWithCommands.commands) == null ? void 0 : _a.commands; return commands == null ? void 0 : commands[commandId]; } function executeCommand(app, commandId) { var _a, _b; if (!commandId) return false; const appWithCommands = app; const result = (_b = (_a = appWithCommands.commands) == null ? void 0 : _a.executeCommandById) == null ? void 0 : _b.call(_a, commandId); return result !== false; } // src/ui/icon-picker.ts var import_obsidian3 = require("obsidian"); var IconPicker = class extends import_obsidian3.Modal { constructor(app, currentIcon, callback) { super(app); this.searchResults = []; this.selectedIcon = currentIcon; this.callback = callback; } onOpen() { this.containerEl.addClass("mod-confirmation"); this.modalEl.addClass("iconic-icon-picker"); this.setTitle("Change icon"); const searchSetting = new import_obsidian3.Setting(this.contentEl); if (!import_obsidian3.Platform.isPhone) { searchSetting.setName("Search"); } searchSetting.addSearch((searchField) => { searchField.setPlaceholder("Search icons...").onChange(() => this.updateSearchResults()); searchField.inputEl.enterKeyHint = "go"; this.searchField = searchField; }); if (this.selectedIcon) { this.searchField.setValue(this.selectedIcon); } this.searchResultsSetting = new import_obsidian3.Setting(this.contentEl); this.searchResultsSetting.settingEl.addClass("iconic-search-results"); this.searchResultsSetting.settingEl.tabIndex = 0; this.searchResultsSetting.settingEl.addEventListener("wheel", (event) => { if (document.body.hasClass("mod-rtl")) { this.searchResultsSetting.settingEl.scrollLeft -= event.deltaY; } else { this.searchResultsSetting.settingEl.scrollLeft += event.deltaY; } }, { passive: true }); const buttonContainer = this.modalEl.createDiv({ cls: "modal-button-container" }); new import_obsidian3.ButtonComponent(buttonContainer).setButtonText("Cancel").onClick(() => this.close()).buttonEl.addClass("mod-cancel"); new import_obsidian3.ButtonComponent(buttonContainer).setButtonText("Save").setCta().onClick(() => { this.callback(this.selectedIcon); this.close(); }); requestAnimationFrame(() => { this.searchField.inputEl.select(); this.updateSearchResults(); }); } /** * Update search results based on current query */ updateSearchResults() { const query = this.searchField.getValue().toLowerCase().trim(); const fuzzySearch = (0, import_obsidian3.prepareFuzzySearch)(query); const matches = []; const iconIds = (0, import_obsidian3.getIconIds)(); if (query) { for (const iconId of iconIds) { const iconName = this.formatIconName(iconId); if (iconId === query || iconId.toLowerCase() === query) { matches.push([0, [iconId, iconName]]); } else { const fuzzyMatch = fuzzySearch(iconName); if (fuzzyMatch) { matches.push([fuzzyMatch.score, [iconId, iconName]]); } } } } else { for (const iconId of iconIds) { const iconName = this.formatIconName(iconId); matches.push([0, [iconId, iconName]]); } } matches.sort(([scoreA], [scoreB]) => scoreA > scoreB ? -1 : 1); this.searchResults.length = 0; const maxResults = 100; for (const [, iconEntry] of matches) { this.searchResults.push(iconEntry); if (this.searchResults.length >= maxResults) break; } this.searchResultsSetting.clear(); for (const [iconId, iconName] of this.searchResults) { this.searchResultsSetting.addExtraButton((iconButton) => { iconButton.setTooltip(iconName, { delay: 300, placement: import_obsidian3.Platform.isPhone ? "top" : "bottom" }); const iconEl = iconButton.extraSettingsEl; iconEl.addClass("iconic-search-result"); iconEl.tabIndex = -1; (0, import_obsidian3.setIcon)(iconEl, iconId); if (iconId === this.selectedIcon) { iconEl.addClass("is-selected"); } iconEl.addEventListener("click", () => { this.selectedIcon = iconId; this.callback(iconId); this.close(); }); if (import_obsidian3.Platform.isPhone) { iconEl.addEventListener("contextmenu", () => { var _a; (_a = navigator.vibrate) == null ? void 0 : _a.call(navigator, 100); }); } }); } if (this.searchResults.length === 0) { this.searchResultsSetting.addExtraButton((button) => { button.extraSettingsEl.addClasses(["iconic-invisible", "iconic-search-result"]); }); } } /** * Format icon ID into readable name */ formatIconName(iconId) { let name = iconId.replace(/^lucide-/, ""); name = name.replace(/-/g, " "); return name.split(" ").map( (word) => word.charAt(0).toUpperCase() + word.slice(1) ).join(" "); } onClose() { this.contentEl.empty(); } }; // src/ui/settings-tab.ts var HomeBaseSettingTab = class extends import_obsidian4.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.icon = "lucide-house"; this.plugin = plugin; } display() { const { containerEl } = this; containerEl.empty(); const isMobile = this.plugin.settings.separateMobile; const activeType = isMobile ? this.plugin.settings.mobileHomeBaseType : this.plugin.settings.homeBaseType; const activeValue = isMobile ? this.plugin.settings.mobileHomeBaseValue : this.plugin.settings.homeBaseValue; const generalGroup = new import_obsidian4.SettingGroup(containerEl); generalGroup.addSetting((setting) => { setting.setName("Type").setDesc("What to open as your home base").addDropdown((dropdown) => { let pluginDisabled = false; for (const type of Object.values(HomeBaseType)) { if (!this.plugin.hasRequiredPlugin(type)) { if (type === activeType) { pluginDisabled = true; dropdown.addOption(type, type); } else { dropdown.selectEl.createEl("option", { text: type, attr: { disabled: "true" } }); continue; } } else { dropdown.addOption(type, type); } } dropdown.setValue(activeType || "File" /* File */).onChange(async (value) => { if (isMobile) { this.plugin.settings.mobileHomeBaseType = value; } else { this.plugin.settings.homeBaseType = value; } await this.plugin.saveSettings(); const scrollContainer = containerEl.closest(".vertical-tab-content") || containerEl.closest(".settings-content") || containerEl.parentElement; const scrollTop = (scrollContainer == null ? void 0 : scrollContainer.scrollTop) || 0; this.display(); requestAnimationFrame(() => { if (scrollContainer) { scrollContainer.scrollTop = scrollTop; } }); }); if (pluginDisabled) { setting.descEl.createDiv({ text: "The required plugin has not been enabled or configured for this type.", cls: "mod-warning" }); } }); }); if (!UNCHANGEABLE_TYPES.includes(activeType)) { generalGroup.addSetting((setting) => { let desc = ""; let placeholder = ""; if (activeType === "File" /* File */) { desc = "The file to open as your home base (supports .md, .mdx, .canvas, .base)"; placeholder = "Path to home base file"; } else if (activeType === "Workspace" /* Workspace */) { desc = "The workspace to load as your home base"; placeholder = "Workspace name"; } else if (activeType === "Random in folder" /* RandomFolder */ || activeType === "New note" /* NewNote */) { desc = activeType === "Random in folder" /* RandomFolder */ ? "The folder to pick a random file from" : "The folder to create new notes in"; placeholder = "Folder path"; } else if (activeType === "Journal" /* Journal */) { desc = "The journal name"; placeholder = "Journal name"; } setting.setName(activeType === "File" /* File */ ? "File" : activeType === "Workspace" /* Workspace */ ? "Workspace" : activeType === "Random in folder" /* RandomFolder */ || activeType === "New note" /* NewNote */ ? "Folder" : activeType === "Journal" /* Journal */ ? "Journal" : "Value").setDesc(desc).addText((text) => { if (activeType === "File" /* File */) { new FilePathSuggest(this.app, text.inputEl); } else if (activeType === "Workspace" /* Workspace */) { new WorkspaceSuggest(this.app, text.inputEl); } else if (activeType === "Random in folder" /* RandomFolder */ || activeType === "New note" /* NewNote */) { new FolderSuggest(this.app, text.inputEl); } text.setPlaceholder(placeholder).setValue(activeValue || "").onChange(async (value) => { if (isMobile) { this.plugin.settings.mobileHomeBaseValue = value; } else { this.plugin.settings.homeBaseValue = value; } await this.plugin.saveSettings(); }); }); }); } generalGroup.addSetting((setting) => { setting.setName("Open on startup").setDesc("Open the home base when launching Obsidian").addToggle((toggle) => { toggle.setValue(this.plugin.settings.openOnStartup).onChange(async (value) => { this.plugin.settings.openOnStartup = value; await this.plugin.saveSettings(); }); }); if ((0, import_obsidian4.requireApiVersion)("1.11.0")) { const nativeOpenBehavior = this.plugin.homeService.getNativeOpenBehavior(); if (nativeOpenBehavior) { setting.descEl.createDiv({ text: `Note: This will override Obsidian's native "Default file to open" setting (currently set to "${nativeOpenBehavior}").`, cls: "mod-warning" }); } } }); generalGroup.addSetting((setting) => { setting.setName("Opening mode (startup)").setDesc("How to handle existing tabs when opening on startup").addDropdown((dropdown) => { for (const [value, label] of Object.entries(OPENING_MODE_OPTIONS)) { dropdown.addOption(value, label); } dropdown.setValue(this.plugin.settings.openMode).onChange(async (value) => { this.plugin.settings.openMode = value; await this.plugin.saveSettings(); }); }); }); generalGroup.addSetting((setting) => { setting.setName("Opening mode (manual)").setDesc("How to handle existing tabs when opening manually").addDropdown((dropdown) => { for (const [value, label] of Object.entries(OPENING_MODE_OPTIONS)) { dropdown.addOption(value, label); } dropdown.setValue(this.plugin.settings.manualOpenMode).onChange(async (value) => { this.plugin.settings.manualOpenMode = value; await this.plugin.saveSettings(); }); }); }); generalGroup.addSetting((setting) => { setting.setName("View mode").setDesc("How to open Markdown files").addDropdown((dropdown) => { for (const [value, label] of Object.entries(VIEW_MODE_OPTIONS)) { dropdown.addOption(value, label); } dropdown.setValue(this.plugin.settings.openViewMode).onChange(async (value) => { this.plugin.settings.openViewMode = value; await this.plugin.saveSettings(); }); }); }); generalGroup.addSetting((setting) => { setting.setName("Revert view on close").setDesc("When navigating away from the home base, restore the default view").addToggle((toggle) => { toggle.setValue(this.plugin.settings.revertView).onChange(async (value) => { this.plugin.settings.revertView = value; await this.plugin.saveSettings(); }); }); }); generalGroup.addSetting((setting) => { setting.setName("Auto-scroll").setDesc("When opening the home base, scroll to the bottom and focus on the last line").addToggle((toggle) => { toggle.setValue(this.plugin.settings.autoScroll).onChange(async (value) => { this.plugin.settings.autoScroll = value; await this.plugin.saveSettings(); }); }); }); generalGroup.addSetting((setting) => { setting.setName("Hide release notes").setDesc("Never display release notes when Obsidian updates").addToggle((toggle) => { toggle.setValue(this.plugin.settings.hideReleaseNotes).onChange(async (value) => { this.plugin.settings.hideReleaseNotes = value; await this.plugin.saveSettings(); }); }); }); const tabGroup = new import_obsidian4.SettingGroup(containerEl).setHeading("Tab Behavior"); tabGroup.addSetting((setting) => { setting.setName("Open home base when all tabs are closed").setDesc("When you close all tabs, automatically open the home base").addToggle((toggle) => { toggle.setValue(this.plugin.settings.openWhenAllTabsClosed).onChange(async (value) => { this.plugin.settings.openWhenAllTabsClosed = value; await this.plugin.saveSettings(); }); }); }); tabGroup.addSetting((setting) => { setting.setName("Replace new tabs").setDesc('Open home base instead of new empty tabs (works independently of "open home base when all tabs are closed")').addToggle((toggle) => { toggle.setValue(this.plugin.settings.replaceNewTab).onChange(async (value) => { this.plugin.settings.replaceNewTab = value; await this.plugin.saveSettings(); const scrollContainer = containerEl.closest(".vertical-tab-content") || containerEl.closest(".settings-content") || containerEl.parentElement; const scrollTop = (scrollContainer == null ? void 0 : scrollContainer.scrollTop) || 0; this.display(); requestAnimationFrame(() => { if (scrollContainer) { scrollContainer.scrollTop = scrollTop; } }); }); }); }); if (this.plugin.settings.replaceNewTab) { tabGroup.addSetting((setting) => { setting.setName("New tab replacement mode").setDesc("When to replace new tabs (only when no tabs are open, or always)").addDropdown((dropdown) => { for (const [value, label] of Object.entries(NEW_TAB_MODE_OPTIONS)) { dropdown.addOption(value, label); } dropdown.setValue(this.plugin.settings.newTabMode).onChange(async (value) => { this.plugin.settings.newTabMode = value; await this.plugin.saveSettings(); }); }); }); tabGroup.addSetting((setting) => { setting.setName("Use different home base for new tabs").setDesc("Configure a different home base to open for new tabs (instead of the main home base)").addToggle((toggle) => { toggle.setValue(this.plugin.settings.useDifferentFileForNewTab).onChange(async (value) => { this.plugin.settings.useDifferentFileForNewTab = value; await this.plugin.saveSettings(); const scrollContainer = containerEl.closest(".vertical-tab-content") || containerEl.closest(".settings-content") || containerEl.parentElement; const scrollTop = (scrollContainer == null ? void 0 : scrollContainer.scrollTop) || 0; this.display(); requestAnimationFrame(() => { if (scrollContainer) { scrollContainer.scrollTop = scrollTop; } }); }); }); }); if (this.plugin.settings.useDifferentFileForNewTab) { const desktopType = this.plugin.settings.newTabType || "File" /* File */; const desktopValue = this.plugin.settings.newTabValue || ""; tabGroup.addSetting((setting) => { setting.setName("New tab type").setDesc("What to open for new tabs").addDropdown((dropdown) => { let pluginDisabled = false; for (const type of Object.values(HomeBaseType)) { if (!this.plugin.hasRequiredPlugin(type)) { if (type === desktopType) { pluginDisabled = true; dropdown.addOption(type, type); } else { dropdown.selectEl.createEl("option", { text: type, attr: { disabled: "true" } }); continue; } } else { dropdown.addOption(type, type); } } dropdown.setValue(desktopType).onChange(async (value) => { this.plugin.settings.newTabType = value; await this.plugin.saveSettings(); const scrollContainer = containerEl.closest(".vertical-tab-content") || containerEl.closest(".settings-content") || containerEl.parentElement; const scrollTop = (scrollContainer == null ? void 0 : scrollContainer.scrollTop) || 0; this.display(); requestAnimationFrame(() => { if (scrollContainer) { scrollContainer.scrollTop = scrollTop; } }); }); if (pluginDisabled) { setting.descEl.createDiv({ text: "The required plugin has not been enabled or configured for this type.", cls: "mod-warning" }); } }); }); if (!UNCHANGEABLE_TYPES.includes(desktopType)) { tabGroup.addSetting((setting) => { let desc = ""; let placeholder = ""; if (desktopType === "File" /* File */) { desc = "The file to open for new tabs (supports .md, .mdx, .canvas, .base)"; placeholder = "Path to new tab file"; } else if (desktopType === "Workspace" /* Workspace */) { desc = "The workspace to load for new tabs"; placeholder = "Workspace name"; } else if (desktopType === "Random in folder" /* RandomFolder */) { desc = "The folder to pick a random file from for new tabs"; placeholder = "Folder path"; } else if (desktopType === "Journal" /* Journal */) { desc = "The journal name for new tabs"; placeholder = "Journal name"; } setting.setName(desktopType === "File" /* File */ ? "New tab file" : desktopType === "Workspace" /* Workspace */ ? "New tab workspace" : desktopType === "Random in folder" /* RandomFolder */ ? "New tab folder" : desktopType === "Journal" /* Journal */ ? "New tab journal" : "New tab value").setDesc(desc).addText((text) => { if (desktopType === "File" /* File */) { new FilePathSuggest(this.app, text.inputEl); } else if (desktopType === "Workspace" /* Workspace */) { new WorkspaceSuggest(this.app, text.inputEl); } else if (desktopType === "Random in folder" /* RandomFolder */) { new FolderSuggest(this.app, text.inputEl); } text.setPlaceholder(placeholder).setValue(desktopValue || "").onChange(async (value) => { this.plugin.settings.newTabValue = value; await this.plugin.saveSettings(); }); }); }); } } } const uiGroup = new import_obsidian4.SettingGroup(containerEl).setHeading("UI Features"); uiGroup.addSetting((setting) => { setting.setName("Sticky home icon").setDesc("Show a home icon in the tab bar that stays pinned to the left (desktop only)").addToggle((toggle) => { toggle.setValue(this.plugin.settings.showStickyHomeIcon).onChange(async (value) => { this.plugin.settings.showStickyHomeIcon = value; await this.plugin.saveSettings(); this.plugin.updateStickyTabIcon(); const scrollContainer = containerEl.closest(".vertical-tab-content") || containerEl.closest(".settings-content") || containerEl.parentElement; const scrollTop = (scrollContainer == null ? void 0 : scrollContainer.scrollTop) || 0; this.display(); requestAnimationFrame(() => { if (scrollContainer) { scrollContainer.scrollTop = scrollTop; } }); }); }); }); if (this.plugin.settings.showStickyHomeIcon) { uiGroup.addSetting((setting) => { setting.setName("Icon").setDesc("The icon to display in the sticky home icon").addButton((button) => { const iconName = this.plugin.settings.stickyIconName || "home"; button.setButtonText("Change icon").setIcon(iconName).onClick(() => { const picker = new IconPicker( this.app, this.plugin.settings.stickyIconName, (icon) => { void (async () => { this.plugin.settings.stickyIconName = icon; await this.plugin.saveSettings(); this.plugin.stickyTabService.update(); this.display(); })(); } ); picker.open(); }); }); }); uiGroup.addSetting((setting) => { setting.setName("Hide tab header").setDesc("Hide the sticky home tab header when it's open, using the sticky icon as the tab indicator").addToggle((toggle) => { toggle.setValue(this.plugin.settings.hideHomeTabHeader).onChange(async (value) => { this.plugin.settings.hideHomeTabHeader = value; await this.plugin.saveSettings(); this.plugin.stickyTabService.updateTabHeaders(); }); }); }); } const mobileGroup = new import_obsidian4.SettingGroup(containerEl).setHeading("Mobile"); mobileGroup.addSetting((setting) => { setting.setName("Separate mobile home base").setDesc("Use a different home base on mobile devices").addToggle((toggle) => { toggle.setValue(this.plugin.settings.separateMobile).onChange(async (value) => { this.plugin.settings.separateMobile = value; await this.plugin.saveSettings(); const scrollContainer = containerEl.closest(".vertical-tab-content") || containerEl.closest(".settings-content") || containerEl.parentElement; const scrollTop = (scrollContainer == null ? void 0 : scrollContainer.scrollTop) || 0; this.display(); requestAnimationFrame(() => { if (scrollContainer) { scrollContainer.scrollTop = scrollTop; } }); }); }); }); if (this.plugin.settings.separateMobile) { mobileGroup.addSetting((setting) => { setting.setName("Mobile home base").setDesc("What to open as your home base on mobile").addDropdown((dropdown) => { const mobileType = this.plugin.settings.mobileHomeBaseType || "File" /* File */; let pluginDisabled = false; for (const type of Object.values(HomeBaseType)) { if (!this.plugin.hasRequiredPlugin(type)) { if (type === mobileType) { pluginDisabled = true; dropdown.addOption(type, type); } else { dropdown.selectEl.createEl("option", { text: type, attr: { disabled: "true" } }); continue; } } else { dropdown.addOption(type, type); } } dropdown.setValue(mobileType).onChange(async (value) => { this.plugin.settings.mobileHomeBaseType = value; await this.plugin.saveSettings(); const scrollContainer = containerEl.closest(".vertical-tab-content") || containerEl.closest(".settings-content") || containerEl.parentElement; const scrollTop = (scrollContainer == null ? void 0 : scrollContainer.scrollTop) || 0; this.display(); requestAnimationFrame(() => { if (scrollContainer) { scrollContainer.scrollTop = scrollTop; } }); }); if (pluginDisabled) { setting.descEl.createDiv({ text: "The required plugin has not been enabled or configured for this type.", cls: "mod-warning" }); } }); }); if (!UNCHANGEABLE_TYPES.includes(this.plugin.settings.mobileHomeBaseType)) { mobileGroup.addSetting((setting) => { const mobileType = this.plugin.settings.mobileHomeBaseType; let desc = ""; let placeholder = ""; if (mobileType === "File" /* File */) { desc = "The file to open as your home base on mobile"; placeholder = "Path to home base file"; } else if (mobileType === "Workspace" /* Workspace */) { desc = "The workspace to load as your home base on mobile"; placeholder = "Workspace name"; } else if (mobileType === "Random in folder" /* RandomFolder */) { desc = "The folder to pick a random file from on mobile"; placeholder = "Folder path"; } else if (mobileType === "Journal" /* Journal */) { desc = "The journal name for mobile"; placeholder = "Journal name"; } setting.setName(mobileType === "File" /* File */ ? "Mobile file" : mobileType === "Workspace" /* Workspace */ ? "Mobile workspace" : mobileType === "Random in folder" /* RandomFolder */ ? "Mobile folder" : mobileType === "Journal" /* Journal */ ? "Mobile journal" : "Mobile value").setDesc(desc).addText((text) => { if (mobileType === "File" /* File */) { new FilePathSuggest(this.app, text.inputEl); } else if (mobileType === "Workspace" /* Workspace */) { new WorkspaceSuggest(this.app, text.inputEl); } else if (mobileType === "Random in folder" /* RandomFolder */) { new FolderSuggest(this.app, text.inputEl); } text.setPlaceholder(placeholder).setValue(this.plugin.settings.mobileHomeBaseValue || "").onChange(async (value) => { this.plugin.settings.mobileHomeBaseValue = value; await this.plugin.saveSettings(); }); }); }); } } mobileGroup.addSetting((setting) => { setting.setName("Replace mobile new tab button").setDesc("Change the mobile new tab button to a home icon").addToggle((toggle) => { toggle.setValue(this.plugin.settings.replaceMobileNewTab).onChange(async (value) => { this.plugin.settings.replaceMobileNewTab = value; await this.plugin.saveSettings(); this.plugin.updateMobileButton(); }); }); }); if (this.plugin.settings.useDifferentFileForNewTab) { mobileGroup.addSetting((setting) => { setting.setName("Separate mobile new tab").setDesc("Use a different new tab file on mobile devices").addToggle((toggle) => { toggle.setValue(this.plugin.settings.newTabSeparateMobile).onChange(async (value) => { this.plugin.settings.newTabSeparateMobile = value; await this.plugin.saveSettings(); const scrollContainer = containerEl.closest(".vertical-tab-content") || containerEl.closest(".settings-content") || containerEl.parentElement; const scrollTop = (scrollContainer == null ? void 0 : scrollContainer.scrollTop) || 0; this.display(); requestAnimationFrame(() => { if (scrollContainer) { scrollContainer.scrollTop = scrollTop; } }); }); }); }); if (this.plugin.settings.newTabSeparateMobile) { const mobileType = this.plugin.settings.mobileNewTabType || "File" /* File */; const mobileValue = this.plugin.settings.mobileNewTabValue || ""; mobileGroup.addSetting((setting) => { setting.setName("Mobile new tab type").setDesc("What to open for new tabs on mobile").addDropdown((dropdown) => { let pluginDisabled = false; for (const type of Object.values(HomeBaseType)) { if (!this.plugin.hasRequiredPlugin(type)) { if (type === mobileType) { pluginDisabled = true; dropdown.addOption(type, type); } else { dropdown.selectEl.createEl("option", { text: type, attr: { disabled: "true" } }); continue; } } else { dropdown.addOption(type, type); } } dropdown.setValue(mobileType).onChange(async (value) => { this.plugin.settings.mobileNewTabType = value; await this.plugin.saveSettings(); const scrollContainer = containerEl.closest(".vertical-tab-content") || containerEl.closest(".settings-content") || containerEl.parentElement; const scrollTop = (scrollContainer == null ? void 0 : scrollContainer.scrollTop) || 0; this.display(); requestAnimationFrame(() => { if (scrollContainer) { scrollContainer.scrollTop = scrollTop; } }); }); if (pluginDisabled) { setting.descEl.createDiv({ text: "The required plugin has not been enabled or configured for this type.", cls: "mod-warning" }); } }); }); if (!UNCHANGEABLE_TYPES.includes(mobileType)) { mobileGroup.addSetting((setting) => { let desc = ""; let placeholder = ""; if (mobileType === "File" /* File */) { desc = "The file to open for new tabs on mobile"; placeholder = "Path to mobile new tab file"; } else if (mobileType === "Workspace" /* Workspace */) { desc = "The workspace to load for new tabs on mobile"; placeholder = "Workspace name"; } else if (mobileType === "Random in folder" /* RandomFolder */) { desc = "The folder to pick a random file from for new tabs on mobile"; placeholder = "Folder path"; } else if (mobileType === "Journal" /* Journal */) { desc = "The journal name for new tabs on mobile"; placeholder = "Journal name"; } setting.setName(mobileType === "File" /* File */ ? "Mobile new tab file" : mobileType === "Workspace" /* Workspace */ ? "Mobile new tab workspace" : mobileType === "Random in folder" /* RandomFolder */ ? "Mobile new tab folder" : mobileType === "Journal" /* Journal */ ? "Mobile new tab journal" : "Mobile new tab value").setDesc(desc).addText((text) => { if (mobileType === "File" /* File */) { new FilePathSuggest(this.app, text.inputEl); } else if (mobileType === "Workspace" /* Workspace */) { new WorkspaceSuggest(this.app, text.inputEl); } else if (mobileType === "Random in folder" /* RandomFolder */) { new FolderSuggest(this.app, text.inputEl); } text.setPlaceholder(placeholder).setValue(mobileValue || "").onChange(async (value) => { this.plugin.settings.mobileNewTabValue = value; await this.plugin.saveSettings(); }); }); }); } } } const automationGroup = new import_obsidian4.SettingGroup(containerEl).setHeading("Automation"); automationGroup.addSetting((setting) => { const commandId = this.plugin.settings.commandOnOpen; const command = commandId ? getCommandById(this.app, commandId) : void 0; const displayValue = command ? command.name : commandId; setting.setName("Command on open").setDesc("Run an Obsidian command when opening home base").addText((text) => { new CommandSuggest(this.app, text.inputEl); text.setPlaceholder("Search for a command...").setValue(displayValue || "").onChange(async (value) => { this.plugin.settings.commandOnOpen = value; await this.plugin.saveSettings(); }); }).addExtraButton((btn) => { btn.setIcon("x").setTooltip("Clear command").onClick(async () => { this.plugin.settings.commandOnOpen = ""; await this.plugin.saveSettings(); const scrollContainer = containerEl.closest(".vertical-tab-content") || containerEl.closest(".settings-content") || containerEl.parentElement; const scrollTop = (scrollContainer == null ? void 0 : scrollContainer.scrollTop) || 0; this.display(); requestAnimationFrame(() => { if (scrollContainer) { scrollContainer.scrollTop = scrollTop; } }); }); }); }); automationGroup.addSetting((setting) => { setting.setName("Wait for git sync").setDesc("Wait before creating periodic or journal notes to allow git sync to finish pulling existing notes. Only applies when a note doesn't already exist.").addToggle((toggle) => { toggle.setValue(this.plugin.settings.waitForGitSync).onChange(async (value) => { this.plugin.settings.waitForGitSync = value; await this.plugin.saveSettings(); this.display(); }); }); }); if (this.plugin.settings.waitForGitSync) { automationGroup.addSetting((setting) => { setting.setName("Git sync timeout (seconds)").setDesc("How long to wait for git sync to finish before creating a new note").addText((text) => { var _a; text.inputEl.type = "number"; text.setPlaceholder("3").setValue(((_a = this.plugin.settings.gitSyncTimeout) == null ? void 0 : _a.toString()) || "3").onChange(async (value) => { const numValue = parseInt(value); if (!isNaN(numValue) && numValue >= 0) { this.plugin.settings.gitSyncTimeout = numValue; await this.plugin.saveSettings(); } }); }); }); } } }; // src/services/home-service.ts var import_obsidian7 = require("obsidian"); // src/utils/file-utils.ts var import_obsidian5 = require("obsidian"); var SUPPORTED_EXTENSIONS2 = ["md", "mdx", "canvas", "base", "kanban"]; function isSupportedExtension(extension) { return SUPPORTED_EXTENSIONS2.includes(extension); } function isMarkdownLike(file) { const ext = file.extension.toLowerCase(); return ext === "md" || ext === "mdx"; } function getFileByPath(app, path) { const exactMatch = app.vault.getAbstractFileByPath(path); if (exactMatch instanceof import_obsidian5.TFile) { return exactMatch; } const file = app.metadataCache.getFirstLinkpathDest(path, "/"); return file; } function trimFileExtension(path) { const lastDot = path.lastIndexOf("."); if (lastDot > 0) { const ext = path.slice(lastDot + 1).toLowerCase(); if (SUPPORTED_EXTENSIONS2.includes(ext)) { return path.slice(0, lastDot); } } return path; } function pathsEqual(path1, path2) { const norm1 = trimFileExtension(path1).toLowerCase(); const norm2 = trimFileExtension(path2).toLowerCase(); return norm1 === norm2; } function leafHasFile(leaf, filePath) { var _a, _b; const state = (_b = (_a = leaf.view) == null ? void 0 : _a.getState) == null ? void 0 : _b.call(_a); const leafFile = state == null ? void 0 : state.file; if (!leafFile) return false; return pathsEqual(leafFile, filePath); } // src/utils/homebase-resolver.ts var import_obsidian6 = require("obsidian"); var import_obsidian_daily_notes_interface = __toESM(require_main(), 1); function randomFile(app, root) { let files = []; if (root) { const resolvedRoot = app.vault.getFolderByPath(root); if (resolvedRoot) { files = getFilesInFolder(resolvedRoot); } else { const allFiles = app.vault.getFiles(); const pattern = root.toLowerCase(); files = allFiles.filter((f) => { const fileName = f.name.toLowerCase(); return fileName === pattern || fileName === pattern.replace(/\.md$/, ""); }); } } else { files = app.vault.getFiles(); } files = files.filter((f) => ["md", "canvas", "base"].includes(f.extension)); if (files.length) { const index = Math.floor(Math.random() * files.length); return files[index] || null; } return null; } function getFilesInFolder(folder) { let files = []; for (const item of folder.children) { if (item instanceof import_obsidian6.TFile) { files.push(item); } else if (item instanceof import_obsidian6.TFolder) { files.push(...getFilesInFolder(item)); } } return files; } function trimFile(file) { if (!file) return ""; return file.extension === "md" ? file.path.slice(0, -3) : file.path; } var PERIODIC_INFO = { ["Daily Note" /* DailyNote */]: { noun: "day", adjective: "daily", create: import_obsidian_daily_notes_interface.createDailyNote, get: import_obsidian_daily_notes_interface.getDailyNote, getAll: import_obsidian_daily_notes_interface.getAllDailyNotes }, ["Weekly Note" /* WeeklyNote */]: { noun: "week", adjective: "weekly", create: import_obsidian_daily_notes_interface.createWeeklyNote, get: import_obsidian_daily_notes_interface.getWeeklyNote, getAll: import_obsidian_daily_notes_interface.getAllWeeklyNotes }, ["Monthly Note" /* MonthlyNote */]: { noun: "month", adjective: "monthly", create: import_obsidian_daily_notes_interface.createMonthlyNote, get: import_obsidian_daily_notes_interface.getMonthlyNote, getAll: import_obsidian_daily_notes_interface.getAllMonthlyNotes }, ["Quarterly Note" /* QuarterlyNote */]: { noun: "quarter", adjective: "quarterly", create: import_obsidian_daily_notes_interface.createQuarterlyNote, get: import_obsidian_daily_notes_interface.getQuarterlyNote, getAll: import_obsidian_daily_notes_interface.getAllQuarterlyNotes }, ["Yearly Note" /* YearlyNote */]: { noun: "year", adjective: "yearly", create: import_obsidian_daily_notes_interface.createYearlyNote, get: import_obsidian_daily_notes_interface.getYearlyNote, getAll: import_obsidian_daily_notes_interface.getAllYearlyNotes }, ["File" /* File */]: null, ["Random file" /* Random */]: null, ["Random in folder" /* RandomFolder */]: null, ["Workspace" /* Workspace */]: null, ["Graph view" /* Graph */]: null, ["Nothing" /* None */]: null, ["Journal" /* Journal */]: null, ["New note" /* NewNote */]: null }; async function getPeriodicNote(kind, plugin) { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l; if (!window.moment) { return null; } const info = PERIODIC_INFO[kind]; if (!info) { return null; } const date = (0, import_obsidian6.moment)().startOf(info.noun); const communityPlugins = ((_a = plugin.app.plugins) == null ? void 0 : _a.plugins) || {}; const periodicNotesPlugin = communityPlugins["periodic-notes"]; const isLegacy = !periodicNotesPlugin || (((_b = periodicNotesPlugin.manifest) == null ? void 0 : _b.version) || "0").startsWith("0"); let note = null; if (isLegacy) { let all = info.getAll(); note = info.get(date, all); if (!note && plugin.settings.waitForGitSync) { new import_obsidian6.Notice(`Home Base: Waiting for git sync (${plugin.settings.gitSyncTimeout}s)...`, 5e3); await delay(plugin.settings.gitSyncTimeout * 1e3); all = info.getAll(); note = info.get(date, all); } if (!note) { note = await info.create(date); } } else { (_d = (_c = periodicNotesPlugin.cache) == null ? void 0 : _c.initialize) == null ? void 0 : _d.call(_c); note = (_f = (_e = periodicNotesPlugin.getPeriodicNote) == null ? void 0 : _e.call(periodicNotesPlugin, info.noun, date)) != null ? _f : null; if (!note && plugin.settings.waitForGitSync) { new import_obsidian6.Notice(`Home Base: Waiting for git sync (${plugin.settings.gitSyncTimeout}s)...`, 5e3); await delay(plugin.settings.gitSyncTimeout * 1e3); (_h = (_g = periodicNotesPlugin.cache) == null ? void 0 : _g.initialize) == null ? void 0 : _h.call(_g); note = (_j = (_i = periodicNotesPlugin.getPeriodicNote) == null ? void 0 : _i.call(periodicNotesPlugin, info.noun, date)) != null ? _j : null; } if (!note) { note = (_l = await ((_k = periodicNotesPlugin.createPeriodicNote) == null ? void 0 : _k.call(periodicNotesPlugin, info.noun, date))) != null ? _l : null; } } return note ? trimFile(note) : null; } async function getJournalNote(journalName, plugin) { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l; const communityPlugins = ((_a = plugin.app.plugins) == null ? void 0 : _a.plugins) || {}; const journals = communityPlugins["journals"]; if (!journals) return null; try { const journal = (_b = journals.getJournal) == null ? void 0 : _b.call(journals, journalName); if (!journal) return null; const origAutoCreate = (_d = (_c = journal.config) == null ? void 0 : _c.value) == null ? void 0 : _d.autoCreate; (_e = journals.reprocessNotes) == null ? void 0 : _e.call(journals); if ((_f = journal.config) == null ? void 0 : _f.value) { journal.config.value.autoCreate = true; } await ((_g = journal.autoCreate) == null ? void 0 : _g.call(journal)); if ((_h = journal.config) == null ? void 0 : _h.value) { journal.config.value.autoCreate = origAutoCreate; } const today = (0, import_obsidian6.moment)().locale("custom-journal-locale").startOf("day"); let note = (_i = journal.get) == null ? void 0 : _i.call(journal, today); if (!note && plugin.settings.waitForGitSync) { new import_obsidian6.Notice(`Home Base: Waiting for git sync (${plugin.settings.gitSyncTimeout}s)...`, 5e3); await delay(plugin.settings.gitSyncTimeout * 1e3); (_j = journals.reprocessNotes) == null ? void 0 : _j.call(journals); note = (_k = journal.get) == null ? void 0 : _k.call(journal, today); } if (!note) return null; const path = (_l = journal.getNotePath) == null ? void 0 : _l.call(journal, note); return path ? path.replace(/\.md$/, "") : null; } catch (e) { return null; } } function resolvePathSync(type, value, app) { switch (type) { case "File" /* File */: return value || null; case "Daily Note" /* DailyNote */: case "Weekly Note" /* WeeklyNote */: case "Monthly Note" /* MonthlyNote */: case "Quarterly Note" /* QuarterlyNote */: case "Yearly Note" /* YearlyNote */: { const info = PERIODIC_INFO[type]; if (info) { const date = (0, import_obsidian6.moment)().startOf(info.noun); const all = info.getAll(); const note = info.get(date, all); return note ? trimFile(note) : null; } return null; } default: return type === "Random in folder" /* RandomFolder */ || type === "New note" /* NewNote */ ? null : value || null; } } async function computeHomeBasePath(type, value, plugin) { switch (type) { case "File" /* File */: return value || null; case "Random file" /* Random */: { const file = randomFile(plugin.app); return file ? trimFile(file) : null; } case "Random in folder" /* RandomFolder */: { const file = randomFile(plugin.app, value); return file ? trimFile(file) : null; } case "Daily Note" /* DailyNote */: case "Weekly Note" /* WeeklyNote */: case "Monthly Note" /* MonthlyNote */: case "Quarterly Note" /* QuarterlyNote */: case "Yearly Note" /* YearlyNote */: return await getPeriodicNote(type, plugin); case "Journal" /* Journal */: return await getJournalNote(value, plugin); case "New note" /* NewNote */: { const fileManager = plugin.app.fileManager; if (fileManager.createNewFile) { const file = await fileManager.createNewFile(plugin.app.vault.getRoot(), value || "Untitled"); return file ? trimFile(file) : null; } return null; } case "Workspace" /* Workspace */: case "Graph view" /* Graph */: case "Nothing" /* None */: return null; default: return value || null; } } function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } // src/services/home-service.ts var LEAF_TYPES = ["markdown", "canvas", "bases", "kanban"]; var DETACH_DELAY = 100; var GRAPH_INIT_DELAY = 200; var GRAPH_COMMAND_FALLBACK_DELAY = 300; function equalsCaseless(path1, path2) { const normalize = (p) => p.toLowerCase().replace(/\.md$/, ""); return normalize(path1) === normalize(path2); } var HomeBaseService = class { constructor(plugin) { this.ghostLeaves = /* @__PURE__ */ new WeakSet(); this.plugin = plugin; this.app = plugin.app; } /** * Open home base with a specific mode (for startup/manual opens) */ async openHomeBaseWithMode(mode, runCommand = true) { var _a; const homeBaseSettings = this.plugin.getHomeBaseSettings(); if (homeBaseSettings.type === "Workspace" /* Workspace */) { return this.openWorkspace(homeBaseSettings.value); } if (homeBaseSettings.type === "Graph view" /* Graph */) { if (this.plugin.settings.showStickyHomeIcon) { return this.openHomeBaseInGhostTab({ runCommand }); } return this.openGraph(); } if (homeBaseSettings.type === "Nothing" /* None */) { if (runCommand) { this.runCommandOnOpen(); } return true; } const resolvedPath = await computeHomeBasePath( homeBaseSettings.type, homeBaseSettings.value, this.plugin ); if (!resolvedPath) { return false; } let file = this.app.metadataCache.getFirstLinkpathDest(resolvedPath, "/"); if (!file) { file = getFileByPath(this.app, resolvedPath); } if (!file) { const untrimmedPath = resolvedPath.endsWith(".md") ? resolvedPath : `${resolvedPath}.md`; file = getFileByPath(this.app, untrimmedPath); if (!file && homeBaseSettings.type === "File" /* File */) { return false; } } if (!file) { return false; } if (mode === "replace-all") { await this.detachAllLeaves(); } else if (mode === "replace-last") { const activeLeaf = (_a = this.app.workspace.getActiveViewOfType(import_obsidian7.View)) == null ? void 0 : _a.leaf; if (activeLeaf) { const viewState = activeLeaf.getViewState(); if (viewState.pinned !== true) { void activeLeaf.detach(); await new Promise((resolve) => setTimeout(resolve, DETACH_DELAY)); } } } const existingLeaf = this.findExistingHomeBaseLeaf(file); if (existingLeaf && mode !== "replace-all") { const viewState = existingLeaf.getViewState(); if (viewState.pinned === true && this.plugin.settings.showStickyHomeIcon) { } else { this.app.workspace.setActiveLeaf(existingLeaf); await this.configureView(existingLeaf, file); if (runCommand) { this.runCommandOnOpen(); } return true; } } const newLeaf = mode === "retain" ? this.app.workspace.getLeaf("tab") : this.app.workspace.getLeaf(false); if (!newLeaf) { return false; } await newLeaf.openFile(file); this.app.workspace.setActiveLeaf(newLeaf); await this.configureView(newLeaf, file); if (runCommand) { this.runCommandOnOpen(); } return true; } /** * Open workspace */ async openWorkspace(workspaceName) { var _a, _b, _c; const workspacePlugin = (_b = (_a = this.app.internalPlugins) == null ? void 0 : _a.plugins) == null ? void 0 : _b.workspaces; if (!(workspacePlugin == null ? void 0 : workspacePlugin.enabled) || !((_c = workspacePlugin.instance) == null ? void 0 : _c.loadWorkspace)) { return false; } workspacePlugin.instance.loadWorkspace(workspaceName); await new Promise((resolve) => setTimeout(resolve, DETACH_DELAY)); return true; } /** * Open graph view */ async openGraph() { var _a, _b; await ((_b = (_a = this.app.commands) == null ? void 0 : _a.executeCommandById) == null ? void 0 : _b.call(_a, "graph:open")); return true; } // Removed deprecated openGraphInGhostTab - now integrated into openHomeBaseInGhostTab /** * Open the home base file * @param options Options for opening */ async openHomeBase(options = {}) { const { runCommand = true } = options; const mode = this.plugin.settings.manualOpenMode; return this.openHomeBaseWithMode(mode, runCommand); } /** * Open home base in an empty leaf (for new tab replacement) */ async openInLeaf(leaf) { const homeBaseSettings = this.plugin.getHomeBaseSettings(); return this.openInLeafWithSettings(leaf, homeBaseSettings); } /** * Open a file in an empty leaf with custom settings * @param leaf The leaf to open the file in * @param settings Settings object with type and value * @param isNewTab Whether this is for new tab replacement (skips pinning/ghost tab logic) */ async openInLeafWithSettings(leaf, settings, isNewTab = false) { if (settings.type === "Workspace" /* Workspace */) { await this.openWorkspace(settings.value); return true; } if (settings.type === "Graph view" /* Graph */) { await this.openGraph(); return true; } if (settings.type === "Nothing" /* None */) { this.runCommandOnOpen(); return true; } const resolvedPath = await computeHomeBasePath( settings.type, settings.value, this.plugin ); if (!resolvedPath) { console.warn("[Home Base] Could not resolve path for new tab:", settings.type, settings.value); return false; } let file = this.app.metadataCache.getFirstLinkpathDest(resolvedPath, "/"); if (!file) { file = getFileByPath(this.app, resolvedPath); } if (!file && !resolvedPath.endsWith(".md") && !resolvedPath.endsWith(".canvas") && !resolvedPath.endsWith(".base")) { const untrimmedPath = `${resolvedPath}.md`; file = getFileByPath(this.app, untrimmedPath); } if (!file) { console.warn("[Home Base] File not found for new tab:", resolvedPath); return false; } if (isNewTab) { console.debug("[Home Base] openInLeafWithSettings: isNewTab=true, bypassing ghost tab logic", { file: file.path, settings }); await leaf.openFile(file); await this.configureView(leaf, file); this.runCommandOnOpen(); return true; } const isTrulyEmpty = !leaf.view || leaf.view.getViewType() === "empty"; if (this.plugin.settings.showStickyHomeIcon && isTrulyEmpty) { const isRandom = settings.type === "Random file" /* Random */ || settings.type === "Random in folder" /* RandomFolder */ || settings.type === "Daily Note" /* DailyNote */ || settings.type === "Weekly Note" /* WeeklyNote */ || settings.type === "Monthly Note" /* MonthlyNote */ || settings.type === "Yearly Note" /* YearlyNote */; const ghostTab = this.findGhostTab(file, isRandom); if (ghostTab) { void leaf.detach(); this.app.workspace.setActiveLeaf(ghostTab); await this.configureView(ghostTab, file); this.runCommandOnOpen(); return true; } this.ghostLeaves.add(leaf); if (!isRandom) { leaf.setPinned(true); } } await leaf.openFile(file); await this.configureView(leaf, file); this.runCommandOnOpen(); return true; } /** * Configure the view mode for a leaf */ async configureView(leaf, file) { const settings = this.plugin.settings; const view = leaf.view; if (!isMarkdownLike(file) || !(view instanceof import_obsidian7.MarkdownView)) { return; } const state = view.getState(); if (settings.revertView) { this.lastView = new WeakRef(view); } if (settings.autoScroll) { const count = view.editor.lineCount(); if (state.mode === "preview") { view.previewMode.applyScroll(count - 4); } else { view.editor.setCursor(count); view.editor.focus(); } } if (settings.openViewMode !== "default") { switch (settings.openViewMode) { case "preview": state.mode = "preview"; break; case "source": state.mode = "source"; state.source = true; break; case "live": state.mode = "source"; state.source = false; break; } await leaf.setViewState({ type: "markdown", state }); } } /** * Revert view to default when navigating away from home base */ async revertView() { const settings = this.plugin.settings; if (!settings.revertView || !this.lastView || settings.openViewMode === "default") { return; } const view = this.lastView.deref(); if (!view) { this.lastView = void 0; return; } const homeBaseSettings = this.plugin.getHomeBaseSettings(); const resolvedPath = await computeHomeBasePath( homeBaseSettings.type, homeBaseSettings.value, this.plugin ); if (!resolvedPath) { this.lastView = void 0; return; } const currentFile = view.file; if (currentFile && equalsCaseless(trimFile(currentFile), resolvedPath)) { return; } const state = view.getState(); const config = this.app.vault.config; const mode = (config == null ? void 0 : config.defaultViewMode) || "source"; const source = (config == null ? void 0 : config.livePreview) !== void 0 ? !config.livePreview : false; if (view.leaf.getViewState().type === "markdown" && (mode !== state.mode || source !== state.source)) { state.mode = mode; state.source = source; await view.leaf.setViewState({ type: "markdown", state, active: true }); } this.lastView = void 0; } /** * Run the configured command after opening */ runCommandOnOpen() { const commandId = this.plugin.settings.commandOnOpen; if (commandId) { setTimeout(() => { executeCommand(this.app, commandId); }, 100); } } /** * Find an existing leaf that has the home base file open */ findExistingHomeBaseLeaf(file) { if (!file) return null; const homeBasePath = file.path; const leaves = LEAF_TYPES.flatMap( (type) => this.app.workspace.getLeavesOfType(type) ); for (const leaf of leaves) { if (leafHasFile(leaf, homeBasePath)) { return leaf; } } return null; } /** * Check if a leaf is a ghost tab * Ghost tab is identified by being in our internal ghostLeaves set * Only tabs specifically created for the sticky icon are ghost tabs */ isGhostLeaf(leaf) { return this.ghostLeaves.has(leaf); } /** * Find the ghost tab (the one opened via sticky icon) * Ghost tab is identified by being in our internal ghostLeaves set * Only returns existing ghost tabs, doesn't create new ones */ findGhostTab(file, isRandom = false) { if (!file) return null; const homeBasePath = file.path; const leaves = []; this.app.workspace.iterateAllLeaves((leaf) => { var _a; const viewType = (_a = leaf.view) == null ? void 0 : _a.getViewType(); if (viewType && LEAF_TYPES.includes(viewType)) { leaves.push(leaf); } }); for (const leaf of leaves) { if (this.ghostLeaves.has(leaf) && leafHasFile(leaf, homeBasePath)) { return leaf; } } return null; } /** * Open home base in ghost tab (for sticky icon) * Ghost tab is pinned and hidden (if setting enabled) * Only one ghost tab should exist at a time * Works for file-based types and Graph view * Note: Random types don't pin (since file changes each time) * Note: Workspace and None don't work (workspace changes layout, None doesn't open anything) */ async openHomeBaseInGhostTab(options = {}) { const { runCommand = true } = options; const homeBaseSettings = this.plugin.getHomeBaseSettings(); if (homeBaseSettings.type === "Workspace" /* Workspace */ || homeBaseSettings.type === "Nothing" /* None */) { return this.openHomeBaseWithMode("retain", runCommand); } if (homeBaseSettings.type === "Graph view" /* Graph */) { let ghostTab2 = this.findGraphGhostTab(); if (ghostTab2) { this.ghostLeaves.add(ghostTab2); ghostTab2.setPinned(true); this.app.workspace.setActiveLeaf(ghostTab2, { focus: !this.isSettingsModalOpen() }); if (runCommand) this.runCommandOnOpen(); return true; } const newLeaf = this.app.workspace.getLeaf("tab"); if (newLeaf) { await newLeaf.setViewState({ type: "graph", state: {} }); await new Promise((resolve) => setTimeout(resolve, GRAPH_INIT_DELAY)); this.ghostLeaves.add(newLeaf); newLeaf.setPinned(true); this.app.workspace.setActiveLeaf(newLeaf, { focus: !this.isSettingsModalOpen() }); if (runCommand) this.runCommandOnOpen(); return true; } await this.openGraph(); await new Promise((resolve) => setTimeout(resolve, GRAPH_COMMAND_FALLBACK_DELAY)); ghostTab2 = this.findGraphGhostTab(); if (ghostTab2) { this.ghostLeaves.add(ghostTab2); ghostTab2.setPinned(true); this.app.workspace.setActiveLeaf(ghostTab2, { focus: !this.isSettingsModalOpen() }); if (runCommand) this.runCommandOnOpen(); return true; } return false; } const isRandom = homeBaseSettings.type === "Random file" /* Random */ || homeBaseSettings.type === "Random in folder" /* RandomFolder */ || homeBaseSettings.type === "Daily Note" /* DailyNote */ || homeBaseSettings.type === "Weekly Note" /* WeeklyNote */ || homeBaseSettings.type === "Monthly Note" /* MonthlyNote */ || homeBaseSettings.type === "Yearly Note" /* YearlyNote */; if (this.isSettingsModalOpen()) { return false; } const resolvedPath = await computeHomeBasePath( homeBaseSettings.type, homeBaseSettings.value, this.plugin ); if (!resolvedPath) { return false; } let file = this.app.metadataCache.getFirstLinkpathDest(resolvedPath, "/"); if (!file) { file = getFileByPath(this.app, resolvedPath); } if (!file && !resolvedPath.endsWith(".md") && !resolvedPath.endsWith(".canvas") && !resolvedPath.endsWith(".base")) { const untrimmedPath = `${resolvedPath}.md`; file = getFileByPath(this.app, untrimmedPath); } if (!file) { return false; } const ghostTab = this.findGhostTab(file, isRandom); console.debug("[Home Base] openHomeBaseInGhostTab:", { file: file.path, ghostTabFound: !!ghostTab, isRandom, zenMode: document.body.classList.contains("zenmode-active") }); if (ghostTab) { const shouldFocus2 = !this.isSettingsModalOpen(); this.app.workspace.setActiveLeaf(ghostTab, { focus: shouldFocus2 }); await this.configureView(ghostTab, file); if (runCommand) { this.runCommandOnOpen(); } return true; } const newGhostTab = this.app.workspace.getLeaf("tab"); this.ghostLeaves.add(newGhostTab); await newGhostTab.openFile(file); if (!isRandom) { newGhostTab.setPinned(true); } setTimeout(() => { this.plugin.stickyTabService.updateTabHeaders(); }, 50); const shouldFocus = !this.isSettingsModalOpen(); this.app.workspace.setActiveLeaf(newGhostTab, { focus: shouldFocus }); await this.configureView(newGhostTab, file); if (runCommand) { this.runCommandOnOpen(); } return true; } /** * Find an empty leaf */ findEmptyLeaf() { const leaves = this.app.workspace.getLeavesOfType("empty"); return leaves[0] || null; } /** * Get the home base file */ getHomeBaseFile() { const homeBaseSettings = this.plugin.getHomeBaseSettings(); const path = resolvePathSync(homeBaseSettings.type, homeBaseSettings.value, this.app); if (!path) return null; return getFileByPath(this.app, path); } /** * Fast detach all leaves using changeLayout (like homepage plugin) * This is much faster than iterating and detaching leaves individually */ async detachAllLeaves() { var _a, _b; const layout = this.app.workspace.getLayout(); layout.main = { "id": "5324373015726ba8", "type": "split", "children": [{ "id": "4509724f8bf84da7", "type": "tabs", "children": [{ "id": "e7a7b303c61786dc", "type": "leaf", "state": { "type": "empty", "state": {}, "icon": "lucide-file", "title": "New tab" } }] }], "direction": "vertical" }; layout.active = "e7a7b303c61786dc"; await this.app.workspace.changeLayout(layout); if (import_obsidian7.Platform.isMobile) { (_b = (_a = this.app.workspace.rightSplit) == null ? void 0 : _a.updateInfo) == null ? void 0 : _b.call(_a); } } /** * Close all leaves in the main workspace except the specified one * Simplified approach: iterate all leaves and close those in main workspace */ async closeAllLeavesExcept(exceptLeaf) { const leavesToClose = []; this.app.workspace.iterateAllLeaves((leaf) => { if (leaf === exceptLeaf) { return; } const view = leaf.view; let container = null; if (view) { const viewAny = view; container = viewAny.containerEl || null; } if (!container) { const leafAny = leaf; container = leafAny.containerEl || null; } if (container) { const rootWorkspace = container.closest(".workspace-split.mod-vertical.mod-root"); const leftSidebar = container.closest(".workspace-split.mod-left-split"); const rightSidebar = container.closest(".workspace-split.mod-right-split"); if (rootWorkspace && !leftSidebar && !rightSidebar) { leavesToClose.push(leaf); } } else { if (exceptLeaf === null) { try { const viewState = leaf.getViewState(); if (viewState) { leavesToClose.push(leaf); } } catch (e) { } } } }); for (const leaf of leavesToClose) { void leaf.detach(); } await new Promise((resolve) => setTimeout(resolve, 200)); } /** * Find an existing graph leaf that should be treated as a ghost tab */ findGraphGhostTab() { let graphLeaves = []; this.app.workspace.iterateAllLeaves((leaf) => { var _a; if (((_a = leaf.view) == null ? void 0 : _a.getViewType()) === "graph") { graphLeaves.push(leaf); } }); const pinned = graphLeaves.find((l) => l.getViewState().pinned === true); if (pinned) return pinned; if (graphLeaves.length === 1 && graphLeaves[0]) return graphLeaves[0]; return null; } /** * Check if the focused tab is the home base */ isFocusedOnHomeBase() { var _a, _b; const activeLeaf = (_a = this.app.workspace.getActiveViewOfType(import_obsidian7.View)) == null ? void 0 : _a.leaf; if (!activeLeaf) return false; const homeBaseSettings = this.plugin.getHomeBaseSettings(); if (homeBaseSettings.type === "Graph view" /* Graph */) { return ((_b = activeLeaf.view) == null ? void 0 : _b.getViewType()) === "graph"; } const homeBaseFile = this.getHomeBaseFile(); if (!homeBaseFile) return false; return leafHasFile(activeLeaf, homeBaseFile.path); } /** * Check if home base file exists */ homeBaseExists() { const homeBaseSettings = this.plugin.getHomeBaseSettings(); const path = resolvePathSync(homeBaseSettings.type, homeBaseSettings.value, this.app); if (!path) return false; return getFileByPath(this.app, path) !== null; } /** * Get the native Obsidian open behavior setting (from app.json) * @returns The native setting value or undefined if not supported/found */ getNativeOpenBehavior() { const config = this.app.vault.config; if (!config) return void 0; return config.openBehavior; } /** * Check if the settings modal is currently open */ isSettingsModalOpen() { const settingsModal = document.querySelector(".modal-container.mod-settings") || document.querySelector(".modal.mod-settings") || document.querySelector(".vertical-tab-content"); if (!settingsModal) { const allModals = document.querySelectorAll(".modal-container"); for (const modal of Array.from(allModals)) { if (modal.querySelector(".vertical-tab-content") || modal.querySelector(".settings-content") || modal.classList.contains("mod-settings")) { return true; } } } return settingsModal !== null; } /** * Set the active file as home base */ async setActiveFileAsHomeBase() { const activeFile = this.app.workspace.getActiveFile(); if (!activeFile) return false; if (!isSupportedExtension(activeFile.extension.toLowerCase())) { return false; } if (this.plugin.settings.separateMobile && import_obsidian7.Platform.isMobile) { this.plugin.settings.mobileHomeBaseType = "File" /* File */; this.plugin.settings.mobileHomeBaseValue = activeFile.path; } else { this.plugin.settings.homeBaseType = "File" /* File */; this.plugin.settings.homeBaseValue = activeFile.path; } await this.plugin.saveSettings(); return true; } /** * Check if active file can be set as home base */ canSetActiveFileAsHomeBase() { const activeFile = this.app.workspace.getActiveFile(); if (!activeFile) return false; return isSupportedExtension(activeFile.extension.toLowerCase()); } /** * Restore ghost leaves from previous session * This identifies pinned home base tabs that should be treated as ghost leaves */ restoreGhostLeaves() { if (!this.plugin.settings.showStickyHomeIcon) { return; } const homeBaseSettings = this.plugin.getHomeBaseSettings(); const homeBasePath = resolvePathSync(homeBaseSettings.type, homeBaseSettings.value, this.app); if (!homeBasePath && homeBaseSettings.type !== "Graph view" /* Graph */) return; const isRandom = homeBaseSettings.type === "Random file" /* Random */ || homeBaseSettings.type === "Random in folder" /* RandomFolder */ || homeBaseSettings.type === "Daily Note" /* DailyNote */ || homeBaseSettings.type === "Weekly Note" /* WeeklyNote */ || homeBaseSettings.type === "Monthly Note" /* MonthlyNote */ || homeBaseSettings.type === "Yearly Note" /* YearlyNote */; if (isRandom) return; if (homeBaseSettings.type === "Graph view" /* Graph */) { const ghostTab = this.findGraphGhostTab(); if (ghostTab && ghostTab.getViewState().pinned === true) { this.ghostLeaves.add(ghostTab); } return; } const leaves = []; this.app.workspace.iterateAllLeaves((leaf) => { var _a; const viewType = (_a = leaf.view) == null ? void 0 : _a.getViewType(); if (viewType && LEAF_TYPES.includes(viewType)) { leaves.push(leaf); } }); for (const leaf of leaves) { if (homeBasePath && leafHasFile(leaf, homeBasePath)) { const viewState = leaf.getViewState(); if (viewState.pinned === true && !this.ghostLeaves.has(leaf)) { this.ghostLeaves.add(leaf); break; } } } } }; // src/services/new-tab-service.ts var import_obsidian8 = require("obsidian"); var STARTUP_RESTORE_DELAY = 500; var DETACH_SETTLE_DELAY = 200; var PLUGIN_RACE_DELAY = 50; var NewTabService = class { constructor(plugin) { this.existingLeaves = /* @__PURE__ */ new WeakSet(); this.isStartup = true; this.startupCompleted = false; this.plugin = plugin; this.app = plugin.app; } /** * Track all existing leaves (for new tab detection) * This must be called even when startup is handled elsewhere */ trackExistingLeaves() { this.app.workspace.iterateAllLeaves((leaf) => { this.existingLeaves.add(leaf); }); this.startupCompleted = true; this.isStartup = false; } /** * Initialize the service - called when layout is ready */ initialize() { this.trackExistingLeaves(); void this.handleStartup(); } /** * Handle app startup - open home base if needed * Only called on actual app startup, not plugin reloads */ async handleStartup() { const settings = this.plugin.settings; const homeBaseSettings = this.plugin.getHomeBaseSettings(); if (!settings.openOnStartup || !homeBaseSettings.value && homeBaseSettings.type === "File" /* File */) { this.startupCompleted = true; this.isStartup = false; return; } if (await this.hasUrlParams()) { this.startupCompleted = true; this.isStartup = false; return; } await new Promise((resolve) => setTimeout(resolve, STARTUP_RESTORE_DELAY)); if (settings.openMode === "replace-all") { let exceptLeaf = null; if (!settings.hideReleaseNotes) { const allLeaves = this.app.workspace.getLeavesOfType("markdown"); for (const leaf of allLeaves) { const view = leaf.view; const markdownView = view; if (markdownView.file) { const file = markdownView.file; const configDir = this.app.vault.configDir; if (file.path.includes("release") || file.path.includes(configDir)) { const container = markdownView.containerEl; if (container && container.querySelector(".release-notes")) { exceptLeaf = leaf; break; } } } } } await this.plugin.homeService.closeAllLeavesExcept(exceptLeaf); await new Promise((resolve) => setTimeout(resolve, DETACH_SETTLE_DELAY)); } if (settings.showStickyHomeIcon) { await this.plugin.homeService.openHomeBaseInGhostTab({ runCommand: true }); } else { await this.plugin.homeService.openHomeBase({ replaceActiveLeaf: false, runCommand: true }); } this.startupCompleted = true; this.isStartup = false; } /** * Check if the settings modal is currently open */ isSettingsModalOpen() { const settingsModal = document.querySelector(".modal-container.mod-settings") || document.querySelector(".modal.mod-settings") || document.querySelector(".vertical-tab-content"); if (!settingsModal) { const allModals = document.querySelectorAll(".modal-container"); for (const modal of Array.from(allModals)) { if (modal.querySelector(".vertical-tab-content") || modal.querySelector(".settings-content") || modal.classList.contains("mod-settings")) { return true; } } } return settingsModal !== null; } /** * Check for URL parameters that indicate Obsidian was opened via a link * Based on obsidian-homepage implementation */ async hasUrlParams() { var _a; const windowAny = window; const capacitor = windowAny.Capacitor; if ((_a = capacitor == null ? void 0 : capacitor.Plugins) == null ? void 0 : _a.App) { try { const launchUrl = await capacitor.Plugins.App.getLaunchUrl(); if (launchUrl == null ? void 0 : launchUrl.url) { const url = new URL(launchUrl.url); const params = Array.from(url.searchParams.keys()); const action = url.hostname; if (["open", "advanced-uri"].includes(action) && ["file", "filepath", "workspace"].some((e) => params.includes(e))) { return true; } } } catch (e) { } } const obsAct = windowAny.OBS_ACT; if (obsAct) { const params = Object.keys(obsAct); const action = obsAct.action; if (action && ["open", "advanced-uri"].includes(action) && ["file", "filepath", "workspace"].some((e) => params.includes(e))) { return true; } } return false; } /** * Handle layout change event - check for new empty tabs * Based on new-tab-default-page implementation */ handleLayoutChange() { if (this.isStartup || !this.startupCompleted) { return; } this.app.workspace.iterateAllLeaves((leaf) => { if (this.existingLeaves.has(leaf)) { return; } this.existingLeaves.add(leaf); if (!this.isEmptyTab(leaf)) { return; } const isOnlyTab = this.isOnlyTab(leaf); if (isOnlyTab && this.plugin.settings.openWhenAllTabsClosed === true) { void this.replaceEmptyTab(leaf, true); return; } if (this.plugin.settings.replaceNewTab !== true) { return; } if (this.plugin.settings.replaceNewTab !== true) { return; } if (this.plugin.settings.newTabMode === "only-when-empty") { if (!isOnlyTab) { return; } } void this.replaceEmptyTab(leaf, false); }); } /** * Check if a leaf is an empty tab * IMPORTANT: Only returns true if the leaf is truly empty (no file opened) * If a file is already opened in the leaf, it's not empty and should NOT be replaced */ isEmptyTab(leaf) { if (!leaf.view) return true; if (leaf.view.getViewType() !== "empty") { return false; } const viewState = leaf.getViewState(); if (viewState && viewState.file) { return false; } return true; } /** * Check if this is the only tab in the main workspace * Only counts root leaves (main workspace tabs), not sidebar tabs * Based on obsidian-disable-tabs pattern using iterateRootLeaves */ isOnlyTab(leaf) { let tabCount = 0; this.app.workspace.iterateRootLeaves((l) => { tabCount++; }); const result = tabCount === 1; console.debug("[Home Base] isOnlyTab:", { leaf, tabCount, isOnlyTab: result }); return result; } /** * Replace an empty tab with the home base or new tab file * @param leaf The leaf to replace * @param isAllTabsClosed Whether this is triggered by "all tabs closed" (true) or "new tab replacement" (false) */ async replaceEmptyTab(leaf, isAllTabsClosed = false) { if (!isAllTabsClosed) { if (this.plugin.settings.replaceNewTab !== true) { console.debug("[Home Base] replaceEmptyTab: replaceNewTab is not true, aborting"); return; } } await new Promise((resolve) => setTimeout(resolve, PLUGIN_RACE_DELAY)); if (!isAllTabsClosed) { if (this.plugin.settings.replaceNewTab !== true) { console.debug("[Home Base] replaceEmptyTab: replaceNewTab changed during delay, aborting"); return; } } else { if (this.plugin.settings.openWhenAllTabsClosed !== true) { console.debug("[Home Base] replaceEmptyTab: openWhenAllTabsClosed changed during delay, aborting"); return; } } if (!this.isEmptyTab(leaf)) { console.debug("[Home Base] replaceEmptyTab: Tab is no longer empty, skipping"); return; } const settings = isAllTabsClosed ? this.plugin.getHomeBaseSettings() : this.plugin.getNewTabSettings(); console.debug("[Home Base] replaceEmptyTab:", { leaf, isAllTabsClosed, settings, replaceNewTab: this.plugin.settings.replaceNewTab, newTabMode: this.plugin.settings.newTabMode, useDifferentFileForNewTab: this.plugin.settings.useDifferentFileForNewTab }); const success = await this.plugin.homeService.openInLeafWithSettings(leaf, settings, true); if (!success) { console.warn("[Home Base] Failed to open file:", settings); } else { console.debug("[Home Base] replaceEmptyTab: Successfully opened file"); } } /** * Force check for empty workspace and open home base */ async openIfEmpty() { const activeView = this.app.workspace.getActiveViewOfType(import_obsidian8.View); const activeLeaf = activeView == null ? void 0 : activeView.leaf; if (!activeLeaf) return; if (this.isEmptyTab(activeLeaf) && this.isOnlyTab(activeLeaf)) { await this.plugin.homeService.openInLeaf(activeLeaf); } } }; // src/services/sticky-tab-service.ts var import_obsidian9 = require("obsidian"); var TAB_HEADER_OPEN_DELAY = 150; var ICON_PLACEMENT_CHECK_INTERVAL = 100; var WINDOW_OPEN_CONTAINER_DELAY = 100; var STICKY_ICON_CLASS = "home-base-sticky-icon"; var STICKY_ICON_ACTIVE_CLASS = "home-base-sticky-icon-active"; var StickyTabService = class { constructor(plugin) { this.stickyIconEl = null; this.layoutChangeHandler = null; this.tabHeaderUpdateTimeout = null; this.sidebarObserver = null; this.tabHeaderObserver = null; this.plugin = plugin; } /** * Update the sticky tab icon based on settings */ update() { if (import_obsidian9.Platform.isMobile) { this.remove(); this.updateTabHeaders(); this.updateWorkspaceClass(false); return; } if (this.plugin.settings.showStickyHomeIcon) { if (this.stickyIconEl) { const iconName = this.plugin.settings.stickyIconName || "home"; (0, import_obsidian9.setIcon)(this.stickyIconEl, iconName); } else { this.create(); } this.updateWorkspaceClass(true); } else { this.remove(); this.updateTabHeaders(); this.updateWorkspaceClass(false); } } /** * Add/remove CSS class on all workspaces to conditionally apply styles */ updateWorkspaceClass(enabled) { const applyToDocument = (doc) => { const mainWorkspace = doc.querySelector(".workspace-split.mod-vertical.mod-root"); if (!mainWorkspace) return; if (enabled) { mainWorkspace.classList.add("home-base-sticky-icon-enabled"); } else { mainWorkspace.classList.remove("home-base-sticky-icon-enabled"); } }; applyToDocument(document); this.plugin.app.workspace.iterateAllLeaves((leaf) => { var _a, _b; const doc = (_b = (_a = leaf.view) == null ? void 0 : _a.containerEl) == null ? void 0 : _b.ownerDocument; if (doc && doc !== document) { applyToDocument(doc); } }); } /** * Create the sticky home icon */ create() { this.remove(); this.stickyIconEl = document.createElement("div"); this.stickyIconEl.className = `${STICKY_ICON_CLASS} clickable-icon`; this.stickyIconEl.setAttribute("aria-label", "Open home base"); this.stickyIconEl.setAttribute("data-tooltip-position", "bottom"); const iconName = this.plugin.settings.stickyIconName || "home"; (0, import_obsidian9.setIcon)(this.stickyIconEl, iconName); this.stickyIconEl.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); void this.plugin.homeService.openHomeBaseInGhostTab({ runCommand: true }).then(() => { setTimeout(() => { this.updateTabHeaders(); }, TAB_HEADER_OPEN_DELAY); }); }); this.stickyIconEl.addEventListener("contextmenu", (e) => { e.preventDefault(); e.stopPropagation(); const menu = new import_obsidian9.Menu(); menu.addItem((item) => { item.setTitle("Close home base").setIcon("x").onClick(() => { void this.closeHomeBase(true); }); }); menu.addItem((item) => { item.setTitle("Change icon").setIcon("lucide-image-plus").onClick(() => { const picker = new IconPicker( this.plugin.app, this.plugin.settings.stickyIconName, (icon) => { void (async () => { this.plugin.settings.stickyIconName = icon; await this.plugin.saveSettings(); if (this.stickyIconEl) { (0, import_obsidian9.setIcon)(this.stickyIconEl, icon || "home"); } })(); } ); picker.open(); }); }); menu.showAtMouseEvent(e); }); const ensureIconInPlace = () => { if (!this.stickyIconEl) return; const mainWorkspace2 = document.querySelector(".workspace-split.mod-vertical.mod-root"); if (!mainWorkspace2) return; const tabHeaderContainerInner = mainWorkspace2.querySelector(".workspace-tab-header-container-inner"); if (!tabHeaderContainerInner) return; const allIcons = tabHeaderContainerInner.querySelectorAll(`.${STICKY_ICON_CLASS}`); allIcons.forEach((icon) => { if (icon !== this.stickyIconEl) { icon.remove(); } }); if (tabHeaderContainerInner.contains(this.stickyIconEl)) { return; } tabHeaderContainerInner.insertBefore(this.stickyIconEl, tabHeaderContainerInner.firstChild); this.updateActiveState(); this.updateTabHeaders(); this.updateWorkspaceClass(true); this.updateIconPositionForSidebar(); this.watchSidebarState(); }; ensureIconInPlace(); const checkInterval = setInterval(() => { if (!this.stickyIconEl || !this.plugin.settings.showStickyHomeIcon) { clearInterval(checkInterval); return; } ensureIconInPlace(); }, ICON_PLACEMENT_CHECK_INTERVAL); this.stickyIconEl._checkInterval = checkInterval; if (!this.layoutChangeHandler) { this.layoutChangeHandler = () => { if (this.stickyIconEl && this.plugin.settings.showStickyHomeIcon) { ensureIconInPlace(); this.updateTabHeaders(); } }; this.plugin.registerEvent( this.plugin.app.workspace.on("layout-change", this.layoutChangeHandler) ); } const mainWorkspace = document.querySelector(".workspace-split.mod-vertical.mod-root"); if (mainWorkspace) { const containerObserver = new MutationObserver(() => { if (!this.stickyIconEl || !this.plugin.settings.showStickyHomeIcon) return; const tabHeaderContainerInner = mainWorkspace.querySelector(".workspace-tab-header-container-inner"); if (tabHeaderContainerInner) { const allIcons = tabHeaderContainerInner.querySelectorAll(`.${STICKY_ICON_CLASS}`); allIcons.forEach((icon) => { if (icon !== this.stickyIconEl) { icon.remove(); } }); if (!tabHeaderContainerInner.contains(this.stickyIconEl)) { tabHeaderContainerInner.insertBefore(this.stickyIconEl, tabHeaderContainerInner.firstChild); this.updateActiveState(); } } }); containerObserver.observe(mainWorkspace, { childList: true, subtree: true // Watch subtree to catch tab container recreation }); this.stickyIconEl._containerObserver = containerObserver; } this.setupTabHeaderObserver(); } /** * Set up MutationObserver to watch for tab header changes and remove ghost tabs immediately * This prevents the flash when tabs are opened/closed */ setupTabHeaderObserver() { if (this.tabHeaderObserver) { return; } this.tabHeaderObserver = new MutationObserver((mutations) => { if (!this.plugin.settings.showStickyHomeIcon || !this.plugin.settings.hideHomeTabHeader) { return; } let hasNewHeaders = false; for (const mutation of mutations) { if (mutation.type === "childList" && mutation.addedNodes.length > 0) { for (const node of Array.from(mutation.addedNodes)) { if (node instanceof HTMLElement && node.classList.contains("workspace-tab-header")) { hasNewHeaders = true; break; } } } if (hasNewHeaders) break; } if (hasNewHeaders) { this.plugin.app.workspace.iterateAllLeaves((leaf) => { const view = leaf.view; let container = null; if (view) { const viewAny = view; container = viewAny.containerEl || null; } if (!container) { const leafAny = leaf; container = leafAny.containerEl || null; } if (container) { const rootWorkspace = container.closest(".workspace-split.mod-vertical.mod-root"); const leftSidebar = container.closest(".workspace-split.mod-left-split"); const rightSidebar = container.closest(".workspace-split.mod-right-split"); if (rootWorkspace && !leftSidebar && !rightSidebar) { if (this.plugin.homeService.isGhostLeaf(leaf)) { const tabHeader = this.getTabHeaderForLeaf(leaf); if (tabHeader && tabHeader.parentElement) { const parent = tabHeader.parentElement; if (parent && parent.classList.contains("workspace-tab-header-container-inner")) { const tabHeaderExtended = tabHeader; if (parent.contains(tabHeader)) { tabHeaderExtended._homeBaseParent = parent; tabHeaderExtended._homeBaseNextSibling = tabHeader.nextSibling; tabHeader.remove(); } } } } } } }); } }); const observeContainer = (container) => { var _a; (_a = this.tabHeaderObserver) == null ? void 0 : _a.observe(container, { childList: true, subtree: false }); }; const observeAllWindows = () => { const containers = document.querySelectorAll(".workspace-tab-header-container-inner"); containers.forEach(observeContainer); this.plugin.app.workspace.iterateAllLeaves((leaf) => { var _a, _b; const doc = (_b = (_a = leaf.view) == null ? void 0 : _a.containerEl) == null ? void 0 : _b.ownerDocument; if (doc && doc !== document) { const windowContainers = doc.querySelectorAll(".workspace-tab-header-container-inner"); windowContainers.forEach(observeContainer); } }); }; observeAllWindows(); const setupWorkspaceObserver = (win) => { const doc = win.document; const workspaceObserver = new MutationObserver(() => { const newContainers = doc.querySelectorAll(".workspace-tab-header-container-inner"); newContainers.forEach(observeContainer); }); const mainWorkspace = doc.querySelector(".workspace-split.mod-vertical.mod-root"); if (mainWorkspace) { workspaceObserver.observe(mainWorkspace, { childList: true, subtree: true }); } }; setupWorkspaceObserver(window); this.plugin.registerEvent( this.plugin.app.workspace.on("window-open", (win) => { const actualWindow = win.win; if (actualWindow instanceof Window) { setupWorkspaceObserver(actualWindow); setTimeout(observeAllWindows, WINDOW_OPEN_CONTAINER_DELAY); } }) ); } /** * Remove the sticky home icon */ remove() { if (this.tabHeaderUpdateTimeout) { clearTimeout(this.tabHeaderUpdateTimeout); this.tabHeaderUpdateTimeout = null; } if (this.stickyIconEl && this.stickyIconEl._checkInterval) { clearInterval(this.stickyIconEl._checkInterval); } if (this.stickyIconEl && this.stickyIconEl._containerObserver) { this.stickyIconEl._containerObserver.disconnect(); } if (this.sidebarObserver) { this.sidebarObserver.disconnect(); this.sidebarObserver = null; } if (this.tabHeaderObserver) { this.tabHeaderObserver.disconnect(); this.tabHeaderObserver = null; } this.updateWorkspaceClass(false); this.plugin.app.workspace.iterateAllLeaves((leaf) => { const view = leaf.view; let container = null; if (view) { const viewAny = view; container = viewAny.containerEl || null; } if (!container) { const leafAny = leaf; container = leafAny.containerEl || null; } if (container) { const rootWorkspace = container.closest(".workspace-split.mod-vertical.mod-root"); const leftSidebar = container.closest(".workspace-split.mod-left-split"); const rightSidebar = container.closest(".workspace-split.mod-right-split"); if (rootWorkspace && !leftSidebar && !rightSidebar) { const tabHeader = this.getTabHeaderForLeaf(leaf); if (tabHeader) { tabHeader.classList.remove("is-home-base-tab"); tabHeader.removeAttribute("data-home-base-ghost"); tabHeader.removeAttribute("aria-hidden"); const tabHeaderExtended = tabHeader; if (tabHeaderExtended._homeBaseParent && !tabHeaderExtended._homeBaseParent.contains(tabHeader)) { const parent = tabHeaderExtended._homeBaseParent; const nextSibling = tabHeaderExtended._homeBaseNextSibling; if (parent) { if (nextSibling && nextSibling.parentElement === parent) { parent.insertBefore(tabHeader, nextSibling); } else { parent.appendChild(tabHeader); } } delete tabHeaderExtended._homeBaseParent; delete tabHeaderExtended._homeBaseNextSibling; } } } } }); if (this.stickyIconEl) { if (this.stickyIconEl.parentElement) { this.stickyIconEl.remove(); } this.stickyIconEl = null; } const cleanupOrphans = (doc) => { doc.querySelectorAll(`.${STICKY_ICON_CLASS}`).forEach((el) => { const stickyEl = el; if (stickyEl._checkInterval) { clearInterval(stickyEl._checkInterval); } if (stickyEl._containerObserver) { stickyEl._containerObserver.disconnect(); } el.remove(); }); }; cleanupOrphans(document); this.plugin.app.workspace.iterateAllLeaves((leaf) => { var _a, _b; const doc = (_b = (_a = leaf.view) == null ? void 0 : _a.containerEl) == null ? void 0 : _b.ownerDocument; if (doc && doc !== document) { cleanupOrphans(doc); } }); } /** * Update the active state of the sticky icon */ updateActiveState() { if (!this.stickyIconEl) return; const isActive = this.plugin.homeService.isFocusedOnHomeBase(); if (isActive) { this.stickyIconEl.classList.add(STICKY_ICON_ACTIVE_CLASS); } else { this.stickyIconEl.classList.remove(STICKY_ICON_ACTIVE_CLASS); } this.updateTabHeaders(); } /** * Check if the left sidebar is collapsed * Based on obsidian-oxygen-settings implementation */ isLeftSidebarCollapsed() { const leftSidebar = document.querySelector(".workspace-split.mod-left-split") || document.querySelector(".mod-left-split"); if (!leftSidebar) return false; return leftSidebar.classList.contains("is-sidedock-collapsed"); } /** * Update icon position based on sidebar state * Note: With inline positioning, icon flows naturally with tabs, so no special positioning needed */ updateIconPositionForSidebar() { } /** * Update icon visibility based on tab bar visibility * REMOVED: JavaScript-based visibility checking was causing issues * Now relies entirely on CSS which is more reliable */ updateIconVisibility() { } /** * Watch for sidebar state changes and update icon position * Based on obsidian-oxygen-settings implementation */ watchSidebarState() { if (this.sidebarObserver) { this.sidebarObserver.disconnect(); } const leftSidebar = document.querySelector(".workspace-split.mod-left-split") || document.querySelector(".mod-left-split"); if (!leftSidebar) return; this.sidebarObserver = new MutationObserver((mutations) => { let shouldUpdate = false; mutations.forEach((mutation) => { if (mutation.type === "attributes" && mutation.attributeName === "class") { shouldUpdate = true; } }); if (shouldUpdate) { this.updateIconPositionForSidebar(); } }); this.sidebarObserver.observe(leftSidebar, { attributes: true, attributeFilter: ["class"] }); } /** * Watch for tab bar visibility changes (Oxygen theme auto-hide, focus mode, etc.) * REMOVED: No longer needed - CSS handles all visibility automatically */ watchTabBarVisibility() { } /** * Toggle the sticky icon visibility */ async toggle() { this.plugin.settings.showStickyHomeIcon = !this.plugin.settings.showStickyHomeIcon; await this.plugin.saveSettings(); this.update(); this.updateTabHeaders(); } /** * Update tab headers to hide/show ghost tab * Only works when sticky icon is enabled * Removed debounce - must be immediate to prevent flash */ updateTabHeaders() { if (this.tabHeaderUpdateTimeout) { clearTimeout(this.tabHeaderUpdateTimeout); this.tabHeaderUpdateTimeout = null; } this._doUpdateTabHeaders(); } /** * Internal method that actually updates the tab headers */ _doUpdateTabHeaders() { if (!this.plugin.settings.showStickyHomeIcon || !this.plugin.settings.hideHomeTabHeader) { this.plugin.app.workspace.iterateAllLeaves((leaf) => { const tabHeader = this.getTabHeaderForLeaf(leaf); if (tabHeader) { tabHeader.classList.remove("is-home-base-tab"); tabHeader.removeAttribute("data-home-base-ghost"); tabHeader.removeAttribute("aria-hidden"); const tabHeaderExtended = tabHeader; if (tabHeaderExtended._homeBaseParent && !tabHeaderExtended._homeBaseParent.contains(tabHeader)) { const parent = tabHeaderExtended._homeBaseParent; const nextSibling = tabHeaderExtended._homeBaseNextSibling; if (parent) { if (nextSibling && nextSibling.parentElement === parent) { parent.insertBefore(tabHeader, nextSibling); } else { parent.appendChild(tabHeader); } } delete tabHeaderExtended._homeBaseParent; delete tabHeaderExtended._homeBaseNextSibling; } } }); return; } const ghostTabHeadersToRemove = []; this.plugin.app.workspace.iterateAllLeaves((leaf) => { const view = leaf.view; let container = null; if (view) { const viewAny = view; container = viewAny.containerEl || null; } if (!container) { const leafAny = leaf; container = leafAny.containerEl || null; } if (container) { const rootWorkspace = container.closest(".workspace-split.mod-vertical.mod-root"); const leftSidebar = container.closest(".workspace-split.mod-left-split"); const rightSidebar = container.closest(".workspace-split.mod-right-split"); if (rootWorkspace && !leftSidebar && !rightSidebar) { if (this.plugin.homeService.isGhostLeaf(leaf)) { const tabHeader = this.getTabHeaderForLeaf(leaf); if (tabHeader && tabHeader.parentElement) { ghostTabHeadersToRemove.push({ tabHeader, leaf }); } } } } }); ghostTabHeadersToRemove.forEach(({ tabHeader }) => { const parent = tabHeader.parentElement; if (parent && parent.classList.contains("workspace-tab-header-container-inner")) { const tabHeaderExtended = tabHeader; if (parent.contains(tabHeader)) { tabHeaderExtended._homeBaseParent = parent; tabHeaderExtended._homeBaseNextSibling = tabHeader.nextSibling; tabHeader.remove(); } } }); requestAnimationFrame(() => { const homeBaseSettings = this.plugin.getHomeBaseSettings(); const homeBasePath = resolvePathSync(homeBaseSettings.type, homeBaseSettings.value, this.plugin.app); this.plugin.app.workspace.iterateAllLeaves((leaf) => { var _a; const view = leaf.view; let container = null; if (view) { const viewAny = view; container = viewAny.containerEl || null; } if (!container) { const leafAny = leaf; container = leafAny.containerEl || null; } if (container) { const rootWorkspace = container.closest(".workspace-split.mod-vertical.mod-root"); const leftSidebar = container.closest(".workspace-split.mod-left-split"); const rightSidebar = container.closest(".workspace-split.mod-right-split"); if (rootWorkspace && !leftSidebar && !rightSidebar) { const isGhostTab = this.plugin.homeService.isGhostLeaf(leaf); const tabHeader = this.getTabHeaderForLeaf(leaf); if (!tabHeader) return; const tabHeaderExtended = tabHeader; const isRemoved = tabHeaderExtended._homeBaseParent && !tabHeaderExtended._homeBaseParent.contains(tabHeader); if (!isGhostTab) { if (isRemoved) { const parent = tabHeaderExtended._homeBaseParent; const nextSibling = tabHeaderExtended._homeBaseNextSibling; if (parent) { if (nextSibling && nextSibling.parentElement === parent) { parent.insertBefore(tabHeader, nextSibling); } else { parent.appendChild(tabHeader); } delete tabHeaderExtended._homeBaseParent; delete tabHeaderExtended._homeBaseNextSibling; } } const isGraphHome = homeBaseSettings.type === "Graph view" /* Graph */ && ((_a = leaf.view) == null ? void 0 : _a.getViewType()) === "graph"; if (homeBasePath && leafHasFile(leaf, homeBasePath) || isGraphHome) { tabHeader.classList.add("is-home-base-tab"); } else { tabHeader.classList.remove("is-home-base-tab"); } tabHeader.removeAttribute("data-home-base-ghost"); tabHeader.removeAttribute("aria-hidden"); } } } }); }); } /** * Get the tab header element for a given leaf */ getTabHeaderForLeaf(leaf) { var _a, _b, _c; const leafAny = leaf; if (leafAny.tabHeaderEl) { return leafAny.tabHeaderEl; } const viewType = (_a = leaf.view) == null ? void 0 : _a.getViewType(); if (!viewType) return null; const doc = ((_c = (_b = leaf.view) == null ? void 0 : _b.containerEl) == null ? void 0 : _c.ownerDocument) || document; const activeLeaf = this.plugin.app.workspace.getMostRecentLeaf(); const isActive = leaf === activeLeaf; const tabHeaders = doc.querySelectorAll(`.workspace-tab-header[data-type="${viewType}"]`); if (isActive) { const activeHeader = doc.querySelector(".workspace-tab-header.is-active"); if (activeHeader && activeHeader.getAttribute("data-type") === viewType) { return activeHeader; } } for (const header of Array.from(tabHeaders)) { const headerEl = header; const headerElWithLeaf = headerEl; const headerLeaf = headerElWithLeaf.leaf; if (headerLeaf === leaf) { return headerEl; } } if (tabHeaders.length === 1) { return tabHeaders[0]; } if (isActive) { const activeHeader = doc.querySelector(".workspace-tab-header.is-active"); if (activeHeader) { return activeHeader; } } return null; } /** * Close the home base tab * When called from context menu: Only closes the ghost tab (the "occupied" slot) * Other home base tabs are left alone */ closeHomeBase(actuallyClose = false) { const homeBaseSettings = this.plugin.getHomeBaseSettings(); const homeBasePath = resolvePathSync(homeBaseSettings.type, homeBaseSettings.value, this.plugin.app); const ghostTabs = []; const allHomeBaseLeaves = []; this.plugin.app.workspace.iterateAllLeaves((leaf) => { const isGhost = this.plugin.homeService.isGhostLeaf(leaf); if (isGhost) { ghostTabs.push(leaf); } if (homeBasePath && leafHasFile(leaf, homeBasePath)) { allHomeBaseLeaves.push(leaf); } }); if (this.plugin.settings.showStickyHomeIcon) { for (const ghostTab of ghostTabs) { void ghostTab.detach(); } } else { for (const leaf of allHomeBaseLeaves) { void leaf.detach(); } } this.updateTabHeaders(); } /** * Pin the home base tab */ pinHomeBaseTab() { const homeBaseSettings = this.plugin.getHomeBaseSettings(); const homeBasePath = resolvePathSync(homeBaseSettings.type, homeBaseSettings.value, this.plugin.app); if (!homeBasePath) return; const homeBaseFile = getFileByPath(this.plugin.app, homeBasePath); if (!homeBaseFile) return; const homeBaseLeaf = this.plugin.homeService.findExistingHomeBaseLeaf(homeBaseFile); if (homeBaseLeaf) { homeBaseLeaf.setPinned(true); } } /** * Unpin the home base tab */ unpinHomeBaseTab() { const homeBaseSettings = this.plugin.getHomeBaseSettings(); const homeBasePath = resolvePathSync(homeBaseSettings.type, homeBaseSettings.value, this.plugin.app); if (!homeBasePath) return; const homeBaseFile = getFileByPath(this.plugin.app, homeBasePath); if (!homeBaseFile) return; const homeBaseLeaf = this.plugin.homeService.findExistingHomeBaseLeaf(homeBaseFile); if (homeBaseLeaf) { homeBaseLeaf.setPinned(false); } } /** * Check if the home base tab is pinned */ isHomeBaseTabPinned() { const homeBaseSettings = this.plugin.getHomeBaseSettings(); const homeBasePath = resolvePathSync(homeBaseSettings.type, homeBaseSettings.value, this.plugin.app); if (!homeBasePath) return false; const homeBaseFile = getFileByPath(this.plugin.app, homeBasePath); if (!homeBaseFile) return false; const homeBaseLeaf = this.plugin.homeService.findExistingHomeBaseLeaf(homeBaseFile); if (!homeBaseLeaf) return false; const viewState = homeBaseLeaf.getViewState(); return viewState.pinned === true; } }; // src/services/mobile-button-service.ts var import_obsidian10 = require("obsidian"); var MOBILE_HOME_CLASS = "home-base-mobile-enabled"; var MobileButtonService = class { constructor(plugin) { this.plugin = plugin; } /** * Update the mobile button based on settings */ update() { if (!import_obsidian10.Platform.isMobile) { this.remove(); return; } if (this.plugin.settings.replaceMobileNewTab) { this.apply(); } else { this.remove(); } } /** * Apply the mobile button replacement */ apply() { document.body.classList.add(MOBILE_HOME_CLASS); } /** * Remove the mobile button replacement */ remove() { document.body.classList.remove(MOBILE_HOME_CLASS); } }; // src/migration.ts async function migrateLegacySettings(plugin) { let needsSave = false; const settings = plugin.settings; if (settings.homeBasePath && !plugin.settings.homeBaseValue) { plugin.settings.homeBaseType = "File" /* File */; plugin.settings.homeBaseValue = settings.homeBasePath; needsSave = true; } if (settings.keepExistingTabs !== void 0) { if (plugin.settings.openMode === DEFAULT_SETTINGS.openMode) { plugin.settings.openMode = settings.keepExistingTabs ? "retain" : "replace-all"; needsSave = true; } delete settings.keepExistingTabs; needsSave = true; } if (settings.mobileHomeBasePath && !plugin.settings.mobileHomeBaseValue) { plugin.settings.mobileHomeBaseType = "File" /* File */; plugin.settings.mobileHomeBaseValue = settings.mobileHomeBasePath; needsSave = true; } if (settings.mobileHomeBasePath !== void 0) { delete settings.mobileHomeBasePath; needsSave = true; } if (settings.homeBasePath !== void 0) { delete settings.homeBasePath; needsSave = true; } if (needsSave) { await plugin.saveSettings(); } } // src/main.ts var HOME_ICON = ``; var DOM_READY_DELAY = 100; var TAB_HEADER_UPDATE_DELAY = 150; var FILE_OPEN_ANIMATION_DELAY = 100; var TAB_SWITCH_ANIMATION_DELAY = 100; var STARTUP_COMPLETE_DELAY = 1e3; var HomeBasePlugin = class extends import_obsidian11.Plugin { constructor() { super(...arguments); // Release notes tracking this.newRelease = false; // Track if patched opening behavior already ran this.openingBehaviorRan = false; // Track if we're currently in startup (to prevent handleOpenWhenEmpty from firing) this.isStartup = true; } async onload() { await this.loadSettings(); await migrateLegacySettings(this); this.patchOpeningBehavior(); (0, import_obsidian11.addIcon)("home-base", HOME_ICON); this.homeService = new HomeBaseService(this); this.newTabService = new NewTabService(this); this.stickyTabService = new StickyTabService(this); this.mobileButtonService = new MobileButtonService(this); this.addRibbonIcon("home", "Open home base", () => { void this.homeService.openHomeBase({ replaceActiveLeaf: false, runCommand: true }); }); this.registerCommands(); this.addSettingTab(new HomeBaseSettingTab(this.app, this)); this.app.workspace.onLayoutReady(() => { setTimeout(() => { if (this.isSettingsModalOpen()) { this.updateStickyTabIcon(); this.updateMobileButton(); this.stickyTabService.updateTabHeaders(); return; } if (!this.openingBehaviorRan) { this.newTabService.initialize(); } else { this.newTabService.trackExistingLeaves(); } this.homeService.restoreGhostLeaves(); setTimeout(() => { this.isStartup = false; }, STARTUP_COMPLETE_DELAY); this.updateStickyTabIcon(); this.updateMobileButton(); this.stickyTabService.updateTabHeaders(); }, DOM_READY_DELAY); }); this.registerEvent( this.app.workspace.on("layout-change", async () => { this.newTabService.handleLayoutChange(); if (this.settings.revertView) { await this.homeService.revertView(); } setTimeout(() => { this.stickyTabService.updateActiveState(); this.stickyTabService.updateTabHeaders(); this.stickyTabService.updateIconPositionForSidebar(); }, TAB_HEADER_UPDATE_DELAY); }) ); this.registerEvent( this.app.workspace.on("file-open", () => { setTimeout(() => { this.stickyTabService.updateActiveState(); this.stickyTabService.updateTabHeaders(); }, FILE_OPEN_ANIMATION_DELAY); }) ); this.registerEvent( this.app.workspace.on("active-leaf-change", () => { setTimeout(() => { this.stickyTabService.updateTabHeaders(); }, TAB_SWITCH_ANIMATION_DELAY); }) ); } onunload() { this.unpatchReleaseNotes(); this.unpatchOpeningBehavior(); this.stickyTabService.remove(); this.mobileButtonService.remove(); } /** * Register plugin commands */ registerCommands() { this.addCommand({ id: "open", name: "Open", callback: () => { const homeBaseSettings = this.getHomeBaseSettings(); if (!homeBaseSettings.value && homeBaseSettings.type === "File" /* File */) { new import_obsidian11.Notice("No home base configured. Set one in settings."); return; } void this.homeService.openHomeBase({ replaceActiveLeaf: false, runCommand: true }); } }); this.addCommand({ id: "set-current-file", name: "Set current file as home", checkCallback: (checking) => { if (!this.homeService.canSetActiveFileAsHomeBase()) { return false; } if (!checking) { void this.homeService.setActiveFileAsHomeBase().then((success) => { if (success) { const activeFile = this.app.workspace.getActiveFile(); new import_obsidian11.Notice(`Home base set to "${activeFile == null ? void 0 : activeFile.name}"`); } }); } return true; } }); this.addCommand({ id: "toggle-sticky-icon", name: "Toggle sticky home icon", callback: async () => { await this.stickyTabService.toggle(); const state = this.settings.showStickyHomeIcon ? "enabled" : "disabled"; new import_obsidian11.Notice(`Sticky home icon ${state}`); } }); this.addCommand({ id: "close", name: "Close", callback: () => { this.stickyTabService.closeHomeBase(); } }); } /** * Load plugin settings */ async loadSettings() { const data = await this.loadData(); this.settings = Object.assign({}, DEFAULT_SETTINGS, data != null ? data : {}); } /** * Get the active home base settings (mobile or desktop) */ getHomeBaseSettings() { if (this.settings.separateMobile && import_obsidian11.Platform.isMobile) { return { type: this.settings.mobileHomeBaseType || "File" /* File */, value: this.settings.mobileHomeBaseValue || "" }; } return { type: this.settings.homeBaseType || "File" /* File */, value: this.settings.homeBaseValue || "" }; } /** * Get the active new tab settings (mobile or desktop) * Falls back to home base settings if useDifferentFileForNewTab is disabled */ getNewTabSettings() { if (!this.settings.useDifferentFileForNewTab) { return this.getHomeBaseSettings(); } if (this.settings.newTabSeparateMobile && import_obsidian11.Platform.isMobile) { return { type: this.settings.mobileNewTabType || "File" /* File */, value: this.settings.mobileNewTabValue || "" }; } return { type: this.settings.newTabType || "File" /* File */, value: this.settings.newTabValue || "" }; } /** * Save plugin settings */ async saveSettings() { await this.saveData(this.settings); } /** * Update the sticky tab icon based on current settings */ updateStickyTabIcon() { this.stickyTabService.update(); this.stickyTabService.updateTabHeaders(); } /** * Update the mobile button based on current settings */ updateMobileButton() { this.mobileButtonService.update(); } /** * Check if we should skip startup logic (e.g., plugin reload, settings modal open) * This prevents destructive behavior when the plugin is reloaded or settings are open */ shouldSkipStartupLogic() { if (this.isSettingsModalOpen()) { return true; } const hasOpenFiles = this.app.workspace.getLeavesOfType("markdown").length > 0 || this.app.workspace.getLeavesOfType("canvas").length > 0 || this.app.workspace.getLeavesOfType("bases").length > 0 || this.app.workspace.getLeavesOfType("empty").length > 0; return hasOpenFiles; } /** * Check if the settings modal is currently open */ isSettingsModalOpen() { const settingsModal = document.querySelector(".modal-container.mod-settings") || document.querySelector(".modal.mod-settings") || document.querySelector(".vertical-tab-content"); if (!settingsModal) { const allModals = document.querySelectorAll(".modal-container"); for (const modal of Array.from(allModals)) { if (modal.querySelector(".vertical-tab-content") || modal.querySelector(".settings-content") || modal.classList.contains("mod-settings")) { return true; } } } return settingsModal !== null; } /** * Patch runOpeningBehavior for fast startup (like homepage plugin) */ patchOpeningBehavior() { try { this.app.nvOrig_runOpeningBehavior = this.app.runOpeningBehavior; this.app.runOpeningBehavior = async (path) => { const openInitially = this.settings.openOnStartup && !this.hasUrlParams(); if (openInitially) { this.openingBehaviorRan = true; const mode = this.settings.openMode; if (mode === "replace-all") { await this.homeService.detachAllLeaves(); } if (this.settings.showStickyHomeIcon) { void this.homeService.openHomeBaseInGhostTab({ runCommand: true }); } else { void this.homeService.openHomeBaseWithMode(mode, true); } } else { if (this.app.nvOrig_runOpeningBehavior) { await this.app.nvOrig_runOpeningBehavior(path); } } this.unpatchReleaseNotes(); }; } catch (e) { console.warn("[Home Base] Failed to patch opening behavior:", e); } } /** * Unpatch runOpeningBehavior */ unpatchOpeningBehavior() { if (this.app.nvOrig_runOpeningBehavior) { this.app.runOpeningBehavior = this.app.nvOrig_runOpeningBehavior; } } /** * Patch showReleaseNotes to track new releases */ patchReleaseNotes() { try { const appAny = this.app; appAny.nvOrig_showReleaseNotes = appAny.showReleaseNotes; appAny.showReleaseNotes = () => { this.newRelease = true; }; } catch (e) { console.warn("[Home Base] Failed to patch release notes:", e); } } /** * Unpatch showReleaseNotes */ unpatchReleaseNotes() { var _a; const appAny = this.app; if (this.newRelease && !this.settings.hideReleaseNotes) { (_a = appAny.nvOrig_showReleaseNotes) == null ? void 0 : _a.call(appAny); } if (appAny.nvOrig_showReleaseNotes) { appAny.showReleaseNotes = appAny.nvOrig_showReleaseNotes; } } /** * Check if a home base type has its required plugin enabled */ hasRequiredPlugin(type) { var _a, _b, _c, _d, _e, _f, _g, _h; switch (type) { case "Workspace" /* Workspace */: return ((_c = (_b = (_a = this.app.internalPlugins) == null ? void 0 : _a.plugins) == null ? void 0 : _b.workspaces) == null ? void 0 : _c.enabled) === true; case "Graph view" /* Graph */: return ((_f = (_e = (_d = this.app.internalPlugins) == null ? void 0 : _d.plugins) == null ? void 0 : _e.graph) == null ? void 0 : _f.enabled) === true; case "Journal" /* Journal */: return !!((_h = (_g = this.app.plugins) == null ? void 0 : _g.plugins) == null ? void 0 : _h["journals"]); case "Daily Note" /* DailyNote */: case "Weekly Note" /* WeeklyNote */: case "Monthly Note" /* MonthlyNote */: case "Quarterly Note" /* QuarterlyNote */: case "Yearly Note" /* YearlyNote */: return this.hasRequiredPeriodicity(type); default: return true; } } /** * Check if periodic notes are available for the given type */ hasRequiredPeriodicity(type) { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s; if (type === "Daily Note" /* DailyNote */) { const coreDailyNotes = ((_c = (_b = (_a = this.app.internalPlugins) == null ? void 0 : _a.plugins) == null ? void 0 : _b["daily-notes"]) == null ? void 0 : _c.enabled) === true; if (coreDailyNotes) { return true; } const periodicNotes2 = (_e = (_d = this.app.plugins) == null ? void 0 : _d.plugins) == null ? void 0 : _e["periodic-notes"]; if (periodicNotes2) { const version2 = ((_f = periodicNotes2 == null ? void 0 : periodicNotes2.manifest) == null ? void 0 : _f.version) || "0"; const isLegacy2 = version2.startsWith("0"); if (isLegacy2) { return ((_h = (_g = periodicNotes2 == null ? void 0 : periodicNotes2.settings) == null ? void 0 : _g["daily"]) == null ? void 0 : _h.enabled) === true; } else { const calendarSet = (_j = (_i = periodicNotes2 == null ? void 0 : periodicNotes2.calendarSetManager) == null ? void 0 : _i.getActiveSet) == null ? void 0 : _j.call(_i); return ((_k = calendarSet == null ? void 0 : calendarSet["day"]) == null ? void 0 : _k.enabled) === true; } } return false; } const periodicNotes = (_m = (_l = this.app.plugins) == null ? void 0 : _l.plugins) == null ? void 0 : _m["periodic-notes"]; if (!periodicNotes) return false; const version = ((_n = periodicNotes == null ? void 0 : periodicNotes.manifest) == null ? void 0 : _n.version) || "0"; const isLegacy = version.startsWith("0"); if (isLegacy) { const periodMap = { ["Weekly Note" /* WeeklyNote */]: "weekly", ["Monthly Note" /* MonthlyNote */]: "monthly", ["Quarterly Note" /* QuarterlyNote */]: "quarterly", ["Yearly Note" /* YearlyNote */]: "yearly" }; const adjective = periodMap[type]; if (!adjective) return false; return ((_p = (_o = periodicNotes == null ? void 0 : periodicNotes.settings) == null ? void 0 : _o[adjective]) == null ? void 0 : _p.enabled) === true; } else { const nounMap = { ["Weekly Note" /* WeeklyNote */]: "week", ["Monthly Note" /* MonthlyNote */]: "month", ["Quarterly Note" /* QuarterlyNote */]: "quarter", ["Yearly Note" /* YearlyNote */]: "year" }; const noun = nounMap[type]; if (!noun) return false; const calendarSet = (_r = (_q = periodicNotes == null ? void 0 : periodicNotes.calendarSetManager) == null ? void 0 : _q.getActiveSet) == null ? void 0 : _r.call(_q); return ((_s = calendarSet == null ? void 0 : calendarSet[noun]) == null ? void 0 : _s.enabled) === true; } } /** * Check if URL params indicate a file/workspace should be opened (skip homepage) */ hasUrlParams() { if (typeof window !== "undefined" && window.OBS_ACT) { const params = Object.keys(window.OBS_ACT); const action = window.OBS_ACT.action; return action !== void 0 && ["open", "advanced-uri"].includes(action) && ["file", "filepath", "workspace"].some((e) => params.includes(e)); } return false; } // "Open when empty" feature removed - redundant with "New tab replacement: only when empty" // Since Obsidian auto-creates an empty tab when you close the last one, they do the same thing }; //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibm9kZV9tb2R1bGVzLy5wbnBtL29ic2lkaWFuLWRhaWx5LW5vdGVzLWludGVyZl84ZDlmYzI0YjBmYzYyMmQ5NGZkMTFmYTVlOWIxODViMy9ub2RlX21vZHVsZXMvb2JzaWRpYW4tZGFpbHktbm90ZXMtaW50ZXJmYWNlL2Rpc3QvbWFpbi5qcyIsICJzcmMvbWFpbi50cyIsICJzcmMvc2V0dGluZ3MudHMiLCAic3JjL3VpL3NldHRpbmdzLXRhYi50cyIsICJzcmMvdWkvZmlsZS1zdWdnZXN0LnRzIiwgInNyYy91aS9jb21tYW5kLXN1Z2dlc3QudHMiLCAic3JjL3VpL2ljb24tcGlja2VyLnRzIiwgInNyYy9zZXJ2aWNlcy9ob21lLXNlcnZpY2UudHMiLCAic3JjL3V0aWxzL2ZpbGUtdXRpbHMudHMiLCAic3JjL3V0aWxzL2hvbWViYXNlLXJlc29sdmVyLnRzIiwgInNyYy9zZXJ2aWNlcy9uZXctdGFiLXNlcnZpY2UudHMiLCAic3JjL3NlcnZpY2VzL3N0aWNreS10YWItc2VydmljZS50cyIsICJzcmMvc2VydmljZXMvbW9iaWxlLWJ1dHRvbi1zZXJ2aWNlLnRzIiwgInNyYy9taWdyYXRpb24udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcblxudmFyIG9ic2lkaWFuID0gcmVxdWlyZSgnb2JzaWRpYW4nKTtcblxuY29uc3QgREVGQVVMVF9EQUlMWV9OT1RFX0ZPUk1BVCA9IFwiWVlZWS1NTS1ERFwiO1xuY29uc3QgREVGQVVMVF9XRUVLTFlfTk9URV9GT1JNQVQgPSBcImdnZ2ctW1ddd3dcIjtcbmNvbnN0IERFRkFVTFRfTU9OVEhMWV9OT1RFX0ZPUk1BVCA9IFwiWVlZWS1NTVwiO1xuY29uc3QgREVGQVVMVF9RVUFSVEVSTFlfTk9URV9GT1JNQVQgPSBcIllZWVktW1FdUVwiO1xuY29uc3QgREVGQVVMVF9ZRUFSTFlfTk9URV9GT1JNQVQgPSBcIllZWVlcIjtcblxuZnVuY3Rpb24gc2hvdWxkVXNlUGVyaW9kaWNOb3Rlc1NldHRpbmdzKHBlcmlvZGljaXR5KSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBwZXJpb2RpY05vdGVzID0gd2luZG93LmFwcC5wbHVnaW5zLmdldFBsdWdpbihcInBlcmlvZGljLW5vdGVzXCIpO1xuICAgIHJldHVybiBwZXJpb2RpY05vdGVzICYmIHBlcmlvZGljTm90ZXMuc2V0dGluZ3M/LltwZXJpb2RpY2l0eV0/LmVuYWJsZWQ7XG59XG4vKipcbiAqIFJlYWQgdGhlIHVzZXIgc2V0dGluZ3MgZm9yIHRoZSBgZGFpbHktbm90ZXNgIHBsdWdpblxuICogdG8ga2VlcCBiZWhhdmlvciBvZiBjcmVhdGluZyBhIG5ldyBub3RlIGluLXN5bmMuXG4gKi9cbmZ1bmN0aW9uIGdldERhaWx5Tm90ZVNldHRpbmdzKCkge1xuICAgIHRyeSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIGNvbnN0IHsgaW50ZXJuYWxQbHVnaW5zLCBwbHVnaW5zIH0gPSB3aW5kb3cuYXBwO1xuICAgICAgICBpZiAoc2hvdWxkVXNlUGVyaW9kaWNOb3Rlc1NldHRpbmdzKFwiZGFpbHlcIikpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgZm9ybWF0LCBmb2xkZXIsIHRlbXBsYXRlIH0gPSBwbHVnaW5zLmdldFBsdWdpbihcInBlcmlvZGljLW5vdGVzXCIpPy5zZXR0aW5ncz8uZGFpbHkgfHwge307XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0IHx8IERFRkFVTFRfREFJTFlfTk9URV9GT1JNQVQsXG4gICAgICAgICAgICAgICAgZm9sZGVyOiBmb2xkZXI/LnRyaW0oKSB8fCBcIlwiLFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlOiB0ZW1wbGF0ZT8udHJpbSgpIHx8IFwiXCIsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgZm9sZGVyLCBmb3JtYXQsIHRlbXBsYXRlIH0gPSBpbnRlcm5hbFBsdWdpbnMuZ2V0UGx1Z2luQnlJZChcImRhaWx5LW5vdGVzXCIpPy5pbnN0YW5jZT8ub3B0aW9ucyB8fCB7fTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0IHx8IERFRkFVTFRfREFJTFlfTk9URV9GT1JNQVQsXG4gICAgICAgICAgICBmb2xkZXI6IGZvbGRlcj8udHJpbSgpIHx8IFwiXCIsXG4gICAgICAgICAgICB0ZW1wbGF0ZTogdGVtcGxhdGU/LnRyaW0oKSB8fCBcIlwiLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIk5vIGN1c3RvbSBkYWlseSBub3RlIHNldHRpbmdzIGZvdW5kIVwiLCBlcnIpO1xuICAgIH1cbn1cbi8qKlxuICogUmVhZCB0aGUgdXNlciBzZXR0aW5ncyBmb3IgdGhlIGB3ZWVrbHktbm90ZXNgIHBsdWdpblxuICogdG8ga2VlcCBiZWhhdmlvciBvZiBjcmVhdGluZyBhIG5ldyBub3RlIGluLXN5bmMuXG4gKi9cbmZ1bmN0aW9uIGdldFdlZWtseU5vdGVTZXR0aW5ncygpIHtcbiAgICB0cnkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICBjb25zdCBwbHVnaW5NYW5hZ2VyID0gd2luZG93LmFwcC5wbHVnaW5zO1xuICAgICAgICBjb25zdCBjYWxlbmRhclNldHRpbmdzID0gcGx1Z2luTWFuYWdlci5nZXRQbHVnaW4oXCJjYWxlbmRhclwiKT8ub3B0aW9ucztcbiAgICAgICAgY29uc3QgcGVyaW9kaWNOb3Rlc1NldHRpbmdzID0gcGx1Z2luTWFuYWdlci5nZXRQbHVnaW4oXCJwZXJpb2RpYy1ub3Rlc1wiKT8uc2V0dGluZ3M/LndlZWtseTtcbiAgICAgICAgaWYgKHNob3VsZFVzZVBlcmlvZGljTm90ZXNTZXR0aW5ncyhcIndlZWtseVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IHBlcmlvZGljTm90ZXNTZXR0aW5ncy5mb3JtYXQgfHwgREVGQVVMVF9XRUVLTFlfTk9URV9GT1JNQVQsXG4gICAgICAgICAgICAgICAgZm9sZGVyOiBwZXJpb2RpY05vdGVzU2V0dGluZ3MuZm9sZGVyPy50cmltKCkgfHwgXCJcIixcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZTogcGVyaW9kaWNOb3Rlc1NldHRpbmdzLnRlbXBsYXRlPy50cmltKCkgfHwgXCJcIixcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSBjYWxlbmRhclNldHRpbmdzIHx8IHt9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZm9ybWF0OiBzZXR0aW5ncy53ZWVrbHlOb3RlRm9ybWF0IHx8IERFRkFVTFRfV0VFS0xZX05PVEVfRk9STUFULFxuICAgICAgICAgICAgZm9sZGVyOiBzZXR0aW5ncy53ZWVrbHlOb3RlRm9sZGVyPy50cmltKCkgfHwgXCJcIixcbiAgICAgICAgICAgIHRlbXBsYXRlOiBzZXR0aW5ncy53ZWVrbHlOb3RlVGVtcGxhdGU/LnRyaW0oKSB8fCBcIlwiLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIk5vIGN1c3RvbSB3ZWVrbHkgbm90ZSBzZXR0aW5ncyBmb3VuZCFcIiwgZXJyKTtcbiAgICB9XG59XG4vKipcbiAqIFJlYWQgdGhlIHVzZXIgc2V0dGluZ3MgZm9yIHRoZSBgcGVyaW9kaWMtbm90ZXNgIHBsdWdpblxuICogdG8ga2VlcCBiZWhhdmlvciBvZiBjcmVhdGluZyBhIG5ldyBub3RlIGluLXN5bmMuXG4gKi9cbmZ1bmN0aW9uIGdldE1vbnRobHlOb3RlU2V0dGluZ3MoKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBwbHVnaW5NYW5hZ2VyID0gd2luZG93LmFwcC5wbHVnaW5zO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gKHNob3VsZFVzZVBlcmlvZGljTm90ZXNTZXR0aW5ncyhcIm1vbnRobHlcIikgJiZcbiAgICAgICAgICAgIHBsdWdpbk1hbmFnZXIuZ2V0UGx1Z2luKFwicGVyaW9kaWMtbm90ZXNcIik/LnNldHRpbmdzPy5tb250aGx5KSB8fFxuICAgICAgICAgICAge307XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBmb3JtYXQ6IHNldHRpbmdzLmZvcm1hdCB8fCBERUZBVUxUX01PTlRITFlfTk9URV9GT1JNQVQsXG4gICAgICAgICAgICBmb2xkZXI6IHNldHRpbmdzLmZvbGRlcj8udHJpbSgpIHx8IFwiXCIsXG4gICAgICAgICAgICB0ZW1wbGF0ZTogc2V0dGluZ3MudGVtcGxhdGU/LnRyaW0oKSB8fCBcIlwiLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIk5vIGN1c3RvbSBtb250aGx5IG5vdGUgc2V0dGluZ3MgZm91bmQhXCIsIGVycik7XG4gICAgfVxufVxuLyoqXG4gKiBSZWFkIHRoZSB1c2VyIHNldHRpbmdzIGZvciB0aGUgYHBlcmlvZGljLW5vdGVzYCBwbHVnaW5cbiAqIHRvIGtlZXAgYmVoYXZpb3Igb2YgY3JlYXRpbmcgYSBuZXcgbm90ZSBpbi1zeW5jLlxuICovXG5mdW5jdGlvbiBnZXRRdWFydGVybHlOb3RlU2V0dGluZ3MoKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBwbHVnaW5NYW5hZ2VyID0gd2luZG93LmFwcC5wbHVnaW5zO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gKHNob3VsZFVzZVBlcmlvZGljTm90ZXNTZXR0aW5ncyhcInF1YXJ0ZXJseVwiKSAmJlxuICAgICAgICAgICAgcGx1Z2luTWFuYWdlci5nZXRQbHVnaW4oXCJwZXJpb2RpYy1ub3Rlc1wiKT8uc2V0dGluZ3M/LnF1YXJ0ZXJseSkgfHxcbiAgICAgICAgICAgIHt9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZm9ybWF0OiBzZXR0aW5ncy5mb3JtYXQgfHwgREVGQVVMVF9RVUFSVEVSTFlfTk9URV9GT1JNQVQsXG4gICAgICAgICAgICBmb2xkZXI6IHNldHRpbmdzLmZvbGRlcj8udHJpbSgpIHx8IFwiXCIsXG4gICAgICAgICAgICB0ZW1wbGF0ZTogc2V0dGluZ3MudGVtcGxhdGU/LnRyaW0oKSB8fCBcIlwiLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIk5vIGN1c3RvbSBxdWFydGVybHkgbm90ZSBzZXR0aW5ncyBmb3VuZCFcIiwgZXJyKTtcbiAgICB9XG59XG4vKipcbiAqIFJlYWQgdGhlIHVzZXIgc2V0dGluZ3MgZm9yIHRoZSBgcGVyaW9kaWMtbm90ZXNgIHBsdWdpblxuICogdG8ga2VlcCBiZWhhdmlvciBvZiBjcmVhdGluZyBhIG5ldyBub3RlIGluLXN5bmMuXG4gKi9cbmZ1bmN0aW9uIGdldFllYXJseU5vdGVTZXR0aW5ncygpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IHBsdWdpbk1hbmFnZXIgPSB3aW5kb3cuYXBwLnBsdWdpbnM7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSAoc2hvdWxkVXNlUGVyaW9kaWNOb3Rlc1NldHRpbmdzKFwieWVhcmx5XCIpICYmXG4gICAgICAgICAgICBwbHVnaW5NYW5hZ2VyLmdldFBsdWdpbihcInBlcmlvZGljLW5vdGVzXCIpPy5zZXR0aW5ncz8ueWVhcmx5KSB8fFxuICAgICAgICAgICAge307XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBmb3JtYXQ6IHNldHRpbmdzLmZvcm1hdCB8fCBERUZBVUxUX1lFQVJMWV9OT1RFX0ZPUk1BVCxcbiAgICAgICAgICAgIGZvbGRlcjogc2V0dGluZ3MuZm9sZGVyPy50cmltKCkgfHwgXCJcIixcbiAgICAgICAgICAgIHRlbXBsYXRlOiBzZXR0aW5ncy50ZW1wbGF0ZT8udHJpbSgpIHx8IFwiXCIsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiTm8gY3VzdG9tIHllYXJseSBub3RlIHNldHRpbmdzIGZvdW5kIVwiLCBlcnIpO1xuICAgIH1cbn1cblxuLy8gQ3JlZGl0OiBAY3JlYXRpb25peC9wYXRoLmpzXG5mdW5jdGlvbiBqb2luKC4uLnBhcnRTZWdtZW50cykge1xuICAgIC8vIFNwbGl0IHRoZSBpbnB1dHMgaW50byBhIGxpc3Qgb2YgcGF0aCBjb21tYW5kcy5cbiAgICBsZXQgcGFydHMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMCwgbCA9IHBhcnRTZWdtZW50cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgcGFydHMgPSBwYXJ0cy5jb25jYXQocGFydFNlZ21lbnRzW2ldLnNwbGl0KFwiL1wiKSk7XG4gICAgfVxuICAgIC8vIEludGVycHJldCB0aGUgcGF0aCBjb21tYW5kcyB0byBnZXQgdGhlIG5ldyByZXNvbHZlZCBwYXRoLlxuICAgIGNvbnN0IG5ld1BhcnRzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDAsIGwgPSBwYXJ0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgY29uc3QgcGFydCA9IHBhcnRzW2ldO1xuICAgICAgICAvLyBSZW1vdmUgbGVhZGluZyBhbmQgdHJhaWxpbmcgc2xhc2hlc1xuICAgICAgICAvLyBBbHNvIHJlbW92ZSBcIi5cIiBzZWdtZW50c1xuICAgICAgICBpZiAoIXBhcnQgfHwgcGFydCA9PT0gXCIuXCIpXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgLy8gUHVzaCBuZXcgcGF0aCBzZWdtZW50cy5cbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgbmV3UGFydHMucHVzaChwYXJ0KTtcbiAgICB9XG4gICAgLy8gUHJlc2VydmUgdGhlIGluaXRpYWwgc2xhc2ggaWYgdGhlcmUgd2FzIG9uZS5cbiAgICBpZiAocGFydHNbMF0gPT09IFwiXCIpXG4gICAgICAgIG5ld1BhcnRzLnVuc2hpZnQoXCJcIik7XG4gICAgLy8gVHVybiBiYWNrIGludG8gYSBzaW5nbGUgc3RyaW5nIHBhdGguXG4gICAgcmV0dXJuIG5ld1BhcnRzLmpvaW4oXCIvXCIpO1xufVxuZnVuY3Rpb24gYmFzZW5hbWUoZnVsbFBhdGgpIHtcbiAgICBsZXQgYmFzZSA9IGZ1bGxQYXRoLnN1YnN0cmluZyhmdWxsUGF0aC5sYXN0SW5kZXhPZihcIi9cIikgKyAxKTtcbiAgICBpZiAoYmFzZS5sYXN0SW5kZXhPZihcIi5cIikgIT0gLTEpXG4gICAgICAgIGJhc2UgPSBiYXNlLnN1YnN0cmluZygwLCBiYXNlLmxhc3RJbmRleE9mKFwiLlwiKSk7XG4gICAgcmV0dXJuIGJhc2U7XG59XG5hc3luYyBmdW5jdGlvbiBlbnN1cmVGb2xkZXJFeGlzdHMocGF0aCkge1xuICAgIGNvbnN0IGRpcnMgPSBwYXRoLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpLnNwbGl0KFwiL1wiKTtcbiAgICBkaXJzLnBvcCgpOyAvLyByZW1vdmUgYmFzZW5hbWVcbiAgICBpZiAoZGlycy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgZGlyID0gam9pbiguLi5kaXJzKTtcbiAgICAgICAgaWYgKCF3aW5kb3cuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChkaXIpKSB7XG4gICAgICAgICAgICBhd2FpdCB3aW5kb3cuYXBwLnZhdWx0LmNyZWF0ZUZvbGRlcihkaXIpO1xuICAgICAgICB9XG4gICAgfVxufVxuYXN5bmMgZnVuY3Rpb24gZ2V0Tm90ZVBhdGgoZGlyZWN0b3J5LCBmaWxlbmFtZSkge1xuICAgIGlmICghZmlsZW5hbWUuZW5kc1dpdGgoXCIubWRcIikpIHtcbiAgICAgICAgZmlsZW5hbWUgKz0gXCIubWRcIjtcbiAgICB9XG4gICAgY29uc3QgcGF0aCA9IG9ic2lkaWFuLm5vcm1hbGl6ZVBhdGgoam9pbihkaXJlY3RvcnksIGZpbGVuYW1lKSk7XG4gICAgYXdhaXQgZW5zdXJlRm9sZGVyRXhpc3RzKHBhdGgpO1xuICAgIHJldHVybiBwYXRoO1xufVxuYXN5bmMgZnVuY3Rpb24gZ2V0VGVtcGxhdGVJbmZvKHRlbXBsYXRlKSB7XG4gICAgY29uc3QgeyBtZXRhZGF0YUNhY2hlLCB2YXVsdCB9ID0gd2luZG93LmFwcDtcbiAgICBjb25zdCB0ZW1wbGF0ZVBhdGggPSBvYnNpZGlhbi5ub3JtYWxpemVQYXRoKHRlbXBsYXRlKTtcbiAgICBpZiAodGVtcGxhdGVQYXRoID09PSBcIi9cIikge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtcIlwiLCBudWxsXSk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlRmlsZSA9IG1ldGFkYXRhQ2FjaGUuZ2V0Rmlyc3RMaW5rcGF0aERlc3QodGVtcGxhdGVQYXRoLCBcIlwiKTtcbiAgICAgICAgY29uc3QgY29udGVudHMgPSBhd2FpdCB2YXVsdC5jYWNoZWRSZWFkKHRlbXBsYXRlRmlsZSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIGNvbnN0IElGb2xkSW5mbyA9IHdpbmRvdy5hcHAuZm9sZE1hbmFnZXIubG9hZCh0ZW1wbGF0ZUZpbGUpO1xuICAgICAgICByZXR1cm4gW2NvbnRlbnRzLCBJRm9sZEluZm9dO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byByZWFkIHRoZSBkYWlseSBub3RlIHRlbXBsYXRlICcke3RlbXBsYXRlUGF0aH0nYCwgZXJyKTtcbiAgICAgICAgbmV3IG9ic2lkaWFuLk5vdGljZShcIkZhaWxlZCB0byByZWFkIHRoZSBkYWlseSBub3RlIHRlbXBsYXRlXCIpO1xuICAgICAgICByZXR1cm4gW1wiXCIsIG51bGxdO1xuICAgIH1cbn1cblxuLyoqXG4gKiBkYXRlVUlEIGlzIGEgd2F5IG9mIHdlZWtseSBpZGVudGlmeWluZyBkYWlseS93ZWVrbHkvbW9udGhseSBub3Rlcy5cbiAqIFRoZXkgYXJlIHByZWZpeGVkIHdpdGggdGhlIGdyYW51bGFyaXR5IHRvIGF2b2lkIGFtYmlndWl0eS5cbiAqL1xuZnVuY3Rpb24gZ2V0RGF0ZVVJRChkYXRlLCBncmFudWxhcml0eSA9IFwiZGF5XCIpIHtcbiAgICBjb25zdCB0cyA9IGRhdGUuY2xvbmUoKS5zdGFydE9mKGdyYW51bGFyaXR5KS5mb3JtYXQoKTtcbiAgICByZXR1cm4gYCR7Z3JhbnVsYXJpdHl9LSR7dHN9YDtcbn1cbmZ1bmN0aW9uIHJlbW92ZUVzY2FwZWRDaGFyYWN0ZXJzKGZvcm1hdCkge1xuICAgIHJldHVybiBmb3JtYXQucmVwbGFjZSgvXFxbW15cXF1dKlxcXS9nLCBcIlwiKTsgLy8gcmVtb3ZlIGV2ZXJ5dGhpbmcgd2l0aGluIGJyYWNrZXRzXG59XG4vKipcbiAqIFhYWDogV2hlbiBwYXJzaW5nIGRhdGVzIHRoYXQgY29udGFpbiBib3RoIHdlZWsgbnVtYmVycyBhbmQgbW9udGhzLFxuICogTW9tZW50IGNob3NlcyB0byBpZ25vcmUgdGhlIHdlZWsgbnVtYmVycy4gRm9yIHRoZSB3ZWVrIGRhdGVVSUQsIHdlXG4gKiB3YW50IHRoZSBvcHBvc2l0ZSBiZWhhdmlvci4gU3RyaXAgdGhlIE1NTSBmcm9tIHRoZSBmb3JtYXQgdG8gcGF0Y2guXG4gKi9cbmZ1bmN0aW9uIGlzRm9ybWF0QW1iaWd1b3VzKGZvcm1hdCwgZ3JhbnVsYXJpdHkpIHtcbiAgICBpZiAoZ3JhbnVsYXJpdHkgPT09IFwid2Vla1wiKSB7XG4gICAgICAgIGNvbnN0IGNsZWFuRm9ybWF0ID0gcmVtb3ZlRXNjYXBlZENoYXJhY3RlcnMoZm9ybWF0KTtcbiAgICAgICAgcmV0dXJuICgvd3sxLDJ9L2kudGVzdChjbGVhbkZvcm1hdCkgJiZcbiAgICAgICAgICAgICgvTXsxLDR9Ly50ZXN0KGNsZWFuRm9ybWF0KSB8fCAvRHsxLDR9Ly50ZXN0KGNsZWFuRm9ybWF0KSkpO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBnZXREYXRlRnJvbUZpbGUoZmlsZSwgZ3JhbnVsYXJpdHkpIHtcbiAgICByZXR1cm4gZ2V0RGF0ZUZyb21GaWxlbmFtZShmaWxlLmJhc2VuYW1lLCBncmFudWxhcml0eSk7XG59XG5mdW5jdGlvbiBnZXREYXRlRnJvbVBhdGgocGF0aCwgZ3JhbnVsYXJpdHkpIHtcbiAgICByZXR1cm4gZ2V0RGF0ZUZyb21GaWxlbmFtZShiYXNlbmFtZShwYXRoKSwgZ3JhbnVsYXJpdHkpO1xufVxuZnVuY3Rpb24gZ2V0RGF0ZUZyb21GaWxlbmFtZShmaWxlbmFtZSwgZ3JhbnVsYXJpdHkpIHtcbiAgICBjb25zdCBnZXRTZXR0aW5ncyA9IHtcbiAgICAgICAgZGF5OiBnZXREYWlseU5vdGVTZXR0aW5ncyxcbiAgICAgICAgd2VlazogZ2V0V2Vla2x5Tm90ZVNldHRpbmdzLFxuICAgICAgICBtb250aDogZ2V0TW9udGhseU5vdGVTZXR0aW5ncyxcbiAgICAgICAgcXVhcnRlcjogZ2V0UXVhcnRlcmx5Tm90ZVNldHRpbmdzLFxuICAgICAgICB5ZWFyOiBnZXRZZWFybHlOb3RlU2V0dGluZ3MsXG4gICAgfTtcbiAgICBjb25zdCBmb3JtYXQgPSBnZXRTZXR0aW5nc1tncmFudWxhcml0eV0oKS5mb3JtYXQuc3BsaXQoXCIvXCIpLnBvcCgpO1xuICAgIGNvbnN0IG5vdGVEYXRlID0gd2luZG93Lm1vbWVudChmaWxlbmFtZSwgZm9ybWF0LCB0cnVlKTtcbiAgICBpZiAoIW5vdGVEYXRlLmlzVmFsaWQoKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKGlzRm9ybWF0QW1iaWd1b3VzKGZvcm1hdCwgZ3JhbnVsYXJpdHkpKSB7XG4gICAgICAgIGlmIChncmFudWxhcml0eSA9PT0gXCJ3ZWVrXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGNsZWFuRm9ybWF0ID0gcmVtb3ZlRXNjYXBlZENoYXJhY3RlcnMoZm9ybWF0KTtcbiAgICAgICAgICAgIGlmICgvd3sxLDJ9L2kudGVzdChjbGVhbkZvcm1hdCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gd2luZG93Lm1vbWVudChmaWxlbmFtZSwgXG4gICAgICAgICAgICAgICAgLy8gSWYgZm9ybWF0IGNvbnRhaW5zIHdlZWssIHJlbW92ZSBkYXkgJiBtb250aCBmb3JtYXR0aW5nXG4gICAgICAgICAgICAgICAgZm9ybWF0LnJlcGxhY2UoL017MSw0fS9nLCBcIlwiKS5yZXBsYWNlKC9EezEsNH0vZywgXCJcIiksIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbm90ZURhdGU7XG59XG5cbmNsYXNzIERhaWx5Tm90ZXNGb2xkZXJNaXNzaW5nRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG59XG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gbWltaWNzIHRoZSBiZWhhdmlvciBvZiB0aGUgZGFpbHktbm90ZXMgcGx1Z2luXG4gKiBzbyBpdCB3aWxsIHJlcGxhY2Uge3tkYXRlfX0sIHt7dGl0bGV9fSwgYW5kIHt7dGltZX19IHdpdGggdGhlXG4gKiBmb3JtYXR0ZWQgdGltZXN0YW1wLlxuICpcbiAqIE5vdGU6IGl0IGhhcyBhbiBhZGRlZCBib251cyB0aGF0IGl0J3Mgbm90ICd0b2RheScgc3BlY2lmaWMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZURhaWx5Tm90ZShkYXRlKSB7XG4gICAgY29uc3QgYXBwID0gd2luZG93LmFwcDtcbiAgICBjb25zdCB7IHZhdWx0IH0gPSBhcHA7XG4gICAgY29uc3QgbW9tZW50ID0gd2luZG93Lm1vbWVudDtcbiAgICBjb25zdCB7IHRlbXBsYXRlLCBmb3JtYXQsIGZvbGRlciB9ID0gZ2V0RGFpbHlOb3RlU2V0dGluZ3MoKTtcbiAgICBjb25zdCBbdGVtcGxhdGVDb250ZW50cywgSUZvbGRJbmZvXSA9IGF3YWl0IGdldFRlbXBsYXRlSW5mbyh0ZW1wbGF0ZSk7XG4gICAgY29uc3QgZmlsZW5hbWUgPSBkYXRlLmZvcm1hdChmb3JtYXQpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gYXdhaXQgZ2V0Tm90ZVBhdGgoZm9sZGVyLCBmaWxlbmFtZSk7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY3JlYXRlZEZpbGUgPSBhd2FpdCB2YXVsdC5jcmVhdGUobm9ybWFsaXplZFBhdGgsIHRlbXBsYXRlQ29udGVudHNcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccypkYXRlXFxzKn19L2dpLCBmaWxlbmFtZSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyp0aW1lXFxzKn19L2dpLCBtb21lbnQoKS5mb3JtYXQoXCJISDptbVwiKSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyp0aXRsZVxccyp9fS9naSwgZmlsZW5hbWUpXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqKGRhdGV8dGltZSlcXHMqKChbKy1dXFxkKykoW3lxbXdkaHNdKSk/XFxzKig6Lis/KT99fS9naSwgKF8sIF90aW1lT3JEYXRlLCBjYWxjLCB0aW1lRGVsdGEsIHVuaXQsIG1vbWVudEZvcm1hdCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gbW9tZW50KCk7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RGF0ZSA9IGRhdGUuY2xvbmUoKS5zZXQoe1xuICAgICAgICAgICAgICAgIGhvdXI6IG5vdy5nZXQoXCJob3VyXCIpLFxuICAgICAgICAgICAgICAgIG1pbnV0ZTogbm93LmdldChcIm1pbnV0ZVwiKSxcbiAgICAgICAgICAgICAgICBzZWNvbmQ6IG5vdy5nZXQoXCJzZWNvbmRcIiksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChjYWxjKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudERhdGUuYWRkKHBhcnNlSW50KHRpbWVEZWx0YSwgMTApLCB1bml0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtb21lbnRGb3JtYXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudERhdGUuZm9ybWF0KG1vbWVudEZvcm1hdC5zdWJzdHJpbmcoMSkudHJpbSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50RGF0ZS5mb3JtYXQoZm9ybWF0KTtcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyp5ZXN0ZXJkYXlcXHMqfX0vZ2ksIGRhdGUuY2xvbmUoKS5zdWJ0cmFjdCgxLCBcImRheVwiKS5mb3JtYXQoZm9ybWF0KSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyp0b21vcnJvd1xccyp9fS9naSwgZGF0ZS5jbG9uZSgpLmFkZCgxLCBcImRcIikuZm9ybWF0KGZvcm1hdCkpKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgYXBwLmZvbGRNYW5hZ2VyLnNhdmUoY3JlYXRlZEZpbGUsIElGb2xkSW5mbyk7XG4gICAgICAgIHJldHVybiBjcmVhdGVkRmlsZTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIGZpbGU6ICcke25vcm1hbGl6ZWRQYXRofSdgLCBlcnIpO1xuICAgICAgICBuZXcgb2JzaWRpYW4uTm90aWNlKFwiVW5hYmxlIHRvIGNyZWF0ZSBuZXcgZmlsZS5cIik7XG4gICAgfVxufVxuZnVuY3Rpb24gZ2V0RGFpbHlOb3RlKGRhdGUsIGRhaWx5Tm90ZXMpIHtcbiAgICByZXR1cm4gZGFpbHlOb3Rlc1tnZXREYXRlVUlEKGRhdGUsIFwiZGF5XCIpXSA/PyBudWxsO1xufVxuZnVuY3Rpb24gZ2V0QWxsRGFpbHlOb3RlcygpIHtcbiAgICAvKipcbiAgICAgKiBGaW5kIGFsbCBkYWlseSBub3RlcyBpbiB0aGUgZGFpbHkgbm90ZSBmb2xkZXJcbiAgICAgKi9cbiAgICBjb25zdCB7IHZhdWx0IH0gPSB3aW5kb3cuYXBwO1xuICAgIGNvbnN0IHsgZm9sZGVyIH0gPSBnZXREYWlseU5vdGVTZXR0aW5ncygpO1xuICAgIGNvbnN0IGRhaWx5Tm90ZXNGb2xkZXIgPSB2YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgob2JzaWRpYW4ubm9ybWFsaXplUGF0aChmb2xkZXIpKTtcbiAgICBpZiAoIWRhaWx5Tm90ZXNGb2xkZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IERhaWx5Tm90ZXNGb2xkZXJNaXNzaW5nRXJyb3IoXCJGYWlsZWQgdG8gZmluZCBkYWlseSBub3RlcyBmb2xkZXJcIik7XG4gICAgfVxuICAgIGNvbnN0IGRhaWx5Tm90ZXMgPSB7fTtcbiAgICBvYnNpZGlhbi5WYXVsdC5yZWN1cnNlQ2hpbGRyZW4oZGFpbHlOb3Rlc0ZvbGRlciwgKG5vdGUpID0+IHtcbiAgICAgICAgaWYgKG5vdGUgaW5zdGFuY2VvZiBvYnNpZGlhbi5URmlsZSkge1xuICAgICAgICAgICAgY29uc3QgZGF0ZSA9IGdldERhdGVGcm9tRmlsZShub3RlLCBcImRheVwiKTtcbiAgICAgICAgICAgIGlmIChkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZVN0cmluZyA9IGdldERhdGVVSUQoZGF0ZSwgXCJkYXlcIik7XG4gICAgICAgICAgICAgICAgZGFpbHlOb3Rlc1tkYXRlU3RyaW5nXSA9IG5vdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gZGFpbHlOb3Rlcztcbn1cblxuY2xhc3MgV2Vla2x5Tm90ZXNGb2xkZXJNaXNzaW5nRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG59XG5mdW5jdGlvbiBnZXREYXlzT2ZXZWVrKCkge1xuICAgIGNvbnN0IHsgbW9tZW50IH0gPSB3aW5kb3c7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBsZXQgd2Vla1N0YXJ0ID0gbW9tZW50LmxvY2FsZURhdGEoKS5fd2Vlay5kb3c7XG4gICAgY29uc3QgZGF5c09mV2VlayA9IFtcbiAgICAgICAgXCJzdW5kYXlcIixcbiAgICAgICAgXCJtb25kYXlcIixcbiAgICAgICAgXCJ0dWVzZGF5XCIsXG4gICAgICAgIFwid2VkbmVzZGF5XCIsXG4gICAgICAgIFwidGh1cnNkYXlcIixcbiAgICAgICAgXCJmcmlkYXlcIixcbiAgICAgICAgXCJzYXR1cmRheVwiLFxuICAgIF07XG4gICAgd2hpbGUgKHdlZWtTdGFydCkge1xuICAgICAgICBkYXlzT2ZXZWVrLnB1c2goZGF5c09mV2Vlay5zaGlmdCgpKTtcbiAgICAgICAgd2Vla1N0YXJ0LS07XG4gICAgfVxuICAgIHJldHVybiBkYXlzT2ZXZWVrO1xufVxuZnVuY3Rpb24gZ2V0RGF5T2ZXZWVrTnVtZXJpY2FsVmFsdWUoZGF5T2ZXZWVrTmFtZSkge1xuICAgIHJldHVybiBnZXREYXlzT2ZXZWVrKCkuaW5kZXhPZihkYXlPZldlZWtOYW1lLnRvTG93ZXJDYXNlKCkpO1xufVxuYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2Vla2x5Tm90ZShkYXRlKSB7XG4gICAgY29uc3QgeyB2YXVsdCB9ID0gd2luZG93LmFwcDtcbiAgICBjb25zdCB7IHRlbXBsYXRlLCBmb3JtYXQsIGZvbGRlciB9ID0gZ2V0V2Vla2x5Tm90ZVNldHRpbmdzKCk7XG4gICAgY29uc3QgW3RlbXBsYXRlQ29udGVudHMsIElGb2xkSW5mb10gPSBhd2FpdCBnZXRUZW1wbGF0ZUluZm8odGVtcGxhdGUpO1xuICAgIGNvbnN0IGZpbGVuYW1lID0gZGF0ZS5mb3JtYXQoZm9ybWF0KTtcbiAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IGF3YWl0IGdldE5vdGVQYXRoKGZvbGRlciwgZmlsZW5hbWUpO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRGaWxlID0gYXdhaXQgdmF1bHQuY3JlYXRlKG5vcm1hbGl6ZWRQYXRoLCB0ZW1wbGF0ZUNvbnRlbnRzXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqKGRhdGV8dGltZSlcXHMqKChbKy1dXFxkKykoW3lxbXdkaHNdKSk/XFxzKig6Lis/KT99fS9naSwgKF8sIF90aW1lT3JEYXRlLCBjYWxjLCB0aW1lRGVsdGEsIHVuaXQsIG1vbWVudEZvcm1hdCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gd2luZG93Lm1vbWVudCgpO1xuICAgICAgICAgICAgY29uc3QgY3VycmVudERhdGUgPSBkYXRlLmNsb25lKCkuc2V0KHtcbiAgICAgICAgICAgICAgICBob3VyOiBub3cuZ2V0KFwiaG91clwiKSxcbiAgICAgICAgICAgICAgICBtaW51dGU6IG5vdy5nZXQoXCJtaW51dGVcIiksXG4gICAgICAgICAgICAgICAgc2Vjb25kOiBub3cuZ2V0KFwic2Vjb25kXCIpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoY2FsYykge1xuICAgICAgICAgICAgICAgIGN1cnJlbnREYXRlLmFkZChwYXJzZUludCh0aW1lRGVsdGEsIDEwKSwgdW5pdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobW9tZW50Rm9ybWF0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnREYXRlLmZvcm1hdChtb21lbnRGb3JtYXQuc3Vic3RyaW5nKDEpLnRyaW0oKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudERhdGUuZm9ybWF0KGZvcm1hdCk7XG4gICAgICAgIH0pXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqdGl0bGVcXHMqfX0vZ2ksIGZpbGVuYW1lKVxuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKnRpbWVcXHMqfX0vZ2ksIHdpbmRvdy5tb21lbnQoKS5mb3JtYXQoXCJISDptbVwiKSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyooc3VuZGF5fG1vbmRheXx0dWVzZGF5fHdlZG5lc2RheXx0aHVyc2RheXxmcmlkYXl8c2F0dXJkYXkpXFxzKjooLio/KX19L2dpLCAoXywgZGF5T2ZXZWVrLCBtb21lbnRGb3JtYXQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGRheSA9IGdldERheU9mV2Vla051bWVyaWNhbFZhbHVlKGRheU9mV2Vlayk7XG4gICAgICAgICAgICByZXR1cm4gZGF0ZS53ZWVrZGF5KGRheSkuZm9ybWF0KG1vbWVudEZvcm1hdC50cmltKCkpO1xuICAgICAgICB9KSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIHdpbmRvdy5hcHAuZm9sZE1hbmFnZXIuc2F2ZShjcmVhdGVkRmlsZSwgSUZvbGRJbmZvKTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZWRGaWxlO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgZmlsZTogJyR7bm9ybWFsaXplZFBhdGh9J2AsIGVycik7XG4gICAgICAgIG5ldyBvYnNpZGlhbi5Ob3RpY2UoXCJVbmFibGUgdG8gY3JlYXRlIG5ldyBmaWxlLlwiKTtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRXZWVrbHlOb3RlKGRhdGUsIHdlZWtseU5vdGVzKSB7XG4gICAgcmV0dXJuIHdlZWtseU5vdGVzW2dldERhdGVVSUQoZGF0ZSwgXCJ3ZWVrXCIpXSA/PyBudWxsO1xufVxuZnVuY3Rpb24gZ2V0QWxsV2Vla2x5Tm90ZXMoKSB7XG4gICAgY29uc3Qgd2Vla2x5Tm90ZXMgPSB7fTtcbiAgICBpZiAoIWFwcEhhc1dlZWtseU5vdGVzUGx1Z2luTG9hZGVkKCkpIHtcbiAgICAgICAgcmV0dXJuIHdlZWtseU5vdGVzO1xuICAgIH1cbiAgICBjb25zdCB7IHZhdWx0IH0gPSB3aW5kb3cuYXBwO1xuICAgIGNvbnN0IHsgZm9sZGVyIH0gPSBnZXRXZWVrbHlOb3RlU2V0dGluZ3MoKTtcbiAgICBjb25zdCB3ZWVrbHlOb3Rlc0ZvbGRlciA9IHZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChvYnNpZGlhbi5ub3JtYWxpemVQYXRoKGZvbGRlcikpO1xuICAgIGlmICghd2Vla2x5Tm90ZXNGb2xkZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFdlZWtseU5vdGVzRm9sZGVyTWlzc2luZ0Vycm9yKFwiRmFpbGVkIHRvIGZpbmQgd2Vla2x5IG5vdGVzIGZvbGRlclwiKTtcbiAgICB9XG4gICAgb2JzaWRpYW4uVmF1bHQucmVjdXJzZUNoaWxkcmVuKHdlZWtseU5vdGVzRm9sZGVyLCAobm90ZSkgPT4ge1xuICAgICAgICBpZiAobm90ZSBpbnN0YW5jZW9mIG9ic2lkaWFuLlRGaWxlKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRlID0gZ2V0RGF0ZUZyb21GaWxlKG5vdGUsIFwid2Vla1wiKTtcbiAgICAgICAgICAgIGlmIChkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZVN0cmluZyA9IGdldERhdGVVSUQoZGF0ZSwgXCJ3ZWVrXCIpO1xuICAgICAgICAgICAgICAgIHdlZWtseU5vdGVzW2RhdGVTdHJpbmddID0gbm90ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB3ZWVrbHlOb3Rlcztcbn1cblxuY2xhc3MgTW9udGhseU5vdGVzRm9sZGVyTWlzc2luZ0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIG1pbWljcyB0aGUgYmVoYXZpb3Igb2YgdGhlIGRhaWx5LW5vdGVzIHBsdWdpblxuICogc28gaXQgd2lsbCByZXBsYWNlIHt7ZGF0ZX19LCB7e3RpdGxlfX0sIGFuZCB7e3RpbWV9fSB3aXRoIHRoZVxuICogZm9ybWF0dGVkIHRpbWVzdGFtcC5cbiAqXG4gKiBOb3RlOiBpdCBoYXMgYW4gYWRkZWQgYm9udXMgdGhhdCBpdCdzIG5vdCAndG9kYXknIHNwZWNpZmljLlxuICovXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVNb250aGx5Tm90ZShkYXRlKSB7XG4gICAgY29uc3QgeyB2YXVsdCB9ID0gd2luZG93LmFwcDtcbiAgICBjb25zdCB7IHRlbXBsYXRlLCBmb3JtYXQsIGZvbGRlciB9ID0gZ2V0TW9udGhseU5vdGVTZXR0aW5ncygpO1xuICAgIGNvbnN0IFt0ZW1wbGF0ZUNvbnRlbnRzLCBJRm9sZEluZm9dID0gYXdhaXQgZ2V0VGVtcGxhdGVJbmZvKHRlbXBsYXRlKTtcbiAgICBjb25zdCBmaWxlbmFtZSA9IGRhdGUuZm9ybWF0KGZvcm1hdCk7XG4gICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSBhd2FpdCBnZXROb3RlUGF0aChmb2xkZXIsIGZpbGVuYW1lKTtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBjcmVhdGVkRmlsZSA9IGF3YWl0IHZhdWx0LmNyZWF0ZShub3JtYWxpemVkUGF0aCwgdGVtcGxhdGVDb250ZW50c1xuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKihkYXRlfHRpbWUpXFxzKigoWystXVxcZCspKFt5cW13ZGhzXSkpP1xccyooOi4rPyk/fX0vZ2ksIChfLCBfdGltZU9yRGF0ZSwgY2FsYywgdGltZURlbHRhLCB1bml0LCBtb21lbnRGb3JtYXQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHdpbmRvdy5tb21lbnQoKTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnREYXRlID0gZGF0ZS5jbG9uZSgpLnNldCh7XG4gICAgICAgICAgICAgICAgaG91cjogbm93LmdldChcImhvdXJcIiksXG4gICAgICAgICAgICAgICAgbWludXRlOiBub3cuZ2V0KFwibWludXRlXCIpLFxuICAgICAgICAgICAgICAgIHNlY29uZDogbm93LmdldChcInNlY29uZFwiKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGNhbGMpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50RGF0ZS5hZGQocGFyc2VJbnQodGltZURlbHRhLCAxMCksIHVuaXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1vbWVudEZvcm1hdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50RGF0ZS5mb3JtYXQobW9tZW50Rm9ybWF0LnN1YnN0cmluZygxKS50cmltKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnREYXRlLmZvcm1hdChmb3JtYXQpO1xuICAgICAgICB9KVxuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKmRhdGVcXHMqfX0vZ2ksIGZpbGVuYW1lKVxuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKnRpbWVcXHMqfX0vZ2ksIHdpbmRvdy5tb21lbnQoKS5mb3JtYXQoXCJISDptbVwiKSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyp0aXRsZVxccyp9fS9naSwgZmlsZW5hbWUpKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgd2luZG93LmFwcC5mb2xkTWFuYWdlci5zYXZlKGNyZWF0ZWRGaWxlLCBJRm9sZEluZm8pO1xuICAgICAgICByZXR1cm4gY3JlYXRlZEZpbGU7XG4gICAgfVxuICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBmaWxlOiAnJHtub3JtYWxpemVkUGF0aH0nYCwgZXJyKTtcbiAgICAgICAgbmV3IG9ic2lkaWFuLk5vdGljZShcIlVuYWJsZSB0byBjcmVhdGUgbmV3IGZpbGUuXCIpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldE1vbnRobHlOb3RlKGRhdGUsIG1vbnRobHlOb3Rlcykge1xuICAgIHJldHVybiBtb250aGx5Tm90ZXNbZ2V0RGF0ZVVJRChkYXRlLCBcIm1vbnRoXCIpXSA/PyBudWxsO1xufVxuZnVuY3Rpb24gZ2V0QWxsTW9udGhseU5vdGVzKCkge1xuICAgIGNvbnN0IG1vbnRobHlOb3RlcyA9IHt9O1xuICAgIGlmICghYXBwSGFzTW9udGhseU5vdGVzUGx1Z2luTG9hZGVkKCkpIHtcbiAgICAgICAgcmV0dXJuIG1vbnRobHlOb3RlcztcbiAgICB9XG4gICAgY29uc3QgeyB2YXVsdCB9ID0gd2luZG93LmFwcDtcbiAgICBjb25zdCB7IGZvbGRlciB9ID0gZ2V0TW9udGhseU5vdGVTZXR0aW5ncygpO1xuICAgIGNvbnN0IG1vbnRobHlOb3Rlc0ZvbGRlciA9IHZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChvYnNpZGlhbi5ub3JtYWxpemVQYXRoKGZvbGRlcikpO1xuICAgIGlmICghbW9udGhseU5vdGVzRm9sZGVyKSB7XG4gICAgICAgIHRocm93IG5ldyBNb250aGx5Tm90ZXNGb2xkZXJNaXNzaW5nRXJyb3IoXCJGYWlsZWQgdG8gZmluZCBtb250aGx5IG5vdGVzIGZvbGRlclwiKTtcbiAgICB9XG4gICAgb2JzaWRpYW4uVmF1bHQucmVjdXJzZUNoaWxkcmVuKG1vbnRobHlOb3Rlc0ZvbGRlciwgKG5vdGUpID0+IHtcbiAgICAgICAgaWYgKG5vdGUgaW5zdGFuY2VvZiBvYnNpZGlhbi5URmlsZSkge1xuICAgICAgICAgICAgY29uc3QgZGF0ZSA9IGdldERhdGVGcm9tRmlsZShub3RlLCBcIm1vbnRoXCIpO1xuICAgICAgICAgICAgaWYgKGRhdGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRlU3RyaW5nID0gZ2V0RGF0ZVVJRChkYXRlLCBcIm1vbnRoXCIpO1xuICAgICAgICAgICAgICAgIG1vbnRobHlOb3Rlc1tkYXRlU3RyaW5nXSA9IG5vdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gbW9udGhseU5vdGVzO1xufVxuXG5jbGFzcyBRdWFydGVybHlOb3Rlc0ZvbGRlck1pc3NpbmdFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBtaW1pY3MgdGhlIGJlaGF2aW9yIG9mIHRoZSBkYWlseS1ub3RlcyBwbHVnaW5cbiAqIHNvIGl0IHdpbGwgcmVwbGFjZSB7e2RhdGV9fSwge3t0aXRsZX19LCBhbmQge3t0aW1lfX0gd2l0aCB0aGVcbiAqIGZvcm1hdHRlZCB0aW1lc3RhbXAuXG4gKlxuICogTm90ZTogaXQgaGFzIGFuIGFkZGVkIGJvbnVzIHRoYXQgaXQncyBub3QgJ3RvZGF5JyBzcGVjaWZpYy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gY3JlYXRlUXVhcnRlcmx5Tm90ZShkYXRlKSB7XG4gICAgY29uc3QgeyB2YXVsdCB9ID0gd2luZG93LmFwcDtcbiAgICBjb25zdCB7IHRlbXBsYXRlLCBmb3JtYXQsIGZvbGRlciB9ID0gZ2V0UXVhcnRlcmx5Tm90ZVNldHRpbmdzKCk7XG4gICAgY29uc3QgW3RlbXBsYXRlQ29udGVudHMsIElGb2xkSW5mb10gPSBhd2FpdCBnZXRUZW1wbGF0ZUluZm8odGVtcGxhdGUpO1xuICAgIGNvbnN0IGZpbGVuYW1lID0gZGF0ZS5mb3JtYXQoZm9ybWF0KTtcbiAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IGF3YWl0IGdldE5vdGVQYXRoKGZvbGRlciwgZmlsZW5hbWUpO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRGaWxlID0gYXdhaXQgdmF1bHQuY3JlYXRlKG5vcm1hbGl6ZWRQYXRoLCB0ZW1wbGF0ZUNvbnRlbnRzXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqKGRhdGV8dGltZSlcXHMqKChbKy1dXFxkKykoW3lxbXdkaHNdKSk/XFxzKig6Lis/KT99fS9naSwgKF8sIF90aW1lT3JEYXRlLCBjYWxjLCB0aW1lRGVsdGEsIHVuaXQsIG1vbWVudEZvcm1hdCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gd2luZG93Lm1vbWVudCgpO1xuICAgICAgICAgICAgY29uc3QgY3VycmVudERhdGUgPSBkYXRlLmNsb25lKCkuc2V0KHtcbiAgICAgICAgICAgICAgICBob3VyOiBub3cuZ2V0KFwiaG91clwiKSxcbiAgICAgICAgICAgICAgICBtaW51dGU6IG5vdy5nZXQoXCJtaW51dGVcIiksXG4gICAgICAgICAgICAgICAgc2Vjb25kOiBub3cuZ2V0KFwic2Vjb25kXCIpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoY2FsYykge1xuICAgICAgICAgICAgICAgIGN1cnJlbnREYXRlLmFkZChwYXJzZUludCh0aW1lRGVsdGEsIDEwKSwgdW5pdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobW9tZW50Rm9ybWF0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnREYXRlLmZvcm1hdChtb21lbnRGb3JtYXQuc3Vic3RyaW5nKDEpLnRyaW0oKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudERhdGUuZm9ybWF0KGZvcm1hdCk7XG4gICAgICAgIH0pXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqZGF0ZVxccyp9fS9naSwgZmlsZW5hbWUpXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqdGltZVxccyp9fS9naSwgd2luZG93Lm1vbWVudCgpLmZvcm1hdChcIkhIOm1tXCIpKVxuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKnRpdGxlXFxzKn19L2dpLCBmaWxlbmFtZSkpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICB3aW5kb3cuYXBwLmZvbGRNYW5hZ2VyLnNhdmUoY3JlYXRlZEZpbGUsIElGb2xkSW5mbyk7XG4gICAgICAgIHJldHVybiBjcmVhdGVkRmlsZTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIGZpbGU6ICcke25vcm1hbGl6ZWRQYXRofSdgLCBlcnIpO1xuICAgICAgICBuZXcgb2JzaWRpYW4uTm90aWNlKFwiVW5hYmxlIHRvIGNyZWF0ZSBuZXcgZmlsZS5cIik7XG4gICAgfVxufVxuZnVuY3Rpb24gZ2V0UXVhcnRlcmx5Tm90ZShkYXRlLCBxdWFydGVybHkpIHtcbiAgICByZXR1cm4gcXVhcnRlcmx5W2dldERhdGVVSUQoZGF0ZSwgXCJxdWFydGVyXCIpXSA/PyBudWxsO1xufVxuZnVuY3Rpb24gZ2V0QWxsUXVhcnRlcmx5Tm90ZXMoKSB7XG4gICAgY29uc3QgcXVhcnRlcmx5ID0ge307XG4gICAgaWYgKCFhcHBIYXNRdWFydGVybHlOb3Rlc1BsdWdpbkxvYWRlZCgpKSB7XG4gICAgICAgIHJldHVybiBxdWFydGVybHk7XG4gICAgfVxuICAgIGNvbnN0IHsgdmF1bHQgfSA9IHdpbmRvdy5hcHA7XG4gICAgY29uc3QgeyBmb2xkZXIgfSA9IGdldFF1YXJ0ZXJseU5vdGVTZXR0aW5ncygpO1xuICAgIGNvbnN0IHF1YXJ0ZXJseUZvbGRlciA9IHZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChvYnNpZGlhbi5ub3JtYWxpemVQYXRoKGZvbGRlcikpO1xuICAgIGlmICghcXVhcnRlcmx5Rm9sZGVyKSB7XG4gICAgICAgIHRocm93IG5ldyBRdWFydGVybHlOb3Rlc0ZvbGRlck1pc3NpbmdFcnJvcihcIkZhaWxlZCB0byBmaW5kIHF1YXJ0ZXJseSBub3RlcyBmb2xkZXJcIik7XG4gICAgfVxuICAgIG9ic2lkaWFuLlZhdWx0LnJlY3Vyc2VDaGlsZHJlbihxdWFydGVybHlGb2xkZXIsIChub3RlKSA9PiB7XG4gICAgICAgIGlmIChub3RlIGluc3RhbmNlb2Ygb2JzaWRpYW4uVEZpbGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGUgPSBnZXREYXRlRnJvbUZpbGUobm90ZSwgXCJxdWFydGVyXCIpO1xuICAgICAgICAgICAgaWYgKGRhdGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRlU3RyaW5nID0gZ2V0RGF0ZVVJRChkYXRlLCBcInF1YXJ0ZXJcIik7XG4gICAgICAgICAgICAgICAgcXVhcnRlcmx5W2RhdGVTdHJpbmddID0gbm90ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBxdWFydGVybHk7XG59XG5cbmNsYXNzIFllYXJseU5vdGVzRm9sZGVyTWlzc2luZ0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIG1pbWljcyB0aGUgYmVoYXZpb3Igb2YgdGhlIGRhaWx5LW5vdGVzIHBsdWdpblxuICogc28gaXQgd2lsbCByZXBsYWNlIHt7ZGF0ZX19LCB7e3RpdGxlfX0sIGFuZCB7e3RpbWV9fSB3aXRoIHRoZVxuICogZm9ybWF0dGVkIHRpbWVzdGFtcC5cbiAqXG4gKiBOb3RlOiBpdCBoYXMgYW4gYWRkZWQgYm9udXMgdGhhdCBpdCdzIG5vdCAndG9kYXknIHNwZWNpZmljLlxuICovXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVZZWFybHlOb3RlKGRhdGUpIHtcbiAgICBjb25zdCB7IHZhdWx0IH0gPSB3aW5kb3cuYXBwO1xuICAgIGNvbnN0IHsgdGVtcGxhdGUsIGZvcm1hdCwgZm9sZGVyIH0gPSBnZXRZZWFybHlOb3RlU2V0dGluZ3MoKTtcbiAgICBjb25zdCBbdGVtcGxhdGVDb250ZW50cywgSUZvbGRJbmZvXSA9IGF3YWl0IGdldFRlbXBsYXRlSW5mbyh0ZW1wbGF0ZSk7XG4gICAgY29uc3QgZmlsZW5hbWUgPSBkYXRlLmZvcm1hdChmb3JtYXQpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gYXdhaXQgZ2V0Tm90ZVBhdGgoZm9sZGVyLCBmaWxlbmFtZSk7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY3JlYXRlZEZpbGUgPSBhd2FpdCB2YXVsdC5jcmVhdGUobm9ybWFsaXplZFBhdGgsIHRlbXBsYXRlQ29udGVudHNcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyooZGF0ZXx0aW1lKVxccyooKFsrLV1cXGQrKShbeXFtd2Roc10pKT9cXHMqKDouKz8pP319L2dpLCAoXywgX3RpbWVPckRhdGUsIGNhbGMsIHRpbWVEZWx0YSwgdW5pdCwgbW9tZW50Rm9ybWF0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSB3aW5kb3cubW9tZW50KCk7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RGF0ZSA9IGRhdGUuY2xvbmUoKS5zZXQoe1xuICAgICAgICAgICAgICAgIGhvdXI6IG5vdy5nZXQoXCJob3VyXCIpLFxuICAgICAgICAgICAgICAgIG1pbnV0ZTogbm93LmdldChcIm1pbnV0ZVwiKSxcbiAgICAgICAgICAgICAgICBzZWNvbmQ6IG5vdy5nZXQoXCJzZWNvbmRcIiksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChjYWxjKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudERhdGUuYWRkKHBhcnNlSW50KHRpbWVEZWx0YSwgMTApLCB1bml0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtb21lbnRGb3JtYXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudERhdGUuZm9ybWF0KG1vbWVudEZvcm1hdC5zdWJzdHJpbmcoMSkudHJpbSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50RGF0ZS5mb3JtYXQoZm9ybWF0KTtcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccypkYXRlXFxzKn19L2dpLCBmaWxlbmFtZSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyp0aW1lXFxzKn19L2dpLCB3aW5kb3cubW9tZW50KCkuZm9ybWF0KFwiSEg6bW1cIikpXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqdGl0bGVcXHMqfX0vZ2ksIGZpbGVuYW1lKSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIHdpbmRvdy5hcHAuZm9sZE1hbmFnZXIuc2F2ZShjcmVhdGVkRmlsZSwgSUZvbGRJbmZvKTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZWRGaWxlO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgZmlsZTogJyR7bm9ybWFsaXplZFBhdGh9J2AsIGVycik7XG4gICAgICAgIG5ldyBvYnNpZGlhbi5Ob3RpY2UoXCJVbmFibGUgdG8gY3JlYXRlIG5ldyBmaWxlLlwiKTtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRZZWFybHlOb3RlKGRhdGUsIHllYXJseU5vdGVzKSB7XG4gICAgcmV0dXJuIHllYXJseU5vdGVzW2dldERhdGVVSUQoZGF0ZSwgXCJ5ZWFyXCIpXSA/PyBudWxsO1xufVxuZnVuY3Rpb24gZ2V0QWxsWWVhcmx5Tm90ZXMoKSB7XG4gICAgY29uc3QgeWVhcmx5Tm90ZXMgPSB7fTtcbiAgICBpZiAoIWFwcEhhc1llYXJseU5vdGVzUGx1Z2luTG9hZGVkKCkpIHtcbiAgICAgICAgcmV0dXJuIHllYXJseU5vdGVzO1xuICAgIH1cbiAgICBjb25zdCB7IHZhdWx0IH0gPSB3aW5kb3cuYXBwO1xuICAgIGNvbnN0IHsgZm9sZGVyIH0gPSBnZXRZZWFybHlOb3RlU2V0dGluZ3MoKTtcbiAgICBjb25zdCB5ZWFybHlOb3Rlc0ZvbGRlciA9IHZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChvYnNpZGlhbi5ub3JtYWxpemVQYXRoKGZvbGRlcikpO1xuICAgIGlmICgheWVhcmx5Tm90ZXNGb2xkZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFllYXJseU5vdGVzRm9sZGVyTWlzc2luZ0Vycm9yKFwiRmFpbGVkIHRvIGZpbmQgeWVhcmx5IG5vdGVzIGZvbGRlclwiKTtcbiAgICB9XG4gICAgb2JzaWRpYW4uVmF1bHQucmVjdXJzZUNoaWxkcmVuKHllYXJseU5vdGVzRm9sZGVyLCAobm90ZSkgPT4ge1xuICAgICAgICBpZiAobm90ZSBpbnN0YW5jZW9mIG9ic2lkaWFuLlRGaWxlKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRlID0gZ2V0RGF0ZUZyb21GaWxlKG5vdGUsIFwieWVhclwiKTtcbiAgICAgICAgICAgIGlmIChkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZVN0cmluZyA9IGdldERhdGVVSUQoZGF0ZSwgXCJ5ZWFyXCIpO1xuICAgICAgICAgICAgICAgIHllYXJseU5vdGVzW2RhdGVTdHJpbmddID0gbm90ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB5ZWFybHlOb3Rlcztcbn1cblxuZnVuY3Rpb24gYXBwSGFzRGFpbHlOb3Rlc1BsdWdpbkxvYWRlZCgpIHtcbiAgICBjb25zdCB7IGFwcCB9ID0gd2luZG93O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgZGFpbHlOb3Rlc1BsdWdpbiA9IGFwcC5pbnRlcm5hbFBsdWdpbnMucGx1Z2luc1tcImRhaWx5LW5vdGVzXCJdO1xuICAgIGlmIChkYWlseU5vdGVzUGx1Z2luICYmIGRhaWx5Tm90ZXNQbHVnaW4uZW5hYmxlZCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBwZXJpb2RpY05vdGVzID0gYXBwLnBsdWdpbnMuZ2V0UGx1Z2luKFwicGVyaW9kaWMtbm90ZXNcIik7XG4gICAgcmV0dXJuIHBlcmlvZGljTm90ZXMgJiYgcGVyaW9kaWNOb3Rlcy5zZXR0aW5ncz8uZGFpbHk/LmVuYWJsZWQ7XG59XG4vKipcbiAqIFhYWDogXCJXZWVrbHkgTm90ZXNcIiBsaXZlIGluIGVpdGhlciB0aGUgQ2FsZW5kYXIgcGx1Z2luIG9yIHRoZSBwZXJpb2RpYy1ub3RlcyBwbHVnaW4uXG4gKiBDaGVjayBib3RoIHVudGlsIHRoZSB3ZWVrbHkgbm90ZXMgZmVhdHVyZSBpcyByZW1vdmVkIGZyb20gdGhlIENhbGVuZGFyIHBsdWdpbi5cbiAqL1xuZnVuY3Rpb24gYXBwSGFzV2Vla2x5Tm90ZXNQbHVnaW5Mb2FkZWQoKSB7XG4gICAgY29uc3QgeyBhcHAgfSA9IHdpbmRvdztcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGlmIChhcHAucGx1Z2lucy5nZXRQbHVnaW4oXCJjYWxlbmRhclwiKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBwZXJpb2RpY05vdGVzID0gYXBwLnBsdWdpbnMuZ2V0UGx1Z2luKFwicGVyaW9kaWMtbm90ZXNcIik7XG4gICAgcmV0dXJuIHBlcmlvZGljTm90ZXMgJiYgcGVyaW9kaWNOb3Rlcy5zZXR0aW5ncz8ud2Vla2x5Py5lbmFibGVkO1xufVxuZnVuY3Rpb24gYXBwSGFzTW9udGhseU5vdGVzUGx1Z2luTG9hZGVkKCkge1xuICAgIGNvbnN0IHsgYXBwIH0gPSB3aW5kb3c7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBwZXJpb2RpY05vdGVzID0gYXBwLnBsdWdpbnMuZ2V0UGx1Z2luKFwicGVyaW9kaWMtbm90ZXNcIik7XG4gICAgcmV0dXJuIHBlcmlvZGljTm90ZXMgJiYgcGVyaW9kaWNOb3Rlcy5zZXR0aW5ncz8ubW9udGhseT8uZW5hYmxlZDtcbn1cbmZ1bmN0aW9uIGFwcEhhc1F1YXJ0ZXJseU5vdGVzUGx1Z2luTG9hZGVkKCkge1xuICAgIGNvbnN0IHsgYXBwIH0gPSB3aW5kb3c7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBwZXJpb2RpY05vdGVzID0gYXBwLnBsdWdpbnMuZ2V0UGx1Z2luKFwicGVyaW9kaWMtbm90ZXNcIik7XG4gICAgcmV0dXJuIHBlcmlvZGljTm90ZXMgJiYgcGVyaW9kaWNOb3Rlcy5zZXR0aW5ncz8ucXVhcnRlcmx5Py5lbmFibGVkO1xufVxuZnVuY3Rpb24gYXBwSGFzWWVhcmx5Tm90ZXNQbHVnaW5Mb2FkZWQoKSB7XG4gICAgY29uc3QgeyBhcHAgfSA9IHdpbmRvdztcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IHBlcmlvZGljTm90ZXMgPSBhcHAucGx1Z2lucy5nZXRQbHVnaW4oXCJwZXJpb2RpYy1ub3Rlc1wiKTtcbiAgICByZXR1cm4gcGVyaW9kaWNOb3RlcyAmJiBwZXJpb2RpY05vdGVzLnNldHRpbmdzPy55ZWFybHk/LmVuYWJsZWQ7XG59XG5mdW5jdGlvbiBnZXRQZXJpb2RpY05vdGVTZXR0aW5ncyhncmFudWxhcml0eSkge1xuICAgIGNvbnN0IGdldFNldHRpbmdzID0ge1xuICAgICAgICBkYXk6IGdldERhaWx5Tm90ZVNldHRpbmdzLFxuICAgICAgICB3ZWVrOiBnZXRXZWVrbHlOb3RlU2V0dGluZ3MsXG4gICAgICAgIG1vbnRoOiBnZXRNb250aGx5Tm90ZVNldHRpbmdzLFxuICAgICAgICBxdWFydGVyOiBnZXRRdWFydGVybHlOb3RlU2V0dGluZ3MsXG4gICAgICAgIHllYXI6IGdldFllYXJseU5vdGVTZXR0aW5ncyxcbiAgICB9W2dyYW51bGFyaXR5XTtcbiAgICByZXR1cm4gZ2V0U2V0dGluZ3MoKTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZVBlcmlvZGljTm90ZShncmFudWxhcml0eSwgZGF0ZSkge1xuICAgIGNvbnN0IGNyZWF0ZUZuID0ge1xuICAgICAgICBkYXk6IGNyZWF0ZURhaWx5Tm90ZSxcbiAgICAgICAgbW9udGg6IGNyZWF0ZU1vbnRobHlOb3RlLFxuICAgICAgICB3ZWVrOiBjcmVhdGVXZWVrbHlOb3RlLFxuICAgIH07XG4gICAgcmV0dXJuIGNyZWF0ZUZuW2dyYW51bGFyaXR5XShkYXRlKTtcbn1cblxuZXhwb3J0cy5ERUZBVUxUX0RBSUxZX05PVEVfRk9STUFUID0gREVGQVVMVF9EQUlMWV9OT1RFX0ZPUk1BVDtcbmV4cG9ydHMuREVGQVVMVF9NT05USExZX05PVEVfRk9STUFUID0gREVGQVVMVF9NT05USExZX05PVEVfRk9STUFUO1xuZXhwb3J0cy5ERUZBVUxUX1FVQVJURVJMWV9OT1RFX0ZPUk1BVCA9IERFRkFVTFRfUVVBUlRFUkxZX05PVEVfRk9STUFUO1xuZXhwb3J0cy5ERUZBVUxUX1dFRUtMWV9OT1RFX0ZPUk1BVCA9IERFRkFVTFRfV0VFS0xZX05PVEVfRk9STUFUO1xuZXhwb3J0cy5ERUZBVUxUX1lFQVJMWV9OT1RFX0ZPUk1BVCA9IERFRkFVTFRfWUVBUkxZX05PVEVfRk9STUFUO1xuZXhwb3J0cy5hcHBIYXNEYWlseU5vdGVzUGx1Z2luTG9hZGVkID0gYXBwSGFzRGFpbHlOb3Rlc1BsdWdpbkxvYWRlZDtcbmV4cG9ydHMuYXBwSGFzTW9udGhseU5vdGVzUGx1Z2luTG9hZGVkID0gYXBwSGFzTW9udGhseU5vdGVzUGx1Z2luTG9hZGVkO1xuZXhwb3J0cy5hcHBIYXNRdWFydGVybHlOb3Rlc1BsdWdpbkxvYWRlZCA9IGFwcEhhc1F1YXJ0ZXJseU5vdGVzUGx1Z2luTG9hZGVkO1xuZXhwb3J0cy5hcHBIYXNXZWVrbHlOb3Rlc1BsdWdpbkxvYWRlZCA9IGFwcEhhc1dlZWtseU5vdGVzUGx1Z2luTG9hZGVkO1xuZXhwb3J0cy5hcHBIYXNZZWFybHlOb3Rlc1BsdWdpbkxvYWRlZCA9IGFwcEhhc1llYXJseU5vdGVzUGx1Z2luTG9hZGVkO1xuZXhwb3J0cy5jcmVhdGVEYWlseU5vdGUgPSBjcmVhdGVEYWlseU5vdGU7XG5leHBvcnRzLmNyZWF0ZU1vbnRobHlOb3RlID0gY3JlYXRlTW9udGhseU5vdGU7XG5leHBvcnRzLmNyZWF0ZVBlcmlvZGljTm90ZSA9IGNyZWF0ZVBlcmlvZGljTm90ZTtcbmV4cG9ydHMuY3JlYXRlUXVhcnRlcmx5Tm90ZSA9IGNyZWF0ZVF1YXJ0ZXJseU5vdGU7XG5leHBvcnRzLmNyZWF0ZVdlZWtseU5vdGUgPSBjcmVhdGVXZWVrbHlOb3RlO1xuZXhwb3J0cy5jcmVhdGVZZWFybHlOb3RlID0gY3JlYXRlWWVhcmx5Tm90ZTtcbmV4cG9ydHMuZ2V0QWxsRGFpbHlOb3RlcyA9IGdldEFsbERhaWx5Tm90ZXM7XG5leHBvcnRzLmdldEFsbE1vbnRobHlOb3RlcyA9IGdldEFsbE1vbnRobHlOb3RlcztcbmV4cG9ydHMuZ2V0QWxsUXVhcnRlcmx5Tm90ZXMgPSBnZXRBbGxRdWFydGVybHlOb3RlcztcbmV4cG9ydHMuZ2V0QWxsV2Vla2x5Tm90ZXMgPSBnZXRBbGxXZWVrbHlOb3RlcztcbmV4cG9ydHMuZ2V0QWxsWWVhcmx5Tm90ZXMgPSBnZXRBbGxZZWFybHlOb3RlcztcbmV4cG9ydHMuZ2V0RGFpbHlOb3RlID0gZ2V0RGFpbHlOb3RlO1xuZXhwb3J0cy5nZXREYWlseU5vdGVTZXR0aW5ncyA9IGdldERhaWx5Tm90ZVNldHRpbmdzO1xuZXhwb3J0cy5nZXREYXRlRnJvbUZpbGUgPSBnZXREYXRlRnJvbUZpbGU7XG5leHBvcnRzLmdldERhdGVGcm9tUGF0aCA9IGdldERhdGVGcm9tUGF0aDtcbmV4cG9ydHMuZ2V0RGF0ZVVJRCA9IGdldERhdGVVSUQ7XG5leHBvcnRzLmdldE1vbnRobHlOb3RlID0gZ2V0TW9udGhseU5vdGU7XG5leHBvcnRzLmdldE1vbnRobHlOb3RlU2V0dGluZ3MgPSBnZXRNb250aGx5Tm90ZVNldHRpbmdzO1xuZXhwb3J0cy5nZXRQZXJpb2RpY05vdGVTZXR0aW5ncyA9IGdldFBlcmlvZGljTm90ZVNldHRpbmdzO1xuZXhwb3J0cy5nZXRRdWFydGVybHlOb3RlID0gZ2V0UXVhcnRlcmx5Tm90ZTtcbmV4cG9ydHMuZ2V0UXVhcnRlcmx5Tm90ZVNldHRpbmdzID0gZ2V0UXVhcnRlcmx5Tm90ZVNldHRpbmdzO1xuZXhwb3J0cy5nZXRUZW1wbGF0ZUluZm8gPSBnZXRUZW1wbGF0ZUluZm87XG5leHBvcnRzLmdldFdlZWtseU5vdGUgPSBnZXRXZWVrbHlOb3RlO1xuZXhwb3J0cy5nZXRXZWVrbHlOb3RlU2V0dGluZ3MgPSBnZXRXZWVrbHlOb3RlU2V0dGluZ3M7XG5leHBvcnRzLmdldFllYXJseU5vdGUgPSBnZXRZZWFybHlOb3RlO1xuZXhwb3J0cy5nZXRZZWFybHlOb3RlU2V0dGluZ3MgPSBnZXRZZWFybHlOb3RlU2V0dGluZ3M7XG4iLCAiLyoqXHJcbiAqIEhvbWUgQmFzZSBQbHVnaW5cclxuICogWW91ciBkZWRpY2F0ZWQgaG9tZSBpbiB5b3VyIHZhdWx0XHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgTm90aWNlLCBQbGF0Zm9ybSwgUGx1Z2luLCBhZGRJY29uIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBERUZBVUxUX1NFVFRJTkdTLCBIb21lQmFzZVNldHRpbmdzLCBIb21lQmFzZVR5cGUgfSBmcm9tICcuL3NldHRpbmdzJztcclxuaW1wb3J0IHsgSG9tZUJhc2VTZXR0aW5nVGFiIH0gZnJvbSAnLi91aS9zZXR0aW5ncy10YWInO1xyXG5pbXBvcnQgeyBIb21lQmFzZVNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2hvbWUtc2VydmljZSc7XHJcbmltcG9ydCB7IE5ld1RhYlNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL25ldy10YWItc2VydmljZSc7XHJcbmltcG9ydCB7IFN0aWNreVRhYlNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL3N0aWNreS10YWItc2VydmljZSc7XHJcbmltcG9ydCB7IE1vYmlsZUJ1dHRvblNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL21vYmlsZS1idXR0b24tc2VydmljZSc7XHJcbmltcG9ydCB7IG1pZ3JhdGVMZWdhY3lTZXR0aW5ncyB9IGZyb20gJy4vbWlncmF0aW9uJztcclxuXHJcbi8qKlxyXG4gKiBFeHRlbmRlZCBBcHAgaW50ZXJmYWNlIGZvciByZWxlYXNlIG5vdGVzIHBhdGNoaW5nXHJcbiAqL1xyXG5pbnRlcmZhY2UgQXBwV2l0aFJlbGVhc2VOb3RlcyB7XHJcblx0c2hvd1JlbGVhc2VOb3Rlcz86ICgpID0+IHZvaWQ7XHJcblx0bnZPcmlnX3Nob3dSZWxlYXNlTm90ZXM/OiAoKSA9PiB2b2lkO1xyXG59XHJcblxyXG4vKipcclxuICogQ3VzdG9tIGhvbWUgaWNvbiBTVkcgKEx1Y2lkZSBob3VzZSBpY29uKVxyXG4gKi9cclxuY29uc3QgSE9NRV9JQ09OID0gYDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIj48cGF0aCBkPVwiTTE1IDIxdi04YTEgMSAwIDAgMC0xLTFoLTRhMSAxIDAgMCAwLTEgMXY4XCIvPjxwYXRoIGQ9XCJNMyAxMGEyIDIgMCAwIDEgLjcwOS0xLjUyOGw3LTZhMiAyIDAgMCAxIDIuNTgyIDBsNyA2QTIgMiAwIDAgMSAyMSAxMHY5YTIgMiAwIDAgMS0yIDJINWEyIDIgMCAwIDEtMi0yelwiLz48L3N2Zz5gO1xyXG5cclxuLyoqXHJcbiAqIFRpbWluZyBjb25zdGFudHMgZm9yIFVJIG9wZXJhdGlvbnNcclxuICogVGhlc2UgZGVsYXlzIGFyZSBuZWNlc3NhcnkgZm9yIE9ic2lkaWFuJ3MgaW50ZXJuYWwgRE9NIHVwZGF0ZXMgdG8gY29tcGxldGVcclxuICovXHJcblxyXG4vKiogRGVsYXkgdG8gZW5zdXJlIERPTSBpcyByZWFkeSBhZnRlciBsYXlvdXQtcmVhZHkgZXZlbnQgKHNldHRpbmdzIG1vZGFsIGRldGVjdGlvbikgKi9cclxuY29uc3QgRE9NX1JFQURZX0RFTEFZID0gMTAwO1xyXG5cclxuLyoqIERlbGF5IGZvciB0YWIgaGVhZGVyIHVwZGF0ZXMgYWZ0ZXIgbGF5b3V0IGNoYW5nZXMgdG8gYXZvaWQgdmlzdWFsIGZsaWNrZXJpbmcgKi9cclxuY29uc3QgVEFCX0hFQURFUl9VUERBVEVfREVMQVkgPSAxNTA7XHJcblxyXG4vKiogRGVsYXkgZm9yIFVJIHVwZGF0ZXMgYWZ0ZXIgZmlsZS1vcGVuIHRvIGxldCBhbmltYXRpb25zIGNvbXBsZXRlICovXHJcbmNvbnN0IEZJTEVfT1BFTl9BTklNQVRJT05fREVMQVkgPSAxMDA7XHJcblxyXG4vKiogRGVsYXkgZm9yIHVwZGF0ZXMgYWZ0ZXIgYWN0aXZlLWxlYWYtY2hhbmdlIHRvIGxldCB0YWIgc3dpdGNoIGFuaW1hdGlvbnMgY29tcGxldGUgKi9cclxuY29uc3QgVEFCX1NXSVRDSF9BTklNQVRJT05fREVMQVkgPSAxMDA7XHJcblxyXG4vKiogRGVsYXkgYWZ0ZXIgbGF5b3V0LXJlYWR5IGJlZm9yZSBtYXJraW5nIHN0YXJ0dXAgYXMgY29tcGxldGUgKGFsbG93cyBldmVyeXRoaW5nIHRvIHNldHRsZSkgKi9cclxuY29uc3QgU1RBUlRVUF9DT01QTEVURV9ERUxBWSA9IDEwMDA7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIb21lQmFzZVBsdWdpbiBleHRlbmRzIFBsdWdpbiB7XHJcblx0c2V0dGluZ3MhOiBIb21lQmFzZVNldHRpbmdzO1xyXG5cclxuXHQvLyBTZXJ2aWNlc1xyXG5cdGhvbWVTZXJ2aWNlITogSG9tZUJhc2VTZXJ2aWNlO1xyXG5cdG5ld1RhYlNlcnZpY2UhOiBOZXdUYWJTZXJ2aWNlO1xyXG5cdHN0aWNreVRhYlNlcnZpY2UhOiBTdGlja3lUYWJTZXJ2aWNlO1xyXG5cdG1vYmlsZUJ1dHRvblNlcnZpY2UhOiBNb2JpbGVCdXR0b25TZXJ2aWNlO1xyXG5cclxuXHQvLyBSZWxlYXNlIG5vdGVzIHRyYWNraW5nXHJcblx0cHJpdmF0ZSBuZXdSZWxlYXNlOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG5cdC8vIFRyYWNrIGlmIHBhdGNoZWQgb3BlbmluZyBiZWhhdmlvciBhbHJlYWR5IHJhblxyXG5cdHByaXZhdGUgb3BlbmluZ0JlaGF2aW9yUmFuOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG5cdC8vIFRyYWNrIGlmIHdlJ3JlIGN1cnJlbnRseSBpbiBzdGFydHVwICh0byBwcmV2ZW50IGhhbmRsZU9wZW5XaGVuRW1wdHkgZnJvbSBmaXJpbmcpXHJcblx0cHJpdmF0ZSBpc1N0YXJ0dXA6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuXHRhc3luYyBvbmxvYWQoKTogUHJvbWlzZTx2b2lkPiB7XHJcblx0XHRhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xyXG5cclxuXHRcdC8vIE1pZ3JhdGUgbGVnYWN5IHNldHRpbmdzIG9uIGZpcnN0IGxvYWRcclxuXHRcdGF3YWl0IG1pZ3JhdGVMZWdhY3lTZXR0aW5ncyh0aGlzKTtcclxuXHJcblx0XHQvLyBQYXRjaCBvcGVuaW5nIGJlaGF2aW9yIGZvciBmYXN0IHN0YXJ0dXAgKGJlZm9yZSBvdGhlciBpbml0aWFsaXphdGlvbilcclxuXHRcdHRoaXMucGF0Y2hPcGVuaW5nQmVoYXZpb3IoKTtcclxuXHJcblx0XHQvLyBSZWdpc3RlciBjdXN0b20gaWNvblxyXG5cdFx0YWRkSWNvbignaG9tZS1iYXNlJywgSE9NRV9JQ09OKTtcclxuXHJcblx0XHQvLyBJbml0aWFsaXplIHNlcnZpY2VzXHJcblx0XHR0aGlzLmhvbWVTZXJ2aWNlID0gbmV3IEhvbWVCYXNlU2VydmljZSh0aGlzKTtcclxuXHRcdHRoaXMubmV3VGFiU2VydmljZSA9IG5ldyBOZXdUYWJTZXJ2aWNlKHRoaXMpO1xyXG5cdFx0dGhpcy5zdGlja3lUYWJTZXJ2aWNlID0gbmV3IFN0aWNreVRhYlNlcnZpY2UodGhpcyk7XHJcblx0XHR0aGlzLm1vYmlsZUJ1dHRvblNlcnZpY2UgPSBuZXcgTW9iaWxlQnV0dG9uU2VydmljZSh0aGlzKTtcclxuXHJcblx0XHQvLyBBZGQgcmliYm9uIGljb25cclxuXHRcdHRoaXMuYWRkUmliYm9uSWNvbignaG9tZScsICdPcGVuIGhvbWUgYmFzZScsICgpID0+IHtcclxuXHRcdFx0dm9pZCB0aGlzLmhvbWVTZXJ2aWNlLm9wZW5Ib21lQmFzZSh7XHJcblx0XHRcdFx0cmVwbGFjZUFjdGl2ZUxlYWY6IGZhbHNlLFxyXG5cdFx0XHRcdHJ1bkNvbW1hbmQ6IHRydWUsXHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gUmVnaXN0ZXIgY29tbWFuZHNcclxuXHRcdHRoaXMucmVnaXN0ZXJDb21tYW5kcygpO1xyXG5cclxuXHRcdC8vIEFkZCBzZXR0aW5ncyB0YWJcclxuXHRcdHRoaXMuYWRkU2V0dGluZ1RhYihuZXcgSG9tZUJhc2VTZXR0aW5nVGFiKHRoaXMuYXBwLCB0aGlzKSk7XHJcblxyXG5cdFx0Ly8gV2FpdCBmb3IgbGF5b3V0IHRvIGJlIHJlYWR5XHJcblx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uub25MYXlvdXRSZWFkeSgoKSA9PiB7XHJcblx0XHRcdC8vIFVzZSBhIHNtYWxsIGRlbGF5IHRvIGVuc3VyZSBET00gaXMgcmVhZHkgKGVzcGVjaWFsbHkgZm9yIHNldHRpbmdzIG1vZGFsIGRldGVjdGlvbilcclxuXHRcdFx0c2V0VGltZW91dCgoKSA9PiB7XHJcblx0XHRcdFx0Ly8gQ2hlY2sgaWYgc2V0dGluZ3MgbW9kYWwgaXMgb3BlbiAtIGlmIHNvLCBza2lwIHN0YXJ0dXAgbG9naWNcclxuXHRcdFx0XHRpZiAodGhpcy5pc1NldHRpbmdzTW9kYWxPcGVuKCkpIHtcclxuXHRcdFx0XHRcdC8vIFN0aWxsIHVwZGF0ZSBVSSBmZWF0dXJlcywganVzdCBkb24ndCBydW4gc3RhcnR1cCBsb2dpY1xyXG5cdFx0XHRcdFx0dGhpcy51cGRhdGVTdGlja3lUYWJJY29uKCk7XHJcblx0XHRcdFx0XHR0aGlzLnVwZGF0ZU1vYmlsZUJ1dHRvbigpO1xyXG5cdFx0XHRcdFx0dGhpcy5zdGlja3lUYWJTZXJ2aWNlLnVwZGF0ZVRhYkhlYWRlcnMoKTtcclxuXHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIEFsd2F5cyBpbml0aWFsaXplIHRoZSBuZXcgdGFiIHNlcnZpY2UgdG8gdHJhY2sgZXhpc3RpbmcgbGVhdmVzXHJcblx0XHRcdFx0Ly8gVGhpcyBpcyBuZWVkZWQgZm9yIG5ldyB0YWIgcmVwbGFjZW1lbnQgdG8gd29ya1xyXG5cdFx0XHRcdC8vIEJ1dCBvbmx5IHJ1biBzdGFydHVwIGxvZ2ljIGlmIG9wZW5pbmcgYmVoYXZpb3IgZGlkbid0IGFscmVhZHkgcnVuXHJcblx0XHRcdFx0aWYgKCF0aGlzLm9wZW5pbmdCZWhhdmlvclJhbikge1xyXG5cdFx0XHRcdFx0Ly8gT3BlbmluZyBiZWhhdmlvciBkaWRuJ3QgcnVuLCBzbyBpbml0aWFsaXplIG5vcm1hbGx5IChpbmNsdWRlcyBzdGFydHVwKVxyXG5cdFx0XHRcdFx0dGhpcy5uZXdUYWJTZXJ2aWNlLmluaXRpYWxpemUoKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0Ly8gT3BlbmluZyBiZWhhdmlvciBhbHJlYWR5IHJhbiwgYnV0IHdlIHN0aWxsIG5lZWQgdG8gdHJhY2sgZXhpc3RpbmcgbGVhdmVzXHJcblx0XHRcdFx0XHQvLyBmb3IgbmV3IHRhYiByZXBsYWNlbWVudCB0byB3b3JrXHJcblx0XHRcdFx0XHR0aGlzLm5ld1RhYlNlcnZpY2UudHJhY2tFeGlzdGluZ0xlYXZlcygpO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gUmVzdG9yZSBnaG9zdCBsZWF2ZXMgZnJvbSBwcmV2aW91cyBzZXNzaW9uIGJlZm9yZSB1cGRhdGluZyBVSVxyXG5cdFx0XHRcdHRoaXMuaG9tZVNlcnZpY2UucmVzdG9yZUdob3N0TGVhdmVzKCk7XHJcblxyXG5cdFx0XHRcdC8vIE1hcmsgc3RhcnR1cCBhcyBjb21wbGV0ZSBhZnRlciBhIGRlbGF5IHRvIGFsbG93IGV2ZXJ5dGhpbmcgdG8gc2V0dGxlXHJcblx0XHRcdFx0c2V0VGltZW91dCgoKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLmlzU3RhcnR1cCA9IGZhbHNlO1xyXG5cdFx0XHRcdH0sIFNUQVJUVVBfQ09NUExFVEVfREVMQVkpO1xyXG5cclxuXHRcdFx0XHQvLyBVcGRhdGUgVUkgZmVhdHVyZXNcclxuXHRcdFx0XHR0aGlzLnVwZGF0ZVN0aWNreVRhYkljb24oKTtcclxuXHRcdFx0XHR0aGlzLnVwZGF0ZU1vYmlsZUJ1dHRvbigpO1xyXG5cclxuXHRcdFx0XHQvLyBVcGRhdGUgdGFiIGhlYWRlcnMgYWZ0ZXIgbGF5b3V0IGlzIHJlYWR5XHJcblx0XHRcdFx0dGhpcy5zdGlja3lUYWJTZXJ2aWNlLnVwZGF0ZVRhYkhlYWRlcnMoKTtcclxuXHRcdFx0fSwgRE9NX1JFQURZX0RFTEFZKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vIFJlZ2lzdGVyIGxheW91dCBjaGFuZ2UgaGFuZGxlclxyXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KFxyXG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uub24oJ2xheW91dC1jaGFuZ2UnLCBhc3luYyAoKSA9PiB7XHJcblx0XHRcdFx0dGhpcy5uZXdUYWJTZXJ2aWNlLmhhbmRsZUxheW91dENoYW5nZSgpO1xyXG5cdFx0XHRcdC8vIEhhbmRsZSByZXZlcnQgdmlldyBvbiBjbG9zZVxyXG5cdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLnJldmVydFZpZXcpIHtcclxuXHRcdFx0XHRcdGF3YWl0IHRoaXMuaG9tZVNlcnZpY2UucmV2ZXJ0VmlldygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHQvLyBcIk9wZW4gd2hlbiBlbXB0eVwiIGZlYXR1cmUgcmVtb3ZlZCAtIHVzZSBcIk5ldyB0YWIgcmVwbGFjZW1lbnQ6IG9ubHkgd2hlbiBlbXB0eVwiIGluc3RlYWRcclxuXHRcdFx0XHQvLyBUaGV5IGRvIHRoZSBzYW1lIHRoaW5nIHNpbmNlIE9ic2lkaWFuIGF1dG8tY3JlYXRlcyBhbiBlbXB0eSB0YWIgd2hlbiB5b3UgY2xvc2UgdGhlIGxhc3Qgb25lXHJcblx0XHRcdFx0Ly8gRGVsYXkgdGFiIGhlYWRlciB1cGRhdGVzIHRvIGF2b2lkIGZsaWNrZXJpbmcgZHVyaW5nIHRhYiB0cmFuc2l0aW9uc1xyXG5cdFx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xyXG5cdFx0XHRcdFx0dGhpcy5zdGlja3lUYWJTZXJ2aWNlLnVwZGF0ZUFjdGl2ZVN0YXRlKCk7XHJcblx0XHRcdFx0XHR0aGlzLnN0aWNreVRhYlNlcnZpY2UudXBkYXRlVGFiSGVhZGVycygpO1xyXG5cdFx0XHRcdFx0Ly8gQWxzbyB1cGRhdGUgaWNvbiBwb3NpdGlvbiBpbiBjYXNlIHNpZGViYXIgc3RhdGUgY2hhbmdlZFxyXG5cdFx0XHRcdFx0dGhpcy5zdGlja3lUYWJTZXJ2aWNlLnVwZGF0ZUljb25Qb3NpdGlvbkZvclNpZGViYXIoKTtcclxuXHRcdFx0XHR9LCBUQUJfSEVBREVSX1VQREFURV9ERUxBWSk7XHJcblx0XHRcdH0pXHJcblx0XHQpO1xyXG5cclxuXHRcdC8vIFJlZ2lzdGVyIGZpbGUgb3BlbiBoYW5kbGVyIGZvciBhY3RpdmUgc3RhdGUgdXBkYXRlc1xyXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KFxyXG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uub24oJ2ZpbGUtb3BlbicsICgpID0+IHtcclxuXHRcdFx0XHQvLyBEZWxheSB1cGRhdGVzIHRvIGxldCBmaWxlIG9wZW4gYW5pbWF0aW9uIGNvbXBsZXRlXHJcblx0XHRcdFx0c2V0VGltZW91dCgoKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLnN0aWNreVRhYlNlcnZpY2UudXBkYXRlQWN0aXZlU3RhdGUoKTtcclxuXHRcdFx0XHRcdHRoaXMuc3RpY2t5VGFiU2VydmljZS51cGRhdGVUYWJIZWFkZXJzKCk7XHJcblx0XHRcdFx0fSwgRklMRV9PUEVOX0FOSU1BVElPTl9ERUxBWSk7XHJcblx0XHRcdH0pXHJcblx0XHQpO1xyXG5cclxuXHRcdC8vIFJlZ2lzdGVyIGFjdGl2ZSBsZWFmIGNoYW5nZSBoYW5kbGVyIGZvciB0YWIgaGVhZGVyIHVwZGF0ZXNcclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudChcclxuXHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLm9uKCdhY3RpdmUtbGVhZi1jaGFuZ2UnLCAoKSA9PiB7XHJcblx0XHRcdFx0Ly8gRGVsYXkgdG8gbGV0IHRhYiBzd2l0Y2ggYW5pbWF0aW9uIGNvbXBsZXRlXHJcblx0XHRcdFx0c2V0VGltZW91dCgoKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLnN0aWNreVRhYlNlcnZpY2UudXBkYXRlVGFiSGVhZGVycygpO1xyXG5cdFx0XHRcdH0sIFRBQl9TV0lUQ0hfQU5JTUFUSU9OX0RFTEFZKTtcclxuXHRcdFx0fSlcclxuXHRcdCk7XHJcblxyXG5cdH1cclxuXHJcblx0b251bmxvYWQoKTogdm9pZCB7XHJcblx0XHQvLyBVbnBhdGNoIHJlbGVhc2Ugbm90ZXNcclxuXHRcdHRoaXMudW5wYXRjaFJlbGVhc2VOb3RlcygpO1xyXG5cclxuXHRcdC8vIFVucGF0Y2ggb3BlbmluZyBiZWhhdmlvclxyXG5cdFx0dGhpcy51bnBhdGNoT3BlbmluZ0JlaGF2aW9yKCk7XHJcblxyXG5cdFx0Ly8gQ2xlYW4gdXAgc2VydmljZXNcclxuXHRcdHRoaXMuc3RpY2t5VGFiU2VydmljZS5yZW1vdmUoKTtcclxuXHRcdHRoaXMubW9iaWxlQnV0dG9uU2VydmljZS5yZW1vdmUoKTtcclxuXHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZWdpc3RlciBwbHVnaW4gY29tbWFuZHNcclxuXHQgKi9cclxuXHRwcml2YXRlIHJlZ2lzdGVyQ29tbWFuZHMoKTogdm9pZCB7XHJcblx0XHQvLyBPcGVuIGhvbWUgYmFzZVxyXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcclxuXHRcdFx0aWQ6ICdvcGVuJyxcclxuXHRcdFx0bmFtZTogJ09wZW4nLFxyXG5cdFx0XHRjYWxsYmFjazogKCkgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IGhvbWVCYXNlU2V0dGluZ3MgPSB0aGlzLmdldEhvbWVCYXNlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRpZiAoIWhvbWVCYXNlU2V0dGluZ3MudmFsdWUgJiYgaG9tZUJhc2VTZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuRmlsZSkge1xyXG5cdFx0XHRcdFx0bmV3IE5vdGljZSgnTm8gaG9tZSBiYXNlIGNvbmZpZ3VyZWQuIFNldCBvbmUgaW4gc2V0dGluZ3MuJyk7XHJcblx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHZvaWQgdGhpcy5ob21lU2VydmljZS5vcGVuSG9tZUJhc2Uoe1xyXG5cdFx0XHRcdFx0cmVwbGFjZUFjdGl2ZUxlYWY6IGZhbHNlLFxyXG5cdFx0XHRcdFx0cnVuQ29tbWFuZDogdHJ1ZSxcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fSxcclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vIFNldCBjdXJyZW50IGZpbGUgYXMgaG9tZSBiYXNlXHJcblx0XHR0aGlzLmFkZENvbW1hbmQoe1xyXG5cdFx0XHRpZDogJ3NldC1jdXJyZW50LWZpbGUnLFxyXG5cdFx0XHRuYW1lOiAnU2V0IGN1cnJlbnQgZmlsZSBhcyBob21lJyxcclxuXHRcdFx0Y2hlY2tDYWxsYmFjazogKGNoZWNraW5nKSA9PiB7XHJcblx0XHRcdFx0aWYgKCF0aGlzLmhvbWVTZXJ2aWNlLmNhblNldEFjdGl2ZUZpbGVBc0hvbWVCYXNlKCkpIHtcclxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYgKCFjaGVja2luZykge1xyXG5cdFx0XHRcdFx0dm9pZCB0aGlzLmhvbWVTZXJ2aWNlLnNldEFjdGl2ZUZpbGVBc0hvbWVCYXNlKCkudGhlbigoc3VjY2VzcykgPT4ge1xyXG5cdFx0XHRcdFx0XHRpZiAoc3VjY2Vzcykge1xyXG5cdFx0XHRcdFx0XHRcdGNvbnN0IGFjdGl2ZUZpbGUgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpO1xyXG5cdFx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoYEhvbWUgYmFzZSBzZXQgdG8gXCIke2FjdGl2ZUZpbGU/Lm5hbWV9XCJgKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9LFxyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gVG9nZ2xlIHN0aWNreSBob21lIGljb25cclxuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XHJcblx0XHRcdGlkOiAndG9nZ2xlLXN0aWNreS1pY29uJyxcclxuXHRcdFx0bmFtZTogJ1RvZ2dsZSBzdGlja3kgaG9tZSBpY29uJyxcclxuXHRcdFx0Y2FsbGJhY2s6IGFzeW5jICgpID0+IHtcclxuXHRcdFx0XHRhd2FpdCB0aGlzLnN0aWNreVRhYlNlcnZpY2UudG9nZ2xlKCk7XHJcblx0XHRcdFx0Y29uc3Qgc3RhdGUgPSB0aGlzLnNldHRpbmdzLnNob3dTdGlja3lIb21lSWNvbiA/ICdlbmFibGVkJyA6ICdkaXNhYmxlZCc7XHJcblx0XHRcdFx0bmV3IE5vdGljZShgU3RpY2t5IGhvbWUgaWNvbiAke3N0YXRlfWApO1xyXG5cdFx0XHR9LFxyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gQ2xvc2UgaG9tZSBiYXNlXHJcblx0XHR0aGlzLmFkZENvbW1hbmQoe1xyXG5cdFx0XHRpZDogJ2Nsb3NlJyxcclxuXHRcdFx0bmFtZTogJ0Nsb3NlJyxcclxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHtcclxuXHRcdFx0XHR0aGlzLnN0aWNreVRhYlNlcnZpY2UuY2xvc2VIb21lQmFzZSgpO1xyXG5cdFx0XHR9LFxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBMb2FkIHBsdWdpbiBzZXR0aW5nc1xyXG5cdCAqL1xyXG5cdGFzeW5jIGxvYWRTZXR0aW5ncygpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHRcdGNvbnN0IGRhdGEgPSAoYXdhaXQgdGhpcy5sb2FkRGF0YSgpKSBhcyBQYXJ0aWFsPEhvbWVCYXNlU2V0dGluZ3M+IHwgbnVsbDtcclxuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBkYXRhID8/IHt9KTtcclxuXHR9XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgdGhlIGFjdGl2ZSBob21lIGJhc2Ugc2V0dGluZ3MgKG1vYmlsZSBvciBkZXNrdG9wKVxyXG5cdCAqL1xyXG5cdGdldEhvbWVCYXNlU2V0dGluZ3MoKToge1xyXG5cdFx0dHlwZTogSG9tZUJhc2VUeXBlO1xyXG5cdFx0dmFsdWU6IHN0cmluZztcclxuXHR9IHtcclxuXHRcdGlmICh0aGlzLnNldHRpbmdzLnNlcGFyYXRlTW9iaWxlICYmIFBsYXRmb3JtLmlzTW9iaWxlKSB7XHJcblx0XHRcdHJldHVybiB7XHJcblx0XHRcdFx0dHlwZTogdGhpcy5zZXR0aW5ncy5tb2JpbGVIb21lQmFzZVR5cGUgfHwgSG9tZUJhc2VUeXBlLkZpbGUsXHJcblx0XHRcdFx0dmFsdWU6IHRoaXMuc2V0dGluZ3MubW9iaWxlSG9tZUJhc2VWYWx1ZSB8fCAnJyxcclxuXHRcdFx0fTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHR0eXBlOiB0aGlzLnNldHRpbmdzLmhvbWVCYXNlVHlwZSB8fCBIb21lQmFzZVR5cGUuRmlsZSxcclxuXHRcdFx0dmFsdWU6IHRoaXMuc2V0dGluZ3MuaG9tZUJhc2VWYWx1ZSB8fCAnJyxcclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgdGhlIGFjdGl2ZSBuZXcgdGFiIHNldHRpbmdzIChtb2JpbGUgb3IgZGVza3RvcClcclxuXHQgKiBGYWxscyBiYWNrIHRvIGhvbWUgYmFzZSBzZXR0aW5ncyBpZiB1c2VEaWZmZXJlbnRGaWxlRm9yTmV3VGFiIGlzIGRpc2FibGVkXHJcblx0ICovXHJcblx0Z2V0TmV3VGFiU2V0dGluZ3MoKToge1xyXG5cdFx0dHlwZTogSG9tZUJhc2VUeXBlO1xyXG5cdFx0dmFsdWU6IHN0cmluZztcclxuXHR9IHtcclxuXHRcdC8vIElmIG5vdCB1c2luZyBkaWZmZXJlbnQgZmlsZSBmb3IgbmV3IHRhYiwgZmFsbCBiYWNrIHRvIGhvbWUgYmFzZSBzZXR0aW5nc1xyXG5cdFx0aWYgKCF0aGlzLnNldHRpbmdzLnVzZURpZmZlcmVudEZpbGVGb3JOZXdUYWIpIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMuZ2V0SG9tZUJhc2VTZXR0aW5ncygpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFVzZSBuZXcgdGFiIHNldHRpbmdzLCBjaGVja2luZyBmb3IgbW9iaWxlIGlmIHNlcGFyYXRlIG1vYmlsZSBpcyBlbmFibGVkXHJcblx0XHRpZiAodGhpcy5zZXR0aW5ncy5uZXdUYWJTZXBhcmF0ZU1vYmlsZSAmJiBQbGF0Zm9ybS5pc01vYmlsZSkge1xyXG5cdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdHR5cGU6IHRoaXMuc2V0dGluZ3MubW9iaWxlTmV3VGFiVHlwZSB8fCBIb21lQmFzZVR5cGUuRmlsZSxcclxuXHRcdFx0XHR2YWx1ZTogdGhpcy5zZXR0aW5ncy5tb2JpbGVOZXdUYWJWYWx1ZSB8fCAnJyxcclxuXHRcdFx0fTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHR0eXBlOiB0aGlzLnNldHRpbmdzLm5ld1RhYlR5cGUgfHwgSG9tZUJhc2VUeXBlLkZpbGUsXHJcblx0XHRcdHZhbHVlOiB0aGlzLnNldHRpbmdzLm5ld1RhYlZhbHVlIHx8ICcnLFxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIFNhdmUgcGx1Z2luIHNldHRpbmdzXHJcblx0ICovXHJcblx0YXN5bmMgc2F2ZVNldHRpbmdzKCk6IFByb21pc2U8dm9pZD4ge1xyXG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIFVwZGF0ZSB0aGUgc3RpY2t5IHRhYiBpY29uIGJhc2VkIG9uIGN1cnJlbnQgc2V0dGluZ3NcclxuXHQgKi9cclxuXHR1cGRhdGVTdGlja3lUYWJJY29uKCk6IHZvaWQge1xyXG5cdFx0dGhpcy5zdGlja3lUYWJTZXJ2aWNlLnVwZGF0ZSgpO1xyXG5cdFx0Ly8gQWxzbyB1cGRhdGUgdGFiIGhlYWRlcnMgd2hlbiBzdGlja3kgaWNvbiBzZXR0aW5nIGNoYW5nZXNcclxuXHRcdHRoaXMuc3RpY2t5VGFiU2VydmljZS51cGRhdGVUYWJIZWFkZXJzKCk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBVcGRhdGUgdGhlIG1vYmlsZSBidXR0b24gYmFzZWQgb24gY3VycmVudCBzZXR0aW5nc1xyXG5cdCAqL1xyXG5cdHVwZGF0ZU1vYmlsZUJ1dHRvbigpOiB2b2lkIHtcclxuXHRcdHRoaXMubW9iaWxlQnV0dG9uU2VydmljZS51cGRhdGUoKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENoZWNrIGlmIHdlIHNob3VsZCBza2lwIHN0YXJ0dXAgbG9naWMgKGUuZy4sIHBsdWdpbiByZWxvYWQsIHNldHRpbmdzIG1vZGFsIG9wZW4pXHJcblx0ICogVGhpcyBwcmV2ZW50cyBkZXN0cnVjdGl2ZSBiZWhhdmlvciB3aGVuIHRoZSBwbHVnaW4gaXMgcmVsb2FkZWQgb3Igc2V0dGluZ3MgYXJlIG9wZW5cclxuXHQgKi9cclxuXHRwcml2YXRlIHNob3VsZFNraXBTdGFydHVwTG9naWMoKTogYm9vbGVhbiB7XHJcblx0XHQvLyBDaGVjayBpZiBzZXR0aW5ncyBtb2RhbCBpcyBvcGVuIC0gbmV2ZXIgcnVuIHN0YXJ0dXAgbG9naWMgaWYgaXQgaXNcclxuXHRcdGlmICh0aGlzLmlzU2V0dGluZ3NNb2RhbE9wZW4oKSkge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDaGVjayBpZiB0aGlzIGlzIGEgcGx1Z2luIHJlbG9hZCB2cyBhY3R1YWwgYXBwIHN0YXJ0dXBcclxuXHRcdC8vIE9uIGFjdHVhbCBzdGFydHVwLCBPYnNpZGlhbiBoYXNuJ3QgcmVzdG9yZWQgdGhlIHdvcmtzcGFjZSB5ZXRcclxuXHRcdC8vIE9uIHBsdWdpbiByZWxvYWQsIGZpbGVzIGFyZSBhbHJlYWR5IG9wZW4gYW5kIHdvcmtzcGFjZSBpcyByZXN0b3JlZFxyXG5cdFx0Y29uc3QgaGFzT3BlbkZpbGVzID0gdGhpcy5hcHAud29ya3NwYWNlLmdldExlYXZlc09mVHlwZSgnbWFya2Rvd24nKS5sZW5ndGggPiAwIHx8XHJcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUoJ2NhbnZhcycpLmxlbmd0aCA+IDAgfHxcclxuXHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLmdldExlYXZlc09mVHlwZSgnYmFzZXMnKS5sZW5ndGggPiAwIHx8XHJcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUoJ2VtcHR5JykubGVuZ3RoID4gMDtcclxuXHJcblx0XHQvLyBJZiBmaWxlcyBhcmUgb3BlbiwgdGhpcyBpcyBsaWtlbHkgYSBwbHVnaW4gcmVsb2FkLCBub3QgYWN0dWFsIHN0YXJ0dXBcclxuXHRcdHJldHVybiBoYXNPcGVuRmlsZXM7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBDaGVjayBpZiB0aGUgc2V0dGluZ3MgbW9kYWwgaXMgY3VycmVudGx5IG9wZW5cclxuXHQgKi9cclxuXHRwcml2YXRlIGlzU2V0dGluZ3NNb2RhbE9wZW4oKTogYm9vbGVhbiB7XHJcblx0XHQvLyBDaGVjayBmb3Igc2V0dGluZ3MgbW9kYWwgYnkgbG9va2luZyBmb3IgdGhlIG1vZGFsIGNvbnRhaW5lclxyXG5cdFx0Ly8gVHJ5IG11bHRpcGxlIHNlbGVjdG9ycyB0byBiZSBtb3JlIHJvYnVzdFxyXG5cdFx0Y29uc3Qgc2V0dGluZ3NNb2RhbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tb2RhbC1jb250YWluZXIubW9kLXNldHRpbmdzJykgfHxcclxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vZGFsLm1vZC1zZXR0aW5ncycpIHx8XHJcblx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy52ZXJ0aWNhbC10YWItY29udGVudCcpO1xyXG5cclxuXHRcdC8vIEFsc28gY2hlY2sgaWYgYW55IG1vZGFsIGlzIG9wZW4gYW5kIGNvbnRhaW5zIHNldHRpbmdzIGNvbnRlbnRcclxuXHRcdGlmICghc2V0dGluZ3NNb2RhbCkge1xyXG5cdFx0XHRjb25zdCBhbGxNb2RhbHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcubW9kYWwtY29udGFpbmVyJyk7XHJcblx0XHRcdGZvciAoY29uc3QgbW9kYWwgb2YgQXJyYXkuZnJvbShhbGxNb2RhbHMpKSB7XHJcblx0XHRcdFx0aWYgKG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJy52ZXJ0aWNhbC10YWItY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRtb2RhbC5xdWVyeVNlbGVjdG9yKCcuc2V0dGluZ3MtY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRtb2RhbC5jbGFzc0xpc3QuY29udGFpbnMoJ21vZC1zZXR0aW5ncycpKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gc2V0dGluZ3NNb2RhbCAhPT0gbnVsbDtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIFBhdGNoIHJ1bk9wZW5pbmdCZWhhdmlvciBmb3IgZmFzdCBzdGFydHVwIChsaWtlIGhvbWVwYWdlIHBsdWdpbilcclxuXHQgKi9cclxuXHRwcml2YXRlIHBhdGNoT3BlbmluZ0JlaGF2aW9yKCk6IHZvaWQge1xyXG5cdFx0dHJ5IHtcclxuXHRcdFx0Ly8gU3RvcmUgb3JpZ2luYWwgbWV0aG9kXHJcblx0XHRcdHRoaXMuYXBwLm52T3JpZ19ydW5PcGVuaW5nQmVoYXZpb3IgPSB0aGlzLmFwcC5ydW5PcGVuaW5nQmVoYXZpb3I7XHJcblxyXG5cdFx0XHQvLyBQYXRjaCB0aGUgbWV0aG9kXHJcblx0XHRcdHRoaXMuYXBwLnJ1bk9wZW5pbmdCZWhhdmlvciA9IGFzeW5jIChwYXRoOiBzdHJpbmcpID0+IHtcclxuXHRcdFx0XHRjb25zdCBvcGVuSW5pdGlhbGx5ID0gKFxyXG5cdFx0XHRcdFx0dGhpcy5zZXR0aW5ncy5vcGVuT25TdGFydHVwICYmXHJcblx0XHRcdFx0XHQhdGhpcy5oYXNVcmxQYXJhbXMoKVxyXG5cdFx0XHRcdCk7XHJcblxyXG5cdFx0XHRcdGlmIChvcGVuSW5pdGlhbGx5KSB7XHJcblx0XHRcdFx0XHQvLyBNYXJrIHRoYXQgd2UndmUgcnVuIG9wZW5pbmcgYmVoYXZpb3JcclxuXHRcdFx0XHRcdHRoaXMub3BlbmluZ0JlaGF2aW9yUmFuID0gdHJ1ZTtcclxuXHJcblx0XHRcdFx0XHQvLyBVc2UgZmFzdCBzdGFydHVwIC0gZGV0YWNoIGFsbCBsZWF2ZXMgYW5kIG9wZW4gaG9tZSBiYXNlXHJcblx0XHRcdFx0XHRjb25zdCBtb2RlID0gdGhpcy5zZXR0aW5ncy5vcGVuTW9kZTtcclxuXHRcdFx0XHRcdGlmIChtb2RlID09PSAncmVwbGFjZS1hbGwnKSB7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMuaG9tZVNlcnZpY2UuZGV0YWNoQWxsTGVhdmVzKCk7XHJcblx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0Ly8gVXNlIGdob3N0IHRhYiBpZiBzdGlja3kgaWNvbiBpcyBlbmFibGVkLCBvdGhlcndpc2UgdXNlIG5vcm1hbCBvcGVuXHJcblx0XHRcdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5zaG93U3RpY2t5SG9tZUljb24pIHtcclxuXHRcdFx0XHRcdFx0dm9pZCB0aGlzLmhvbWVTZXJ2aWNlLm9wZW5Ib21lQmFzZUluR2hvc3RUYWIoe1xyXG5cdFx0XHRcdFx0XHRcdHJ1bkNvbW1hbmQ6IHRydWUsXHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0dm9pZCB0aGlzLmhvbWVTZXJ2aWNlLm9wZW5Ib21lQmFzZVdpdGhNb2RlKG1vZGUsIHRydWUpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHQvLyBDYWxsIG9yaWdpbmFsIGJlaGF2aW9yXHJcblx0XHRcdFx0XHRpZiAodGhpcy5hcHAubnZPcmlnX3J1bk9wZW5pbmdCZWhhdmlvcikge1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLmFwcC5udk9yaWdfcnVuT3BlbmluZ0JlaGF2aW9yKHBhdGgpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gVW5wYXRjaCByZWxlYXNlIG5vdGVzIGFmdGVyIG9wZW5pbmcgYmVoYXZpb3IgY29tcGxldGVzXHJcblx0XHRcdFx0dGhpcy51bnBhdGNoUmVsZWFzZU5vdGVzKCk7XHJcblx0XHRcdH07XHJcblx0XHR9IGNhdGNoIChlKSB7XHJcblx0XHRcdGNvbnNvbGUud2FybignW0hvbWUgQmFzZV0gRmFpbGVkIHRvIHBhdGNoIG9wZW5pbmcgYmVoYXZpb3I6JywgZSk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBVbnBhdGNoIHJ1bk9wZW5pbmdCZWhhdmlvclxyXG5cdCAqL1xyXG5cdHByaXZhdGUgdW5wYXRjaE9wZW5pbmdCZWhhdmlvcigpOiB2b2lkIHtcclxuXHJcblx0XHRpZiAodGhpcy5hcHAubnZPcmlnX3J1bk9wZW5pbmdCZWhhdmlvcikge1xyXG5cclxuXHRcdFx0dGhpcy5hcHAucnVuT3BlbmluZ0JlaGF2aW9yID0gdGhpcy5hcHAubnZPcmlnX3J1bk9wZW5pbmdCZWhhdmlvcjtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIFBhdGNoIHNob3dSZWxlYXNlTm90ZXMgdG8gdHJhY2sgbmV3IHJlbGVhc2VzXHJcblx0ICovXHJcblx0cHJpdmF0ZSBwYXRjaFJlbGVhc2VOb3RlcygpOiB2b2lkIHtcclxuXHRcdHRyeSB7XHJcblx0XHRcdGNvbnN0IGFwcEFueSA9IHRoaXMuYXBwIGFzIHVua25vd24gYXMgQXBwV2l0aFJlbGVhc2VOb3RlcztcclxuXHRcdFx0YXBwQW55Lm52T3JpZ19zaG93UmVsZWFzZU5vdGVzID0gYXBwQW55LnNob3dSZWxlYXNlTm90ZXM7XHJcblx0XHRcdGFwcEFueS5zaG93UmVsZWFzZU5vdGVzID0gKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMubmV3UmVsZWFzZSA9IHRydWU7XHJcblx0XHRcdH07XHJcblx0XHR9IGNhdGNoIChlKSB7XHJcblx0XHRcdGNvbnNvbGUud2FybignW0hvbWUgQmFzZV0gRmFpbGVkIHRvIHBhdGNoIHJlbGVhc2Ugbm90ZXM6JywgZSk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBVbnBhdGNoIHNob3dSZWxlYXNlTm90ZXNcclxuXHQgKi9cclxuXHRwcml2YXRlIHVucGF0Y2hSZWxlYXNlTm90ZXMoKTogdm9pZCB7XHJcblx0XHRjb25zdCBhcHBBbnkgPSB0aGlzLmFwcCBhcyB1bmtub3duIGFzIEFwcFdpdGhSZWxlYXNlTm90ZXM7XHJcblxyXG5cdFx0aWYgKHRoaXMubmV3UmVsZWFzZSAmJiAhdGhpcy5zZXR0aW5ncy5oaWRlUmVsZWFzZU5vdGVzKSB7XHJcblxyXG5cdFx0XHRhcHBBbnkubnZPcmlnX3Nob3dSZWxlYXNlTm90ZXM/LigpO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0XHRpZiAoYXBwQW55Lm52T3JpZ19zaG93UmVsZWFzZU5vdGVzKSB7XHJcblxyXG5cdFx0XHRhcHBBbnkuc2hvd1JlbGVhc2VOb3RlcyA9IGFwcEFueS5udk9yaWdfc2hvd1JlbGVhc2VOb3RlcztcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENoZWNrIGlmIGEgaG9tZSBiYXNlIHR5cGUgaGFzIGl0cyByZXF1aXJlZCBwbHVnaW4gZW5hYmxlZFxyXG5cdCAqL1xyXG5cdGhhc1JlcXVpcmVkUGx1Z2luKHR5cGU6IEhvbWVCYXNlVHlwZSk6IGJvb2xlYW4ge1xyXG5cdFx0c3dpdGNoICh0eXBlKSB7XHJcblx0XHRcdGNhc2UgSG9tZUJhc2VUeXBlLldvcmtzcGFjZTpcclxuXHJcblx0XHRcdFx0cmV0dXJuIHRoaXMuYXBwLmludGVybmFsUGx1Z2lucz8ucGx1Z2lucz8ud29ya3NwYWNlcz8uZW5hYmxlZCA9PT0gdHJ1ZTtcclxuXHRcdFx0Y2FzZSBIb21lQmFzZVR5cGUuR3JhcGg6XHJcblxyXG5cdFx0XHRcdHJldHVybiB0aGlzLmFwcC5pbnRlcm5hbFBsdWdpbnM/LnBsdWdpbnM/LmdyYXBoPy5lbmFibGVkID09PSB0cnVlO1xyXG5cdFx0XHRjYXNlIEhvbWVCYXNlVHlwZS5Kb3VybmFsOlxyXG5cclxuXHRcdFx0XHRyZXR1cm4gISF0aGlzLmFwcC5wbHVnaW5zPy5wbHVnaW5zPy5bJ2pvdXJuYWxzJ107XHJcblx0XHRcdGNhc2UgSG9tZUJhc2VUeXBlLkRhaWx5Tm90ZTpcclxuXHRcdFx0Y2FzZSBIb21lQmFzZVR5cGUuV2Vla2x5Tm90ZTpcclxuXHRcdFx0Y2FzZSBIb21lQmFzZVR5cGUuTW9udGhseU5vdGU6XHJcblx0XHRcdGNhc2UgSG9tZUJhc2VUeXBlLlF1YXJ0ZXJseU5vdGU6XHJcblx0XHRcdGNhc2UgSG9tZUJhc2VUeXBlLlllYXJseU5vdGU6XHJcblx0XHRcdFx0cmV0dXJuIHRoaXMuaGFzUmVxdWlyZWRQZXJpb2RpY2l0eSh0eXBlKTtcclxuXHRcdFx0ZGVmYXVsdDpcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENoZWNrIGlmIHBlcmlvZGljIG5vdGVzIGFyZSBhdmFpbGFibGUgZm9yIHRoZSBnaXZlbiB0eXBlXHJcblx0ICovXHJcblx0cHJpdmF0ZSBoYXNSZXF1aXJlZFBlcmlvZGljaXR5KHR5cGU6IEhvbWVCYXNlVHlwZSk6IGJvb2xlYW4ge1xyXG5cdFx0aWYgKHR5cGUgPT09IEhvbWVCYXNlVHlwZS5EYWlseU5vdGUpIHtcclxuXHRcdFx0Ly8gRGFpbHkgbm90ZXMgY2FuIGNvbWUgZnJvbSBlaXRoZXIgY29yZSBwbHVnaW4gT1IgcGVyaW9kaWMgbm90ZXMgcGx1Z2luXHJcblx0XHRcdGNvbnN0IGNvcmVEYWlseU5vdGVzID0gdGhpcy5hcHAuaW50ZXJuYWxQbHVnaW5zPy5wbHVnaW5zPy5bJ2RhaWx5LW5vdGVzJ10/LmVuYWJsZWQgPT09IHRydWU7XHJcblx0XHRcdGlmIChjb3JlRGFpbHlOb3Rlcykge1xyXG5cdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHRcdC8vIENoZWNrIHBlcmlvZGljIG5vdGVzIHBsdWdpbiBmb3IgZGFpbHkgbm90ZSBzdXBwb3J0XHJcblx0XHRcdGNvbnN0IHBlcmlvZGljTm90ZXMgPSB0aGlzLmFwcC5wbHVnaW5zPy5wbHVnaW5zPy5bJ3BlcmlvZGljLW5vdGVzJ107XHJcblx0XHRcdGlmIChwZXJpb2RpY05vdGVzKSB7XHJcblx0XHRcdFx0Y29uc3QgdmVyc2lvbiA9IChwZXJpb2RpY05vdGVzIGFzIHsgbWFuaWZlc3Q/OiB7IHZlcnNpb24/OiBzdHJpbmcgfSB9KT8ubWFuaWZlc3Q/LnZlcnNpb24gfHwgJzAnO1xyXG5cdFx0XHRcdGNvbnN0IGlzTGVnYWN5ID0gdmVyc2lvbi5zdGFydHNXaXRoKCcwJyk7XHJcblxyXG5cdFx0XHRcdGlmIChpc0xlZ2FjeSkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIChwZXJpb2RpY05vdGVzIGFzIHsgc2V0dGluZ3M/OiBSZWNvcmQ8c3RyaW5nLCB7IGVuYWJsZWQ/OiBib29sZWFuIH0+IH0pPy5zZXR0aW5ncz8uWydkYWlseSddPy5lbmFibGVkID09PSB0cnVlO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRjb25zdCBjYWxlbmRhclNldCA9IChwZXJpb2RpY05vdGVzIGFzIHsgY2FsZW5kYXJTZXRNYW5hZ2VyPzogeyBnZXRBY3RpdmVTZXQ/OiAoKSA9PiBSZWNvcmQ8c3RyaW5nLCB7IGVuYWJsZWQ/OiBib29sZWFuIH0+IH0gfSk/LmNhbGVuZGFyU2V0TWFuYWdlcj8uZ2V0QWN0aXZlU2V0Py4oKTtcclxuXHRcdFx0XHRcdHJldHVybiBjYWxlbmRhclNldD8uWydkYXknXT8uZW5hYmxlZCA9PT0gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0XHRjb25zdCBwZXJpb2RpY05vdGVzID0gdGhpcy5hcHAucGx1Z2lucz8ucGx1Z2lucz8uWydwZXJpb2RpYy1ub3RlcyddO1xyXG5cdFx0aWYgKCFwZXJpb2RpY05vdGVzKSByZXR1cm4gZmFsc2U7XHJcblxyXG5cdFx0Ly8gQ2hlY2sgaWYgcGVyaW9kaWMgbm90ZXMgcGx1Z2luIGhhcyB0aGUgcmVxdWlyZWQgcGVyaW9kIGVuYWJsZWRcclxuXHJcblx0XHRjb25zdCB2ZXJzaW9uID0gKHBlcmlvZGljTm90ZXMgYXMgeyBtYW5pZmVzdD86IHsgdmVyc2lvbj86IHN0cmluZyB9IH0pPy5tYW5pZmVzdD8udmVyc2lvbiB8fCAnMCc7XHJcblx0XHRjb25zdCBpc0xlZ2FjeSA9IHZlcnNpb24uc3RhcnRzV2l0aCgnMCcpO1xyXG5cclxuXHRcdGlmIChpc0xlZ2FjeSkge1xyXG5cdFx0XHQvLyBMZWdhY3kgcGVyaW9kaWMgbm90ZXNcclxuXHRcdFx0Y29uc3QgcGVyaW9kTWFwOiBQYXJ0aWFsPFJlY29yZDxIb21lQmFzZVR5cGUsIHN0cmluZz4+ID0ge1xyXG5cdFx0XHRcdFtIb21lQmFzZVR5cGUuV2Vla2x5Tm90ZV06ICd3ZWVrbHknLFxyXG5cdFx0XHRcdFtIb21lQmFzZVR5cGUuTW9udGhseU5vdGVdOiAnbW9udGhseScsXHJcblx0XHRcdFx0W0hvbWVCYXNlVHlwZS5RdWFydGVybHlOb3RlXTogJ3F1YXJ0ZXJseScsXHJcblx0XHRcdFx0W0hvbWVCYXNlVHlwZS5ZZWFybHlOb3RlXTogJ3llYXJseScsXHJcblx0XHRcdH07XHJcblxyXG5cdFx0XHRjb25zdCBhZGplY3RpdmUgPSBwZXJpb2RNYXBbdHlwZV07XHJcblx0XHRcdGlmICghYWRqZWN0aXZlKSByZXR1cm4gZmFsc2U7XHJcblxyXG5cdFx0XHRyZXR1cm4gKHBlcmlvZGljTm90ZXMgYXMgeyBzZXR0aW5ncz86IFJlY29yZDxzdHJpbmcsIHsgZW5hYmxlZD86IGJvb2xlYW4gfT4gfSk/LnNldHRpbmdzPy5bYWRqZWN0aXZlXT8uZW5hYmxlZCA9PT0gdHJ1ZTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdC8vIE5ldyBwZXJpb2RpYyBub3Rlc1xyXG5cdFx0XHRjb25zdCBub3VuTWFwOiBQYXJ0aWFsPFJlY29yZDxIb21lQmFzZVR5cGUsIHN0cmluZz4+ID0ge1xyXG5cdFx0XHRcdFtIb21lQmFzZVR5cGUuV2Vla2x5Tm90ZV06ICd3ZWVrJyxcclxuXHRcdFx0XHRbSG9tZUJhc2VUeXBlLk1vbnRobHlOb3RlXTogJ21vbnRoJyxcclxuXHRcdFx0XHRbSG9tZUJhc2VUeXBlLlF1YXJ0ZXJseU5vdGVdOiAncXVhcnRlcicsXHJcblx0XHRcdFx0W0hvbWVCYXNlVHlwZS5ZZWFybHlOb3RlXTogJ3llYXInLFxyXG5cdFx0XHR9O1xyXG5cclxuXHRcdFx0Y29uc3Qgbm91biA9IG5vdW5NYXBbdHlwZV07XHJcblx0XHRcdGlmICghbm91bikgcmV0dXJuIGZhbHNlO1xyXG5cclxuXHRcdFx0Y29uc3QgY2FsZW5kYXJTZXQgPSAocGVyaW9kaWNOb3RlcyBhcyB7IGNhbGVuZGFyU2V0TWFuYWdlcj86IHsgZ2V0QWN0aXZlU2V0PzogKCkgPT4gUmVjb3JkPHN0cmluZywgeyBlbmFibGVkPzogYm9vbGVhbiB9PiB9IH0pPy5jYWxlbmRhclNldE1hbmFnZXI/LmdldEFjdGl2ZVNldD8uKCk7XHJcblxyXG5cdFx0XHRyZXR1cm4gY2FsZW5kYXJTZXQ/Lltub3VuXT8uZW5hYmxlZCA9PT0gdHJ1ZTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENoZWNrIGlmIFVSTCBwYXJhbXMgaW5kaWNhdGUgYSBmaWxlL3dvcmtzcGFjZSBzaG91bGQgYmUgb3BlbmVkIChza2lwIGhvbWVwYWdlKVxyXG5cdCAqL1xyXG5cdHByaXZhdGUgaGFzVXJsUGFyYW1zKCk6IGJvb2xlYW4ge1xyXG5cdFx0Ly8gQ2hlY2sgZm9yIFVSTCBwYXJhbXMgdGhhdCBpbmRpY2F0ZSBhIHNwZWNpZmljIGZpbGUvd29ya3NwYWNlIHNob3VsZCBiZSBvcGVuZWRcclxuXHRcdC8vIFRoaXMgcHJldmVudHMgaG9tZXBhZ2UgZnJvbSBvcGVuaW5nIHdoZW4gT2JzaWRpYW4gaXMgb3BlbmVkIHdpdGggYSBzcGVjaWZpYyBmaWxlXHJcblx0XHRpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Lk9CU19BQ1QpIHtcclxuXHRcdFx0Y29uc3QgcGFyYW1zID0gT2JqZWN0LmtleXMod2luZG93Lk9CU19BQ1QpO1xyXG5cdFx0XHRjb25zdCBhY3Rpb24gPSB3aW5kb3cuT0JTX0FDVC5hY3Rpb247XHJcblx0XHRcdHJldHVybiAoXHJcblx0XHRcdFx0YWN0aW9uICE9PSB1bmRlZmluZWQgJiZcclxuXHRcdFx0XHRbJ29wZW4nLCAnYWR2YW5jZWQtdXJpJ10uaW5jbHVkZXMoYWN0aW9uKSAmJlxyXG5cdFx0XHRcdFsnZmlsZScsICdmaWxlcGF0aCcsICd3b3Jrc3BhY2UnXS5zb21lKGUgPT4gcGFyYW1zLmluY2x1ZGVzKGUpKVxyXG5cdFx0XHQpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxuXHJcblx0Ly8gXCJPcGVuIHdoZW4gZW1wdHlcIiBmZWF0dXJlIHJlbW92ZWQgLSByZWR1bmRhbnQgd2l0aCBcIk5ldyB0YWIgcmVwbGFjZW1lbnQ6IG9ubHkgd2hlbiBlbXB0eVwiXHJcblx0Ly8gU2luY2UgT2JzaWRpYW4gYXV0by1jcmVhdGVzIGFuIGVtcHR5IHRhYiB3aGVuIHlvdSBjbG9zZSB0aGUgbGFzdCBvbmUsIHRoZXkgZG8gdGhlIHNhbWUgdGhpbmdcclxufVxyXG4iLCAiLyoqXHJcbiAqIEhvbWUgQmFzZSBQbHVnaW4gU2V0dGluZ3NcclxuICovXHJcblxyXG5leHBvcnQgdHlwZSBWaWV3TW9kZSA9ICdkZWZhdWx0JyB8ICdwcmV2aWV3JyB8ICdzb3VyY2UnIHwgJ2xpdmUnO1xyXG5leHBvcnQgdHlwZSBOZXdUYWJNb2RlID0gJ29ubHktd2hlbi1lbXB0eScgfCAnYWx3YXlzJztcclxuZXhwb3J0IHR5cGUgT3BlbmluZ01vZGUgPSAncmVwbGFjZS1hbGwnIHwgJ3JlcGxhY2UtbGFzdCcgfCAncmV0YWluJztcclxuXHJcbi8qKlxyXG4gKiBIb21lcGFnZSB0eXBlIGVudW0gLSBtYXRjaGVzIGhvbWVwYWdlIHBsdWdpbidzIEtpbmQgZW51bVxyXG4gKi9cclxuZXhwb3J0IGVudW0gSG9tZUJhc2VUeXBlIHtcclxuXHRGaWxlID0gJ0ZpbGUnLFxyXG5cdFdvcmtzcGFjZSA9ICdXb3Jrc3BhY2UnLFxyXG5cdFJhbmRvbSA9ICdSYW5kb20gZmlsZScsXHJcblx0UmFuZG9tRm9sZGVyID0gJ1JhbmRvbSBpbiBmb2xkZXInLFxyXG5cdEdyYXBoID0gJ0dyYXBoIHZpZXcnLFxyXG5cdE5vbmUgPSAnTm90aGluZycsXHJcblx0Sm91cm5hbCA9ICdKb3VybmFsJyxcclxuXHROZXdOb3RlID0gJ05ldyBub3RlJyxcclxuXHREYWlseU5vdGUgPSAnRGFpbHkgTm90ZScsXHJcblx0V2Vla2x5Tm90ZSA9ICdXZWVrbHkgTm90ZScsXHJcblx0TW9udGhseU5vdGUgPSAnTW9udGhseSBOb3RlJyxcclxuXHRRdWFydGVybHlOb3RlID0gJ1F1YXJ0ZXJseSBOb3RlJyxcclxuXHRZZWFybHlOb3RlID0gJ1llYXJseSBOb3RlJyxcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBIb21lQmFzZVNldHRpbmdzIHtcclxuXHQvLyBHZW5lcmFsXHJcblx0aG9tZUJhc2VUeXBlOiBIb21lQmFzZVR5cGU7XHJcblx0aG9tZUJhc2VWYWx1ZTogc3RyaW5nOyAvLyBUeXBlLXNwZWNpZmljIHZhbHVlIChmaWxlIHBhdGgsIHdvcmtzcGFjZSBuYW1lLCBmb2xkZXIgcGF0aCwgZXRjLilcclxuXHRvcGVuT25TdGFydHVwOiBib29sZWFuO1xyXG5cdG9wZW5WaWV3TW9kZTogVmlld01vZGU7XHJcblx0b3Blbk1vZGU6IE9wZW5pbmdNb2RlO1xyXG5cdG1hbnVhbE9wZW5Nb2RlOiBPcGVuaW5nTW9kZTtcclxuXHJcblx0Ly8gVGFiIEJlaGF2aW9yXHJcblx0cmVwbGFjZU5ld1RhYjogYm9vbGVhbjtcclxuXHRuZXdUYWJNb2RlOiBOZXdUYWJNb2RlO1xyXG5cdG9wZW5XaGVuQWxsVGFic0Nsb3NlZDogYm9vbGVhbjsgLy8gT3BlbiBob21lIGJhc2Ugd2hlbiBhbGwgdGFicyBhcmUgY2xvc2VkIChpbmRlcGVuZGVudCBvZiByZXBsYWNlTmV3VGFiKVxyXG5cdHVzZURpZmZlcmVudEZpbGVGb3JOZXdUYWI6IGJvb2xlYW47IC8vIFVzZSBzZXBhcmF0ZSBuZXcgdGFiIHNldHRpbmdzIHZzIGhvbWUgYmFzZVxyXG5cdG5ld1RhYlR5cGU6IEhvbWVCYXNlVHlwZTtcclxuXHRuZXdUYWJWYWx1ZTogc3RyaW5nO1xyXG5cdG5ld1RhYlNlcGFyYXRlTW9iaWxlOiBib29sZWFuO1xyXG5cdG1vYmlsZU5ld1RhYlR5cGU6IEhvbWVCYXNlVHlwZTtcclxuXHRtb2JpbGVOZXdUYWJWYWx1ZTogc3RyaW5nO1xyXG5cclxuXHQvLyBVSSBGZWF0dXJlcyAob2ZmIGJ5IGRlZmF1bHQpXHJcblx0c2hvd1N0aWNreUhvbWVJY29uOiBib29sZWFuO1xyXG5cdHN0aWNreUljb25OYW1lOiBzdHJpbmcgfCBudWxsO1xyXG5cdGhpZGVIb21lVGFiSGVhZGVyOiBib29sZWFuO1xyXG5cdHJlcGxhY2VNb2JpbGVOZXdUYWI6IGJvb2xlYW47XHJcblx0XHJcblx0Ly8gTW9iaWxlXHJcblx0c2VwYXJhdGVNb2JpbGU6IGJvb2xlYW47XHJcblx0bW9iaWxlSG9tZUJhc2VUeXBlOiBIb21lQmFzZVR5cGU7XHJcblx0bW9iaWxlSG9tZUJhc2VWYWx1ZTogc3RyaW5nO1xyXG5cclxuXHQvLyBBdXRvbWF0aW9uXHJcblx0Y29tbWFuZE9uT3Blbjogc3RyaW5nO1xyXG5cdHdhaXRGb3JHaXRTeW5jOiBib29sZWFuO1xyXG5cdGdpdFN5bmNUaW1lb3V0OiBudW1iZXI7XHJcblx0XHJcblx0Ly8gVmlldyBiZWhhdmlvclxyXG5cdHJldmVydFZpZXc6IGJvb2xlYW47XHJcblx0YXV0b1Njcm9sbDogYm9vbGVhbjtcclxuXHRoaWRlUmVsZWFzZU5vdGVzOiBib29sZWFuO1xyXG5cclxuXHQvLyBMZWdhY3kgLSBrZXB0IGluIHR5cGUgZm9yIG1pZ3JhdGlvbiBidXQgcmVtb3ZlZCBmcm9tIGRlZmF1bHRzXHJcblx0aG9tZUJhc2VQYXRoPzogc3RyaW5nO1xyXG5cdGtlZXBFeGlzdGluZ1RhYnM/OiBib29sZWFuO1xyXG5cdG1vYmlsZUhvbWVCYXNlUGF0aD86IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IERFRkFVTFRfU0VUVElOR1M6IEhvbWVCYXNlU2V0dGluZ3MgPSB7XHJcblx0Ly8gR2VuZXJhbFxyXG5cdGhvbWVCYXNlVHlwZTogSG9tZUJhc2VUeXBlLkZpbGUsXHJcblx0aG9tZUJhc2VWYWx1ZTogJycsXHJcblx0b3Blbk9uU3RhcnR1cDogdHJ1ZSxcclxuXHRvcGVuVmlld01vZGU6ICdkZWZhdWx0JyxcclxuXHRvcGVuTW9kZTogJ3JlcGxhY2UtYWxsJyxcclxuXHRtYW51YWxPcGVuTW9kZTogJ3JldGFpbicsXHJcblxyXG5cdC8vIFRhYiBCZWhhdmlvclxyXG5cdHJlcGxhY2VOZXdUYWI6IGZhbHNlLFxyXG5cdG5ld1RhYk1vZGU6ICdvbmx5LXdoZW4tZW1wdHknLCAvLyBEZWZhdWx0OiBvbmx5IHJlcGxhY2Ugd2hlbiBubyB0YWJzIGFyZSBvcGVuXHJcblx0b3BlbldoZW5BbGxUYWJzQ2xvc2VkOiB0cnVlLCAvLyBEZWZhdWx0OiBvcGVuIGhvbWUgYmFzZSB3aGVuIGFsbCB0YWJzIGFyZSBjbG9zZWRcclxuXHR1c2VEaWZmZXJlbnRGaWxlRm9yTmV3VGFiOiBmYWxzZSxcclxuXHRuZXdUYWJUeXBlOiBIb21lQmFzZVR5cGUuRmlsZSxcclxuXHRuZXdUYWJWYWx1ZTogJycsXHJcblx0bmV3VGFiU2VwYXJhdGVNb2JpbGU6IGZhbHNlLFxyXG5cdG1vYmlsZU5ld1RhYlR5cGU6IEhvbWVCYXNlVHlwZS5GaWxlLFxyXG5cdG1vYmlsZU5ld1RhYlZhbHVlOiAnJyxcclxuXHJcblx0Ly8gVUkgRmVhdHVyZXNcclxuXHRzaG93U3RpY2t5SG9tZUljb246IGZhbHNlLFxyXG5cdHN0aWNreUljb25OYW1lOiAnaG9tZScsXHJcblx0aGlkZUhvbWVUYWJIZWFkZXI6IGZhbHNlLFxyXG5cdHJlcGxhY2VNb2JpbGVOZXdUYWI6IGZhbHNlLFxyXG5cdFxyXG5cdC8vIE1vYmlsZVxyXG5cdHNlcGFyYXRlTW9iaWxlOiBmYWxzZSxcclxuXHRtb2JpbGVIb21lQmFzZVR5cGU6IEhvbWVCYXNlVHlwZS5GaWxlLFxyXG5cdG1vYmlsZUhvbWVCYXNlVmFsdWU6ICcnLFxyXG5cclxuXHQvLyBBdXRvbWF0aW9uXHJcblx0Y29tbWFuZE9uT3BlbjogJycsXHJcblx0d2FpdEZvckdpdFN5bmM6IGZhbHNlLFxyXG5cdGdpdFN5bmNUaW1lb3V0OiAzLCAvLyBEZWZhdWx0IDMgc2Vjb25kc1xyXG5cdFxyXG5cdC8vIFZpZXcgYmVoYXZpb3JcclxuXHRyZXZlcnRWaWV3OiBmYWxzZSxcclxuXHRhdXRvU2Nyb2xsOiBmYWxzZSxcclxuXHRoaWRlUmVsZWFzZU5vdGVzOiBmYWxzZSwgLy8gT0ZGIGJ5IGRlZmF1bHRcclxufTtcclxuXHJcbi8qKlxyXG4gKiBWaWV3IG1vZGUgZGlzcGxheSBuYW1lcyBmb3Igc2V0dGluZ3MgZHJvcGRvd25cclxuICovXHJcbmV4cG9ydCBjb25zdCBWSUVXX01PREVfT1BUSU9OUzogUmVjb3JkPFZpZXdNb2RlLCBzdHJpbmc+ID0ge1xyXG5cdCdkZWZhdWx0JzogJ0RlZmF1bHQnLFxyXG5cdCdwcmV2aWV3JzogJ1JlYWRpbmcgdmlldycsXHJcblx0J3NvdXJjZSc6ICdTb3VyY2UgbW9kZScsXHJcblx0J2xpdmUnOiAnTGl2ZSBQcmV2aWV3JyxcclxufTtcclxuXHJcbi8qKlxyXG4gKiBOZXcgdGFiIG1vZGUgZGlzcGxheSBuYW1lcyBmb3Igc2V0dGluZ3MgZHJvcGRvd25cclxuICovXHJcbmV4cG9ydCBjb25zdCBORVdfVEFCX01PREVfT1BUSU9OUzogUmVjb3JkPE5ld1RhYk1vZGUsIHN0cmluZz4gPSB7XHJcblx0J29ubHktd2hlbi1lbXB0eSc6ICdPbmx5IHdoZW4gbm8gdGFicyBhcmUgb3BlbicsXHJcblx0J2Fsd2F5cyc6ICdBbHdheXMgcmVwbGFjZSBuZXcgdGFicycsXHJcbn07XHJcblxyXG4vKipcclxuICogT3BlbmluZyBtb2RlIGRpc3BsYXkgbmFtZXMgZm9yIHNldHRpbmdzIGRyb3Bkb3duXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgT1BFTklOR19NT0RFX09QVElPTlM6IFJlY29yZDxPcGVuaW5nTW9kZSwgc3RyaW5nPiA9IHtcclxuXHQncmVwbGFjZS1hbGwnOiAnUmVwbGFjZSBhbGwgb3BlbiBub3RlcycsXHJcblx0J3JlcGxhY2UtbGFzdCc6ICdSZXBsYWNlIGxhc3Qgbm90ZScsXHJcblx0J3JldGFpbic6ICdLZWVwIG9wZW4gbm90ZXMnLFxyXG59O1xyXG5cclxuLyoqXHJcbiAqIEhvbWVwYWdlIHR5cGVzIHRoYXQgZG9uJ3QgcmVxdWlyZSBhIHZhbHVlIGlucHV0XHJcbiAqL1xyXG5leHBvcnQgY29uc3QgVU5DSEFOR0VBQkxFX1RZUEVTOiBIb21lQmFzZVR5cGVbXSA9IFtcclxuXHRIb21lQmFzZVR5cGUuUmFuZG9tLFxyXG5cdEhvbWVCYXNlVHlwZS5HcmFwaCxcclxuXHRIb21lQmFzZVR5cGUuTm9uZSxcclxuXHRIb21lQmFzZVR5cGUuRGFpbHlOb3RlLFxyXG5cdEhvbWVCYXNlVHlwZS5XZWVrbHlOb3RlLFxyXG5cdEhvbWVCYXNlVHlwZS5Nb250aGx5Tm90ZSxcclxuXHRIb21lQmFzZVR5cGUuUXVhcnRlcmx5Tm90ZSxcclxuXHRIb21lQmFzZVR5cGUuWWVhcmx5Tm90ZSxcclxuXTtcclxuIiwgIi8qKlxyXG4gKiBIb21lIEJhc2UgU2V0dGluZ3MgVGFiXHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgQXBwLCBQbHVnaW5TZXR0aW5nVGFiLCByZXF1aXJlQXBpVmVyc2lvbiwgU2V0dGluZ0dyb3VwIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgdHlwZSBIb21lQmFzZVBsdWdpbiBmcm9tICcuLi9tYWluJztcclxuaW1wb3J0IHtcclxuXHRWSUVXX01PREVfT1BUSU9OUyxcclxuXHRORVdfVEFCX01PREVfT1BUSU9OUyxcclxuXHRPUEVOSU5HX01PREVfT1BUSU9OUyxcclxuXHRWaWV3TW9kZSxcclxuXHROZXdUYWJNb2RlLFxyXG5cdE9wZW5pbmdNb2RlLFxyXG5cdEhvbWVCYXNlVHlwZSxcclxuXHRVTkNIQU5HRUFCTEVfVFlQRVMsXHJcbn0gZnJvbSAnLi4vc2V0dGluZ3MnO1xyXG5cclxuaW1wb3J0IHsgRmlsZVBhdGhTdWdnZXN0LCBGb2xkZXJTdWdnZXN0LCBXb3Jrc3BhY2VTdWdnZXN0IH0gZnJvbSAnLi9maWxlLXN1Z2dlc3QnO1xyXG5pbXBvcnQgeyBDb21tYW5kU3VnZ2VzdCwgZ2V0Q29tbWFuZEJ5SWQgfSBmcm9tICcuL2NvbW1hbmQtc3VnZ2VzdCc7XHJcbmltcG9ydCB7IEljb25QaWNrZXIgfSBmcm9tICcuL2ljb24tcGlja2VyJztcclxuXHJcbmV4cG9ydCBjbGFzcyBIb21lQmFzZVNldHRpbmdUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcclxuXHRwbHVnaW46IEhvbWVCYXNlUGx1Z2luO1xyXG5cdHB1YmxpYyBpY29uID0gJ2x1Y2lkZS1ob3VzZSc7XHJcblxyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEhvbWVCYXNlUGx1Z2luKSB7XHJcblx0XHRzdXBlcihhcHAsIHBsdWdpbik7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHR9XHJcblxyXG5cdGRpc3BsYXkoKTogdm9pZCB7XHJcblx0XHRjb25zdCB7IGNvbnRhaW5lckVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGFpbmVyRWwuZW1wdHkoKTtcclxuXHJcblx0XHQvLyBHZXQgYWN0aXZlIHNldHRpbmdzIChtb2JpbGUgb3IgZGVza3RvcClcclxuXHRcdGNvbnN0IGlzTW9iaWxlID0gdGhpcy5wbHVnaW4uc2V0dGluZ3Muc2VwYXJhdGVNb2JpbGU7XHJcblx0XHRjb25zdCBhY3RpdmVUeXBlID0gaXNNb2JpbGUgPyB0aGlzLnBsdWdpbi5zZXR0aW5ncy5tb2JpbGVIb21lQmFzZVR5cGUgOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5ob21lQmFzZVR5cGU7XHJcblx0XHRjb25zdCBhY3RpdmVWYWx1ZSA9IGlzTW9iaWxlID8gdGhpcy5wbHVnaW4uc2V0dGluZ3MubW9iaWxlSG9tZUJhc2VWYWx1ZSA6IHRoaXMucGx1Z2luLnNldHRpbmdzLmhvbWVCYXNlVmFsdWU7XHJcblxyXG5cdFx0Ly8gR2VuZXJhbCBTZXR0aW5ncyAobm8gaGVhZGluZyBmb3IgZmlyc3QgZ3JvdXApXHJcblx0XHRjb25zdCBnZW5lcmFsR3JvdXAgPSBuZXcgU2V0dGluZ0dyb3VwKGNvbnRhaW5lckVsKTtcclxuXHJcblx0XHQvLyBIb21lIHBhZ2UgdHlwZSBkcm9wZG93blxyXG5cdFx0Z2VuZXJhbEdyb3VwLmFkZFNldHRpbmcoc2V0dGluZyA9PiB7XHJcblx0XHRcdHNldHRpbmdcclxuXHRcdFx0XHQuc2V0TmFtZSgnVHlwZScpXHJcblx0XHRcdFx0LnNldERlc2MoJ1doYXQgdG8gb3BlbiBhcyB5b3VyIGhvbWUgYmFzZScpXHJcblx0XHRcdFx0LmFkZERyb3Bkb3duKGRyb3Bkb3duID0+IHtcclxuXHRcdFx0XHRcdGxldCBwbHVnaW5EaXNhYmxlZCA9IGZhbHNlO1xyXG5cclxuXHRcdFx0XHRcdGZvciAoY29uc3QgdHlwZSBvZiBPYmplY3QudmFsdWVzKEhvbWVCYXNlVHlwZSkpIHtcclxuXHRcdFx0XHRcdFx0aWYgKCF0aGlzLnBsdWdpbi5oYXNSZXF1aXJlZFBsdWdpbih0eXBlKSkge1xyXG5cdFx0XHRcdFx0XHRcdC8vIElmIGN1cnJlbnQgdHlwZSBpcyBkaXNhYmxlZCwgbWFyayBpdCBidXQgc3RpbGwgYWxsb3cgaXRcclxuXHRcdFx0XHRcdFx0XHRpZiAodHlwZSA9PT0gYWN0aXZlVHlwZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0cGx1Z2luRGlzYWJsZWQgPSB0cnVlO1xyXG5cdFx0XHRcdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKHR5cGUsIHR5cGUpO1xyXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0XHQvLyBBZGQgZGlzYWJsZWQgb3B0aW9uXHJcblx0XHRcdFx0XHRcdFx0XHRkcm9wZG93bi5zZWxlY3RFbC5jcmVhdGVFbCgnb3B0aW9uJywge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHR0ZXh0OiB0eXBlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRhdHRyOiB7IGRpc2FibGVkOiAndHJ1ZScgfVxyXG5cdFx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKHR5cGUsIHR5cGUpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0ZHJvcGRvd25cclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKGFjdGl2ZVR5cGUgfHwgSG9tZUJhc2VUeXBlLkZpbGUpXHJcblx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKGlzTW9iaWxlKSB7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5tb2JpbGVIb21lQmFzZVR5cGUgPSB2YWx1ZSBhcyBIb21lQmFzZVR5cGU7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmhvbWVCYXNlVHlwZSA9IHZhbHVlIGFzIEhvbWVCYXNlVHlwZTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFJlLXJlbmRlciB0byBzaG93L2hpZGUgdmFsdWUgaW5wdXRcclxuXHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxDb250YWluZXIgPSBjb250YWluZXJFbC5jbG9zZXN0KCcudmVydGljYWwtdGFiLWNvbnRlbnQnKSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0Y29udGFpbmVyRWwuY2xvc2VzdCgnLnNldHRpbmdzLWNvbnRlbnQnKSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0Y29udGFpbmVyRWwucGFyZW50RWxlbWVudDtcclxuXHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxUb3AgPSBzY3JvbGxDb250YWluZXI/LnNjcm9sbFRvcCB8fCAwO1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBzY3JvbGxUb3A7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cclxuXHRcdFx0XHRcdC8vIFNob3cgd2FybmluZyBpZiBjdXJyZW50IHR5cGUgcmVxdWlyZXMgYSBkaXNhYmxlZCBwbHVnaW5cclxuXHRcdFx0XHRcdGlmIChwbHVnaW5EaXNhYmxlZCkge1xyXG5cdFx0XHRcdFx0XHRzZXR0aW5nLmRlc2NFbC5jcmVhdGVEaXYoe1xyXG5cdFx0XHRcdFx0XHRcdHRleHQ6ICdUaGUgcmVxdWlyZWQgcGx1Z2luIGhhcyBub3QgYmVlbiBlbmFibGVkIG9yIGNvbmZpZ3VyZWQgZm9yIHRoaXMgdHlwZS4nLFxyXG5cdFx0XHRcdFx0XHRcdGNsczogJ21vZC13YXJuaW5nJ1xyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vIFZhbHVlIGlucHV0IChjb25kaXRpb25hbCBvbiB0eXBlKVxyXG5cdFx0aWYgKCFVTkNIQU5HRUFCTEVfVFlQRVMuaW5jbHVkZXMoYWN0aXZlVHlwZSkpIHtcclxuXHRcdFx0Z2VuZXJhbEdyb3VwLmFkZFNldHRpbmcoc2V0dGluZyA9PiB7XHJcblx0XHRcdFx0bGV0IGRlc2MgPSAnJztcclxuXHRcdFx0XHRsZXQgcGxhY2Vob2xkZXIgPSAnJztcclxuXHJcblx0XHRcdFx0aWYgKGFjdGl2ZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5GaWxlKSB7XHJcblx0XHRcdFx0XHRkZXNjID0gJ1RoZSBmaWxlIHRvIG9wZW4gYXMgeW91ciBob21lIGJhc2UgKHN1cHBvcnRzIC5tZCwgLm1keCwgLmNhbnZhcywgLmJhc2UpJztcclxuXHRcdFx0XHRcdHBsYWNlaG9sZGVyID0gJ1BhdGggdG8gaG9tZSBiYXNlIGZpbGUnO1xyXG5cdFx0XHRcdH0gZWxzZSBpZiAoYWN0aXZlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLldvcmtzcGFjZSkge1xyXG5cdFx0XHRcdFx0ZGVzYyA9ICdUaGUgd29ya3NwYWNlIHRvIGxvYWQgYXMgeW91ciBob21lIGJhc2UnO1xyXG5cdFx0XHRcdFx0cGxhY2Vob2xkZXIgPSAnV29ya3NwYWNlIG5hbWUnO1xyXG5cdFx0XHRcdH0gZWxzZSBpZiAoYWN0aXZlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLlJhbmRvbUZvbGRlciB8fCBhY3RpdmVUeXBlID09PSBIb21lQmFzZVR5cGUuTmV3Tm90ZSkge1xyXG5cdFx0XHRcdFx0ZGVzYyA9IGFjdGl2ZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5SYW5kb21Gb2xkZXIgPyAnVGhlIGZvbGRlciB0byBwaWNrIGEgcmFuZG9tIGZpbGUgZnJvbScgOiAnVGhlIGZvbGRlciB0byBjcmVhdGUgbmV3IG5vdGVzIGluJztcclxuXHRcdFx0XHRcdHBsYWNlaG9sZGVyID0gJ0ZvbGRlciBwYXRoJztcclxuXHRcdFx0XHR9IGVsc2UgaWYgKGFjdGl2ZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5Kb3VybmFsKSB7XHJcblx0XHRcdFx0XHRkZXNjID0gJ1RoZSBqb3VybmFsIG5hbWUnO1xyXG5cdFx0XHRcdFx0cGxhY2Vob2xkZXIgPSAnSm91cm5hbCBuYW1lJztcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHNldHRpbmdcclxuXHRcdFx0XHRcdC5zZXROYW1lKGFjdGl2ZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5GaWxlID8gJ0ZpbGUnIDpcclxuXHRcdFx0XHRcdFx0YWN0aXZlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLldvcmtzcGFjZSA/ICdXb3Jrc3BhY2UnIDpcclxuXHRcdFx0XHRcdFx0XHQoYWN0aXZlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLlJhbmRvbUZvbGRlciB8fCBhY3RpdmVUeXBlID09PSBIb21lQmFzZVR5cGUuTmV3Tm90ZSkgPyAnRm9sZGVyJyA6XHJcblx0XHRcdFx0XHRcdFx0XHRhY3RpdmVUeXBlID09PSBIb21lQmFzZVR5cGUuSm91cm5hbCA/ICdKb3VybmFsJyA6ICdWYWx1ZScpXHJcblx0XHRcdFx0XHQuc2V0RGVzYyhkZXNjKVxyXG5cdFx0XHRcdFx0LmFkZFRleHQodGV4dCA9PiB7XHJcblx0XHRcdFx0XHRcdC8vIEFkZCBhcHByb3ByaWF0ZSBzdWdnZXN0ZXJcclxuXHRcdFx0XHRcdFx0aWYgKGFjdGl2ZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5GaWxlKSB7XHJcblx0XHRcdFx0XHRcdFx0bmV3IEZpbGVQYXRoU3VnZ2VzdCh0aGlzLmFwcCwgdGV4dC5pbnB1dEVsKTtcclxuXHRcdFx0XHRcdFx0fSBlbHNlIGlmIChhY3RpdmVUeXBlID09PSBIb21lQmFzZVR5cGUuV29ya3NwYWNlKSB7XHJcblx0XHRcdFx0XHRcdFx0bmV3IFdvcmtzcGFjZVN1Z2dlc3QodGhpcy5hcHAsIHRleHQuaW5wdXRFbCk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoYWN0aXZlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLlJhbmRvbUZvbGRlciB8fCBhY3RpdmVUeXBlID09PSBIb21lQmFzZVR5cGUuTmV3Tm90ZSkge1xyXG5cdFx0XHRcdFx0XHRcdG5ldyBGb2xkZXJTdWdnZXN0KHRoaXMuYXBwLCB0ZXh0LmlucHV0RWwpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHR0ZXh0XHJcblx0XHRcdFx0XHRcdFx0LnNldFBsYWNlaG9sZGVyKHBsYWNlaG9sZGVyKVxyXG5cdFx0XHRcdFx0XHRcdC5zZXRWYWx1ZShhY3RpdmVWYWx1ZSB8fCAnJylcclxuXHRcdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKGlzTW9iaWxlKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLm1vYmlsZUhvbWVCYXNlVmFsdWUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmhvbWVCYXNlVmFsdWUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdGdlbmVyYWxHcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRzZXR0aW5nXHJcblx0XHRcdFx0LnNldE5hbWUoJ09wZW4gb24gc3RhcnR1cCcpXHJcblx0XHRcdFx0LnNldERlc2MoJ09wZW4gdGhlIGhvbWUgYmFzZSB3aGVuIGxhdW5jaGluZyBPYnNpZGlhbicpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSh0b2dnbGUgPT4ge1xyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuT25TdGFydHVwKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLm9wZW5PblN0YXJ0dXAgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblxyXG5cdFx0XHQvLyBBZGQgd2FybmluZyBpZiBPYnNpZGlhbiAxLjExLjArIGFuZCBuYXRpdmUgc2V0dGluZyBleGlzdHNcclxuXHRcdFx0aWYgKHJlcXVpcmVBcGlWZXJzaW9uKCcxLjExLjAnKSkge1xyXG5cdFx0XHRcdGNvbnN0IG5hdGl2ZU9wZW5CZWhhdmlvciA9IHRoaXMucGx1Z2luLmhvbWVTZXJ2aWNlLmdldE5hdGl2ZU9wZW5CZWhhdmlvcigpO1xyXG5cdFx0XHRcdGlmIChuYXRpdmVPcGVuQmVoYXZpb3IpIHtcclxuXHRcdFx0XHRcdHNldHRpbmcuZGVzY0VsLmNyZWF0ZURpdih7XHJcblx0XHRcdFx0XHRcdHRleHQ6IGBOb3RlOiBUaGlzIHdpbGwgb3ZlcnJpZGUgT2JzaWRpYW4ncyBuYXRpdmUgXCJEZWZhdWx0IGZpbGUgdG8gb3BlblwiIHNldHRpbmcgKGN1cnJlbnRseSBzZXQgdG8gXCIke25hdGl2ZU9wZW5CZWhhdmlvcn1cIikuYCxcclxuXHRcdFx0XHRcdFx0Y2xzOiAnbW9kLXdhcm5pbmcnXHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vIFwiT3BlbiB3aGVuIGVtcHR5XCIgc2V0dGluZyByZW1vdmVkIC0gcmVkdW5kYW50IHdpdGggXCJOZXcgdGFiIHJlcGxhY2VtZW50OiBvbmx5IHdoZW4gZW1wdHlcIlxyXG5cdFx0Ly8gU2luY2UgT2JzaWRpYW4gYXV0by1jcmVhdGVzIGFuIGVtcHR5IHRhYiB3aGVuIHlvdSBjbG9zZSB0aGUgbGFzdCBvbmUsIHRoZXkgZG8gdGhlIHNhbWUgdGhpbmdcclxuXHJcblx0XHRnZW5lcmFsR3JvdXAuYWRkU2V0dGluZyhzZXR0aW5nID0+IHtcclxuXHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdC5zZXROYW1lKCdPcGVuaW5nIG1vZGUgKHN0YXJ0dXApJylcclxuXHRcdFx0XHQuc2V0RGVzYygnSG93IHRvIGhhbmRsZSBleGlzdGluZyB0YWJzIHdoZW4gb3BlbmluZyBvbiBzdGFydHVwJylcclxuXHRcdFx0XHQuYWRkRHJvcGRvd24oZHJvcGRvd24gPT4ge1xyXG5cdFx0XHRcdFx0Zm9yIChjb25zdCBbdmFsdWUsIGxhYmVsXSBvZiBPYmplY3QuZW50cmllcyhPUEVOSU5HX01PREVfT1BUSU9OUykpIHtcclxuXHRcdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKHZhbHVlLCBsYWJlbCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRkcm9wZG93blxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3Blbk1vZGUpXHJcblx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Mub3Blbk1vZGUgPSB2YWx1ZSBhcyBPcGVuaW5nTW9kZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRnZW5lcmFsR3JvdXAuYWRkU2V0dGluZyhzZXR0aW5nID0+IHtcclxuXHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdC5zZXROYW1lKCdPcGVuaW5nIG1vZGUgKG1hbnVhbCknKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdIb3cgdG8gaGFuZGxlIGV4aXN0aW5nIHRhYnMgd2hlbiBvcGVuaW5nIG1hbnVhbGx5JylcclxuXHRcdFx0XHQuYWRkRHJvcGRvd24oZHJvcGRvd24gPT4ge1xyXG5cdFx0XHRcdFx0Zm9yIChjb25zdCBbdmFsdWUsIGxhYmVsXSBvZiBPYmplY3QuZW50cmllcyhPUEVOSU5HX01PREVfT1BUSU9OUykpIHtcclxuXHRcdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKHZhbHVlLCBsYWJlbCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRkcm9wZG93blxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MubWFudWFsT3Blbk1vZGUpXHJcblx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MubWFudWFsT3Blbk1vZGUgPSB2YWx1ZSBhcyBPcGVuaW5nTW9kZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRnZW5lcmFsR3JvdXAuYWRkU2V0dGluZyhzZXR0aW5nID0+IHtcclxuXHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdC5zZXROYW1lKCdWaWV3IG1vZGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdIb3cgdG8gb3BlbiBNYXJrZG93biBmaWxlcycpXHJcblx0XHRcdFx0LmFkZERyb3Bkb3duKGRyb3Bkb3duID0+IHtcclxuXHRcdFx0XHRcdGZvciAoY29uc3QgW3ZhbHVlLCBsYWJlbF0gb2YgT2JqZWN0LmVudHJpZXMoVklFV19NT0RFX09QVElPTlMpKSB7XHJcblx0XHRcdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbih2YWx1ZSwgbGFiZWwpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZHJvcGRvd25cclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLm9wZW5WaWV3TW9kZSlcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuVmlld01vZGUgPSB2YWx1ZSBhcyBWaWV3TW9kZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRnZW5lcmFsR3JvdXAuYWRkU2V0dGluZyhzZXR0aW5nID0+IHtcclxuXHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdC5zZXROYW1lKCdSZXZlcnQgdmlldyBvbiBjbG9zZScpXHJcblx0XHRcdFx0LnNldERlc2MoJ1doZW4gbmF2aWdhdGluZyBhd2F5IGZyb20gdGhlIGhvbWUgYmFzZSwgcmVzdG9yZSB0aGUgZGVmYXVsdCB2aWV3JylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKHRvZ2dsZSA9PiB7XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnJldmVydFZpZXcpXHJcblx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MucmV2ZXJ0VmlldyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdGdlbmVyYWxHcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRzZXR0aW5nXHJcblx0XHRcdFx0LnNldE5hbWUoJ0F1dG8tc2Nyb2xsJylcclxuXHRcdFx0XHQuc2V0RGVzYygnV2hlbiBvcGVuaW5nIHRoZSBob21lIGJhc2UsIHNjcm9sbCB0byB0aGUgYm90dG9tIGFuZCBmb2N1cyBvbiB0aGUgbGFzdCBsaW5lJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKHRvZ2dsZSA9PiB7XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmF1dG9TY3JvbGwpXHJcblx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYXV0b1Njcm9sbCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdGdlbmVyYWxHcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRzZXR0aW5nXHJcblx0XHRcdFx0LnNldE5hbWUoJ0hpZGUgcmVsZWFzZSBub3RlcycpXHJcblx0XHRcdFx0LnNldERlc2MoJ05ldmVyIGRpc3BsYXkgcmVsZWFzZSBub3RlcyB3aGVuIE9ic2lkaWFuIHVwZGF0ZXMnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUodG9nZ2xlID0+IHtcclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuaGlkZVJlbGVhc2VOb3RlcylcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5oaWRlUmVsZWFzZU5vdGVzID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gVGFiIEJlaGF2aW9yIFNldHRpbmdzXHJcblx0XHRjb25zdCB0YWJHcm91cCA9IG5ldyBTZXR0aW5nR3JvdXAoY29udGFpbmVyRWwpLnNldEhlYWRpbmcoJ1RhYiBCZWhhdmlvcicpO1xyXG5cclxuXHRcdHRhYkdyb3VwLmFkZFNldHRpbmcoc2V0dGluZyA9PiB7XHJcblx0XHRcdHNldHRpbmdcclxuXHRcdFx0XHQuc2V0TmFtZSgnT3BlbiBob21lIGJhc2Ugd2hlbiBhbGwgdGFicyBhcmUgY2xvc2VkJylcclxuXHRcdFx0XHQuc2V0RGVzYygnV2hlbiB5b3UgY2xvc2UgYWxsIHRhYnMsIGF1dG9tYXRpY2FsbHkgb3BlbiB0aGUgaG9tZSBiYXNlJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKHRvZ2dsZSA9PiB7XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLm9wZW5XaGVuQWxsVGFic0Nsb3NlZClcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuV2hlbkFsbFRhYnNDbG9zZWQgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHR0YWJHcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRzZXR0aW5nXHJcblx0XHRcdFx0LnNldE5hbWUoJ1JlcGxhY2UgbmV3IHRhYnMnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdPcGVuIGhvbWUgYmFzZSBpbnN0ZWFkIG9mIG5ldyBlbXB0eSB0YWJzICh3b3JrcyBpbmRlcGVuZGVudGx5IG9mIFwib3BlbiBob21lIGJhc2Ugd2hlbiBhbGwgdGFicyBhcmUgY2xvc2VkXCIpJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKHRvZ2dsZSA9PiB7XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnJlcGxhY2VOZXdUYWIpXHJcblx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MucmVwbGFjZU5ld1RhYiA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyBQcmVzZXJ2ZSBzY3JvbGwgcG9zaXRpb24gYmVmb3JlIHJlLXJlbmRlcmluZ1xyXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHNjcm9sbENvbnRhaW5lciA9IGNvbnRhaW5lckVsLmNsb3Nlc3QoJy52ZXJ0aWNhbC10YWItY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRjb250YWluZXJFbC5jbG9zZXN0KCcuc2V0dGluZ3MtY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRjb250YWluZXJFbC5wYXJlbnRFbGVtZW50O1xyXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHNjcm9sbFRvcCA9IHNjcm9sbENvbnRhaW5lcj8uc2Nyb2xsVG9wIHx8IDA7XHJcblxyXG5cdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpOyAvLyBSZS1yZW5kZXIgdG8gc2hvdy9oaWRlIGRlcGVuZGVudCBzZXR0aW5nXHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFJlc3RvcmUgc2Nyb2xsIHBvc2l0aW9uIGFmdGVyIHJlbmRlcmluZ1xyXG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBzY3JvbGxUb3A7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gT25seSBzaG93IG5ldyB0YWIgbW9kZSBpZiByZXBsYWNlIG5ldyB0YWIgaXMgZW5hYmxlZFxyXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnJlcGxhY2VOZXdUYWIpIHtcclxuXHRcdFx0dGFiR3JvdXAuYWRkU2V0dGluZyhzZXR0aW5nID0+IHtcclxuXHRcdFx0XHRzZXR0aW5nXHJcblx0XHRcdFx0XHQuc2V0TmFtZSgnTmV3IHRhYiByZXBsYWNlbWVudCBtb2RlJylcclxuXHRcdFx0XHRcdC5zZXREZXNjKCdXaGVuIHRvIHJlcGxhY2UgbmV3IHRhYnMgKG9ubHkgd2hlbiBubyB0YWJzIGFyZSBvcGVuLCBvciBhbHdheXMpJylcclxuXHRcdFx0XHRcdC5hZGREcm9wZG93bihkcm9wZG93biA9PiB7XHJcblx0XHRcdFx0XHRcdGZvciAoY29uc3QgW3ZhbHVlLCBsYWJlbF0gb2YgT2JqZWN0LmVudHJpZXMoTkVXX1RBQl9NT0RFX09QVElPTlMpKSB7XHJcblx0XHRcdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKHZhbHVlLCBsYWJlbCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0ZHJvcGRvd25cclxuXHRcdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MubmV3VGFiTW9kZSlcclxuXHRcdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MubmV3VGFiTW9kZSA9IHZhbHVlIGFzIE5ld1RhYk1vZGU7XHJcblx0XHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdC8vIFVzZSBkaWZmZXJlbnQgZmlsZSBmb3IgbmV3IHRhYnMgdG9nZ2xlXHJcblx0XHRcdHRhYkdyb3VwLmFkZFNldHRpbmcoc2V0dGluZyA9PiB7XHJcblx0XHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdFx0LnNldE5hbWUoJ1VzZSBkaWZmZXJlbnQgaG9tZSBiYXNlIGZvciBuZXcgdGFicycpXHJcblx0XHRcdFx0XHQuc2V0RGVzYygnQ29uZmlndXJlIGEgZGlmZmVyZW50IGhvbWUgYmFzZSB0byBvcGVuIGZvciBuZXcgdGFicyAoaW5zdGVhZCBvZiB0aGUgbWFpbiBob21lIGJhc2UpJylcclxuXHRcdFx0XHRcdC5hZGRUb2dnbGUodG9nZ2xlID0+IHtcclxuXHRcdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZURpZmZlcmVudEZpbGVGb3JOZXdUYWIpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZURpZmZlcmVudEZpbGVGb3JOZXdUYWIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdC8vIFByZXNlcnZlIHNjcm9sbCBwb3NpdGlvbiBiZWZvcmUgcmUtcmVuZGVyaW5nXHJcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxDb250YWluZXIgPSBjb250YWluZXJFbC5jbG9zZXN0KCcudmVydGljYWwtdGFiLWNvbnRlbnQnKSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRjb250YWluZXJFbC5jbG9zZXN0KCcuc2V0dGluZ3MtY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnRhaW5lckVsLnBhcmVudEVsZW1lbnQ7XHJcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxUb3AgPSBzY3JvbGxDb250YWluZXI/LnNjcm9sbFRvcCB8fCAwO1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpOyAvLyBSZS1yZW5kZXIgdG8gc2hvdy9oaWRlIGRlcGVuZGVudCBzZXR0aW5nc1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdC8vIFJlc3RvcmUgc2Nyb2xsIHBvc2l0aW9uIGFmdGVyIHJlbmRlcmluZ1xyXG5cdFx0XHRcdFx0XHRcdFx0cmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKHNjcm9sbENvbnRhaW5lcikge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBzY3JvbGxUb3A7XHJcblx0XHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0Ly8gU2hvdyBuZXcgdGFiIGNvbmZpZ3VyYXRpb24gaWYgZW5hYmxlZCAoYWx3YXlzIGRlc2t0b3Agc2V0dGluZ3MpXHJcblx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VEaWZmZXJlbnRGaWxlRm9yTmV3VGFiKSB7XHJcblx0XHRcdFx0Y29uc3QgZGVza3RvcFR5cGUgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5uZXdUYWJUeXBlIHx8IEhvbWVCYXNlVHlwZS5GaWxlO1xyXG5cdFx0XHRcdGNvbnN0IGRlc2t0b3BWYWx1ZSA9IHRoaXMucGx1Z2luLnNldHRpbmdzLm5ld1RhYlZhbHVlIHx8ICcnO1xyXG5cclxuXHRcdFx0XHQvLyBOZXcgdGFiIHR5cGUgZHJvcGRvd25cclxuXHRcdFx0XHR0YWJHcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdFx0XHQuc2V0TmFtZSgnTmV3IHRhYiB0eXBlJylcclxuXHRcdFx0XHRcdFx0LnNldERlc2MoJ1doYXQgdG8gb3BlbiBmb3IgbmV3IHRhYnMnKVxyXG5cdFx0XHRcdFx0XHQuYWRkRHJvcGRvd24oZHJvcGRvd24gPT4ge1xyXG5cdFx0XHRcdFx0XHRcdGxldCBwbHVnaW5EaXNhYmxlZCA9IGZhbHNlO1xyXG5cclxuXHRcdFx0XHRcdFx0XHRmb3IgKGNvbnN0IHR5cGUgb2YgT2JqZWN0LnZhbHVlcyhIb21lQmFzZVR5cGUpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoIXRoaXMucGx1Z2luLmhhc1JlcXVpcmVkUGx1Z2luKHR5cGUpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdC8vIElmIGN1cnJlbnQgdHlwZSBpcyBkaXNhYmxlZCwgbWFyayBpdCBidXQgc3RpbGwgYWxsb3cgaXRcclxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKHR5cGUgPT09IGRlc2t0b3BUeXBlKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0cGx1Z2luRGlzYWJsZWQgPSB0cnVlO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbih0eXBlLCB0eXBlKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBBZGQgZGlzYWJsZWQgb3B0aW9uXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0ZHJvcGRvd24uc2VsZWN0RWwuY3JlYXRlRWwoJ29wdGlvbicsIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRleHQ6IHR5cGUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRhdHRyOiB7IGRpc2FibGVkOiAndHJ1ZScgfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGNvbnRpbnVlO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRkcm9wZG93bi5hZGRPcHRpb24odHlwZSwgdHlwZSk7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0XHRkcm9wZG93blxyXG5cdFx0XHRcdFx0XHRcdFx0LnNldFZhbHVlKGRlc2t0b3BUeXBlKVxyXG5cdFx0XHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MubmV3VGFiVHlwZSA9IHZhbHVlIGFzIEhvbWVCYXNlVHlwZTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBSZS1yZW5kZXIgdG8gc2hvdy9oaWRlIHZhbHVlIGlucHV0XHJcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnN0IHNjcm9sbENvbnRhaW5lciA9IGNvbnRhaW5lckVsLmNsb3Nlc3QoJy52ZXJ0aWNhbC10YWItY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0Y29udGFpbmVyRWwuY2xvc2VzdCgnLnNldHRpbmdzLWNvbnRlbnQnKSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGNvbnRhaW5lckVsLnBhcmVudEVsZW1lbnQ7XHJcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnN0IHNjcm9sbFRvcCA9IHNjcm9sbENvbnRhaW5lcj8uc2Nyb2xsVG9wIHx8IDA7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRyZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmIChzY3JvbGxDb250YWluZXIpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBzY3JvbGxUb3A7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdFx0XHRcdH0pO1xyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyBTaG93IHdhcm5pbmcgaWYgY3VycmVudCB0eXBlIHJlcXVpcmVzIGEgZGlzYWJsZWQgcGx1Z2luXHJcblx0XHRcdFx0XHRcdFx0aWYgKHBsdWdpbkRpc2FibGVkKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRzZXR0aW5nLmRlc2NFbC5jcmVhdGVEaXYoe1xyXG5cdFx0XHRcdFx0XHRcdFx0XHR0ZXh0OiAnVGhlIHJlcXVpcmVkIHBsdWdpbiBoYXMgbm90IGJlZW4gZW5hYmxlZCBvciBjb25maWd1cmVkIGZvciB0aGlzIHR5cGUuJyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0Y2xzOiAnbW9kLXdhcm5pbmcnXHJcblx0XHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cclxuXHRcdFx0XHQvLyBWYWx1ZSBpbnB1dCAoY29uZGl0aW9uYWwgb24gdHlwZSlcclxuXHRcdFx0XHRpZiAoIVVOQ0hBTkdFQUJMRV9UWVBFUy5pbmNsdWRlcyhkZXNrdG9wVHlwZSkpIHtcclxuXHRcdFx0XHRcdHRhYkdyb3VwLmFkZFNldHRpbmcoc2V0dGluZyA9PiB7XHJcblx0XHRcdFx0XHRcdGxldCBkZXNjID0gJyc7XHJcblx0XHRcdFx0XHRcdGxldCBwbGFjZWhvbGRlciA9ICcnO1xyXG5cclxuXHRcdFx0XHRcdFx0aWYgKGRlc2t0b3BUeXBlID09PSBIb21lQmFzZVR5cGUuRmlsZSkge1xyXG5cdFx0XHRcdFx0XHRcdGRlc2MgPSAnVGhlIGZpbGUgdG8gb3BlbiBmb3IgbmV3IHRhYnMgKHN1cHBvcnRzIC5tZCwgLm1keCwgLmNhbnZhcywgLmJhc2UpJztcclxuXHRcdFx0XHRcdFx0XHRwbGFjZWhvbGRlciA9ICdQYXRoIHRvIG5ldyB0YWIgZmlsZSc7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoZGVza3RvcFR5cGUgPT09IEhvbWVCYXNlVHlwZS5Xb3Jrc3BhY2UpIHtcclxuXHRcdFx0XHRcdFx0XHRkZXNjID0gJ1RoZSB3b3Jrc3BhY2UgdG8gbG9hZCBmb3IgbmV3IHRhYnMnO1xyXG5cdFx0XHRcdFx0XHRcdHBsYWNlaG9sZGVyID0gJ1dvcmtzcGFjZSBuYW1lJztcclxuXHRcdFx0XHRcdFx0fSBlbHNlIGlmIChkZXNrdG9wVHlwZSA9PT0gSG9tZUJhc2VUeXBlLlJhbmRvbUZvbGRlcikge1xyXG5cdFx0XHRcdFx0XHRcdGRlc2MgPSAnVGhlIGZvbGRlciB0byBwaWNrIGEgcmFuZG9tIGZpbGUgZnJvbSBmb3IgbmV3IHRhYnMnO1xyXG5cdFx0XHRcdFx0XHRcdHBsYWNlaG9sZGVyID0gJ0ZvbGRlciBwYXRoJztcclxuXHRcdFx0XHRcdFx0fSBlbHNlIGlmIChkZXNrdG9wVHlwZSA9PT0gSG9tZUJhc2VUeXBlLkpvdXJuYWwpIHtcclxuXHRcdFx0XHRcdFx0XHRkZXNjID0gJ1RoZSBqb3VybmFsIG5hbWUgZm9yIG5ldyB0YWJzJztcclxuXHRcdFx0XHRcdFx0XHRwbGFjZWhvbGRlciA9ICdKb3VybmFsIG5hbWUnO1xyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRzZXR0aW5nXHJcblx0XHRcdFx0XHRcdFx0LnNldE5hbWUoZGVza3RvcFR5cGUgPT09IEhvbWVCYXNlVHlwZS5GaWxlID8gJ05ldyB0YWIgZmlsZScgOlxyXG5cdFx0XHRcdFx0XHRcdFx0ZGVza3RvcFR5cGUgPT09IEhvbWVCYXNlVHlwZS5Xb3Jrc3BhY2UgPyAnTmV3IHRhYiB3b3Jrc3BhY2UnIDpcclxuXHRcdFx0XHRcdFx0XHRcdFx0ZGVza3RvcFR5cGUgPT09IEhvbWVCYXNlVHlwZS5SYW5kb21Gb2xkZXIgPyAnTmV3IHRhYiBmb2xkZXInIDpcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRkZXNrdG9wVHlwZSA9PT0gSG9tZUJhc2VUeXBlLkpvdXJuYWwgPyAnTmV3IHRhYiBqb3VybmFsJyA6ICdOZXcgdGFiIHZhbHVlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0RGVzYyhkZXNjKVxyXG5cdFx0XHRcdFx0XHRcdC5hZGRUZXh0KHRleHQgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0Ly8gQWRkIGFwcHJvcHJpYXRlIHN1Z2dlc3RlclxyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKGRlc2t0b3BUeXBlID09PSBIb21lQmFzZVR5cGUuRmlsZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRuZXcgRmlsZVBhdGhTdWdnZXN0KHRoaXMuYXBwLCB0ZXh0LmlucHV0RWwpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmIChkZXNrdG9wVHlwZSA9PT0gSG9tZUJhc2VUeXBlLldvcmtzcGFjZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRuZXcgV29ya3NwYWNlU3VnZ2VzdCh0aGlzLmFwcCwgdGV4dC5pbnB1dEVsKTtcclxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoZGVza3RvcFR5cGUgPT09IEhvbWVCYXNlVHlwZS5SYW5kb21Gb2xkZXIpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0bmV3IEZvbGRlclN1Z2dlc3QodGhpcy5hcHAsIHRleHQuaW5wdXRFbCk7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0dGV4dFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQuc2V0UGxhY2Vob2xkZXIocGxhY2Vob2xkZXIpXHJcblx0XHRcdFx0XHRcdFx0XHRcdC5zZXRWYWx1ZShkZXNrdG9wVmFsdWUgfHwgJycpXHJcblx0XHRcdFx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MubmV3VGFiVmFsdWUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBMZWdhY3kgXCJLZWVwIGV4aXN0aW5nIHRhYnNcIiAtIGtlcHQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgYnV0IGhpZGRlblxyXG5cdFx0Ly8gKGZ1bmN0aW9uYWxpdHkgbm93IGhhbmRsZWQgYnkgXCJPcGVuaW5nIG1vZGUgKHN0YXJ0dXApXCIpXHJcblxyXG5cdFx0Ly8gVUkgRmVhdHVyZXMgU2V0dGluZ3NcclxuXHRcdGNvbnN0IHVpR3JvdXAgPSBuZXcgU2V0dGluZ0dyb3VwKGNvbnRhaW5lckVsKS5zZXRIZWFkaW5nKCdVSSBGZWF0dXJlcycpO1xyXG5cclxuXHRcdHVpR3JvdXAuYWRkU2V0dGluZyhzZXR0aW5nID0+IHtcclxuXHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdC5zZXROYW1lKCdTdGlja3kgaG9tZSBpY29uJylcclxuXHRcdFx0XHQuc2V0RGVzYygnU2hvdyBhIGhvbWUgaWNvbiBpbiB0aGUgdGFiIGJhciB0aGF0IHN0YXlzIHBpbm5lZCB0byB0aGUgbGVmdCAoZGVza3RvcCBvbmx5KScpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSh0b2dnbGUgPT4ge1xyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93U3RpY2t5SG9tZUljb24pXHJcblx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hvd1N0aWNreUhvbWVJY29uID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlU3RpY2t5VGFiSWNvbigpO1xyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyBQcmVzZXJ2ZSBzY3JvbGwgcG9zaXRpb24gYmVmb3JlIHJlLXJlbmRlcmluZ1xyXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHNjcm9sbENvbnRhaW5lciA9IGNvbnRhaW5lckVsLmNsb3Nlc3QoJy52ZXJ0aWNhbC10YWItY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRjb250YWluZXJFbC5jbG9zZXN0KCcuc2V0dGluZ3MtY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRjb250YWluZXJFbC5wYXJlbnRFbGVtZW50O1xyXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHNjcm9sbFRvcCA9IHNjcm9sbENvbnRhaW5lcj8uc2Nyb2xsVG9wIHx8IDA7XHJcblxyXG5cdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpOyAvLyBSZS1yZW5kZXIgdG8gc2hvdy9oaWRlIGRlcGVuZGVudCBzZXR0aW5nXHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFJlc3RvcmUgc2Nyb2xsIHBvc2l0aW9uIGFmdGVyIHJlbmRlcmluZ1xyXG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBzY3JvbGxUb3A7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gT25seSBzaG93IHN0aWNreSBpY29uIHNldHRpbmdzIGlmIHN0aWNreSBpY29uIGlzIGVuYWJsZWRcclxuXHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93U3RpY2t5SG9tZUljb24pIHtcclxuXHRcdFx0dWlHcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRcdHNldHRpbmdcclxuXHRcdFx0XHRcdC5zZXROYW1lKCdJY29uJylcclxuXHRcdFx0XHRcdC5zZXREZXNjKCdUaGUgaWNvbiB0byBkaXNwbGF5IGluIHRoZSBzdGlja3kgaG9tZSBpY29uJylcclxuXHRcdFx0XHRcdC5hZGRCdXR0b24oYnV0dG9uID0+IHtcclxuXHRcdFx0XHRcdFx0Y29uc3QgaWNvbk5hbWUgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdGlja3lJY29uTmFtZSB8fCAnaG9tZSc7XHJcblx0XHRcdFx0XHRcdGJ1dHRvblxyXG5cdFx0XHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KCdDaGFuZ2UgaWNvbicpXHJcblx0XHRcdFx0XHRcdFx0LnNldEljb24oaWNvbk5hbWUpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgcGlja2VyID0gbmV3IEljb25QaWNrZXIoXHJcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMuYXBwLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdGlja3lJY29uTmFtZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0KGljb246IHN0cmluZyB8IG51bGwpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR2b2lkIChhc3luYyAoKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdGlja3lJY29uTmFtZSA9IGljb247XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFVwZGF0ZSB0aGUgaWNvbiBkaXNwbGF5XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zdGlja3lUYWJTZXJ2aWNlLnVwZGF0ZSgpO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gUmUtcmVuZGVyIHNldHRpbmdzIHRvIHVwZGF0ZSBidXR0b24gaWNvblxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSkoKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0KTtcclxuXHRcdFx0XHRcdFx0XHRcdHBpY2tlci5vcGVuKCk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHR1aUdyb3VwLmFkZFNldHRpbmcoc2V0dGluZyA9PiB7XHJcblx0XHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdFx0LnNldE5hbWUoJ0hpZGUgdGFiIGhlYWRlcicpXHJcblx0XHRcdFx0XHQuc2V0RGVzYygnSGlkZSB0aGUgc3RpY2t5IGhvbWUgdGFiIGhlYWRlciB3aGVuIGl0XFwncyBvcGVuLCB1c2luZyB0aGUgc3RpY2t5IGljb24gYXMgdGhlIHRhYiBpbmRpY2F0b3InKVxyXG5cdFx0XHRcdFx0LmFkZFRvZ2dsZSh0b2dnbGUgPT4ge1xyXG5cdFx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuaGlkZUhvbWVUYWJIZWFkZXIpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmhpZGVIb21lVGFiSGVhZGVyID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnN0aWNreVRhYlNlcnZpY2UudXBkYXRlVGFiSGVhZGVycygpO1xyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0XHQvLyBNb2JpbGUgU2V0dGluZ3NcclxuXHRcdGNvbnN0IG1vYmlsZUdyb3VwID0gbmV3IFNldHRpbmdHcm91cChjb250YWluZXJFbCkuc2V0SGVhZGluZygnTW9iaWxlJyk7XHJcblxyXG5cdFx0bW9iaWxlR3JvdXAuYWRkU2V0dGluZyhzZXR0aW5nID0+IHtcclxuXHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdC5zZXROYW1lKCdTZXBhcmF0ZSBtb2JpbGUgaG9tZSBiYXNlJylcclxuXHRcdFx0XHQuc2V0RGVzYygnVXNlIGEgZGlmZmVyZW50IGhvbWUgYmFzZSBvbiBtb2JpbGUgZGV2aWNlcycpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSh0b2dnbGUgPT4ge1xyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zZXBhcmF0ZU1vYmlsZSlcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zZXBhcmF0ZU1vYmlsZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyBSZS1yZW5kZXIgdG8gc2hvdyBtb2JpbGUgc2V0dGluZ3NcclxuXHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxDb250YWluZXIgPSBjb250YWluZXJFbC5jbG9zZXN0KCcudmVydGljYWwtdGFiLWNvbnRlbnQnKSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0Y29udGFpbmVyRWwuY2xvc2VzdCgnLnNldHRpbmdzLWNvbnRlbnQnKSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0Y29udGFpbmVyRWwucGFyZW50RWxlbWVudDtcclxuXHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxUb3AgPSBzY3JvbGxDb250YWluZXI/LnNjcm9sbFRvcCB8fCAwO1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBzY3JvbGxUb3A7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gU2hvdyBtb2JpbGUtc3BlY2lmaWMgc2V0dGluZ3MgaWYgc2VwYXJhdGUgbW9iaWxlIGlzIGVuYWJsZWRcclxuXHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zZXBhcmF0ZU1vYmlsZSkge1xyXG5cdFx0XHRtb2JpbGVHcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRcdHNldHRpbmdcclxuXHRcdFx0XHRcdC5zZXROYW1lKCdNb2JpbGUgaG9tZSBiYXNlJylcclxuXHRcdFx0XHRcdC5zZXREZXNjKCdXaGF0IHRvIG9wZW4gYXMgeW91ciBob21lIGJhc2Ugb24gbW9iaWxlJylcclxuXHRcdFx0XHRcdC5hZGREcm9wZG93bihkcm9wZG93biA9PiB7XHJcblx0XHRcdFx0XHRcdGNvbnN0IG1vYmlsZVR5cGUgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5tb2JpbGVIb21lQmFzZVR5cGUgfHwgSG9tZUJhc2VUeXBlLkZpbGU7XHJcblx0XHRcdFx0XHRcdGxldCBwbHVnaW5EaXNhYmxlZCA9IGZhbHNlO1xyXG5cclxuXHRcdFx0XHRcdFx0Zm9yIChjb25zdCB0eXBlIG9mIE9iamVjdC52YWx1ZXMoSG9tZUJhc2VUeXBlKSkge1xyXG5cdFx0XHRcdFx0XHRcdGlmICghdGhpcy5wbHVnaW4uaGFzUmVxdWlyZWRQbHVnaW4odHlwZSkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdC8vIElmIGN1cnJlbnQgdHlwZSBpcyBkaXNhYmxlZCwgbWFyayBpdCBidXQgc3RpbGwgYWxsb3cgaXRcclxuXHRcdFx0XHRcdFx0XHRcdGlmICh0eXBlID09PSBtb2JpbGVUeXBlKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHBsdWdpbkRpc2FibGVkID0gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKHR5cGUsIHR5cGUpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gQWRkIGRpc2FibGVkIG9wdGlvblxyXG5cdFx0XHRcdFx0XHRcdFx0XHRkcm9wZG93bi5zZWxlY3RFbC5jcmVhdGVFbCgnb3B0aW9uJywge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRleHQ6IHR5cGUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0YXR0cjogeyBkaXNhYmxlZDogJ3RydWUnIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnRpbnVlO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0XHRkcm9wZG93bi5hZGRPcHRpb24odHlwZSwgdHlwZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRkcm9wZG93blxyXG5cdFx0XHRcdFx0XHRcdC5zZXRWYWx1ZShtb2JpbGVUeXBlKVxyXG5cdFx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5tb2JpbGVIb21lQmFzZVR5cGUgPSB2YWx1ZSBhcyBIb21lQmFzZVR5cGU7XHJcblx0XHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxDb250YWluZXIgPSBjb250YWluZXJFbC5jbG9zZXN0KCcudmVydGljYWwtdGFiLWNvbnRlbnQnKSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRjb250YWluZXJFbC5jbG9zZXN0KCcuc2V0dGluZ3MtY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnRhaW5lckVsLnBhcmVudEVsZW1lbnQ7XHJcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxUb3AgPSBzY3JvbGxDb250YWluZXI/LnNjcm9sbFRvcCB8fCAwO1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0c2Nyb2xsQ29udGFpbmVyLnNjcm9sbFRvcCA9IHNjcm9sbFRvcDtcclxuXHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBTaG93IHdhcm5pbmcgaWYgY3VycmVudCB0eXBlIHJlcXVpcmVzIGEgZGlzYWJsZWQgcGx1Z2luXHJcblx0XHRcdFx0XHRcdGlmIChwbHVnaW5EaXNhYmxlZCkge1xyXG5cdFx0XHRcdFx0XHRcdHNldHRpbmcuZGVzY0VsLmNyZWF0ZURpdih7XHJcblx0XHRcdFx0XHRcdFx0XHR0ZXh0OiAnVGhlIHJlcXVpcmVkIHBsdWdpbiBoYXMgbm90IGJlZW4gZW5hYmxlZCBvciBjb25maWd1cmVkIGZvciB0aGlzIHR5cGUuJyxcclxuXHRcdFx0XHRcdFx0XHRcdGNsczogJ21vZC13YXJuaW5nJ1xyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHRpZiAoIVVOQ0hBTkdFQUJMRV9UWVBFUy5pbmNsdWRlcyh0aGlzLnBsdWdpbi5zZXR0aW5ncy5tb2JpbGVIb21lQmFzZVR5cGUpKSB7XHJcblx0XHRcdFx0bW9iaWxlR3JvdXAuYWRkU2V0dGluZyhzZXR0aW5nID0+IHtcclxuXHRcdFx0XHRcdGNvbnN0IG1vYmlsZVR5cGUgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5tb2JpbGVIb21lQmFzZVR5cGU7XHJcblx0XHRcdFx0XHRsZXQgZGVzYyA9ICcnO1xyXG5cdFx0XHRcdFx0bGV0IHBsYWNlaG9sZGVyID0gJyc7XHJcblxyXG5cdFx0XHRcdFx0aWYgKG1vYmlsZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5GaWxlKSB7XHJcblx0XHRcdFx0XHRcdGRlc2MgPSAnVGhlIGZpbGUgdG8gb3BlbiBhcyB5b3VyIGhvbWUgYmFzZSBvbiBtb2JpbGUnO1xyXG5cdFx0XHRcdFx0XHRwbGFjZWhvbGRlciA9ICdQYXRoIHRvIGhvbWUgYmFzZSBmaWxlJztcclxuXHRcdFx0XHRcdH0gZWxzZSBpZiAobW9iaWxlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLldvcmtzcGFjZSkge1xyXG5cdFx0XHRcdFx0XHRkZXNjID0gJ1RoZSB3b3Jrc3BhY2UgdG8gbG9hZCBhcyB5b3VyIGhvbWUgYmFzZSBvbiBtb2JpbGUnO1xyXG5cdFx0XHRcdFx0XHRwbGFjZWhvbGRlciA9ICdXb3Jrc3BhY2UgbmFtZSc7XHJcblx0XHRcdFx0XHR9IGVsc2UgaWYgKG1vYmlsZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5SYW5kb21Gb2xkZXIpIHtcclxuXHRcdFx0XHRcdFx0ZGVzYyA9ICdUaGUgZm9sZGVyIHRvIHBpY2sgYSByYW5kb20gZmlsZSBmcm9tIG9uIG1vYmlsZSc7XHJcblx0XHRcdFx0XHRcdHBsYWNlaG9sZGVyID0gJ0ZvbGRlciBwYXRoJztcclxuXHRcdFx0XHRcdH0gZWxzZSBpZiAobW9iaWxlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLkpvdXJuYWwpIHtcclxuXHRcdFx0XHRcdFx0ZGVzYyA9ICdUaGUgam91cm5hbCBuYW1lIGZvciBtb2JpbGUnO1xyXG5cdFx0XHRcdFx0XHRwbGFjZWhvbGRlciA9ICdKb3VybmFsIG5hbWUnO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdHNldHRpbmdcclxuXHRcdFx0XHRcdFx0LnNldE5hbWUobW9iaWxlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLkZpbGUgPyAnTW9iaWxlIGZpbGUnIDpcclxuXHRcdFx0XHRcdFx0XHRtb2JpbGVUeXBlID09PSBIb21lQmFzZVR5cGUuV29ya3NwYWNlID8gJ01vYmlsZSB3b3Jrc3BhY2UnIDpcclxuXHRcdFx0XHRcdFx0XHRcdG1vYmlsZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5SYW5kb21Gb2xkZXIgPyAnTW9iaWxlIGZvbGRlcicgOlxyXG5cdFx0XHRcdFx0XHRcdFx0XHRtb2JpbGVUeXBlID09PSBIb21lQmFzZVR5cGUuSm91cm5hbCA/ICdNb2JpbGUgam91cm5hbCcgOiAnTW9iaWxlIHZhbHVlJylcclxuXHRcdFx0XHRcdFx0LnNldERlc2MoZGVzYylcclxuXHRcdFx0XHRcdFx0LmFkZFRleHQodGV4dCA9PiB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKG1vYmlsZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5GaWxlKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRuZXcgRmlsZVBhdGhTdWdnZXN0KHRoaXMuYXBwLCB0ZXh0LmlucHV0RWwpO1xyXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAobW9iaWxlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLldvcmtzcGFjZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0bmV3IFdvcmtzcGFjZVN1Z2dlc3QodGhpcy5hcHAsIHRleHQuaW5wdXRFbCk7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmIChtb2JpbGVUeXBlID09PSBIb21lQmFzZVR5cGUuUmFuZG9tRm9sZGVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRuZXcgRm9sZGVyU3VnZ2VzdCh0aGlzLmFwcCwgdGV4dC5pbnB1dEVsKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRcdHRleHRcclxuXHRcdFx0XHRcdFx0XHRcdC5zZXRQbGFjZWhvbGRlcihwbGFjZWhvbGRlcilcclxuXHRcdFx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5tb2JpbGVIb21lQmFzZVZhbHVlIHx8ICcnKVxyXG5cdFx0XHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MubW9iaWxlSG9tZUJhc2VWYWx1ZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFJlcGxhY2UgbW9iaWxlIG5ldyB0YWIgYnV0dG9uIChhbHdheXMgYXZhaWxhYmxlLCBub3QgZGVwZW5kZW50IG9uIFwiVXNlIGRpZmZlcmVudCBob21lIGJhc2UgZm9yIG5ldyB0YWJzXCIpXHJcblx0XHRtb2JpbGVHcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRzZXR0aW5nXHJcblx0XHRcdFx0LnNldE5hbWUoJ1JlcGxhY2UgbW9iaWxlIG5ldyB0YWIgYnV0dG9uJylcclxuXHRcdFx0XHQuc2V0RGVzYygnQ2hhbmdlIHRoZSBtb2JpbGUgbmV3IHRhYiBidXR0b24gdG8gYSBob21lIGljb24nKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUodG9nZ2xlID0+IHtcclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MucmVwbGFjZU1vYmlsZU5ld1RhYilcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5yZXBsYWNlTW9iaWxlTmV3VGFiID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlTW9iaWxlQnV0dG9uKCk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gTW9iaWxlIG5ldyB0YWIgc2V0dGluZ3MgKG9ubHkgc2hvdyBpZiBcIlVzZSBkaWZmZXJlbnQgZmlsZSBmb3IgbmV3IHRhYnNcIiBpcyBlbmFibGVkKVxyXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZURpZmZlcmVudEZpbGVGb3JOZXdUYWIpIHtcclxuXHRcdFx0Ly8gU2VwYXJhdGUgbW9iaWxlIG5ldyB0YWIgdG9nZ2xlXHJcblx0XHRcdG1vYmlsZUdyb3VwLmFkZFNldHRpbmcoc2V0dGluZyA9PiB7XHJcblx0XHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdFx0LnNldE5hbWUoJ1NlcGFyYXRlIG1vYmlsZSBuZXcgdGFiJylcclxuXHRcdFx0XHRcdC5zZXREZXNjKCdVc2UgYSBkaWZmZXJlbnQgbmV3IHRhYiBmaWxlIG9uIG1vYmlsZSBkZXZpY2VzJylcclxuXHRcdFx0XHRcdC5hZGRUb2dnbGUodG9nZ2xlID0+IHtcclxuXHRcdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLm5ld1RhYlNlcGFyYXRlTW9iaWxlKVxyXG5cdFx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5uZXdUYWJTZXBhcmF0ZU1vYmlsZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0Ly8gUmUtcmVuZGVyIHRvIHNob3cgbW9iaWxlIHNldHRpbmdzXHJcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxDb250YWluZXIgPSBjb250YWluZXJFbC5jbG9zZXN0KCcudmVydGljYWwtdGFiLWNvbnRlbnQnKSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRjb250YWluZXJFbC5jbG9zZXN0KCcuc2V0dGluZ3MtY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnRhaW5lckVsLnBhcmVudEVsZW1lbnQ7XHJcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxUb3AgPSBzY3JvbGxDb250YWluZXI/LnNjcm9sbFRvcCB8fCAwO1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0c2Nyb2xsQ29udGFpbmVyLnNjcm9sbFRvcCA9IHNjcm9sbFRvcDtcclxuXHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHQvLyBTaG93IG1vYmlsZS1zcGVjaWZpYyBuZXcgdGFiIHNldHRpbmdzIGlmIHNlcGFyYXRlIG1vYmlsZSBpcyBlbmFibGVkXHJcblx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5uZXdUYWJTZXBhcmF0ZU1vYmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IG1vYmlsZVR5cGUgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5tb2JpbGVOZXdUYWJUeXBlIHx8IEhvbWVCYXNlVHlwZS5GaWxlO1xyXG5cdFx0XHRcdGNvbnN0IG1vYmlsZVZhbHVlID0gdGhpcy5wbHVnaW4uc2V0dGluZ3MubW9iaWxlTmV3VGFiVmFsdWUgfHwgJyc7XHJcblxyXG5cdFx0XHRcdC8vIE1vYmlsZSBuZXcgdGFiIHR5cGUgZHJvcGRvd25cclxuXHRcdFx0XHRtb2JpbGVHcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdFx0XHQuc2V0TmFtZSgnTW9iaWxlIG5ldyB0YWIgdHlwZScpXHJcblx0XHRcdFx0XHRcdC5zZXREZXNjKCdXaGF0IHRvIG9wZW4gZm9yIG5ldyB0YWJzIG9uIG1vYmlsZScpXHJcblx0XHRcdFx0XHRcdC5hZGREcm9wZG93bihkcm9wZG93biA9PiB7XHJcblx0XHRcdFx0XHRcdFx0bGV0IHBsdWdpbkRpc2FibGVkID0gZmFsc2U7XHJcblxyXG5cdFx0XHRcdFx0XHRcdGZvciAoY29uc3QgdHlwZSBvZiBPYmplY3QudmFsdWVzKEhvbWVCYXNlVHlwZSkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICghdGhpcy5wbHVnaW4uaGFzUmVxdWlyZWRQbHVnaW4odHlwZSkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSWYgY3VycmVudCB0eXBlIGlzIGRpc2FibGVkLCBtYXJrIGl0IGJ1dCBzdGlsbCBhbGxvdyBpdFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAodHlwZSA9PT0gbW9iaWxlVHlwZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHBsdWdpbkRpc2FibGVkID0gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRkcm9wZG93bi5hZGRPcHRpb24odHlwZSwgdHlwZSk7XHJcblx0XHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gQWRkIGRpc2FibGVkIG9wdGlvblxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGRyb3Bkb3duLnNlbGVjdEVsLmNyZWF0ZUVsKCdvcHRpb24nLCB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0ZXh0OiB0eXBlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YXR0cjogeyBkaXNhYmxlZDogJ3RydWUnIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKHR5cGUsIHR5cGUpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRcdFx0ZHJvcGRvd25cclxuXHRcdFx0XHRcdFx0XHRcdC5zZXRWYWx1ZShtb2JpbGVUeXBlKVxyXG5cdFx0XHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MubW9iaWxlTmV3VGFiVHlwZSA9IHZhbHVlIGFzIEhvbWVCYXNlVHlwZTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxDb250YWluZXIgPSBjb250YWluZXJFbC5jbG9zZXN0KCcudmVydGljYWwtdGFiLWNvbnRlbnQnKSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGNvbnRhaW5lckVsLmNsb3Nlc3QoJy5zZXR0aW5ncy1jb250ZW50JykgfHxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRjb250YWluZXJFbC5wYXJlbnRFbGVtZW50O1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRjb25zdCBzY3JvbGxUb3AgPSBzY3JvbGxDb250YWluZXI/LnNjcm9sbFRvcCB8fCAwO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRzY3JvbGxDb250YWluZXIuc2Nyb2xsVG9wID0gc2Nyb2xsVG9wO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0XHR9KTtcclxuXHJcblx0XHRcdFx0XHRcdFx0Ly8gU2hvdyB3YXJuaW5nIGlmIGN1cnJlbnQgdHlwZSByZXF1aXJlcyBhIGRpc2FibGVkIHBsdWdpblxyXG5cdFx0XHRcdFx0XHRcdGlmIChwbHVnaW5EaXNhYmxlZCkge1xyXG5cdFx0XHRcdFx0XHRcdFx0c2V0dGluZy5kZXNjRWwuY3JlYXRlRGl2KHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0dGV4dDogJ1RoZSByZXF1aXJlZCBwbHVnaW4gaGFzIG5vdCBiZWVuIGVuYWJsZWQgb3IgY29uZmlndXJlZCBmb3IgdGhpcyB0eXBlLicsXHJcblx0XHRcdFx0XHRcdFx0XHRcdGNsczogJ21vZC13YXJuaW5nJ1xyXG5cdFx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9KTtcclxuXHJcblx0XHRcdFx0Ly8gTW9iaWxlIHZhbHVlIGlucHV0IChjb25kaXRpb25hbCBvbiB0eXBlKVxyXG5cdFx0XHRcdGlmICghVU5DSEFOR0VBQkxFX1RZUEVTLmluY2x1ZGVzKG1vYmlsZVR5cGUpKSB7XHJcblx0XHRcdFx0XHRtb2JpbGVHcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRcdFx0XHRsZXQgZGVzYyA9ICcnO1xyXG5cdFx0XHRcdFx0XHRsZXQgcGxhY2Vob2xkZXIgPSAnJztcclxuXHJcblx0XHRcdFx0XHRcdGlmIChtb2JpbGVUeXBlID09PSBIb21lQmFzZVR5cGUuRmlsZSkge1xyXG5cdFx0XHRcdFx0XHRcdGRlc2MgPSAnVGhlIGZpbGUgdG8gb3BlbiBmb3IgbmV3IHRhYnMgb24gbW9iaWxlJztcclxuXHRcdFx0XHRcdFx0XHRwbGFjZWhvbGRlciA9ICdQYXRoIHRvIG1vYmlsZSBuZXcgdGFiIGZpbGUnO1xyXG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKG1vYmlsZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5Xb3Jrc3BhY2UpIHtcclxuXHRcdFx0XHRcdFx0XHRkZXNjID0gJ1RoZSB3b3Jrc3BhY2UgdG8gbG9hZCBmb3IgbmV3IHRhYnMgb24gbW9iaWxlJztcclxuXHRcdFx0XHRcdFx0XHRwbGFjZWhvbGRlciA9ICdXb3Jrc3BhY2UgbmFtZSc7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAobW9iaWxlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLlJhbmRvbUZvbGRlcikge1xyXG5cdFx0XHRcdFx0XHRcdGRlc2MgPSAnVGhlIGZvbGRlciB0byBwaWNrIGEgcmFuZG9tIGZpbGUgZnJvbSBmb3IgbmV3IHRhYnMgb24gbW9iaWxlJztcclxuXHRcdFx0XHRcdFx0XHRwbGFjZWhvbGRlciA9ICdGb2xkZXIgcGF0aCc7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAobW9iaWxlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLkpvdXJuYWwpIHtcclxuXHRcdFx0XHRcdFx0XHRkZXNjID0gJ1RoZSBqb3VybmFsIG5hbWUgZm9yIG5ldyB0YWJzIG9uIG1vYmlsZSc7XHJcblx0XHRcdFx0XHRcdFx0cGxhY2Vob2xkZXIgPSAnSm91cm5hbCBuYW1lJztcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0c2V0dGluZ1xyXG5cdFx0XHRcdFx0XHRcdC5zZXROYW1lKG1vYmlsZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5GaWxlID8gJ01vYmlsZSBuZXcgdGFiIGZpbGUnIDpcclxuXHRcdFx0XHRcdFx0XHRcdG1vYmlsZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5Xb3Jrc3BhY2UgPyAnTW9iaWxlIG5ldyB0YWIgd29ya3NwYWNlJyA6XHJcblx0XHRcdFx0XHRcdFx0XHRcdG1vYmlsZVR5cGUgPT09IEhvbWVCYXNlVHlwZS5SYW5kb21Gb2xkZXIgPyAnTW9iaWxlIG5ldyB0YWIgZm9sZGVyJyA6XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0bW9iaWxlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLkpvdXJuYWwgPyAnTW9iaWxlIG5ldyB0YWIgam91cm5hbCcgOiAnTW9iaWxlIG5ldyB0YWIgdmFsdWUnKVxyXG5cdFx0XHRcdFx0XHRcdC5zZXREZXNjKGRlc2MpXHJcblx0XHRcdFx0XHRcdFx0LmFkZFRleHQodGV4dCA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAobW9iaWxlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLkZpbGUpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0bmV3IEZpbGVQYXRoU3VnZ2VzdCh0aGlzLmFwcCwgdGV4dC5pbnB1dEVsKTtcclxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAobW9iaWxlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLldvcmtzcGFjZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRuZXcgV29ya3NwYWNlU3VnZ2VzdCh0aGlzLmFwcCwgdGV4dC5pbnB1dEVsKTtcclxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAobW9iaWxlVHlwZSA9PT0gSG9tZUJhc2VUeXBlLlJhbmRvbUZvbGRlcikge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRuZXcgRm9sZGVyU3VnZ2VzdCh0aGlzLmFwcCwgdGV4dC5pbnB1dEVsKTtcclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRcdFx0XHR0ZXh0XHJcblx0XHRcdFx0XHRcdFx0XHRcdC5zZXRQbGFjZWhvbGRlcihwbGFjZWhvbGRlcilcclxuXHRcdFx0XHRcdFx0XHRcdFx0LnNldFZhbHVlKG1vYmlsZVZhbHVlIHx8ICcnKVxyXG5cdFx0XHRcdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLm1vYmlsZU5ld1RhYlZhbHVlID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQXV0b21hdGlvbiBTZXR0aW5nc1xyXG5cdFx0Y29uc3QgYXV0b21hdGlvbkdyb3VwID0gbmV3IFNldHRpbmdHcm91cChjb250YWluZXJFbCkuc2V0SGVhZGluZygnQXV0b21hdGlvbicpO1xyXG5cclxuXHRcdGF1dG9tYXRpb25Hcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRjb25zdCBjb21tYW5kSWQgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5jb21tYW5kT25PcGVuO1xyXG5cdFx0XHRjb25zdCBjb21tYW5kID0gY29tbWFuZElkID8gZ2V0Q29tbWFuZEJ5SWQodGhpcy5hcHAsIGNvbW1hbmRJZCkgOiB1bmRlZmluZWQ7XHJcblx0XHRcdGNvbnN0IGRpc3BsYXlWYWx1ZSA9IGNvbW1hbmQgPyBjb21tYW5kLm5hbWUgOiBjb21tYW5kSWQ7XHJcblxyXG5cdFx0XHRzZXR0aW5nXHJcblx0XHRcdFx0LnNldE5hbWUoJ0NvbW1hbmQgb24gb3BlbicpXHJcblx0XHRcdFx0LnNldERlc2MoJ1J1biBhbiBPYnNpZGlhbiBjb21tYW5kIHdoZW4gb3BlbmluZyBob21lIGJhc2UnKVxyXG5cdFx0XHRcdC5hZGRUZXh0KHRleHQgPT4ge1xyXG5cdFx0XHRcdFx0Ly8gQWRkIGNvbW1hbmQgc3VnZ2VzdGVyXHJcblx0XHRcdFx0XHRuZXcgQ29tbWFuZFN1Z2dlc3QodGhpcy5hcHAsIHRleHQuaW5wdXRFbCk7XHJcblxyXG5cdFx0XHRcdFx0dGV4dFxyXG5cdFx0XHRcdFx0XHQuc2V0UGxhY2Vob2xkZXIoJ1NlYXJjaCBmb3IgYSBjb21tYW5kLi4uJylcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKGRpc3BsYXlWYWx1ZSB8fCAnJylcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5jb21tYW5kT25PcGVuID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pXHJcblx0XHRcdFx0LmFkZEV4dHJhQnV0dG9uKGJ0biA9PiB7XHJcblx0XHRcdFx0XHRidG5cclxuXHRcdFx0XHRcdFx0LnNldEljb24oJ3gnKVxyXG5cdFx0XHRcdFx0XHQuc2V0VG9vbHRpcCgnQ2xlYXIgY29tbWFuZCcpXHJcblx0XHRcdFx0XHRcdC5vbkNsaWNrKGFzeW5jICgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5jb21tYW5kT25PcGVuID0gJyc7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFByZXNlcnZlIHNjcm9sbCBwb3NpdGlvbiBiZWZvcmUgcmUtcmVuZGVyaW5nXHJcblx0XHRcdFx0XHRcdFx0Y29uc3Qgc2Nyb2xsQ29udGFpbmVyID0gY29udGFpbmVyRWwuY2xvc2VzdCgnLnZlcnRpY2FsLXRhYi1jb250ZW50JykgfHxcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnRhaW5lckVsLmNsb3Nlc3QoJy5zZXR0aW5ncy1jb250ZW50JykgfHxcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnRhaW5lckVsLnBhcmVudEVsZW1lbnQ7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3Qgc2Nyb2xsVG9wID0gc2Nyb2xsQ29udGFpbmVyPy5zY3JvbGxUb3AgfHwgMDtcclxuXHJcblx0XHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFJlc3RvcmUgc2Nyb2xsIHBvc2l0aW9uIGFmdGVyIHJlbmRlcmluZ1xyXG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBzY3JvbGxUb3A7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0YXV0b21hdGlvbkdyb3VwLmFkZFNldHRpbmcoc2V0dGluZyA9PiB7XHJcblx0XHRcdHNldHRpbmdcclxuXHRcdFx0XHQuc2V0TmFtZSgnV2FpdCBmb3IgZ2l0IHN5bmMnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdXYWl0IGJlZm9yZSBjcmVhdGluZyBwZXJpb2RpYyBvciBqb3VybmFsIG5vdGVzIHRvIGFsbG93IGdpdCBzeW5jIHRvIGZpbmlzaCBwdWxsaW5nIGV4aXN0aW5nIG5vdGVzLiBPbmx5IGFwcGxpZXMgd2hlbiBhIG5vdGUgZG9lc25cXCd0IGFscmVhZHkgZXhpc3QuJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKHRvZ2dsZSA9PiB7XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLndhaXRGb3JHaXRTeW5jKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLndhaXRGb3JHaXRTeW5jID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7IC8vIFJlLXJlbmRlciB0byBzaG93L2hpZGUgdGltZW91dCBzZXR0aW5nXHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLndhaXRGb3JHaXRTeW5jKSB7XHJcblx0XHRcdGF1dG9tYXRpb25Hcm91cC5hZGRTZXR0aW5nKHNldHRpbmcgPT4ge1xyXG5cdFx0XHRcdHNldHRpbmdcclxuXHRcdFx0XHRcdC5zZXROYW1lKCdHaXQgc3luYyB0aW1lb3V0IChzZWNvbmRzKScpXHJcblx0XHRcdFx0XHQuc2V0RGVzYygnSG93IGxvbmcgdG8gd2FpdCBmb3IgZ2l0IHN5bmMgdG8gZmluaXNoIGJlZm9yZSBjcmVhdGluZyBhIG5ldyBub3RlJylcclxuXHRcdFx0XHRcdC5hZGRUZXh0KHRleHQgPT4ge1xyXG5cdFx0XHRcdFx0XHR0ZXh0LmlucHV0RWwudHlwZSA9ICdudW1iZXInO1xyXG5cdFx0XHRcdFx0XHR0ZXh0XHJcblx0XHRcdFx0XHRcdFx0LnNldFBsYWNlaG9sZGVyKCczJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZ2l0U3luY1RpbWVvdXQ/LnRvU3RyaW5nKCkgfHwgJzMnKVxyXG5cdFx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBudW1WYWx1ZSA9IHBhcnNlSW50KHZhbHVlKTtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICghaXNOYU4obnVtVmFsdWUpICYmIG51bVZhbHVlID49IDApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZ2l0U3luY1RpbWVvdXQgPSBudW1WYWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0fVxyXG59XHJcbiIsICIvKipcclxuICogRmlsZSBQYXRoIFN1Z2dlc3RlciBDb21wb25lbnRcclxuICogUHJvdmlkZXMgYXV0b2NvbXBsZXRlIGZvciBmaWxlIHBhdGhzIGluIHNldHRpbmdzXHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgQWJzdHJhY3RJbnB1dFN1Z2dlc3QsIEFwcCwgVEZpbGUsIFRGb2xkZXIgfSBmcm9tICdvYnNpZGlhbic7XHJcblxyXG4vKipcclxuICogU3VwcG9ydGVkIGZpbGUgZXh0ZW5zaW9ucyBmb3IgaG9tZSBiYXNlXHJcbiAqL1xyXG5jb25zdCBTVVBQT1JURURfRVhURU5TSU9OUyA9IFsnbWQnLCAnbWR4JywgJ2NhbnZhcycsICdiYXNlJ107XHJcblxyXG4vKipcclxuICogRmlsZSBwYXRoIHN1Z2dlc3RlciB0aGF0IHByb3ZpZGVzIGF1dG9jb21wbGV0ZSBmb3IgdmF1bHQgZmlsZXNcclxuICovXHJcbmV4cG9ydCBjbGFzcyBGaWxlUGF0aFN1Z2dlc3QgZXh0ZW5kcyBBYnN0cmFjdElucHV0U3VnZ2VzdDxURmlsZT4ge1xyXG5cdHByaXZhdGUgaW5wdXRFbDogSFRNTElucHV0RWxlbWVudDtcclxuXHJcblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIGlucHV0RWw6IEhUTUxJbnB1dEVsZW1lbnQpIHtcclxuXHRcdHN1cGVyKGFwcCwgaW5wdXRFbCk7XHJcblx0XHR0aGlzLmlucHV0RWwgPSBpbnB1dEVsO1xyXG5cdH1cclxuXHJcblx0Z2V0U3VnZ2VzdGlvbnMocXVlcnk6IHN0cmluZyk6IFRGaWxlW10ge1xyXG5cdFx0Y29uc3QgbG93ZXJRdWVyeSA9IHF1ZXJ5LnRvTG93ZXJDYXNlKCk7XHJcblx0XHRjb25zdCBmaWxlczogVEZpbGVbXSA9IFtdO1xyXG5cclxuXHRcdC8vIEdldCBhbGwgZmlsZXMgZnJvbSB2YXVsdFxyXG5cdFx0dGhpcy5hcHAudmF1bHQuZ2V0QWxsTG9hZGVkRmlsZXMoKS5mb3JFYWNoKChmaWxlKSA9PiB7XHJcblx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHQvLyBPbmx5IGluY2x1ZGUgc3VwcG9ydGVkIGZpbGUgdHlwZXNcclxuXHRcdFx0XHRpZiAoU1VQUE9SVEVEX0VYVEVOU0lPTlMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pKSB7XHJcblx0XHRcdFx0XHQvLyBNYXRjaCBhZ2FpbnN0IHBhdGggb3IgbmFtZVxyXG5cdFx0XHRcdFx0aWYgKFxyXG5cdFx0XHRcdFx0XHRmaWxlLnBhdGgudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhsb3dlclF1ZXJ5KSB8fFxyXG5cdFx0XHRcdFx0XHRmaWxlLmJhc2VuYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMobG93ZXJRdWVyeSlcclxuXHRcdFx0XHRcdCkge1xyXG5cdFx0XHRcdFx0XHRmaWxlcy5wdXNoKGZpbGUpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gU29ydCBieSByZWxldmFuY2UgKGV4YWN0IG1hdGNoZXMgZmlyc3QsIHRoZW4gYWxwaGFiZXRpY2FsbHkpXHJcblx0XHRmaWxlcy5zb3J0KChhLCBiKSA9PiB7XHJcblx0XHRcdGNvbnN0IGFTdGFydHNXaXRoID0gYS5wYXRoLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChsb3dlclF1ZXJ5KTtcclxuXHRcdFx0Y29uc3QgYlN0YXJ0c1dpdGggPSBiLnBhdGgudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKGxvd2VyUXVlcnkpO1xyXG5cclxuXHRcdFx0aWYgKGFTdGFydHNXaXRoICYmICFiU3RhcnRzV2l0aCkgcmV0dXJuIC0xO1xyXG5cdFx0XHRpZiAoIWFTdGFydHNXaXRoICYmIGJTdGFydHNXaXRoKSByZXR1cm4gMTtcclxuXHJcblx0XHRcdHJldHVybiBhLnBhdGgubG9jYWxlQ29tcGFyZShiLnBhdGgpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gTGltaXQgcmVzdWx0c1xyXG5cdFx0cmV0dXJuIGZpbGVzLnNsaWNlKDAsIDIwKTtcclxuXHR9XHJcblxyXG5cdHJlbmRlclN1Z2dlc3Rpb24oZmlsZTogVEZpbGUsIGVsOiBIVE1MRWxlbWVudCk6IHZvaWQge1xyXG5cdFx0ZWwuYWRkQ2xhc3MoJ2hvbWUtYmFzZS1zdWdnZXN0aW9uLWl0ZW0nKTtcclxuXHJcblx0XHQvLyBTaG93IGZpbGUgbmFtZSBwcm9taW5lbnRseVxyXG5cdFx0Y29uc3QgdGl0bGVFbCA9IGVsLmNyZWF0ZUVsKCdkaXYnLCB7XHJcblx0XHRcdGNsczogJ3N1Z2dlc3Rpb24tdGl0bGUnXHJcblx0XHR9KTtcclxuXHRcdHRpdGxlRWwuY3JlYXRlRWwoJ3NwYW4nLCB7IHRleHQ6IGZpbGUuYmFzZW5hbWUgfSk7XHJcblxyXG5cdFx0Ly8gU2hvdyBmaWxlIHR5cGUgaW5kaWNhdG9yIG5leHQgdG8gdGl0bGVcclxuXHRcdGlmIChmaWxlLmV4dGVuc2lvbiAhPT0gJ21kJykge1xyXG5cdFx0XHR0aXRsZUVsLmNyZWF0ZUVsKCdzcGFuJywge1xyXG5cdFx0XHRcdHRleHQ6IGZpbGUuZXh0ZW5zaW9uLnRvVXBwZXJDYXNlKCksXHJcblx0XHRcdFx0Y2xzOiAnc3VnZ2VzdGlvbi1mbGFpcidcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gU2hvdyBwYXRoIGluIHNtYWxsZXIgdGV4dCBpZiBkaWZmZXJlbnQgZnJvbSBiYXNlbmFtZVxyXG5cdFx0aWYgKGZpbGUucGFyZW50ICYmIGZpbGUucGFyZW50LnBhdGggIT09ICcvJykge1xyXG5cdFx0XHRlbC5jcmVhdGVFbCgnZGl2Jywge1xyXG5cdFx0XHRcdHRleHQ6IGZpbGUucGFyZW50LnBhdGgsXHJcblx0XHRcdFx0Y2xzOiAnc3VnZ2VzdGlvbi1ub3RlJ1xyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHNlbGVjdFN1Z2dlc3Rpb24oZmlsZTogVEZpbGUpOiB2b2lkIHtcclxuXHRcdHRoaXMuaW5wdXRFbC52YWx1ZSA9IGZpbGUucGF0aDtcclxuXHRcdHRoaXMuaW5wdXRFbC50cmlnZ2VyKCdpbnB1dCcpO1xyXG5cdFx0dGhpcy5jbG9zZSgpO1xyXG5cdH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEZvbGRlciBwYXRoIHN1Z2dlc3RlciBmb3Igc2VsZWN0aW5nIGZvbGRlcnNcclxuICovXHJcbmV4cG9ydCBjbGFzcyBGb2xkZXJTdWdnZXN0IGV4dGVuZHMgQWJzdHJhY3RJbnB1dFN1Z2dlc3Q8VEZvbGRlcj4ge1xyXG5cdHByaXZhdGUgaW5wdXRFbDogSFRNTElucHV0RWxlbWVudDtcclxuXHJcblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIGlucHV0RWw6IEhUTUxJbnB1dEVsZW1lbnQpIHtcclxuXHRcdHN1cGVyKGFwcCwgaW5wdXRFbCk7XHJcblx0XHR0aGlzLmlucHV0RWwgPSBpbnB1dEVsO1xyXG5cdH1cclxuXHJcblx0Z2V0U3VnZ2VzdGlvbnMocXVlcnk6IHN0cmluZyk6IFRGb2xkZXJbXSB7XHJcblx0XHRjb25zdCBsb3dlclF1ZXJ5ID0gcXVlcnkudG9Mb3dlckNhc2UoKTtcclxuXHRcdGNvbnN0IGZvbGRlcnM6IFRGb2xkZXJbXSA9IFtdO1xyXG5cclxuXHRcdHRoaXMuYXBwLnZhdWx0LmdldEFsbExvYWRlZEZpbGVzKCkuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRpZiAoZmlsZS5wYXRoLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMobG93ZXJRdWVyeSkpIHtcclxuXHRcdFx0XHRcdGZvbGRlcnMucHVzaChmaWxlKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdGZvbGRlcnMuc29ydCgoYSwgYikgPT4gYS5wYXRoLmxvY2FsZUNvbXBhcmUoYi5wYXRoKSk7XHJcblx0XHRyZXR1cm4gZm9sZGVycy5zbGljZSgwLCAyMCk7XHJcblx0fVxyXG5cclxuXHRyZW5kZXJTdWdnZXN0aW9uKGZvbGRlcjogVEZvbGRlciwgZWw6IEhUTUxFbGVtZW50KTogdm9pZCB7XHJcblx0XHRlbC5jcmVhdGVFbCgnZGl2JywgeyB0ZXh0OiBmb2xkZXIucGF0aCB8fCAnLycgfSk7XHJcblx0fVxyXG5cclxuXHRzZWxlY3RTdWdnZXN0aW9uKGZvbGRlcjogVEZvbGRlcik6IHZvaWQge1xyXG5cdFx0dGhpcy5pbnB1dEVsLnZhbHVlID0gZm9sZGVyLnBhdGg7XHJcblx0XHR0aGlzLmlucHV0RWwudHJpZ2dlcignaW5wdXQnKTtcclxuXHRcdHRoaXMuY2xvc2UoKTtcclxuXHR9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBXb3Jrc3BhY2Ugc3VnZ2VzdGVyIGZvciBzZWxlY3RpbmcgT2JzaWRpYW4gd29ya3NwYWNlc1xyXG4gKi9cclxuZXhwb3J0IGNsYXNzIFdvcmtzcGFjZVN1Z2dlc3QgZXh0ZW5kcyBBYnN0cmFjdElucHV0U3VnZ2VzdDxzdHJpbmc+IHtcclxuXHRwcml2YXRlIGlucHV0RWw6IEhUTUxJbnB1dEVsZW1lbnQ7XHJcblxyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBpbnB1dEVsOiBIVE1MSW5wdXRFbGVtZW50KSB7XHJcblx0XHRzdXBlcihhcHAsIGlucHV0RWwpO1xyXG5cdFx0dGhpcy5pbnB1dEVsID0gaW5wdXRFbDtcclxuXHR9XHJcblxyXG5cdGdldFN1Z2dlc3Rpb25zKHF1ZXJ5OiBzdHJpbmcpOiBzdHJpbmdbXSB7XHJcblxyXG5cdFx0Y29uc3Qgd29ya3NwYWNlc1BsdWdpbiA9IHRoaXMuYXBwLmludGVybmFsUGx1Z2lucz8ucGx1Z2lucz8ud29ya3NwYWNlcztcclxuXHJcblx0XHRpZiAoIXdvcmtzcGFjZXNQbHVnaW4/LmVuYWJsZWQgfHwgIXdvcmtzcGFjZXNQbHVnaW4uaW5zdGFuY2U/LndvcmtzcGFjZXMpIHtcclxuXHRcdFx0cmV0dXJuIFtdO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0XHRjb25zdCB3b3Jrc3BhY2VzID0gT2JqZWN0LmtleXMod29ya3NwYWNlc1BsdWdpbi5pbnN0YW5jZS53b3Jrc3BhY2VzKTtcclxuXHRcdGNvbnN0IGxvd2VyUXVlcnkgPSBxdWVyeS50b0xvd2VyQ2FzZSgpO1xyXG5cclxuXHRcdHJldHVybiB3b3Jrc3BhY2VzLmZpbHRlcigod29ya3NwYWNlOiBzdHJpbmcpID0+XHJcblx0XHRcdHdvcmtzcGFjZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGxvd2VyUXVlcnkpXHJcblx0XHQpO1xyXG5cdH1cclxuXHJcblx0cmVuZGVyU3VnZ2VzdGlvbih3b3Jrc3BhY2U6IHN0cmluZywgZWw6IEhUTUxFbGVtZW50KTogdm9pZCB7XHJcblx0XHRlbC5jcmVhdGVFbCgnZGl2JywgeyB0ZXh0OiB3b3Jrc3BhY2UgfSk7XHJcblx0fVxyXG5cclxuXHRzZWxlY3RTdWdnZXN0aW9uKHdvcmtzcGFjZTogc3RyaW5nKTogdm9pZCB7XHJcblx0XHR0aGlzLmlucHV0RWwudmFsdWUgPSB3b3Jrc3BhY2U7XHJcblx0XHR0aGlzLmlucHV0RWwudHJpZ2dlcignaW5wdXQnKTtcclxuXHRcdHRoaXMuY2xvc2UoKTtcclxuXHR9XHJcbn0iLCAiLyoqXHJcbiAqIENvbW1hbmQgU3VnZ2VzdGVyIENvbXBvbmVudFxyXG4gKiBQcm92aWRlcyBhdXRvY29tcGxldGUgZm9yIE9ic2lkaWFuIGNvbW1hbmRzIGluIHNldHRpbmdzXHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgQWJzdHJhY3RJbnB1dFN1Z2dlc3QsIEFwcCwgQ29tbWFuZCB9IGZyb20gJ29ic2lkaWFuJztcclxuXHJcbi8qKlxyXG4gKiBDb21tYW5kIHN1Z2dlc3RlciB0aGF0IHByb3ZpZGVzIGF1dG9jb21wbGV0ZSBmb3IgT2JzaWRpYW4gY29tbWFuZHNcclxuICovXHJcbmV4cG9ydCBjbGFzcyBDb21tYW5kU3VnZ2VzdCBleHRlbmRzIEFic3RyYWN0SW5wdXRTdWdnZXN0PENvbW1hbmQ+IHtcclxuXHRwcml2YXRlIGlucHV0RWw6IEhUTUxJbnB1dEVsZW1lbnQ7XHJcblxyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBpbnB1dEVsOiBIVE1MSW5wdXRFbGVtZW50KSB7XHJcblx0XHRzdXBlcihhcHAsIGlucHV0RWwpO1xyXG5cdFx0dGhpcy5pbnB1dEVsID0gaW5wdXRFbDtcclxuXHR9XHJcblxyXG5cdGdldFN1Z2dlc3Rpb25zKHF1ZXJ5OiBzdHJpbmcpOiBDb21tYW5kW10ge1xyXG5cdFx0Y29uc3QgbG93ZXJRdWVyeSA9IHF1ZXJ5LnRvTG93ZXJDYXNlKCk7XHJcblx0XHRjb25zdCBjb21tYW5kczogQ29tbWFuZFtdID0gW107XHJcblxyXG5cdFx0Ly8gR2V0IGFsbCBjb21tYW5kcyBmcm9tIHRoZSBhcHBcclxuXHRcdGNvbnN0IGFwcFdpdGhDb21tYW5kcyA9IHRoaXMuYXBwIGFzIEFwcCAmIHsgXHJcblx0XHRcdGNvbW1hbmRzPzogeyBjb21tYW5kcz86IFJlY29yZDxzdHJpbmcsIENvbW1hbmQ+IH0gXHJcblx0XHR9O1xyXG5cdFx0Y29uc3QgYWxsQ29tbWFuZHMgPSBhcHBXaXRoQ29tbWFuZHMuY29tbWFuZHM/LmNvbW1hbmRzO1xyXG5cdFx0XHJcblx0XHRpZiAoYWxsQ29tbWFuZHMpIHtcclxuXHRcdFx0Zm9yIChjb25zdCBjb21tYW5kIG9mIE9iamVjdC52YWx1ZXMoYWxsQ29tbWFuZHMpKSB7XHJcblx0XHRcdFx0aWYgKGNvbW1hbmQubmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGxvd2VyUXVlcnkpIHx8XHJcblx0XHRcdFx0XHRjb21tYW5kLmlkLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMobG93ZXJRdWVyeSkpIHtcclxuXHRcdFx0XHRcdGNvbW1hbmRzLnB1c2goY29tbWFuZCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gU29ydCBhbHBoYWJldGljYWxseSBieSBuYW1lXHJcblx0XHRjb21tYW5kcy5zb3J0KChhLCBiKSA9PiBhLm5hbWUubG9jYWxlQ29tcGFyZShiLm5hbWUpKTtcclxuXHJcblx0XHQvLyBMaW1pdCByZXN1bHRzXHJcblx0XHRyZXR1cm4gY29tbWFuZHMuc2xpY2UoMCwgMzApO1xyXG5cdH1cclxuXHJcblx0cmVuZGVyU3VnZ2VzdGlvbihjb21tYW5kOiBDb21tYW5kLCBlbDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcclxuXHRcdGVsLmNyZWF0ZUVsKCdkaXYnLCB7IFxyXG5cdFx0XHR0ZXh0OiBjb21tYW5kLm5hbWUsXHJcblx0XHRcdGNsczogJ3N1Z2dlc3Rpb24tdGl0bGUnXHJcblx0XHR9KTtcclxuXHRcdFxyXG5cdFx0ZWwuY3JlYXRlRWwoJ3NtYWxsJywgeyBcclxuXHRcdFx0dGV4dDogY29tbWFuZC5pZCxcclxuXHRcdFx0Y2xzOiAnc3VnZ2VzdGlvbi1ub3RlJ1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRzZWxlY3RTdWdnZXN0aW9uKGNvbW1hbmQ6IENvbW1hbmQpOiB2b2lkIHtcclxuXHRcdHRoaXMuaW5wdXRFbC52YWx1ZSA9IGNvbW1hbmQuaWQ7XHJcblx0XHR0aGlzLmlucHV0RWwudHJpZ2dlcignaW5wdXQnKTtcclxuXHRcdHRoaXMuY2xvc2UoKTtcclxuXHR9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFeHRlbmRlZCBBcHAgaW50ZXJmYWNlIHdpdGggY29tbWFuZHNcclxuICovXHJcbmludGVyZmFjZSBBcHBXaXRoQ29tbWFuZHMgZXh0ZW5kcyBBcHAge1xyXG5cdGNvbW1hbmRzPzoge1xyXG5cdFx0Y29tbWFuZHM/OiBSZWNvcmQ8c3RyaW5nLCBDb21tYW5kPjtcclxuXHRcdGV4ZWN1dGVDb21tYW5kQnlJZD86IChjb21tYW5kSWQ6IHN0cmluZykgPT4gYm9vbGVhbiB8IFByb21pc2U8dm9pZD47XHJcblx0fTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBhIGNvbW1hbmQgYnkgaXRzIElEXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29tbWFuZEJ5SWQoYXBwOiBBcHAsIGNvbW1hbmRJZDogc3RyaW5nKTogQ29tbWFuZCB8IHVuZGVmaW5lZCB7XHJcblx0Y29uc3QgYXBwV2l0aENvbW1hbmRzID0gYXBwIGFzIEFwcFdpdGhDb21tYW5kcztcclxuXHRjb25zdCBjb21tYW5kcyA9IGFwcFdpdGhDb21tYW5kcy5jb21tYW5kcz8uY29tbWFuZHM7XHJcblx0cmV0dXJuIGNvbW1hbmRzPy5bY29tbWFuZElkXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEV4ZWN1dGUgYSBjb21tYW5kIGJ5IGl0cyBJRFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGV4ZWN1dGVDb21tYW5kKGFwcDogQXBwLCBjb21tYW5kSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG5cdGlmICghY29tbWFuZElkKSByZXR1cm4gZmFsc2U7XHJcblx0XHJcblx0Y29uc3QgYXBwV2l0aENvbW1hbmRzID0gYXBwIGFzIEFwcFdpdGhDb21tYW5kcztcclxuXHRjb25zdCByZXN1bHQgPSBhcHBXaXRoQ29tbWFuZHMuY29tbWFuZHM/LmV4ZWN1dGVDb21tYW5kQnlJZD8uKGNvbW1hbmRJZCk7XHJcblx0cmV0dXJuIHJlc3VsdCAhPT0gZmFsc2U7XHJcbn1cclxuIiwgIi8qKlxyXG4gKiBJY29uIFBpY2tlciBNb2RhbFxyXG4gKiBTaW1wbGlmaWVkIGljb24gcGlja2VyIGZvciBzZWxlY3Rpbmcgc3RpY2t5IGljb25cclxuICogQmFzZWQgb24gaWNvbmljIHBsdWdpbidzIGljb24gcGlja2VyXHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgQXBwLCBCdXR0b25Db21wb25lbnQsIE1vZGFsLCBQbGF0Zm9ybSwgU2V0dGluZywgVGV4dENvbXBvbmVudCwgcHJlcGFyZUZ1enp5U2VhcmNoLCBzZXRJY29uLCBnZXRJY29uSWRzIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBJY29uUGlja2VyQ2FsbGJhY2sge1xyXG5cdChpY29uOiBzdHJpbmcgfCBudWxsKTogdm9pZDtcclxufVxyXG5cclxuLyoqXHJcbiAqIFNpbXBsaWZpZWQgaWNvbiBwaWNrZXIgbW9kYWxcclxuICovXHJcbmV4cG9ydCBjbGFzcyBJY29uUGlja2VyIGV4dGVuZHMgTW9kYWwge1xyXG5cdHByaXZhdGUgc2VsZWN0ZWRJY29uOiBzdHJpbmcgfCBudWxsO1xyXG5cdHByaXZhdGUgY2FsbGJhY2s6IEljb25QaWNrZXJDYWxsYmFjaztcclxuXHRwcml2YXRlIHNlYXJjaEZpZWxkOiBUZXh0Q29tcG9uZW50O1xyXG5cdHByaXZhdGUgc2VhcmNoUmVzdWx0czogW2ljb246IHN0cmluZywgaWNvbk5hbWU6IHN0cmluZ11bXSA9IFtdO1xyXG5cdHByaXZhdGUgc2VhcmNoUmVzdWx0c1NldHRpbmc6IFNldHRpbmc7XHJcblxyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBjdXJyZW50SWNvbjogc3RyaW5nIHwgbnVsbCwgY2FsbGJhY2s6IEljb25QaWNrZXJDYWxsYmFjaykge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMuc2VsZWN0ZWRJY29uID0gY3VycmVudEljb247XHJcblx0XHR0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XHJcblx0fVxyXG5cclxuXHRvbk9wZW4oKTogdm9pZCB7XHJcblx0XHR0aGlzLmNvbnRhaW5lckVsLmFkZENsYXNzKCdtb2QtY29uZmlybWF0aW9uJyk7XHJcblx0XHR0aGlzLm1vZGFsRWwuYWRkQ2xhc3MoJ2ljb25pYy1pY29uLXBpY2tlcicpO1xyXG5cdFx0dGhpcy5zZXRUaXRsZSgnQ2hhbmdlIGljb24nKTtcclxuXHJcblx0XHQvLyBTZWFyY2ggZmllbGRcclxuXHRcdGNvbnN0IHNlYXJjaFNldHRpbmcgPSBuZXcgU2V0dGluZyh0aGlzLmNvbnRlbnRFbCk7XHJcblx0XHRpZiAoIVBsYXRmb3JtLmlzUGhvbmUpIHtcclxuXHRcdFx0c2VhcmNoU2V0dGluZy5zZXROYW1lKCdTZWFyY2gnKTtcclxuXHRcdH1cclxuXHRcdHNlYXJjaFNldHRpbmcuYWRkU2VhcmNoKChzZWFyY2hGaWVsZCkgPT4ge1xyXG5cdFx0XHRzZWFyY2hGaWVsZFxyXG5cdFx0XHRcdC5zZXRQbGFjZWhvbGRlcignU2VhcmNoIGljb25zLi4uJylcclxuXHRcdFx0XHQub25DaGFuZ2UoKCkgPT4gdGhpcy51cGRhdGVTZWFyY2hSZXN1bHRzKCkpO1xyXG5cdFx0XHRzZWFyY2hGaWVsZC5pbnB1dEVsLmVudGVyS2V5SGludCA9ICdnbyc7XHJcblx0XHRcdHRoaXMuc2VhcmNoRmllbGQgPSBzZWFyY2hGaWVsZDtcclxuXHRcdH0pO1xyXG5cdFx0aWYgKHRoaXMuc2VsZWN0ZWRJY29uKSB7XHJcblx0XHRcdHRoaXMuc2VhcmNoRmllbGQuc2V0VmFsdWUodGhpcy5zZWxlY3RlZEljb24pO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFNlYXJjaCByZXN1bHRzXHJcblx0XHR0aGlzLnNlYXJjaFJlc3VsdHNTZXR0aW5nID0gbmV3IFNldHRpbmcodGhpcy5jb250ZW50RWwpO1xyXG5cdFx0dGhpcy5zZWFyY2hSZXN1bHRzU2V0dGluZy5zZXR0aW5nRWwuYWRkQ2xhc3MoJ2ljb25pYy1zZWFyY2gtcmVzdWx0cycpO1xyXG5cdFx0dGhpcy5zZWFyY2hSZXN1bHRzU2V0dGluZy5zZXR0aW5nRWwudGFiSW5kZXggPSAwO1xyXG5cdFx0XHJcblx0XHQvLyBBbGxvdyB2ZXJ0aWNhbCBzY3JvbGxpbmcgdG8gd29yayBob3Jpem9udGFsbHlcclxuXHRcdHRoaXMuc2VhcmNoUmVzdWx0c1NldHRpbmcuc2V0dGluZ0VsLmFkZEV2ZW50TGlzdGVuZXIoJ3doZWVsJywgKGV2ZW50KSA9PiB7XHJcblx0XHRcdGlmIChkb2N1bWVudC5ib2R5Lmhhc0NsYXNzKCdtb2QtcnRsJykpIHtcclxuXHRcdFx0XHR0aGlzLnNlYXJjaFJlc3VsdHNTZXR0aW5nLnNldHRpbmdFbC5zY3JvbGxMZWZ0IC09IGV2ZW50LmRlbHRhWTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR0aGlzLnNlYXJjaFJlc3VsdHNTZXR0aW5nLnNldHRpbmdFbC5zY3JvbGxMZWZ0ICs9IGV2ZW50LmRlbHRhWTtcclxuXHRcdFx0fVxyXG5cdFx0fSwgeyBwYXNzaXZlOiB0cnVlIH0pO1xyXG5cclxuXHRcdC8vIEJ1dHRvbnMgLSBtYXRjaCBpY29uaWMncyBidXR0b24gbGF5b3V0XHJcblx0XHRjb25zdCBidXR0b25Db250YWluZXIgPSB0aGlzLm1vZGFsRWwuY3JlYXRlRGl2KHsgY2xzOiAnbW9kYWwtYnV0dG9uLWNvbnRhaW5lcicgfSk7XHJcblxyXG5cdFx0Ly8gQ2FuY2VsXHJcblx0XHRuZXcgQnV0dG9uQ29tcG9uZW50KGJ1dHRvbkNvbnRhaW5lcilcclxuXHRcdFx0LnNldEJ1dHRvblRleHQoJ0NhbmNlbCcpXHJcblx0XHRcdC5vbkNsaWNrKCgpID0+IHRoaXMuY2xvc2UoKSlcclxuXHRcdFx0LmJ1dHRvbkVsLmFkZENsYXNzKCdtb2QtY2FuY2VsJyk7XHJcblxyXG5cdFx0Ly8gU2F2ZVxyXG5cdFx0bmV3IEJ1dHRvbkNvbXBvbmVudChidXR0b25Db250YWluZXIpXHJcblx0XHRcdC5zZXRCdXR0b25UZXh0KCdTYXZlJylcclxuXHRcdFx0LnNldEN0YSgpXHJcblx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHR0aGlzLmNhbGxiYWNrKHRoaXMuc2VsZWN0ZWRJY29uKTtcclxuXHRcdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdC8vIEF1dG8tZm9jdXMgc2VhcmNoIGZpZWxkXHJcblx0XHRyZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG5cdFx0XHR0aGlzLnNlYXJjaEZpZWxkLmlucHV0RWwuc2VsZWN0KCk7XHJcblx0XHRcdHRoaXMudXBkYXRlU2VhcmNoUmVzdWx0cygpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBVcGRhdGUgc2VhcmNoIHJlc3VsdHMgYmFzZWQgb24gY3VycmVudCBxdWVyeVxyXG5cdCAqL1xyXG5cdHByaXZhdGUgdXBkYXRlU2VhcmNoUmVzdWx0cygpOiB2b2lkIHtcclxuXHRcdGNvbnN0IHF1ZXJ5ID0gdGhpcy5zZWFyY2hGaWVsZC5nZXRWYWx1ZSgpLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xyXG5cdFx0Y29uc3QgZnV6enlTZWFyY2ggPSBwcmVwYXJlRnV6enlTZWFyY2gocXVlcnkpO1xyXG5cdFx0Y29uc3QgbWF0Y2hlczogW3Njb3JlOiBudW1iZXIsIGljb25FbnRyeTogW3N0cmluZywgc3RyaW5nXV1bXSA9IFtdO1xyXG5cclxuXHRcdC8vIEdldCBhbGwgYXZhaWxhYmxlIGljb25zXHJcblx0XHRjb25zdCBpY29uSWRzID0gZ2V0SWNvbklkcygpO1xyXG5cclxuXHRcdC8vIFNlYXJjaCBpY29uc1xyXG5cdFx0aWYgKHF1ZXJ5KSB7XHJcblx0XHRcdGZvciAoY29uc3QgaWNvbklkIG9mIGljb25JZHMpIHtcclxuXHRcdFx0XHQvLyBDcmVhdGUgYSByZWFkYWJsZSBuYW1lIGZyb20gaWNvbiBJRFxyXG5cdFx0XHRcdGNvbnN0IGljb25OYW1lID0gdGhpcy5mb3JtYXRJY29uTmFtZShpY29uSWQpO1xyXG5cdFx0XHRcdFxyXG5cdFx0XHRcdGlmIChpY29uSWQgPT09IHF1ZXJ5IHx8IGljb25JZC50b0xvd2VyQ2FzZSgpID09PSBxdWVyeSkge1xyXG5cdFx0XHRcdFx0bWF0Y2hlcy5wdXNoKFswLCBbaWNvbklkLCBpY29uTmFtZV1dKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0Y29uc3QgZnV6enlNYXRjaCA9IGZ1enp5U2VhcmNoKGljb25OYW1lKTtcclxuXHRcdFx0XHRcdGlmIChmdXp6eU1hdGNoKSB7XHJcblx0XHRcdFx0XHRcdG1hdGNoZXMucHVzaChbZnV6enlNYXRjaC5zY29yZSwgW2ljb25JZCwgaWNvbk5hbWVdXSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHQvLyBTaG93IGFsbCBpY29ucyBpZiBubyBxdWVyeVxyXG5cdFx0XHRmb3IgKGNvbnN0IGljb25JZCBvZiBpY29uSWRzKSB7XHJcblx0XHRcdFx0Y29uc3QgaWNvbk5hbWUgPSB0aGlzLmZvcm1hdEljb25OYW1lKGljb25JZCk7XHJcblx0XHRcdFx0bWF0Y2hlcy5wdXNoKFswLCBbaWNvbklkLCBpY29uTmFtZV1dKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFNvcnQgYnkgc2NvcmVcclxuXHRcdG1hdGNoZXMuc29ydCgoW3Njb3JlQV0sIFtzY29yZUJdKSA9PiBzY29yZUEgPiBzY29yZUIgPyAtMSA6ICsxKTtcclxuXHJcblx0XHQvLyBMaW1pdCByZXN1bHRzXHJcblx0XHR0aGlzLnNlYXJjaFJlc3VsdHMubGVuZ3RoID0gMDtcclxuXHRcdGNvbnN0IG1heFJlc3VsdHMgPSAxMDA7XHJcblx0XHRmb3IgKGNvbnN0IFssIGljb25FbnRyeV0gb2YgbWF0Y2hlcykge1xyXG5cdFx0XHR0aGlzLnNlYXJjaFJlc3VsdHMucHVzaChpY29uRW50cnkpO1xyXG5cdFx0XHRpZiAodGhpcy5zZWFyY2hSZXN1bHRzLmxlbmd0aCA+PSBtYXhSZXN1bHRzKSBicmVhaztcclxuXHRcdH1cclxuXHJcblx0XHQvLyBVcGRhdGUgVUkgLSB1c2UgRXh0cmFCdXR0b25Db21wb25lbnQgbGlrZSBpY29uaWNcclxuXHRcdHRoaXMuc2VhcmNoUmVzdWx0c1NldHRpbmcuY2xlYXIoKTtcclxuXHRcdGZvciAoY29uc3QgW2ljb25JZCwgaWNvbk5hbWVdIG9mIHRoaXMuc2VhcmNoUmVzdWx0cykge1xyXG5cdFx0XHR0aGlzLnNlYXJjaFJlc3VsdHNTZXR0aW5nLmFkZEV4dHJhQnV0dG9uKChpY29uQnV0dG9uKSA9PiB7XHJcblx0XHRcdFx0aWNvbkJ1dHRvbi5zZXRUb29sdGlwKGljb25OYW1lLCB7XHJcblx0XHRcdFx0XHRkZWxheTogMzAwLFxyXG5cdFx0XHRcdFx0cGxhY2VtZW50OiBQbGF0Zm9ybS5pc1Bob25lID8gJ3RvcCcgOiAnYm90dG9tJyxcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0XHRjb25zdCBpY29uRWwgPSBpY29uQnV0dG9uLmV4dHJhU2V0dGluZ3NFbDtcclxuXHRcdFx0XHRpY29uRWwuYWRkQ2xhc3MoJ2ljb25pYy1zZWFyY2gtcmVzdWx0Jyk7XHJcblx0XHRcdFx0aWNvbkVsLnRhYkluZGV4ID0gLTE7XHJcblxyXG5cdFx0XHRcdHNldEljb24oaWNvbkVsLCBpY29uSWQpO1xyXG5cclxuXHRcdFx0XHQvLyBIaWdobGlnaHQgc2VsZWN0ZWQgaWNvblxyXG5cdFx0XHRcdGlmIChpY29uSWQgPT09IHRoaXMuc2VsZWN0ZWRJY29uKSB7XHJcblx0XHRcdFx0XHRpY29uRWwuYWRkQ2xhc3MoJ2lzLXNlbGVjdGVkJyk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpY29uRWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLnNlbGVjdGVkSWNvbiA9IGljb25JZDtcclxuXHRcdFx0XHRcdHRoaXMuY2FsbGJhY2soaWNvbklkKTtcclxuXHRcdFx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdFx0XHR9KTtcclxuXHJcblx0XHRcdFx0Ly8gTW9iaWxlOiBzaG93IHRvb2x0aXAgb24gbG9uZyBwcmVzc1xyXG5cdFx0XHRcdGlmIChQbGF0Zm9ybS5pc1Bob25lKSB7XHJcblx0XHRcdFx0XHRpY29uRWwuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCAoKSA9PiB7XHJcblx0XHRcdFx0XHRcdG5hdmlnYXRvci52aWJyYXRlPy4oMTAwKTtcclxuXHRcdFx0XHRcdFx0Ly8gVG9vbHRpcCBpcyBhbHJlYWR5IHNldCBhYm92ZVxyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBVc2UgYW4gaW52aXNpYmxlIGJ1dHRvbiB0byBwcmVzZXJ2ZSBoZWlnaHQgaWYgbm8gcmVzdWx0c1xyXG5cdFx0aWYgKHRoaXMuc2VhcmNoUmVzdWx0cy5sZW5ndGggPT09IDApIHtcclxuXHRcdFx0dGhpcy5zZWFyY2hSZXN1bHRzU2V0dGluZy5hZGRFeHRyYUJ1dHRvbigoYnV0dG9uKSA9PiB7XHJcblx0XHRcdFx0YnV0dG9uLmV4dHJhU2V0dGluZ3NFbC5hZGRDbGFzc2VzKFsnaWNvbmljLWludmlzaWJsZScsICdpY29uaWMtc2VhcmNoLXJlc3VsdCddKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBGb3JtYXQgaWNvbiBJRCBpbnRvIHJlYWRhYmxlIG5hbWVcclxuXHQgKi9cclxuXHRwcml2YXRlIGZvcm1hdEljb25OYW1lKGljb25JZDogc3RyaW5nKTogc3RyaW5nIHtcclxuXHRcdC8vIFJlbW92ZSBsdWNpZGUtIHByZWZpeCBpZiBwcmVzZW50XHJcblx0XHRsZXQgbmFtZSA9IGljb25JZC5yZXBsYWNlKC9ebHVjaWRlLS8sICcnKTtcclxuXHRcdC8vIFJlcGxhY2UgZGFzaGVzIHdpdGggc3BhY2VzXHJcblx0XHRuYW1lID0gbmFtZS5yZXBsYWNlKC8tL2csICcgJyk7XHJcblx0XHQvLyBDYXBpdGFsaXplIGZpcnN0IGxldHRlciBvZiBlYWNoIHdvcmRcclxuXHRcdHJldHVybiBuYW1lLnNwbGl0KCcgJykubWFwKHdvcmQgPT4gXHJcblx0XHRcdHdvcmQuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyB3b3JkLnNsaWNlKDEpXHJcblx0XHQpLmpvaW4oJyAnKTtcclxuXHR9XHJcblxyXG5cdG9uQ2xvc2UoKTogdm9pZCB7XHJcblx0XHR0aGlzLmNvbnRlbnRFbC5lbXB0eSgpO1xyXG5cdH1cclxufVxyXG4iLCAiLyoqXHJcbiAqIEhvbWUgQmFzZSBTZXJ2aWNlXHJcbiAqIENvcmUgbG9naWMgZm9yIG9wZW5pbmcgYW5kIG1hbmFnaW5nIHRoZSBob21lIGJhc2UgZmlsZVxyXG4gKi9cclxuXHJcbmltcG9ydCB7IEFwcCwgVEZpbGUsIFdvcmtzcGFjZUxlYWYsIE1hcmtkb3duVmlldywgUGxhdGZvcm0sIFZpZXcgYXMgT1ZpZXcgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB0eXBlIEhvbWVCYXNlUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5pbXBvcnQgeyBIb21lQmFzZVR5cGUsIE9wZW5pbmdNb2RlIH0gZnJvbSAnLi4vc2V0dGluZ3MnO1xyXG5pbXBvcnQgeyBnZXRGaWxlQnlQYXRoLCBpc01hcmtkb3duTGlrZSwgbGVhZkhhc0ZpbGUsIGlzU3VwcG9ydGVkRXh0ZW5zaW9uIH0gZnJvbSAnLi4vdXRpbHMvZmlsZS11dGlscyc7XHJcbmltcG9ydCB7IGV4ZWN1dGVDb21tYW5kIH0gZnJvbSAnLi4vdWkvY29tbWFuZC1zdWdnZXN0JztcclxuaW1wb3J0IHsgY29tcHV0ZUhvbWVCYXNlUGF0aCwgdHJpbUZpbGUsIHJlc29sdmVQYXRoU3luYyB9IGZyb20gJy4uL3V0aWxzL2hvbWViYXNlLXJlc29sdmVyJztcclxuXHJcbi8qKlxyXG4gKiBWaWV3IHR5cGVzIHRoYXQgY2FuIGJlIGhvbWUgYmFzZSBmaWxlc1xyXG4gKi9cclxuY29uc3QgTEVBRl9UWVBFUyA9IFsnbWFya2Rvd24nLCAnY2FudmFzJywgJ2Jhc2VzJywgJ2thbmJhbiddO1xyXG5cclxuLyoqXHJcbiAqIFRpbWluZyBjb25zdGFudHMgZm9yIGhvbWUgc2VydmljZSBvcGVyYXRpb25zXHJcbiAqIFRoZXNlIGRlbGF5cyBlbnN1cmUgT2JzaWRpYW4ncyBpbnRlcm5hbCBzdGF0ZSBpcyB1cGRhdGVkIGJlZm9yZSBwcm9jZWVkaW5nXHJcbiAqL1xyXG5cclxuLyoqIFNob3J0IGRlbGF5IGZvciBsZWFmIGRldGFjaG1lbnQgdG8gY29tcGxldGUgKi9cclxuY29uc3QgREVUQUNIX0RFTEFZID0gMTAwO1xyXG5cclxuLyoqIERlbGF5IGZvciBncmFwaCB2aWV3IGluaXRpYWxpemF0aW9uICovXHJcbmNvbnN0IEdSQVBIX0lOSVRfREVMQVkgPSAyMDA7XHJcblxyXG4vKiogRmFsbGJhY2sgZGVsYXkgd2hlbiB1c2luZyBncmFwaCBjb21tYW5kIGluc3RlYWQgb2YgZGlyZWN0IGNyZWF0aW9uICovXHJcbmNvbnN0IEdSQVBIX0NPTU1BTkRfRkFMTEJBQ0tfREVMQVkgPSAzMDA7XHJcblxyXG4vKipcclxuICogSGVscGVyIHRvIGNoZWNrIGlmIHR3byBmaWxlIHBhdGhzIGFyZSBlcXVhbCAoY2FzZS1pbnNlbnNpdGl2ZSwgaWdub3JpbmcgZXh0ZW5zaW9uKVxyXG4gKi9cclxuZnVuY3Rpb24gZXF1YWxzQ2FzZWxlc3MocGF0aDE6IHN0cmluZywgcGF0aDI6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG5cdGNvbnN0IG5vcm1hbGl6ZSA9IChwOiBzdHJpbmcpID0+IHAudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9cXC5tZCQvLCAnJyk7XHJcblx0cmV0dXJuIG5vcm1hbGl6ZShwYXRoMSkgPT09IG5vcm1hbGl6ZShwYXRoMik7XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBIb21lQmFzZVNlcnZpY2Uge1xyXG5cdHByaXZhdGUgYXBwOiBBcHA7XHJcblx0cHJpdmF0ZSBwbHVnaW46IEhvbWVCYXNlUGx1Z2luO1xyXG5cdHByaXZhdGUgZ2hvc3RMZWF2ZXM6IFdlYWtTZXQ8V29ya3NwYWNlTGVhZj4gPSBuZXcgV2Vha1NldCgpO1xyXG5cclxuXHRjb25zdHJ1Y3RvcihwbHVnaW46IEhvbWVCYXNlUGx1Z2luKSB7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gcGx1Z2luLmFwcDtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIE9wZW4gaG9tZSBiYXNlIHdpdGggYSBzcGVjaWZpYyBtb2RlIChmb3Igc3RhcnR1cC9tYW51YWwgb3BlbnMpXHJcblx0ICovXHJcblx0YXN5bmMgb3BlbkhvbWVCYXNlV2l0aE1vZGUobW9kZTogT3BlbmluZ01vZGUsIHJ1bkNvbW1hbmQ6IGJvb2xlYW4gPSB0cnVlKTogUHJvbWlzZTxib29sZWFuPiB7XHJcblx0XHRjb25zdCBob21lQmFzZVNldHRpbmdzID0gdGhpcy5wbHVnaW4uZ2V0SG9tZUJhc2VTZXR0aW5ncygpO1xyXG5cclxuXHRcdC8vIEhhbmRsZSBub24tZmlsZSB0eXBlcyAoV29ya3NwYWNlLCBHcmFwaCwgTm9uZSlcclxuXHRcdGlmIChob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5Xb3Jrc3BhY2UpIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMub3BlbldvcmtzcGFjZShob21lQmFzZVNldHRpbmdzLnZhbHVlKTtcclxuXHRcdH1cclxuXHRcdGlmIChob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5HcmFwaCkge1xyXG5cdFx0XHQvLyBHcmFwaCB2aWV3OiBzdXBwb3J0IGdob3N0IHRhYiBpZiBzdGlja3kgaWNvbiBpcyBlbmFibGVkXHJcblx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93U3RpY2t5SG9tZUljb24pIHtcclxuXHRcdFx0XHRyZXR1cm4gdGhpcy5vcGVuSG9tZUJhc2VJbkdob3N0VGFiKHsgcnVuQ29tbWFuZCB9KTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gdGhpcy5vcGVuR3JhcGgoKTtcclxuXHRcdH1cclxuXHRcdGlmIChob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5Ob25lKSB7XHJcblx0XHRcdC8vIEp1c3QgcnVuIGNvbW1hbmQsIGRvbid0IG9wZW4gYW55dGhpbmdcclxuXHRcdFx0aWYgKHJ1bkNvbW1hbmQpIHtcclxuXHRcdFx0XHR0aGlzLnJ1bkNvbW1hbmRPbk9wZW4oKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBSZXNvbHZlIHRoZSBhY3R1YWwgZmlsZSBwYXRoIGJhc2VkIG9uIHR5cGVcclxuXHRcdGNvbnN0IHJlc29sdmVkUGF0aCA9IGF3YWl0IGNvbXB1dGVIb21lQmFzZVBhdGgoXHJcblx0XHRcdGhvbWVCYXNlU2V0dGluZ3MudHlwZSxcclxuXHRcdFx0aG9tZUJhc2VTZXR0aW5ncy52YWx1ZSxcclxuXHRcdFx0dGhpcy5wbHVnaW5cclxuXHRcdCk7XHJcblxyXG5cdFx0aWYgKCFyZXNvbHZlZFBhdGgpIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEdldCB0aGUgZmlsZSAtIHVzZSBtZXRhZGF0YUNhY2hlIGZvciBiZXR0ZXIgcGF0aCByZXNvbHV0aW9uIChsaWtlIGhvbWVwYWdlIHBsdWdpbilcclxuXHRcdGxldCBmaWxlID0gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaXJzdExpbmtwYXRoRGVzdChyZXNvbHZlZFBhdGgsICcvJyk7XHJcblxyXG5cdFx0Ly8gSWYgbm90IGZvdW5kIGFuZCBhdXRvLWNyZWF0ZSBpcyBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIHR5cGUsIHJldHVyblxyXG5cdFx0Ly8gRm9yIG5vdywgd2UnbGwgdHJ5IGdldEZpbGVCeVBhdGggYXMgZmFsbGJhY2tcclxuXHRcdGlmICghZmlsZSkge1xyXG5cdFx0XHRmaWxlID0gZ2V0RmlsZUJ5UGF0aCh0aGlzLmFwcCwgcmVzb2x2ZWRQYXRoKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIWZpbGUpIHtcclxuXHRcdFx0Ly8gVHJ5IHRvIGNyZWF0ZSBpZiBpdCdzIGEgbWFya2Rvd24gZmlsZSBhbmQgcGF0aCBkb2Vzbid0IGhhdmUgZXh0ZW5zaW9uXHJcblx0XHRcdGNvbnN0IHVudHJpbW1lZFBhdGggPSByZXNvbHZlZFBhdGguZW5kc1dpdGgoJy5tZCcpID8gcmVzb2x2ZWRQYXRoIDogYCR7cmVzb2x2ZWRQYXRofS5tZGA7XHJcblx0XHRcdGZpbGUgPSBnZXRGaWxlQnlQYXRoKHRoaXMuYXBwLCB1bnRyaW1tZWRQYXRoKTtcclxuXHJcblx0XHRcdGlmICghZmlsZSAmJiBob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5GaWxlKSB7XHJcblx0XHRcdFx0Ly8gQ291bGQgY3JlYXRlIGZpbGUgaGVyZSBpZiBhdXRvQ3JlYXRlIHNldHRpbmcgZXhpc3RzLCBidXQgZm9yIG5vdyBqdXN0IHJldHVyblxyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmICghZmlsZSkge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gSGFuZGxlIG9wZW5pbmcgbW9kZVxyXG5cdFx0aWYgKG1vZGUgPT09ICdyZXBsYWNlLWFsbCcpIHtcclxuXHRcdFx0YXdhaXQgdGhpcy5kZXRhY2hBbGxMZWF2ZXMoKTtcclxuXHRcdH0gZWxzZSBpZiAobW9kZSA9PT0gJ3JlcGxhY2UtbGFzdCcpIHtcclxuXHRcdFx0Ly8gUmVwbGFjZSB0aGUgYWN0aXZlIGxlYWYgKGNsb3NlIGl0IGFuZCBvcGVuIGhvbWUgYmFzZSBpbiBpdHMgcGxhY2UpXHJcblx0XHRcdGNvbnN0IGFjdGl2ZUxlYWYgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShPVmlldyk/LmxlYWY7XHJcblx0XHRcdGlmIChhY3RpdmVMZWFmKSB7XHJcblx0XHRcdFx0Y29uc3Qgdmlld1N0YXRlID0gYWN0aXZlTGVhZi5nZXRWaWV3U3RhdGUoKTtcclxuXHRcdFx0XHQvLyBPbmx5IGNsb3NlIGlmIG5vdCBwaW5uZWRcclxuXHRcdFx0XHRpZiAodmlld1N0YXRlLnBpbm5lZCAhPT0gdHJ1ZSkge1xyXG5cdFx0XHRcdFx0dm9pZCBhY3RpdmVMZWFmLmRldGFjaCgpO1xyXG5cdFx0XHRcdFx0Ly8gV2FpdCBhIGJpdCBmb3IgZGV0YWNobWVudFxyXG5cdFx0XHRcdFx0YXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIERFVEFDSF9ERUxBWSkpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIENoZWNrIGZvciBleGlzdGluZyBsZWFmIChidXQgZXhjbHVkZSBnaG9zdCB0YWIgZm9yIG1hbnVhbCBvcGVucylcclxuXHRcdGNvbnN0IGV4aXN0aW5nTGVhZiA9IHRoaXMuZmluZEV4aXN0aW5nSG9tZUJhc2VMZWFmKGZpbGUpO1xyXG5cdFx0aWYgKGV4aXN0aW5nTGVhZiAmJiBtb2RlICE9PSAncmVwbGFjZS1hbGwnKSB7XHJcblx0XHRcdC8vIEZvciByZXBsYWNlLWxhc3QsIHdlIHN0aWxsIHdhbnQgdG8gcmV1c2UgZXhpc3RpbmcgaWYgZm91bmQgKGFmdGVyIGNsb3NpbmcgYWN0aXZlKVxyXG5cdFx0XHRjb25zdCB2aWV3U3RhdGUgPSBleGlzdGluZ0xlYWYuZ2V0Vmlld1N0YXRlKCk7XHJcblx0XHRcdGlmICh2aWV3U3RhdGUucGlubmVkID09PSB0cnVlICYmIHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dTdGlja3lIb21lSWNvbikge1xyXG5cdFx0XHRcdC8vIERvbid0IHVzZSBnaG9zdCB0YWIgZm9yIG1hbnVhbCBvcGVucyAtIHdpbGwgY3JlYXRlIG5ldyB0YWIgYmVsb3dcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uuc2V0QWN0aXZlTGVhZihleGlzdGluZ0xlYWYpO1xyXG5cdFx0XHRcdGF3YWl0IHRoaXMuY29uZmlndXJlVmlldyhleGlzdGluZ0xlYWYsIGZpbGUpO1xyXG5cdFx0XHRcdGlmIChydW5Db21tYW5kKSB7XHJcblx0XHRcdFx0XHR0aGlzLnJ1bkNvbW1hbmRPbk9wZW4oKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBPcGVuIGluIG5ldyBsZWFmXHJcblx0XHRjb25zdCBuZXdMZWFmID0gbW9kZSA9PT0gJ3JldGFpbidcclxuXHRcdFx0PyB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhZigndGFiJylcclxuXHRcdFx0OiB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhZihmYWxzZSk7XHJcblxyXG5cdFx0aWYgKCFuZXdMZWFmKSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHRcdGF3YWl0IG5ld0xlYWYub3BlbkZpbGUoZmlsZSk7XHJcblx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uuc2V0QWN0aXZlTGVhZihuZXdMZWFmKTtcclxuXHRcdGF3YWl0IHRoaXMuY29uZmlndXJlVmlldyhuZXdMZWFmLCBmaWxlKTtcclxuXHJcblx0XHRpZiAocnVuQ29tbWFuZCkge1xyXG5cdFx0XHR0aGlzLnJ1bkNvbW1hbmRPbk9wZW4oKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdHJ1ZTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIE9wZW4gd29ya3NwYWNlXHJcblx0ICovXHJcblx0cHJpdmF0ZSBhc3luYyBvcGVuV29ya3NwYWNlKHdvcmtzcGFjZU5hbWU6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG5cclxuXHRcdGNvbnN0IHdvcmtzcGFjZVBsdWdpbiA9IHRoaXMuYXBwLmludGVybmFsUGx1Z2lucz8ucGx1Z2lucz8ud29ya3NwYWNlcztcclxuXHJcblx0XHRpZiAoIXdvcmtzcGFjZVBsdWdpbj8uZW5hYmxlZCB8fCAhd29ya3NwYWNlUGx1Z2luLmluc3RhbmNlPy5sb2FkV29ya3NwYWNlKSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHJcblx0XHR3b3Jrc3BhY2VQbHVnaW4uaW5zdGFuY2UubG9hZFdvcmtzcGFjZSh3b3Jrc3BhY2VOYW1lKTtcclxuXHRcdGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBERVRBQ0hfREVMQVkpKTtcclxuXHRcdHJldHVybiB0cnVlO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogT3BlbiBncmFwaCB2aWV3XHJcblx0ICovXHJcblx0YXN5bmMgb3BlbkdyYXBoKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG5cclxuXHRcdGF3YWl0IHRoaXMuYXBwLmNvbW1hbmRzPy5leGVjdXRlQ29tbWFuZEJ5SWQ/LignZ3JhcGg6b3BlbicpO1xyXG5cdFx0cmV0dXJuIHRydWU7XHJcblx0fVxyXG5cclxuXHQvLyBSZW1vdmVkIGRlcHJlY2F0ZWQgb3BlbkdyYXBoSW5HaG9zdFRhYiAtIG5vdyBpbnRlZ3JhdGVkIGludG8gb3BlbkhvbWVCYXNlSW5HaG9zdFRhYlxyXG5cclxuXHQvKipcclxuXHQgKiBPcGVuIHRoZSBob21lIGJhc2UgZmlsZVxyXG5cdCAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIG9wZW5pbmdcclxuXHQgKi9cclxuXHRhc3luYyBvcGVuSG9tZUJhc2Uob3B0aW9uczoge1xyXG5cdFx0cmVwbGFjZUFjdGl2ZUxlYWY/OiBib29sZWFuO1xyXG5cdFx0cnVuQ29tbWFuZD86IGJvb2xlYW47XHJcblx0fSA9IHt9KTogUHJvbWlzZTxib29sZWFuPiB7XHJcblx0XHRjb25zdCB7IHJ1bkNvbW1hbmQgPSB0cnVlIH0gPSBvcHRpb25zO1xyXG5cdFx0Y29uc3QgbW9kZSA9IHRoaXMucGx1Z2luLnNldHRpbmdzLm1hbnVhbE9wZW5Nb2RlO1xyXG5cclxuXHJcblx0XHQvLyBVc2UgdGhlIG5ldyBtZXRob2Qgd2l0aCBtYW51YWwgbW9kZVxyXG5cdFx0cmV0dXJuIHRoaXMub3BlbkhvbWVCYXNlV2l0aE1vZGUobW9kZSwgcnVuQ29tbWFuZCk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBPcGVuIGhvbWUgYmFzZSBpbiBhbiBlbXB0eSBsZWFmIChmb3IgbmV3IHRhYiByZXBsYWNlbWVudClcclxuXHQgKi9cclxuXHRhc3luYyBvcGVuSW5MZWFmKGxlYWY6IFdvcmtzcGFjZUxlYWYpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuXHRcdGNvbnN0IGhvbWVCYXNlU2V0dGluZ3MgPSB0aGlzLnBsdWdpbi5nZXRIb21lQmFzZVNldHRpbmdzKCk7XHJcblx0XHRyZXR1cm4gdGhpcy5vcGVuSW5MZWFmV2l0aFNldHRpbmdzKGxlYWYsIGhvbWVCYXNlU2V0dGluZ3MpO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogT3BlbiBhIGZpbGUgaW4gYW4gZW1wdHkgbGVhZiB3aXRoIGN1c3RvbSBzZXR0aW5nc1xyXG5cdCAqIEBwYXJhbSBsZWFmIFRoZSBsZWFmIHRvIG9wZW4gdGhlIGZpbGUgaW5cclxuXHQgKiBAcGFyYW0gc2V0dGluZ3MgU2V0dGluZ3Mgb2JqZWN0IHdpdGggdHlwZSBhbmQgdmFsdWVcclxuXHQgKiBAcGFyYW0gaXNOZXdUYWIgV2hldGhlciB0aGlzIGlzIGZvciBuZXcgdGFiIHJlcGxhY2VtZW50IChza2lwcyBwaW5uaW5nL2dob3N0IHRhYiBsb2dpYylcclxuXHQgKi9cclxuXHRhc3luYyBvcGVuSW5MZWFmV2l0aFNldHRpbmdzKGxlYWY6IFdvcmtzcGFjZUxlYWYsIHNldHRpbmdzOiB7IHR5cGU6IEhvbWVCYXNlVHlwZTsgdmFsdWU6IHN0cmluZyB9LCBpc05ld1RhYjogYm9vbGVhbiA9IGZhbHNlKTogUHJvbWlzZTxib29sZWFuPiB7XHJcblx0XHQvLyBIYW5kbGUgbm9uLWZpbGUgdHlwZXNcclxuXHRcdGlmIChzZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuV29ya3NwYWNlKSB7XHJcblx0XHRcdGF3YWl0IHRoaXMub3BlbldvcmtzcGFjZShzZXR0aW5ncy52YWx1ZSk7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fVxyXG5cdFx0aWYgKHNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5HcmFwaCkge1xyXG5cdFx0XHRhd2FpdCB0aGlzLm9wZW5HcmFwaCgpO1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdGlmIChzZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuTm9uZSkge1xyXG5cdFx0XHR0aGlzLnJ1bkNvbW1hbmRPbk9wZW4oKTtcclxuXHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUmVzb2x2ZSB0aGUgYWN0dWFsIGZpbGUgcGF0aCBiYXNlZCBvbiB0eXBlXHJcblx0XHRjb25zdCByZXNvbHZlZFBhdGggPSBhd2FpdCBjb21wdXRlSG9tZUJhc2VQYXRoKFxyXG5cdFx0XHRzZXR0aW5ncy50eXBlLFxyXG5cdFx0XHRzZXR0aW5ncy52YWx1ZSxcclxuXHRcdFx0dGhpcy5wbHVnaW5cclxuXHRcdCk7XHJcblxyXG5cdFx0aWYgKCFyZXNvbHZlZFBhdGgpIHtcclxuXHRcdFx0Ly8gTG9nIHdhcm5pbmcgZm9yIGRlYnVnZ2luZyAtIGZpbGUgcGF0aCBjb3VsZG4ndCBiZSByZXNvbHZlZFxyXG5cdFx0XHRjb25zb2xlLndhcm4oJ1tIb21lIEJhc2VdIENvdWxkIG5vdCByZXNvbHZlIHBhdGggZm9yIG5ldyB0YWI6Jywgc2V0dGluZ3MudHlwZSwgc2V0dGluZ3MudmFsdWUpO1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gR2V0IHRoZSBmaWxlIC0gdXNlIG1ldGFkYXRhQ2FjaGUgZm9yIGJldHRlciBwYXRoIHJlc29sdXRpb24gKGxpa2UgaG9tZXBhZ2UgcGx1Z2luKVxyXG5cdFx0Ly8gVGhpcyBpcyBlc3BlY2lhbGx5IGltcG9ydGFudCBmb3IgcGVyaW9kaWMgbm90ZXMgd2hpY2ggbWF5IGhhdmUgYmVlbiBqdXN0IGNyZWF0ZWRcclxuXHRcdGxldCBmaWxlID0gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaXJzdExpbmtwYXRoRGVzdChyZXNvbHZlZFBhdGgsICcvJyk7XHJcblxyXG5cdFx0Ly8gSWYgbm90IGZvdW5kLCB0cnkgZ2V0RmlsZUJ5UGF0aCBhcyBmYWxsYmFja1xyXG5cdFx0aWYgKCFmaWxlKSB7XHJcblx0XHRcdGZpbGUgPSBnZXRGaWxlQnlQYXRoKHRoaXMuYXBwLCByZXNvbHZlZFBhdGgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEZvciBwZXJpb2RpYyBub3RlcywgdGhlIHBhdGggbWlnaHQgYmUgdHJpbW1lZCAobm8gZXh0ZW5zaW9uKVxyXG5cdFx0Ly8gVHJ5IHdpdGggLm1kIGV4dGVuc2lvbiBpZiBzdGlsbCBub3QgZm91bmRcclxuXHRcdGlmICghZmlsZSAmJiAhcmVzb2x2ZWRQYXRoLmVuZHNXaXRoKCcubWQnKSAmJiAhcmVzb2x2ZWRQYXRoLmVuZHNXaXRoKCcuY2FudmFzJykgJiYgIXJlc29sdmVkUGF0aC5lbmRzV2l0aCgnLmJhc2UnKSkge1xyXG5cdFx0XHRjb25zdCB1bnRyaW1tZWRQYXRoID0gYCR7cmVzb2x2ZWRQYXRofS5tZGA7XHJcblx0XHRcdGZpbGUgPSBnZXRGaWxlQnlQYXRoKHRoaXMuYXBwLCB1bnRyaW1tZWRQYXRoKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIWZpbGUpIHtcclxuXHRcdFx0Ly8gTG9nIHdhcm5pbmcgZm9yIGRlYnVnZ2luZyAtIGZpbGUgbm90IGZvdW5kXHJcblx0XHRcdGNvbnNvbGUud2FybignW0hvbWUgQmFzZV0gRmlsZSBub3QgZm91bmQgZm9yIG5ldyB0YWI6JywgcmVzb2x2ZWRQYXRoKTtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEZvciBuZXcgdGFiIHJlcGxhY2VtZW50OiBqdXN0IG9wZW4gdGhlIGZpbGUsIG5vIHBpbm5pbmcsIG5vIGdob3N0IHRhYiBsb2dpY1xyXG5cdFx0Ly8gTXVsdGlwbGUgdGFicyB3aXRoIHRoZSBzYW1lIGZpbGUgYXJlIGZpbmVcclxuXHRcdC8vIENSSVRJQ0FMOiBXaGVuIGlzTmV3VGFiPXRydWUsIGNvbXBsZXRlbHkgYnlwYXNzIEFMTCBnaG9zdCB0YWIgbG9naWNcclxuXHRcdGlmIChpc05ld1RhYikge1xyXG5cdFx0XHRjb25zb2xlLmRlYnVnKCdbSG9tZSBCYXNlXSBvcGVuSW5MZWFmV2l0aFNldHRpbmdzOiBpc05ld1RhYj10cnVlLCBieXBhc3NpbmcgZ2hvc3QgdGFiIGxvZ2ljJywge1xyXG5cdFx0XHRcdGZpbGU6IGZpbGUucGF0aCxcclxuXHRcdFx0XHRzZXR0aW5nczogc2V0dGluZ3NcclxuXHRcdFx0fSk7XHJcblx0XHRcdGF3YWl0IGxlYWYub3BlbkZpbGUoZmlsZSk7XHJcblx0XHRcdGF3YWl0IHRoaXMuY29uZmlndXJlVmlldyhsZWFmLCBmaWxlKTtcclxuXHRcdFx0dGhpcy5ydW5Db21tYW5kT25PcGVuKCk7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEZvciBob21lIGJhc2U6IHVzZSBnaG9zdCB0YWIvcGlubmluZyBsb2dpYyAoZXhpc3RpbmcgYmVoYXZpb3IpXHJcblx0XHQvLyBJZiBzdGlja3kgaWNvbiBpcyBlbmFibGVkIEFORCB0aGlzIGlzIGEgdHJ1bHkgZW1wdHkgdGFiIChub3QgYSBmaWxlIG9wZW5lZCBmcm9tIGV4cGxvcmVyKSxcclxuXHRcdC8vIGNoZWNrIGlmIHRoZXJlJ3MgYSBnaG9zdCB0YWIgYW5kIG1lcmdlIHdpdGggaXQuXHJcblx0XHQvLyBUaGlzIGVuc3VyZXMgdGhhdCB3aGVuIHlvdSBjbG9zZSB0aGUgbGFzdCB0YWIgYW5kIE9ic2lkaWFuIGNyZWF0ZXMgYSBuZXcgZW1wdHkgb25lLFxyXG5cdFx0Ly8gaXQgbWVyZ2VzIHdpdGggdGhlIGdob3N0IHRhYiBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgZHVwbGljYXRlLlxyXG5cdFx0Ly8gQlVUOiBJZiB0aGUgdXNlciBtYW51YWxseSBvcGVuZWQgYSBmaWxlIGZyb20gZXhwbG9yZXIsIHdlIHNob3VsZCBOT1QgbWVyZ2UgLSBsZXQgdGhlbSBoYXZlIHRoZWlyIHRhYi5cclxuXHRcdGNvbnN0IGlzVHJ1bHlFbXB0eSA9ICFsZWFmLnZpZXcgfHwgbGVhZi52aWV3LmdldFZpZXdUeXBlKCkgPT09ICdlbXB0eSc7XHJcblxyXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dTdGlja3lIb21lSWNvbiAmJiBpc1RydWx5RW1wdHkpIHtcclxuXHRcdFx0Ly8gUmFuZG9tIHR5cGVzIGFuZCBwZXJpb2RpYyBub3RlczogZG9uJ3QgcGluLCBidXQgY2FuIHN0aWxsIG1lcmdlXHJcblx0XHRcdGNvbnN0IGlzUmFuZG9tID0gc2V0dGluZ3MudHlwZSA9PT0gSG9tZUJhc2VUeXBlLlJhbmRvbSB8fFxyXG5cdFx0XHRcdHNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5SYW5kb21Gb2xkZXIgfHxcclxuXHRcdFx0XHRzZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuRGFpbHlOb3RlIHx8XHJcblx0XHRcdFx0c2V0dGluZ3MudHlwZSA9PT0gSG9tZUJhc2VUeXBlLldlZWtseU5vdGUgfHxcclxuXHRcdFx0XHRzZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuTW9udGhseU5vdGUgfHxcclxuXHRcdFx0XHRzZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuWWVhcmx5Tm90ZTtcclxuXHRcdFx0Y29uc3QgZ2hvc3RUYWIgPSB0aGlzLmZpbmRHaG9zdFRhYihmaWxlLCBpc1JhbmRvbSk7XHJcblxyXG5cdFx0XHRpZiAoZ2hvc3RUYWIpIHtcclxuXHRcdFx0XHQvLyBDbG9zZSB0aGUgbmV3IGVtcHR5IGxlYWYgc2luY2Ugd2UncmUgbWVyZ2luZyB3aXRoIGdob3N0IHRhYlxyXG5cdFx0XHRcdHZvaWQgbGVhZi5kZXRhY2goKTtcclxuXHJcblx0XHRcdFx0Ly8gRm9jdXMgdGhlIGdob3N0IHRhYiBhbmQgY29uZmlndXJlIGl0XHJcblx0XHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLnNldEFjdGl2ZUxlYWYoZ2hvc3RUYWIpO1xyXG5cdFx0XHRcdGF3YWl0IHRoaXMuY29uZmlndXJlVmlldyhnaG9zdFRhYiwgZmlsZSk7XHJcblx0XHRcdFx0dGhpcy5ydW5Db21tYW5kT25PcGVuKCk7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIE5vIGdob3N0IHRhYiBmb3VuZCwgYnV0IHN0aWNreSBpY29uIGlzIGVuYWJsZWQgLSB0aGlzIHRhYiBzaG91bGQgYmVjb21lIHRoZSBnaG9zdCB0YWJcclxuXHRcdFx0Ly8gUGluIGl0IHNvIGl0J3MgcmVjb2duaXplZCBhcyB0aGUgZ2hvc3QgdGFiXHJcblx0XHRcdHRoaXMuZ2hvc3RMZWF2ZXMuYWRkKGxlYWYpO1xyXG5cdFx0XHRpZiAoIWlzUmFuZG9tKSB7XHJcblx0XHRcdFx0bGVhZi5zZXRQaW5uZWQodHJ1ZSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdGF3YWl0IGxlYWYub3BlbkZpbGUoZmlsZSk7XHJcblx0XHRhd2FpdCB0aGlzLmNvbmZpZ3VyZVZpZXcobGVhZiwgZmlsZSk7XHJcblxyXG5cdFx0Ly8gUnVuIGNvbW1hbmQgaWYgY29uZmlndXJlZFxyXG5cdFx0dGhpcy5ydW5Db21tYW5kT25PcGVuKCk7XHJcblxyXG5cdFx0cmV0dXJuIHRydWU7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBMYXN0IHZpZXcgcmVmZXJlbmNlIGZvciByZXZlcnRWaWV3IGZ1bmN0aW9uYWxpdHlcclxuXHQgKi9cclxuXHRwcml2YXRlIGxhc3RWaWV3OiBXZWFrUmVmPE1hcmtkb3duVmlldz4gfCB1bmRlZmluZWQ7XHJcblxyXG5cdC8qKlxyXG5cdCAqIENvbmZpZ3VyZSB0aGUgdmlldyBtb2RlIGZvciBhIGxlYWZcclxuXHQgKi9cclxuXHRwcml2YXRlIGFzeW5jIGNvbmZpZ3VyZVZpZXcobGVhZjogV29ya3NwYWNlTGVhZiwgZmlsZTogVEZpbGUpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHRcdGNvbnN0IHNldHRpbmdzID0gdGhpcy5wbHVnaW4uc2V0dGluZ3M7XHJcblx0XHRjb25zdCB2aWV3ID0gbGVhZi52aWV3O1xyXG5cclxuXHRcdC8vIE9ubHkgY29uZmlndXJlIHZpZXcgbW9kZSBmb3IgbWFya2Rvd24tbGlrZSBmaWxlc1xyXG5cdFx0aWYgKCFpc01hcmtkb3duTGlrZShmaWxlKSB8fCAhKHZpZXcgaW5zdGFuY2VvZiBNYXJrZG93blZpZXcpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBzdGF0ZSA9IHZpZXcuZ2V0U3RhdGUoKTtcclxuXHJcblx0XHQvLyBUcmFjayB2aWV3IGZvciByZXZlcnRWaWV3IGlmIGVuYWJsZWRcclxuXHRcdGlmIChzZXR0aW5ncy5yZXZlcnRWaWV3KSB7XHJcblx0XHRcdHRoaXMubGFzdFZpZXcgPSBuZXcgV2Vha1JlZih2aWV3KTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBBdXRvLXNjcm9sbCB0byBib3R0b20gaWYgZW5hYmxlZFxyXG5cdFx0aWYgKHNldHRpbmdzLmF1dG9TY3JvbGwpIHtcclxuXHRcdFx0Y29uc3QgY291bnQgPSB2aWV3LmVkaXRvci5saW5lQ291bnQoKTtcclxuXHJcblx0XHRcdGlmIChzdGF0ZS5tb2RlID09PSAncHJldmlldycpIHtcclxuXHRcdFx0XHR2aWV3LnByZXZpZXdNb2RlLmFwcGx5U2Nyb2xsKGNvdW50IC0gNCk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dmlldy5lZGl0b3Iuc2V0Q3Vyc29yKGNvdW50KTtcclxuXHRcdFx0XHR2aWV3LmVkaXRvci5mb2N1cygpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gU2V0IHZpZXcgbW9kZVxyXG5cdFx0aWYgKHNldHRpbmdzLm9wZW5WaWV3TW9kZSAhPT0gJ2RlZmF1bHQnKSB7XHJcblx0XHRcdHN3aXRjaCAoc2V0dGluZ3Mub3BlblZpZXdNb2RlKSB7XHJcblx0XHRcdFx0Y2FzZSAncHJldmlldyc6XHJcblx0XHRcdFx0XHRzdGF0ZS5tb2RlID0gJ3ByZXZpZXcnO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0Y2FzZSAnc291cmNlJzpcclxuXHRcdFx0XHRcdHN0YXRlLm1vZGUgPSAnc291cmNlJztcclxuXHRcdFx0XHRcdHN0YXRlLnNvdXJjZSA9IHRydWU7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRjYXNlICdsaXZlJzpcclxuXHRcdFx0XHRcdHN0YXRlLm1vZGUgPSAnc291cmNlJztcclxuXHRcdFx0XHRcdHN0YXRlLnNvdXJjZSA9IGZhbHNlO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGF3YWl0IGxlYWYuc2V0Vmlld1N0YXRlKHtcclxuXHRcdFx0XHR0eXBlOiAnbWFya2Rvd24nLFxyXG5cdFx0XHRcdHN0YXRlOiBzdGF0ZSxcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZXZlcnQgdmlldyB0byBkZWZhdWx0IHdoZW4gbmF2aWdhdGluZyBhd2F5IGZyb20gaG9tZSBiYXNlXHJcblx0ICovXHJcblx0YXN5bmMgcmV2ZXJ0VmlldygpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHRcdGNvbnN0IHNldHRpbmdzID0gdGhpcy5wbHVnaW4uc2V0dGluZ3M7XHJcblx0XHRpZiAoIXNldHRpbmdzLnJldmVydFZpZXcgfHwgIXRoaXMubGFzdFZpZXcgfHwgc2V0dGluZ3Mub3BlblZpZXdNb2RlID09PSAnZGVmYXVsdCcpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IHZpZXcgPSB0aGlzLmxhc3RWaWV3LmRlcmVmKCk7XHJcblx0XHRpZiAoIXZpZXcpIHtcclxuXHRcdFx0dGhpcy5sYXN0VmlldyA9IHVuZGVmaW5lZDtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGhvbWVCYXNlU2V0dGluZ3MgPSB0aGlzLnBsdWdpbi5nZXRIb21lQmFzZVNldHRpbmdzKCk7XHJcblx0XHRjb25zdCByZXNvbHZlZFBhdGggPSBhd2FpdCBjb21wdXRlSG9tZUJhc2VQYXRoKFxyXG5cdFx0XHRob21lQmFzZVNldHRpbmdzLnR5cGUsXHJcblx0XHRcdGhvbWVCYXNlU2V0dGluZ3MudmFsdWUsXHJcblx0XHRcdHRoaXMucGx1Z2luXHJcblx0XHQpO1xyXG5cclxuXHRcdGlmICghcmVzb2x2ZWRQYXRoKSB7XHJcblx0XHRcdHRoaXMubGFzdFZpZXcgPSB1bmRlZmluZWQ7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDaGVjayBpZiB3ZSdyZSBzdGlsbCBvbiB0aGUgaG9tZSBiYXNlIGZpbGVcclxuXHRcdGNvbnN0IGN1cnJlbnRGaWxlID0gdmlldy5maWxlO1xyXG5cdFx0aWYgKGN1cnJlbnRGaWxlICYmIGVxdWFsc0Nhc2VsZXNzKHRyaW1GaWxlKGN1cnJlbnRGaWxlKSwgcmVzb2x2ZWRQYXRoKSkge1xyXG5cdFx0XHRyZXR1cm47IC8vIFN0aWxsIG9uIGhvbWUgYmFzZSwgZG9uJ3QgcmV2ZXJ0XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUmV2ZXJ0IHRvIGRlZmF1bHQgdmlld1xyXG5cdFx0Y29uc3Qgc3RhdGUgPSB2aWV3LmdldFN0YXRlKCk7XHJcblx0XHRjb25zdCBjb25maWcgPSB0aGlzLmFwcC52YXVsdC5jb25maWc7XHJcblx0XHRjb25zdCBtb2RlID0gY29uZmlnPy5kZWZhdWx0Vmlld01vZGUgfHwgJ3NvdXJjZSc7XHJcblx0XHRjb25zdCBzb3VyY2UgPSBjb25maWc/LmxpdmVQcmV2aWV3ICE9PSB1bmRlZmluZWQgPyAhY29uZmlnLmxpdmVQcmV2aWV3IDogZmFsc2U7XHJcblxyXG5cdFx0aWYgKFxyXG5cdFx0XHR2aWV3LmxlYWYuZ2V0Vmlld1N0YXRlKCkudHlwZSA9PT0gJ21hcmtkb3duJyAmJlxyXG5cdFx0XHQobW9kZSAhPT0gc3RhdGUubW9kZSB8fCBzb3VyY2UgIT09IHN0YXRlLnNvdXJjZSlcclxuXHRcdCkge1xyXG5cdFx0XHRzdGF0ZS5tb2RlID0gbW9kZTtcclxuXHRcdFx0c3RhdGUuc291cmNlID0gc291cmNlO1xyXG5cdFx0XHRhd2FpdCB2aWV3LmxlYWYuc2V0Vmlld1N0YXRlKHsgdHlwZTogJ21hcmtkb3duJywgc3RhdGUsIGFjdGl2ZTogdHJ1ZSB9KTtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLmxhc3RWaWV3ID0gdW5kZWZpbmVkO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogUnVuIHRoZSBjb25maWd1cmVkIGNvbW1hbmQgYWZ0ZXIgb3BlbmluZ1xyXG5cdCAqL1xyXG5cdHByaXZhdGUgcnVuQ29tbWFuZE9uT3BlbigpOiB2b2lkIHtcclxuXHRcdGNvbnN0IGNvbW1hbmRJZCA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmNvbW1hbmRPbk9wZW47XHJcblx0XHRpZiAoY29tbWFuZElkKSB7XHJcblx0XHRcdC8vIFNtYWxsIGRlbGF5IHRvIGVuc3VyZSB0aGUgdmlldyBpcyByZWFkeVxyXG5cdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcclxuXHRcdFx0XHRleGVjdXRlQ29tbWFuZCh0aGlzLmFwcCwgY29tbWFuZElkKTtcclxuXHRcdFx0fSwgMTAwKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEZpbmQgYW4gZXhpc3RpbmcgbGVhZiB0aGF0IGhhcyB0aGUgaG9tZSBiYXNlIGZpbGUgb3BlblxyXG5cdCAqL1xyXG5cdGZpbmRFeGlzdGluZ0hvbWVCYXNlTGVhZihmaWxlPzogVEZpbGUpOiBXb3Jrc3BhY2VMZWFmIHwgbnVsbCB7XHJcblx0XHRpZiAoIWZpbGUpIHJldHVybiBudWxsO1xyXG5cdFx0Y29uc3QgaG9tZUJhc2VQYXRoID0gZmlsZS5wYXRoO1xyXG5cclxuXHRcdGNvbnN0IGxlYXZlcyA9IExFQUZfVFlQRVMuZmxhdE1hcCh0eXBlID0+XHJcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUodHlwZSlcclxuXHRcdCk7XHJcblxyXG5cdFx0Zm9yIChjb25zdCBsZWFmIG9mIGxlYXZlcykge1xyXG5cdFx0XHRpZiAobGVhZkhhc0ZpbGUobGVhZiwgaG9tZUJhc2VQYXRoKSkge1xyXG5cdFx0XHRcdHJldHVybiBsZWFmO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBDaGVjayBpZiBhIGxlYWYgaXMgYSBnaG9zdCB0YWJcclxuXHQgKiBHaG9zdCB0YWIgaXMgaWRlbnRpZmllZCBieSBiZWluZyBpbiBvdXIgaW50ZXJuYWwgZ2hvc3RMZWF2ZXMgc2V0XHJcblx0ICogT25seSB0YWJzIHNwZWNpZmljYWxseSBjcmVhdGVkIGZvciB0aGUgc3RpY2t5IGljb24gYXJlIGdob3N0IHRhYnNcclxuXHQgKi9cclxuXHRpc0dob3N0TGVhZihsZWFmOiBXb3Jrc3BhY2VMZWFmKTogYm9vbGVhbiB7XHJcblx0XHRyZXR1cm4gdGhpcy5naG9zdExlYXZlcy5oYXMobGVhZik7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBGaW5kIHRoZSBnaG9zdCB0YWIgKHRoZSBvbmUgb3BlbmVkIHZpYSBzdGlja3kgaWNvbilcclxuXHQgKiBHaG9zdCB0YWIgaXMgaWRlbnRpZmllZCBieSBiZWluZyBpbiBvdXIgaW50ZXJuYWwgZ2hvc3RMZWF2ZXMgc2V0XHJcblx0ICogT25seSByZXR1cm5zIGV4aXN0aW5nIGdob3N0IHRhYnMsIGRvZXNuJ3QgY3JlYXRlIG5ldyBvbmVzXHJcblx0ICovXHJcblx0ZmluZEdob3N0VGFiKGZpbGU/OiBURmlsZSwgaXNSYW5kb206IGJvb2xlYW4gPSBmYWxzZSk6IFdvcmtzcGFjZUxlYWYgfCBudWxsIHtcclxuXHRcdGlmICghZmlsZSkgcmV0dXJuIG51bGw7XHJcblx0XHRjb25zdCBob21lQmFzZVBhdGggPSBmaWxlLnBhdGg7XHJcblxyXG5cdFx0Ly8gVXNlIGl0ZXJhdGVBbGxMZWF2ZXMgaW5zdGVhZCBvZiBnZXRMZWF2ZXNPZlR5cGUgdG8gZmluZCB0YWJzIGV2ZW4gd2hlbiBoaWRkZW4gKHplbiBtb2RlLCBldGMuKVxyXG5cdFx0Y29uc3QgbGVhdmVzOiBXb3Jrc3BhY2VMZWFmW10gPSBbXTtcclxuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5pdGVyYXRlQWxsTGVhdmVzKChsZWFmKSA9PiB7XHJcblx0XHRcdGNvbnN0IHZpZXdUeXBlID0gbGVhZi52aWV3Py5nZXRWaWV3VHlwZSgpO1xyXG5cdFx0XHRpZiAodmlld1R5cGUgJiYgTEVBRl9UWVBFUy5pbmNsdWRlcyh2aWV3VHlwZSkpIHtcclxuXHRcdFx0XHRsZWF2ZXMucHVzaChsZWFmKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gQ2hlY2sgZm9yIGEgbWF0Y2ggaW4gb3VyIFdlYWtTZXRcclxuXHRcdGZvciAoY29uc3QgbGVhZiBvZiBsZWF2ZXMpIHtcclxuXHRcdFx0aWYgKHRoaXMuZ2hvc3RMZWF2ZXMuaGFzKGxlYWYpICYmIGxlYWZIYXNGaWxlKGxlYWYsIGhvbWVCYXNlUGF0aCkpIHtcclxuXHRcdFx0XHRyZXR1cm4gbGVhZjtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBudWxsO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogT3BlbiBob21lIGJhc2UgaW4gZ2hvc3QgdGFiIChmb3Igc3RpY2t5IGljb24pXHJcblx0ICogR2hvc3QgdGFiIGlzIHBpbm5lZCBhbmQgaGlkZGVuIChpZiBzZXR0aW5nIGVuYWJsZWQpXHJcblx0ICogT25seSBvbmUgZ2hvc3QgdGFiIHNob3VsZCBleGlzdCBhdCBhIHRpbWVcclxuXHQgKiBXb3JrcyBmb3IgZmlsZS1iYXNlZCB0eXBlcyBhbmQgR3JhcGggdmlld1xyXG5cdCAqIE5vdGU6IFJhbmRvbSB0eXBlcyBkb24ndCBwaW4gKHNpbmNlIGZpbGUgY2hhbmdlcyBlYWNoIHRpbWUpXHJcblx0ICogTm90ZTogV29ya3NwYWNlIGFuZCBOb25lIGRvbid0IHdvcmsgKHdvcmtzcGFjZSBjaGFuZ2VzIGxheW91dCwgTm9uZSBkb2Vzbid0IG9wZW4gYW55dGhpbmcpXHJcblx0ICovXHJcblx0YXN5bmMgb3BlbkhvbWVCYXNlSW5HaG9zdFRhYihvcHRpb25zOiB7XHJcblx0XHRydW5Db21tYW5kPzogYm9vbGVhbjtcclxuXHR9ID0ge30pOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuXHRcdGNvbnN0IHsgcnVuQ29tbWFuZCA9IHRydWUgfSA9IG9wdGlvbnM7XHJcblx0XHRjb25zdCBob21lQmFzZVNldHRpbmdzID0gdGhpcy5wbHVnaW4uZ2V0SG9tZUJhc2VTZXR0aW5ncygpO1xyXG5cclxuXHRcdC8vIEhhbmRsZSBub24tZmlsZSB0eXBlcyAoV29ya3NwYWNlIGFuZCBOb25lIGRvbid0IHdvcmsgd2l0aCBnaG9zdCB0YWIpXHJcblx0XHRpZiAoaG9tZUJhc2VTZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuV29ya3NwYWNlIHx8XHJcblx0XHRcdGhvbWVCYXNlU2V0dGluZ3MudHlwZSA9PT0gSG9tZUJhc2VUeXBlLk5vbmUpIHtcclxuXHRcdFx0Ly8gRm9yIHRoZXNlIHR5cGVzLCBqdXN0IHVzZSBub3JtYWwgb3BlblxyXG5cdFx0XHRyZXR1cm4gdGhpcy5vcGVuSG9tZUJhc2VXaXRoTW9kZSgncmV0YWluJywgcnVuQ29tbWFuZCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gR3JhcGggdmlldyBoYW5kbGluZ1xyXG5cdFx0aWYgKGhvbWVCYXNlU2V0dGluZ3MudHlwZSA9PT0gSG9tZUJhc2VUeXBlLkdyYXBoKSB7XHJcblx0XHRcdC8vIEZpbmQgZXhpc3RpbmcgZ3JhcGggZ2hvc3QgdGFiXHJcblx0XHRcdGxldCBnaG9zdFRhYiA9IHRoaXMuZmluZEdyYXBoR2hvc3RUYWIoKTtcclxuXHJcblx0XHRcdGlmIChnaG9zdFRhYikge1xyXG5cdFx0XHRcdHRoaXMuZ2hvc3RMZWF2ZXMuYWRkKGdob3N0VGFiKTtcclxuXHRcdFx0XHRnaG9zdFRhYi5zZXRQaW5uZWQodHJ1ZSk7XHJcblx0XHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLnNldEFjdGl2ZUxlYWYoZ2hvc3RUYWIsIHsgZm9jdXM6ICF0aGlzLmlzU2V0dGluZ3NNb2RhbE9wZW4oKSB9KTtcclxuXHRcdFx0XHRpZiAocnVuQ29tbWFuZCkgdGhpcy5ydW5Db21tYW5kT25PcGVuKCk7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIENyZWF0ZSBuZXcgZ3JhcGggdGFiXHJcblx0XHRcdGNvbnN0IG5ld0xlYWYgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhZigndGFiJyk7XHJcblx0XHRcdGlmIChuZXdMZWFmKSB7XHJcblx0XHRcdFx0YXdhaXQgbmV3TGVhZi5zZXRWaWV3U3RhdGUoeyB0eXBlOiAnZ3JhcGgnLCBzdGF0ZToge30gfSk7XHJcblx0XHRcdFx0YXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIEdSQVBIX0lOSVRfREVMQVkpKTtcclxuXHJcblx0XHRcdFx0dGhpcy5naG9zdExlYXZlcy5hZGQobmV3TGVhZik7XHJcblx0XHRcdFx0bmV3TGVhZi5zZXRQaW5uZWQodHJ1ZSk7XHJcblx0XHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLnNldEFjdGl2ZUxlYWYobmV3TGVhZiwgeyBmb2N1czogIXRoaXMuaXNTZXR0aW5nc01vZGFsT3BlbigpIH0pO1xyXG5cdFx0XHRcdGlmIChydW5Db21tYW5kKSB0aGlzLnJ1bkNvbW1hbmRPbk9wZW4oKTtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gRmFsbGJhY2sgdG8gY29tbWFuZFxyXG5cdFx0XHRhd2FpdCB0aGlzLm9wZW5HcmFwaCgpO1xyXG5cdFx0XHRhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgR1JBUEhfQ09NTUFORF9GQUxMQkFDS19ERUxBWSkpO1xyXG5cdFx0XHRnaG9zdFRhYiA9IHRoaXMuZmluZEdyYXBoR2hvc3RUYWIoKTtcclxuXHRcdFx0aWYgKGdob3N0VGFiKSB7XHJcblx0XHRcdFx0dGhpcy5naG9zdExlYXZlcy5hZGQoZ2hvc3RUYWIpO1xyXG5cdFx0XHRcdGdob3N0VGFiLnNldFBpbm5lZCh0cnVlKTtcclxuXHRcdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uuc2V0QWN0aXZlTGVhZihnaG9zdFRhYiwgeyBmb2N1czogIXRoaXMuaXNTZXR0aW5nc01vZGFsT3BlbigpIH0pO1xyXG5cdFx0XHRcdGlmIChydW5Db21tYW5kKSB0aGlzLnJ1bkNvbW1hbmRPbk9wZW4oKTtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUmFuZG9tIHR5cGVzIGFuZCBwZXJpb2RpYyBub3RlczogZG9uJ3QgcGluIChmaWxlIGNoYW5nZXMgZWFjaCB0aW1lKVxyXG5cdFx0Ly8gQnV0IHN0aWxsIGFsbG93IG1lcmdpbmcgd2l0aCBleGlzdGluZyB0YWJzIGlmIHN0aWNreSBpY29uIGlzIGVuYWJsZWRcclxuXHRcdGNvbnN0IGlzUmFuZG9tID0gaG9tZUJhc2VTZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuUmFuZG9tIHx8XHJcblx0XHRcdGhvbWVCYXNlU2V0dGluZ3MudHlwZSA9PT0gSG9tZUJhc2VUeXBlLlJhbmRvbUZvbGRlciB8fFxyXG5cdFx0XHRob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5EYWlseU5vdGUgfHxcclxuXHRcdFx0aG9tZUJhc2VTZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuV2Vla2x5Tm90ZSB8fFxyXG5cdFx0XHRob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5Nb250aGx5Tm90ZSB8fFxyXG5cdFx0XHRob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5ZZWFybHlOb3RlO1xyXG5cclxuXHRcdC8vIENoZWNrIGlmIHNldHRpbmdzIG1vZGFsIGlzIG9wZW5cclxuXHRcdGlmICh0aGlzLmlzU2V0dGluZ3NNb2RhbE9wZW4oKSkge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUmVzb2x2ZSB0aGUgYWN0dWFsIGZpbGUgcGF0aCBiYXNlZCBvbiB0eXBlXHJcblx0XHRjb25zdCByZXNvbHZlZFBhdGggPSBhd2FpdCBjb21wdXRlSG9tZUJhc2VQYXRoKFxyXG5cdFx0XHRob21lQmFzZVNldHRpbmdzLnR5cGUsXHJcblx0XHRcdGhvbWVCYXNlU2V0dGluZ3MudmFsdWUsXHJcblx0XHRcdHRoaXMucGx1Z2luXHJcblx0XHQpO1xyXG5cclxuXHRcdGlmICghcmVzb2x2ZWRQYXRoKSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBHZXQgdGhlIGhvbWUgYmFzZSBmaWxlIC0gdXNlIG1ldGFkYXRhQ2FjaGUgZm9yIGJldHRlciBwYXRoIHJlc29sdXRpb24gKGxpa2UgaG9tZXBhZ2UgcGx1Z2luKVxyXG5cdFx0Ly8gVGhpcyBpcyBlc3BlY2lhbGx5IGltcG9ydGFudCBmb3IgcGVyaW9kaWMgbm90ZXMgd2hpY2ggbWF5IGhhdmUgYmVlbiBqdXN0IGNyZWF0ZWRcclxuXHRcdGxldCBmaWxlID0gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaXJzdExpbmtwYXRoRGVzdChyZXNvbHZlZFBhdGgsICcvJyk7XHJcblxyXG5cdFx0Ly8gSWYgbm90IGZvdW5kLCB0cnkgZ2V0RmlsZUJ5UGF0aCBhcyBmYWxsYmFja1xyXG5cdFx0aWYgKCFmaWxlKSB7XHJcblx0XHRcdGZpbGUgPSBnZXRGaWxlQnlQYXRoKHRoaXMuYXBwLCByZXNvbHZlZFBhdGgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEZvciBwZXJpb2RpYyBub3RlcywgdGhlIHBhdGggbWlnaHQgYmUgdHJpbW1lZCAobm8gZXh0ZW5zaW9uKVxyXG5cdFx0Ly8gVHJ5IHdpdGggLm1kIGV4dGVuc2lvbiBpZiBzdGlsbCBub3QgZm91bmRcclxuXHRcdGlmICghZmlsZSAmJiAhcmVzb2x2ZWRQYXRoLmVuZHNXaXRoKCcubWQnKSAmJiAhcmVzb2x2ZWRQYXRoLmVuZHNXaXRoKCcuY2FudmFzJykgJiYgIXJlc29sdmVkUGF0aC5lbmRzV2l0aCgnLmJhc2UnKSkge1xyXG5cdFx0XHRjb25zdCB1bnRyaW1tZWRQYXRoID0gYCR7cmVzb2x2ZWRQYXRofS5tZGA7XHJcblx0XHRcdGZpbGUgPSBnZXRGaWxlQnlQYXRoKHRoaXMuYXBwLCB1bnRyaW1tZWRQYXRoKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIWZpbGUpIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIENoZWNrIGlmIGdob3N0IHRhYiBhbHJlYWR5IGV4aXN0c1xyXG5cdFx0Y29uc3QgZ2hvc3RUYWIgPSB0aGlzLmZpbmRHaG9zdFRhYihmaWxlLCBpc1JhbmRvbSk7XHJcblxyXG5cdFx0Y29uc29sZS5kZWJ1ZygnW0hvbWUgQmFzZV0gb3BlbkhvbWVCYXNlSW5HaG9zdFRhYjonLCB7XHJcblx0XHRcdGZpbGU6IGZpbGUucGF0aCxcclxuXHRcdFx0Z2hvc3RUYWJGb3VuZDogISFnaG9zdFRhYixcclxuXHRcdFx0aXNSYW5kb206IGlzUmFuZG9tLFxyXG5cdFx0XHR6ZW5Nb2RlOiBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5jb250YWlucygnemVubW9kZS1hY3RpdmUnKVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0aWYgKGdob3N0VGFiKSB7XHJcblx0XHRcdC8vIEdob3N0IHRhYiBleGlzdHMgLSBqdXN0IGp1bXAgdG8gaXQsIGRvbid0IGNsb3NlIG90aGVyIHRhYnNcclxuXHRcdFx0Ly8gVXNlciBjYW4gaGF2ZSBtdWx0aXBsZSBob21lIGJhc2UgdGFicyBvcGVuLCBidXQgY2xpY2tpbmcgc3RpY2t5IGljb24ganVtcHMgdG8gdGhlIFwib2NjdXBpZWRcIiBvbmVcclxuXHRcdFx0Y29uc3Qgc2hvdWxkRm9jdXMgPSAhdGhpcy5pc1NldHRpbmdzTW9kYWxPcGVuKCk7XHJcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5zZXRBY3RpdmVMZWFmKGdob3N0VGFiLCB7IGZvY3VzOiBzaG91bGRGb2N1cyB9KTtcclxuXHRcdFx0YXdhaXQgdGhpcy5jb25maWd1cmVWaWV3KGdob3N0VGFiLCBmaWxlKTtcclxuXHJcblx0XHRcdGlmIChydW5Db21tYW5kKSB7XHJcblx0XHRcdFx0dGhpcy5ydW5Db21tYW5kT25PcGVuKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gR2hvc3QgdGFiIGRvZXNuJ3QgZXhpc3QgLSBjcmVhdGUgaXRcclxuXHRcdC8vIERvbid0IGNsb3NlIGV4aXN0aW5nIHRhYnMgLSB1c2VyIGNhbiBoYXZlIG11bHRpcGxlIGhvbWUgYmFzZSB0YWJzXHJcblx0XHQvLyBUaGUgZmlyc3Qgb25lIHdlIGNyZWF0ZSB3aWxsIFwib2NjdXB5XCIgdGhlIGdob3N0IHRhYiBzbG90IChiZSBwaW5uZWQgYW5kIGhpZGRlbilcclxuXHJcblx0XHQvLyBDcmVhdGUgbmV3IGdob3N0IHRhYlxyXG5cdFx0Y29uc3QgbmV3R2hvc3RUYWIgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhZigndGFiJyk7XHJcblx0XHR0aGlzLmdob3N0TGVhdmVzLmFkZChuZXdHaG9zdFRhYik7XHJcblx0XHRhd2FpdCBuZXdHaG9zdFRhYi5vcGVuRmlsZShmaWxlKTtcclxuXHJcblx0XHQvLyBQaW4gdGhlIGdob3N0IHRhYiAodW5sZXNzIGl0J3MgcmFuZG9tIC0gZmlsZSBjaGFuZ2VzIGVhY2ggdGltZSlcclxuXHRcdGlmICghaXNSYW5kb20pIHtcclxuXHRcdFx0bmV3R2hvc3RUYWIuc2V0UGlubmVkKHRydWUpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIE1hcmsgdGhlIHRhYiBoZWFkZXIgaW1tZWRpYXRlbHkgYWZ0ZXIgcGlubmluZyAoZm9yIGF1dG8taGlkZSB0YWIgY291bnRpbmcpXHJcblx0XHQvLyBVc2UgYSBzbWFsbCBkZWxheSB0byBlbnN1cmUgdGhlIHRhYiBoZWFkZXIgZXhpc3RzXHJcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uc3RpY2t5VGFiU2VydmljZS51cGRhdGVUYWJIZWFkZXJzKCk7XHJcblx0XHR9LCA1MCk7XHJcblxyXG5cdFx0Ly8gRm9jdXMgaXRcclxuXHRcdGNvbnN0IHNob3VsZEZvY3VzID0gIXRoaXMuaXNTZXR0aW5nc01vZGFsT3BlbigpO1xyXG5cdFx0dGhpcy5hcHAud29ya3NwYWNlLnNldEFjdGl2ZUxlYWYobmV3R2hvc3RUYWIsIHsgZm9jdXM6IHNob3VsZEZvY3VzIH0pO1xyXG5cclxuXHRcdC8vIENvbmZpZ3VyZSB0aGUgdmlld1xyXG5cdFx0YXdhaXQgdGhpcy5jb25maWd1cmVWaWV3KG5ld0dob3N0VGFiLCBmaWxlKTtcclxuXHJcblx0XHQvLyBSdW4gY29tbWFuZCBpZiBjb25maWd1cmVkXHJcblx0XHRpZiAocnVuQ29tbWFuZCkge1xyXG5cdFx0XHR0aGlzLnJ1bkNvbW1hbmRPbk9wZW4oKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdHJ1ZTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEZpbmQgYW4gZW1wdHkgbGVhZlxyXG5cdCAqL1xyXG5cdHByaXZhdGUgZmluZEVtcHR5TGVhZigpOiBXb3Jrc3BhY2VMZWFmIHwgbnVsbCB7XHJcblx0XHRjb25zdCBsZWF2ZXMgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhdmVzT2ZUeXBlKCdlbXB0eScpO1xyXG5cdFx0cmV0dXJuIGxlYXZlc1swXSB8fCBudWxsO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IHRoZSBob21lIGJhc2UgZmlsZVxyXG5cdCAqL1xyXG5cdGdldEhvbWVCYXNlRmlsZSgpOiBURmlsZSB8IG51bGwge1xyXG5cdFx0Y29uc3QgaG9tZUJhc2VTZXR0aW5ncyA9IHRoaXMucGx1Z2luLmdldEhvbWVCYXNlU2V0dGluZ3MoKTtcclxuXHRcdGNvbnN0IHBhdGggPSByZXNvbHZlUGF0aFN5bmMoaG9tZUJhc2VTZXR0aW5ncy50eXBlLCBob21lQmFzZVNldHRpbmdzLnZhbHVlLCB0aGlzLmFwcCk7XHJcblx0XHRpZiAoIXBhdGgpIHJldHVybiBudWxsO1xyXG5cclxuXHRcdHJldHVybiBnZXRGaWxlQnlQYXRoKHRoaXMuYXBwLCBwYXRoKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEZhc3QgZGV0YWNoIGFsbCBsZWF2ZXMgdXNpbmcgY2hhbmdlTGF5b3V0IChsaWtlIGhvbWVwYWdlIHBsdWdpbilcclxuXHQgKiBUaGlzIGlzIG11Y2ggZmFzdGVyIHRoYW4gaXRlcmF0aW5nIGFuZCBkZXRhY2hpbmcgbGVhdmVzIGluZGl2aWR1YWxseVxyXG5cdCAqL1xyXG5cdGFzeW5jIGRldGFjaEFsbExlYXZlcygpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHRcdGNvbnN0IGxheW91dCA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMYXlvdXQoKTtcclxuXHRcdGxheW91dC5tYWluID0ge1xyXG5cdFx0XHRcImlkXCI6IFwiNTMyNDM3MzAxNTcyNmJhOFwiLFxyXG5cdFx0XHRcInR5cGVcIjogXCJzcGxpdFwiLFxyXG5cdFx0XHRcImNoaWxkcmVuXCI6IFt7XHJcblx0XHRcdFx0XCJpZFwiOiBcIjQ1MDk3MjRmOGJmODRkYTdcIixcclxuXHRcdFx0XHRcInR5cGVcIjogXCJ0YWJzXCIsXHJcblx0XHRcdFx0XCJjaGlsZHJlblwiOiBbe1xyXG5cdFx0XHRcdFx0XCJpZFwiOiBcImU3YTdiMzAzYzYxNzg2ZGNcIixcclxuXHRcdFx0XHRcdFwidHlwZVwiOiBcImxlYWZcIixcclxuXHRcdFx0XHRcdFwic3RhdGVcIjogeyBcInR5cGVcIjogXCJlbXB0eVwiLCBcInN0YXRlXCI6IHt9LCBcImljb25cIjogXCJsdWNpZGUtZmlsZVwiLCBcInRpdGxlXCI6IFwiTmV3IHRhYlwiIH1cclxuXHRcdFx0XHR9XVxyXG5cdFx0XHR9XSxcclxuXHRcdFx0XCJkaXJlY3Rpb25cIjogXCJ2ZXJ0aWNhbFwiXHJcblx0XHR9O1xyXG5cdFx0bGF5b3V0LmFjdGl2ZSA9IFwiZTdhN2IzMDNjNjE3ODZkY1wiO1xyXG5cdFx0YXdhaXQgdGhpcy5hcHAud29ya3NwYWNlLmNoYW5nZUxheW91dChsYXlvdXQpO1xyXG5cclxuXHRcdGlmIChQbGF0Zm9ybS5pc01vYmlsZSkge1xyXG5cclxuXHRcdFx0KHRoaXMuYXBwLndvcmtzcGFjZS5yaWdodFNwbGl0IGFzIHsgdXBkYXRlSW5mbz86ICgpID0+IHZvaWQgfSk/LnVwZGF0ZUluZm8/LigpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogQ2xvc2UgYWxsIGxlYXZlcyBpbiB0aGUgbWFpbiB3b3Jrc3BhY2UgZXhjZXB0IHRoZSBzcGVjaWZpZWQgb25lXHJcblx0ICogU2ltcGxpZmllZCBhcHByb2FjaDogaXRlcmF0ZSBhbGwgbGVhdmVzIGFuZCBjbG9zZSB0aG9zZSBpbiBtYWluIHdvcmtzcGFjZVxyXG5cdCAqL1xyXG5cdGFzeW5jIGNsb3NlQWxsTGVhdmVzRXhjZXB0KGV4Y2VwdExlYWY6IFdvcmtzcGFjZUxlYWYgfCBudWxsKTogUHJvbWlzZTx2b2lkPiB7XHJcblx0XHQvLyBVc2UgaXRlcmF0ZUFsbExlYXZlcyB0byBnZXQgQUxMIGxlYXZlc1xyXG5cdFx0Y29uc3QgbGVhdmVzVG9DbG9zZTogV29ya3NwYWNlTGVhZltdID0gW107XHJcblxyXG5cdFx0dGhpcy5hcHAud29ya3NwYWNlLml0ZXJhdGVBbGxMZWF2ZXMoKGxlYWYpID0+IHtcclxuXHRcdFx0Ly8gU2tpcCB0aGUgZXhjZXB0aW9uIGxlYWZcclxuXHRcdFx0aWYgKGxlYWYgPT09IGV4Y2VwdExlYWYpIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFRyeSB0byBkZXRlcm1pbmUgaWYgdGhpcyBpcyBhIG1haW4gd29ya3NwYWNlIGxlYWZcclxuXHRcdFx0Ly8gR2V0IHRoZSB2aWV3J3MgY29udGFpbmVyIGVsZW1lbnRcclxuXHRcdFx0Y29uc3QgdmlldyA9IGxlYWYudmlldztcclxuXHRcdFx0bGV0IGNvbnRhaW5lcjogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcclxuXHJcblx0XHRcdGlmICh2aWV3KSB7XHJcblx0XHRcdFx0Y29uc3Qgdmlld0FueSA9IHZpZXcgYXMgdW5rbm93biBhcyB7IGNvbnRhaW5lckVsPzogSFRNTEVsZW1lbnQgfTtcclxuXHRcdFx0XHRjb250YWluZXIgPSB2aWV3QW55LmNvbnRhaW5lckVsIHx8IG51bGw7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIElmIG5vIGNvbnRhaW5lciBmcm9tIHZpZXcsIHRyeSBsZWFmJ3MgY29udGFpbmVyRWxcclxuXHRcdFx0aWYgKCFjb250YWluZXIpIHtcclxuXHRcdFx0XHRjb25zdCBsZWFmQW55ID0gbGVhZiBhcyB1bmtub3duIGFzIHsgY29udGFpbmVyRWw/OiBIVE1MRWxlbWVudCB9O1xyXG5cdFx0XHRcdGNvbnRhaW5lciA9IGxlYWZBbnkuY29udGFpbmVyRWwgfHwgbnVsbDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKGNvbnRhaW5lcikge1xyXG5cdFx0XHRcdC8vIENoZWNrIGlmIGl0J3MgaW4gdGhlIG1haW4gd29ya3NwYWNlIChyb290LCBub3Qgc2lkZWJhcilcclxuXHRcdFx0XHRjb25zdCByb290V29ya3NwYWNlID0gY29udGFpbmVyLmNsb3Nlc3QoJy53b3Jrc3BhY2Utc3BsaXQubW9kLXZlcnRpY2FsLm1vZC1yb290Jyk7XHJcblx0XHRcdFx0Y29uc3QgbGVmdFNpZGViYXIgPSBjb250YWluZXIuY2xvc2VzdCgnLndvcmtzcGFjZS1zcGxpdC5tb2QtbGVmdC1zcGxpdCcpO1xyXG5cdFx0XHRcdGNvbnN0IHJpZ2h0U2lkZWJhciA9IGNvbnRhaW5lci5jbG9zZXN0KCcud29ya3NwYWNlLXNwbGl0Lm1vZC1yaWdodC1zcGxpdCcpO1xyXG5cclxuXHRcdFx0XHRpZiAocm9vdFdvcmtzcGFjZSAmJiAhbGVmdFNpZGViYXIgJiYgIXJpZ2h0U2lkZWJhcikge1xyXG5cdFx0XHRcdFx0bGVhdmVzVG9DbG9zZS5wdXNoKGxlYWYpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHQvLyBJZiB3ZSBjYW4ndCBmaW5kIGNvbnRhaW5lciwgc3RpbGwgdHJ5IHRvIGNsb3NlIGl0IGlmIGl0J3MgaW4gbWFpbiB3b3Jrc3BhY2VcclxuXHRcdFx0XHQvLyBUaGlzIGhhbmRsZXMgZWRnZSBjYXNlcyB3aGVyZSBjb250YWluZXIgZGV0ZWN0aW9uIGZhaWxzXHJcblx0XHRcdFx0Ly8gT25seSBjbG9zZSBpZiB3ZSdyZSBjbG9zaW5nIGV2ZXJ5dGhpbmcgKGV4Y2VwdExlYWYgaXMgbnVsbClcclxuXHRcdFx0XHRpZiAoZXhjZXB0TGVhZiA9PT0gbnVsbCkge1xyXG5cdFx0XHRcdFx0Ly8gVHJ5IHRvIGdldCBsZWFmJ3MgdmlldyBzdGF0ZSB0byBjaGVjayBpZiBpdCdzIGEgbWFpbiB3b3Jrc3BhY2UgdGFiXHJcblx0XHRcdFx0XHR0cnkge1xyXG5cdFx0XHRcdFx0XHRjb25zdCB2aWV3U3RhdGUgPSBsZWFmLmdldFZpZXdTdGF0ZSgpO1xyXG5cdFx0XHRcdFx0XHQvLyBJZiBpdCBoYXMgYSB2aWV3IHN0YXRlLCBpdCdzIGxpa2VseSBhIG1haW4gd29ya3NwYWNlIHRhYlxyXG5cdFx0XHRcdFx0XHRpZiAodmlld1N0YXRlKSB7XHJcblx0XHRcdFx0XHRcdFx0bGVhdmVzVG9DbG9zZS5wdXNoKGxlYWYpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9IGNhdGNoIHtcclxuXHRcdFx0XHRcdFx0Ly8gSWYgd2UgY2FuJ3QgZ2V0IHZpZXcgc3RhdGUsIHNraXAgaXRcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHJcblx0XHQvLyBDbG9zZSBhbGwgaWRlbnRpZmllZCBsZWF2ZXNcclxuXHRcdGZvciAoY29uc3QgbGVhZiBvZiBsZWF2ZXNUb0Nsb3NlKSB7XHJcblx0XHRcdHZvaWQgbGVhZi5kZXRhY2goKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBXYWl0IGZvciBkZXRhY2htZW50cyB0byBjb21wbGV0ZVxyXG5cdFx0YXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDIwMCkpO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogRmluZCBhbiBleGlzdGluZyBncmFwaCBsZWFmIHRoYXQgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgYSBnaG9zdCB0YWJcclxuXHQgKi9cclxuXHRwcml2YXRlIGZpbmRHcmFwaEdob3N0VGFiKCk6IFdvcmtzcGFjZUxlYWYgfCBudWxsIHtcclxuXHRcdGxldCBncmFwaExlYXZlczogV29ya3NwYWNlTGVhZltdID0gW107XHJcblx0XHR0aGlzLmFwcC53b3Jrc3BhY2UuaXRlcmF0ZUFsbExlYXZlcygobGVhZikgPT4ge1xyXG5cdFx0XHRpZiAobGVhZi52aWV3Py5nZXRWaWV3VHlwZSgpID09PSAnZ3JhcGgnKSB7XHJcblx0XHRcdFx0Z3JhcGhMZWF2ZXMucHVzaChsZWFmKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gUHJlZmVyIHBpbm5lZCBncmFwaCB2aWV3XHJcblx0XHRjb25zdCBwaW5uZWQgPSBncmFwaExlYXZlcy5maW5kKGwgPT4gbC5nZXRWaWV3U3RhdGUoKS5waW5uZWQgPT09IHRydWUpO1xyXG5cdFx0aWYgKHBpbm5lZCkgcmV0dXJuIHBpbm5lZDtcclxuXHJcblx0XHQvLyBGYWxsYmFjayB0byBmaXJzdCBncmFwaCB2aWV3IGlmIG9ubHkgb25lIGV4aXN0c1xyXG5cdFx0aWYgKGdyYXBoTGVhdmVzLmxlbmd0aCA9PT0gMSAmJiBncmFwaExlYXZlc1swXSkgcmV0dXJuIGdyYXBoTGVhdmVzWzBdO1xyXG5cclxuXHRcdHJldHVybiBudWxsO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogQ2hlY2sgaWYgdGhlIGZvY3VzZWQgdGFiIGlzIHRoZSBob21lIGJhc2VcclxuXHQgKi9cclxuXHRpc0ZvY3VzZWRPbkhvbWVCYXNlKCk6IGJvb2xlYW4ge1xyXG5cdFx0Y29uc3QgYWN0aXZlTGVhZiA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE9WaWV3KT8ubGVhZjtcclxuXHRcdGlmICghYWN0aXZlTGVhZikgcmV0dXJuIGZhbHNlO1xyXG5cclxuXHRcdGNvbnN0IGhvbWVCYXNlU2V0dGluZ3MgPSB0aGlzLnBsdWdpbi5nZXRIb21lQmFzZVNldHRpbmdzKCk7XHJcblxyXG5cdFx0Ly8gSGFuZGxlIEdyYXBoIHZpZXdcclxuXHRcdGlmIChob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5HcmFwaCkge1xyXG5cdFx0XHRyZXR1cm4gYWN0aXZlTGVhZi52aWV3Py5nZXRWaWV3VHlwZSgpID09PSAnZ3JhcGgnO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEhhbmRsZSBmaWxlLWJhc2VkIHR5cGVzXHJcblx0XHRjb25zdCBob21lQmFzZUZpbGUgPSB0aGlzLmdldEhvbWVCYXNlRmlsZSgpO1xyXG5cdFx0aWYgKCFob21lQmFzZUZpbGUpIHJldHVybiBmYWxzZTtcclxuXHJcblx0XHRyZXR1cm4gbGVhZkhhc0ZpbGUoYWN0aXZlTGVhZiwgaG9tZUJhc2VGaWxlLnBhdGgpO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogQ2hlY2sgaWYgaG9tZSBiYXNlIGZpbGUgZXhpc3RzXHJcblx0ICovXHJcblx0aG9tZUJhc2VFeGlzdHMoKTogYm9vbGVhbiB7XHJcblx0XHRjb25zdCBob21lQmFzZVNldHRpbmdzID0gdGhpcy5wbHVnaW4uZ2V0SG9tZUJhc2VTZXR0aW5ncygpO1xyXG5cdFx0Y29uc3QgcGF0aCA9IHJlc29sdmVQYXRoU3luYyhob21lQmFzZVNldHRpbmdzLnR5cGUsIGhvbWVCYXNlU2V0dGluZ3MudmFsdWUsIHRoaXMuYXBwKTtcclxuXHRcdGlmICghcGF0aCkgcmV0dXJuIGZhbHNlO1xyXG5cclxuXHRcdHJldHVybiBnZXRGaWxlQnlQYXRoKHRoaXMuYXBwLCBwYXRoKSAhPT0gbnVsbDtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCB0aGUgbmF0aXZlIE9ic2lkaWFuIG9wZW4gYmVoYXZpb3Igc2V0dGluZyAoZnJvbSBhcHAuanNvbilcclxuXHQgKiBAcmV0dXJucyBUaGUgbmF0aXZlIHNldHRpbmcgdmFsdWUgb3IgdW5kZWZpbmVkIGlmIG5vdCBzdXBwb3J0ZWQvZm91bmRcclxuXHQgKi9cclxuXHRnZXROYXRpdmVPcGVuQmVoYXZpb3IoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcclxuXHRcdC8vIFRoZSBjb25maWcgcHJvcGVydHkgaXMgYWRkZWQgdmlhIGludGVybmFsIHR5cGUgYXVnbWVudGF0aW9uXHJcblx0XHRjb25zdCBjb25maWcgPSB0aGlzLmFwcC52YXVsdC5jb25maWc7XHJcblx0XHRpZiAoIWNvbmZpZykgcmV0dXJuIHVuZGVmaW5lZDtcclxuXHJcblx0XHRyZXR1cm4gY29uZmlnLm9wZW5CZWhhdmlvcjtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENoZWNrIGlmIHRoZSBzZXR0aW5ncyBtb2RhbCBpcyBjdXJyZW50bHkgb3BlblxyXG5cdCAqL1xyXG5cdHByaXZhdGUgaXNTZXR0aW5nc01vZGFsT3BlbigpOiBib29sZWFuIHtcclxuXHRcdC8vIENoZWNrIGZvciBzZXR0aW5ncyBtb2RhbCBieSBsb29raW5nIGZvciB0aGUgbW9kYWwgY29udGFpbmVyXHJcblx0XHQvLyBUcnkgbXVsdGlwbGUgc2VsZWN0b3JzIHRvIGJlIG1vcmUgcm9idXN0XHJcblx0XHRjb25zdCBzZXR0aW5nc01vZGFsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vZGFsLWNvbnRhaW5lci5tb2Qtc2V0dGluZ3MnKSB8fFxyXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kYWwubW9kLXNldHRpbmdzJykgfHxcclxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnZlcnRpY2FsLXRhYi1jb250ZW50Jyk7XHJcblxyXG5cdFx0Ly8gQWxzbyBjaGVjayBpZiBhbnkgbW9kYWwgaXMgb3BlbiBhbmQgY29udGFpbnMgc2V0dGluZ3MgY29udGVudFxyXG5cdFx0aWYgKCFzZXR0aW5nc01vZGFsKSB7XHJcblx0XHRcdGNvbnN0IGFsbE1vZGFscyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5tb2RhbC1jb250YWluZXInKTtcclxuXHRcdFx0Zm9yIChjb25zdCBtb2RhbCBvZiBBcnJheS5mcm9tKGFsbE1vZGFscykpIHtcclxuXHRcdFx0XHRpZiAobW9kYWwucXVlcnlTZWxlY3RvcignLnZlcnRpY2FsLXRhYi1jb250ZW50JykgfHxcclxuXHRcdFx0XHRcdG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJy5zZXR0aW5ncy1jb250ZW50JykgfHxcclxuXHRcdFx0XHRcdG1vZGFsLmNsYXNzTGlzdC5jb250YWlucygnbW9kLXNldHRpbmdzJykpIHtcclxuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBzZXR0aW5nc01vZGFsICE9PSBudWxsO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogU2V0IHRoZSBhY3RpdmUgZmlsZSBhcyBob21lIGJhc2VcclxuXHQgKi9cclxuXHRhc3luYyBzZXRBY3RpdmVGaWxlQXNIb21lQmFzZSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuXHRcdGNvbnN0IGFjdGl2ZUZpbGUgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpO1xyXG5cdFx0aWYgKCFhY3RpdmVGaWxlKSByZXR1cm4gZmFsc2U7XHJcblxyXG5cdFx0Ly8gQ2hlY2sgaWYgdGhlIGZpbGUgdHlwZSBpcyBzdXBwb3J0ZWRcclxuXHRcdGlmICghaXNTdXBwb3J0ZWRFeHRlbnNpb24oYWN0aXZlRmlsZS5leHRlbnNpb24udG9Mb3dlckNhc2UoKSkpIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zZXBhcmF0ZU1vYmlsZSAmJiBQbGF0Zm9ybS5pc01vYmlsZSkge1xyXG5cdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5tb2JpbGVIb21lQmFzZVR5cGUgPSBIb21lQmFzZVR5cGUuRmlsZTtcclxuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MubW9iaWxlSG9tZUJhc2VWYWx1ZSA9IGFjdGl2ZUZpbGUucGF0aDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmhvbWVCYXNlVHlwZSA9IEhvbWVCYXNlVHlwZS5GaWxlO1xyXG5cdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5ob21lQmFzZVZhbHVlID0gYWN0aXZlRmlsZS5wYXRoO1xyXG5cdFx0fVxyXG5cclxuXHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0cmV0dXJuIHRydWU7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBDaGVjayBpZiBhY3RpdmUgZmlsZSBjYW4gYmUgc2V0IGFzIGhvbWUgYmFzZVxyXG5cdCAqL1xyXG5cdGNhblNldEFjdGl2ZUZpbGVBc0hvbWVCYXNlKCk6IGJvb2xlYW4ge1xyXG5cdFx0Y29uc3QgYWN0aXZlRmlsZSA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVGaWxlKCk7XHJcblx0XHRpZiAoIWFjdGl2ZUZpbGUpIHJldHVybiBmYWxzZTtcclxuXHJcblx0XHRyZXR1cm4gaXNTdXBwb3J0ZWRFeHRlbnNpb24oYWN0aXZlRmlsZS5leHRlbnNpb24udG9Mb3dlckNhc2UoKSk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZXN0b3JlIGdob3N0IGxlYXZlcyBmcm9tIHByZXZpb3VzIHNlc3Npb25cclxuXHQgKiBUaGlzIGlkZW50aWZpZXMgcGlubmVkIGhvbWUgYmFzZSB0YWJzIHRoYXQgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgZ2hvc3QgbGVhdmVzXHJcblx0ICovXHJcblx0cmVzdG9yZUdob3N0TGVhdmVzKCk6IHZvaWQge1xyXG5cdFx0aWYgKCF0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93U3RpY2t5SG9tZUljb24pIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGhvbWVCYXNlU2V0dGluZ3MgPSB0aGlzLnBsdWdpbi5nZXRIb21lQmFzZVNldHRpbmdzKCk7XHJcblx0XHRjb25zdCBob21lQmFzZVBhdGggPSByZXNvbHZlUGF0aFN5bmMoaG9tZUJhc2VTZXR0aW5ncy50eXBlLCBob21lQmFzZVNldHRpbmdzLnZhbHVlLCB0aGlzLmFwcCk7XHJcblxyXG5cdFx0Ly8gRm9yIGZpbGUtYmFzZWQgdHlwZXMsIHdlIG5lZWQgYSBwYXRoXHJcblx0XHRpZiAoIWhvbWVCYXNlUGF0aCAmJiBob21lQmFzZVNldHRpbmdzLnR5cGUgIT09IEhvbWVCYXNlVHlwZS5HcmFwaCkgcmV0dXJuO1xyXG5cclxuXHRcdC8vIEZvciByYW5kb20vZHluYW1pYyB0eXBlcywgd2UgZG9uJ3QgcmVzdG9yZSBnaG9zdCBsZWF2ZXNcclxuXHRcdGNvbnN0IGlzUmFuZG9tID0gaG9tZUJhc2VTZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuUmFuZG9tIHx8XHJcblx0XHRcdGhvbWVCYXNlU2V0dGluZ3MudHlwZSA9PT0gSG9tZUJhc2VUeXBlLlJhbmRvbUZvbGRlciB8fFxyXG5cdFx0XHRob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5EYWlseU5vdGUgfHxcclxuXHRcdFx0aG9tZUJhc2VTZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuV2Vla2x5Tm90ZSB8fFxyXG5cdFx0XHRob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5Nb250aGx5Tm90ZSB8fFxyXG5cdFx0XHRob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5ZZWFybHlOb3RlO1xyXG5cclxuXHRcdGlmIChpc1JhbmRvbSkgcmV0dXJuO1xyXG5cclxuXHRcdC8vIEhhbmRsZSBHcmFwaCB2aWV3XHJcblx0XHRpZiAoaG9tZUJhc2VTZXR0aW5ncy50eXBlID09PSBIb21lQmFzZVR5cGUuR3JhcGgpIHtcclxuXHRcdFx0Y29uc3QgZ2hvc3RUYWIgPSB0aGlzLmZpbmRHcmFwaEdob3N0VGFiKCk7XHJcblx0XHRcdGlmIChnaG9zdFRhYiAmJiBnaG9zdFRhYi5nZXRWaWV3U3RhdGUoKS5waW5uZWQgPT09IHRydWUpIHtcclxuXHRcdFx0XHR0aGlzLmdob3N0TGVhdmVzLmFkZChnaG9zdFRhYik7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEZpbmQgcGlubmVkIGhvbWUgYmFzZSB0YWJzIGFuZCBtYXJrIHRoZSBmaXJzdCBvbmUgYXMgYSBnaG9zdCBsZWFmXHJcblx0XHRjb25zdCBsZWF2ZXM6IFdvcmtzcGFjZUxlYWZbXSA9IFtdO1xyXG5cdFx0dGhpcy5hcHAud29ya3NwYWNlLml0ZXJhdGVBbGxMZWF2ZXMoKGxlYWYpID0+IHtcclxuXHRcdFx0Y29uc3Qgdmlld1R5cGUgPSBsZWFmLnZpZXc/LmdldFZpZXdUeXBlKCk7XHJcblx0XHRcdGlmICh2aWV3VHlwZSAmJiBMRUFGX1RZUEVTLmluY2x1ZGVzKHZpZXdUeXBlKSkge1xyXG5cdFx0XHRcdGxlYXZlcy5wdXNoKGxlYWYpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHRmb3IgKGNvbnN0IGxlYWYgb2YgbGVhdmVzKSB7XHJcblx0XHRcdGlmIChob21lQmFzZVBhdGggJiYgbGVhZkhhc0ZpbGUobGVhZiwgaG9tZUJhc2VQYXRoKSkge1xyXG5cdFx0XHRcdGNvbnN0IHZpZXdTdGF0ZSA9IGxlYWYuZ2V0Vmlld1N0YXRlKCk7XHJcblx0XHRcdFx0aWYgKHZpZXdTdGF0ZS5waW5uZWQgPT09IHRydWUgJiYgIXRoaXMuZ2hvc3RMZWF2ZXMuaGFzKGxlYWYpKSB7XHJcblx0XHRcdFx0XHQvLyBGb3VuZCBhIHBpbm5lZCBob21lIGJhc2UgdGFiIC0gbWFyayBpdCBhcyBnaG9zdFxyXG5cdFx0XHRcdFx0dGhpcy5naG9zdExlYXZlcy5hZGQobGVhZik7XHJcblx0XHRcdFx0XHQvLyBPbmx5IHJlc3RvcmUgb25lIGdob3N0IGxlYWYgKHRoZSBmaXJzdCBwaW5uZWQgaG9tZSBiYXNlIHRhYilcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxufVxyXG4iLCAiLyoqXHJcbiAqIEZpbGUgVXRpbGl0aWVzXHJcbiAqIEhlbHBlciBmdW5jdGlvbnMgZm9yIGZpbGUgdHlwZSBkZXRlY3Rpb24gYW5kIGhhbmRsaW5nXHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgQXBwLCBURmlsZSwgV29ya3NwYWNlTGVhZiB9IGZyb20gJ29ic2lkaWFuJztcclxuXHJcbi8qKlxyXG4gKiBTdXBwb3J0ZWQgZmlsZSBleHRlbnNpb25zIGZvciBob21lIGJhc2VcclxuICovXHJcbmV4cG9ydCBjb25zdCBTVVBQT1JURURfRVhURU5TSU9OUyA9IFsnbWQnLCAnbWR4JywgJ2NhbnZhcycsICdiYXNlJywgJ2thbmJhbiddIGFzIGNvbnN0O1xyXG5leHBvcnQgdHlwZSBTdXBwb3J0ZWRFeHRlbnNpb24gPSB0eXBlb2YgU1VQUE9SVEVEX0VYVEVOU0lPTlNbbnVtYmVyXTtcclxuXHJcbi8qKlxyXG4gKiBWaWV3IHR5cGVzIGNvcnJlc3BvbmRpbmcgdG8gZmlsZSBleHRlbnNpb25zXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgVklFV19UWVBFX01BUDogUmVjb3JkPFN1cHBvcnRlZEV4dGVuc2lvbiwgc3RyaW5nPiA9IHtcclxuXHQnbWQnOiAnbWFya2Rvd24nLFxyXG5cdCdtZHgnOiAnbWFya2Rvd24nLFxyXG5cdCdjYW52YXMnOiAnY2FudmFzJyxcclxuXHQnYmFzZSc6ICdiYXNlcycsXHJcblx0J2thbmJhbic6ICdrYW5iYW4nLFxyXG59O1xyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIGEgZmlsZSBleHRlbnNpb24gaXMgc3VwcG9ydGVkXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaXNTdXBwb3J0ZWRFeHRlbnNpb24oZXh0ZW5zaW9uOiBzdHJpbmcpOiBleHRlbnNpb24gaXMgU3VwcG9ydGVkRXh0ZW5zaW9uIHtcclxuXHRyZXR1cm4gU1VQUE9SVEVEX0VYVEVOU0lPTlMuaW5jbHVkZXMoZXh0ZW5zaW9uIGFzIFN1cHBvcnRlZEV4dGVuc2lvbik7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIGZpbGUgZXh0ZW5zaW9uIGZyb20gYSBwYXRoXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsZUV4dGVuc2lvbihwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xyXG5cdGNvbnN0IHBhcnRzID0gcGF0aC5zcGxpdCgnLicpO1xyXG5cdHJldHVybiBwYXJ0cy5sZW5ndGggPiAxID8gKHBhcnRzW3BhcnRzLmxlbmd0aCAtIDFdID8/ICcnKS50b0xvd2VyQ2FzZSgpIDogJyc7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIHZpZXcgdHlwZSBmb3IgYSBmaWxlXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Vmlld1R5cGVGb3JGaWxlKGZpbGU6IFRGaWxlKTogc3RyaW5nIHtcclxuXHRjb25zdCBleHQgPSBmaWxlLmV4dGVuc2lvbi50b0xvd2VyQ2FzZSgpO1xyXG5cdGlmIChpc1N1cHBvcnRlZEV4dGVuc2lvbihleHQpKSB7XHJcblx0XHRyZXR1cm4gVklFV19UWVBFX01BUFtleHRdO1xyXG5cdH1cclxuXHRyZXR1cm4gJ21hcmtkb3duJzsgLy8gRGVmYXVsdCBmYWxsYmFja1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2sgaWYgYSBmaWxlIGlzIGEgbWFya2Rvd24tbGlrZSBmaWxlIChtZCBvciBtZHgpXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaXNNYXJrZG93bkxpa2UoZmlsZTogVEZpbGUpOiBib29sZWFuIHtcclxuXHRjb25zdCBleHQgPSBmaWxlLmV4dGVuc2lvbi50b0xvd2VyQ2FzZSgpO1xyXG5cdHJldHVybiBleHQgPT09ICdtZCcgfHwgZXh0ID09PSAnbWR4JztcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIGEgZmlsZSBpcyBhbiBNRFggZmlsZVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGlzTWR4RmlsZShmaWxlOiBURmlsZSk6IGJvb2xlYW4ge1xyXG5cdHJldHVybiBmaWxlLmV4dGVuc2lvbi50b0xvd2VyQ2FzZSgpID09PSAnbWR4JztcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIGEgZmlsZSBpcyBhIGNhbnZhcyBmaWxlXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaXNDYW52YXNGaWxlKGZpbGU6IFRGaWxlKTogYm9vbGVhbiB7XHJcblx0cmV0dXJuIGZpbGUuZXh0ZW5zaW9uLnRvTG93ZXJDYXNlKCkgPT09ICdjYW52YXMnO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2sgaWYgYSBmaWxlIGlzIGEgYmFzZSBmaWxlXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaXNCYXNlRmlsZShmaWxlOiBURmlsZSk6IGJvb2xlYW4ge1xyXG5cdHJldHVybiBmaWxlLmV4dGVuc2lvbi50b0xvd2VyQ2FzZSgpID09PSAnYmFzZSc7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBmaWxlIGJ5IHBhdGgsIHRyeWluZyB3aXRoIGFuZCB3aXRob3V0IGV4dGVuc2lvblxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZpbGVCeVBhdGgoYXBwOiBBcHAsIHBhdGg6IHN0cmluZyk6IFRGaWxlIHwgbnVsbCB7XHJcblx0Ly8gVHJ5IGV4YWN0IHBhdGggZmlyc3RcclxuXHRjb25zdCBleGFjdE1hdGNoID0gYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChwYXRoKTtcclxuXHRpZiAoZXhhY3RNYXRjaCBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRyZXR1cm4gZXhhY3RNYXRjaDtcclxuXHR9XHJcblxyXG5cdC8vIFRyeSB1c2luZyBtZXRhZGF0YUNhY2hlIGZvciBmdXp6eSBtYXRjaGluZ1xyXG5cdGNvbnN0IGZpbGUgPSBhcHAubWV0YWRhdGFDYWNoZS5nZXRGaXJzdExpbmtwYXRoRGVzdChwYXRoLCAnLycpO1xyXG5cdHJldHVybiBmaWxlO1xyXG59XHJcblxyXG4vKipcclxuICogVHJpbSB0aGUgZmlsZSBleHRlbnNpb24gZnJvbSBhIHBhdGggZm9yIGNvbXBhcmlzb25cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiB0cmltRmlsZUV4dGVuc2lvbihwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xyXG5cdGNvbnN0IGxhc3REb3QgPSBwYXRoLmxhc3RJbmRleE9mKCcuJyk7XHJcblx0aWYgKGxhc3REb3QgPiAwKSB7XHJcblx0XHRjb25zdCBleHQgPSBwYXRoLnNsaWNlKGxhc3REb3QgKyAxKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0aWYgKFNVUFBPUlRFRF9FWFRFTlNJT05TLmluY2x1ZGVzKGV4dCBhcyBTdXBwb3J0ZWRFeHRlbnNpb24pKSB7XHJcblx0XHRcdHJldHVybiBwYXRoLnNsaWNlKDAsIGxhc3REb3QpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRyZXR1cm4gcGF0aDtcclxufVxyXG5cclxuLyoqXHJcbiAqIENvbXBhcmUgdHdvIHBhdGhzLCBpZ25vcmluZyBjYXNlIGFuZCBleHRlbnNpb24gZGlmZmVyZW5jZXNcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBwYXRoc0VxdWFsKHBhdGgxOiBzdHJpbmcsIHBhdGgyOiBzdHJpbmcpOiBib29sZWFuIHtcclxuXHRjb25zdCBub3JtMSA9IHRyaW1GaWxlRXh0ZW5zaW9uKHBhdGgxKS50b0xvd2VyQ2FzZSgpO1xyXG5cdGNvbnN0IG5vcm0yID0gdHJpbUZpbGVFeHRlbnNpb24ocGF0aDIpLnRvTG93ZXJDYXNlKCk7XHJcblx0cmV0dXJuIG5vcm0xID09PSBub3JtMjtcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIGEgbGVhZiBpcyBzaG93aW5nIGEgc3BlY2lmaWMgZmlsZVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGxlYWZIYXNGaWxlKGxlYWY6IFdvcmtzcGFjZUxlYWYsIGZpbGVQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcclxuXHRjb25zdCBzdGF0ZSA9IGxlYWYudmlldz8uZ2V0U3RhdGU/LigpO1xyXG5cdGNvbnN0IGxlYWZGaWxlID0gc3RhdGU/LmZpbGUgYXMgc3RyaW5nIHwgdW5kZWZpbmVkO1xyXG5cdFxyXG5cdGlmICghbGVhZkZpbGUpIHJldHVybiBmYWxzZTtcclxuXHRcclxuXHRyZXR1cm4gcGF0aHNFcXVhbChsZWFmRmlsZSwgZmlsZVBhdGgpO1xyXG59XHJcbiIsICIvKipcclxuICogSG9tZSBCYXNlIFR5cGUgUmVzb2x1dGlvbiBVdGlsaXRpZXNcclxuICogUmVzb2x2ZXMgaG9tZSBiYXNlIHBhdGhzIGJhc2VkIG9uIHR5cGUgKEZpbGUsIFdvcmtzcGFjZSwgUmFuZG9tLCBldGMuKVxyXG4gKi9cclxuXHJcbmltcG9ydCB7IEFwcCwgVEZpbGUsIFRGb2xkZXIsIG1vbWVudCwgTm90aWNlIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBIb21lQmFzZVR5cGUgfSBmcm9tICcuLi9zZXR0aW5ncyc7XHJcbmltcG9ydCB0eXBlIEhvbWVCYXNlUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5pbXBvcnQge1xyXG5cdGNyZWF0ZURhaWx5Tm90ZSwgZ2V0RGFpbHlOb3RlLCBnZXRBbGxEYWlseU5vdGVzLFxyXG5cdGNyZWF0ZVdlZWtseU5vdGUsIGdldFdlZWtseU5vdGUsIGdldEFsbFdlZWtseU5vdGVzLFxyXG5cdGNyZWF0ZU1vbnRobHlOb3RlLCBnZXRNb250aGx5Tm90ZSwgZ2V0QWxsTW9udGhseU5vdGVzLFxyXG5cdGNyZWF0ZVF1YXJ0ZXJseU5vdGUsIGdldFF1YXJ0ZXJseU5vdGUsIGdldEFsbFF1YXJ0ZXJseU5vdGVzLFxyXG5cdGNyZWF0ZVllYXJseU5vdGUsIGdldFllYXJseU5vdGUsIGdldEFsbFllYXJseU5vdGVzLFxyXG59IGZyb20gJ29ic2lkaWFuLWRhaWx5LW5vdGVzLWludGVyZmFjZSc7XHJcblxyXG4vKipcclxuICogR2V0IGEgcmFuZG9tIGZpbGUgZnJvbSB0aGUgdmF1bHRcclxuICogQHBhcmFtIGFwcCBUaGUgT2JzaWRpYW4gYXBwIGluc3RhbmNlXHJcbiAqIEBwYXJhbSByb290IE9wdGlvbmFsIGZvbGRlciBwYXRoIE9SIGZpbGVuYW1lIHBhdHRlcm4gKGUuZy4sIFwiaW5kZXgubWRcIiB0byBmaW5kIGFsbCBmaWxlcyBuYW1lZCBpbmRleC5tZClcclxuICovXHJcbmZ1bmN0aW9uIHJhbmRvbUZpbGUoYXBwOiBBcHAsIHJvb3Q/OiBzdHJpbmcpOiBURmlsZSB8IG51bGwge1xyXG5cdGxldCBmaWxlczogVEZpbGVbXSA9IFtdO1xyXG5cdFxyXG5cdGlmIChyb290KSB7XHJcblx0XHQvLyBGaXJzdCB0cnkgYXMgYSBmb2xkZXIgcGF0aFxyXG5cdFx0Y29uc3QgcmVzb2x2ZWRSb290ID0gYXBwLnZhdWx0LmdldEZvbGRlckJ5UGF0aChyb290KTtcclxuXHRcdGlmIChyZXNvbHZlZFJvb3QpIHtcclxuXHRcdFx0Ly8gSXQncyBhIGZvbGRlciAtIGdldCBhbGwgZmlsZXMgaW4gaXRcclxuXHRcdFx0ZmlsZXMgPSBnZXRGaWxlc0luRm9sZGVyKHJlc29sdmVkUm9vdCk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHQvLyBOb3QgYSBmb2xkZXIgLSB0cmVhdCBhcyBmaWxlbmFtZSBwYXR0ZXJuIChlLmcuLCBcImluZGV4Lm1kXCIpXHJcblx0XHRcdC8vIFNlYXJjaCBmb3IgYWxsIGZpbGVzIG1hdGNoaW5nIHRoaXMgbmFtZSBpbiB0aGUgdmF1bHRcclxuXHRcdFx0Y29uc3QgYWxsRmlsZXMgPSBhcHAudmF1bHQuZ2V0RmlsZXMoKTtcclxuXHRcdFx0Y29uc3QgcGF0dGVybiA9IHJvb3QudG9Mb3dlckNhc2UoKTtcclxuXHRcdFx0ZmlsZXMgPSBhbGxGaWxlcy5maWx0ZXIoKGY6IFRGaWxlKSA9PiB7XHJcblx0XHRcdFx0Y29uc3QgZmlsZU5hbWUgPSBmLm5hbWUudG9Mb3dlckNhc2UoKTtcclxuXHRcdFx0XHRyZXR1cm4gZmlsZU5hbWUgPT09IHBhdHRlcm4gfHwgZmlsZU5hbWUgPT09IHBhdHRlcm4ucmVwbGFjZSgvXFwubWQkLywgJycpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHR9IGVsc2Uge1xyXG5cdFx0Ly8gTm8gcm9vdCBzcGVjaWZpZWQgLSBnZXQgYWxsIGZpbGVzXHJcblx0XHRmaWxlcyA9IGFwcC52YXVsdC5nZXRGaWxlcygpO1xyXG5cdH1cclxuXHJcblx0Ly8gRmlsdGVyIHRvIHN1cHBvcnRlZCBmaWxlIHR5cGVzXHJcblx0ZmlsZXMgPSBmaWxlcy5maWx0ZXIoKGY6IFRGaWxlKSA9PiBbJ21kJywgJ2NhbnZhcycsICdiYXNlJ10uaW5jbHVkZXMoZi5leHRlbnNpb24pKTtcclxuXHRcclxuXHRpZiAoZmlsZXMubGVuZ3RoKSB7XHJcblx0XHRjb25zdCBpbmRleCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGZpbGVzLmxlbmd0aCk7XHJcblx0XHRyZXR1cm4gZmlsZXNbaW5kZXhdIHx8IG51bGw7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gbnVsbDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBhbGwgZmlsZXMgaW4gYSBmb2xkZXIgcmVjdXJzaXZlbHlcclxuICovXHJcbmZ1bmN0aW9uIGdldEZpbGVzSW5Gb2xkZXIoZm9sZGVyOiBURm9sZGVyKTogVEZpbGVbXSB7XHJcblx0bGV0IGZpbGVzOiBURmlsZVtdID0gW107XHJcblx0XHJcblx0Zm9yIChjb25zdCBpdGVtIG9mIGZvbGRlci5jaGlsZHJlbikge1xyXG5cdFx0aWYgKGl0ZW0gaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRmaWxlcy5wdXNoKGl0ZW0pO1xyXG5cdFx0fSBlbHNlIGlmIChpdGVtIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRmaWxlcy5wdXNoKC4uLmdldEZpbGVzSW5Gb2xkZXIoaXRlbSkpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRcclxuXHRyZXR1cm4gZmlsZXM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUcmltIGZpbGUgZXh0ZW5zaW9uIGZvciAubWQgZmlsZXMgKGxpa2UgaG9tZXBhZ2UgcGx1Z2luKVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHRyaW1GaWxlKGZpbGU6IFRGaWxlKTogc3RyaW5nIHtcclxuXHRpZiAoIWZpbGUpIHJldHVybiAnJztcclxuXHRyZXR1cm4gZmlsZS5leHRlbnNpb24gPT09ICdtZCcgPyBmaWxlLnBhdGguc2xpY2UoMCwgLTMpIDogZmlsZS5wYXRoO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIFBlcmlvZGljIG5vdGUgaW5mbyAobGlrZSBob21lcGFnZSBwbHVnaW4pXHJcbiAqL1xyXG5pbnRlcmZhY2UgUGVyaW9kaWNJbmZvIHtcclxuXHRub3VuOiBzdHJpbmc7XHJcblx0YWRqZWN0aXZlOiBzdHJpbmc7XHJcblx0Y3JlYXRlOiAoZGF0ZTogbW9tZW50Lk1vbWVudCkgPT4gUHJvbWlzZTxURmlsZT47XHJcblx0Z2V0OiAoZGF0ZTogbW9tZW50Lk1vbWVudCwgYWxsOiBSZWNvcmQ8c3RyaW5nLCBURmlsZT4pID0+IFRGaWxlO1xyXG5cdGdldEFsbDogKCkgPT4gUmVjb3JkPHN0cmluZywgVEZpbGU+O1xyXG59XHJcblxyXG5jb25zdCBQRVJJT0RJQ19JTkZPOiBSZWNvcmQ8SG9tZUJhc2VUeXBlLCBQZXJpb2RpY0luZm8gfCBudWxsPiA9IHtcclxuXHRbSG9tZUJhc2VUeXBlLkRhaWx5Tm90ZV06IHtcclxuXHRcdG5vdW46ICdkYXknLFxyXG5cdFx0YWRqZWN0aXZlOiAnZGFpbHknLFxyXG5cdFx0Y3JlYXRlOiBjcmVhdGVEYWlseU5vdGUsXHJcblx0XHRnZXQ6IGdldERhaWx5Tm90ZSxcclxuXHRcdGdldEFsbDogZ2V0QWxsRGFpbHlOb3RlcyxcclxuXHR9LFxyXG5cdFtIb21lQmFzZVR5cGUuV2Vla2x5Tm90ZV06IHtcclxuXHRcdG5vdW46ICd3ZWVrJyxcclxuXHRcdGFkamVjdGl2ZTogJ3dlZWtseScsXHJcblx0XHRjcmVhdGU6IGNyZWF0ZVdlZWtseU5vdGUsXHJcblx0XHRnZXQ6IGdldFdlZWtseU5vdGUsXHJcblx0XHRnZXRBbGw6IGdldEFsbFdlZWtseU5vdGVzLFxyXG5cdH0sXHJcblx0W0hvbWVCYXNlVHlwZS5Nb250aGx5Tm90ZV06IHtcclxuXHRcdG5vdW46ICdtb250aCcsXHJcblx0XHRhZGplY3RpdmU6ICdtb250aGx5JyxcclxuXHRcdGNyZWF0ZTogY3JlYXRlTW9udGhseU5vdGUsXHJcblx0XHRnZXQ6IGdldE1vbnRobHlOb3RlLFxyXG5cdFx0Z2V0QWxsOiBnZXRBbGxNb250aGx5Tm90ZXMsXHJcblx0fSxcclxuXHRbSG9tZUJhc2VUeXBlLlF1YXJ0ZXJseU5vdGVdOiB7XHJcblx0XHRub3VuOiAncXVhcnRlcicsXHJcblx0XHRhZGplY3RpdmU6ICdxdWFydGVybHknLFxyXG5cdFx0Y3JlYXRlOiBjcmVhdGVRdWFydGVybHlOb3RlLFxyXG5cdFx0Z2V0OiBnZXRRdWFydGVybHlOb3RlLFxyXG5cdFx0Z2V0QWxsOiBnZXRBbGxRdWFydGVybHlOb3RlcyxcclxuXHR9LFxyXG5cdFtIb21lQmFzZVR5cGUuWWVhcmx5Tm90ZV06IHtcclxuXHRcdG5vdW46ICd5ZWFyJyxcclxuXHRcdGFkamVjdGl2ZTogJ3llYXJseScsXHJcblx0XHRjcmVhdGU6IGNyZWF0ZVllYXJseU5vdGUsXHJcblx0XHRnZXQ6IGdldFllYXJseU5vdGUsXHJcblx0XHRnZXRBbGw6IGdldEFsbFllYXJseU5vdGVzLFxyXG5cdH0sXHJcblx0W0hvbWVCYXNlVHlwZS5GaWxlXTogbnVsbCxcclxuXHRbSG9tZUJhc2VUeXBlLlJhbmRvbV06IG51bGwsXHJcblx0W0hvbWVCYXNlVHlwZS5SYW5kb21Gb2xkZXJdOiBudWxsLFxyXG5cdFtIb21lQmFzZVR5cGUuV29ya3NwYWNlXTogbnVsbCxcclxuXHRbSG9tZUJhc2VUeXBlLkdyYXBoXTogbnVsbCxcclxuXHRbSG9tZUJhc2VUeXBlLk5vbmVdOiBudWxsLFxyXG5cdFtIb21lQmFzZVR5cGUuSm91cm5hbF06IG51bGwsXHJcblx0W0hvbWVCYXNlVHlwZS5OZXdOb3RlXTogbnVsbCxcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXQgcGVyaW9kaWMgbm90ZSBwYXRoIChEYWlseSwgV2Vla2x5LCBNb250aGx5LCBZZWFybHkpXHJcbiAqIEJhc2VkIG9uIGhvbWVwYWdlIHBsdWdpbiBpbXBsZW1lbnRhdGlvblxyXG4gKi9cclxuYXN5bmMgZnVuY3Rpb24gZ2V0UGVyaW9kaWNOb3RlKGtpbmQ6IEhvbWVCYXNlVHlwZSwgcGx1Z2luOiBIb21lQmFzZVBsdWdpbik6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xyXG5cdGlmICghd2luZG93Lm1vbWVudCkge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cdFxyXG5cdGNvbnN0IGluZm8gPSBQRVJJT0RJQ19JTkZPW2tpbmRdO1xyXG5cdGlmICghaW5mbykge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cdFxyXG5cdGNvbnN0IGRhdGUgPSBtb21lbnQoKS5zdGFydE9mKGluZm8ubm91biBhcyBtb21lbnQudW5pdE9mVGltZS5TdGFydE9mKTtcclxuXHRjb25zdCBjb21tdW5pdHlQbHVnaW5zID0gcGx1Z2luLmFwcC5wbHVnaW5zPy5wbHVnaW5zIHx8IHt9O1xyXG5cdGNvbnN0IHBlcmlvZGljTm90ZXNQbHVnaW4gPSBjb21tdW5pdHlQbHVnaW5zWydwZXJpb2RpYy1ub3RlcyddO1xyXG5cdGNvbnN0IGlzTGVnYWN5ID0gIXBlcmlvZGljTm90ZXNQbHVnaW4gfHwgKHBlcmlvZGljTm90ZXNQbHVnaW4ubWFuaWZlc3Q/LnZlcnNpb24gfHwgJzAnKS5zdGFydHNXaXRoKCcwJyk7XHJcblx0XHJcblx0bGV0IG5vdGU6IFRGaWxlIHwgbnVsbCA9IG51bGw7XHJcblx0XHJcblx0aWYgKGlzTGVnYWN5KSB7XHJcblx0XHQvLyBMZWdhY3kgUGVyaW9kaWMgTm90ZXMgb3IgQ29yZSBEYWlseSBOb3RlcyAodmlhIGludGVyZmFjZSlcclxuXHRcdGxldCBhbGwgPSBpbmZvLmdldEFsbCgpO1xyXG5cdFx0bm90ZSA9IGluZm8uZ2V0KGRhdGUsIGFsbCk7XHJcblx0XHRcclxuXHRcdC8vIElmIG5vdGUgZG9lc24ndCBleGlzdCBhbmQgd2FpdCBmb3IgZ2l0IHN5bmMgaXMgZW5hYmxlZCwgd2FpdCBiZWZvcmUgY3JlYXRpbmdcclxuXHRcdGlmICghbm90ZSAmJiBwbHVnaW4uc2V0dGluZ3Mud2FpdEZvckdpdFN5bmMpIHtcclxuXHRcdFx0bmV3IE5vdGljZShgSG9tZSBCYXNlOiBXYWl0aW5nIGZvciBnaXQgc3luYyAoJHtwbHVnaW4uc2V0dGluZ3MuZ2l0U3luY1RpbWVvdXR9cykuLi5gLCA1MDAwKTtcclxuXHRcdFx0YXdhaXQgZGVsYXkocGx1Z2luLnNldHRpbmdzLmdpdFN5bmNUaW1lb3V0ICogMTAwMCk7XHJcblx0XHRcdGFsbCA9IGluZm8uZ2V0QWxsKCk7XHJcblx0XHRcdG5vdGUgPSBpbmZvLmdldChkYXRlLCBhbGwpO1xyXG5cdFx0fVxyXG5cdFx0XHJcblx0XHRpZiAoIW5vdGUpIHtcclxuXHRcdFx0bm90ZSA9IGF3YWl0IGluZm8uY3JlYXRlKGRhdGUpO1xyXG5cdFx0fVxyXG5cdH0gZWxzZSB7XHJcblx0XHQvLyB2MS4wLjArIFBlcmlvZGljIE5vdGVzIEFQSVxyXG5cdFx0cGVyaW9kaWNOb3Rlc1BsdWdpbi5jYWNoZT8uaW5pdGlhbGl6ZT8uKCk7XHJcblx0XHRub3RlID0gcGVyaW9kaWNOb3Rlc1BsdWdpbi5nZXRQZXJpb2RpY05vdGU/LihpbmZvLm5vdW4gYXMgJ2RheScgfCAnd2VlaycgfCAnbW9udGgnIHwgJ3llYXInLCBkYXRlKSA/PyBudWxsO1xyXG5cdFx0XHJcblx0XHQvLyBJZiBub3RlIGRvZXNuJ3QgZXhpc3QgYW5kIHdhaXQgZm9yIGdpdCBzeW5jIGlzIGVuYWJsZWQsIHdhaXQgYmVmb3JlIGNyZWF0aW5nXHJcblx0XHRpZiAoIW5vdGUgJiYgcGx1Z2luLnNldHRpbmdzLndhaXRGb3JHaXRTeW5jKSB7XHJcblx0XHRcdG5ldyBOb3RpY2UoYEhvbWUgQmFzZTogV2FpdGluZyBmb3IgZ2l0IHN5bmMgKCR7cGx1Z2luLnNldHRpbmdzLmdpdFN5bmNUaW1lb3V0fXMpLi4uYCwgNTAwMCk7XHJcblx0XHRcdGF3YWl0IGRlbGF5KHBsdWdpbi5zZXR0aW5ncy5naXRTeW5jVGltZW91dCAqIDEwMDApO1xyXG5cdFx0XHRwZXJpb2RpY05vdGVzUGx1Z2luLmNhY2hlPy5pbml0aWFsaXplPy4oKTtcclxuXHRcdFx0bm90ZSA9IHBlcmlvZGljTm90ZXNQbHVnaW4uZ2V0UGVyaW9kaWNOb3RlPy4oaW5mby5ub3VuIGFzICdkYXknIHwgJ3dlZWsnIHwgJ21vbnRoJyB8ICd5ZWFyJywgZGF0ZSkgPz8gbnVsbDtcclxuXHRcdH1cclxuXHRcdFxyXG5cdFx0aWYgKCFub3RlKSB7XHJcblx0XHRcdG5vdGUgPSBhd2FpdCBwZXJpb2RpY05vdGVzUGx1Z2luLmNyZWF0ZVBlcmlvZGljTm90ZT8uKGluZm8ubm91biBhcyAnZGF5JyB8ICd3ZWVrJyB8ICdtb250aCcgfCAneWVhcicsIGRhdGUpID8/IG51bGw7XHJcblx0XHR9XHJcblx0fVxyXG5cdFxyXG5cdHJldHVybiBub3RlID8gdHJpbUZpbGUobm90ZSkgOiBudWxsO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0IGpvdXJuYWwgbm90ZSBwYXRoXHJcbiAqL1xyXG5hc3luYyBmdW5jdGlvbiBnZXRKb3VybmFsTm90ZShqb3VybmFsTmFtZTogc3RyaW5nLCBwbHVnaW46IEhvbWVCYXNlUGx1Z2luKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XHJcblx0Y29uc3QgY29tbXVuaXR5UGx1Z2lucyA9IHBsdWdpbi5hcHAucGx1Z2lucz8ucGx1Z2lucyB8fCB7fTtcclxuXHRjb25zdCBqb3VybmFscyA9IGNvbW11bml0eVBsdWdpbnNbJ2pvdXJuYWxzJ107XHJcblx0aWYgKCFqb3VybmFscykgcmV0dXJuIG51bGw7XHJcblx0XHJcblx0dHJ5IHtcclxuXHRcdGNvbnN0IGpvdXJuYWwgPSBqb3VybmFscy5nZXRKb3VybmFsPy4oam91cm5hbE5hbWUpO1xyXG5cdFx0aWYgKCFqb3VybmFsKSByZXR1cm4gbnVsbDtcclxuXHRcdFxyXG5cdFx0Y29uc3Qgb3JpZ0F1dG9DcmVhdGUgPSBqb3VybmFsLmNvbmZpZz8udmFsdWU/LmF1dG9DcmVhdGU7XHJcblx0XHRcclxuXHRcdC8vIFRyaWdnZXIgYXV0by1jcmVhdGUgKGhhY2t5IGxvZ2ljIGZyb20gaG9tZXBhZ2UgcGx1Z2luKVxyXG5cdFx0am91cm5hbHMucmVwcm9jZXNzTm90ZXM/LigpO1xyXG5cdFx0aWYgKGpvdXJuYWwuY29uZmlnPy52YWx1ZSkge1xyXG5cdFx0XHRqb3VybmFsLmNvbmZpZy52YWx1ZS5hdXRvQ3JlYXRlID0gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdFxyXG5cdFx0YXdhaXQgam91cm5hbC5hdXRvQ3JlYXRlPy4oKTtcclxuXHRcdFxyXG5cdFx0aWYgKGpvdXJuYWwuY29uZmlnPy52YWx1ZSkge1xyXG5cdFx0XHRqb3VybmFsLmNvbmZpZy52YWx1ZS5hdXRvQ3JlYXRlID0gb3JpZ0F1dG9DcmVhdGU7XHJcblx0XHR9XHJcblx0XHRcclxuXHRcdGNvbnN0IHRvZGF5ID0gbW9tZW50KCkubG9jYWxlKCdjdXN0b20tam91cm5hbC1sb2NhbGUnKS5zdGFydE9mKCdkYXknKTtcclxuXHRcdFxyXG5cdFx0Ly8gSWYgbm90ZSBkb2Vzbid0IGV4aXN0IGFuZCB3YWl0IGZvciBnaXQgc3luYyBpcyBlbmFibGVkLCB3YWl0XHJcblx0XHRsZXQgbm90ZSA9IGpvdXJuYWwuZ2V0Py4odG9kYXkpO1xyXG5cdFx0aWYgKCFub3RlICYmIHBsdWdpbi5zZXR0aW5ncy53YWl0Rm9yR2l0U3luYykge1xyXG5cdFx0XHRuZXcgTm90aWNlKGBIb21lIEJhc2U6IFdhaXRpbmcgZm9yIGdpdCBzeW5jICgke3BsdWdpbi5zZXR0aW5ncy5naXRTeW5jVGltZW91dH1zKS4uLmAsIDUwMDApO1xyXG5cdFx0XHRhd2FpdCBkZWxheShwbHVnaW4uc2V0dGluZ3MuZ2l0U3luY1RpbWVvdXQgKiAxMDAwKTtcclxuXHRcdFx0am91cm5hbHMucmVwcm9jZXNzTm90ZXM/LigpO1xyXG5cdFx0XHRub3RlID0gam91cm5hbC5nZXQ/Lih0b2RheSk7XHJcblx0XHR9XHJcblx0XHRcclxuXHRcdGlmICghbm90ZSkgcmV0dXJuIG51bGw7XHJcblx0XHRcclxuXHRcdGNvbnN0IHBhdGggPSBqb3VybmFsLmdldE5vdGVQYXRoPy4obm90ZSk7XHJcblx0XHRyZXR1cm4gcGF0aCA/IHBhdGgucmVwbGFjZSgvXFwubWQkLywgJycpIDogbnVsbDtcclxuXHR9IGNhdGNoIHtcclxuXHRcdHJldHVybiBudWxsO1xyXG5cdH1cclxufVxyXG5cclxuLyoqXHJcbiAqIENvbXB1dGUgdGhlIGFjdHVhbCBmaWxlIHBhdGggYmFzZWQgb24gaG9tZSBiYXNlIHR5cGUgc3luY2hyb25vdXNseVxyXG4gKiBVc2VkIGZvciBjb21wYXJpc29uIGFuZCBVSSB1cGRhdGVzIHdoZXJlIGFzeW5jIGlzIG5vdCBwb3NzaWJsZVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVQYXRoU3luYyhcclxuXHR0eXBlOiBIb21lQmFzZVR5cGUsXHJcblx0dmFsdWU6IHN0cmluZyxcclxuXHRhcHA6IEFwcFxyXG4pOiBzdHJpbmcgfCBudWxsIHtcclxuXHRzd2l0Y2ggKHR5cGUpIHtcclxuXHRcdGNhc2UgSG9tZUJhc2VUeXBlLkZpbGU6XHJcblx0XHRcdHJldHVybiB2YWx1ZSB8fCBudWxsO1xyXG5cdFx0XHJcblx0XHRjYXNlIEhvbWVCYXNlVHlwZS5EYWlseU5vdGU6XHJcblx0XHRjYXNlIEhvbWVCYXNlVHlwZS5XZWVrbHlOb3RlOlxyXG5cdFx0Y2FzZSBIb21lQmFzZVR5cGUuTW9udGhseU5vdGU6XHJcblx0XHRjYXNlIEhvbWVCYXNlVHlwZS5RdWFydGVybHlOb3RlOlxyXG5cdFx0Y2FzZSBIb21lQmFzZVR5cGUuWWVhcmx5Tm90ZToge1xyXG5cdFx0XHRjb25zdCBpbmZvID0gUEVSSU9ESUNfSU5GT1t0eXBlXTtcclxuXHRcdFx0aWYgKGluZm8pIHtcclxuXHRcdFx0XHRjb25zdCBkYXRlID0gbW9tZW50KCkuc3RhcnRPZihpbmZvLm5vdW4gYXMgbW9tZW50LnVuaXRPZlRpbWUuU3RhcnRPZik7XHJcblx0XHRcdFx0Y29uc3QgYWxsID0gaW5mby5nZXRBbGwoKTtcclxuXHRcdFx0XHRjb25zdCBub3RlID0gaW5mby5nZXQoZGF0ZSwgYWxsKTtcclxuXHRcdFx0XHRyZXR1cm4gbm90ZSA/IHRyaW1GaWxlKG5vdGUpIDogbnVsbDtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gbnVsbDtcclxuXHRcdH1cclxuXHJcblx0XHRkZWZhdWx0OlxyXG5cdFx0XHQvLyBGb3IgUmFuZG9tLCBKb3VybmFsLCBOZXdOb3RlLCBldGMuLCB3ZSBjYW4ndCByZWxpYWJseSByZXNvbHZlIHN5bmNocm9ub3VzbHlcclxuXHRcdFx0Ly8gYnV0IHdlIG1pZ2h0IHJldHVybiB0aGUgdmFsdWUgaWYgaXQncyBhIHBhdGhcclxuXHRcdFx0cmV0dXJuICh0eXBlID09PSBIb21lQmFzZVR5cGUuUmFuZG9tRm9sZGVyIHx8IHR5cGUgPT09IEhvbWVCYXNlVHlwZS5OZXdOb3RlKSA/IG51bGwgOiAodmFsdWUgfHwgbnVsbCk7XHJcblx0fVxyXG59XHJcblxyXG4vKipcclxuICogQ29tcHV0ZSB0aGUgYWN0dWFsIGZpbGUgcGF0aCBiYXNlZCBvbiBob21lIGJhc2UgdHlwZVxyXG4gKi9cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbXB1dGVIb21lQmFzZVBhdGgoXHJcblx0dHlwZTogSG9tZUJhc2VUeXBlLFxyXG5cdHZhbHVlOiBzdHJpbmcsXHJcblx0cGx1Z2luOiBIb21lQmFzZVBsdWdpblxyXG4pOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcclxuXHRzd2l0Y2ggKHR5cGUpIHtcclxuXHRcdGNhc2UgSG9tZUJhc2VUeXBlLkZpbGU6XHJcblx0XHRcdHJldHVybiB2YWx1ZSB8fCBudWxsO1xyXG5cdFx0XHJcblx0XHRjYXNlIEhvbWVCYXNlVHlwZS5SYW5kb206IHtcclxuXHRcdFx0Y29uc3QgZmlsZSA9IHJhbmRvbUZpbGUocGx1Z2luLmFwcCk7XHJcblx0XHRcdHJldHVybiBmaWxlID8gdHJpbUZpbGUoZmlsZSkgOiBudWxsO1xyXG5cdFx0fVxyXG5cdFx0XHJcblx0XHRjYXNlIEhvbWVCYXNlVHlwZS5SYW5kb21Gb2xkZXI6IHtcclxuXHRcdFx0Y29uc3QgZmlsZSA9IHJhbmRvbUZpbGUocGx1Z2luLmFwcCwgdmFsdWUpO1xyXG5cdFx0XHRyZXR1cm4gZmlsZSA/IHRyaW1GaWxlKGZpbGUpIDogbnVsbDtcclxuXHRcdH1cclxuXHRcdFxyXG5cdFx0Y2FzZSBIb21lQmFzZVR5cGUuRGFpbHlOb3RlOlxyXG5cdFx0Y2FzZSBIb21lQmFzZVR5cGUuV2Vla2x5Tm90ZTpcclxuXHRcdGNhc2UgSG9tZUJhc2VUeXBlLk1vbnRobHlOb3RlOlxyXG5cdFx0Y2FzZSBIb21lQmFzZVR5cGUuUXVhcnRlcmx5Tm90ZTpcclxuXHRcdGNhc2UgSG9tZUJhc2VUeXBlLlllYXJseU5vdGU6XHJcblx0XHRcdHJldHVybiBhd2FpdCBnZXRQZXJpb2RpY05vdGUodHlwZSwgcGx1Z2luKTtcclxuXHRcdFxyXG5cdFx0Y2FzZSBIb21lQmFzZVR5cGUuSm91cm5hbDpcclxuXHRcdFx0cmV0dXJuIGF3YWl0IGdldEpvdXJuYWxOb3RlKHZhbHVlLCBwbHVnaW4pO1xyXG5cdFx0XHJcblx0XHRjYXNlIEhvbWVCYXNlVHlwZS5OZXdOb3RlOiB7XHJcblx0XHRcdGNvbnN0IGZpbGVNYW5hZ2VyID0gcGx1Z2luLmFwcC5maWxlTWFuYWdlcjtcclxuXHRcdFx0aWYgKGZpbGVNYW5hZ2VyLmNyZWF0ZU5ld0ZpbGUpIHtcclxuXHRcdFx0XHRjb25zdCBmaWxlID0gYXdhaXQgZmlsZU1hbmFnZXIuY3JlYXRlTmV3RmlsZShwbHVnaW4uYXBwLnZhdWx0LmdldFJvb3QoKSwgdmFsdWUgfHwgJ1VudGl0bGVkJyk7XHJcblx0XHRcdFx0cmV0dXJuIGZpbGUgPyB0cmltRmlsZShmaWxlKSA6IG51bGw7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIG51bGw7XHJcblx0XHR9XHJcblx0XHRcclxuXHRcdGNhc2UgSG9tZUJhc2VUeXBlLldvcmtzcGFjZTpcclxuXHRcdGNhc2UgSG9tZUJhc2VUeXBlLkdyYXBoOlxyXG5cdFx0Y2FzZSBIb21lQmFzZVR5cGUuTm9uZTpcclxuXHRcdFx0Ly8gVGhlc2UgZG9uJ3QgcmVzb2x2ZSB0byBhIGZpbGUgcGF0aFxyXG5cdFx0XHRyZXR1cm4gbnVsbDtcclxuXHRcdFxyXG5cdFx0ZGVmYXVsdDpcclxuXHRcdFx0cmV0dXJuIHZhbHVlIHx8IG51bGw7XHJcblx0fVxyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2sgaWYgYSBob21lIGJhc2UgdHlwZSByZXF1aXJlcyBhIGZpbGUgdG8gYmUgb3BlbmVkXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZXNGaWxlKHR5cGU6IEhvbWVCYXNlVHlwZSk6IGJvb2xlYW4ge1xyXG5cdHJldHVybiB0eXBlICE9PSBIb21lQmFzZVR5cGUuV29ya3NwYWNlICYmIFxyXG5cdCAgICAgICB0eXBlICE9PSBIb21lQmFzZVR5cGUuR3JhcGggJiYgXHJcblx0ICAgICAgIHR5cGUgIT09IEhvbWVCYXNlVHlwZS5Ob25lO1xyXG59XHJcblxyXG4vKipcclxuICogSGVscGVyIHRvIHdhaXQgZm9yIGEgc3BlY2lmaWVkIGR1cmF0aW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBkZWxheShtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XHJcblx0cmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xyXG59XHJcblxyXG4iLCAiLyoqXHJcbiAqIE5ldyBUYWIgU2VydmljZVxyXG4gKiBIYW5kbGVzIHN0YXJ0dXAgZGV0ZWN0aW9uIGFuZCBuZXcgdGFiIHJlcGxhY2VtZW50XHJcbiAqIEluc3BpcmVkIGJ5IG9ic2lkaWFuLWhvbWVwYWdlIGFuZCBuZXctdGFiLWRlZmF1bHQtcGFnZVxyXG4gKi9cclxuXHJcbmltcG9ydCB7IEFwcCwgV29ya3NwYWNlTGVhZiwgVmlldywgVEZpbGUgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB0eXBlIEhvbWVCYXNlUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5pbXBvcnQgeyBIb21lQmFzZVR5cGUgfSBmcm9tICcuLi9zZXR0aW5ncyc7XHJcblxyXG4vKipcclxuICogVGltaW5nIGNvbnN0YW50cyBmb3IgbmV3IHRhYiBvcGVyYXRpb25zXHJcbiAqIFRoZXNlIGRlbGF5cyBhcmUgbmVjZXNzYXJ5IGZvciBPYnNpZGlhbiB0byBmaW5pc2ggaW50ZXJuYWwgb3BlcmF0aW9uc1xyXG4gKiBiZWZvcmUgSG9tZSBCYXNlIHByb2Nlc3NlcyB0aGUgbmV3IHRhYi5cclxuICovXHJcblxyXG4vKiogRGVsYXkgZm9yIE9ic2lkaWFuIHRvIHJlc3RvcmUgd29ya3NwYWNlIG9uIHN0YXJ0dXAgYmVmb3JlIEhvbWUgQmFzZSBydW5zICovXHJcbmNvbnN0IFNUQVJUVVBfUkVTVE9SRV9ERUxBWSA9IDUwMDtcclxuXHJcbi8qKiBEZWxheSBhZnRlciBjbG9zaW5nIGFsbCBsZWF2ZXMgdG8gbGV0IGRldGFjaG1lbnRzIHNldHRsZSAqL1xyXG5jb25zdCBERVRBQ0hfU0VUVExFX0RFTEFZID0gMjAwO1xyXG5cclxuLyoqIFNtYWxsIHNhZmV0eSBkZWxheSB0byBoYW5kbGUgcmFjZSBjb25kaXRpb25zIHdpdGggb3RoZXIgcGx1Z2lucyAqL1xyXG5jb25zdCBQTFVHSU5fUkFDRV9ERUxBWSA9IDUwO1xyXG5cclxuZXhwb3J0IGNsYXNzIE5ld1RhYlNlcnZpY2Uge1xyXG5cdHByaXZhdGUgYXBwOiBBcHA7XHJcblx0cHJpdmF0ZSBwbHVnaW46IEhvbWVCYXNlUGx1Z2luO1xyXG5cdHByaXZhdGUgZXhpc3RpbmdMZWF2ZXM6IFdlYWtTZXQ8V29ya3NwYWNlTGVhZj4gPSBuZXcgV2Vha1NldCgpO1xyXG5cdHByaXZhdGUgaXNTdGFydHVwOiBib29sZWFuID0gdHJ1ZTtcclxuXHRwcml2YXRlIHN0YXJ0dXBDb21wbGV0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcblx0Y29uc3RydWN0b3IocGx1Z2luOiBIb21lQmFzZVBsdWdpbikge1xyXG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XHJcblx0XHR0aGlzLmFwcCA9IHBsdWdpbi5hcHA7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBUcmFjayBhbGwgZXhpc3RpbmcgbGVhdmVzIChmb3IgbmV3IHRhYiBkZXRlY3Rpb24pXHJcblx0ICogVGhpcyBtdXN0IGJlIGNhbGxlZCBldmVuIHdoZW4gc3RhcnR1cCBpcyBoYW5kbGVkIGVsc2V3aGVyZVxyXG5cdCAqL1xyXG5cdHRyYWNrRXhpc3RpbmdMZWF2ZXMoKTogdm9pZCB7XHJcblx0XHR0aGlzLmFwcC53b3Jrc3BhY2UuaXRlcmF0ZUFsbExlYXZlcygobGVhZikgPT4ge1xyXG5cdFx0XHR0aGlzLmV4aXN0aW5nTGVhdmVzLmFkZChsZWFmKTtcclxuXHRcdH0pO1xyXG5cdFx0Ly8gTWFyayBzdGFydHVwIGFzIGNvbXBsZXRlZCBzbyBsYXlvdXQgY2hhbmdlIGhhbmRsZXIgd29ya3NcclxuXHRcdHRoaXMuc3RhcnR1cENvbXBsZXRlZCA9IHRydWU7XHJcblx0XHR0aGlzLmlzU3RhcnR1cCA9IGZhbHNlO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogSW5pdGlhbGl6ZSB0aGUgc2VydmljZSAtIGNhbGxlZCB3aGVuIGxheW91dCBpcyByZWFkeVxyXG5cdCAqL1xyXG5cdGluaXRpYWxpemUoKTogdm9pZCB7XHJcblx0XHQvLyBUcmFjayBhbGwgZXhpc3RpbmcgbGVhdmVzXHJcblx0XHR0aGlzLnRyYWNrRXhpc3RpbmdMZWF2ZXMoKTtcclxuXHJcblx0XHQvLyBIYW5kbGUgc3RhcnR1cFxyXG5cdFx0dm9pZCB0aGlzLmhhbmRsZVN0YXJ0dXAoKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEhhbmRsZSBhcHAgc3RhcnR1cCAtIG9wZW4gaG9tZSBiYXNlIGlmIG5lZWRlZFxyXG5cdCAqIE9ubHkgY2FsbGVkIG9uIGFjdHVhbCBhcHAgc3RhcnR1cCwgbm90IHBsdWdpbiByZWxvYWRzXHJcblx0ICovXHJcblx0cHJpdmF0ZSBhc3luYyBoYW5kbGVTdGFydHVwKCk6IFByb21pc2U8dm9pZD4ge1xyXG5cdFx0Y29uc3Qgc2V0dGluZ3MgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncztcclxuXHJcblx0XHQvLyBDaGVjayBpZiB3ZSBzaG91bGQgc2tpcCAob3Blbk9uU3RhcnR1cCBpcyBmYWxzZSwgb3Igbm8gaG9tZSBiYXNlIGNvbmZpZ3VyZWQpXHJcblx0XHRjb25zdCBob21lQmFzZVNldHRpbmdzID0gdGhpcy5wbHVnaW4uZ2V0SG9tZUJhc2VTZXR0aW5ncygpO1xyXG5cdFx0aWYgKCFzZXR0aW5ncy5vcGVuT25TdGFydHVwIHx8ICghaG9tZUJhc2VTZXR0aW5ncy52YWx1ZSAmJiBob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5GaWxlKSkge1xyXG5cdFx0XHR0aGlzLnN0YXJ0dXBDb21wbGV0ZWQgPSB0cnVlO1xyXG5cdFx0XHR0aGlzLmlzU3RhcnR1cCA9IGZhbHNlO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ2hlY2sgZm9yIFVSTCBwYXJhbXMgKGxpa2Ugb2JzaWRpYW46Ly9vcGVuIGxpbmtzKSAtIGlmIHByZXNlbnQsIHNraXAgZXZlcnl0aGluZ1xyXG5cdFx0aWYgKGF3YWl0IHRoaXMuaGFzVXJsUGFyYW1zKCkpIHtcclxuXHRcdFx0dGhpcy5zdGFydHVwQ29tcGxldGVkID0gdHJ1ZTtcclxuXHRcdFx0dGhpcy5pc1N0YXJ0dXAgPSBmYWxzZTtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFdhaXQgYSBiaXQgZm9yIE9ic2lkaWFuIHRvIGZpbmlzaCByZXN0b3JpbmcgdGhlIHdvcmtzcGFjZVxyXG5cdFx0Ly8gVGhpcyBlbnN1cmVzIGFsbCB0YWJzIGFyZSBsb2FkZWQgYmVmb3JlIHdlIHRyeSB0byBjbG9zZSB0aGVtXHJcblx0XHQvLyBOZWVkIGxvbmdlciBkZWxheSB0byBlbnN1cmUgd29ya3NwYWNlIGlzIGZ1bGx5IHJlc3RvcmVkXHJcblx0XHRhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgU1RBUlRVUF9SRVNUT1JFX0RFTEFZKSk7XHJcblxyXG5cdFx0Ly8gSWYgb3Blbk1vZGUgaXMgcmVwbGFjZS1hbGwsIGNsb3NlIEFMTCB0YWJzIGZpcnN0LCB0aGVuIG9wZW4gaG9tZSBiYXNlXHJcblx0XHQvLyBUaGlzIHNob3VsZCBPTkxZIGhhcHBlbiBvbiBzdGFydHVwLCBub3Qgd2hlbiBtYW51YWxseSBvcGVuaW5nXHJcblx0XHQvLyBXZSBjbG9zZSBldmVyeXRoaW5nIGZpcnN0LCB0aGVuIG9wZW4gZnJlc2ggLSBkb24ndCB0cnkgdG8gZmluZCB0YWJzIHRvIGtlZXBcclxuXHRcdC8vIEV4Y2VwdGlvbjogSWYgaGlkZVJlbGVhc2VOb3RlcyBpcyBPRkYsIHByZXNlcnZlIHJlbGVhc2Ugbm90ZXMgdGFiXHJcblx0XHRpZiAoc2V0dGluZ3Mub3Blbk1vZGUgPT09ICdyZXBsYWNlLWFsbCcpIHtcclxuXHRcdFx0Ly8gSWYgaGlkZVJlbGVhc2VOb3RlcyBpcyBPRkYsIHdlIHNob3VsZCBwcmVzZXJ2ZSByZWxlYXNlIG5vdGVzIHRhYlxyXG5cdFx0XHRsZXQgZXhjZXB0TGVhZjogV29ya3NwYWNlTGVhZiB8IG51bGwgPSBudWxsO1xyXG5cdFx0XHRpZiAoIXNldHRpbmdzLmhpZGVSZWxlYXNlTm90ZXMpIHtcclxuXHRcdFx0XHQvLyBUcnkgdG8gZmluZCByZWxlYXNlIG5vdGVzIHRhYlxyXG5cdFx0XHRcdGNvbnN0IGFsbExlYXZlcyA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUoJ21hcmtkb3duJyk7XHJcblx0XHRcdFx0Zm9yIChjb25zdCBsZWFmIG9mIGFsbExlYXZlcykge1xyXG5cdFx0XHRcdFx0Y29uc3QgdmlldyA9IGxlYWYudmlldztcclxuXHJcblx0XHRcdFx0XHRjb25zdCBtYXJrZG93blZpZXcgPSB2aWV3IGFzIHVua25vd24gYXMgeyBmaWxlPzogVEZpbGU7IGNvbnRhaW5lckVsPzogSFRNTEVsZW1lbnQgfTtcclxuXHRcdFx0XHRcdGlmIChtYXJrZG93blZpZXcuZmlsZSkge1xyXG5cdFx0XHRcdFx0XHRjb25zdCBmaWxlID0gbWFya2Rvd25WaWV3LmZpbGU7XHJcblx0XHRcdFx0XHRcdC8vIFJlbGVhc2Ugbm90ZXMgYXJlIHR5cGljYWxseSBpbiBjb25maWcgZm9sZGVyIG9yIGhhdmUgc3BlY2lmaWMgbmFtaW5nXHJcblx0XHRcdFx0XHRcdC8vIENoZWNrIGlmIGl0J3MgYSByZWxlYXNlIG5vdGVzIHRhYiBieSBsb29raW5nIGF0IHRoZSBmaWxlIHBhdGhcclxuXHRcdFx0XHRcdFx0Y29uc3QgY29uZmlnRGlyID0gdGhpcy5hcHAudmF1bHQuY29uZmlnRGlyO1xyXG5cdFx0XHRcdFx0XHRpZiAoZmlsZS5wYXRoLmluY2x1ZGVzKCdyZWxlYXNlJykgfHwgZmlsZS5wYXRoLmluY2x1ZGVzKGNvbmZpZ0RpcikpIHtcclxuXHRcdFx0XHRcdFx0XHQvLyBDaGVjayBpZiBpdCdzIGFjdHVhbGx5IGEgcmVsZWFzZSBub3RlcyB2aWV3XHJcblx0XHRcdFx0XHRcdFx0Y29uc3QgY29udGFpbmVyID0gbWFya2Rvd25WaWV3LmNvbnRhaW5lckVsO1xyXG5cdFx0XHRcdFx0XHRcdGlmIChjb250YWluZXIgJiYgY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy5yZWxlYXNlLW5vdGVzJykpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGV4Y2VwdExlYWYgPSBsZWFmO1xyXG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBDbG9zZSBBTEwgdGFicyAtIGRvbid0IHRyeSB0byBrZWVwIGFueSwganVzdCBjbG9zZSBldmVyeXRoaW5nIChleGNlcHQgcmVsZWFzZSBub3RlcyBpZiBhcHBsaWNhYmxlKVxyXG5cdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5ob21lU2VydmljZS5jbG9zZUFsbExlYXZlc0V4Y2VwdChleGNlcHRMZWFmKTtcclxuXHRcdFx0Ly8gV2FpdCBsb25nZXIgdG8gZW5zdXJlIGFsbCBkZXRhY2htZW50cyBhcmUgcHJvY2Vzc2VkXHJcblx0XHRcdGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBERVRBQ0hfU0VUVExFX0RFTEFZKSk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gT24gc3RhcnR1cCwgdXNlIGdob3N0IHRhYiBpZiBzdGlja3kgaWNvbiBpcyBlbmFibGVkLCBvdGhlcndpc2UgdXNlIG5vcm1hbCBvcGVuSG9tZUJhc2VcclxuXHRcdGlmIChzZXR0aW5ncy5zaG93U3RpY2t5SG9tZUljb24pIHtcclxuXHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uaG9tZVNlcnZpY2Uub3BlbkhvbWVCYXNlSW5HaG9zdFRhYih7XHJcblx0XHRcdFx0cnVuQ29tbWFuZDogdHJ1ZSxcclxuXHRcdFx0fSk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHQvLyBBbHdheXMgY2FsbCBvcGVuSG9tZUJhc2UgLSBpdCB3aWxsIG9wZW4gaG9tZSBiYXNlIGlmIG5vdCBhbHJlYWR5IG9wZW5cclxuXHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uaG9tZVNlcnZpY2Uub3BlbkhvbWVCYXNlKHtcclxuXHRcdFx0XHRyZXBsYWNlQWN0aXZlTGVhZjogZmFsc2UsXHJcblx0XHRcdFx0cnVuQ29tbWFuZDogdHJ1ZSxcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0dGhpcy5zdGFydHVwQ29tcGxldGVkID0gdHJ1ZTtcclxuXHRcdHRoaXMuaXNTdGFydHVwID0gZmFsc2U7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBDaGVjayBpZiB0aGUgc2V0dGluZ3MgbW9kYWwgaXMgY3VycmVudGx5IG9wZW5cclxuXHQgKi9cclxuXHRwcml2YXRlIGlzU2V0dGluZ3NNb2RhbE9wZW4oKTogYm9vbGVhbiB7XHJcblx0XHQvLyBDaGVjayBmb3Igc2V0dGluZ3MgbW9kYWwgYnkgbG9va2luZyBmb3IgdGhlIG1vZGFsIGNvbnRhaW5lclxyXG5cdFx0Ly8gVHJ5IG11bHRpcGxlIHNlbGVjdG9ycyB0byBiZSBtb3JlIHJvYnVzdFxyXG5cdFx0Y29uc3Qgc2V0dGluZ3NNb2RhbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tb2RhbC1jb250YWluZXIubW9kLXNldHRpbmdzJykgfHxcclxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vZGFsLm1vZC1zZXR0aW5ncycpIHx8XHJcblx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy52ZXJ0aWNhbC10YWItY29udGVudCcpO1xyXG5cclxuXHRcdC8vIEFsc28gY2hlY2sgaWYgYW55IG1vZGFsIGlzIG9wZW4gYW5kIGNvbnRhaW5zIHNldHRpbmdzIGNvbnRlbnRcclxuXHRcdGlmICghc2V0dGluZ3NNb2RhbCkge1xyXG5cdFx0XHRjb25zdCBhbGxNb2RhbHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcubW9kYWwtY29udGFpbmVyJyk7XHJcblx0XHRcdGZvciAoY29uc3QgbW9kYWwgb2YgQXJyYXkuZnJvbShhbGxNb2RhbHMpKSB7XHJcblx0XHRcdFx0aWYgKG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJy52ZXJ0aWNhbC10YWItY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRtb2RhbC5xdWVyeVNlbGVjdG9yKCcuc2V0dGluZ3MtY29udGVudCcpIHx8XHJcblx0XHRcdFx0XHRtb2RhbC5jbGFzc0xpc3QuY29udGFpbnMoJ21vZC1zZXR0aW5ncycpKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gc2V0dGluZ3NNb2RhbCAhPT0gbnVsbDtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENoZWNrIGZvciBVUkwgcGFyYW1ldGVycyB0aGF0IGluZGljYXRlIE9ic2lkaWFuIHdhcyBvcGVuZWQgdmlhIGEgbGlua1xyXG5cdCAqIEJhc2VkIG9uIG9ic2lkaWFuLWhvbWVwYWdlIGltcGxlbWVudGF0aW9uXHJcblx0ICovXHJcblx0cHJpdmF0ZSBhc3luYyBoYXNVcmxQYXJhbXMoKTogUHJvbWlzZTxib29sZWFuPiB7XHJcblx0XHQvLyBDaGVjayBmb3IgbW9iaWxlIFVSTCBwYXJhbXMgKENhcGFjaXRvciBBUEkpXHJcblx0XHRjb25zdCB3aW5kb3dBbnkgPSB3aW5kb3cgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcclxuXHJcblx0XHRjb25zdCBjYXBhY2l0b3IgPSB3aW5kb3dBbnkuQ2FwYWNpdG9yIGFzIHsgUGx1Z2lucz86IHsgQXBwPzogeyBnZXRMYXVuY2hVcmw6ICgpID0+IFByb21pc2U8eyB1cmw/OiBzdHJpbmcgfSB8IG51bGw+IH0gfSB9IHwgdW5kZWZpbmVkO1xyXG5cdFx0aWYgKGNhcGFjaXRvcj8uUGx1Z2lucz8uQXBwKSB7XHJcblx0XHRcdHRyeSB7XHJcblx0XHRcdFx0Y29uc3QgbGF1bmNoVXJsID0gYXdhaXQgY2FwYWNpdG9yLlBsdWdpbnMuQXBwLmdldExhdW5jaFVybCgpO1xyXG5cdFx0XHRcdGlmIChsYXVuY2hVcmw/LnVybCkge1xyXG5cdFx0XHRcdFx0Y29uc3QgdXJsID0gbmV3IFVSTChsYXVuY2hVcmwudXJsKTtcclxuXHRcdFx0XHRcdGNvbnN0IHBhcmFtcyA9IEFycmF5LmZyb20odXJsLnNlYXJjaFBhcmFtcy5rZXlzKCkpO1xyXG5cdFx0XHRcdFx0Y29uc3QgYWN0aW9uID0gdXJsLmhvc3RuYW1lO1xyXG5cclxuXHRcdFx0XHRcdGlmIChbJ29wZW4nLCAnYWR2YW5jZWQtdXJpJ10uaW5jbHVkZXMoYWN0aW9uKSAmJlxyXG5cdFx0XHRcdFx0XHRbJ2ZpbGUnLCAnZmlsZXBhdGgnLCAnd29ya3NwYWNlJ10uc29tZShlID0+IHBhcmFtcy5pbmNsdWRlcyhlKSkpIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9IGNhdGNoIHtcclxuXHRcdFx0XHQvLyBJZ25vcmUgZXJyb3JzXHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBDaGVjayBmb3IgZGVza3RvcCBVUkwgcGFyYW1zXHJcblx0XHRjb25zdCBvYnNBY3QgPSB3aW5kb3dBbnkuT0JTX0FDVCBhcyB7IGFjdGlvbj86IHN0cmluZyB9IHwgdW5kZWZpbmVkO1xyXG5cdFx0aWYgKG9ic0FjdCkge1xyXG5cdFx0XHRjb25zdCBwYXJhbXMgPSBPYmplY3Qua2V5cyhvYnNBY3QpO1xyXG5cdFx0XHRjb25zdCBhY3Rpb24gPSBvYnNBY3QuYWN0aW9uO1xyXG5cclxuXHRcdFx0aWYgKGFjdGlvbiAmJiBbJ29wZW4nLCAnYWR2YW5jZWQtdXJpJ10uaW5jbHVkZXMoYWN0aW9uKSAmJlxyXG5cdFx0XHRcdFsnZmlsZScsICdmaWxlcGF0aCcsICd3b3Jrc3BhY2UnXS5zb21lKGUgPT4gcGFyYW1zLmluY2x1ZGVzKGUpKSkge1xyXG5cdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogSGFuZGxlIGxheW91dCBjaGFuZ2UgZXZlbnQgLSBjaGVjayBmb3IgbmV3IGVtcHR5IHRhYnNcclxuXHQgKiBCYXNlZCBvbiBuZXctdGFiLWRlZmF1bHQtcGFnZSBpbXBsZW1lbnRhdGlvblxyXG5cdCAqL1xyXG5cdGhhbmRsZUxheW91dENoYW5nZSgpOiB2b2lkIHtcclxuXHRcdC8vIFNraXAgZHVyaW5nIHN0YXJ0dXBcclxuXHRcdGlmICh0aGlzLmlzU3RhcnR1cCB8fCAhdGhpcy5zdGFydHVwQ29tcGxldGVkKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDaGVjayBhbGwgbGVhdmVzIGZvciBuZXcgZW1wdHkgb25lc1xyXG5cdFx0dGhpcy5hcHAud29ya3NwYWNlLml0ZXJhdGVBbGxMZWF2ZXMoKGxlYWYpID0+IHtcclxuXHRcdFx0Ly8gU2tpcCBpZiB3ZSd2ZSBhbHJlYWR5IHNlZW4gdGhpcyBsZWFmXHJcblx0XHRcdGlmICh0aGlzLmV4aXN0aW5nTGVhdmVzLmhhcyhsZWFmKSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gTWFyayBhcyBzZWVuIEJFRk9SRSBjaGVja2luZyBpZiBpdCdzIGVtcHR5XHJcblx0XHRcdC8vIFRoaXMgcHJldmVudHMgcHJvY2Vzc2luZyB0aGUgc2FtZSBsZWFmIG11bHRpcGxlIHRpbWVzXHJcblx0XHRcdHRoaXMuZXhpc3RpbmdMZWF2ZXMuYWRkKGxlYWYpO1xyXG5cclxuXHRcdFx0Ly8gQ2hlY2sgaWYgdGhpcyBpcyBhbiBlbXB0eSB0YWJcclxuXHRcdFx0aWYgKCF0aGlzLmlzRW1wdHlUYWIobGVhZikpIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIENoZWNrIGlmIHRoaXMgaXMgdGhlIG9ubHkgdGFiIChhbGwgdGFicyB3ZXJlIGNsb3NlZClcclxuXHRcdFx0Y29uc3QgaXNPbmx5VGFiID0gdGhpcy5pc09ubHlUYWIobGVhZik7XHJcblxyXG5cdFx0XHQvLyBIYW5kbGUgXCJPcGVuIHdoZW4gYWxsIHRhYnMgYXJlIGNsb3NlZFwiIC0gd29ya3MgaW5kZXBlbmRlbnRseSBvZiByZXBsYWNlTmV3VGFiXHJcblx0XHRcdGlmIChpc09ubHlUYWIgJiYgdGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbldoZW5BbGxUYWJzQ2xvc2VkID09PSB0cnVlKSB7XHJcblx0XHRcdFx0Ly8gT3BlbiBob21lIGJhc2Ugd2hlbiBhbGwgdGFicyBhcmUgY2xvc2VkXHJcblx0XHRcdFx0dm9pZCB0aGlzLnJlcGxhY2VFbXB0eVRhYihsZWFmLCB0cnVlKTsgLy8gUGFzcyB0cnVlIHRvIGluZGljYXRlIHRoaXMgaXMgZm9yIFwiYWxsIHRhYnMgY2xvc2VkXCJcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEhhbmRsZSBcIlJlcGxhY2UgbmV3IHRhYnNcIiAtIG9ubHkgaWYgZW5hYmxlZFxyXG5cdFx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MucmVwbGFjZU5ld1RhYiAhPT0gdHJ1ZSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gRG91YmxlLWNoZWNrIHJlcGxhY2VOZXdUYWIgaXMgc3RpbGwgdHJ1ZSAoaW4gY2FzZSBpdCBjaGFuZ2VkIGR1cmluZyBwcm9jZXNzaW5nKVxyXG5cdFx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MucmVwbGFjZU5ld1RhYiAhPT0gdHJ1ZSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gSGFuZGxlIGJhc2VkIG9uIG1vZGVcclxuXHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLm5ld1RhYk1vZGUgPT09ICdvbmx5LXdoZW4tZW1wdHknKSB7XHJcblx0XHRcdFx0Ly8gT25seSByZXBsYWNlIGlmIHRoaXMgaXMgdGhlIG9ubHkgdGFiXHJcblx0XHRcdFx0aWYgKCFpc09ubHlUYWIpIHtcclxuXHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFJlcGxhY2UgdGhlIGVtcHR5IHRhYiB3aXRoIGhvbWUgYmFzZSAoZm9yIG5ldyB0YWIgcmVwbGFjZW1lbnQpXHJcblx0XHRcdHZvaWQgdGhpcy5yZXBsYWNlRW1wdHlUYWIobGVhZiwgZmFsc2UpOyAvLyBQYXNzIGZhbHNlIHRvIGluZGljYXRlIHRoaXMgaXMgZm9yIFwibmV3IHRhYiByZXBsYWNlbWVudFwiXHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENoZWNrIGlmIGEgbGVhZiBpcyBhbiBlbXB0eSB0YWJcclxuXHQgKiBJTVBPUlRBTlQ6IE9ubHkgcmV0dXJucyB0cnVlIGlmIHRoZSBsZWFmIGlzIHRydWx5IGVtcHR5IChubyBmaWxlIG9wZW5lZClcclxuXHQgKiBJZiBhIGZpbGUgaXMgYWxyZWFkeSBvcGVuZWQgaW4gdGhlIGxlYWYsIGl0J3Mgbm90IGVtcHR5IGFuZCBzaG91bGQgTk9UIGJlIHJlcGxhY2VkXHJcblx0ICovXHJcblx0cHJpdmF0ZSBpc0VtcHR5VGFiKGxlYWY6IFdvcmtzcGFjZUxlYWYpOiBib29sZWFuIHtcclxuXHRcdGlmICghbGVhZi52aWV3KSByZXR1cm4gdHJ1ZTtcclxuXHJcblx0XHQvLyBDaGVjayBpZiB2aWV3IHR5cGUgaXMgZW1wdHlcclxuXHRcdGlmIChsZWFmLnZpZXcuZ2V0Vmlld1R5cGUoKSAhPT0gJ2VtcHR5Jykge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRG91YmxlLWNoZWNrOiBpZiB0aGUgdmlldyBoYXMgYSBzdGF0ZSB3aXRoIGEgZmlsZSwgaXQncyBub3QgZW1wdHlcclxuXHRcdC8vIFRoaXMgcHJldmVudHMgcmVwbGFjaW5nIHRhYnMgdGhhdCB3ZXJlIGp1c3Qgb3BlbmVkIHdpdGggZmlsZXMgZnJvbSBleHBsb3JlclxyXG5cdFx0Y29uc3Qgdmlld1N0YXRlID0gbGVhZi5nZXRWaWV3U3RhdGUoKTtcclxuXHRcdGlmICh2aWV3U3RhdGUgJiYgKHZpZXdTdGF0ZSBhcyB7IGZpbGU/OiBzdHJpbmcgfSkuZmlsZSkge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHRydWU7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBDaGVjayBpZiB0aGlzIGlzIHRoZSBvbmx5IHRhYiBpbiB0aGUgbWFpbiB3b3Jrc3BhY2VcclxuXHQgKiBPbmx5IGNvdW50cyByb290IGxlYXZlcyAobWFpbiB3b3Jrc3BhY2UgdGFicyksIG5vdCBzaWRlYmFyIHRhYnNcclxuXHQgKiBCYXNlZCBvbiBvYnNpZGlhbi1kaXNhYmxlLXRhYnMgcGF0dGVybiB1c2luZyBpdGVyYXRlUm9vdExlYXZlc1xyXG5cdCAqL1xyXG5cdHByaXZhdGUgaXNPbmx5VGFiKGxlYWY6IFdvcmtzcGFjZUxlYWYpOiBib29sZWFuIHtcclxuXHRcdGxldCB0YWJDb3VudCA9IDA7XHJcblx0XHR0aGlzLmFwcC53b3Jrc3BhY2UuaXRlcmF0ZVJvb3RMZWF2ZXMoKGwpID0+IHtcclxuXHRcdFx0dGFiQ291bnQrKztcclxuXHRcdH0pO1xyXG5cclxuXHRcdGNvbnN0IHJlc3VsdCA9IHRhYkNvdW50ID09PSAxO1xyXG5cdFx0Y29uc29sZS5kZWJ1ZygnW0hvbWUgQmFzZV0gaXNPbmx5VGFiOicsIHtcclxuXHRcdFx0bGVhZjogbGVhZixcclxuXHRcdFx0dGFiQ291bnQ6IHRhYkNvdW50LFxyXG5cdFx0XHRpc09ubHlUYWI6IHJlc3VsdFxyXG5cdFx0fSk7XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIFJlcGxhY2UgYW4gZW1wdHkgdGFiIHdpdGggdGhlIGhvbWUgYmFzZSBvciBuZXcgdGFiIGZpbGVcclxuXHQgKiBAcGFyYW0gbGVhZiBUaGUgbGVhZiB0byByZXBsYWNlXHJcblx0ICogQHBhcmFtIGlzQWxsVGFic0Nsb3NlZCBXaGV0aGVyIHRoaXMgaXMgdHJpZ2dlcmVkIGJ5IFwiYWxsIHRhYnMgY2xvc2VkXCIgKHRydWUpIG9yIFwibmV3IHRhYiByZXBsYWNlbWVudFwiIChmYWxzZSlcclxuXHQgKi9cclxuXHRwcml2YXRlIGFzeW5jIHJlcGxhY2VFbXB0eVRhYihsZWFmOiBXb3Jrc3BhY2VMZWFmLCBpc0FsbFRhYnNDbG9zZWQ6IGJvb2xlYW4gPSBmYWxzZSk6IFByb21pc2U8dm9pZD4ge1xyXG5cdFx0Ly8gSWYgdGhpcyBpcyBmb3IgbmV3IHRhYiByZXBsYWNlbWVudCAobm90IGFsbCB0YWJzIGNsb3NlZCksIGNoZWNrIHJlcGxhY2VOZXdUYWJcclxuXHRcdGlmICghaXNBbGxUYWJzQ2xvc2VkKSB7XHJcblx0XHRcdC8vIENSSVRJQ0FMOiBDaGVjayByZXBsYWNlTmV3VGFiIG9uZSBtb3JlIHRpbWUgYmVmb3JlIGFjdHVhbGx5IHJlcGxhY2luZ1xyXG5cdFx0XHQvLyBUaGlzIHByZXZlbnRzIHJhY2UgY29uZGl0aW9ucyB3aGVyZSB0aGUgc2V0dGluZyBjaGFuZ2VkIGJldHdlZW4gY2hlY2tzXHJcblx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5yZXBsYWNlTmV3VGFiICE9PSB0cnVlKSB7XHJcblx0XHRcdFx0Y29uc29sZS5kZWJ1ZygnW0hvbWUgQmFzZV0gcmVwbGFjZUVtcHR5VGFiOiByZXBsYWNlTmV3VGFiIGlzIG5vdCB0cnVlLCBhYm9ydGluZycpO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFNtYWxsIGRlbGF5IHRvIGhhbmRsZSByYWNlIGNvbmRpdGlvbnMgd2l0aCBvdGhlciBwbHVnaW5zXHJcblx0XHRhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgUExVR0lOX1JBQ0VfREVMQVkpKTtcclxuXHJcblx0XHQvLyBJZiB0aGlzIGlzIGZvciBuZXcgdGFiIHJlcGxhY2VtZW50LCBjaGVjayBhZ2FpbiBhZnRlciBkZWxheVxyXG5cdFx0aWYgKCFpc0FsbFRhYnNDbG9zZWQpIHtcclxuXHRcdFx0Ly8gRmluYWwgY2hlY2sgYWZ0ZXIgZGVsYXkgLSBzZXR0aW5nIG1pZ2h0IGhhdmUgY2hhbmdlZFxyXG5cdFx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MucmVwbGFjZU5ld1RhYiAhPT0gdHJ1ZSkge1xyXG5cdFx0XHRcdGNvbnNvbGUuZGVidWcoJ1tIb21lIEJhc2VdIHJlcGxhY2VFbXB0eVRhYjogcmVwbGFjZU5ld1RhYiBjaGFuZ2VkIGR1cmluZyBkZWxheSwgYWJvcnRpbmcnKTtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdC8vIElmIHRoaXMgaXMgZm9yIGFsbCB0YWJzIGNsb3NlZCwgY2hlY2sgdGhhdCBzZXR0aW5nIGluc3RlYWRcclxuXHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLm9wZW5XaGVuQWxsVGFic0Nsb3NlZCAhPT0gdHJ1ZSkge1xyXG5cdFx0XHRcdGNvbnNvbGUuZGVidWcoJ1tIb21lIEJhc2VdIHJlcGxhY2VFbXB0eVRhYjogb3BlbldoZW5BbGxUYWJzQ2xvc2VkIGNoYW5nZWQgZHVyaW5nIGRlbGF5LCBhYm9ydGluZycpO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIERvdWJsZS1jaGVjayB0aGUgdGFiIGlzIHN0aWxsIGVtcHR5XHJcblx0XHRpZiAoIXRoaXMuaXNFbXB0eVRhYihsZWFmKSkge1xyXG5cdFx0XHRjb25zb2xlLmRlYnVnKCdbSG9tZSBCYXNlXSByZXBsYWNlRW1wdHlUYWI6IFRhYiBpcyBubyBsb25nZXIgZW1wdHksIHNraXBwaW5nJyk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBJZiB0aGlzIGlzIGZvciBcImFsbCB0YWJzIGNsb3NlZFwiLCB1c2UgaG9tZSBiYXNlIHNldHRpbmdzXHJcblx0XHQvLyBPdGhlcndpc2UsIHVzZSBuZXcgdGFiIHNldHRpbmdzIChmb3IgXCJyZXBsYWNlIG5ldyB0YWJzXCIgZmVhdHVyZSlcclxuXHRcdGNvbnN0IHNldHRpbmdzID0gaXNBbGxUYWJzQ2xvc2VkXHJcblx0XHRcdD8gdGhpcy5wbHVnaW4uZ2V0SG9tZUJhc2VTZXR0aW5ncygpXHJcblx0XHRcdDogdGhpcy5wbHVnaW4uZ2V0TmV3VGFiU2V0dGluZ3MoKTtcclxuXHJcblx0XHRjb25zb2xlLmRlYnVnKCdbSG9tZSBCYXNlXSByZXBsYWNlRW1wdHlUYWI6Jywge1xyXG5cdFx0XHRsZWFmOiBsZWFmLFxyXG5cdFx0XHRpc0FsbFRhYnNDbG9zZWQ6IGlzQWxsVGFic0Nsb3NlZCxcclxuXHRcdFx0c2V0dGluZ3M6IHNldHRpbmdzLFxyXG5cdFx0XHRyZXBsYWNlTmV3VGFiOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5yZXBsYWNlTmV3VGFiLFxyXG5cdFx0XHRuZXdUYWJNb2RlOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5uZXdUYWJNb2RlLFxyXG5cdFx0XHR1c2VEaWZmZXJlbnRGaWxlRm9yTmV3VGFiOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VEaWZmZXJlbnRGaWxlRm9yTmV3VGFiXHJcblx0XHR9KTtcclxuXHJcblx0XHQvLyBPcGVuIGZpbGUgaW4gdGhpcyBsZWFmXHJcblx0XHQvLyBQYXNzIGlzTmV3VGFiPXRydWUgdG8gc2tpcCBwaW5uaW5nL2dob3N0IHRhYiBsb2dpYyAtIG5ldyB0YWJzIHNob3VsZCB3b3JrIGluZGVwZW5kZW50bHlcclxuXHRcdGNvbnN0IHN1Y2Nlc3MgPSBhd2FpdCB0aGlzLnBsdWdpbi5ob21lU2VydmljZS5vcGVuSW5MZWFmV2l0aFNldHRpbmdzKGxlYWYsIHNldHRpbmdzLCB0cnVlKTtcclxuXHJcblx0XHRpZiAoIXN1Y2Nlc3MpIHtcclxuXHRcdFx0Y29uc29sZS53YXJuKCdbSG9tZSBCYXNlXSBGYWlsZWQgdG8gb3BlbiBmaWxlOicsIHNldHRpbmdzKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGNvbnNvbGUuZGVidWcoJ1tIb21lIEJhc2VdIHJlcGxhY2VFbXB0eVRhYjogU3VjY2Vzc2Z1bGx5IG9wZW5lZCBmaWxlJyk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBGb3JjZSBjaGVjayBmb3IgZW1wdHkgd29ya3NwYWNlIGFuZCBvcGVuIGhvbWUgYmFzZVxyXG5cdCAqL1xyXG5cdGFzeW5jIG9wZW5JZkVtcHR5KCk6IFByb21pc2U8dm9pZD4ge1xyXG5cdFx0Ly8gQ2hlY2sgaWYgdGhlcmUncyBhbiBlbXB0eSB2aWV3XHJcblx0XHRjb25zdCBhY3RpdmVWaWV3ID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoVmlldyk7XHJcblx0XHRjb25zdCBhY3RpdmVMZWFmID0gYWN0aXZlVmlldz8ubGVhZjtcclxuXHJcblx0XHRpZiAoIWFjdGl2ZUxlYWYpIHJldHVybjtcclxuXHJcblx0XHQvLyBDaGVjayBpZiBpdCdzIGVtcHR5IGFuZCBpcyB0aGUgb25seSB0YWJcclxuXHRcdGlmICh0aGlzLmlzRW1wdHlUYWIoYWN0aXZlTGVhZikgJiYgdGhpcy5pc09ubHlUYWIoYWN0aXZlTGVhZikpIHtcclxuXHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uaG9tZVNlcnZpY2Uub3BlbkluTGVhZihhY3RpdmVMZWFmKTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuIiwgIi8qKlxyXG4gKiBTdGlja3kgVGFiIFNlcnZpY2VcclxuICogTWFuYWdlcyB0aGUgc3RpY2t5IGhvbWUgaWNvbiBpbiB0aGUgdGFiIGJhclxyXG4gKi9cclxuXHJcbmltcG9ydCB7IE1lbnUsIFBsYXRmb3JtLCBzZXRJY29uLCBXb3Jrc3BhY2VMZWFmIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgdHlwZSBIb21lQmFzZVBsdWdpbiBmcm9tICcuLi9tYWluJztcclxuaW1wb3J0IHsgSG9tZUJhc2VUeXBlIH0gZnJvbSAnLi4vc2V0dGluZ3MnO1xyXG5pbXBvcnQgeyBnZXRGaWxlQnlQYXRoLCBsZWFmSGFzRmlsZSB9IGZyb20gJy4uL3V0aWxzL2ZpbGUtdXRpbHMnO1xyXG5pbXBvcnQgeyByZXNvbHZlUGF0aFN5bmMgfSBmcm9tICcuLi91dGlscy9ob21lYmFzZS1yZXNvbHZlcic7XHJcbmltcG9ydCB7IEljb25QaWNrZXIgfSBmcm9tICcuLi91aS9pY29uLXBpY2tlcic7XHJcblxyXG4vKipcclxuICogVGltaW5nIGNvbnN0YW50cyBmb3Igc3RpY2t5IHRhYiBvcGVyYXRpb25zXHJcbiAqIFRoZXNlIGRlbGF5cyBhcmUgbmVjZXNzYXJ5IGZvciBVSSB1cGRhdGVzIGFuZCBET00gbW9uaXRvcmluZy5cclxuICovXHJcblxyXG4vKiogRGVsYXkgZm9yIHRhYiBoZWFkZXIgdXBkYXRlcyBhZnRlciBvcGVuaW5nIGhvbWUgYmFzZSAqL1xyXG5jb25zdCBUQUJfSEVBREVSX09QRU5fREVMQVkgPSAxNTA7XHJcblxyXG4vKiogSW50ZXJ2YWwgZm9yIHBlcmlvZGljIGljb24gcGxhY2VtZW50IGNoZWNrIChlbnN1cmVzIGl0IHN1cnZpdmVzIERPTSB1cGRhdGVzKSAqL1xyXG5jb25zdCBJQ09OX1BMQUNFTUVOVF9DSEVDS19JTlRFUlZBTCA9IDEwMDtcclxuXHJcbi8qKiBTbWFsbCBkZWxheSB0byBjYXRjaCBjb250YWluZXJzIGluIG5ld2x5IG9wZW5lZCB3aW5kb3dzICovXHJcbmNvbnN0IFdJTkRPV19PUEVOX0NPTlRBSU5FUl9ERUxBWSA9IDEwMDtcclxuXHJcbi8qKlxyXG4gKiBDU1MgY2xhc3MgZm9yIHRoZSBzdGlja3kgaG9tZSBpY29uIGNvbnRhaW5lclxyXG4gKi9cclxuY29uc3QgU1RJQ0tZX0lDT05fQ0xBU1MgPSAnaG9tZS1iYXNlLXN0aWNreS1pY29uJztcclxuY29uc3QgU1RJQ0tZX0lDT05fQUNUSVZFX0NMQVNTID0gJ2hvbWUtYmFzZS1zdGlja3ktaWNvbi1hY3RpdmUnO1xyXG5cclxuLyoqXHJcbiAqIEV4dGVuZGVkIEhUTUxFbGVtZW50IGludGVyZmFjZSBmb3Igc3RpY2t5IGljb24gd2l0aCBjdXN0b20gcHJvcGVydGllc1xyXG4gKi9cclxuaW50ZXJmYWNlIFN0aWNreUljb25FbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQge1xyXG5cdF9jaGVja0ludGVydmFsPzogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+O1xyXG5cdF9jb250YWluZXJPYnNlcnZlcj86IE11dGF0aW9uT2JzZXJ2ZXI7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFeHRlbmRlZCBIVE1MRWxlbWVudCBpbnRlcmZhY2UgZm9yIHRhYiBoZWFkZXIgd2l0aCBob21lIGJhc2UgcHJvcGVydGllc1xyXG4gKi9cclxuaW50ZXJmYWNlIFRhYkhlYWRlckVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7XHJcblx0X2hvbWVCYXNlUGFyZW50PzogSFRNTEVsZW1lbnQ7XHJcblx0X2hvbWVCYXNlTmV4dFNpYmxpbmc/OiBOb2RlIHwgbnVsbDtcclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFN0aWNreVRhYlNlcnZpY2Uge1xyXG5cdHByaXZhdGUgcGx1Z2luOiBIb21lQmFzZVBsdWdpbjtcclxuXHRwcml2YXRlIHN0aWNreUljb25FbDogU3RpY2t5SWNvbkVsZW1lbnQgfCBudWxsID0gbnVsbDtcclxuXHRwcml2YXRlIGxheW91dENoYW5nZUhhbmRsZXI6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xyXG5cdHByaXZhdGUgdGFiSGVhZGVyVXBkYXRlVGltZW91dDogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcclxuXHRwcml2YXRlIHNpZGViYXJPYnNlcnZlcjogTXV0YXRpb25PYnNlcnZlciB8IG51bGwgPSBudWxsO1xyXG5cdHByaXZhdGUgdGFiSGVhZGVyT2JzZXJ2ZXI6IE11dGF0aW9uT2JzZXJ2ZXIgfCBudWxsID0gbnVsbDtcclxuXHJcblx0Y29uc3RydWN0b3IocGx1Z2luOiBIb21lQmFzZVBsdWdpbikge1xyXG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBVcGRhdGUgdGhlIHN0aWNreSB0YWIgaWNvbiBiYXNlZCBvbiBzZXR0aW5nc1xyXG5cdCAqL1xyXG5cdHVwZGF0ZSgpOiB2b2lkIHtcclxuXHRcdC8vIE9ubHkgc2hvdyBvbiBkZXNrdG9wXHJcblx0XHRpZiAoUGxhdGZvcm0uaXNNb2JpbGUpIHtcclxuXHRcdFx0dGhpcy5yZW1vdmUoKTtcclxuXHRcdFx0dGhpcy51cGRhdGVUYWJIZWFkZXJzKCk7IC8vIENsZWFuIHVwIHRhYiBoZWFkZXJzXHJcblx0XHRcdHRoaXMudXBkYXRlV29ya3NwYWNlQ2xhc3MoZmFsc2UpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dTdGlja3lIb21lSWNvbikge1xyXG5cdFx0XHRpZiAodGhpcy5zdGlja3lJY29uRWwpIHtcclxuXHRcdFx0XHQvLyBJY29uIGFscmVhZHkgZXhpc3RzLCBqdXN0IHVwZGF0ZSB0aGUgaWNvblxyXG5cdFx0XHRcdGNvbnN0IGljb25OYW1lID0gdGhpcy5wbHVnaW4uc2V0dGluZ3Muc3RpY2t5SWNvbk5hbWUgfHwgJ2hvbWUnO1xyXG5cdFx0XHRcdHNldEljb24odGhpcy5zdGlja3lJY29uRWwsIGljb25OYW1lKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHQvLyBJY29uIGRvZXNuJ3QgZXhpc3QsIGNyZWF0ZSBpdFxyXG5cdFx0XHRcdHRoaXMuY3JlYXRlKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0dGhpcy51cGRhdGVXb3Jrc3BhY2VDbGFzcyh0cnVlKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRoaXMucmVtb3ZlKCk7XHJcblx0XHRcdHRoaXMudXBkYXRlVGFiSGVhZGVycygpOyAvLyBDbGVhbiB1cCB0YWIgaGVhZGVycyB3aGVuIHJlbW92aW5nIGljb25cclxuXHRcdFx0dGhpcy51cGRhdGVXb3Jrc3BhY2VDbGFzcyhmYWxzZSk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBBZGQvcmVtb3ZlIENTUyBjbGFzcyBvbiBhbGwgd29ya3NwYWNlcyB0byBjb25kaXRpb25hbGx5IGFwcGx5IHN0eWxlc1xyXG5cdCAqL1xyXG5cdHByaXZhdGUgdXBkYXRlV29ya3NwYWNlQ2xhc3MoZW5hYmxlZDogYm9vbGVhbik6IHZvaWQge1xyXG5cdFx0Y29uc3QgYXBwbHlUb0RvY3VtZW50ID0gKGRvYzogRG9jdW1lbnQpID0+IHtcclxuXHRcdFx0Y29uc3QgbWFpbldvcmtzcGFjZSA9IGRvYy5xdWVyeVNlbGVjdG9yKCcud29ya3NwYWNlLXNwbGl0Lm1vZC12ZXJ0aWNhbC5tb2Qtcm9vdCcpO1xyXG5cdFx0XHRpZiAoIW1haW5Xb3Jrc3BhY2UpIHJldHVybjtcclxuXHJcblx0XHRcdGlmIChlbmFibGVkKSB7XHJcblx0XHRcdFx0bWFpbldvcmtzcGFjZS5jbGFzc0xpc3QuYWRkKCdob21lLWJhc2Utc3RpY2t5LWljb24tZW5hYmxlZCcpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdG1haW5Xb3Jrc3BhY2UuY2xhc3NMaXN0LnJlbW92ZSgnaG9tZS1iYXNlLXN0aWNreS1pY29uLWVuYWJsZWQnKTtcclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHJcblx0XHQvLyBBcHBseSB0byBtYWluIHdpbmRvd1xyXG5cdFx0YXBwbHlUb0RvY3VtZW50KGRvY3VtZW50KTtcclxuXHJcblx0XHQvLyBBcHBseSB0byBhbGwgb3RoZXIgd2luZG93c1xyXG5cdFx0dGhpcy5wbHVnaW4uYXBwLndvcmtzcGFjZS5pdGVyYXRlQWxsTGVhdmVzKChsZWFmKSA9PiB7XHJcblx0XHRcdGNvbnN0IGRvYyA9IGxlYWYudmlldz8uY29udGFpbmVyRWw/Lm93bmVyRG9jdW1lbnQ7XHJcblx0XHRcdGlmIChkb2MgJiYgZG9jICE9PSBkb2N1bWVudCkge1xyXG5cdFx0XHRcdGFwcGx5VG9Eb2N1bWVudChkb2MpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENyZWF0ZSB0aGUgc3RpY2t5IGhvbWUgaWNvblxyXG5cdCAqL1xyXG5cdHByaXZhdGUgY3JlYXRlKCk6IHZvaWQge1xyXG5cdFx0Ly8gUmVtb3ZlIGV4aXN0aW5nIGljb24gZmlyc3RcclxuXHRcdHRoaXMucmVtb3ZlKCk7XHJcblxyXG5cdFx0Ly8gQ3JlYXRlIHRoZSBzdGlja3kgaWNvbiBlbGVtZW50IG9uY2VcclxuXHRcdHRoaXMuc3RpY2t5SWNvbkVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcblx0XHR0aGlzLnN0aWNreUljb25FbC5jbGFzc05hbWUgPSBgJHtTVElDS1lfSUNPTl9DTEFTU30gY2xpY2thYmxlLWljb25gO1xyXG5cdFx0dGhpcy5zdGlja3lJY29uRWwuc2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsJywgJ09wZW4gaG9tZSBiYXNlJyk7XHJcblx0XHR0aGlzLnN0aWNreUljb25FbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdG9vbHRpcC1wb3NpdGlvbicsICdib3R0b20nKTtcclxuXHJcblx0XHQvLyBBZGQgdGhlIGljb24gZnJvbSBzZXR0aW5ncyAoZGVmYXVsdCB0byAnaG9tZScpXHJcblx0XHRjb25zdCBpY29uTmFtZSA9IHRoaXMucGx1Z2luLnNldHRpbmdzLnN0aWNreUljb25OYW1lIHx8ICdob21lJztcclxuXHRcdHNldEljb24odGhpcy5zdGlja3lJY29uRWwsIGljb25OYW1lKTtcclxuXHJcblx0XHQvLyBBZGQgY2xpY2sgaGFuZGxlclxyXG5cdFx0dGhpcy5zdGlja3lJY29uRWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBlID0+IHtcclxuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cclxuXHRcdFx0Ly8gT3BlbiBob21lIGJhc2UgaW4gZ2hvc3QgdGFiIChhbHdheXMgdXNlIGdob3N0IHRhYiBmb3Igc3RpY2t5IGljb24pXHJcblx0XHRcdHZvaWQgdGhpcy5wbHVnaW4uaG9tZVNlcnZpY2Uub3BlbkhvbWVCYXNlSW5HaG9zdFRhYih7XHJcblx0XHRcdFx0cnVuQ29tbWFuZDogdHJ1ZSxcclxuXHRcdFx0fSkudGhlbigoKSA9PiB7XHJcblx0XHRcdFx0Ly8gVXBkYXRlIHRhYiBoZWFkZXJzIGFmdGVyIG9wZW5pbmcsIHdpdGggYSBzbGlnaHQgZGVsYXkgdG8gbGV0IGFuaW1hdGlvbnMgY29tcGxldGVcclxuXHRcdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcclxuXHRcdFx0XHRcdHRoaXMudXBkYXRlVGFiSGVhZGVycygpO1xyXG5cdFx0XHRcdH0sIFRBQl9IRUFERVJfT1BFTl9ERUxBWSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gQWRkIGNvbnRleHQgbWVudSBmb3IgY2hhbmdpbmcgaWNvbiBhbmQgY2xvc2luZyBob21lIGJhc2VcclxuXHRcdHRoaXMuc3RpY2t5SWNvbkVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgZSA9PiB7XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0ZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcblx0XHRcdGNvbnN0IG1lbnUgPSBuZXcgTWVudSgpO1xyXG5cclxuXHRcdFx0Ly8gQWRkIENsb3NlIGhvbWUgYmFzZSBvcHRpb24gKGZpcnN0KVxyXG5cdFx0XHRtZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRpdGVtXHJcblx0XHRcdFx0XHQuc2V0VGl0bGUoJ0Nsb3NlIGhvbWUgYmFzZScpXHJcblx0XHRcdFx0XHQuc2V0SWNvbigneCcpXHJcblx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XHJcblx0XHRcdFx0XHRcdC8vIEFjdHVhbGx5IGNsb3NlIGl0IChpbmNsdWRpbmcgZ2hvc3QgdGFiIGlmIHN0aWNreSBpY29uIGlzIGVuYWJsZWQpXHJcblx0XHRcdFx0XHRcdC8vIElmIG5ldyB0YWIgcmVwbGFjZW1lbnQgaXMgZW5hYmxlZCwgaXQgd2lsbCByZW9wZW4gd2hlbiB5b3UgY3JlYXRlIGEgbmV3IHRhYlxyXG5cdFx0XHRcdFx0XHR2b2lkIHRoaXMuY2xvc2VIb21lQmFzZSh0cnVlKTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdC8vIEFkZCBDaGFuZ2UgaWNvbiBvcHRpb24gKHNlY29uZClcclxuXHRcdFx0bWVudS5hZGRJdGVtKChpdGVtKSA9PiB7XHJcblx0XHRcdFx0aXRlbVxyXG5cdFx0XHRcdFx0LnNldFRpdGxlKCdDaGFuZ2UgaWNvbicpXHJcblx0XHRcdFx0XHQuc2V0SWNvbignbHVjaWRlLWltYWdlLXBsdXMnKVxyXG5cdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRjb25zdCBwaWNrZXIgPSBuZXcgSWNvblBpY2tlcihcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5hcHAsXHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc3RpY2t5SWNvbk5hbWUsXHJcblx0XHRcdFx0XHRcdFx0KGljb246IHN0cmluZyB8IG51bGwpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdHZvaWQgKGFzeW5jICgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc3RpY2t5SWNvbk5hbWUgPSBpY29uO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gVXBkYXRlIHRoZSBpY29uIGRpc3BsYXlcclxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKHRoaXMuc3RpY2t5SWNvbkVsKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0c2V0SWNvbih0aGlzLnN0aWNreUljb25FbCwgaWNvbiB8fCAnaG9tZScpO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHR9KSgpO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0KTtcclxuXHRcdFx0XHRcdFx0cGlja2VyLm9wZW4oKTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0bWVudS5zaG93QXRNb3VzZUV2ZW50KGUpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gRnVuY3Rpb24gdG8gZW5zdXJlIGljb24gaXMgaW4gdGhlIHJpZ2h0IHBsYWNlXHJcblx0XHQvLyBJbnNlcnQgaXQgaW50byB0aGUgd29ya3NwYWNlLXRhYi1oZWFkZXItY29udGFpbmVyLWlubmVyIHNvIGl0J3MgcGFydCBvZiB0aGUgdGFiIGJhciBzdHJ1Y3R1cmVcclxuXHRcdC8vIFRoaXMgbWFrZXMgaXQgYXV0b21hdGljYWxseSBoaWRlIHdoZW4gcGx1Z2lucy90aGVtZXMgaGlkZSB0aGUgdGFiIGJhclxyXG5cdFx0Y29uc3QgZW5zdXJlSWNvbkluUGxhY2UgPSAoKSA9PiB7XHJcblx0XHRcdGlmICghdGhpcy5zdGlja3lJY29uRWwpIHJldHVybjtcclxuXHJcblx0XHRcdGNvbnN0IG1haW5Xb3Jrc3BhY2UgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcud29ya3NwYWNlLXNwbGl0Lm1vZC12ZXJ0aWNhbC5tb2Qtcm9vdCcpO1xyXG5cdFx0XHRpZiAoIW1haW5Xb3Jrc3BhY2UpIHJldHVybjtcclxuXHJcblx0XHRcdC8vIEZpbmQgdGhlIHdvcmtzcGFjZS10YWItaGVhZGVyLWNvbnRhaW5lci1pbm5lciAoaW5zaWRlIHRoZSB0YWIgY29udGFpbmVyKVxyXG5cdFx0XHRjb25zdCB0YWJIZWFkZXJDb250YWluZXJJbm5lciA9IG1haW5Xb3Jrc3BhY2UucXVlcnlTZWxlY3RvcignLndvcmtzcGFjZS10YWItaGVhZGVyLWNvbnRhaW5lci1pbm5lcicpO1xyXG5cdFx0XHRpZiAoIXRhYkhlYWRlckNvbnRhaW5lcklubmVyKSByZXR1cm47XHJcblxyXG5cdFx0XHQvLyBSZW1vdmUgYW55IGR1cGxpY2F0ZSBpY29ucyBmaXJzdCAoaW4gY2FzZSBtdXRhdGlvbiBvYnNlcnZlciBvciBvdGhlciBjb2RlIGNyZWF0ZWQgdGhlbSlcclxuXHRcdFx0Y29uc3QgYWxsSWNvbnMgPSB0YWJIZWFkZXJDb250YWluZXJJbm5lci5xdWVyeVNlbGVjdG9yQWxsKGAuJHtTVElDS1lfSUNPTl9DTEFTU31gKTtcclxuXHRcdFx0YWxsSWNvbnMuZm9yRWFjaCgoaWNvbikgPT4ge1xyXG5cdFx0XHRcdGlmIChpY29uICE9PSB0aGlzLnN0aWNreUljb25FbCkge1xyXG5cdFx0XHRcdFx0aWNvbi5yZW1vdmUoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0Ly8gQ2hlY2sgaWYgb3VyIGljb24gaXMgYWxyZWFkeSBpbiB0aGUgY29udGFpbmVyXHJcblx0XHRcdGlmICh0YWJIZWFkZXJDb250YWluZXJJbm5lci5jb250YWlucyh0aGlzLnN0aWNreUljb25FbCkpIHtcclxuXHRcdFx0XHQvLyBBbHJlYWR5IGluIHBsYWNlLCBub3RoaW5nIHRvIGRvXHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBJY29uIGlzIG1pc3NpbmcgLSBwcmVwZW5kIGl0IHRvIHRoZSB0YWIgaGVhZGVyIGNvbnRhaW5lciBpbm5lclxyXG5cdFx0XHQvLyBUaGlzIG1ha2VzIGl0IHBhcnQgb2YgdGhlIHRhYiBiYXIgc3RydWN0dXJlLCBzbyBpdCBoaWRlcyBhdXRvbWF0aWNhbGx5IHdoZW4gdGFicyBhcmUgaGlkZGVuXHJcblx0XHRcdHRhYkhlYWRlckNvbnRhaW5lcklubmVyLmluc2VydEJlZm9yZSh0aGlzLnN0aWNreUljb25FbCwgdGFiSGVhZGVyQ29udGFpbmVySW5uZXIuZmlyc3RDaGlsZCk7XHJcblxyXG5cdFx0XHQvLyBVcGRhdGUgYWN0aXZlIHN0YXRlIGFmdGVyIGluc2VydGlvblxyXG5cdFx0XHR0aGlzLnVwZGF0ZUFjdGl2ZVN0YXRlKCk7XHJcblxyXG5cdFx0XHQvLyBVcGRhdGUgdGFiIGhlYWRlcnMgd2hlbiBpY29uIGlzIGNyZWF0ZWRcclxuXHRcdFx0dGhpcy51cGRhdGVUYWJIZWFkZXJzKCk7XHJcblxyXG5cdFx0XHQvLyBFbnN1cmUgd29ya3NwYWNlIGNsYXNzIGlzIHNldFxyXG5cdFx0XHR0aGlzLnVwZGF0ZVdvcmtzcGFjZUNsYXNzKHRydWUpO1xyXG5cclxuXHRcdFx0Ly8gVXBkYXRlIGljb24gcG9zaXRpb24gYmFzZWQgb24gc2lkZWJhciBzdGF0ZVxyXG5cdFx0XHR0aGlzLnVwZGF0ZUljb25Qb3NpdGlvbkZvclNpZGViYXIoKTtcclxuXHJcblx0XHRcdC8vIFdhdGNoIGZvciBzaWRlYmFyIGNvbGxhcHNlL2V4cGFuZCBjaGFuZ2VzXHJcblx0XHRcdHRoaXMud2F0Y2hTaWRlYmFyU3RhdGUoKTtcclxuXHRcdH07XHJcblxyXG5cdFx0Ly8gVHJ5IHRvIGluc2VydCBpbW1lZGlhdGVseVxyXG5cdFx0ZW5zdXJlSWNvbkluUGxhY2UoKTtcclxuXHJcblx0XHQvLyBTZXQgdXAgYSByZWxpYWJsZSBjaGVjayB0aGF0IHJ1bnMgcGVyaW9kaWNhbGx5IHRvIGVuc3VyZSBpY29uIGlzIGFsd2F5cyB0aGVyZVxyXG5cdFx0Ly8gVGhpcyBpcyBzaW1wbGUgYW5kIHJlbGlhYmxlIC0ganVzdCBjaGVjayBpZiBpdCdzIHRoZXJlLCBpZiBub3QsIHB1dCBpdCBiYWNrXHJcblx0XHRjb25zdCBjaGVja0ludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xyXG5cdFx0XHRpZiAoIXRoaXMuc3RpY2t5SWNvbkVsIHx8ICF0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93U3RpY2t5SG9tZUljb24pIHtcclxuXHRcdFx0XHRjbGVhckludGVydmFsKGNoZWNrSW50ZXJ2YWwpO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRlbnN1cmVJY29uSW5QbGFjZSgpO1xyXG5cdFx0fSwgSUNPTl9QTEFDRU1FTlRfQ0hFQ0tfSU5URVJWQUwpOyAvLyBDaGVjayBldmVyeSAxMDBtcyAtIG1vcmUgZnJlcXVlbnQgdG8gY2F0Y2ggY29udGFpbmVyIHJlY3JlYXRpb24gaW1tZWRpYXRlbHlcclxuXHJcblx0XHQvLyBTdG9yZSBpbnRlcnZhbCBzbyB3ZSBjYW4gY2xlYXIgaXQgbGF0ZXJcclxuXHRcdHRoaXMuc3RpY2t5SWNvbkVsLl9jaGVja0ludGVydmFsID0gY2hlY2tJbnRlcnZhbDtcclxuXHJcblx0XHQvLyBBbHNvIGNoZWNrIG9uIGxheW91dCBjaGFuZ2VzIC0gYnV0IGRvIGl0IGltbWVkaWF0ZWx5LCBubyBkZWxheVxyXG5cdFx0aWYgKCF0aGlzLmxheW91dENoYW5nZUhhbmRsZXIpIHtcclxuXHRcdFx0dGhpcy5sYXlvdXRDaGFuZ2VIYW5kbGVyID0gKCkgPT4ge1xyXG5cdFx0XHRcdGlmICh0aGlzLnN0aWNreUljb25FbCAmJiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93U3RpY2t5SG9tZUljb24pIHtcclxuXHRcdFx0XHRcdC8vIENoZWNrIGltbWVkaWF0ZWx5IC0gZG9uJ3Qgd2FpdCBmb3IgbGF5b3V0IHRvIHNldHRsZVxyXG5cdFx0XHRcdFx0Ly8gVGhpcyBwcmV2ZW50cyBmbGlja2VyaW5nIHdoZW4gdGFicyBjbG9zZVxyXG5cdFx0XHRcdFx0ZW5zdXJlSWNvbkluUGxhY2UoKTtcclxuXHRcdFx0XHRcdC8vIFVwZGF0ZSB0YWIgaGVhZGVycyBvbiBsYXlvdXQgY2hhbmdlXHJcblx0XHRcdFx0XHR0aGlzLnVwZGF0ZVRhYkhlYWRlcnMoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH07XHJcblxyXG5cdFx0XHR0aGlzLnBsdWdpbi5yZWdpc3RlckV2ZW50KFxyXG5cdFx0XHRcdHRoaXMucGx1Z2luLmFwcC53b3Jrc3BhY2Uub24oJ2xheW91dC1jaGFuZ2UnLCB0aGlzLmxheW91dENoYW5nZUhhbmRsZXIpXHJcblx0XHRcdCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQWxzbyB3YXRjaCBmb3Igd2hlbiB3b3Jrc3BhY2UtdGFiLWhlYWRlci1jb250YWluZXItaW5uZXIgaXMgYWRkZWQgYmFjayAoYWZ0ZXIgYWxsIHRhYnMgY2xvc2VkKVxyXG5cdFx0Ly8gVXNlIGEgTXV0YXRpb25PYnNlcnZlciBvbiB0aGUgd29ya3NwYWNlIHNwbGl0IHRvIGNhdGNoIGNvbnRhaW5lciByZWNyZWF0aW9uXHJcblx0XHRjb25zdCBtYWluV29ya3NwYWNlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLndvcmtzcGFjZS1zcGxpdC5tb2QtdmVydGljYWwubW9kLXJvb3QnKTtcclxuXHRcdGlmIChtYWluV29ya3NwYWNlKSB7XHJcblx0XHRcdGNvbnN0IGNvbnRhaW5lck9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKCkgPT4ge1xyXG5cdFx0XHRcdGlmICghdGhpcy5zdGlja3lJY29uRWwgfHwgIXRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dTdGlja3lIb21lSWNvbikgcmV0dXJuO1xyXG5cclxuXHRcdFx0XHQvLyBDaGVjayBpZiB0YWIgaGVhZGVyIGNvbnRhaW5lciBpbm5lciBleGlzdHMgYW5kIGljb24gaXMgbWlzc2luZ1xyXG5cdFx0XHRcdGNvbnN0IHRhYkhlYWRlckNvbnRhaW5lcklubmVyID0gbWFpbldvcmtzcGFjZS5xdWVyeVNlbGVjdG9yKCcud29ya3NwYWNlLXRhYi1oZWFkZXItY29udGFpbmVyLWlubmVyJyk7XHJcblx0XHRcdFx0aWYgKHRhYkhlYWRlckNvbnRhaW5lcklubmVyKSB7XHJcblx0XHRcdFx0XHQvLyBSZW1vdmUgYW55IGR1cGxpY2F0ZSBpY29ucyBmaXJzdFxyXG5cdFx0XHRcdFx0Y29uc3QgYWxsSWNvbnMgPSB0YWJIZWFkZXJDb250YWluZXJJbm5lci5xdWVyeVNlbGVjdG9yQWxsKGAuJHtTVElDS1lfSUNPTl9DTEFTU31gKTtcclxuXHRcdFx0XHRcdGFsbEljb25zLmZvckVhY2goKGljb24pID0+IHtcclxuXHRcdFx0XHRcdFx0aWYgKGljb24gIT09IHRoaXMuc3RpY2t5SWNvbkVsKSB7XHJcblx0XHRcdFx0XHRcdFx0aWNvbi5yZW1vdmUoKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fSk7XHJcblxyXG5cdFx0XHRcdFx0Ly8gT25seSByZS1pbnNlcnQgaWYgb3VyIGljb24gaXMgbm90IGFscmVhZHkgaW4gdGhlIGNvbnRhaW5lclxyXG5cdFx0XHRcdFx0aWYgKCF0YWJIZWFkZXJDb250YWluZXJJbm5lci5jb250YWlucyh0aGlzLnN0aWNreUljb25FbCkpIHtcclxuXHRcdFx0XHRcdFx0Ly8gQ29udGFpbmVyIGV4aXN0cyBidXQgaWNvbiBpcyBtaXNzaW5nIC0gcmUtaW5zZXJ0IGltbWVkaWF0ZWx5XHJcblx0XHRcdFx0XHRcdHRhYkhlYWRlckNvbnRhaW5lcklubmVyLmluc2VydEJlZm9yZSh0aGlzLnN0aWNreUljb25FbCwgdGFiSGVhZGVyQ29udGFpbmVySW5uZXIuZmlyc3RDaGlsZCk7XHJcblx0XHRcdFx0XHRcdHRoaXMudXBkYXRlQWN0aXZlU3RhdGUoKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0Y29udGFpbmVyT2JzZXJ2ZXIub2JzZXJ2ZShtYWluV29ya3NwYWNlLCB7XHJcblx0XHRcdFx0Y2hpbGRMaXN0OiB0cnVlLFxyXG5cdFx0XHRcdHN1YnRyZWU6IHRydWUsIC8vIFdhdGNoIHN1YnRyZWUgdG8gY2F0Y2ggdGFiIGNvbnRhaW5lciByZWNyZWF0aW9uXHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0Ly8gU3RvcmUgb2JzZXJ2ZXIgc28gd2UgY2FuIGNsZWFuIGl0IHVwXHJcblx0XHRcdHRoaXMuc3RpY2t5SWNvbkVsLl9jb250YWluZXJPYnNlcnZlciA9IGNvbnRhaW5lck9ic2VydmVyO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFNldCB1cCBNdXRhdGlvbk9ic2VydmVyIHRvIHdhdGNoIGZvciBuZXcgdGFiIGhlYWRlcnMgYW5kIHJlbW92ZSBnaG9zdCB0YWJzIGltbWVkaWF0ZWx5XHJcblx0XHR0aGlzLnNldHVwVGFiSGVhZGVyT2JzZXJ2ZXIoKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldCB1cCBNdXRhdGlvbk9ic2VydmVyIHRvIHdhdGNoIGZvciB0YWIgaGVhZGVyIGNoYW5nZXMgYW5kIHJlbW92ZSBnaG9zdCB0YWJzIGltbWVkaWF0ZWx5XHJcblx0ICogVGhpcyBwcmV2ZW50cyB0aGUgZmxhc2ggd2hlbiB0YWJzIGFyZSBvcGVuZWQvY2xvc2VkXHJcblx0ICovXHJcblx0cHJpdmF0ZSBzZXR1cFRhYkhlYWRlck9ic2VydmVyKCk6IHZvaWQge1xyXG5cdFx0aWYgKHRoaXMudGFiSGVhZGVyT2JzZXJ2ZXIpIHtcclxuXHRcdFx0cmV0dXJuOyAvLyBBbHJlYWR5IHNldCB1cFxyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMudGFiSGVhZGVyT2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigobXV0YXRpb25zKSA9PiB7XHJcblx0XHRcdC8vIE9ubHkgcHJvY2VzcyBpZiBzZXR0aW5ncyBhcmUgZW5hYmxlZFxyXG5cdFx0XHRpZiAoIXRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dTdGlja3lIb21lSWNvbiB8fCAhdGhpcy5wbHVnaW4uc2V0dGluZ3MuaGlkZUhvbWVUYWJIZWFkZXIpIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIENoZWNrIGlmIGFueSBuZXcgdGFiIGhlYWRlcnMgd2VyZSBhZGRlZFxyXG5cdFx0XHRsZXQgaGFzTmV3SGVhZGVycyA9IGZhbHNlO1xyXG5cdFx0XHRmb3IgKGNvbnN0IG11dGF0aW9uIG9mIG11dGF0aW9ucykge1xyXG5cdFx0XHRcdGlmIChtdXRhdGlvbi50eXBlID09PSAnY2hpbGRMaXN0JyAmJiBtdXRhdGlvbi5hZGRlZE5vZGVzLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0XHRcdGZvciAoY29uc3Qgbm9kZSBvZiBBcnJheS5mcm9tKG11dGF0aW9uLmFkZGVkTm9kZXMpKSB7XHJcblx0XHRcdFx0XHRcdGlmIChub2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgJiYgbm9kZS5jbGFzc0xpc3QuY29udGFpbnMoJ3dvcmtzcGFjZS10YWItaGVhZGVyJykpIHtcclxuXHRcdFx0XHRcdFx0XHRoYXNOZXdIZWFkZXJzID0gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoaGFzTmV3SGVhZGVycykgYnJlYWs7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmIChoYXNOZXdIZWFkZXJzKSB7XHJcblx0XHRcdFx0Ly8gSW1tZWRpYXRlbHkgcmVtb3ZlIGFueSBnaG9zdCB0YWIgaGVhZGVycyB0aGF0IGFwcGVhcmVkXHJcblx0XHRcdFx0dGhpcy5wbHVnaW4uYXBwLndvcmtzcGFjZS5pdGVyYXRlQWxsTGVhdmVzKChsZWFmKSA9PiB7XHJcblx0XHRcdFx0XHQvLyBPbmx5IHByb2Nlc3MgbGVhdmVzIGluIHRoZSBtYWluIHdvcmtzcGFjZSAobm90IHNpZGViYXJzKVxyXG5cdFx0XHRcdFx0Y29uc3QgdmlldyA9IGxlYWYudmlldztcclxuXHRcdFx0XHRcdGxldCBjb250YWluZXI6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XHJcblxyXG5cdFx0XHRcdFx0aWYgKHZpZXcpIHtcclxuXHRcdFx0XHRcdFx0Y29uc3Qgdmlld0FueSA9IHZpZXcgYXMgdW5rbm93biBhcyB7IGNvbnRhaW5lckVsPzogSFRNTEVsZW1lbnQgfTtcclxuXHRcdFx0XHRcdFx0Y29udGFpbmVyID0gdmlld0FueS5jb250YWluZXJFbCB8fCBudWxsO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdGlmICghY29udGFpbmVyKSB7XHJcblx0XHRcdFx0XHRcdGNvbnN0IGxlYWZBbnkgPSBsZWFmIGFzIHVua25vd24gYXMgeyBjb250YWluZXJFbD86IEhUTUxFbGVtZW50IH07XHJcblx0XHRcdFx0XHRcdGNvbnRhaW5lciA9IGxlYWZBbnkuY29udGFpbmVyRWwgfHwgbnVsbDtcclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRpZiAoY29udGFpbmVyKSB7XHJcblx0XHRcdFx0XHRcdC8vIENoZWNrIGlmIGl0J3MgaW4gdGhlIG1haW4gd29ya3NwYWNlIChyb290LCBub3Qgc2lkZWJhcilcclxuXHRcdFx0XHRcdFx0Y29uc3Qgcm9vdFdvcmtzcGFjZSA9IGNvbnRhaW5lci5jbG9zZXN0KCcud29ya3NwYWNlLXNwbGl0Lm1vZC12ZXJ0aWNhbC5tb2Qtcm9vdCcpO1xyXG5cdFx0XHRcdFx0XHRjb25zdCBsZWZ0U2lkZWJhciA9IGNvbnRhaW5lci5jbG9zZXN0KCcud29ya3NwYWNlLXNwbGl0Lm1vZC1sZWZ0LXNwbGl0Jyk7XHJcblx0XHRcdFx0XHRcdGNvbnN0IHJpZ2h0U2lkZWJhciA9IGNvbnRhaW5lci5jbG9zZXN0KCcud29ya3NwYWNlLXNwbGl0Lm1vZC1yaWdodC1zcGxpdCcpO1xyXG5cclxuXHRcdFx0XHRcdFx0Ly8gT25seSBwcm9jZXNzIG1haW4gd29ya3NwYWNlIGxlYXZlc1xyXG5cdFx0XHRcdFx0XHRpZiAocm9vdFdvcmtzcGFjZSAmJiAhbGVmdFNpZGViYXIgJiYgIXJpZ2h0U2lkZWJhcikge1xyXG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5ob21lU2VydmljZS5pc0dob3N0TGVhZihsZWFmKSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgdGFiSGVhZGVyID0gdGhpcy5nZXRUYWJIZWFkZXJGb3JMZWFmKGxlYWYpO1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHRhYkhlYWRlciAmJiB0YWJIZWFkZXIucGFyZW50RWxlbWVudCkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRjb25zdCBwYXJlbnQgPSB0YWJIZWFkZXIucGFyZW50RWxlbWVudDtcclxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKHBhcmVudCAmJiBwYXJlbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCd3b3Jrc3BhY2UtdGFiLWhlYWRlci1jb250YWluZXItaW5uZXInKSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGNvbnN0IHRhYkhlYWRlckV4dGVuZGVkID0gdGFiSGVhZGVyIGFzIFRhYkhlYWRlckVsZW1lbnQ7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gT25seSByZW1vdmUgaWYgbm90IGFscmVhZHkgcmVtb3ZlZFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmIChwYXJlbnQuY29udGFpbnModGFiSGVhZGVyKSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGFiSGVhZGVyRXh0ZW5kZWQuX2hvbWVCYXNlUGFyZW50ID0gcGFyZW50O1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGFiSGVhZGVyRXh0ZW5kZWQuX2hvbWVCYXNlTmV4dFNpYmxpbmcgPSB0YWJIZWFkZXIubmV4dFNpYmxpbmc7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0YWJIZWFkZXIucmVtb3ZlKCk7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdGNvbnN0IG9ic2VydmVDb250YWluZXIgPSAoY29udGFpbmVyOiBFbGVtZW50KSA9PiB7XHJcblx0XHRcdHRoaXMudGFiSGVhZGVyT2JzZXJ2ZXI/Lm9ic2VydmUoY29udGFpbmVyLCB7XHJcblx0XHRcdFx0Y2hpbGRMaXN0OiB0cnVlLFxyXG5cdFx0XHRcdHN1YnRyZWU6IGZhbHNlXHJcblx0XHRcdH0pO1xyXG5cdFx0fTtcclxuXHJcblx0XHQvLyBPYnNlcnZlIGFsbCBleGlzdGluZyBjb250YWluZXJzIGluIGFsbCB3aW5kb3dzXHJcblx0XHRjb25zdCBvYnNlcnZlQWxsV2luZG93cyA9ICgpID0+IHtcclxuXHRcdFx0Y29uc3QgY29udGFpbmVycyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy53b3Jrc3BhY2UtdGFiLWhlYWRlci1jb250YWluZXItaW5uZXInKTtcclxuXHRcdFx0Y29udGFpbmVycy5mb3JFYWNoKG9ic2VydmVDb250YWluZXIpO1xyXG5cclxuXHRcdFx0dGhpcy5wbHVnaW4uYXBwLndvcmtzcGFjZS5pdGVyYXRlQWxsTGVhdmVzKChsZWFmKSA9PiB7XHJcblx0XHRcdFx0Y29uc3QgZG9jID0gbGVhZi52aWV3Py5jb250YWluZXJFbD8ub3duZXJEb2N1bWVudDtcclxuXHRcdFx0XHRpZiAoZG9jICYmIGRvYyAhPT0gZG9jdW1lbnQpIHtcclxuXHRcdFx0XHRcdGNvbnN0IHdpbmRvd0NvbnRhaW5lcnMgPSBkb2MucXVlcnlTZWxlY3RvckFsbCgnLndvcmtzcGFjZS10YWItaGVhZGVyLWNvbnRhaW5lci1pbm5lcicpO1xyXG5cdFx0XHRcdFx0d2luZG93Q29udGFpbmVycy5mb3JFYWNoKG9ic2VydmVDb250YWluZXIpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9O1xyXG5cclxuXHRcdG9ic2VydmVBbGxXaW5kb3dzKCk7XHJcblxyXG5cdFx0Ly8gQWxzbyB3YXRjaCBmb3IgbmV3IGNvbnRhaW5lcnMgYmVpbmcgYWRkZWQgaW4gYWxsIHdpbmRvd3NcclxuXHRcdGNvbnN0IHNldHVwV29ya3NwYWNlT2JzZXJ2ZXIgPSAod2luOiBXaW5kb3cpID0+IHtcclxuXHRcdFx0Y29uc3QgZG9jID0gd2luLmRvY3VtZW50O1xyXG5cdFx0XHRjb25zdCB3b3Jrc3BhY2VPYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKCgpID0+IHtcclxuXHRcdFx0XHRjb25zdCBuZXdDb250YWluZXJzID0gZG9jLnF1ZXJ5U2VsZWN0b3JBbGwoJy53b3Jrc3BhY2UtdGFiLWhlYWRlci1jb250YWluZXItaW5uZXInKTtcclxuXHRcdFx0XHRuZXdDb250YWluZXJzLmZvckVhY2gob2JzZXJ2ZUNvbnRhaW5lcik7XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0Y29uc3QgbWFpbldvcmtzcGFjZSA9IGRvYy5xdWVyeVNlbGVjdG9yKCcud29ya3NwYWNlLXNwbGl0Lm1vZC12ZXJ0aWNhbC5tb2Qtcm9vdCcpO1xyXG5cdFx0XHRpZiAobWFpbldvcmtzcGFjZSkge1xyXG5cdFx0XHRcdHdvcmtzcGFjZU9ic2VydmVyLm9ic2VydmUobWFpbldvcmtzcGFjZSwge1xyXG5cdFx0XHRcdFx0Y2hpbGRMaXN0OiB0cnVlLFxyXG5cdFx0XHRcdFx0c3VidHJlZTogdHJ1ZVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9XHJcblx0XHR9O1xyXG5cclxuXHRcdHNldHVwV29ya3NwYWNlT2JzZXJ2ZXIod2luZG93KTtcclxuXHJcblx0XHQvLyBSZWdpc3RlciBmb3IgZnV0dXJlIHdpbmRvd3NcclxuXHRcdHRoaXMucGx1Z2luLnJlZ2lzdGVyRXZlbnQoXHJcblx0XHRcdHRoaXMucGx1Z2luLmFwcC53b3Jrc3BhY2Uub24oJ3dpbmRvdy1vcGVuJywgKHdpbikgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IGFjdHVhbFdpbmRvdyA9IHdpbi53aW47XHJcblx0XHRcdFx0aWYgKGFjdHVhbFdpbmRvdyBpbnN0YW5jZW9mIFdpbmRvdykge1xyXG5cdFx0XHRcdFx0c2V0dXBXb3Jrc3BhY2VPYnNlcnZlcihhY3R1YWxXaW5kb3cpO1xyXG5cdFx0XHRcdFx0Ly8gUmUtcnVuIG9ic2VydmUgYWxsIHRvIGNhdGNoIGNvbnRhaW5lcnMgaW4gdGhlIG5ldyB3aW5kb3dcclxuXHRcdFx0XHRcdHNldFRpbWVvdXQob2JzZXJ2ZUFsbFdpbmRvd3MsIFdJTkRPV19PUEVOX0NPTlRBSU5FUl9ERUxBWSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9KVxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIFJlbW92ZSB0aGUgc3RpY2t5IGhvbWUgaWNvblxyXG5cdCAqL1xyXG5cdHJlbW92ZSgpOiB2b2lkIHtcclxuXHRcdC8vIENsZWFyIGFueSBwZW5kaW5nIHRhYiBoZWFkZXIgdXBkYXRlc1xyXG5cdFx0aWYgKHRoaXMudGFiSGVhZGVyVXBkYXRlVGltZW91dCkge1xyXG5cdFx0XHRjbGVhclRpbWVvdXQodGhpcy50YWJIZWFkZXJVcGRhdGVUaW1lb3V0KTtcclxuXHRcdFx0dGhpcy50YWJIZWFkZXJVcGRhdGVUaW1lb3V0ID0gbnVsbDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDbGVhciBhbnkgY2hlY2sgaW50ZXJ2YWxzXHJcblx0XHRpZiAodGhpcy5zdGlja3lJY29uRWwgJiYgdGhpcy5zdGlja3lJY29uRWwuX2NoZWNrSW50ZXJ2YWwpIHtcclxuXHRcdFx0Y2xlYXJJbnRlcnZhbCh0aGlzLnN0aWNreUljb25FbC5fY2hlY2tJbnRlcnZhbCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRGlzY29ubmVjdCBjb250YWluZXIgb2JzZXJ2ZXJcclxuXHRcdGlmICh0aGlzLnN0aWNreUljb25FbCAmJiB0aGlzLnN0aWNreUljb25FbC5fY29udGFpbmVyT2JzZXJ2ZXIpIHtcclxuXHRcdFx0dGhpcy5zdGlja3lJY29uRWwuX2NvbnRhaW5lck9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBEaXNjb25uZWN0IHNpZGViYXIgb2JzZXJ2ZXJcclxuXHRcdGlmICh0aGlzLnNpZGViYXJPYnNlcnZlcikge1xyXG5cdFx0XHR0aGlzLnNpZGViYXJPYnNlcnZlci5kaXNjb25uZWN0KCk7XHJcblx0XHRcdHRoaXMuc2lkZWJhck9ic2VydmVyID0gbnVsbDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBEaXNjb25uZWN0IHRhYiBoZWFkZXIgb2JzZXJ2ZXJcclxuXHRcdGlmICh0aGlzLnRhYkhlYWRlck9ic2VydmVyKSB7XHJcblx0XHRcdHRoaXMudGFiSGVhZGVyT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xyXG5cdFx0XHR0aGlzLnRhYkhlYWRlck9ic2VydmVyID0gbnVsbDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBSRVNUT1JFIEVWRVJZVEhJTkcgYmVmb3JlIGZ1bGx5IHJlbW92aW5nXHJcblx0XHQvLyBUaGlzIGVuc3VyZXMgdGFiIGhlYWRlcnMgYXJlIHZpc2libGUgYWdhaW4gYW5kIHdvcmtzcGFjZSBjbGFzc2VzIGFyZSByZW1vdmVkXHJcblx0XHR0aGlzLnVwZGF0ZVdvcmtzcGFjZUNsYXNzKGZhbHNlKTtcclxuXHJcblx0XHR0aGlzLnBsdWdpbi5hcHAud29ya3NwYWNlLml0ZXJhdGVBbGxMZWF2ZXMoKGxlYWYpID0+IHtcclxuXHRcdFx0Ly8gT25seSBwcm9jZXNzIGxlYXZlcyBpbiB0aGUgbWFpbiB3b3Jrc3BhY2UgKG5vdCBzaWRlYmFycylcclxuXHRcdFx0Y29uc3QgdmlldyA9IGxlYWYudmlldztcclxuXHRcdFx0bGV0IGNvbnRhaW5lcjogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcclxuXHJcblx0XHRcdGlmICh2aWV3KSB7XHJcblx0XHRcdFx0Y29uc3Qgdmlld0FueSA9IHZpZXcgYXMgdW5rbm93biBhcyB7IGNvbnRhaW5lckVsPzogSFRNTEVsZW1lbnQgfTtcclxuXHRcdFx0XHRjb250YWluZXIgPSB2aWV3QW55LmNvbnRhaW5lckVsIHx8IG51bGw7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmICghY29udGFpbmVyKSB7XHJcblx0XHRcdFx0Y29uc3QgbGVhZkFueSA9IGxlYWYgYXMgdW5rbm93biBhcyB7IGNvbnRhaW5lckVsPzogSFRNTEVsZW1lbnQgfTtcclxuXHRcdFx0XHRjb250YWluZXIgPSBsZWFmQW55LmNvbnRhaW5lckVsIHx8IG51bGw7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmIChjb250YWluZXIpIHtcclxuXHRcdFx0XHQvLyBDaGVjayBpZiBpdCdzIGluIHRoZSBtYWluIHdvcmtzcGFjZSAocm9vdCwgbm90IHNpZGViYXIpXHJcblx0XHRcdFx0Y29uc3Qgcm9vdFdvcmtzcGFjZSA9IGNvbnRhaW5lci5jbG9zZXN0KCcud29ya3NwYWNlLXNwbGl0Lm1vZC12ZXJ0aWNhbC5tb2Qtcm9vdCcpO1xyXG5cdFx0XHRcdGNvbnN0IGxlZnRTaWRlYmFyID0gY29udGFpbmVyLmNsb3Nlc3QoJy53b3Jrc3BhY2Utc3BsaXQubW9kLWxlZnQtc3BsaXQnKTtcclxuXHRcdFx0XHRjb25zdCByaWdodFNpZGViYXIgPSBjb250YWluZXIuY2xvc2VzdCgnLndvcmtzcGFjZS1zcGxpdC5tb2QtcmlnaHQtc3BsaXQnKTtcclxuXHJcblx0XHRcdFx0Ly8gT25seSBwcm9jZXNzIG1haW4gd29ya3NwYWNlIGxlYXZlc1xyXG5cdFx0XHRcdGlmIChyb290V29ya3NwYWNlICYmICFsZWZ0U2lkZWJhciAmJiAhcmlnaHRTaWRlYmFyKSB7XHJcblx0XHRcdFx0XHRjb25zdCB0YWJIZWFkZXIgPSB0aGlzLmdldFRhYkhlYWRlckZvckxlYWYobGVhZik7XHJcblx0XHRcdFx0XHRpZiAodGFiSGVhZGVyKSB7XHJcblx0XHRcdFx0XHRcdHRhYkhlYWRlci5jbGFzc0xpc3QucmVtb3ZlKCdpcy1ob21lLWJhc2UtdGFiJyk7XHJcblx0XHRcdFx0XHRcdHRhYkhlYWRlci5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtaG9tZS1iYXNlLWdob3N0Jyk7XHJcblx0XHRcdFx0XHRcdHRhYkhlYWRlci5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJyk7XHJcblxyXG5cdFx0XHRcdFx0XHRjb25zdCB0YWJIZWFkZXJFeHRlbmRlZCA9IHRhYkhlYWRlciBhcyBUYWJIZWFkZXJFbGVtZW50O1xyXG5cdFx0XHRcdFx0XHRpZiAodGFiSGVhZGVyRXh0ZW5kZWQuX2hvbWVCYXNlUGFyZW50ICYmICF0YWJIZWFkZXJFeHRlbmRlZC5faG9tZUJhc2VQYXJlbnQuY29udGFpbnModGFiSGVhZGVyKSkge1xyXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHBhcmVudCA9IHRhYkhlYWRlckV4dGVuZGVkLl9ob21lQmFzZVBhcmVudDtcclxuXHRcdFx0XHRcdFx0XHRjb25zdCBuZXh0U2libGluZyA9IHRhYkhlYWRlckV4dGVuZGVkLl9ob21lQmFzZU5leHRTaWJsaW5nO1xyXG5cdFx0XHRcdFx0XHRcdGlmIChwYXJlbnQpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmIChuZXh0U2libGluZyAmJiBuZXh0U2libGluZy5wYXJlbnRFbGVtZW50ID09PSBwYXJlbnQpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cGFyZW50Lmluc2VydEJlZm9yZSh0YWJIZWFkZXIsIG5leHRTaWJsaW5nKTtcclxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHBhcmVudC5hcHBlbmRDaGlsZCh0YWJIZWFkZXIpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRkZWxldGUgdGFiSGVhZGVyRXh0ZW5kZWQuX2hvbWVCYXNlUGFyZW50O1xyXG5cdFx0XHRcdFx0XHRcdGRlbGV0ZSB0YWJIZWFkZXJFeHRlbmRlZC5faG9tZUJhc2VOZXh0U2libGluZztcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0aWYgKHRoaXMuc3RpY2t5SWNvbkVsKSB7XHJcblx0XHRcdC8vIE9ubHkgcmVtb3ZlIGlmIGl0J3MgYWN0dWFsbHkgaW4gdGhlIERPTVxyXG5cdFx0XHRpZiAodGhpcy5zdGlja3lJY29uRWwucGFyZW50RWxlbWVudCkge1xyXG5cdFx0XHRcdHRoaXMuc3RpY2t5SWNvbkVsLnJlbW92ZSgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHRoaXMuc3RpY2t5SWNvbkVsID0gbnVsbDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBBbHNvIGNsZWFuIHVwIGFueSBvcnBoYW5lZCBpY29ucyBpbiBhbGwgd2luZG93c1xyXG5cdFx0Y29uc3QgY2xlYW51cE9ycGhhbnMgPSAoZG9jOiBEb2N1bWVudCkgPT4ge1xyXG5cdFx0XHRkb2MucXVlcnlTZWxlY3RvckFsbChgLiR7U1RJQ0tZX0lDT05fQ0xBU1N9YCkuZm9yRWFjaChlbCA9PiB7XHJcblx0XHRcdFx0Y29uc3Qgc3RpY2t5RWwgPSBlbCBhcyBTdGlja3lJY29uRWxlbWVudDtcclxuXHRcdFx0XHRpZiAoc3RpY2t5RWwuX2NoZWNrSW50ZXJ2YWwpIHtcclxuXHRcdFx0XHRcdGNsZWFySW50ZXJ2YWwoc3RpY2t5RWwuX2NoZWNrSW50ZXJ2YWwpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoc3RpY2t5RWwuX2NvbnRhaW5lck9ic2VydmVyKSB7XHJcblx0XHRcdFx0XHRzdGlja3lFbC5fY29udGFpbmVyT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRlbC5yZW1vdmUoKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9O1xyXG5cclxuXHRcdGNsZWFudXBPcnBoYW5zKGRvY3VtZW50KTtcclxuXHRcdHRoaXMucGx1Z2luLmFwcC53b3Jrc3BhY2UuaXRlcmF0ZUFsbExlYXZlcygobGVhZikgPT4ge1xyXG5cdFx0XHRjb25zdCBkb2MgPSBsZWFmLnZpZXc/LmNvbnRhaW5lckVsPy5vd25lckRvY3VtZW50O1xyXG5cdFx0XHRpZiAoZG9jICYmIGRvYyAhPT0gZG9jdW1lbnQpIHtcclxuXHRcdFx0XHRjbGVhbnVwT3JwaGFucyhkb2MpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIFVwZGF0ZSB0aGUgYWN0aXZlIHN0YXRlIG9mIHRoZSBzdGlja3kgaWNvblxyXG5cdCAqL1xyXG5cdHVwZGF0ZUFjdGl2ZVN0YXRlKCk6IHZvaWQge1xyXG5cdFx0aWYgKCF0aGlzLnN0aWNreUljb25FbCkgcmV0dXJuO1xyXG5cclxuXHRcdGNvbnN0IGlzQWN0aXZlID0gdGhpcy5wbHVnaW4uaG9tZVNlcnZpY2UuaXNGb2N1c2VkT25Ib21lQmFzZSgpO1xyXG5cclxuXHRcdGlmIChpc0FjdGl2ZSkge1xyXG5cdFx0XHR0aGlzLnN0aWNreUljb25FbC5jbGFzc0xpc3QuYWRkKFNUSUNLWV9JQ09OX0FDVElWRV9DTEFTUyk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0aGlzLnN0aWNreUljb25FbC5jbGFzc0xpc3QucmVtb3ZlKFNUSUNLWV9JQ09OX0FDVElWRV9DTEFTUyk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQWxzbyB1cGRhdGUgdGFiIGhlYWRlcnMgd2hlbiBhY3RpdmUgc3RhdGUgY2hhbmdlcyAoZGVib3VuY2VkKVxyXG5cdFx0dGhpcy51cGRhdGVUYWJIZWFkZXJzKCk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBDaGVjayBpZiB0aGUgbGVmdCBzaWRlYmFyIGlzIGNvbGxhcHNlZFxyXG5cdCAqIEJhc2VkIG9uIG9ic2lkaWFuLW94eWdlbi1zZXR0aW5ncyBpbXBsZW1lbnRhdGlvblxyXG5cdCAqL1xyXG5cdHByaXZhdGUgaXNMZWZ0U2lkZWJhckNvbGxhcHNlZCgpOiBib29sZWFuIHtcclxuXHRcdC8vIFVzZSB0aGUgY29ycmVjdCBzZWxlY3RvciBmb3IgbGVmdCBzaWRlYmFyXHJcblx0XHRjb25zdCBsZWZ0U2lkZWJhciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy53b3Jrc3BhY2Utc3BsaXQubW9kLWxlZnQtc3BsaXQnKSB8fFxyXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kLWxlZnQtc3BsaXQnKTtcclxuXHJcblx0XHRpZiAoIWxlZnRTaWRlYmFyKSByZXR1cm4gZmFsc2U7XHJcblxyXG5cdFx0Ly8gQ2hlY2sgZm9yIHRoZSBpcy1zaWRlZG9jay1jb2xsYXBzZWQgY2xhc3MgLSB0aGlzIGlzIHRoZSBtb3N0IHJlbGlhYmxlIGluZGljYXRvclxyXG5cdFx0cmV0dXJuIGxlZnRTaWRlYmFyLmNsYXNzTGlzdC5jb250YWlucygnaXMtc2lkZWRvY2stY29sbGFwc2VkJyk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBVcGRhdGUgaWNvbiBwb3NpdGlvbiBiYXNlZCBvbiBzaWRlYmFyIHN0YXRlXHJcblx0ICogTm90ZTogV2l0aCBpbmxpbmUgcG9zaXRpb25pbmcsIGljb24gZmxvd3MgbmF0dXJhbGx5IHdpdGggdGFicywgc28gbm8gc3BlY2lhbCBwb3NpdGlvbmluZyBuZWVkZWRcclxuXHQgKi9cclxuXHR1cGRhdGVJY29uUG9zaXRpb25Gb3JTaWRlYmFyKCk6IHZvaWQge1xyXG5cdFx0Ly8gSWNvbiBub3cgZmxvd3MgbmF0dXJhbGx5IHdpdGggdGFicywgbm8gc3BlY2lhbCBwb3NpdGlvbmluZyBuZWVkZWRcclxuXHRcdC8vIFRoaXMgbWV0aG9kIGlzIGtlcHQgZm9yIHBvdGVudGlhbCBmdXR1cmUgdXNlIGJ1dCBjdXJyZW50bHkgZG9lcyBub3RoaW5nXHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBVcGRhdGUgaWNvbiB2aXNpYmlsaXR5IGJhc2VkIG9uIHRhYiBiYXIgdmlzaWJpbGl0eVxyXG5cdCAqIFJFTU9WRUQ6IEphdmFTY3JpcHQtYmFzZWQgdmlzaWJpbGl0eSBjaGVja2luZyB3YXMgY2F1c2luZyBpc3N1ZXNcclxuXHQgKiBOb3cgcmVsaWVzIGVudGlyZWx5IG9uIENTUyB3aGljaCBpcyBtb3JlIHJlbGlhYmxlXHJcblx0ICovXHJcblx0dXBkYXRlSWNvblZpc2liaWxpdHkoKTogdm9pZCB7XHJcblx0XHQvLyBEbyBub3RoaW5nIC0gbGV0IENTUyBoYW5kbGUgYWxsIHZpc2liaWxpdHlcclxuXHRcdC8vIFRoZSBpY29uIGlzIGluc2lkZSB0aGUgdGFiIGNvbnRhaW5lciwgc28gaXQgd2lsbCBoaWRlIGF1dG9tYXRpY2FsbHlcclxuXHRcdC8vIHdoZW4gdGhlIGNvbnRhaW5lciBpcyBoaWRkZW4gYnkgYW55IHRoZW1lL3BsdWdpblxyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogV2F0Y2ggZm9yIHNpZGViYXIgc3RhdGUgY2hhbmdlcyBhbmQgdXBkYXRlIGljb24gcG9zaXRpb25cclxuXHQgKiBCYXNlZCBvbiBvYnNpZGlhbi1veHlnZW4tc2V0dGluZ3MgaW1wbGVtZW50YXRpb25cclxuXHQgKi9cclxuXHRwcml2YXRlIHdhdGNoU2lkZWJhclN0YXRlKCk6IHZvaWQge1xyXG5cdFx0aWYgKHRoaXMuc2lkZWJhck9ic2VydmVyKSB7XHJcblx0XHRcdHRoaXMuc2lkZWJhck9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBsZWZ0U2lkZWJhciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy53b3Jrc3BhY2Utc3BsaXQubW9kLWxlZnQtc3BsaXQnKSB8fFxyXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kLWxlZnQtc3BsaXQnKTtcclxuXHJcblx0XHRpZiAoIWxlZnRTaWRlYmFyKSByZXR1cm47XHJcblxyXG5cdFx0Ly8gV2F0Y2ggZm9yIGNsYXNzIGNoYW5nZXMgb24gdGhlIHNpZGViYXIgZWxlbWVudFxyXG5cdFx0dGhpcy5zaWRlYmFyT2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigobXV0YXRpb25zKSA9PiB7XHJcblx0XHRcdGxldCBzaG91bGRVcGRhdGUgPSBmYWxzZTtcclxuXHRcdFx0bXV0YXRpb25zLmZvckVhY2goKG11dGF0aW9uKSA9PiB7XHJcblx0XHRcdFx0aWYgKG11dGF0aW9uLnR5cGUgPT09ICdhdHRyaWJ1dGVzJyAmJiBtdXRhdGlvbi5hdHRyaWJ1dGVOYW1lID09PSAnY2xhc3MnKSB7XHJcblx0XHRcdFx0XHRzaG91bGRVcGRhdGUgPSB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHRcdGlmIChzaG91bGRVcGRhdGUpIHtcclxuXHRcdFx0XHR0aGlzLnVwZGF0ZUljb25Qb3NpdGlvbkZvclNpZGViYXIoKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5zaWRlYmFyT2JzZXJ2ZXIub2JzZXJ2ZShsZWZ0U2lkZWJhciwge1xyXG5cdFx0XHRhdHRyaWJ1dGVzOiB0cnVlLFxyXG5cdFx0XHRhdHRyaWJ1dGVGaWx0ZXI6IFsnY2xhc3MnXSxcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogV2F0Y2ggZm9yIHRhYiBiYXIgdmlzaWJpbGl0eSBjaGFuZ2VzIChPeHlnZW4gdGhlbWUgYXV0by1oaWRlLCBmb2N1cyBtb2RlLCBldGMuKVxyXG5cdCAqIFJFTU9WRUQ6IE5vIGxvbmdlciBuZWVkZWQgLSBDU1MgaGFuZGxlcyBhbGwgdmlzaWJpbGl0eSBhdXRvbWF0aWNhbGx5XHJcblx0ICovXHJcblx0cHJpdmF0ZSB3YXRjaFRhYkJhclZpc2liaWxpdHkoKTogdm9pZCB7XHJcblx0XHQvLyBEbyBub3RoaW5nIC0gQ1NTIGhhbmRsZXMgYWxsIHZpc2liaWxpdHlcclxuXHRcdC8vIFRoZSBpY29uIGlzIGluc2lkZSB0aGUgdGFiIGNvbnRhaW5lciwgc28gaXQgaGlkZXMgYXV0b21hdGljYWxseVxyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogVG9nZ2xlIHRoZSBzdGlja3kgaWNvbiB2aXNpYmlsaXR5XHJcblx0ICovXHJcblx0YXN5bmMgdG9nZ2xlKCk6IFByb21pc2U8dm9pZD4ge1xyXG5cdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hvd1N0aWNreUhvbWVJY29uID0gIXRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dTdGlja3lIb21lSWNvbjtcclxuXHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0dGhpcy51cGRhdGUoKTtcclxuXHRcdC8vIFVwZGF0ZSB0YWIgaGVhZGVycyB3aGVuIHRvZ2dsaW5nIHN0aWNreSBpY29uXHJcblx0XHR0aGlzLnVwZGF0ZVRhYkhlYWRlcnMoKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIFVwZGF0ZSB0YWIgaGVhZGVycyB0byBoaWRlL3Nob3cgZ2hvc3QgdGFiXHJcblx0ICogT25seSB3b3JrcyB3aGVuIHN0aWNreSBpY29uIGlzIGVuYWJsZWRcclxuXHQgKiBSZW1vdmVkIGRlYm91bmNlIC0gbXVzdCBiZSBpbW1lZGlhdGUgdG8gcHJldmVudCBmbGFzaFxyXG5cdCAqL1xyXG5cdHVwZGF0ZVRhYkhlYWRlcnMoKTogdm9pZCB7XHJcblx0XHQvLyBDbGVhciBhbnkgcGVuZGluZyB1cGRhdGVcclxuXHRcdGlmICh0aGlzLnRhYkhlYWRlclVwZGF0ZVRpbWVvdXQpIHtcclxuXHRcdFx0Y2xlYXJUaW1lb3V0KHRoaXMudGFiSGVhZGVyVXBkYXRlVGltZW91dCk7XHJcblx0XHRcdHRoaXMudGFiSGVhZGVyVXBkYXRlVGltZW91dCA9IG51bGw7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRXhlY3V0ZSBpbW1lZGlhdGVseSAtIG5vIGRlYm91bmNlIHRvIHByZXZlbnQgZmxhc2hcclxuXHRcdHRoaXMuX2RvVXBkYXRlVGFiSGVhZGVycygpO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogSW50ZXJuYWwgbWV0aG9kIHRoYXQgYWN0dWFsbHkgdXBkYXRlcyB0aGUgdGFiIGhlYWRlcnNcclxuXHQgKi9cclxuXHRwcml2YXRlIF9kb1VwZGF0ZVRhYkhlYWRlcnMoKTogdm9pZCB7XHJcblx0XHQvLyBPbmx5IGhpZGUgZ2hvc3QgdGFiIGlmIEJPVEggc3RpY2t5IGljb24gQU5EIGhpZGUgdGFiIGhlYWRlciBhcmUgZW5hYmxlZFxyXG5cdFx0aWYgKCF0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93U3RpY2t5SG9tZUljb24gfHwgIXRoaXMucGx1Z2luLnNldHRpbmdzLmhpZGVIb21lVGFiSGVhZGVyKSB7XHJcblx0XHRcdC8vIFJlbW92ZSBhbGwgaG9tZSBiYXNlIHRhYiBjbGFzc2VzIGZyb20gQUxMIHdpbmRvd3NcclxuXHRcdFx0dGhpcy5wbHVnaW4uYXBwLndvcmtzcGFjZS5pdGVyYXRlQWxsTGVhdmVzKChsZWFmKSA9PiB7XHJcblx0XHRcdFx0Y29uc3QgdGFiSGVhZGVyID0gdGhpcy5nZXRUYWJIZWFkZXJGb3JMZWFmKGxlYWYpO1xyXG5cdFx0XHRcdGlmICh0YWJIZWFkZXIpIHtcclxuXHRcdFx0XHRcdHRhYkhlYWRlci5jbGFzc0xpc3QucmVtb3ZlKCdpcy1ob21lLWJhc2UtdGFiJyk7XHJcblx0XHRcdFx0XHR0YWJIZWFkZXIucmVtb3ZlQXR0cmlidXRlKCdkYXRhLWhvbWUtYmFzZS1naG9zdCcpO1xyXG5cdFx0XHRcdFx0dGFiSGVhZGVyLnJlbW92ZUF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nKTtcclxuXHJcblx0XHRcdFx0XHRjb25zdCB0YWJIZWFkZXJFeHRlbmRlZCA9IHRhYkhlYWRlciBhcyBUYWJIZWFkZXJFbGVtZW50O1xyXG5cdFx0XHRcdFx0aWYgKHRhYkhlYWRlckV4dGVuZGVkLl9ob21lQmFzZVBhcmVudCAmJiAhdGFiSGVhZGVyRXh0ZW5kZWQuX2hvbWVCYXNlUGFyZW50LmNvbnRhaW5zKHRhYkhlYWRlcikpIHtcclxuXHRcdFx0XHRcdFx0Y29uc3QgcGFyZW50ID0gdGFiSGVhZGVyRXh0ZW5kZWQuX2hvbWVCYXNlUGFyZW50O1xyXG5cdFx0XHRcdFx0XHRjb25zdCBuZXh0U2libGluZyA9IHRhYkhlYWRlckV4dGVuZGVkLl9ob21lQmFzZU5leHRTaWJsaW5nO1xyXG5cdFx0XHRcdFx0XHRpZiAocGFyZW50KSB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKG5leHRTaWJsaW5nICYmIG5leHRTaWJsaW5nLnBhcmVudEVsZW1lbnQgPT09IHBhcmVudCkge1xyXG5cdFx0XHRcdFx0XHRcdFx0cGFyZW50Lmluc2VydEJlZm9yZSh0YWJIZWFkZXIsIG5leHRTaWJsaW5nKTtcclxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdFx0cGFyZW50LmFwcGVuZENoaWxkKHRhYkhlYWRlcik7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGRlbGV0ZSB0YWJIZWFkZXJFeHRlbmRlZC5faG9tZUJhc2VQYXJlbnQ7XHJcblx0XHRcdFx0XHRcdGRlbGV0ZSB0YWJIZWFkZXJFeHRlbmRlZC5faG9tZUJhc2VOZXh0U2libGluZztcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ1JJVElDQUw6IFJlbW92ZSBnaG9zdCB0YWIgaGVhZGVycyBTWU5DSFJPTk9VU0xZIGJlZm9yZSBhbnkgYW5pbWF0aW9uIGZyYW1lc1xyXG5cdFx0Ly8gVGhpcyBwcmV2ZW50cyB0aGVtIGZyb20gYnJpZWZseSBhcHBlYXJpbmcgd2hlbiB0YWJzIGNoYW5nZVxyXG5cdFx0Y29uc3QgZ2hvc3RUYWJIZWFkZXJzVG9SZW1vdmU6IEFycmF5PHsgdGFiSGVhZGVyOiBIVE1MRWxlbWVudDsgbGVhZjogV29ya3NwYWNlTGVhZiB9PiA9IFtdO1xyXG5cclxuXHRcdHRoaXMucGx1Z2luLmFwcC53b3Jrc3BhY2UuaXRlcmF0ZUFsbExlYXZlcygobGVhZikgPT4ge1xyXG5cdFx0XHQvLyBPbmx5IHByb2Nlc3MgbGVhdmVzIGluIHRoZSBtYWluIHdvcmtzcGFjZSAobm90IHNpZGViYXJzKVxyXG5cdFx0XHRjb25zdCB2aWV3ID0gbGVhZi52aWV3O1xyXG5cdFx0XHRsZXQgY29udGFpbmVyOiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsO1xyXG5cclxuXHRcdFx0aWYgKHZpZXcpIHtcclxuXHRcdFx0XHRjb25zdCB2aWV3QW55ID0gdmlldyBhcyB1bmtub3duIGFzIHsgY29udGFpbmVyRWw/OiBIVE1MRWxlbWVudCB9O1xyXG5cdFx0XHRcdGNvbnRhaW5lciA9IHZpZXdBbnkuY29udGFpbmVyRWwgfHwgbnVsbDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKCFjb250YWluZXIpIHtcclxuXHRcdFx0XHRjb25zdCBsZWFmQW55ID0gbGVhZiBhcyB1bmtub3duIGFzIHsgY29udGFpbmVyRWw/OiBIVE1MRWxlbWVudCB9O1xyXG5cdFx0XHRcdGNvbnRhaW5lciA9IGxlYWZBbnkuY29udGFpbmVyRWwgfHwgbnVsbDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKGNvbnRhaW5lcikge1xyXG5cdFx0XHRcdC8vIENoZWNrIGlmIGl0J3MgaW4gdGhlIG1haW4gd29ya3NwYWNlIChyb290LCBub3Qgc2lkZWJhcilcclxuXHRcdFx0XHRjb25zdCByb290V29ya3NwYWNlID0gY29udGFpbmVyLmNsb3Nlc3QoJy53b3Jrc3BhY2Utc3BsaXQubW9kLXZlcnRpY2FsLm1vZC1yb290Jyk7XHJcblx0XHRcdFx0Y29uc3QgbGVmdFNpZGViYXIgPSBjb250YWluZXIuY2xvc2VzdCgnLndvcmtzcGFjZS1zcGxpdC5tb2QtbGVmdC1zcGxpdCcpO1xyXG5cdFx0XHRcdGNvbnN0IHJpZ2h0U2lkZWJhciA9IGNvbnRhaW5lci5jbG9zZXN0KCcud29ya3NwYWNlLXNwbGl0Lm1vZC1yaWdodC1zcGxpdCcpO1xyXG5cclxuXHRcdFx0XHQvLyBPbmx5IHByb2Nlc3MgbWFpbiB3b3Jrc3BhY2UgbGVhdmVzXHJcblx0XHRcdFx0aWYgKHJvb3RXb3Jrc3BhY2UgJiYgIWxlZnRTaWRlYmFyICYmICFyaWdodFNpZGViYXIpIHtcclxuXHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5ob21lU2VydmljZS5pc0dob3N0TGVhZihsZWFmKSkge1xyXG5cdFx0XHRcdFx0XHRjb25zdCB0YWJIZWFkZXIgPSB0aGlzLmdldFRhYkhlYWRlckZvckxlYWYobGVhZik7XHJcblx0XHRcdFx0XHRcdGlmICh0YWJIZWFkZXIgJiYgdGFiSGVhZGVyLnBhcmVudEVsZW1lbnQpIHtcclxuXHRcdFx0XHRcdFx0XHRnaG9zdFRhYkhlYWRlcnNUb1JlbW92ZS5wdXNoKHsgdGFiSGVhZGVyLCBsZWFmIH0pO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHQvLyBSZW1vdmUgYWxsIGdob3N0IHRhYiBoZWFkZXJzIHN5bmNocm9ub3VzbHkgQkVGT1JFIGFueSByZW5kZXJpbmdcclxuXHRcdGdob3N0VGFiSGVhZGVyc1RvUmVtb3ZlLmZvckVhY2goKHsgdGFiSGVhZGVyIH0pID0+IHtcclxuXHRcdFx0Y29uc3QgcGFyZW50ID0gdGFiSGVhZGVyLnBhcmVudEVsZW1lbnQ7XHJcblx0XHRcdGlmIChwYXJlbnQgJiYgcGFyZW50LmNsYXNzTGlzdC5jb250YWlucygnd29ya3NwYWNlLXRhYi1oZWFkZXItY29udGFpbmVyLWlubmVyJykpIHtcclxuXHRcdFx0XHRjb25zdCB0YWJIZWFkZXJFeHRlbmRlZCA9IHRhYkhlYWRlciBhcyBUYWJIZWFkZXJFbGVtZW50O1xyXG5cdFx0XHRcdC8vIE9ubHkgcmVtb3ZlIGlmIG5vdCBhbHJlYWR5IHJlbW92ZWRcclxuXHRcdFx0XHRpZiAocGFyZW50LmNvbnRhaW5zKHRhYkhlYWRlcikpIHtcclxuXHRcdFx0XHRcdHRhYkhlYWRlckV4dGVuZGVkLl9ob21lQmFzZVBhcmVudCA9IHBhcmVudDtcclxuXHRcdFx0XHRcdHRhYkhlYWRlckV4dGVuZGVkLl9ob21lQmFzZU5leHRTaWJsaW5nID0gdGFiSGVhZGVyLm5leHRTaWJsaW5nO1xyXG5cdFx0XHRcdFx0dGFiSGVhZGVyLnJlbW92ZSgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gTm93IHVwZGF0ZSBvdGhlciB0YWIgaGVhZGVycyBpbiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgKG5vbi1jcml0aWNhbClcclxuXHRcdHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcblx0XHRcdGNvbnN0IGhvbWVCYXNlU2V0dGluZ3MgPSB0aGlzLnBsdWdpbi5nZXRIb21lQmFzZVNldHRpbmdzKCk7XHJcblx0XHRcdGNvbnN0IGhvbWVCYXNlUGF0aCA9IHJlc29sdmVQYXRoU3luYyhob21lQmFzZVNldHRpbmdzLnR5cGUsIGhvbWVCYXNlU2V0dGluZ3MudmFsdWUsIHRoaXMucGx1Z2luLmFwcCk7XHJcblxyXG5cdFx0XHQvLyBSZXN0b3JlIGFueSBub24tZ2hvc3QgdGFicyB0aGF0IHdlcmUgaW5jb3JyZWN0bHkgcmVtb3ZlZFxyXG5cdFx0XHR0aGlzLnBsdWdpbi5hcHAud29ya3NwYWNlLml0ZXJhdGVBbGxMZWF2ZXMoKGxlYWYpID0+IHtcclxuXHRcdFx0XHQvLyBPbmx5IHByb2Nlc3MgbGVhdmVzIGluIHRoZSBtYWluIHdvcmtzcGFjZSAobm90IHNpZGViYXJzKVxyXG5cdFx0XHRcdGNvbnN0IHZpZXcgPSBsZWFmLnZpZXc7XHJcblx0XHRcdFx0bGV0IGNvbnRhaW5lcjogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcclxuXHJcblx0XHRcdFx0aWYgKHZpZXcpIHtcclxuXHRcdFx0XHRcdGNvbnN0IHZpZXdBbnkgPSB2aWV3IGFzIHVua25vd24gYXMgeyBjb250YWluZXJFbD86IEhUTUxFbGVtZW50IH07XHJcblx0XHRcdFx0XHRjb250YWluZXIgPSB2aWV3QW55LmNvbnRhaW5lckVsIHx8IG51bGw7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoIWNvbnRhaW5lcikge1xyXG5cdFx0XHRcdFx0Y29uc3QgbGVhZkFueSA9IGxlYWYgYXMgdW5rbm93biBhcyB7IGNvbnRhaW5lckVsPzogSFRNTEVsZW1lbnQgfTtcclxuXHRcdFx0XHRcdGNvbnRhaW5lciA9IGxlYWZBbnkuY29udGFpbmVyRWwgfHwgbnVsbDtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGlmIChjb250YWluZXIpIHtcclxuXHRcdFx0XHRcdC8vIENoZWNrIGlmIGl0J3MgaW4gdGhlIG1haW4gd29ya3NwYWNlIChyb290LCBub3Qgc2lkZWJhcilcclxuXHRcdFx0XHRcdGNvbnN0IHJvb3RXb3Jrc3BhY2UgPSBjb250YWluZXIuY2xvc2VzdCgnLndvcmtzcGFjZS1zcGxpdC5tb2QtdmVydGljYWwubW9kLXJvb3QnKTtcclxuXHRcdFx0XHRcdGNvbnN0IGxlZnRTaWRlYmFyID0gY29udGFpbmVyLmNsb3Nlc3QoJy53b3Jrc3BhY2Utc3BsaXQubW9kLWxlZnQtc3BsaXQnKTtcclxuXHRcdFx0XHRcdGNvbnN0IHJpZ2h0U2lkZWJhciA9IGNvbnRhaW5lci5jbG9zZXN0KCcud29ya3NwYWNlLXNwbGl0Lm1vZC1yaWdodC1zcGxpdCcpO1xyXG5cclxuXHRcdFx0XHRcdC8vIE9ubHkgcHJvY2VzcyBtYWluIHdvcmtzcGFjZSBsZWF2ZXNcclxuXHRcdFx0XHRcdGlmIChyb290V29ya3NwYWNlICYmICFsZWZ0U2lkZWJhciAmJiAhcmlnaHRTaWRlYmFyKSB7XHJcblx0XHRcdFx0XHRcdGNvbnN0IGlzR2hvc3RUYWIgPSB0aGlzLnBsdWdpbi5ob21lU2VydmljZS5pc0dob3N0TGVhZihsZWFmKTtcclxuXHRcdFx0XHRcdFx0Y29uc3QgdGFiSGVhZGVyID0gdGhpcy5nZXRUYWJIZWFkZXJGb3JMZWFmKGxlYWYpO1xyXG5cdFx0XHRcdFx0XHRpZiAoIXRhYkhlYWRlcikgcmV0dXJuO1xyXG5cclxuXHRcdFx0XHRcdFx0Y29uc3QgdGFiSGVhZGVyRXh0ZW5kZWQgPSB0YWJIZWFkZXIgYXMgVGFiSGVhZGVyRWxlbWVudDtcclxuXHRcdFx0XHRcdFx0Y29uc3QgaXNSZW1vdmVkID0gdGFiSGVhZGVyRXh0ZW5kZWQuX2hvbWVCYXNlUGFyZW50ICYmICF0YWJIZWFkZXJFeHRlbmRlZC5faG9tZUJhc2VQYXJlbnQuY29udGFpbnModGFiSGVhZGVyKTtcclxuXHJcblx0XHRcdFx0XHRcdGlmICghaXNHaG9zdFRhYikge1xyXG5cdFx0XHRcdFx0XHRcdC8vIE5vdCBhIGdob3N0IHRhYiAtIHJlc3RvcmUgaWYgaXQgd2FzIHJlbW92ZWRcclxuXHRcdFx0XHRcdFx0XHRpZiAoaXNSZW1vdmVkKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBwYXJlbnQgPSB0YWJIZWFkZXJFeHRlbmRlZC5faG9tZUJhc2VQYXJlbnQ7XHJcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBuZXh0U2libGluZyA9IHRhYkhlYWRlckV4dGVuZGVkLl9ob21lQmFzZU5leHRTaWJsaW5nO1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHBhcmVudCkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAobmV4dFNpYmxpbmcgJiYgbmV4dFNpYmxpbmcucGFyZW50RWxlbWVudCA9PT0gcGFyZW50KSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0cGFyZW50Lmluc2VydEJlZm9yZSh0YWJIZWFkZXIsIG5leHRTaWJsaW5nKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRwYXJlbnQuYXBwZW5kQ2hpbGQodGFiSGVhZGVyKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRkZWxldGUgdGFiSGVhZGVyRXh0ZW5kZWQuX2hvbWVCYXNlUGFyZW50O1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRkZWxldGUgdGFiSGVhZGVyRXh0ZW5kZWQuX2hvbWVCYXNlTmV4dFNpYmxpbmc7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyBDaGVjayBpZiB0aGlzIGlzIGEgbm9ybWFsIGhvbWUgYmFzZSB0YWIgKG5vdCBnaG9zdCkgdG8gYXBwbHkgYWN0aXZlIHN0YXRlIHN0eWxpbmcgaWYgbmVlZGVkXHJcblx0XHRcdFx0XHRcdFx0Ly8gV2Ugb25seSBkbyB0aGlzIGlmIHdlIGhhdmUgYSBwYXRoIHRvIGNvbXBhcmUgYWdhaW5zdCAob3IgaWYgaXQncyBhIGdyYXBoIHZpZXcpXHJcblx0XHRcdFx0XHRcdFx0Y29uc3QgaXNHcmFwaEhvbWUgPSBob21lQmFzZVNldHRpbmdzLnR5cGUgPT09IEhvbWVCYXNlVHlwZS5HcmFwaCAmJiBsZWFmLnZpZXc/LmdldFZpZXdUeXBlKCkgPT09ICdncmFwaCc7XHJcblx0XHRcdFx0XHRcdFx0aWYgKChob21lQmFzZVBhdGggJiYgbGVhZkhhc0ZpbGUobGVhZiwgaG9tZUJhc2VQYXRoKSkgfHwgaXNHcmFwaEhvbWUpIHtcclxuXHRcdFx0XHRcdFx0XHRcdHRhYkhlYWRlci5jbGFzc0xpc3QuYWRkKCdpcy1ob21lLWJhc2UtdGFiJyk7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdHRhYkhlYWRlci5jbGFzc0xpc3QucmVtb3ZlKCdpcy1ob21lLWJhc2UtdGFiJyk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0XHR0YWJIZWFkZXIucmVtb3ZlQXR0cmlidXRlKCdkYXRhLWhvbWUtYmFzZS1naG9zdCcpO1xyXG5cdFx0XHRcdFx0XHRcdHRhYkhlYWRlci5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgdGhlIHRhYiBoZWFkZXIgZWxlbWVudCBmb3IgYSBnaXZlbiBsZWFmXHJcblx0ICovXHJcblx0cHJpdmF0ZSBnZXRUYWJIZWFkZXJGb3JMZWFmKGxlYWY6IFdvcmtzcGFjZUxlYWYpOiBIVE1MRWxlbWVudCB8IG51bGwge1xyXG5cdFx0Ly8gVHJ5IHRvIGdldCBmcm9tIGxlYWYncyBpbnRlcm5hbCBwcm9wZXJ0eSBmaXJzdCAoaWYgYXZhaWxhYmxlKVxyXG5cdFx0Y29uc3QgbGVhZkFueSA9IGxlYWYgYXMgdW5rbm93biBhcyB7IHRhYkhlYWRlckVsPzogSFRNTEVsZW1lbnQgfTtcclxuXHRcdGlmIChsZWFmQW55LnRhYkhlYWRlckVsKSB7XHJcblx0XHRcdHJldHVybiBsZWFmQW55LnRhYkhlYWRlckVsO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEZhbGxiYWNrOiBmaW5kIGJ5IHF1ZXJ5aW5nIERPTSB3aXRoaW4gdGhlIGxlYWYncyB3aW5kb3dcclxuXHRcdGNvbnN0IHZpZXdUeXBlID0gbGVhZi52aWV3Py5nZXRWaWV3VHlwZSgpO1xyXG5cdFx0aWYgKCF2aWV3VHlwZSkgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0Ly8gR2V0IHRoZSBkb2N1bWVudCBmb3IgdGhpcyBsZWFmXHJcblx0XHRjb25zdCBkb2MgPSBsZWFmLnZpZXc/LmNvbnRhaW5lckVsPy5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50O1xyXG5cclxuXHRcdC8vIEdldCB0aGUgYWN0aXZlIGxlYWYgdG8gaGVscCB3aXRoIG1hdGNoaW5nXHJcblx0XHRjb25zdCBhY3RpdmVMZWFmID0gdGhpcy5wbHVnaW4uYXBwLndvcmtzcGFjZS5nZXRNb3N0UmVjZW50TGVhZigpO1xyXG5cdFx0Y29uc3QgaXNBY3RpdmUgPSBsZWFmID09PSBhY3RpdmVMZWFmO1xyXG5cclxuXHRcdC8vIEZpbmQgYWxsIHRhYiBoZWFkZXJzIHdpdGggbWF0Y2hpbmcgdmlldyB0eXBlIGluIFRISVMgd2luZG93XHJcblx0XHRjb25zdCB0YWJIZWFkZXJzID0gZG9jLnF1ZXJ5U2VsZWN0b3JBbGwoYC53b3Jrc3BhY2UtdGFiLWhlYWRlcltkYXRhLXR5cGU9XCIke3ZpZXdUeXBlfVwiXWApO1xyXG5cclxuXHRcdC8vIElmIHRoaXMgaXMgdGhlIGFjdGl2ZSBsZWFmLCBwcmVmZXIgdGhlIGFjdGl2ZSB0YWIgaGVhZGVyIGluIFRISVMgd2luZG93XHJcblx0XHRpZiAoaXNBY3RpdmUpIHtcclxuXHRcdFx0Y29uc3QgYWN0aXZlSGVhZGVyID0gZG9jLnF1ZXJ5U2VsZWN0b3IoJy53b3Jrc3BhY2UtdGFiLWhlYWRlci5pcy1hY3RpdmUnKTtcclxuXHRcdFx0aWYgKGFjdGl2ZUhlYWRlciAmJiBhY3RpdmVIZWFkZXIuZ2V0QXR0cmlidXRlKCdkYXRhLXR5cGUnKSA9PT0gdmlld1R5cGUpIHtcclxuXHRcdFx0XHRyZXR1cm4gYWN0aXZlSGVhZGVyIGFzIEhUTUxFbGVtZW50O1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gVHJ5IHRvIG1hdGNoIGJ5IGNoZWNraW5nIGlmIGhlYWRlcidzIGxlYWYgcHJvcGVydHkgbWF0Y2hlc1xyXG5cdFx0Zm9yIChjb25zdCBoZWFkZXIgb2YgQXJyYXkuZnJvbSh0YWJIZWFkZXJzKSkge1xyXG5cdFx0XHRjb25zdCBoZWFkZXJFbCA9IGhlYWRlciBhcyBIVE1MRWxlbWVudDtcclxuXHRcdFx0Y29uc3QgaGVhZGVyRWxXaXRoTGVhZiA9IGhlYWRlckVsIGFzIHVua25vd24gYXMgeyBsZWFmPzogV29ya3NwYWNlTGVhZiB9O1xyXG5cdFx0XHRjb25zdCBoZWFkZXJMZWFmID0gaGVhZGVyRWxXaXRoTGVhZi5sZWFmO1xyXG5cdFx0XHRpZiAoaGVhZGVyTGVhZiA9PT0gbGVhZikge1xyXG5cdFx0XHRcdHJldHVybiBoZWFkZXJFbDtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIElmIG9ubHkgb25lIHRhYiBoZWFkZXIgbWF0Y2hlcyB0aGUgdmlldyB0eXBlIGluIHRoaXMgd2luZG93LCBpdCdzIGxpa2VseSB0aGUgb25lXHJcblx0XHRpZiAodGFiSGVhZGVycy5sZW5ndGggPT09IDEpIHtcclxuXHRcdFx0cmV0dXJuIHRhYkhlYWRlcnNbMF0gYXMgSFRNTEVsZW1lbnQ7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gTGFzdCByZXNvcnQ6IGlmIHRoaXMgaXMgYWN0aXZlIGFuZCB3ZSBmb3VuZCBhbiBhY3RpdmUgaGVhZGVyIGluIHRoaXMgd2luZG93LCB1c2UgaXRcclxuXHRcdGlmIChpc0FjdGl2ZSkge1xyXG5cdFx0XHRjb25zdCBhY3RpdmVIZWFkZXIgPSBkb2MucXVlcnlTZWxlY3RvcignLndvcmtzcGFjZS10YWItaGVhZGVyLmlzLWFjdGl2ZScpO1xyXG5cdFx0XHRpZiAoYWN0aXZlSGVhZGVyKSB7XHJcblx0XHRcdFx0cmV0dXJuIGFjdGl2ZUhlYWRlciBhcyBIVE1MRWxlbWVudDtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBudWxsO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogQ2xvc2UgdGhlIGhvbWUgYmFzZSB0YWJcclxuXHQgKiBXaGVuIGNhbGxlZCBmcm9tIGNvbnRleHQgbWVudTogT25seSBjbG9zZXMgdGhlIGdob3N0IHRhYiAodGhlIFwib2NjdXBpZWRcIiBzbG90KVxyXG5cdCAqIE90aGVyIGhvbWUgYmFzZSB0YWJzIGFyZSBsZWZ0IGFsb25lXHJcblx0ICovXHJcblx0Y2xvc2VIb21lQmFzZShhY3R1YWxseUNsb3NlOiBib29sZWFuID0gZmFsc2UpOiB2b2lkIHtcclxuXHRcdGNvbnN0IGhvbWVCYXNlU2V0dGluZ3MgPSB0aGlzLnBsdWdpbi5nZXRIb21lQmFzZVNldHRpbmdzKCk7XHJcblx0XHRjb25zdCBob21lQmFzZVBhdGggPSByZXNvbHZlUGF0aFN5bmMoaG9tZUJhc2VTZXR0aW5ncy50eXBlLCBob21lQmFzZVNldHRpbmdzLnZhbHVlLCB0aGlzLnBsdWdpbi5hcHApO1xyXG5cclxuXHRcdC8vIEZpbmQgdGhlIGdob3N0IHRhYiAodGhlIFwib2NjdXBpZWRcIiBzbG90IC0gcGlubmVkIGhvbWUgYmFzZSB0YWIpXHJcblx0XHRjb25zdCBnaG9zdFRhYnM6IFdvcmtzcGFjZUxlYWZbXSA9IFtdO1xyXG5cdFx0Y29uc3QgYWxsSG9tZUJhc2VMZWF2ZXM6IFdvcmtzcGFjZUxlYWZbXSA9IFtdO1xyXG5cclxuXHRcdHRoaXMucGx1Z2luLmFwcC53b3Jrc3BhY2UuaXRlcmF0ZUFsbExlYXZlcygobGVhZikgPT4ge1xyXG5cdFx0XHRjb25zdCBpc0dob3N0ID0gdGhpcy5wbHVnaW4uaG9tZVNlcnZpY2UuaXNHaG9zdExlYWYobGVhZik7XHJcblx0XHRcdGlmIChpc0dob3N0KSB7XHJcblx0XHRcdFx0Z2hvc3RUYWJzLnB1c2gobGVhZik7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmIChob21lQmFzZVBhdGggJiYgbGVhZkhhc0ZpbGUobGVhZiwgaG9tZUJhc2VQYXRoKSkge1xyXG5cdFx0XHRcdGFsbEhvbWVCYXNlTGVhdmVzLnB1c2gobGVhZik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93U3RpY2t5SG9tZUljb24pIHtcclxuXHRcdFx0Ly8gU3RpY2t5IGljb24gZW5hYmxlZDogb25seSBjbG9zZSB0aGUgZ2hvc3QgdGFiKHMpXHJcblx0XHRcdGZvciAoY29uc3QgZ2hvc3RUYWIgb2YgZ2hvc3RUYWJzKSB7XHJcblx0XHRcdFx0dm9pZCBnaG9zdFRhYi5kZXRhY2goKTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Ly8gU3RpY2t5IGljb24gZGlzYWJsZWQ6IGNsb3NlIGFsbCBob21lIGJhc2UgdGFic1xyXG5cdFx0XHRmb3IgKGNvbnN0IGxlYWYgb2YgYWxsSG9tZUJhc2VMZWF2ZXMpIHtcclxuXHRcdFx0XHR2b2lkIGxlYWYuZGV0YWNoKCk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBVcGRhdGUgdGFiIGhlYWRlcnMgYWZ0ZXIgY2xvc2luZ1xyXG5cdFx0dGhpcy51cGRhdGVUYWJIZWFkZXJzKCk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBQaW4gdGhlIGhvbWUgYmFzZSB0YWJcclxuXHQgKi9cclxuXHRwaW5Ib21lQmFzZVRhYigpOiB2b2lkIHtcclxuXHRcdGNvbnN0IGhvbWVCYXNlU2V0dGluZ3MgPSB0aGlzLnBsdWdpbi5nZXRIb21lQmFzZVNldHRpbmdzKCk7XHJcblx0XHRjb25zdCBob21lQmFzZVBhdGggPSByZXNvbHZlUGF0aFN5bmMoaG9tZUJhc2VTZXR0aW5ncy50eXBlLCBob21lQmFzZVNldHRpbmdzLnZhbHVlLCB0aGlzLnBsdWdpbi5hcHApO1xyXG5cdFx0aWYgKCFob21lQmFzZVBhdGgpIHJldHVybjtcclxuXHJcblx0XHRjb25zdCBob21lQmFzZUZpbGUgPSBnZXRGaWxlQnlQYXRoKHRoaXMucGx1Z2luLmFwcCwgaG9tZUJhc2VQYXRoKTtcclxuXHRcdGlmICghaG9tZUJhc2VGaWxlKSByZXR1cm47XHJcblxyXG5cdFx0Y29uc3QgaG9tZUJhc2VMZWFmID0gdGhpcy5wbHVnaW4uaG9tZVNlcnZpY2UuZmluZEV4aXN0aW5nSG9tZUJhc2VMZWFmKGhvbWVCYXNlRmlsZSk7XHJcblx0XHRpZiAoaG9tZUJhc2VMZWFmKSB7XHJcblx0XHRcdGhvbWVCYXNlTGVhZi5zZXRQaW5uZWQodHJ1ZSk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBVbnBpbiB0aGUgaG9tZSBiYXNlIHRhYlxyXG5cdCAqL1xyXG5cdHVucGluSG9tZUJhc2VUYWIoKTogdm9pZCB7XHJcblx0XHRjb25zdCBob21lQmFzZVNldHRpbmdzID0gdGhpcy5wbHVnaW4uZ2V0SG9tZUJhc2VTZXR0aW5ncygpO1xyXG5cdFx0Y29uc3QgaG9tZUJhc2VQYXRoID0gcmVzb2x2ZVBhdGhTeW5jKGhvbWVCYXNlU2V0dGluZ3MudHlwZSwgaG9tZUJhc2VTZXR0aW5ncy52YWx1ZSwgdGhpcy5wbHVnaW4uYXBwKTtcclxuXHRcdGlmICghaG9tZUJhc2VQYXRoKSByZXR1cm47XHJcblxyXG5cdFx0Y29uc3QgaG9tZUJhc2VGaWxlID0gZ2V0RmlsZUJ5UGF0aCh0aGlzLnBsdWdpbi5hcHAsIGhvbWVCYXNlUGF0aCk7XHJcblx0XHRpZiAoIWhvbWVCYXNlRmlsZSkgcmV0dXJuO1xyXG5cclxuXHRcdGNvbnN0IGhvbWVCYXNlTGVhZiA9IHRoaXMucGx1Z2luLmhvbWVTZXJ2aWNlLmZpbmRFeGlzdGluZ0hvbWVCYXNlTGVhZihob21lQmFzZUZpbGUpO1xyXG5cdFx0aWYgKGhvbWVCYXNlTGVhZikge1xyXG5cdFx0XHRob21lQmFzZUxlYWYuc2V0UGlubmVkKGZhbHNlKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENoZWNrIGlmIHRoZSBob21lIGJhc2UgdGFiIGlzIHBpbm5lZFxyXG5cdCAqL1xyXG5cdGlzSG9tZUJhc2VUYWJQaW5uZWQoKTogYm9vbGVhbiB7XHJcblx0XHRjb25zdCBob21lQmFzZVNldHRpbmdzID0gdGhpcy5wbHVnaW4uZ2V0SG9tZUJhc2VTZXR0aW5ncygpO1xyXG5cdFx0Y29uc3QgaG9tZUJhc2VQYXRoID0gcmVzb2x2ZVBhdGhTeW5jKGhvbWVCYXNlU2V0dGluZ3MudHlwZSwgaG9tZUJhc2VTZXR0aW5ncy52YWx1ZSwgdGhpcy5wbHVnaW4uYXBwKTtcclxuXHRcdGlmICghaG9tZUJhc2VQYXRoKSByZXR1cm4gZmFsc2U7XHJcblxyXG5cdFx0Y29uc3QgaG9tZUJhc2VGaWxlID0gZ2V0RmlsZUJ5UGF0aCh0aGlzLnBsdWdpbi5hcHAsIGhvbWVCYXNlUGF0aCk7XHJcblx0XHRpZiAoIWhvbWVCYXNlRmlsZSkgcmV0dXJuIGZhbHNlO1xyXG5cclxuXHRcdGNvbnN0IGhvbWVCYXNlTGVhZiA9IHRoaXMucGx1Z2luLmhvbWVTZXJ2aWNlLmZpbmRFeGlzdGluZ0hvbWVCYXNlTGVhZihob21lQmFzZUZpbGUpO1xyXG5cdFx0aWYgKCFob21lQmFzZUxlYWYpIHJldHVybiBmYWxzZTtcclxuXHJcblx0XHRjb25zdCB2aWV3U3RhdGUgPSBob21lQmFzZUxlYWYuZ2V0Vmlld1N0YXRlKCk7XHJcblx0XHRyZXR1cm4gdmlld1N0YXRlLnBpbm5lZCA9PT0gdHJ1ZTtcclxuXHR9XHJcbn1cclxuIiwgIi8qKlxyXG4gKiBNb2JpbGUgQnV0dG9uIFNlcnZpY2VcclxuICogTWFuYWdlcyB0aGUgbW9iaWxlIG5ldyB0YWIgYnV0dG9uIHJlcGxhY2VtZW50XHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB0eXBlIEhvbWVCYXNlUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5cclxuLyoqXHJcbiAqIENTUyBjbGFzcyBmb3Igd2hlbiBtb2JpbGUgYnV0dG9uIGlzIHJlcGxhY2VkXHJcbiAqL1xyXG5jb25zdCBNT0JJTEVfSE9NRV9DTEFTUyA9ICdob21lLWJhc2UtbW9iaWxlLWVuYWJsZWQnO1xyXG5cclxuZXhwb3J0IGNsYXNzIE1vYmlsZUJ1dHRvblNlcnZpY2Uge1xyXG5cdHByaXZhdGUgcGx1Z2luOiBIb21lQmFzZVBsdWdpbjtcclxuXHJcblx0Y29uc3RydWN0b3IocGx1Z2luOiBIb21lQmFzZVBsdWdpbikge1xyXG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBVcGRhdGUgdGhlIG1vYmlsZSBidXR0b24gYmFzZWQgb24gc2V0dGluZ3NcclxuXHQgKi9cclxuXHR1cGRhdGUoKTogdm9pZCB7XHJcblx0XHQvLyBPbmx5IGFwcGx5IG9uIG1vYmlsZVxyXG5cdFx0aWYgKCFQbGF0Zm9ybS5pc01vYmlsZSkge1xyXG5cdFx0XHR0aGlzLnJlbW92ZSgpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnJlcGxhY2VNb2JpbGVOZXdUYWIpIHtcclxuXHRcdFx0dGhpcy5hcHBseSgpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy5yZW1vdmUoKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEFwcGx5IHRoZSBtb2JpbGUgYnV0dG9uIHJlcGxhY2VtZW50XHJcblx0ICovXHJcblx0cHJpdmF0ZSBhcHBseSgpOiB2b2lkIHtcclxuXHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChNT0JJTEVfSE9NRV9DTEFTUyk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZW1vdmUgdGhlIG1vYmlsZSBidXR0b24gcmVwbGFjZW1lbnRcclxuXHQgKi9cclxuXHRyZW1vdmUoKTogdm9pZCB7XHJcblx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoTU9CSUxFX0hPTUVfQ0xBU1MpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IHsgSG9tZUJhc2VUeXBlLCBERUZBVUxUX1NFVFRJTkdTIH0gZnJvbSAnLi9zZXR0aW5ncyc7XHJcbmltcG9ydCB0eXBlIEhvbWVCYXNlUGx1Z2luIGZyb20gJy4vbWFpbic7XHJcblxyXG4vKipcclxuICogTWlncmF0ZSBsZWdhY3kgc2V0dGluZ3MgdG8gbmV3IGZvcm1hdFxyXG4gKi9cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1pZ3JhdGVMZWdhY3lTZXR0aW5ncyhwbHVnaW46IEhvbWVCYXNlUGx1Z2luKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBsZXQgbmVlZHNTYXZlID0gZmFsc2U7XHJcbiAgICBjb25zdCBzZXR0aW5ncyA9IHBsdWdpbi5zZXR0aW5ncyBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IGJvb2xlYW4gfCBIb21lQmFzZVR5cGUgfCB1bmRlZmluZWQ+O1xyXG5cclxuICAgIC8vIE1pZ3JhdGUgaG9tZUJhc2VQYXRoIHRvIGhvbWVCYXNlVHlwZS9ob21lQmFzZVZhbHVlXHJcbiAgICBpZiAoc2V0dGluZ3MuaG9tZUJhc2VQYXRoICYmICFwbHVnaW4uc2V0dGluZ3MuaG9tZUJhc2VWYWx1ZSkge1xyXG4gICAgICAgIHBsdWdpbi5zZXR0aW5ncy5ob21lQmFzZVR5cGUgPSBIb21lQmFzZVR5cGUuRmlsZTtcclxuICAgICAgICBwbHVnaW4uc2V0dGluZ3MuaG9tZUJhc2VWYWx1ZSA9IHNldHRpbmdzLmhvbWVCYXNlUGF0aCBhcyBzdHJpbmc7XHJcbiAgICAgICAgbmVlZHNTYXZlID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBNaWdyYXRlIGtlZXBFeGlzdGluZ1RhYnMgdG8gb3Blbk1vZGVcclxuICAgIGlmIChzZXR0aW5ncy5rZWVwRXhpc3RpbmdUYWJzICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAvLyBPbmx5IG1pZ3JhdGUgaWYgb3Blbk1vZGUgaXMgc3RpbGwgYXQgZGVmYXVsdCAoaGFzbid0IGJlZW4gc2V0IGJ5IHVzZXIpXHJcbiAgICAgICAgaWYgKHBsdWdpbi5zZXR0aW5ncy5vcGVuTW9kZSA9PT0gREVGQVVMVF9TRVRUSU5HUy5vcGVuTW9kZSkge1xyXG4gICAgICAgICAgICBwbHVnaW4uc2V0dGluZ3Mub3Blbk1vZGUgPSBzZXR0aW5ncy5rZWVwRXhpc3RpbmdUYWJzID8gJ3JldGFpbicgOiAncmVwbGFjZS1hbGwnO1xyXG4gICAgICAgICAgICBuZWVkc1NhdmUgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBEZWxldGUgbGVnYWN5IHByb3BlcnR5IHNvIGl0IGRvZXNuJ3QgdHJpZ2dlciBhZ2FpblxyXG4gICAgICAgIGRlbGV0ZSBzZXR0aW5ncy5rZWVwRXhpc3RpbmdUYWJzO1xyXG4gICAgICAgIG5lZWRzU2F2ZSA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gTWlncmF0ZSBtb2JpbGUgaG9tZUJhc2VQYXRoXHJcbiAgICBpZiAoc2V0dGluZ3MubW9iaWxlSG9tZUJhc2VQYXRoICYmICFwbHVnaW4uc2V0dGluZ3MubW9iaWxlSG9tZUJhc2VWYWx1ZSkge1xyXG4gICAgICAgIHBsdWdpbi5zZXR0aW5ncy5tb2JpbGVIb21lQmFzZVR5cGUgPSBIb21lQmFzZVR5cGUuRmlsZTtcclxuICAgICAgICBwbHVnaW4uc2V0dGluZ3MubW9iaWxlSG9tZUJhc2VWYWx1ZSA9IHNldHRpbmdzLm1vYmlsZUhvbWVCYXNlUGF0aCBhcyBzdHJpbmc7XHJcbiAgICAgICAgbmVlZHNTYXZlID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBBbHNvIGNsZWFuIHVwIG1vYmlsZSBob21lIGJhc2UgcGF0aCBsZWdhY3kgcHJvcGVydHlcclxuICAgIGlmIChzZXR0aW5ncy5tb2JpbGVIb21lQmFzZVBhdGggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGRlbGV0ZSBzZXR0aW5ncy5tb2JpbGVIb21lQmFzZVBhdGg7XHJcbiAgICAgICAgbmVlZHNTYXZlID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDbGVhbiB1cCBsZWdhY3kgaG9tZUJhc2VQYXRoIGlmIGl0IG1hdGNoZXMgaG9tZUJhc2VWYWx1ZVxyXG4gICAgaWYgKHNldHRpbmdzLmhvbWVCYXNlUGF0aCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgZGVsZXRlIHNldHRpbmdzLmhvbWVCYXNlUGF0aDtcclxuICAgICAgICBuZWVkc1NhdmUgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChuZWVkc1NhdmUpIHtcclxuICAgICAgICBhd2FpdCBwbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcbiAgICB9XHJcbn1cclxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUVBLFdBQU8sZUFBZSxTQUFTLGNBQWMsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUU1RCxRQUFJLFdBQVcsUUFBUSxVQUFVO0FBRWpDLFFBQU0sNEJBQTRCO0FBQ2xDLFFBQU0sNkJBQTZCO0FBQ25DLFFBQU0sOEJBQThCO0FBQ3BDLFFBQU0sZ0NBQWdDO0FBQ3RDLFFBQU0sNkJBQTZCO0FBRW5DLGFBQVMsK0JBQStCLGFBQWE7QUFackQ7QUFjSSxZQUFNLGdCQUFnQixPQUFPLElBQUksUUFBUSxVQUFVLGdCQUFnQjtBQUNuRSxhQUFPLG1CQUFpQix5QkFBYyxhQUFkLG1CQUF5QixpQkFBekIsbUJBQXVDO0FBQUEsSUFDbkU7QUFLQSxhQUFTLHVCQUF1QjtBQXJCaEM7QUFzQkksVUFBSTtBQUVBLGNBQU0sRUFB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LFVBQUksQ0FBQyxVQUFXLFFBQU87QUFFdkIsZUFBUSwwREFBd0UsYUFBeEUsbUJBQW1GLGVBQW5GLG1CQUErRixhQUFZO0FBQUEsSUFDcEgsT0FBTztBQUVOLFlBQU0sVUFBaUQ7QUFBQSxRQUN0RCwrQkFBd0IsR0FBRztBQUFBLFFBQzNCLGlDQUF5QixHQUFHO0FBQUEsUUFDNUIscUNBQTJCLEdBQUc7QUFBQSxRQUM5QiwrQkFBd0IsR0FBRztBQUFBLE1BQzVCO0FBRUEsWUFBTSxPQUFPLFFBQVEsSUFBSTtBQUN6QixVQUFJLENBQUMsS0FBTSxRQUFPO0FBRWxCLFlBQU0sZUFBZSwwREFBMkcsdUJBQTNHLG1CQUErSCxpQkFBL0g7QUFFckIsZUFBTyxnREFBYyxVQUFkLG1CQUFxQixhQUFZO0FBQUEsSUFDekM7QUFBQSxFQUNEO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFLUSxlQUF3QjtBQUcvQixRQUFJLE9BQU8sV0FBVyxlQUFlLE9BQU8sU0FBUztBQUNwRCxZQUFNLFNBQVMsT0FBTyxLQUFLLE9BQU8sT0FBTztBQUN6QyxZQUFNLFNBQVMsT0FBTyxRQUFRO0FBQzlCLGFBQ0MsV0FBVyxVQUNYLENBQUMsUUFBUSxjQUFjLEVBQUUsU0FBUyxNQUFNLEtBQ3hDLENBQUMsUUFBUSxZQUFZLFdBQVcsRUFBRSxLQUFLLE9BQUssT0FBTyxTQUFTLENBQUMsQ0FBQztBQUFBLElBRWhFO0FBQ0EsV0FBTztBQUFBLEVBQ1I7QUFBQTtBQUFBO0FBSUQ7IiwKICAibmFtZXMiOiBbImZvcm1hdCIsICJmb2xkZXIiLCAidGVtcGxhdGUiLCAiY3JlYXRlRGFpbHlOb3RlIiwgIm1vbWVudCIsICJnZXREYWlseU5vdGUiLCAiZ2V0QWxsRGFpbHlOb3RlcyIsICJjcmVhdGVXZWVrbHlOb3RlIiwgImdldFdlZWtseU5vdGUiLCAiZ2V0QWxsV2Vla2x5Tm90ZXMiLCAiY3JlYXRlTW9udGhseU5vdGUiLCAiZ2V0TW9udGhseU5vdGUiLCAiZ2V0QWxsTW9udGhseU5vdGVzIiwgImNyZWF0ZVF1YXJ0ZXJseU5vdGUiLCAiZ2V0UXVhcnRlcmx5Tm90ZSIsICJnZXRBbGxRdWFydGVybHlOb3RlcyIsICJjcmVhdGVZZWFybHlOb3RlIiwgImdldFllYXJseU5vdGUiLCAiZ2V0QWxsWWVhcmx5Tm90ZXMiLCAiaW1wb3J0X29ic2lkaWFuIiwgIkhvbWVCYXNlVHlwZSIsICJpbXBvcnRfb2JzaWRpYW4iLCAiaW1wb3J0X29ic2lkaWFuIiwgImltcG9ydF9vYnNpZGlhbiIsICJpbXBvcnRfb2JzaWRpYW4iLCAiaW1wb3J0X29ic2lkaWFuIiwgIlNVUFBPUlRFRF9FWFRFTlNJT05TIiwgIlNVUFBPUlRFRF9FWFRFTlNJT05TIiwgIlNVUFBPUlRFRF9FWFRFTlNJT05TIiwgImltcG9ydF9vYnNpZGlhbiIsICJPVmlldyIsICJnaG9zdFRhYiIsICJzaG91bGRGb2N1cyIsICJpbXBvcnRfb2JzaWRpYW4iLCAiaW1wb3J0X29ic2lkaWFuIiwgIm1haW5Xb3Jrc3BhY2UiLCAiaW1wb3J0X29ic2lkaWFuIiwgInBlcmlvZGljTm90ZXMiLCAidmVyc2lvbiIsICJpc0xlZ2FjeSJdCn0K