Files
obsidian-gui-tasks/main.js
2026-03-29 11:42:33 -04:00

3625 lines
495 KiB
JavaScript

"use strict";
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/obsidian-daily-notes-interface/dist/main.js
var require_main = __commonJS({
"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_FORMAT2 = "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: plugins2 } = window.app;
if (shouldUsePeriodicNotesSettings("daily")) {
const { format: format2, folder: folder2, template: template2 } = ((_b = (_a = plugins2.getPlugin("periodic-notes")) == null ? void 0 : _a.settings) == null ? void 0 : _b.daily) || {};
return {
format: format2 || DEFAULT_DAILY_NOTE_FORMAT2,
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_FORMAT2,
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 createDailyNote(date) {
const app = window.app;
const { vault } = app;
const moment = 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, moment().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 = 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*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 getDailyNote(date, dailyNotes) {
var _a;
return (_a = dailyNotes[getDateUID(date, "day")]) != null ? _a : null;
}
function getAllDailyNotes() {
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 } = window;
let weekStart = moment.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 createWeeklyNote(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 getWeeklyNote(date, weeklyNotes) {
var _a;
return (_a = weeklyNotes[getDateUID(date, "week")]) != null ? _a : null;
}
function getAllWeeklyNotes() {
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 createMonthlyNote(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 getMonthlyNote(date, monthlyNotes) {
var _a;
return (_a = monthlyNotes[getDateUID(date, "month")]) != null ? _a : null;
}
function getAllMonthlyNotes() {
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 createQuarterlyNote(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 getQuarterlyNote(date, quarterly) {
var _a;
return (_a = quarterly[getDateUID(date, "quarter")]) != null ? _a : null;
}
function getAllQuarterlyNotes() {
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 createYearlyNote(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 getYearlyNote(date, yearlyNotes) {
var _a;
return (_a = yearlyNotes[getDateUID(date, "year")]) != null ? _a : null;
}
function getAllYearlyNotes() {
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: createDailyNote,
month: createMonthlyNote,
week: createWeeklyNote
};
return createFn[granularity](date);
}
exports.DEFAULT_DAILY_NOTE_FORMAT = DEFAULT_DAILY_NOTE_FORMAT2;
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 = createDailyNote;
exports.createMonthlyNote = createMonthlyNote;
exports.createPeriodicNote = createPeriodicNote;
exports.createQuarterlyNote = createQuarterlyNote;
exports.createWeeklyNote = createWeeklyNote;
exports.createYearlyNote = createYearlyNote;
exports.getAllDailyNotes = getAllDailyNotes;
exports.getAllMonthlyNotes = getAllMonthlyNotes;
exports.getAllQuarterlyNotes = getAllQuarterlyNotes;
exports.getAllWeeklyNotes = getAllWeeklyNotes;
exports.getAllYearlyNotes = getAllYearlyNotes;
exports.getDailyNote = getDailyNote;
exports.getDailyNoteSettings = getDailyNoteSettings;
exports.getDateFromFile = getDateFromFile;
exports.getDateFromPath = getDateFromPath;
exports.getDateUID = getDateUID;
exports.getMonthlyNote = getMonthlyNote;
exports.getMonthlyNoteSettings = getMonthlyNoteSettings;
exports.getPeriodicNoteSettings = getPeriodicNoteSettings;
exports.getQuarterlyNote = getQuarterlyNote;
exports.getQuarterlyNoteSettings = getQuarterlyNoteSettings;
exports.getTemplateInfo = getTemplateInfo;
exports.getWeeklyNote = getWeeklyNote;
exports.getWeeklyNoteSettings = getWeeklyNoteSettings;
exports.getYearlyNote = getYearlyNote;
exports.getYearlyNoteSettings = getYearlyNoteSettings;
}
});
// src/main.ts
var main_exports = {};
__export(main_exports, {
default: () => YaotpPlugin
});
module.exports = __toCommonJS(main_exports);
var import_obsidian6 = require("obsidian");
// src/constants.ts
var VIEW_TYPE = "yaotp-task-view";
var VIEW_ICON = "check-square";
var DEFAULT_INBOX_PATH = "Tasks/Inbox.md";
var DEFAULT_TASK_REGEX = "^Tasks\\/.*\\.md$";
var DEFAULT_DAILY_NOTE_FORMAT = "YYYY-MM-DD";
var DEFAULT_DAILY_NOTE_FOLDER = "";
var DEFAULT_TASK_FILE_FOLDER = "Tasks";
var DAILY_NOTE_TASKS_HEADING = "#### Tasks";
// src/settings.ts
var import_obsidian = require("obsidian");
var DEFAULT_SETTINGS = {
inboxPath: DEFAULT_INBOX_PATH,
taskFileRegex: DEFAULT_TASK_REGEX,
taskFileFolder: DEFAULT_TASK_FILE_FOLDER,
dailyNoteFormat: DEFAULT_DAILY_NOTE_FORMAT,
dailyNoteFolder: DEFAULT_DAILY_NOTE_FOLDER
};
var YaotpSettingTab = class extends import_obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
new import_obsidian.Setting(containerEl).setName("Inbox file path").setDesc("Vault-relative path to the default Inbox task file.").addText(
(text) => text.setPlaceholder("Tasks/Inbox.md").setValue(this.plugin.settings.inboxPath).onChange(async (value) => {
this.plugin.settings.inboxPath = value.trim();
await this.plugin.saveSettings();
})
);
new import_obsidian.Setting(containerEl).setName("Task file regex").setDesc(
"Regular expression matched against vault-relative file paths to identify task files."
).addText((text) => {
text.setPlaceholder("^Tasks\\/.*\\.md$").setValue(this.plugin.settings.taskFileRegex).onChange(async (value) => {
try {
new RegExp(value);
text.inputEl.removeClass("yaotp-setting-error");
this.plugin.settings.taskFileRegex = value.trim();
await this.plugin.saveSettings();
} catch (e) {
text.inputEl.addClass("yaotp-setting-error");
}
});
text.inputEl.style.width = "100%";
});
new import_obsidian.Setting(containerEl).setName("Task file folder").setDesc("Vault-relative folder where new task lists are created. Leave empty for the vault root.").addText(
(text) => text.setPlaceholder("Tasks").setValue(this.plugin.settings.taskFileFolder).onChange(async (value) => {
this.plugin.settings.taskFileFolder = value.trim();
await this.plugin.saveSettings();
})
);
new import_obsidian.Setting(containerEl).setName("Daily note date format").setDesc(
"Moment.js date format for daily notes. Should match your Daily Notes plugin setting."
).addText(
(text) => text.setPlaceholder("YYYY-MM-DD").setValue(this.plugin.settings.dailyNoteFormat).onChange(async (value) => {
this.plugin.settings.dailyNoteFormat = value.trim();
await this.plugin.saveSettings();
})
);
new import_obsidian.Setting(containerEl).setName("Daily note folder").setDesc(
"Folder where daily notes are stored. Leave empty for the vault root. Should match your Daily Notes plugin setting."
).addText(
(text) => text.setPlaceholder("Daily Notes").setValue(this.plugin.settings.dailyNoteFolder).onChange(async (value) => {
this.plugin.settings.dailyNoteFolder = value.trim();
await this.plugin.saveSettings();
})
);
}
};
// src/view/TaskFileView.ts
var import_obsidian5 = require("obsidian");
// src/parser.ts
var CHECKLIST_RE = /^- \[([ xX])\] (.*)$/;
function parseTaskFile(markdown) {
const lines = markdown.split("\n");
const tasks = [];
const headerLines = [];
let current = null;
let state = "idle";
let noteBuffer = [];
const flush = () => {
if (current) {
while (noteBuffer.length > 0 && noteBuffer[noteBuffer.length - 1].trim() === "") {
noteBuffer.pop();
}
current.notes = noteBuffer;
tasks.push(current);
current = null;
noteBuffer = [];
}
};
for (const line of lines) {
const match = CHECKLIST_RE.exec(line);
if (match) {
flush();
current = {
text: match[2],
notes: [],
completed: match[1].toLowerCase() === "x"
};
state = "after-task";
continue;
}
if (current === null) {
headerLines.push(line);
continue;
}
const isBlank = line.trim() === "";
if (state === "after-task") {
if (isBlank) {
state = "in-notes";
} else {
noteBuffer.push(line);
state = "in-notes";
}
continue;
}
if (state === "in-notes") {
noteBuffer.push(line);
continue;
}
}
flush();
while (headerLines.length > 0 && headerLines[headerLines.length - 1].trim() === "") {
headerLines.pop();
}
const header = headerLines.length > 0 ? headerLines.join("\n") + "\n" : "";
return { header, tasks };
}
function serializeTaskFile(data) {
const { header, tasks } = data;
if (tasks.length === 0) return header || "";
const parts = [];
for (const task of tasks) {
const marker = task.completed ? "x" : " ";
parts.push(`- [${marker}] ${task.text}`);
if (task.notes.length > 0) {
parts.push("");
for (const note of task.notes) {
parts.push(note);
}
}
parts.push("");
}
const taskContent = parts.join("\n").replace(/\n+$/, "") + "\n";
return header ? header + "\n" + taskContent : taskContent;
}
// src/daily-notes.ts
var import_obsidian2 = require("obsidian");
var dni = null;
async function getDni() {
if (!dni) {
dni = await Promise.resolve().then(() => __toESM(require_main()));
}
return dni;
}
async function appendTaskToDailyNote(task, app) {
const lib = await getDni();
if (!lib.appHasDailyNotesPluginLoaded(app)) {
new import_obsidian2.Notice(
"YAOTP: Daily Notes plugin is not enabled. Please enable it in Settings \u2192 Core plugins."
);
return;
}
const all = lib.getAllDailyNotes();
const today = window.moment();
let file = lib.getDailyNote(today, all);
if (!file) {
file = await lib.createDailyNote(today);
}
const existing = await app.vault.read(file);
const appended = buildAppendedContent(existing, task);
await app.vault.modify(file, appended);
}
function buildAppendedContent(existing, task) {
var _a;
const taskLine = `- [x] ${task.text}`;
const notesBlock = task.notes.length > 0 ? "\n\n" + task.notes.join("\n") : "";
const entry = taskLine + notesBlock;
const headingIndex = existing.lastIndexOf(DAILY_NOTE_TASKS_HEADING);
if (headingIndex === -1) {
const base = existing.trimEnd();
return base + (base.length > 0 ? "\n\n" : "") + DAILY_NOTE_TASKS_HEADING + "\n\n" + entry + "\n";
}
const afterHeading = existing.slice(headingIndex + DAILY_NOTE_TASKS_HEADING.length);
const nextHeadingMatch = afterHeading.match(/\n#{1,4} /);
const insertionRelative = (_a = nextHeadingMatch == null ? void 0 : nextHeadingMatch.index) != null ? _a : afterHeading.length;
const before = existing.slice(0, headingIndex + DAILY_NOTE_TASKS_HEADING.length);
const sectionContent = afterHeading.slice(0, insertionRelative).trimEnd();
const after = afterHeading.slice(insertionRelative);
return before + sectionContent + "\n\n" + entry + (after.length > 0 ? "\n" + after : "\n");
}
// node_modules/sortablejs/modular/sortable.esm.js
function _defineProperty(e, r, t) {
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t,
enumerable: true,
configurable: true,
writable: true
}) : e[r] = t, e;
}
function _extends() {
return _extends = Object.assign ? Object.assign.bind() : function(n) {
for (var e = 1; e < arguments.length; e++) {
var t = arguments[e];
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
}
return n;
}, _extends.apply(null, arguments);
}
function ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function(r2) {
return Object.getOwnPropertyDescriptor(e, r2).enumerable;
})), t.push.apply(t, o);
}
return t;
}
function _objectSpread2(e) {
for (var r = 1; r < arguments.length; r++) {
var t = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t), true).forEach(function(r2) {
_defineProperty(e, r2, t[r2]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r2) {
Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
});
}
return e;
}
function _objectWithoutProperties(e, t) {
if (null == e) return {};
var o, r, i = _objectWithoutPropertiesLoose(e, t);
if (Object.getOwnPropertySymbols) {
var n = Object.getOwnPropertySymbols(e);
for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
}
return i;
}
function _objectWithoutPropertiesLoose(r, e) {
if (null == r) return {};
var t = {};
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
if (-1 !== e.indexOf(n)) continue;
t[n] = r[n];
}
return t;
}
function _toPrimitive(t, r) {
if ("object" != typeof t || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != typeof i) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == typeof i ? i : i + "";
}
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o2) {
return typeof o2;
} : function(o2) {
return o2 && "function" == typeof Symbol && o2.constructor === Symbol && o2 !== Symbol.prototype ? "symbol" : typeof o2;
}, _typeof(o);
}
var version = "1.15.7";
function userAgent(pattern) {
if (typeof window !== "undefined" && window.navigator) {
return !!/* @__PURE__ */ navigator.userAgent.match(pattern);
}
}
var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
var Edge = userAgent(/Edge/i);
var FireFox = userAgent(/firefox/i);
var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
var IOS = userAgent(/iP(ad|od|hone)/i);
var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
var captureMode = {
capture: false,
passive: false
};
function on(el, event, fn) {
el.addEventListener(event, fn, !IE11OrLess && captureMode);
}
function off(el, event, fn) {
el.removeEventListener(event, fn, !IE11OrLess && captureMode);
}
function matches(el, selector) {
if (!selector) return;
selector[0] === ">" && (selector = selector.substring(1));
if (el) {
try {
if (el.matches) {
return el.matches(selector);
} else if (el.msMatchesSelector) {
return el.msMatchesSelector(selector);
} else if (el.webkitMatchesSelector) {
return el.webkitMatchesSelector(selector);
}
} catch (_) {
return false;
}
}
return false;
}
function getParentOrHost(el) {
return el.host && el !== document && el.host.nodeType && el.host !== el ? el.host : el.parentNode;
}
function closest(el, selector, ctx, includeCTX) {
if (el) {
ctx = ctx || document;
do {
if (selector != null && (selector[0] === ">" ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
return el;
}
if (el === ctx) break;
} while (el = getParentOrHost(el));
}
return null;
}
var R_SPACE = /\s+/g;
function toggleClass(el, name, state) {
if (el && name) {
if (el.classList) {
el.classList[state ? "add" : "remove"](name);
} else {
var className = (" " + el.className + " ").replace(R_SPACE, " ").replace(" " + name + " ", " ");
el.className = (className + (state ? " " + name : "")).replace(R_SPACE, " ");
}
}
}
function css(el, prop, val) {
var style = el && el.style;
if (style) {
if (val === void 0) {
if (document.defaultView && document.defaultView.getComputedStyle) {
val = document.defaultView.getComputedStyle(el, "");
} else if (el.currentStyle) {
val = el.currentStyle;
}
return prop === void 0 ? val : val[prop];
} else {
if (!(prop in style) && prop.indexOf("webkit") === -1) {
prop = "-webkit-" + prop;
}
style[prop] = val + (typeof val === "string" ? "" : "px");
}
}
}
function matrix(el, selfOnly) {
var appliedTransforms = "";
if (typeof el === "string") {
appliedTransforms = el;
} else {
do {
var transform = css(el, "transform");
if (transform && transform !== "none") {
appliedTransforms = transform + " " + appliedTransforms;
}
} while (!selfOnly && (el = el.parentNode));
}
var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
return matrixFn && new matrixFn(appliedTransforms);
}
function find(ctx, tagName, iterator) {
if (ctx) {
var list = ctx.getElementsByTagName(tagName), i = 0, n = list.length;
if (iterator) {
for (; i < n; i++) {
iterator(list[i], i);
}
}
return list;
}
return [];
}
function getWindowScrollingElement() {
var scrollingElement = document.scrollingElement;
if (scrollingElement) {
return scrollingElement;
} else {
return document.documentElement;
}
}
function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
if (!el.getBoundingClientRect && el !== window) return;
var elRect, top, left, bottom, right, height, width;
if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
elRect = el.getBoundingClientRect();
top = elRect.top;
left = elRect.left;
bottom = elRect.bottom;
right = elRect.right;
height = elRect.height;
width = elRect.width;
} else {
top = 0;
left = 0;
bottom = window.innerHeight;
right = window.innerWidth;
height = window.innerHeight;
width = window.innerWidth;
}
if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
container = container || el.parentNode;
if (!IE11OrLess) {
do {
if (container && container.getBoundingClientRect && (css(container, "transform") !== "none" || relativeToNonStaticParent && css(container, "position") !== "static")) {
var containerRect = container.getBoundingClientRect();
top -= containerRect.top + parseInt(css(container, "border-top-width"));
left -= containerRect.left + parseInt(css(container, "border-left-width"));
bottom = top + elRect.height;
right = left + elRect.width;
break;
}
} while (container = container.parentNode);
}
}
if (undoScale && el !== window) {
var elMatrix = matrix(container || el), scaleX = elMatrix && elMatrix.a, scaleY = elMatrix && elMatrix.d;
if (elMatrix) {
top /= scaleY;
left /= scaleX;
width /= scaleX;
height /= scaleY;
bottom = top + height;
right = left + width;
}
}
return {
top,
left,
bottom,
right,
width,
height
};
}
function isScrolledPast(el, elSide, parentSide) {
var parent = getParentAutoScrollElement(el, true), elSideVal = getRect(el)[elSide];
while (parent) {
var parentSideVal = getRect(parent)[parentSide], visible = void 0;
if (parentSide === "top" || parentSide === "left") {
visible = elSideVal >= parentSideVal;
} else {
visible = elSideVal <= parentSideVal;
}
if (!visible) return parent;
if (parent === getWindowScrollingElement()) break;
parent = getParentAutoScrollElement(parent, false);
}
return false;
}
function getChild(el, childNum, options, includeDragEl) {
var currentChild = 0, i = 0, children = el.children;
while (i < children.length) {
if (children[i].style.display !== "none" && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
if (currentChild === childNum) {
return children[i];
}
currentChild++;
}
i++;
}
return null;
}
function lastChild(el, selector) {
var last = el.lastElementChild;
while (last && (last === Sortable.ghost || css(last, "display") === "none" || selector && !matches(last, selector))) {
last = last.previousElementSibling;
}
return last || null;
}
function index(el, selector) {
var index2 = 0;
if (!el || !el.parentNode) {
return -1;
}
while (el = el.previousElementSibling) {
if (el.nodeName.toUpperCase() !== "TEMPLATE" && el !== Sortable.clone && (!selector || matches(el, selector))) {
index2++;
}
}
return index2;
}
function getRelativeScrollOffset(el) {
var offsetLeft = 0, offsetTop = 0, winScroller = getWindowScrollingElement();
if (el) {
do {
var elMatrix = matrix(el), scaleX = elMatrix.a, scaleY = elMatrix.d;
offsetLeft += el.scrollLeft * scaleX;
offsetTop += el.scrollTop * scaleY;
} while (el !== winScroller && (el = el.parentNode));
}
return [offsetLeft, offsetTop];
}
function indexOfObject(arr, obj) {
for (var i in arr) {
if (!arr.hasOwnProperty(i)) continue;
for (var key in obj) {
if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
}
}
return -1;
}
function getParentAutoScrollElement(el, includeSelf) {
if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
var elem = el;
var gotSelf = false;
do {
if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
var elemCSS = css(elem);
if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == "auto" || elemCSS.overflowX == "scroll") || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == "auto" || elemCSS.overflowY == "scroll")) {
if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
if (gotSelf || includeSelf) return elem;
gotSelf = true;
}
}
} while (elem = elem.parentNode);
return getWindowScrollingElement();
}
function extend(dst, src) {
if (dst && src) {
for (var key in src) {
if (src.hasOwnProperty(key)) {
dst[key] = src[key];
}
}
}
return dst;
}
function isRectEqual(rect1, rect2) {
return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width);
}
var _throttleTimeout;
function throttle(callback, ms) {
return function() {
if (!_throttleTimeout) {
var args = arguments, _this = this;
if (args.length === 1) {
callback.call(_this, args[0]);
} else {
callback.apply(_this, args);
}
_throttleTimeout = setTimeout(function() {
_throttleTimeout = void 0;
}, ms);
}
};
}
function cancelThrottle() {
clearTimeout(_throttleTimeout);
_throttleTimeout = void 0;
}
function scrollBy(el, x, y) {
el.scrollLeft += x;
el.scrollTop += y;
}
function clone(el) {
var Polymer = window.Polymer;
var $ = window.jQuery || window.Zepto;
if (Polymer && Polymer.dom) {
return Polymer.dom(el).cloneNode(true);
} else if ($) {
return $(el).clone(true)[0];
} else {
return el.cloneNode(true);
}
}
function getChildContainingRectFromElement(container, options, ghostEl2) {
var rect = {};
Array.from(container.children).forEach(function(child) {
var _rect$left, _rect$top, _rect$right, _rect$bottom;
if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl2) return;
var childRect = getRect(child);
rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left);
rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top);
rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right);
rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom);
});
rect.width = rect.right - rect.left;
rect.height = rect.bottom - rect.top;
rect.x = rect.left;
rect.y = rect.top;
return rect;
}
var expando = "Sortable" + (/* @__PURE__ */ new Date()).getTime();
function AnimationStateManager() {
var animationStates = [], animationCallbackId;
return {
captureAnimationState: function captureAnimationState() {
animationStates = [];
if (!this.options.animation) return;
var children = [].slice.call(this.el.children);
children.forEach(function(child) {
if (css(child, "display") === "none" || child === Sortable.ghost) return;
animationStates.push({
target: child,
rect: getRect(child)
});
var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect);
if (child.thisAnimationDuration) {
var childMatrix = matrix(child, true);
if (childMatrix) {
fromRect.top -= childMatrix.f;
fromRect.left -= childMatrix.e;
}
}
child.fromRect = fromRect;
});
},
addAnimationState: function addAnimationState(state) {
animationStates.push(state);
},
removeAnimationState: function removeAnimationState(target) {
animationStates.splice(indexOfObject(animationStates, {
target
}), 1);
},
animateAll: function animateAll(callback) {
var _this = this;
if (!this.options.animation) {
clearTimeout(animationCallbackId);
if (typeof callback === "function") callback();
return;
}
var animating = false, animationTime = 0;
animationStates.forEach(function(state) {
var time = 0, target = state.target, fromRect = target.fromRect, toRect = getRect(target), prevFromRect = target.prevFromRect, prevToRect = target.prevToRect, animatingRect = state.rect, targetMatrix = matrix(target, true);
if (targetMatrix) {
toRect.top -= targetMatrix.f;
toRect.left -= targetMatrix.e;
}
target.toRect = toRect;
if (target.thisAnimationDuration) {
if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && // Make sure animatingRect is on line between toRect & fromRect
(animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
}
}
if (!isRectEqual(toRect, fromRect)) {
target.prevFromRect = fromRect;
target.prevToRect = toRect;
if (!time) {
time = _this.options.animation;
}
_this.animate(target, animatingRect, toRect, time);
}
if (time) {
animating = true;
animationTime = Math.max(animationTime, time);
clearTimeout(target.animationResetTimer);
target.animationResetTimer = setTimeout(function() {
target.animationTime = 0;
target.prevFromRect = null;
target.fromRect = null;
target.prevToRect = null;
target.thisAnimationDuration = null;
}, time);
target.thisAnimationDuration = time;
}
});
clearTimeout(animationCallbackId);
if (!animating) {
if (typeof callback === "function") callback();
} else {
animationCallbackId = setTimeout(function() {
if (typeof callback === "function") callback();
}, animationTime);
}
animationStates = [];
},
animate: function animate(target, currentRect, toRect, duration) {
if (duration) {
css(target, "transition", "");
css(target, "transform", "");
var elMatrix = matrix(this.el), scaleX = elMatrix && elMatrix.a, scaleY = elMatrix && elMatrix.d, translateX = (currentRect.left - toRect.left) / (scaleX || 1), translateY = (currentRect.top - toRect.top) / (scaleY || 1);
target.animatingX = !!translateX;
target.animatingY = !!translateY;
css(target, "transform", "translate3d(" + translateX + "px," + translateY + "px,0)");
this.forRepaintDummy = repaint(target);
css(target, "transition", "transform " + duration + "ms" + (this.options.easing ? " " + this.options.easing : ""));
css(target, "transform", "translate3d(0,0,0)");
typeof target.animated === "number" && clearTimeout(target.animated);
target.animated = setTimeout(function() {
css(target, "transition", "");
css(target, "transform", "");
target.animated = false;
target.animatingX = false;
target.animatingY = false;
}, duration);
}
}
};
}
function repaint(target) {
return target.offsetWidth;
}
function calculateRealTime(animatingRect, fromRect, toRect, options) {
return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation;
}
var plugins = [];
var defaults = {
initializeByDefault: true
};
var PluginManager = {
mount: function mount(plugin) {
for (var option2 in defaults) {
if (defaults.hasOwnProperty(option2) && !(option2 in plugin)) {
plugin[option2] = defaults[option2];
}
}
plugins.forEach(function(p) {
if (p.pluginName === plugin.pluginName) {
throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
}
});
plugins.push(plugin);
},
pluginEvent: function pluginEvent(eventName, sortable, evt) {
var _this = this;
this.eventCanceled = false;
evt.cancel = function() {
_this.eventCanceled = true;
};
var eventNameGlobal = eventName + "Global";
plugins.forEach(function(plugin) {
if (!sortable[plugin.pluginName]) return;
if (sortable[plugin.pluginName][eventNameGlobal]) {
sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
sortable
}, evt));
}
if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
sortable[plugin.pluginName][eventName](_objectSpread2({
sortable
}, evt));
}
});
},
initializePlugins: function initializePlugins(sortable, el, defaults2, options) {
plugins.forEach(function(plugin) {
var pluginName = plugin.pluginName;
if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
var initialized = new plugin(sortable, el, sortable.options);
initialized.sortable = sortable;
initialized.options = sortable.options;
sortable[pluginName] = initialized;
_extends(defaults2, initialized.defaults);
});
for (var option2 in sortable.options) {
if (!sortable.options.hasOwnProperty(option2)) continue;
var modified = this.modifyOption(sortable, option2, sortable.options[option2]);
if (typeof modified !== "undefined") {
sortable.options[option2] = modified;
}
}
},
getEventProperties: function getEventProperties(name, sortable) {
var eventProperties = {};
plugins.forEach(function(plugin) {
if (typeof plugin.eventProperties !== "function") return;
_extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
});
return eventProperties;
},
modifyOption: function modifyOption(sortable, name, value) {
var modifiedValue;
plugins.forEach(function(plugin) {
if (!sortable[plugin.pluginName]) return;
if (plugin.optionListeners && typeof plugin.optionListeners[name] === "function") {
modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
}
});
return modifiedValue;
}
};
function dispatchEvent(_ref) {
var sortable = _ref.sortable, rootEl2 = _ref.rootEl, name = _ref.name, targetEl = _ref.targetEl, cloneEl2 = _ref.cloneEl, toEl = _ref.toEl, fromEl = _ref.fromEl, oldIndex2 = _ref.oldIndex, newIndex2 = _ref.newIndex, oldDraggableIndex2 = _ref.oldDraggableIndex, newDraggableIndex2 = _ref.newDraggableIndex, originalEvent = _ref.originalEvent, putSortable2 = _ref.putSortable, extraEventProperties = _ref.extraEventProperties;
sortable = sortable || rootEl2 && rootEl2[expando];
if (!sortable) return;
var evt, options = sortable.options, onName = "on" + name.charAt(0).toUpperCase() + name.substr(1);
if (window.CustomEvent && !IE11OrLess && !Edge) {
evt = new CustomEvent(name, {
bubbles: true,
cancelable: true
});
} else {
evt = document.createEvent("Event");
evt.initEvent(name, true, true);
}
evt.to = toEl || rootEl2;
evt.from = fromEl || rootEl2;
evt.item = targetEl || rootEl2;
evt.clone = cloneEl2;
evt.oldIndex = oldIndex2;
evt.newIndex = newIndex2;
evt.oldDraggableIndex = oldDraggableIndex2;
evt.newDraggableIndex = newDraggableIndex2;
evt.originalEvent = originalEvent;
evt.pullMode = putSortable2 ? putSortable2.lastPutMode : void 0;
var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
for (var option2 in allEventProperties) {
evt[option2] = allEventProperties[option2];
}
if (rootEl2) {
rootEl2.dispatchEvent(evt);
}
if (options[onName]) {
options[onName].call(sortable, evt);
}
}
var _excluded = ["evt"];
var pluginEvent2 = function pluginEvent3(eventName, sortable) {
var _ref = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}, originalEvent = _ref.evt, data = _objectWithoutProperties(_ref, _excluded);
PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
dragEl,
parentEl,
ghostEl,
rootEl,
nextEl,
lastDownEl,
cloneEl,
cloneHidden,
dragStarted: moved,
putSortable,
activeSortable: Sortable.active,
originalEvent,
oldIndex,
oldDraggableIndex,
newIndex,
newDraggableIndex,
hideGhostForTarget: _hideGhostForTarget,
unhideGhostForTarget: _unhideGhostForTarget,
cloneNowHidden: function cloneNowHidden() {
cloneHidden = true;
},
cloneNowShown: function cloneNowShown() {
cloneHidden = false;
},
dispatchSortableEvent: function dispatchSortableEvent(name) {
_dispatchEvent({
sortable,
name,
originalEvent
});
}
}, data));
};
function _dispatchEvent(info) {
dispatchEvent(_objectSpread2({
putSortable,
cloneEl,
targetEl: dragEl,
rootEl,
oldIndex,
oldDraggableIndex,
newIndex,
newDraggableIndex
}, info));
}
var dragEl;
var parentEl;
var ghostEl;
var rootEl;
var nextEl;
var lastDownEl;
var cloneEl;
var cloneHidden;
var oldIndex;
var newIndex;
var oldDraggableIndex;
var newDraggableIndex;
var activeGroup;
var putSortable;
var awaitingDragStarted = false;
var ignoreNextClick = false;
var sortables = [];
var tapEvt;
var touchEvt;
var lastDx;
var lastDy;
var tapDistanceLeft;
var tapDistanceTop;
var moved;
var lastTarget;
var lastDirection;
var pastFirstInvertThresh = false;
var isCircumstantialInvert = false;
var targetMoveDistance;
var ghostRelativeParent;
var ghostRelativeParentInitialScroll = [];
var _silent = false;
var savedInputChecked = [];
var documentExists = typeof document !== "undefined";
var PositionGhostAbsolutely = IOS;
var CSSFloatProperty = Edge || IE11OrLess ? "cssFloat" : "float";
var supportDraggable = documentExists && !ChromeForAndroid && !IOS && "draggable" in document.createElement("div");
var supportCssPointerEvents = function() {
if (!documentExists) return;
if (IE11OrLess) {
return false;
}
var el = document.createElement("x");
el.style.cssText = "pointer-events:auto";
return el.style.pointerEvents === "auto";
}();
var _detectDirection = function _detectDirection2(el, options) {
var elCSS = css(el), elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth), child1 = getChild(el, 0, options), child2 = getChild(el, 1, options), firstChildCSS = child1 && css(child1), secondChildCSS = child2 && css(child2), firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width, secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
if (elCSS.display === "flex") {
return elCSS.flexDirection === "column" || elCSS.flexDirection === "column-reverse" ? "vertical" : "horizontal";
}
if (elCSS.display === "grid") {
return elCSS.gridTemplateColumns.split(" ").length <= 1 ? "vertical" : "horizontal";
}
if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== "none") {
var touchingSideChild2 = firstChildCSS["float"] === "left" ? "left" : "right";
return child2 && (secondChildCSS.clear === "both" || secondChildCSS.clear === touchingSideChild2) ? "vertical" : "horizontal";
}
return child1 && (firstChildCSS.display === "block" || firstChildCSS.display === "flex" || firstChildCSS.display === "table" || firstChildCSS.display === "grid" || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === "none" || child2 && elCSS[CSSFloatProperty] === "none" && firstChildWidth + secondChildWidth > elWidth) ? "vertical" : "horizontal";
};
var _dragElInRowColumn = function _dragElInRowColumn2(dragRect, targetRect, vertical) {
var dragElS1Opp = vertical ? dragRect.left : dragRect.top, dragElS2Opp = vertical ? dragRect.right : dragRect.bottom, dragElOppLength = vertical ? dragRect.width : dragRect.height, targetS1Opp = vertical ? targetRect.left : targetRect.top, targetS2Opp = vertical ? targetRect.right : targetRect.bottom, targetOppLength = vertical ? targetRect.width : targetRect.height;
return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
};
var _detectNearestEmptySortable = function _detectNearestEmptySortable2(x, y) {
var ret;
sortables.some(function(sortable) {
var threshold = sortable[expando].options.emptyInsertThreshold;
if (!threshold || lastChild(sortable)) return;
var rect = getRect(sortable), insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold, insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
if (insideHorizontally && insideVertically) {
return ret = sortable;
}
});
return ret;
};
var _prepareGroup = function _prepareGroup2(options) {
function toFn(value, pull) {
return function(to, from, dragEl2, evt) {
var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
if (value == null && (pull || sameGroup)) {
return true;
} else if (value == null || value === false) {
return false;
} else if (pull && value === "clone") {
return value;
} else if (typeof value === "function") {
return toFn(value(to, from, dragEl2, evt), pull)(to, from, dragEl2, evt);
} else {
var otherGroup = (pull ? to : from).options.group.name;
return value === true || typeof value === "string" && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
}
};
}
var group = {};
var originalGroup = options.group;
if (!originalGroup || _typeof(originalGroup) != "object") {
originalGroup = {
name: originalGroup
};
}
group.name = originalGroup.name;
group.checkPull = toFn(originalGroup.pull, true);
group.checkPut = toFn(originalGroup.put);
group.revertClone = originalGroup.revertClone;
options.group = group;
};
var _hideGhostForTarget = function _hideGhostForTarget2() {
if (!supportCssPointerEvents && ghostEl) {
css(ghostEl, "display", "none");
}
};
var _unhideGhostForTarget = function _unhideGhostForTarget2() {
if (!supportCssPointerEvents && ghostEl) {
css(ghostEl, "display", "");
}
};
if (documentExists && !ChromeForAndroid) {
document.addEventListener("click", function(evt) {
if (ignoreNextClick) {
evt.preventDefault();
evt.stopPropagation && evt.stopPropagation();
evt.stopImmediatePropagation && evt.stopImmediatePropagation();
ignoreNextClick = false;
return false;
}
}, true);
}
var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent2(evt) {
if (dragEl) {
evt = evt.touches ? evt.touches[0] : evt;
var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
if (nearest) {
var event = {};
for (var i in evt) {
if (evt.hasOwnProperty(i)) {
event[i] = evt[i];
}
}
event.target = event.rootEl = nearest;
event.preventDefault = void 0;
event.stopPropagation = void 0;
nearest[expando]._onDragOver(event);
}
}
};
var _checkOutsideTargetEl = function _checkOutsideTargetEl2(evt) {
if (dragEl) {
dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
}
};
function Sortable(el, options) {
if (!(el && el.nodeType && el.nodeType === 1)) {
throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
}
this.el = el;
this.options = options = _extends({}, options);
el[expando] = this;
var defaults2 = {
group: null,
sort: true,
disabled: false,
store: null,
handle: null,
draggable: /^[uo]l$/i.test(el.nodeName) ? ">li" : ">*",
swapThreshold: 1,
// percentage; 0 <= x <= 1
invertSwap: false,
// invert always
invertedSwapThreshold: null,
// will be set to same as swapThreshold if default
removeCloneOnHide: true,
direction: function direction() {
return _detectDirection(el, this.options);
},
ghostClass: "sortable-ghost",
chosenClass: "sortable-chosen",
dragClass: "sortable-drag",
ignore: "a, img",
filter: null,
preventOnFilter: true,
animation: 0,
easing: null,
setData: function setData(dataTransfer, dragEl2) {
dataTransfer.setData("Text", dragEl2.textContent);
},
dropBubble: false,
dragoverBubble: false,
dataIdAttr: "data-id",
delay: 0,
delayOnTouchOnly: false,
touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
forceFallback: false,
fallbackClass: "sortable-fallback",
fallbackOnBody: false,
fallbackTolerance: 0,
fallbackOffset: {
x: 0,
y: 0
},
// Disabled on Safari: #1571; Enabled on Safari IOS: #2244
supportPointer: Sortable.supportPointer !== false && "PointerEvent" in window && (!Safari || IOS),
emptyInsertThreshold: 5
};
PluginManager.initializePlugins(this, el, defaults2);
for (var name in defaults2) {
!(name in options) && (options[name] = defaults2[name]);
}
_prepareGroup(options);
for (var fn in this) {
if (fn.charAt(0) === "_" && typeof this[fn] === "function") {
this[fn] = this[fn].bind(this);
}
}
this.nativeDraggable = options.forceFallback ? false : supportDraggable;
if (this.nativeDraggable) {
this.options.touchStartThreshold = 1;
}
if (options.supportPointer) {
on(el, "pointerdown", this._onTapStart);
} else {
on(el, "mousedown", this._onTapStart);
on(el, "touchstart", this._onTapStart);
}
if (this.nativeDraggable) {
on(el, "dragover", this);
on(el, "dragenter", this);
}
sortables.push(this.el);
options.store && options.store.get && this.sort(options.store.get(this) || []);
_extends(this, AnimationStateManager());
}
Sortable.prototype = /** @lends Sortable.prototype */
{
constructor: Sortable,
_isOutsideThisEl: function _isOutsideThisEl(target) {
if (!this.el.contains(target) && target !== this.el) {
lastTarget = null;
}
},
_getDirection: function _getDirection(evt, target) {
return typeof this.options.direction === "function" ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
},
_onTapStart: function _onTapStart(evt) {
if (!evt.cancelable) return;
var _this = this, el = this.el, options = this.options, preventOnFilter = options.preventOnFilter, type = evt.type, touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === "touch" && evt, target = (touch || evt).target, originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target, filter = options.filter;
_saveInputCheckedState(el);
if (dragEl) {
return;
}
if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
return;
}
if (originalTarget.isContentEditable) {
return;
}
if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === "SELECT") {
return;
}
target = closest(target, options.draggable, el, false);
if (target && target.animated) {
return;
}
if (lastDownEl === target) {
return;
}
oldIndex = index(target);
oldDraggableIndex = index(target, options.draggable);
if (typeof filter === "function") {
if (filter.call(this, evt, target, this)) {
_dispatchEvent({
sortable: _this,
rootEl: originalTarget,
name: "filter",
targetEl: target,
toEl: el,
fromEl: el
});
pluginEvent2("filter", _this, {
evt
});
preventOnFilter && evt.preventDefault();
return;
}
} else if (filter) {
filter = filter.split(",").some(function(criteria) {
criteria = closest(originalTarget, criteria.trim(), el, false);
if (criteria) {
_dispatchEvent({
sortable: _this,
rootEl: criteria,
name: "filter",
targetEl: target,
fromEl: el,
toEl: el
});
pluginEvent2("filter", _this, {
evt
});
return true;
}
});
if (filter) {
preventOnFilter && evt.preventDefault();
return;
}
}
if (options.handle && !closest(originalTarget, options.handle, el, false)) {
return;
}
this._prepareDragStart(evt, touch, target);
},
_prepareDragStart: function _prepareDragStart(evt, touch, target) {
var _this = this, el = _this.el, options = _this.options, ownerDocument = el.ownerDocument, dragStartFn;
if (target && !dragEl && target.parentNode === el) {
var dragRect = getRect(target);
rootEl = el;
dragEl = target;
parentEl = dragEl.parentNode;
nextEl = dragEl.nextSibling;
lastDownEl = target;
activeGroup = options.group;
Sortable.dragged = dragEl;
tapEvt = {
target: dragEl,
clientX: (touch || evt).clientX,
clientY: (touch || evt).clientY
};
tapDistanceLeft = tapEvt.clientX - dragRect.left;
tapDistanceTop = tapEvt.clientY - dragRect.top;
this._lastX = (touch || evt).clientX;
this._lastY = (touch || evt).clientY;
dragEl.style["will-change"] = "all";
dragStartFn = function dragStartFn2() {
pluginEvent2("delayEnded", _this, {
evt
});
if (Sortable.eventCanceled) {
_this._onDrop();
return;
}
_this._disableDelayedDragEvents();
if (!FireFox && _this.nativeDraggable) {
dragEl.draggable = true;
}
_this._triggerDragStart(evt, touch);
_dispatchEvent({
sortable: _this,
name: "choose",
originalEvent: evt
});
toggleClass(dragEl, options.chosenClass, true);
};
options.ignore.split(",").forEach(function(criteria) {
find(dragEl, criteria.trim(), _disableDraggable);
});
on(ownerDocument, "dragover", nearestEmptyInsertDetectEvent);
on(ownerDocument, "mousemove", nearestEmptyInsertDetectEvent);
on(ownerDocument, "touchmove", nearestEmptyInsertDetectEvent);
if (options.supportPointer) {
on(ownerDocument, "pointerup", _this._onDrop);
!this.nativeDraggable && on(ownerDocument, "pointercancel", _this._onDrop);
} else {
on(ownerDocument, "mouseup", _this._onDrop);
on(ownerDocument, "touchend", _this._onDrop);
on(ownerDocument, "touchcancel", _this._onDrop);
}
if (FireFox && this.nativeDraggable) {
this.options.touchStartThreshold = 4;
dragEl.draggable = true;
}
pluginEvent2("delayStart", this, {
evt
});
if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
if (Sortable.eventCanceled) {
this._onDrop();
return;
}
if (options.supportPointer) {
on(ownerDocument, "pointerup", _this._disableDelayedDrag);
on(ownerDocument, "pointercancel", _this._disableDelayedDrag);
} else {
on(ownerDocument, "mouseup", _this._disableDelayedDrag);
on(ownerDocument, "touchend", _this._disableDelayedDrag);
on(ownerDocument, "touchcancel", _this._disableDelayedDrag);
}
on(ownerDocument, "mousemove", _this._delayedDragTouchMoveHandler);
on(ownerDocument, "touchmove", _this._delayedDragTouchMoveHandler);
options.supportPointer && on(ownerDocument, "pointermove", _this._delayedDragTouchMoveHandler);
_this._dragStartTimer = setTimeout(dragStartFn, options.delay);
} else {
dragStartFn();
}
}
},
_delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler(e) {
var touch = e.touches ? e.touches[0] : e;
if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) {
this._disableDelayedDrag();
}
},
_disableDelayedDrag: function _disableDelayedDrag() {
dragEl && _disableDraggable(dragEl);
clearTimeout(this._dragStartTimer);
this._disableDelayedDragEvents();
},
_disableDelayedDragEvents: function _disableDelayedDragEvents() {
var ownerDocument = this.el.ownerDocument;
off(ownerDocument, "mouseup", this._disableDelayedDrag);
off(ownerDocument, "touchend", this._disableDelayedDrag);
off(ownerDocument, "touchcancel", this._disableDelayedDrag);
off(ownerDocument, "pointerup", this._disableDelayedDrag);
off(ownerDocument, "pointercancel", this._disableDelayedDrag);
off(ownerDocument, "mousemove", this._delayedDragTouchMoveHandler);
off(ownerDocument, "touchmove", this._delayedDragTouchMoveHandler);
off(ownerDocument, "pointermove", this._delayedDragTouchMoveHandler);
},
_triggerDragStart: function _triggerDragStart(evt, touch) {
touch = touch || evt.pointerType == "touch" && evt;
if (!this.nativeDraggable || touch) {
if (this.options.supportPointer) {
on(document, "pointermove", this._onTouchMove);
} else if (touch) {
on(document, "touchmove", this._onTouchMove);
} else {
on(document, "mousemove", this._onTouchMove);
}
} else {
on(dragEl, "dragend", this);
on(rootEl, "dragstart", this._onDragStart);
}
try {
if (document.selection) {
_nextTick(function() {
document.selection.empty();
});
} else {
window.getSelection().removeAllRanges();
}
} catch (err) {
}
},
_dragStarted: function _dragStarted(fallback, evt) {
awaitingDragStarted = false;
if (rootEl && dragEl) {
pluginEvent2("dragStarted", this, {
evt
});
if (this.nativeDraggable) {
on(document, "dragover", _checkOutsideTargetEl);
}
var options = this.options;
!fallback && toggleClass(dragEl, options.dragClass, false);
toggleClass(dragEl, options.ghostClass, true);
Sortable.active = this;
fallback && this._appendGhost();
_dispatchEvent({
sortable: this,
name: "start",
originalEvent: evt
});
} else {
this._nulling();
}
},
_emulateDragOver: function _emulateDragOver() {
if (touchEvt) {
this._lastX = touchEvt.clientX;
this._lastY = touchEvt.clientY;
_hideGhostForTarget();
var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
var parent = target;
while (target && target.shadowRoot) {
target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
if (target === parent) break;
parent = target;
}
dragEl.parentNode[expando]._isOutsideThisEl(target);
if (parent) {
do {
if (parent[expando]) {
var inserted = void 0;
inserted = parent[expando]._onDragOver({
clientX: touchEvt.clientX,
clientY: touchEvt.clientY,
target,
rootEl: parent
});
if (inserted && !this.options.dragoverBubble) {
break;
}
}
target = parent;
} while (parent = getParentOrHost(parent));
}
_unhideGhostForTarget();
}
},
_onTouchMove: function _onTouchMove(evt) {
if (tapEvt) {
var options = this.options, fallbackTolerance = options.fallbackTolerance, fallbackOffset = options.fallbackOffset, touch = evt.touches ? evt.touches[0] : evt, ghostMatrix = ghostEl && matrix(ghostEl, true), scaleX = ghostEl && ghostMatrix && ghostMatrix.a, scaleY = ghostEl && ghostMatrix && ghostMatrix.d, relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent), dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1), dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1);
if (!Sortable.active && !awaitingDragStarted) {
if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
return;
}
this._onDragStart(evt, true);
}
if (ghostEl) {
if (ghostMatrix) {
ghostMatrix.e += dx - (lastDx || 0);
ghostMatrix.f += dy - (lastDy || 0);
} else {
ghostMatrix = {
a: 1,
b: 0,
c: 0,
d: 1,
e: dx,
f: dy
};
}
var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
css(ghostEl, "webkitTransform", cssMatrix);
css(ghostEl, "mozTransform", cssMatrix);
css(ghostEl, "msTransform", cssMatrix);
css(ghostEl, "transform", cssMatrix);
lastDx = dx;
lastDy = dy;
touchEvt = touch;
}
evt.cancelable && evt.preventDefault();
}
},
_appendGhost: function _appendGhost() {
if (!ghostEl) {
var container = this.options.fallbackOnBody ? document.body : rootEl, rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container), options = this.options;
if (PositionGhostAbsolutely) {
ghostRelativeParent = container;
while (css(ghostRelativeParent, "position") === "static" && css(ghostRelativeParent, "transform") === "none" && ghostRelativeParent !== document) {
ghostRelativeParent = ghostRelativeParent.parentNode;
}
if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
rect.top += ghostRelativeParent.scrollTop;
rect.left += ghostRelativeParent.scrollLeft;
} else {
ghostRelativeParent = getWindowScrollingElement();
}
ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
}
ghostEl = dragEl.cloneNode(true);
toggleClass(ghostEl, options.ghostClass, false);
toggleClass(ghostEl, options.fallbackClass, true);
toggleClass(ghostEl, options.dragClass, true);
css(ghostEl, "transition", "");
css(ghostEl, "transform", "");
css(ghostEl, "box-sizing", "border-box");
css(ghostEl, "margin", 0);
css(ghostEl, "top", rect.top);
css(ghostEl, "left", rect.left);
css(ghostEl, "width", rect.width);
css(ghostEl, "height", rect.height);
css(ghostEl, "opacity", "0.8");
css(ghostEl, "position", PositionGhostAbsolutely ? "absolute" : "fixed");
css(ghostEl, "zIndex", "100000");
css(ghostEl, "pointerEvents", "none");
Sortable.ghost = ghostEl;
container.appendChild(ghostEl);
css(ghostEl, "transform-origin", tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + "% " + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + "%");
}
},
_onDragStart: function _onDragStart(evt, fallback) {
var _this = this;
var dataTransfer = evt.dataTransfer;
var options = _this.options;
pluginEvent2("dragStart", this, {
evt
});
if (Sortable.eventCanceled) {
this._onDrop();
return;
}
pluginEvent2("setupClone", this);
if (!Sortable.eventCanceled) {
cloneEl = clone(dragEl);
cloneEl.removeAttribute("id");
cloneEl.draggable = false;
cloneEl.style["will-change"] = "";
this._hideClone();
toggleClass(cloneEl, this.options.chosenClass, false);
Sortable.clone = cloneEl;
}
_this.cloneId = _nextTick(function() {
pluginEvent2("clone", _this);
if (Sortable.eventCanceled) return;
if (!_this.options.removeCloneOnHide) {
rootEl.insertBefore(cloneEl, dragEl);
}
_this._hideClone();
_dispatchEvent({
sortable: _this,
name: "clone"
});
});
!fallback && toggleClass(dragEl, options.dragClass, true);
if (fallback) {
ignoreNextClick = true;
_this._loopId = setInterval(_this._emulateDragOver, 50);
} else {
off(document, "mouseup", _this._onDrop);
off(document, "touchend", _this._onDrop);
off(document, "touchcancel", _this._onDrop);
if (dataTransfer) {
dataTransfer.effectAllowed = "move";
options.setData && options.setData.call(_this, dataTransfer, dragEl);
}
on(document, "drop", _this);
css(dragEl, "transform", "translateZ(0)");
}
awaitingDragStarted = true;
_this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
on(document, "selectstart", _this);
moved = true;
window.getSelection().removeAllRanges();
if (Safari) {
css(document.body, "user-select", "none");
}
},
// Returns true - if no further action is needed (either inserted or another condition)
_onDragOver: function _onDragOver(evt) {
var el = this.el, target = evt.target, dragRect, targetRect, revert, options = this.options, group = options.group, activeSortable = Sortable.active, isOwner = activeGroup === group, canSort = options.sort, fromSortable = putSortable || activeSortable, vertical, _this = this, completedFired = false;
if (_silent) return;
function dragOverEvent(name, extra) {
pluginEvent2(name, _this, _objectSpread2({
evt,
isOwner,
axis: vertical ? "vertical" : "horizontal",
revert,
dragRect,
targetRect,
canSort,
fromSortable,
target,
completed,
onMove: function onMove(target2, after2) {
return _onMove(rootEl, el, dragEl, dragRect, target2, getRect(target2), evt, after2);
},
changed
}, extra));
}
function capture() {
dragOverEvent("dragOverAnimationCapture");
_this.captureAnimationState();
if (_this !== fromSortable) {
fromSortable.captureAnimationState();
}
}
function completed(insertion) {
dragOverEvent("dragOverCompleted", {
insertion
});
if (insertion) {
if (isOwner) {
activeSortable._hideClone();
} else {
activeSortable._showClone(_this);
}
if (_this !== fromSortable) {
toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
toggleClass(dragEl, options.ghostClass, true);
}
if (putSortable !== _this && _this !== Sortable.active) {
putSortable = _this;
} else if (_this === Sortable.active && putSortable) {
putSortable = null;
}
if (fromSortable === _this) {
_this._ignoreWhileAnimating = target;
}
_this.animateAll(function() {
dragOverEvent("dragOverAnimationComplete");
_this._ignoreWhileAnimating = null;
});
if (_this !== fromSortable) {
fromSortable.animateAll();
fromSortable._ignoreWhileAnimating = null;
}
}
if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
lastTarget = null;
}
if (!options.dragoverBubble && !evt.rootEl && target !== document) {
dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
!insertion && nearestEmptyInsertDetectEvent(evt);
}
!options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
return completedFired = true;
}
function changed() {
newIndex = index(dragEl);
newDraggableIndex = index(dragEl, options.draggable);
_dispatchEvent({
sortable: _this,
name: "change",
toEl: el,
newIndex,
newDraggableIndex,
originalEvent: evt
});
}
if (evt.preventDefault !== void 0) {
evt.cancelable && evt.preventDefault();
}
target = closest(target, options.draggable, el, true);
dragOverEvent("dragOver");
if (Sortable.eventCanceled) return completedFired;
if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
return completed(false);
}
ignoreNextClick = false;
if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
vertical = this._getDirection(evt, target) === "vertical";
dragRect = getRect(dragEl);
dragOverEvent("dragOverValid");
if (Sortable.eventCanceled) return completedFired;
if (revert) {
parentEl = rootEl;
capture();
this._hideClone();
dragOverEvent("revert");
if (!Sortable.eventCanceled) {
if (nextEl) {
rootEl.insertBefore(dragEl, nextEl);
} else {
rootEl.appendChild(dragEl);
}
}
return completed(true);
}
var elLastChild = lastChild(el, options.draggable);
if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
if (elLastChild === dragEl) {
return completed(false);
}
if (elLastChild && el === evt.target) {
target = elLastChild;
}
if (target) {
targetRect = getRect(target);
}
if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
capture();
if (elLastChild && elLastChild.nextSibling) {
el.insertBefore(dragEl, elLastChild.nextSibling);
} else {
el.appendChild(dragEl);
}
parentEl = el;
changed();
return completed(true);
}
} else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
var firstChild = getChild(el, 0, options, true);
if (firstChild === dragEl) {
return completed(false);
}
target = firstChild;
targetRect = getRect(target);
if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
capture();
el.insertBefore(dragEl, firstChild);
parentEl = el;
changed();
return completed(true);
}
} else if (target.parentNode === el) {
targetRect = getRect(target);
var direction = 0, targetBeforeFirstSwap, differentLevel = dragEl.parentNode !== el, differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical), side1 = vertical ? "top" : "left", scrolledPastTop = isScrolledPast(target, "top", "top") || isScrolledPast(dragEl, "top", "top"), scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
if (lastTarget !== target) {
targetBeforeFirstSwap = targetRect[side1];
pastFirstInvertThresh = false;
isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
}
direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
var sibling;
if (direction !== 0) {
var dragIndex = index(dragEl);
do {
dragIndex -= direction;
sibling = parentEl.children[dragIndex];
} while (sibling && (css(sibling, "display") === "none" || sibling === ghostEl));
}
if (direction === 0 || sibling === target) {
return completed(false);
}
lastTarget = target;
lastDirection = direction;
var nextSibling = target.nextElementSibling, after = false;
after = direction === 1;
var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
if (moveVector !== false) {
if (moveVector === 1 || moveVector === -1) {
after = moveVector === 1;
}
_silent = true;
setTimeout(_unsilent, 30);
capture();
if (after && !nextSibling) {
el.appendChild(dragEl);
} else {
target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
}
if (scrolledPastTop) {
scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
}
parentEl = dragEl.parentNode;
if (targetBeforeFirstSwap !== void 0 && !isCircumstantialInvert) {
targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
}
changed();
return completed(true);
}
}
if (el.contains(dragEl)) {
return completed(false);
}
}
return false;
},
_ignoreWhileAnimating: null,
_offMoveEvents: function _offMoveEvents() {
off(document, "mousemove", this._onTouchMove);
off(document, "touchmove", this._onTouchMove);
off(document, "pointermove", this._onTouchMove);
off(document, "dragover", nearestEmptyInsertDetectEvent);
off(document, "mousemove", nearestEmptyInsertDetectEvent);
off(document, "touchmove", nearestEmptyInsertDetectEvent);
},
_offUpEvents: function _offUpEvents() {
var ownerDocument = this.el.ownerDocument;
off(ownerDocument, "mouseup", this._onDrop);
off(ownerDocument, "touchend", this._onDrop);
off(ownerDocument, "pointerup", this._onDrop);
off(ownerDocument, "pointercancel", this._onDrop);
off(ownerDocument, "touchcancel", this._onDrop);
off(document, "selectstart", this);
},
_onDrop: function _onDrop(evt) {
var el = this.el, options = this.options;
newIndex = index(dragEl);
newDraggableIndex = index(dragEl, options.draggable);
pluginEvent2("drop", this, {
evt
});
parentEl = dragEl && dragEl.parentNode;
newIndex = index(dragEl);
newDraggableIndex = index(dragEl, options.draggable);
if (Sortable.eventCanceled) {
this._nulling();
return;
}
awaitingDragStarted = false;
isCircumstantialInvert = false;
pastFirstInvertThresh = false;
clearInterval(this._loopId);
clearTimeout(this._dragStartTimer);
_cancelNextTick(this.cloneId);
_cancelNextTick(this._dragStartId);
if (this.nativeDraggable) {
off(document, "drop", this);
off(el, "dragstart", this._onDragStart);
}
this._offMoveEvents();
this._offUpEvents();
if (Safari) {
css(document.body, "user-select", "");
}
css(dragEl, "transform", "");
if (evt) {
if (moved) {
evt.cancelable && evt.preventDefault();
!options.dropBubble && evt.stopPropagation();
}
ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== "clone") {
cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
}
if (dragEl) {
if (this.nativeDraggable) {
off(dragEl, "dragend", this);
}
_disableDraggable(dragEl);
dragEl.style["will-change"] = "";
if (moved && !awaitingDragStarted) {
toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
}
toggleClass(dragEl, this.options.chosenClass, false);
_dispatchEvent({
sortable: this,
name: "unchoose",
toEl: parentEl,
newIndex: null,
newDraggableIndex: null,
originalEvent: evt
});
if (rootEl !== parentEl) {
if (newIndex >= 0) {
_dispatchEvent({
rootEl: parentEl,
name: "add",
toEl: parentEl,
fromEl: rootEl,
originalEvent: evt
});
_dispatchEvent({
sortable: this,
name: "remove",
toEl: parentEl,
originalEvent: evt
});
_dispatchEvent({
rootEl: parentEl,
name: "sort",
toEl: parentEl,
fromEl: rootEl,
originalEvent: evt
});
_dispatchEvent({
sortable: this,
name: "sort",
toEl: parentEl,
originalEvent: evt
});
}
putSortable && putSortable.save();
} else {
if (newIndex !== oldIndex) {
if (newIndex >= 0) {
_dispatchEvent({
sortable: this,
name: "update",
toEl: parentEl,
originalEvent: evt
});
_dispatchEvent({
sortable: this,
name: "sort",
toEl: parentEl,
originalEvent: evt
});
}
}
}
if (Sortable.active) {
if (newIndex == null || newIndex === -1) {
newIndex = oldIndex;
newDraggableIndex = oldDraggableIndex;
}
_dispatchEvent({
sortable: this,
name: "end",
toEl: parentEl,
originalEvent: evt
});
this.save();
}
}
}
this._nulling();
},
_nulling: function _nulling() {
pluginEvent2("nulling", this);
rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null;
var el = this.el;
savedInputChecked.forEach(function(checkEl) {
if (el.contains(checkEl)) {
checkEl.checked = true;
}
});
savedInputChecked.length = lastDx = lastDy = 0;
},
handleEvent: function handleEvent(evt) {
switch (evt.type) {
case "drop":
case "dragend":
this._onDrop(evt);
break;
case "dragenter":
case "dragover":
if (dragEl) {
this._onDragOver(evt);
_globalDragOver(evt);
}
break;
case "selectstart":
evt.preventDefault();
break;
}
},
/**
* Serializes the item into an array of string.
* @returns {String[]}
*/
toArray: function toArray() {
var order = [], el, children = this.el.children, i = 0, n = children.length, options = this.options;
for (; i < n; i++) {
el = children[i];
if (closest(el, options.draggable, this.el, false)) {
order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
}
}
return order;
},
/**
* Sorts the elements according to the array.
* @param {String[]} order order of the items
*/
sort: function sort(order, useAnimation) {
var items = {}, rootEl2 = this.el;
this.toArray().forEach(function(id, i) {
var el = rootEl2.children[i];
if (closest(el, this.options.draggable, rootEl2, false)) {
items[id] = el;
}
}, this);
useAnimation && this.captureAnimationState();
order.forEach(function(id) {
if (items[id]) {
rootEl2.removeChild(items[id]);
rootEl2.appendChild(items[id]);
}
});
useAnimation && this.animateAll();
},
/**
* Save the current sorting
*/
save: function save() {
var store = this.options.store;
store && store.set && store.set(this);
},
/**
* For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
* @param {HTMLElement} el
* @param {String} [selector] default: `options.draggable`
* @returns {HTMLElement|null}
*/
closest: function closest$1(el, selector) {
return closest(el, selector || this.options.draggable, this.el, false);
},
/**
* Set/get option
* @param {string} name
* @param {*} [value]
* @returns {*}
*/
option: function option(name, value) {
var options = this.options;
if (value === void 0) {
return options[name];
} else {
var modifiedValue = PluginManager.modifyOption(this, name, value);
if (typeof modifiedValue !== "undefined") {
options[name] = modifiedValue;
} else {
options[name] = value;
}
if (name === "group") {
_prepareGroup(options);
}
}
},
/**
* Destroy
*/
destroy: function destroy() {
pluginEvent2("destroy", this);
var el = this.el;
el[expando] = null;
off(el, "mousedown", this._onTapStart);
off(el, "touchstart", this._onTapStart);
off(el, "pointerdown", this._onTapStart);
if (this.nativeDraggable) {
off(el, "dragover", this);
off(el, "dragenter", this);
}
Array.prototype.forEach.call(el.querySelectorAll("[draggable]"), function(el2) {
el2.removeAttribute("draggable");
});
this._onDrop();
this._disableDelayedDragEvents();
sortables.splice(sortables.indexOf(this.el), 1);
this.el = el = null;
},
_hideClone: function _hideClone() {
if (!cloneHidden) {
pluginEvent2("hideClone", this);
if (Sortable.eventCanceled) return;
css(cloneEl, "display", "none");
if (this.options.removeCloneOnHide && cloneEl.parentNode) {
cloneEl.parentNode.removeChild(cloneEl);
}
cloneHidden = true;
}
},
_showClone: function _showClone(putSortable2) {
if (putSortable2.lastPutMode !== "clone") {
this._hideClone();
return;
}
if (cloneHidden) {
pluginEvent2("showClone", this);
if (Sortable.eventCanceled) return;
if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
rootEl.insertBefore(cloneEl, dragEl);
} else if (nextEl) {
rootEl.insertBefore(cloneEl, nextEl);
} else {
rootEl.appendChild(cloneEl);
}
if (this.options.group.revertClone) {
this.animate(dragEl, cloneEl);
}
css(cloneEl, "display", "");
cloneHidden = false;
}
}
};
function _globalDragOver(evt) {
if (evt.dataTransfer) {
evt.dataTransfer.dropEffect = "move";
}
evt.cancelable && evt.preventDefault();
}
function _onMove(fromEl, toEl, dragEl2, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
var evt, sortable = fromEl[expando], onMoveFn = sortable.options.onMove, retVal;
if (window.CustomEvent && !IE11OrLess && !Edge) {
evt = new CustomEvent("move", {
bubbles: true,
cancelable: true
});
} else {
evt = document.createEvent("Event");
evt.initEvent("move", true, true);
}
evt.to = toEl;
evt.from = fromEl;
evt.dragged = dragEl2;
evt.draggedRect = dragRect;
evt.related = targetEl || toEl;
evt.relatedRect = targetRect || getRect(toEl);
evt.willInsertAfter = willInsertAfter;
evt.originalEvent = originalEvent;
fromEl.dispatchEvent(evt);
if (onMoveFn) {
retVal = onMoveFn.call(sortable, evt, originalEvent);
}
return retVal;
}
function _disableDraggable(el) {
el.draggable = false;
}
function _unsilent() {
_silent = false;
}
function _ghostIsFirst(evt, vertical, sortable) {
var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true));
var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
var spacer = 10;
return vertical ? evt.clientX < childContainingRect.left - spacer || evt.clientY < firstElRect.top && evt.clientX < firstElRect.right : evt.clientY < childContainingRect.top - spacer || evt.clientY < firstElRect.bottom && evt.clientX < firstElRect.left;
}
function _ghostIsLast(evt, vertical, sortable) {
var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable));
var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
var spacer = 10;
return vertical ? evt.clientX > childContainingRect.right + spacer || evt.clientY > lastElRect.bottom && evt.clientX > lastElRect.left : evt.clientY > childContainingRect.bottom + spacer || evt.clientX > lastElRect.right && evt.clientY > lastElRect.top;
}
function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
var mouseOnAxis = vertical ? evt.clientY : evt.clientX, targetLength = vertical ? targetRect.height : targetRect.width, targetS1 = vertical ? targetRect.top : targetRect.left, targetS2 = vertical ? targetRect.bottom : targetRect.right, invert = false;
if (!invertSwap) {
if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
pastFirstInvertThresh = true;
}
if (!pastFirstInvertThresh) {
if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance : mouseOnAxis > targetS2 - targetMoveDistance) {
return -lastDirection;
}
} else {
invert = true;
}
} else {
if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
return _getInsertDirection(target);
}
}
}
invert = invert || invertSwap;
if (invert) {
if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
}
}
return 0;
}
function _getInsertDirection(target) {
if (index(dragEl) < index(target)) {
return 1;
} else {
return -1;
}
}
function _generateId(el) {
var str = el.tagName + el.className + el.src + el.href + el.textContent, i = str.length, sum = 0;
while (i--) {
sum += str.charCodeAt(i);
}
return sum.toString(36);
}
function _saveInputCheckedState(root) {
savedInputChecked.length = 0;
var inputs = root.getElementsByTagName("input");
var idx = inputs.length;
while (idx--) {
var el = inputs[idx];
el.checked && savedInputChecked.push(el);
}
}
function _nextTick(fn) {
return setTimeout(fn, 0);
}
function _cancelNextTick(id) {
return clearTimeout(id);
}
if (documentExists) {
on(document, "touchmove", function(evt) {
if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
evt.preventDefault();
}
});
}
Sortable.utils = {
on,
off,
css,
find,
is: function is(el, selector) {
return !!closest(el, selector, el, false);
},
extend,
throttle,
closest,
toggleClass,
clone,
index,
nextTick: _nextTick,
cancelNextTick: _cancelNextTick,
detectDirection: _detectDirection,
getChild,
expando
};
Sortable.get = function(element) {
return element[expando];
};
Sortable.mount = function() {
for (var _len = arguments.length, plugins2 = new Array(_len), _key = 0; _key < _len; _key++) {
plugins2[_key] = arguments[_key];
}
if (plugins2[0].constructor === Array) plugins2 = plugins2[0];
plugins2.forEach(function(plugin) {
if (!plugin.prototype || !plugin.prototype.constructor) {
throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
}
if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
PluginManager.mount(plugin);
});
};
Sortable.create = function(el, options) {
return new Sortable(el, options);
};
Sortable.version = version;
var autoScrolls = [];
var scrollEl;
var scrollRootEl;
var scrolling = false;
var lastAutoScrollX;
var lastAutoScrollY;
var touchEvt$1;
var pointerElemChangedInterval;
function AutoScrollPlugin() {
function AutoScroll() {
this.defaults = {
scroll: true,
forceAutoScrollFallback: false,
scrollSensitivity: 30,
scrollSpeed: 10,
bubbleScroll: true
};
for (var fn in this) {
if (fn.charAt(0) === "_" && typeof this[fn] === "function") {
this[fn] = this[fn].bind(this);
}
}
}
AutoScroll.prototype = {
dragStarted: function dragStarted(_ref) {
var originalEvent = _ref.originalEvent;
if (this.sortable.nativeDraggable) {
on(document, "dragover", this._handleAutoScroll);
} else {
if (this.options.supportPointer) {
on(document, "pointermove", this._handleFallbackAutoScroll);
} else if (originalEvent.touches) {
on(document, "touchmove", this._handleFallbackAutoScroll);
} else {
on(document, "mousemove", this._handleFallbackAutoScroll);
}
}
},
dragOverCompleted: function dragOverCompleted(_ref2) {
var originalEvent = _ref2.originalEvent;
if (!this.options.dragOverBubble && !originalEvent.rootEl) {
this._handleAutoScroll(originalEvent);
}
},
drop: function drop3() {
if (this.sortable.nativeDraggable) {
off(document, "dragover", this._handleAutoScroll);
} else {
off(document, "pointermove", this._handleFallbackAutoScroll);
off(document, "touchmove", this._handleFallbackAutoScroll);
off(document, "mousemove", this._handleFallbackAutoScroll);
}
clearPointerElemChangedInterval();
clearAutoScrolls();
cancelThrottle();
},
nulling: function nulling() {
touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
autoScrolls.length = 0;
},
_handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
this._handleAutoScroll(evt, true);
},
_handleAutoScroll: function _handleAutoScroll(evt, fallback) {
var _this = this;
var x = (evt.touches ? evt.touches[0] : evt).clientX, y = (evt.touches ? evt.touches[0] : evt).clientY, elem = document.elementFromPoint(x, y);
touchEvt$1 = evt;
if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) {
autoScroll(evt, this.options, elem, fallback);
var ogElemScroller = getParentAutoScrollElement(elem, true);
if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
pointerElemChangedInterval && clearPointerElemChangedInterval();
pointerElemChangedInterval = setInterval(function() {
var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
if (newElem !== ogElemScroller) {
ogElemScroller = newElem;
clearAutoScrolls();
}
autoScroll(evt, _this.options, newElem, fallback);
}, 10);
lastAutoScrollX = x;
lastAutoScrollY = y;
}
} else {
if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
clearAutoScrolls();
return;
}
autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
}
}
};
return _extends(AutoScroll, {
pluginName: "scroll",
initializeByDefault: true
});
}
function clearAutoScrolls() {
autoScrolls.forEach(function(autoScroll2) {
clearInterval(autoScroll2.pid);
});
autoScrolls = [];
}
function clearPointerElemChangedInterval() {
clearInterval(pointerElemChangedInterval);
}
var autoScroll = throttle(function(evt, options, rootEl2, isFallback) {
if (!options.scroll) return;
var x = (evt.touches ? evt.touches[0] : evt).clientX, y = (evt.touches ? evt.touches[0] : evt).clientY, sens = options.scrollSensitivity, speed = options.scrollSpeed, winScroller = getWindowScrollingElement();
var scrollThisInstance = false, scrollCustomFn;
if (scrollRootEl !== rootEl2) {
scrollRootEl = rootEl2;
clearAutoScrolls();
scrollEl = options.scroll;
scrollCustomFn = options.scrollFn;
if (scrollEl === true) {
scrollEl = getParentAutoScrollElement(rootEl2, true);
}
}
var layersOut = 0;
var currentParent = scrollEl;
do {
var el = currentParent, rect = getRect(el), top = rect.top, bottom = rect.bottom, left = rect.left, right = rect.right, width = rect.width, height = rect.height, canScrollX = void 0, canScrollY = void 0, scrollWidth = el.scrollWidth, scrollHeight = el.scrollHeight, elCSS = css(el), scrollPosX = el.scrollLeft, scrollPosY = el.scrollTop;
if (el === winScroller) {
canScrollX = width < scrollWidth && (elCSS.overflowX === "auto" || elCSS.overflowX === "scroll" || elCSS.overflowX === "visible");
canScrollY = height < scrollHeight && (elCSS.overflowY === "auto" || elCSS.overflowY === "scroll" || elCSS.overflowY === "visible");
} else {
canScrollX = width < scrollWidth && (elCSS.overflowX === "auto" || elCSS.overflowX === "scroll");
canScrollY = height < scrollHeight && (elCSS.overflowY === "auto" || elCSS.overflowY === "scroll");
}
var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
if (!autoScrolls[layersOut]) {
for (var i = 0; i <= layersOut; i++) {
if (!autoScrolls[i]) {
autoScrolls[i] = {};
}
}
}
if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
autoScrolls[layersOut].el = el;
autoScrolls[layersOut].vx = vx;
autoScrolls[layersOut].vy = vy;
clearInterval(autoScrolls[layersOut].pid);
if (vx != 0 || vy != 0) {
scrollThisInstance = true;
autoScrolls[layersOut].pid = setInterval(function() {
if (isFallback && this.layer === 0) {
Sortable.active._onTouchMove(touchEvt$1);
}
var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
if (typeof scrollCustomFn === "function") {
if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== "continue") {
return;
}
}
scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
}.bind({
layer: layersOut
}), 24);
}
}
layersOut++;
} while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
scrolling = scrollThisInstance;
}, 30);
var drop = function drop2(_ref) {
var originalEvent = _ref.originalEvent, putSortable2 = _ref.putSortable, dragEl2 = _ref.dragEl, activeSortable = _ref.activeSortable, dispatchSortableEvent = _ref.dispatchSortableEvent, hideGhostForTarget = _ref.hideGhostForTarget, unhideGhostForTarget = _ref.unhideGhostForTarget;
if (!originalEvent) return;
var toSortable = putSortable2 || activeSortable;
hideGhostForTarget();
var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
var target = document.elementFromPoint(touch.clientX, touch.clientY);
unhideGhostForTarget();
if (toSortable && !toSortable.el.contains(target)) {
dispatchSortableEvent("spill");
this.onSpill({
dragEl: dragEl2,
putSortable: putSortable2
});
}
};
function Revert() {
}
Revert.prototype = {
startIndex: null,
dragStart: function dragStart(_ref2) {
var oldDraggableIndex2 = _ref2.oldDraggableIndex;
this.startIndex = oldDraggableIndex2;
},
onSpill: function onSpill(_ref3) {
var dragEl2 = _ref3.dragEl, putSortable2 = _ref3.putSortable;
this.sortable.captureAnimationState();
if (putSortable2) {
putSortable2.captureAnimationState();
}
var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
if (nextSibling) {
this.sortable.el.insertBefore(dragEl2, nextSibling);
} else {
this.sortable.el.appendChild(dragEl2);
}
this.sortable.animateAll();
if (putSortable2) {
putSortable2.animateAll();
}
},
drop
};
_extends(Revert, {
pluginName: "revertOnSpill"
});
function Remove() {
}
Remove.prototype = {
onSpill: function onSpill2(_ref4) {
var dragEl2 = _ref4.dragEl, putSortable2 = _ref4.putSortable;
var parentSortable = putSortable2 || this.sortable;
parentSortable.captureAnimationState();
dragEl2.parentNode && dragEl2.parentNode.removeChild(dragEl2);
parentSortable.animateAll();
},
drop
};
_extends(Remove, {
pluginName: "removeOnSpill"
});
Sortable.mount(new AutoScrollPlugin());
Sortable.mount(Remove, Revert);
var sortable_esm_default = Sortable;
// src/view/TaskListComponent.ts
var TaskListComponent = class {
constructor(container, callbacks) {
this.sortable = null;
this.container = container;
this.callbacks = callbacks;
}
render(tasks) {
this.destroy();
this.container.empty();
if (tasks.length === 0) return;
const list = this.container.createEl("ul", { cls: "yaotp-task-list" });
tasks.forEach((task, index2) => {
const item = list.createEl("li", { cls: "yaotp-task-item" });
if (task.completed) item.addClass("yaotp-task-completed");
item.dataset.index = String(index2);
const handle = item.createDiv({ cls: "yaotp-drag-handle" });
handle.innerHTML = "&#8942;";
const checkbox = item.createEl("input", {
cls: "yaotp-checkbox",
type: "checkbox",
attr: { "aria-label": "Complete task" }
});
checkbox.checked = task.completed;
checkbox.addEventListener("click", (e) => {
e.stopPropagation();
this.callbacks.onComplete(index2);
});
const textEl = item.createDiv({ cls: "yaotp-task-text" });
textEl.setText(task.text);
if (task.notes.length > 0) {
textEl.addClass("yaotp-task-has-notes");
}
textEl.addEventListener("click", () => {
this.callbacks.onEdit(index2);
});
});
this.sortable = sortable_esm_default.create(list, {
handle: ".yaotp-drag-handle",
animation: 150,
delay: 300,
delayOnTouchOnly: true,
onEnd: (evt) => {
const oldIndex2 = evt.oldIndex;
const newIndex2 = evt.newIndex;
if (oldIndex2 !== void 0 && newIndex2 !== void 0 && oldIndex2 !== newIndex2) {
this.callbacks.onReorder(oldIndex2, newIndex2);
}
}
});
}
destroy() {
if (this.sortable) {
this.sortable.destroy();
this.sortable = null;
}
}
};
// src/view/FileSwitcherBar.ts
function buildFileSwitcherBar(opts) {
const { currentFile, taskFiles, inboxPath, onSwitchFile, onCreateFile } = opts;
const bar = createDiv({ cls: "yaotp-switcher-bar" });
const selectWrap = bar.createDiv({ cls: "yaotp-switcher-select-wrap" });
const select = selectWrap.createEl("select", { cls: "yaotp-switcher-select" });
const inbox = taskFiles.find((f) => f.path === inboxPath);
const others = taskFiles.filter((f) => f.path !== inboxPath);
for (const file of inbox ? [inbox, ...others] : others) {
const opt = select.createEl("option", { text: file.basename, value: file.path });
if (file.path === currentFile.path) opt.selected = true;
}
select.addEventListener("change", () => {
const chosen = taskFiles.find((f) => f.path === select.value);
if (chosen) onSwitchFile(chosen);
});
const newBtn = bar.createEl("button", {
text: "+ New list",
cls: "yaotp-switcher-new-btn"
});
const createGroup = bar.createDiv({ cls: "yaotp-switcher-create-group" });
createGroup.style.display = "none";
const nameInput = createGroup.createEl("input", {
type: "text",
cls: "yaotp-switcher-name-input",
attr: { placeholder: "File name (without .md)" }
});
const confirmBtn = createGroup.createEl("button", {
text: "Create",
cls: "mod-cta yaotp-switcher-confirm-btn"
});
const cancelBtn = createGroup.createEl("button", {
text: "\u2715",
cls: "yaotp-switcher-cancel-btn"
});
const showInput = () => {
newBtn.style.display = "none";
createGroup.style.display = "flex";
nameInput.value = "";
setTimeout(() => nameInput.focus(), 0);
};
const hideInput = () => {
createGroup.style.display = "none";
newBtn.style.display = "";
};
const submit = () => {
const name = nameInput.value.trim();
if (name) {
hideInput();
onCreateFile(name);
}
};
newBtn.addEventListener("click", showInput);
confirmBtn.addEventListener("click", submit);
cancelBtn.addEventListener("click", hideInput);
nameInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") submit();
if (e.key === "Escape") hideInput();
});
return bar;
}
// src/view/TaskEditorModal.ts
var import_obsidian3 = require("obsidian");
var TaskEditorModal = class extends import_obsidian3.Modal {
constructor(app, task, taskFiles, currentFile, onSave, onDelete) {
super(app);
this.textarea = null;
this.selectedFile = null;
this.fileLabel = null;
this.keyboardCleanup = null;
this.task = task;
this.taskFiles = taskFiles;
this.currentFile = currentFile;
this.onSave = onSave;
this.onDelete = onDelete;
}
onOpen() {
var _a;
const { contentEl } = this;
contentEl.addClass("yaotp-editor-modal");
const applyLayout = (keyboardHeight) => {
const available = window.innerHeight - keyboardHeight;
this.containerEl.style.height = `${available}px`;
this.containerEl.style.alignItems = "flex-start";
this.containerEl.style.paddingTop = "8px";
this.modalEl.style.maxHeight = `${available - 16}px`;
};
const resetLayout = () => {
this.containerEl.style.height = "";
this.containerEl.style.alignItems = "";
this.containerEl.style.paddingTop = "";
this.modalEl.style.maxHeight = "";
};
const onCapacitorShow = (e) => {
var _a2, _b, _c;
const kh = (_c = (_b = e.keyboardHeight) != null ? _b : (_a2 = e.detail) == null ? void 0 : _a2.keyboardHeight) != null ? _c : 0;
if (kh > 0) applyLayout(kh);
};
const onCapacitorHide = () => resetLayout();
const onViewport = () => {
const vv = window.visualViewport;
if (!vv) return;
const kh = Math.max(0, window.innerHeight - vv.height - vv.offsetTop);
if (kh > 50) applyLayout(kh);
else resetLayout();
};
window.addEventListener("keyboardWillShow", onCapacitorShow);
window.addEventListener("keyboardDidShow", onCapacitorShow);
window.addEventListener("keyboardWillHide", onCapacitorHide);
window.addEventListener("keyboardDidHide", onCapacitorHide);
(_a = window.visualViewport) == null ? void 0 : _a.addEventListener("resize", onViewport);
window.addEventListener("resize", onViewport);
this.keyboardCleanup = () => {
var _a2;
window.removeEventListener("keyboardWillShow", onCapacitorShow);
window.removeEventListener("keyboardDidShow", onCapacitorShow);
window.removeEventListener("keyboardWillHide", onCapacitorHide);
window.removeEventListener("keyboardDidHide", onCapacitorHide);
(_a2 = window.visualViewport) == null ? void 0 : _a2.removeEventListener("resize", onViewport);
window.removeEventListener("resize", onViewport);
resetLayout();
};
contentEl.createEl("h2", { text: "Edit task" });
const initialValue = this.task.notes.length > 0 ? [this.task.text, "", ...this.task.notes].join("\n") : this.task.text;
this.textarea = contentEl.createEl("textarea", {
cls: "yaotp-editor-textarea",
attr: { rows: "8", placeholder: "Task title\n\nNotes\u2026" }
});
this.textarea.value = initialValue;
this.textarea.addEventListener("focus", () => setTimeout(onViewport, 500));
this.textarea.addEventListener("blur", () => setTimeout(resetLayout, 100));
setTimeout(() => {
var _a2;
return (_a2 = this.textarea) == null ? void 0 : _a2.focus();
}, 50);
const fileRow = contentEl.createDiv({ cls: "yaotp-editor-file-row" });
fileRow.createEl("span", { text: "File: ", cls: "yaotp-editor-file-label-prefix" });
this.fileLabel = fileRow.createEl("span", {
text: this.currentFile.basename,
cls: "yaotp-editor-file-name"
});
const changeBtn = fileRow.createEl("button", {
text: "Change\u2026",
cls: "yaotp-editor-file-btn"
});
changeBtn.addEventListener("click", () => {
const picker = new TaskFilePicker(
this.app,
this.taskFiles,
(file) => {
this.selectedFile = file;
if (this.fileLabel) {
this.fileLabel.setText(file.basename);
}
}
);
picker.open();
});
const btnRow = contentEl.createDiv({ cls: "yaotp-editor-btn-row" });
const deleteBtn = btnRow.createEl("button", {
text: "Delete",
cls: "yaotp-editor-delete-btn"
});
deleteBtn.addEventListener("click", () => {
new ConfirmModal(this.app, "Delete this task? This cannot be undone.", () => {
this.close();
this.onDelete();
}).open();
});
const saveBtn = btnRow.createEl("button", {
text: "Save",
cls: "mod-cta yaotp-editor-save-btn"
});
saveBtn.addEventListener("click", () => this.save());
const cancelBtn = btnRow.createEl("button", { text: "Cancel" });
cancelBtn.addEventListener("click", () => this.close());
}
onClose() {
var _a;
(_a = this.keyboardCleanup) == null ? void 0 : _a.call(this);
this.keyboardCleanup = null;
this.contentEl.empty();
}
save() {
var _a;
if (!this.textarea) return;
const lines = this.textarea.value.split("\n");
const text = (_a = lines[0]) != null ? _a : "";
const notes = lines.slice(1);
while (notes.length > 0 && notes[0].trim() === "") notes.shift();
this.onSave({
text,
notes,
targetFile: this.selectedFile
});
this.close();
}
};
var ConfirmModal = class extends import_obsidian3.Modal {
constructor(app, message, onConfirm) {
super(app);
this.message = message;
this.onConfirm = onConfirm;
}
onOpen() {
const { contentEl } = this;
contentEl.createEl("p", { text: this.message });
const row = contentEl.createDiv({ cls: "yaotp-editor-btn-row" });
const confirmBtn = row.createEl("button", {
text: "Delete",
cls: "mod-warning yaotp-editor-delete-btn"
});
confirmBtn.addEventListener("click", () => {
this.onConfirm();
this.close();
});
const cancelBtn = row.createEl("button", { text: "Cancel" });
cancelBtn.addEventListener("click", () => this.close());
}
onClose() {
this.contentEl.empty();
}
};
var TaskFilePicker = class extends import_obsidian3.FuzzySuggestModal {
constructor(app, files, onSelect) {
super(app);
this.files = files;
this.onSelect = onSelect;
this.setPlaceholder("Select a task file\u2026");
}
getItems() {
return this.files;
}
getItemText(file) {
return file.path;
}
onChooseItem(file) {
this.onSelect(file);
}
};
// src/file-intercept.ts
var import_obsidian4 = require("obsidian");
var originalSetViewState = null;
var bypassLeaves = /* @__PURE__ */ new WeakSet();
function allowMarkdownOnce(leaf) {
bypassLeaves.add(leaf);
}
function installFileIntercept(isTaskFile) {
if (originalSetViewState) return;
const proto = import_obsidian4.WorkspaceLeaf.prototype;
originalSetViewState = proto.setViewState;
proto.setViewState = function(state, eState) {
var _a, _b, _c, _d, _e;
if ((state == null ? void 0 : state.type) === "markdown" && ((_a = state == null ? void 0 : state.state) == null ? void 0 : _a.file) && isTaskFile(state.state.file) && // Don't intercept mode-only changes within an already-open markdown view
// for the same file (e.g. switching to Source mode via the context menu).
// We DO still intercept if the leaf is markdown but showing a different
// file, or if the view is not yet markdown at all.
!(((_b = this.view) == null ? void 0 : _b.getViewType()) === "markdown" && // eslint-disable-next-line @typescript-eslint/no-explicit-any
((_d = (_c = this.view) == null ? void 0 : _c.file) == null ? void 0 : _d.path) === ((_e = state.state) == null ? void 0 : _e.file))) {
if (bypassLeaves.has(this)) {
bypassLeaves.delete(this);
return originalSetViewState.call(this, state, eState);
}
const newState = { ...state, type: VIEW_TYPE };
return originalSetViewState.call(this, newState, eState);
}
return originalSetViewState.call(this, state, eState);
};
}
function uninstallFileIntercept() {
if (!originalSetViewState) return;
import_obsidian4.WorkspaceLeaf.prototype.setViewState = originalSetViewState;
originalSetViewState = null;
}
// src/view/TaskFileView.ts
var TaskFileView = class extends import_obsidian5.TextFileView {
constructor(leaf, settings, getTaskFiles) {
super(leaf);
this.tasks = [];
this.fileHeader = "";
this.taskList = null;
this.rootEl = null;
this.listEl = null;
this.settings = settings;
this.getTaskFiles = getTaskFiles;
}
getViewType() {
return VIEW_TYPE;
}
getDisplayText() {
var _a, _b;
return (_b = (_a = this.file) == null ? void 0 : _a.basename) != null ? _b : "Tasks";
}
getIcon() {
return VIEW_ICON;
}
// Called by Obsidian when the file content is loaded or changes externally.
setViewData(data, _clear) {
const { header, tasks } = parseTaskFile(data);
this.fileHeader = header;
this.tasks = tasks;
this.renderView();
}
// Called by Obsidian when it needs to read back the file content.
getViewData() {
return serializeTaskFile({ header: this.fileHeader, tasks: this.tasks });
}
clear() {
this.fileHeader = "";
this.tasks = [];
this.renderView();
}
// Obsidian calls this after the view is attached to the DOM.
async onOpen() {
this.contentEl.addClass("yaotp-view");
this.rootEl = this.contentEl;
this.addAction("pencil", "Edit source", async () => {
if (!this.file) return;
const filePath = this.file.path;
allowMarkdownOnce(this.leaf);
await this.leaf.setViewState({
type: "markdown",
state: { file: filePath }
});
await this.leaf.setViewState({
type: "markdown",
state: { file: filePath, mode: "source" }
});
});
}
async onClose() {
var _a;
(_a = this.taskList) == null ? void 0 : _a.destroy();
this.taskList = null;
}
// ── Private ──────────────────────────────────────────────────────────────
renderView() {
if (!this.rootEl) return;
this.rootEl.empty();
if (this.file) {
const taskFiles = this.getTaskFiles();
const bar = buildFileSwitcherBar({
app: this.app,
currentFile: this.file,
taskFiles,
inboxPath: this.settings.inboxPath,
onSwitchFile: (file) => this.openFile(file),
onCreateFile: (name) => this.createAndOpenFile(name)
});
this.rootEl.appendChild(bar);
}
const addItem = this.rootEl.createDiv({ cls: "yaotp-task-item yaotp-add-task-item" });
const addHandle = addItem.createDiv({ cls: "yaotp-drag-handle yaotp-drag-handle-disabled" });
addHandle.innerHTML = "&#8942;";
addItem.createEl("input", {
cls: "yaotp-checkbox",
type: "checkbox",
attr: { disabled: true, "aria-hidden": "true" }
});
const addInput = addItem.createEl("input", {
cls: "yaotp-new-task-input",
type: "text",
attr: { placeholder: "Enter new task..." }
});
addInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
const text = addInput.value.trim();
if (text) this.addTask(text);
}
});
this.listEl = this.rootEl.createDiv({ cls: "yaotp-list-container" });
this.taskList = new TaskListComponent(this.listEl, {
onComplete: (index2) => this.completeTask(index2),
onEdit: (index2) => this.editTask(index2),
onReorder: (oldIndex2, newIndex2) => this.reorderTask(oldIndex2, newIndex2)
});
this.taskList.render(this.tasks);
}
async persistTasks() {
if (!this.file) return;
await this.app.vault.modify(
this.file,
serializeTaskFile({ header: this.fileHeader, tasks: this.tasks })
);
}
async addTask(text) {
this.tasks.unshift({ text, notes: [], completed: false });
await this.persistTasks();
this.renderView();
}
async completeTask(index2) {
const task = this.tasks[index2];
if (!task) return;
task.completed = true;
this.tasks.splice(index2, 1);
await this.persistTasks();
await appendTaskToDailyNote(task, this.app);
this.renderView();
}
editTask(index2) {
const task = this.tasks[index2];
if (!task || !this.file) return;
const taskFiles = this.getTaskFiles();
const modal = new TaskEditorModal(
this.app,
task,
taskFiles,
this.file,
async (result) => {
var _a;
task.text = result.text;
task.notes = result.notes;
if (result.targetFile && result.targetFile.path !== ((_a = this.file) == null ? void 0 : _a.path)) {
this.tasks.splice(index2, 1);
await this.persistTasks();
await this.appendTaskToFile(task, result.targetFile);
} else {
await this.persistTasks();
}
this.renderView();
},
async () => {
this.tasks.splice(index2, 1);
await this.persistTasks();
this.renderView();
}
);
modal.open();
}
reorderTask(oldIndex2, newIndex2) {
const moved2 = this.tasks.splice(oldIndex2, 1)[0];
this.tasks.splice(newIndex2, 0, moved2);
this.persistTasks();
}
async appendTaskToFile(task, file) {
const content = await this.app.vault.read(file);
const data = parseTaskFile(content);
data.tasks.push(task);
await this.app.vault.modify(file, serializeTaskFile(data));
}
openFile(file) {
this.app.workspace.getLeaf(false).openFile(file);
}
async createAndOpenFile(name) {
const folder = this.settings.taskFileFolder;
const path = folder ? `${folder}/${name}.md` : `${name}.md`;
let file = this.app.vault.getAbstractFileByPath(path);
if (!file) {
try {
file = await this.app.vault.create(path, "");
} catch (e) {
new import_obsidian5.Notice(`YAOTP: Could not create file: ${path}`);
return;
}
}
this.openFile(file);
}
};
// src/main.ts
var YaotpPlugin = class extends import_obsidian6.Plugin {
constructor() {
super(...arguments);
this.settings = { ...DEFAULT_SETTINGS };
this.taskRegex = new RegExp(DEFAULT_SETTINGS.taskFileRegex);
}
async onload() {
await this.loadSettings();
this.rebuildRegex();
this.registerView(
VIEW_TYPE,
(leaf) => new TaskFileView(leaf, this.settings, () => this.getTaskFiles())
);
installFileIntercept((path) => this.isTaskFile(path));
this.app.workspace.onLayoutReady(() => {
this.redirectExistingLeaves();
});
this.addSettingTab(new YaotpSettingTab(this.app, this));
}
onunload() {
uninstallFileIntercept();
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
this.rebuildRegex();
}
isTaskFile(path) {
return this.taskRegex.test(path);
}
getTaskFiles() {
return this.app.vault.getMarkdownFiles().filter((f) => this.isTaskFile(f.path));
}
rebuildRegex() {
try {
this.taskRegex = new RegExp(this.settings.taskFileRegex);
} catch (e) {
this.taskRegex = new RegExp(DEFAULT_SETTINGS.taskFileRegex);
}
}
redirectExistingLeaves() {
this.app.workspace.iterateAllLeaves((leaf) => {
var _a;
const state = leaf.getViewState();
if (state.type === "markdown" && ((_a = state.state) == null ? void 0 : _a.file) && this.isTaskFile(state.state.file)) {
leaf.setViewState({ ...state, type: VIEW_TYPE });
}
});
}
};
/*! Bundled license information:
sortablejs/modular/sortable.esm.js:
(**!
* Sortable 1.15.7
* @author RubaXa <trash@rubaxa.org>
* @author owenm <owen23355@gmail.com>
* @license MIT
*)
*/
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibm9kZV9tb2R1bGVzL29ic2lkaWFuLWRhaWx5LW5vdGVzLWludGVyZmFjZS9kaXN0L21haW4uanMiLCAic3JjL21haW4udHMiLCAic3JjL2NvbnN0YW50cy50cyIsICJzcmMvc2V0dGluZ3MudHMiLCAic3JjL3ZpZXcvVGFza0ZpbGVWaWV3LnRzIiwgInNyYy9wYXJzZXIudHMiLCAic3JjL2RhaWx5LW5vdGVzLnRzIiwgIm5vZGVfbW9kdWxlcy9zb3J0YWJsZWpzL21vZHVsYXIvc29ydGFibGUuZXNtLmpzIiwgInNyYy92aWV3L1Rhc2tMaXN0Q29tcG9uZW50LnRzIiwgInNyYy92aWV3L0ZpbGVTd2l0Y2hlckJhci50cyIsICJzcmMvdmlldy9UYXNrRWRpdG9yTW9kYWwudHMiLCAic3JjL2ZpbGUtaW50ZXJjZXB0LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbnZhciBvYnNpZGlhbiA9IHJlcXVpcmUoJ29ic2lkaWFuJyk7XG5cbmNvbnN0IERFRkFVTFRfREFJTFlfTk9URV9GT1JNQVQgPSBcIllZWVktTU0tRERcIjtcbmNvbnN0IERFRkFVTFRfV0VFS0xZX05PVEVfRk9STUFUID0gXCJnZ2dnLVtXXXd3XCI7XG5jb25zdCBERUZBVUxUX01PTlRITFlfTk9URV9GT1JNQVQgPSBcIllZWVktTU1cIjtcbmNvbnN0IERFRkFVTFRfUVVBUlRFUkxZX05PVEVfRk9STUFUID0gXCJZWVlZLVtRXVFcIjtcbmNvbnN0IERFRkFVTFRfWUVBUkxZX05PVEVfRk9STUFUID0gXCJZWVlZXCI7XG5cbmZ1bmN0aW9uIHNob3VsZFVzZVBlcmlvZGljTm90ZXNTZXR0aW5ncyhwZXJpb2RpY2l0eSkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgcGVyaW9kaWNOb3RlcyA9IHdpbmRvdy5hcHAucGx1Z2lucy5nZXRQbHVnaW4oXCJwZXJpb2RpYy1ub3Rlc1wiKTtcbiAgICByZXR1cm4gcGVyaW9kaWNOb3RlcyAmJiBwZXJpb2RpY05vdGVzLnNldHRpbmdzPy5bcGVyaW9kaWNpdHldPy5lbmFibGVkO1xufVxuLyoqXG4gKiBSZWFkIHRoZSB1c2VyIHNldHRpbmdzIGZvciB0aGUgYGRhaWx5LW5vdGVzYCBwbHVnaW5cbiAqIHRvIGtlZXAgYmVoYXZpb3Igb2YgY3JlYXRpbmcgYSBuZXcgbm90ZSBpbi1zeW5jLlxuICovXG5mdW5jdGlvbiBnZXREYWlseU5vdGVTZXR0aW5ncygpIHtcbiAgICB0cnkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICBjb25zdCB7IGludGVybmFsUGx1Z2lucywgcGx1Z2lucyB9ID0gd2luZG93LmFwcDtcbiAgICAgICAgaWYgKHNob3VsZFVzZVBlcmlvZGljTm90ZXNTZXR0aW5ncyhcImRhaWx5XCIpKSB7XG4gICAgICAgICAgICBjb25zdCB7IGZvcm1hdCwgZm9sZGVyLCB0ZW1wbGF0ZSB9ID0gcGx1Z2lucy5nZXRQbHVnaW4oXCJwZXJpb2RpYy1ub3Rlc1wiKT8uc2V0dGluZ3M/LmRhaWx5IHx8IHt9O1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IGZvcm1hdCB8fCBERUZBVUxUX0RBSUxZX05PVEVfRk9STUFULFxuICAgICAgICAgICAgICAgIGZvbGRlcjogZm9sZGVyPy50cmltKCkgfHwgXCJcIixcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZTogdGVtcGxhdGU/LnRyaW0oKSB8fCBcIlwiLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IGZvbGRlciwgZm9ybWF0LCB0ZW1wbGF0ZSB9ID0gaW50ZXJuYWxQbHVnaW5zLmdldFBsdWdpbkJ5SWQoXCJkYWlseS1ub3Rlc1wiKT8uaW5zdGFuY2U/Lm9wdGlvbnMgfHwge307XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBmb3JtYXQ6IGZvcm1hdCB8fCBERUZBVUxUX0RBSUxZX05PVEVfRk9STUFULFxuICAgICAgICAgICAgZm9sZGVyOiBmb2xkZXI/LnRyaW0oKSB8fCBcIlwiLFxuICAgICAgICAgICAgdGVtcGxhdGU6IHRlbXBsYXRlPy50cmltKCkgfHwgXCJcIixcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmluZm8oXCJObyBjdXN0b20gZGFpbHkgbm90ZSBzZXR0aW5ncyBmb3VuZCFcIiwgZXJyKTtcbiAgICB9XG59XG4vKipcbiAqIFJlYWQgdGhlIHVzZXIgc2V0dGluZ3MgZm9yIHRoZSBgd2Vla2x5LW5vdGVzYCBwbHVnaW5cbiAqIHRvIGtlZXAgYmVoYXZpb3Igb2YgY3JlYXRpbmcgYSBuZXcgbm90ZSBpbi1zeW5jLlxuICovXG5mdW5jdGlvbiBnZXRXZWVrbHlOb3RlU2V0dGluZ3MoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgY29uc3QgcGx1Z2luTWFuYWdlciA9IHdpbmRvdy5hcHAucGx1Z2lucztcbiAgICAgICAgY29uc3QgY2FsZW5kYXJTZXR0aW5ncyA9IHBsdWdpbk1hbmFnZXIuZ2V0UGx1Z2luKFwiY2FsZW5kYXJcIik/Lm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IHBlcmlvZGljTm90ZXNTZXR0aW5ncyA9IHBsdWdpbk1hbmFnZXIuZ2V0UGx1Z2luKFwicGVyaW9kaWMtbm90ZXNcIik/LnNldHRpbmdzPy53ZWVrbHk7XG4gICAgICAgIGlmIChzaG91bGRVc2VQZXJpb2RpY05vdGVzU2V0dGluZ3MoXCJ3ZWVrbHlcIikpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZm9ybWF0OiBwZXJpb2RpY05vdGVzU2V0dGluZ3MuZm9ybWF0IHx8IERFRkFVTFRfV0VFS0xZX05PVEVfRk9STUFULFxuICAgICAgICAgICAgICAgIGZvbGRlcjogcGVyaW9kaWNOb3Rlc1NldHRpbmdzLmZvbGRlcj8udHJpbSgpIHx8IFwiXCIsXG4gICAgICAgICAgICAgICAgdGVtcGxhdGU6IHBlcmlvZGljTm90ZXNTZXR0aW5ncy50ZW1wbGF0ZT8udHJpbSgpIHx8IFwiXCIsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gY2FsZW5kYXJTZXR0aW5ncyB8fCB7fTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZvcm1hdDogc2V0dGluZ3Mud2Vla2x5Tm90ZUZvcm1hdCB8fCBERUZBVUxUX1dFRUtMWV9OT1RFX0ZPUk1BVCxcbiAgICAgICAgICAgIGZvbGRlcjogc2V0dGluZ3Mud2Vla2x5Tm90ZUZvbGRlcj8udHJpbSgpIHx8IFwiXCIsXG4gICAgICAgICAgICB0ZW1wbGF0ZTogc2V0dGluZ3Mud2Vla2x5Tm90ZVRlbXBsYXRlPy50cmltKCkgfHwgXCJcIixcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmluZm8oXCJObyBjdXN0b20gd2Vla2x5IG5vdGUgc2V0dGluZ3MgZm91bmQhXCIsIGVycik7XG4gICAgfVxufVxuLyoqXG4gKiBSZWFkIHRoZSB1c2VyIHNldHRpbmdzIGZvciB0aGUgYHBlcmlvZGljLW5vdGVzYCBwbHVnaW5cbiAqIHRvIGtlZXAgYmVoYXZpb3Igb2YgY3JlYXRpbmcgYSBuZXcgbm90ZSBpbi1zeW5jLlxuICovXG5mdW5jdGlvbiBnZXRNb250aGx5Tm90ZVNldHRpbmdzKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgcGx1Z2luTWFuYWdlciA9IHdpbmRvdy5hcHAucGx1Z2lucztcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBzZXR0aW5ncyA9IChzaG91bGRVc2VQZXJpb2RpY05vdGVzU2V0dGluZ3MoXCJtb250aGx5XCIpICYmXG4gICAgICAgICAgICBwbHVnaW5NYW5hZ2VyLmdldFBsdWdpbihcInBlcmlvZGljLW5vdGVzXCIpPy5zZXR0aW5ncz8ubW9udGhseSkgfHxcbiAgICAgICAgICAgIHt9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZm9ybWF0OiBzZXR0aW5ncy5mb3JtYXQgfHwgREVGQVVMVF9NT05USExZX05PVEVfRk9STUFULFxuICAgICAgICAgICAgZm9sZGVyOiBzZXR0aW5ncy5mb2xkZXI/LnRyaW0oKSB8fCBcIlwiLFxuICAgICAgICAgICAgdGVtcGxhdGU6IHNldHRpbmdzLnRlbXBsYXRlPy50cmltKCkgfHwgXCJcIixcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmluZm8oXCJObyBjdXN0b20gbW9udGhseSBub3RlIHNldHRpbmdzIGZvdW5kIVwiLCBlcnIpO1xuICAgIH1cbn1cbi8qKlxuICogUmVhZCB0aGUgdXNlciBzZXR0aW5ncyBmb3IgdGhlIGBwZXJpb2RpYy1ub3Rlc2AgcGx1Z2luXG4gKiB0byBrZWVwIGJlaGF2aW9yIG9mIGNyZWF0aW5nIGEgbmV3IG5vdGUgaW4tc3luYy5cbiAqL1xuZnVuY3Rpb24gZ2V0UXVhcnRlcmx5Tm90ZVNldHRpbmdzKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgcGx1Z2luTWFuYWdlciA9IHdpbmRvdy5hcHAucGx1Z2lucztcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBzZXR0aW5ncyA9IChzaG91bGRVc2VQZXJpb2RpY05vdGVzU2V0dGluZ3MoXCJxdWFydGVybHlcIikgJiZcbiAgICAgICAgICAgIHBsdWdpbk1hbmFnZXIuZ2V0UGx1Z2luKFwicGVyaW9kaWMtbm90ZXNcIik/LnNldHRpbmdzPy5xdWFydGVybHkpIHx8XG4gICAgICAgICAgICB7fTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZvcm1hdDogc2V0dGluZ3MuZm9ybWF0IHx8IERFRkFVTFRfUVVBUlRFUkxZX05PVEVfRk9STUFULFxuICAgICAgICAgICAgZm9sZGVyOiBzZXR0aW5ncy5mb2xkZXI/LnRyaW0oKSB8fCBcIlwiLFxuICAgICAgICAgICAgdGVtcGxhdGU6IHNldHRpbmdzLnRlbXBsYXRlPy50cmltKCkgfHwgXCJcIixcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmluZm8oXCJObyBjdXN0b20gcXVhcnRlcmx5IG5vdGUgc2V0dGluZ3MgZm91bmQhXCIsIGVycik7XG4gICAgfVxufVxuLyoqXG4gKiBSZWFkIHRoZSB1c2VyIHNldHRpbmdzIGZvciB0aGUgYHBlcmlvZGljLW5vdGVzYCBwbHVnaW5cbiAqIHRvIGtlZXAgYmVoYXZpb3Igb2YgY3JlYXRpbmcgYSBuZXcgbm90ZSBpbi1zeW5jLlxuICovXG5mdW5jdGlvbiBnZXRZZWFybHlOb3RlU2V0dGluZ3MoKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBwbHVnaW5NYW5hZ2VyID0gd2luZG93LmFwcC5wbHVnaW5zO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gKHNob3VsZFVzZVBlcmlvZGljTm90ZXNTZXR0aW5ncyhcInllYXJseVwiKSAmJlxuICAgICAgICAgICAgcGx1Z2luTWFuYWdlci5nZXRQbHVnaW4oXCJwZXJpb2RpYy1ub3Rlc1wiKT8uc2V0dGluZ3M/LnllYXJseSkgfHxcbiAgICAgICAgICAgIHt9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZm9ybWF0OiBzZXR0aW5ncy5mb3JtYXQgfHwgREVGQVVMVF9ZRUFSTFlfTk9URV9GT1JNQVQsXG4gICAgICAgICAgICBmb2xkZXI6IHNldHRpbmdzLmZvbGRlcj8udHJpbSgpIHx8IFwiXCIsXG4gICAgICAgICAgICB0ZW1wbGF0ZTogc2V0dGluZ3MudGVtcGxhdGU/LnRyaW0oKSB8fCBcIlwiLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIk5vIGN1c3RvbSB5ZWFybHkgbm90ZSBzZXR0aW5ncyBmb3VuZCFcIiwgZXJyKTtcbiAgICB9XG59XG5cbi8vIENyZWRpdDogQGNyZWF0aW9uaXgvcGF0aC5qc1xuZnVuY3Rpb24gam9pbiguLi5wYXJ0U2VnbWVudHMpIHtcbiAgICAvLyBTcGxpdCB0aGUgaW5wdXRzIGludG8gYSBsaXN0IG9mIHBhdGggY29tbWFuZHMuXG4gICAgbGV0IHBhcnRzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDAsIGwgPSBwYXJ0U2VnbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIHBhcnRzID0gcGFydHMuY29uY2F0KHBhcnRTZWdtZW50c1tpXS5zcGxpdChcIi9cIikpO1xuICAgIH1cbiAgICAvLyBJbnRlcnByZXQgdGhlIHBhdGggY29tbWFuZHMgdG8gZ2V0IHRoZSBuZXcgcmVzb2x2ZWQgcGF0aC5cbiAgICBjb25zdCBuZXdQYXJ0cyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwLCBsID0gcGFydHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHBhcnQgPSBwYXJ0c1tpXTtcbiAgICAgICAgLy8gUmVtb3ZlIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXNcbiAgICAgICAgLy8gQWxzbyByZW1vdmUgXCIuXCIgc2VnbWVudHNcbiAgICAgICAgaWYgKCFwYXJ0IHx8IHBhcnQgPT09IFwiLlwiKVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIC8vIFB1c2ggbmV3IHBhdGggc2VnbWVudHMuXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIG5ld1BhcnRzLnB1c2gocGFydCk7XG4gICAgfVxuICAgIC8vIFByZXNlcnZlIHRoZSBpbml0aWFsIHNsYXNoIGlmIHRoZXJlIHdhcyBvbmUuXG4gICAgaWYgKHBhcnRzWzBdID09PSBcIlwiKVxuICAgICAgICBuZXdQYXJ0cy51bnNoaWZ0KFwiXCIpO1xuICAgIC8vIFR1cm4gYmFjayBpbnRvIGEgc2luZ2xlIHN0cmluZyBwYXRoLlxuICAgIHJldHVybiBuZXdQYXJ0cy5qb2luKFwiL1wiKTtcbn1cbmZ1bmN0aW9uIGJhc2VuYW1lKGZ1bGxQYXRoKSB7XG4gICAgbGV0IGJhc2UgPSBmdWxsUGF0aC5zdWJzdHJpbmcoZnVsbFBhdGgubGFzdEluZGV4T2YoXCIvXCIpICsgMSk7XG4gICAgaWYgKGJhc2UubGFzdEluZGV4T2YoXCIuXCIpICE9IC0xKVxuICAgICAgICBiYXNlID0gYmFzZS5zdWJzdHJpbmcoMCwgYmFzZS5sYXN0SW5kZXhPZihcIi5cIikpO1xuICAgIHJldHVybiBiYXNlO1xufVxuYXN5bmMgZnVuY3Rpb24gZW5zdXJlRm9sZGVyRXhpc3RzKHBhdGgpIHtcbiAgICBjb25zdCBkaXJzID0gcGF0aC5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKS5zcGxpdChcIi9cIik7XG4gICAgZGlycy5wb3AoKTsgLy8gcmVtb3ZlIGJhc2VuYW1lXG4gICAgaWYgKGRpcnMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IGRpciA9IGpvaW4oLi4uZGlycyk7XG4gICAgICAgIGlmICghd2luZG93LmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZGlyKSkge1xuICAgICAgICAgICAgYXdhaXQgd2luZG93LmFwcC52YXVsdC5jcmVhdGVGb2xkZXIoZGlyKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmFzeW5jIGZ1bmN0aW9uIGdldE5vdGVQYXRoKGRpcmVjdG9yeSwgZmlsZW5hbWUpIHtcbiAgICBpZiAoIWZpbGVuYW1lLmVuZHNXaXRoKFwiLm1kXCIpKSB7XG4gICAgICAgIGZpbGVuYW1lICs9IFwiLm1kXCI7XG4gICAgfVxuICAgIGNvbnN0IHBhdGggPSBvYnNpZGlhbi5ub3JtYWxpemVQYXRoKGpvaW4oZGlyZWN0b3J5LCBmaWxlbmFtZSkpO1xuICAgIGF3YWl0IGVuc3VyZUZvbGRlckV4aXN0cyhwYXRoKTtcbiAgICByZXR1cm4gcGF0aDtcbn1cbmFzeW5jIGZ1bmN0aW9uIGdldFRlbXBsYXRlSW5mbyh0ZW1wbGF0ZSkge1xuICAgIGNvbnN0IHsgbWV0YWRhdGFDYWNoZSwgdmF1bHQgfSA9IHdpbmRvdy5hcHA7XG4gICAgY29uc3QgdGVtcGxhdGVQYXRoID0gb2JzaWRpYW4ubm9ybWFsaXplUGF0aCh0ZW1wbGF0ZSk7XG4gICAgaWYgKHRlbXBsYXRlUGF0aCA9PT0gXCIvXCIpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShbXCJcIiwgbnVsbF0pO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBjb25zdCB0ZW1wbGF0ZUZpbGUgPSBtZXRhZGF0YUNhY2hlLmdldEZpcnN0TGlua3BhdGhEZXN0KHRlbXBsYXRlUGF0aCwgXCJcIik7XG4gICAgICAgIGNvbnN0IGNvbnRlbnRzID0gYXdhaXQgdmF1bHQuY2FjaGVkUmVhZCh0ZW1wbGF0ZUZpbGUpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICBjb25zdCBJRm9sZEluZm8gPSB3aW5kb3cuYXBwLmZvbGRNYW5hZ2VyLmxvYWQodGVtcGxhdGVGaWxlKTtcbiAgICAgICAgcmV0dXJuIFtjb250ZW50cywgSUZvbGRJbmZvXTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcmVhZCB0aGUgZGFpbHkgbm90ZSB0ZW1wbGF0ZSAnJHt0ZW1wbGF0ZVBhdGh9J2AsIGVycik7XG4gICAgICAgIG5ldyBvYnNpZGlhbi5Ob3RpY2UoXCJGYWlsZWQgdG8gcmVhZCB0aGUgZGFpbHkgbm90ZSB0ZW1wbGF0ZVwiKTtcbiAgICAgICAgcmV0dXJuIFtcIlwiLCBudWxsXTtcbiAgICB9XG59XG5cbi8qKlxuICogZGF0ZVVJRCBpcyBhIHdheSBvZiB3ZWVrbHkgaWRlbnRpZnlpbmcgZGFpbHkvd2Vla2x5L21vbnRobHkgbm90ZXMuXG4gKiBUaGV5IGFyZSBwcmVmaXhlZCB3aXRoIHRoZSBncmFudWxhcml0eSB0byBhdm9pZCBhbWJpZ3VpdHkuXG4gKi9cbmZ1bmN0aW9uIGdldERhdGVVSUQoZGF0ZSwgZ3JhbnVsYXJpdHkgPSBcImRheVwiKSB7XG4gICAgY29uc3QgdHMgPSBkYXRlLmNsb25lKCkuc3RhcnRPZihncmFudWxhcml0eSkuZm9ybWF0KCk7XG4gICAgcmV0dXJuIGAke2dyYW51bGFyaXR5fS0ke3RzfWA7XG59XG5mdW5jdGlvbiByZW1vdmVFc2NhcGVkQ2hhcmFjdGVycyhmb3JtYXQpIHtcbiAgICByZXR1cm4gZm9ybWF0LnJlcGxhY2UoL1xcW1teXFxdXSpcXF0vZywgXCJcIik7IC8vIHJlbW92ZSBldmVyeXRoaW5nIHdpdGhpbiBicmFja2V0c1xufVxuLyoqXG4gKiBYWFg6IFdoZW4gcGFyc2luZyBkYXRlcyB0aGF0IGNvbnRhaW4gYm90aCB3ZWVrIG51bWJlcnMgYW5kIG1vbnRocyxcbiAqIE1vbWVudCBjaG9zZXMgdG8gaWdub3JlIHRoZSB3ZWVrIG51bWJlcnMuIEZvciB0aGUgd2VlayBkYXRlVUlELCB3ZVxuICogd2FudCB0aGUgb3Bwb3NpdGUgYmVoYXZpb3IuIFN0cmlwIHRoZSBNTU0gZnJvbSB0aGUgZm9ybWF0IHRvIHBhdGNoLlxuICovXG5mdW5jdGlvbiBpc0Zvcm1hdEFtYmlndW91cyhmb3JtYXQsIGdyYW51bGFyaXR5KSB7XG4gICAgaWYgKGdyYW51bGFyaXR5ID09PSBcIndlZWtcIikge1xuICAgICAgICBjb25zdCBjbGVhbkZvcm1hdCA9IHJlbW92ZUVzY2FwZWRDaGFyYWN0ZXJzKGZvcm1hdCk7XG4gICAgICAgIHJldHVybiAoL3d7MSwyfS9pLnRlc3QoY2xlYW5Gb3JtYXQpICYmXG4gICAgICAgICAgICAoL017MSw0fS8udGVzdChjbGVhbkZvcm1hdCkgfHwgL0R7MSw0fS8udGVzdChjbGVhbkZvcm1hdCkpKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gZ2V0RGF0ZUZyb21GaWxlKGZpbGUsIGdyYW51bGFyaXR5KSB7XG4gICAgcmV0dXJuIGdldERhdGVGcm9tRmlsZW5hbWUoZmlsZS5iYXNlbmFtZSwgZ3JhbnVsYXJpdHkpO1xufVxuZnVuY3Rpb24gZ2V0RGF0ZUZyb21QYXRoKHBhdGgsIGdyYW51bGFyaXR5KSB7XG4gICAgcmV0dXJuIGdldERhdGVGcm9tRmlsZW5hbWUoYmFzZW5hbWUocGF0aCksIGdyYW51bGFyaXR5KTtcbn1cbmZ1bmN0aW9uIGdldERhdGVGcm9tRmlsZW5hbWUoZmlsZW5hbWUsIGdyYW51bGFyaXR5KSB7XG4gICAgY29uc3QgZ2V0U2V0dGluZ3MgPSB7XG4gICAgICAgIGRheTogZ2V0RGFpbHlOb3RlU2V0dGluZ3MsXG4gICAgICAgIHdlZWs6IGdldFdlZWtseU5vdGVTZXR0aW5ncyxcbiAgICAgICAgbW9udGg6IGdldE1vbnRobHlOb3RlU2V0dGluZ3MsXG4gICAgICAgIHF1YXJ0ZXI6IGdldFF1YXJ0ZXJseU5vdGVTZXR0aW5ncyxcbiAgICAgICAgeWVhcjogZ2V0WWVhcmx5Tm90ZVNldHRpbmdzLFxuICAgIH07XG4gICAgY29uc3QgZm9ybWF0ID0gZ2V0U2V0dGluZ3NbZ3JhbnVsYXJpdHldKCkuZm9ybWF0LnNwbGl0KFwiL1wiKS5wb3AoKTtcbiAgICBjb25zdCBub3RlRGF0ZSA9IHdpbmRvdy5tb21lbnQoZmlsZW5hbWUsIGZvcm1hdCwgdHJ1ZSk7XG4gICAgaWYgKCFub3RlRGF0ZS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmIChpc0Zvcm1hdEFtYmlndW91cyhmb3JtYXQsIGdyYW51bGFyaXR5KSkge1xuICAgICAgICBpZiAoZ3JhbnVsYXJpdHkgPT09IFwid2Vla1wiKSB7XG4gICAgICAgICAgICBjb25zdCBjbGVhbkZvcm1hdCA9IHJlbW92ZUVzY2FwZWRDaGFyYWN0ZXJzKGZvcm1hdCk7XG4gICAgICAgICAgICBpZiAoL3d7MSwyfS9pLnRlc3QoY2xlYW5Gb3JtYXQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5tb21lbnQoZmlsZW5hbWUsIFxuICAgICAgICAgICAgICAgIC8vIElmIGZvcm1hdCBjb250YWlucyB3ZWVrLCByZW1vdmUgZGF5ICYgbW9udGggZm9ybWF0dGluZ1xuICAgICAgICAgICAgICAgIGZvcm1hdC5yZXBsYWNlKC9NezEsNH0vZywgXCJcIikucmVwbGFjZSgvRHsxLDR9L2csIFwiXCIpLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5vdGVEYXRlO1xufVxuXG5jbGFzcyBEYWlseU5vdGVzRm9sZGVyTWlzc2luZ0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIG1pbWljcyB0aGUgYmVoYXZpb3Igb2YgdGhlIGRhaWx5LW5vdGVzIHBsdWdpblxuICogc28gaXQgd2lsbCByZXBsYWNlIHt7ZGF0ZX19LCB7e3RpdGxlfX0sIGFuZCB7e3RpbWV9fSB3aXRoIHRoZVxuICogZm9ybWF0dGVkIHRpbWVzdGFtcC5cbiAqXG4gKiBOb3RlOiBpdCBoYXMgYW4gYWRkZWQgYm9udXMgdGhhdCBpdCdzIG5vdCAndG9kYXknIHNwZWNpZmljLlxuICovXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVEYWlseU5vdGUoZGF0ZSkge1xuICAgIGNvbnN0IGFwcCA9IHdpbmRvdy5hcHA7XG4gICAgY29uc3QgeyB2YXVsdCB9ID0gYXBwO1xuICAgIGNvbnN0IG1vbWVudCA9IHdpbmRvdy5tb21lbnQ7XG4gICAgY29uc3QgeyB0ZW1wbGF0ZSwgZm9ybWF0LCBmb2xkZXIgfSA9IGdldERhaWx5Tm90ZVNldHRpbmdzKCk7XG4gICAgY29uc3QgW3RlbXBsYXRlQ29udGVudHMsIElGb2xkSW5mb10gPSBhd2FpdCBnZXRUZW1wbGF0ZUluZm8odGVtcGxhdGUpO1xuICAgIGNvbnN0IGZpbGVuYW1lID0gZGF0ZS5mb3JtYXQoZm9ybWF0KTtcbiAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IGF3YWl0IGdldE5vdGVQYXRoKGZvbGRlciwgZmlsZW5hbWUpO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRGaWxlID0gYXdhaXQgdmF1bHQuY3JlYXRlKG5vcm1hbGl6ZWRQYXRoLCB0ZW1wbGF0ZUNvbnRlbnRzXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqZGF0ZVxccyp9fS9naSwgZmlsZW5hbWUpXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqdGltZVxccyp9fS9naSwgbW9tZW50KCkuZm9ybWF0KFwiSEg6bW1cIikpXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqdGl0bGVcXHMqfX0vZ2ksIGZpbGVuYW1lKVxuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKihkYXRlfHRpbWUpXFxzKigoWystXVxcZCspKFt5cW13ZGhzXSkpP1xccyooOi4rPyk/fX0vZ2ksIChfLCBfdGltZU9yRGF0ZSwgY2FsYywgdGltZURlbHRhLCB1bml0LCBtb21lbnRGb3JtYXQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IG1vbWVudCgpO1xuICAgICAgICAgICAgY29uc3QgY3VycmVudERhdGUgPSBkYXRlLmNsb25lKCkuc2V0KHtcbiAgICAgICAgICAgICAgICBob3VyOiBub3cuZ2V0KFwiaG91clwiKSxcbiAgICAgICAgICAgICAgICBtaW51dGU6IG5vdy5nZXQoXCJtaW51dGVcIiksXG4gICAgICAgICAgICAgICAgc2Vjb25kOiBub3cuZ2V0KFwic2Vjb25kXCIpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoY2FsYykge1xuICAgICAgICAgICAgICAgIGN1cnJlbnREYXRlLmFkZChwYXJzZUludCh0aW1lRGVsdGEsIDEwKSwgdW5pdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobW9tZW50Rm9ybWF0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnREYXRlLmZvcm1hdChtb21lbnRGb3JtYXQuc3Vic3RyaW5nKDEpLnRyaW0oKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudERhdGUuZm9ybWF0KGZvcm1hdCk7XG4gICAgICAgIH0pXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqeWVzdGVyZGF5XFxzKn19L2dpLCBkYXRlLmNsb25lKCkuc3VidHJhY3QoMSwgXCJkYXlcIikuZm9ybWF0KGZvcm1hdCkpXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqdG9tb3Jyb3dcXHMqfX0vZ2ksIGRhdGUuY2xvbmUoKS5hZGQoMSwgXCJkXCIpLmZvcm1hdChmb3JtYXQpKSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIGFwcC5mb2xkTWFuYWdlci5zYXZlKGNyZWF0ZWRGaWxlLCBJRm9sZEluZm8pO1xuICAgICAgICByZXR1cm4gY3JlYXRlZEZpbGU7XG4gICAgfVxuICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBmaWxlOiAnJHtub3JtYWxpemVkUGF0aH0nYCwgZXJyKTtcbiAgICAgICAgbmV3IG9ic2lkaWFuLk5vdGljZShcIlVuYWJsZSB0byBjcmVhdGUgbmV3IGZpbGUuXCIpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldERhaWx5Tm90ZShkYXRlLCBkYWlseU5vdGVzKSB7XG4gICAgcmV0dXJuIGRhaWx5Tm90ZXNbZ2V0RGF0ZVVJRChkYXRlLCBcImRheVwiKV0gPz8gbnVsbDtcbn1cbmZ1bmN0aW9uIGdldEFsbERhaWx5Tm90ZXMoKSB7XG4gICAgLyoqXG4gICAgICogRmluZCBhbGwgZGFpbHkgbm90ZXMgaW4gdGhlIGRhaWx5IG5vdGUgZm9sZGVyXG4gICAgICovXG4gICAgY29uc3QgeyB2YXVsdCB9ID0gd2luZG93LmFwcDtcbiAgICBjb25zdCB7IGZvbGRlciB9ID0gZ2V0RGFpbHlOb3RlU2V0dGluZ3MoKTtcbiAgICBjb25zdCBkYWlseU5vdGVzRm9sZGVyID0gdmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKG9ic2lkaWFuLm5vcm1hbGl6ZVBhdGgoZm9sZGVyKSk7XG4gICAgaWYgKCFkYWlseU5vdGVzRm9sZGVyKSB7XG4gICAgICAgIHRocm93IG5ldyBEYWlseU5vdGVzRm9sZGVyTWlzc2luZ0Vycm9yKFwiRmFpbGVkIHRvIGZpbmQgZGFpbHkgbm90ZXMgZm9sZGVyXCIpO1xuICAgIH1cbiAgICBjb25zdCBkYWlseU5vdGVzID0ge307XG4gICAgb2JzaWRpYW4uVmF1bHQucmVjdXJzZUNoaWxkcmVuKGRhaWx5Tm90ZXNGb2xkZXIsIChub3RlKSA9PiB7XG4gICAgICAgIGlmIChub3RlIGluc3RhbmNlb2Ygb2JzaWRpYW4uVEZpbGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGUgPSBnZXREYXRlRnJvbUZpbGUobm90ZSwgXCJkYXlcIik7XG4gICAgICAgICAgICBpZiAoZGF0ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGVTdHJpbmcgPSBnZXREYXRlVUlEKGRhdGUsIFwiZGF5XCIpO1xuICAgICAgICAgICAgICAgIGRhaWx5Tm90ZXNbZGF0ZVN0cmluZ10gPSBub3RlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGRhaWx5Tm90ZXM7XG59XG5cbmNsYXNzIFdlZWtseU5vdGVzRm9sZGVyTWlzc2luZ0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxuZnVuY3Rpb24gZ2V0RGF5c09mV2VlaygpIHtcbiAgICBjb25zdCB7IG1vbWVudCB9ID0gd2luZG93O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgbGV0IHdlZWtTdGFydCA9IG1vbWVudC5sb2NhbGVEYXRhKCkuX3dlZWsuZG93O1xuICAgIGNvbnN0IGRheXNPZldlZWsgPSBbXG4gICAgICAgIFwic3VuZGF5XCIsXG4gICAgICAgIFwibW9uZGF5XCIsXG4gICAgICAgIFwidHVlc2RheVwiLFxuICAgICAgICBcIndlZG5lc2RheVwiLFxuICAgICAgICBcInRodXJzZGF5XCIsXG4gICAgICAgIFwiZnJpZGF5XCIsXG4gICAgICAgIFwic2F0dXJkYXlcIixcbiAgICBdO1xuICAgIHdoaWxlICh3ZWVrU3RhcnQpIHtcbiAgICAgICAgZGF5c09mV2Vlay5wdXNoKGRheXNPZldlZWsuc2hpZnQoKSk7XG4gICAgICAgIHdlZWtTdGFydC0tO1xuICAgIH1cbiAgICByZXR1cm4gZGF5c09mV2Vlaztcbn1cbmZ1bmN0aW9uIGdldERheU9mV2Vla051bWVyaWNhbFZhbHVlKGRheU9mV2Vla05hbWUpIHtcbiAgICByZXR1cm4gZ2V0RGF5c09mV2VlaygpLmluZGV4T2YoZGF5T2ZXZWVrTmFtZS50b0xvd2VyQ2FzZSgpKTtcbn1cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdlZWtseU5vdGUoZGF0ZSkge1xuICAgIGNvbnN0IHsgdmF1bHQgfSA9IHdpbmRvdy5hcHA7XG4gICAgY29uc3QgeyB0ZW1wbGF0ZSwgZm9ybWF0LCBmb2xkZXIgfSA9IGdldFdlZWtseU5vdGVTZXR0aW5ncygpO1xuICAgIGNvbnN0IFt0ZW1wbGF0ZUNvbnRlbnRzLCBJRm9sZEluZm9dID0gYXdhaXQgZ2V0VGVtcGxhdGVJbmZvKHRlbXBsYXRlKTtcbiAgICBjb25zdCBmaWxlbmFtZSA9IGRhdGUuZm9ybWF0KGZvcm1hdCk7XG4gICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSBhd2FpdCBnZXROb3RlUGF0aChmb2xkZXIsIGZpbGVuYW1lKTtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBjcmVhdGVkRmlsZSA9IGF3YWl0IHZhdWx0LmNyZWF0ZShub3JtYWxpemVkUGF0aCwgdGVtcGxhdGVDb250ZW50c1xuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKihkYXRlfHRpbWUpXFxzKigoWystXVxcZCspKFt5cW13ZGhzXSkpP1xccyooOi4rPyk/fX0vZ2ksIChfLCBfdGltZU9yRGF0ZSwgY2FsYywgdGltZURlbHRhLCB1bml0LCBtb21lbnRGb3JtYXQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHdpbmRvdy5tb21lbnQoKTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnREYXRlID0gZGF0ZS5jbG9uZSgpLnNldCh7XG4gICAgICAgICAgICAgICAgaG91cjogbm93LmdldChcImhvdXJcIiksXG4gICAgICAgICAgICAgICAgbWludXRlOiBub3cuZ2V0KFwibWludXRlXCIpLFxuICAgICAgICAgICAgICAgIHNlY29uZDogbm93LmdldChcInNlY29uZFwiKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGNhbGMpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50RGF0ZS5hZGQocGFyc2VJbnQodGltZURlbHRhLCAxMCksIHVuaXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1vbWVudEZvcm1hdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50RGF0ZS5mb3JtYXQobW9tZW50Rm9ybWF0LnN1YnN0cmluZygxKS50cmltKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnREYXRlLmZvcm1hdChmb3JtYXQpO1xuICAgICAgICB9KVxuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKnRpdGxlXFxzKn19L2dpLCBmaWxlbmFtZSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyp0aW1lXFxzKn19L2dpLCB3aW5kb3cubW9tZW50KCkuZm9ybWF0KFwiSEg6bW1cIikpXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqKHN1bmRheXxtb25kYXl8dHVlc2RheXx3ZWRuZXNkYXl8dGh1cnNkYXl8ZnJpZGF5fHNhdHVyZGF5KVxccyo6KC4qPyl9fS9naSwgKF8sIGRheU9mV2VlaywgbW9tZW50Rm9ybWF0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkYXkgPSBnZXREYXlPZldlZWtOdW1lcmljYWxWYWx1ZShkYXlPZldlZWspO1xuICAgICAgICAgICAgcmV0dXJuIGRhdGUud2Vla2RheShkYXkpLmZvcm1hdChtb21lbnRGb3JtYXQudHJpbSgpKTtcbiAgICAgICAgfSkpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICB3aW5kb3cuYXBwLmZvbGRNYW5hZ2VyLnNhdmUoY3JlYXRlZEZpbGUsIElGb2xkSW5mbyk7XG4gICAgICAgIHJldHVybiBjcmVhdGVkRmlsZTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIGZpbGU6ICcke25vcm1hbGl6ZWRQYXRofSdgLCBlcnIpO1xuICAgICAgICBuZXcgb2JzaWRpYW4uTm90aWNlKFwiVW5hYmxlIHRvIGNyZWF0ZSBuZXcgZmlsZS5cIik7XG4gICAgfVxufVxuZnVuY3Rpb24gZ2V0V2Vla2x5Tm90ZShkYXRlLCB3ZWVrbHlOb3Rlcykge1xuICAgIHJldHVybiB3ZWVrbHlOb3Rlc1tnZXREYXRlVUlEKGRhdGUsIFwid2Vla1wiKV0gPz8gbnVsbDtcbn1cbmZ1bmN0aW9uIGdldEFsbFdlZWtseU5vdGVzKCkge1xuICAgIGNvbnN0IHdlZWtseU5vdGVzID0ge307XG4gICAgaWYgKCFhcHBIYXNXZWVrbHlOb3Rlc1BsdWdpbkxvYWRlZCgpKSB7XG4gICAgICAgIHJldHVybiB3ZWVrbHlOb3RlcztcbiAgICB9XG4gICAgY29uc3QgeyB2YXVsdCB9ID0gd2luZG93LmFwcDtcbiAgICBjb25zdCB7IGZvbGRlciB9ID0gZ2V0V2Vla2x5Tm90ZVNldHRpbmdzKCk7XG4gICAgY29uc3Qgd2Vla2x5Tm90ZXNGb2xkZXIgPSB2YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgob2JzaWRpYW4ubm9ybWFsaXplUGF0aChmb2xkZXIpKTtcbiAgICBpZiAoIXdlZWtseU5vdGVzRm9sZGVyKSB7XG4gICAgICAgIHRocm93IG5ldyBXZWVrbHlOb3Rlc0ZvbGRlck1pc3NpbmdFcnJvcihcIkZhaWxlZCB0byBmaW5kIHdlZWtseSBub3RlcyBmb2xkZXJcIik7XG4gICAgfVxuICAgIG9ic2lkaWFuLlZhdWx0LnJlY3Vyc2VDaGlsZHJlbih3ZWVrbHlOb3Rlc0ZvbGRlciwgKG5vdGUpID0+IHtcbiAgICAgICAgaWYgKG5vdGUgaW5zdGFuY2VvZiBvYnNpZGlhbi5URmlsZSkge1xuICAgICAgICAgICAgY29uc3QgZGF0ZSA9IGdldERhdGVGcm9tRmlsZShub3RlLCBcIndlZWtcIik7XG4gICAgICAgICAgICBpZiAoZGF0ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGVTdHJpbmcgPSBnZXREYXRlVUlEKGRhdGUsIFwid2Vla1wiKTtcbiAgICAgICAgICAgICAgICB3ZWVrbHlOb3Rlc1tkYXRlU3RyaW5nXSA9IG5vdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gd2Vla2x5Tm90ZXM7XG59XG5cbmNsYXNzIE1vbnRobHlOb3Rlc0ZvbGRlck1pc3NpbmdFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBtaW1pY3MgdGhlIGJlaGF2aW9yIG9mIHRoZSBkYWlseS1ub3RlcyBwbHVnaW5cbiAqIHNvIGl0IHdpbGwgcmVwbGFjZSB7e2RhdGV9fSwge3t0aXRsZX19LCBhbmQge3t0aW1lfX0gd2l0aCB0aGVcbiAqIGZvcm1hdHRlZCB0aW1lc3RhbXAuXG4gKlxuICogTm90ZTogaXQgaGFzIGFuIGFkZGVkIGJvbnVzIHRoYXQgaXQncyBub3QgJ3RvZGF5JyBzcGVjaWZpYy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gY3JlYXRlTW9udGhseU5vdGUoZGF0ZSkge1xuICAgIGNvbnN0IHsgdmF1bHQgfSA9IHdpbmRvdy5hcHA7XG4gICAgY29uc3QgeyB0ZW1wbGF0ZSwgZm9ybWF0LCBmb2xkZXIgfSA9IGdldE1vbnRobHlOb3RlU2V0dGluZ3MoKTtcbiAgICBjb25zdCBbdGVtcGxhdGVDb250ZW50cywgSUZvbGRJbmZvXSA9IGF3YWl0IGdldFRlbXBsYXRlSW5mbyh0ZW1wbGF0ZSk7XG4gICAgY29uc3QgZmlsZW5hbWUgPSBkYXRlLmZvcm1hdChmb3JtYXQpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gYXdhaXQgZ2V0Tm90ZVBhdGgoZm9sZGVyLCBmaWxlbmFtZSk7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY3JlYXRlZEZpbGUgPSBhd2FpdCB2YXVsdC5jcmVhdGUobm9ybWFsaXplZFBhdGgsIHRlbXBsYXRlQ29udGVudHNcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyooZGF0ZXx0aW1lKVxccyooKFsrLV1cXGQrKShbeXFtd2Roc10pKT9cXHMqKDouKz8pP319L2dpLCAoXywgX3RpbWVPckRhdGUsIGNhbGMsIHRpbWVEZWx0YSwgdW5pdCwgbW9tZW50Rm9ybWF0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSB3aW5kb3cubW9tZW50KCk7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RGF0ZSA9IGRhdGUuY2xvbmUoKS5zZXQoe1xuICAgICAgICAgICAgICAgIGhvdXI6IG5vdy5nZXQoXCJob3VyXCIpLFxuICAgICAgICAgICAgICAgIG1pbnV0ZTogbm93LmdldChcIm1pbnV0ZVwiKSxcbiAgICAgICAgICAgICAgICBzZWNvbmQ6IG5vdy5nZXQoXCJzZWNvbmRcIiksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChjYWxjKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudERhdGUuYWRkKHBhcnNlSW50KHRpbWVEZWx0YSwgMTApLCB1bml0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtb21lbnRGb3JtYXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudERhdGUuZm9ybWF0KG1vbWVudEZvcm1hdC5zdWJzdHJpbmcoMSkudHJpbSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50RGF0ZS5mb3JtYXQoZm9ybWF0KTtcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccypkYXRlXFxzKn19L2dpLCBmaWxlbmFtZSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyp0aW1lXFxzKn19L2dpLCB3aW5kb3cubW9tZW50KCkuZm9ybWF0KFwiSEg6bW1cIikpXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqdGl0bGVcXHMqfX0vZ2ksIGZpbGVuYW1lKSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIHdpbmRvdy5hcHAuZm9sZE1hbmFnZXIuc2F2ZShjcmVhdGVkRmlsZSwgSUZvbGRJbmZvKTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZWRGaWxlO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgZmlsZTogJyR7bm9ybWFsaXplZFBhdGh9J2AsIGVycik7XG4gICAgICAgIG5ldyBvYnNpZGlhbi5Ob3RpY2UoXCJVbmFibGUgdG8gY3JlYXRlIG5ldyBmaWxlLlwiKTtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRNb250aGx5Tm90ZShkYXRlLCBtb250aGx5Tm90ZXMpIHtcbiAgICByZXR1cm4gbW9udGhseU5vdGVzW2dldERhdGVVSUQoZGF0ZSwgXCJtb250aFwiKV0gPz8gbnVsbDtcbn1cbmZ1bmN0aW9uIGdldEFsbE1vbnRobHlOb3RlcygpIHtcbiAgICBjb25zdCBtb250aGx5Tm90ZXMgPSB7fTtcbiAgICBpZiAoIWFwcEhhc01vbnRobHlOb3Rlc1BsdWdpbkxvYWRlZCgpKSB7XG4gICAgICAgIHJldHVybiBtb250aGx5Tm90ZXM7XG4gICAgfVxuICAgIGNvbnN0IHsgdmF1bHQgfSA9IHdpbmRvdy5hcHA7XG4gICAgY29uc3QgeyBmb2xkZXIgfSA9IGdldE1vbnRobHlOb3RlU2V0dGluZ3MoKTtcbiAgICBjb25zdCBtb250aGx5Tm90ZXNGb2xkZXIgPSB2YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgob2JzaWRpYW4ubm9ybWFsaXplUGF0aChmb2xkZXIpKTtcbiAgICBpZiAoIW1vbnRobHlOb3Rlc0ZvbGRlcikge1xuICAgICAgICB0aHJvdyBuZXcgTW9udGhseU5vdGVzRm9sZGVyTWlzc2luZ0Vycm9yKFwiRmFpbGVkIHRvIGZpbmQgbW9udGhseSBub3RlcyBmb2xkZXJcIik7XG4gICAgfVxuICAgIG9ic2lkaWFuLlZhdWx0LnJlY3Vyc2VDaGlsZHJlbihtb250aGx5Tm90ZXNGb2xkZXIsIChub3RlKSA9PiB7XG4gICAgICAgIGlmIChub3RlIGluc3RhbmNlb2Ygb2JzaWRpYW4uVEZpbGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGUgPSBnZXREYXRlRnJvbUZpbGUobm90ZSwgXCJtb250aFwiKTtcbiAgICAgICAgICAgIGlmIChkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZVN0cmluZyA9IGdldERhdGVVSUQoZGF0ZSwgXCJtb250aFwiKTtcbiAgICAgICAgICAgICAgICBtb250aGx5Tm90ZXNbZGF0ZVN0cmluZ10gPSBub3RlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIG1vbnRobHlOb3Rlcztcbn1cblxuY2xhc3MgUXVhcnRlcmx5Tm90ZXNGb2xkZXJNaXNzaW5nRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG59XG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gbWltaWNzIHRoZSBiZWhhdmlvciBvZiB0aGUgZGFpbHktbm90ZXMgcGx1Z2luXG4gKiBzbyBpdCB3aWxsIHJlcGxhY2Uge3tkYXRlfX0sIHt7dGl0bGV9fSwgYW5kIHt7dGltZX19IHdpdGggdGhlXG4gKiBmb3JtYXR0ZWQgdGltZXN0YW1wLlxuICpcbiAqIE5vdGU6IGl0IGhhcyBhbiBhZGRlZCBib251cyB0aGF0IGl0J3Mgbm90ICd0b2RheScgc3BlY2lmaWMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVF1YXJ0ZXJseU5vdGUoZGF0ZSkge1xuICAgIGNvbnN0IHsgdmF1bHQgfSA9IHdpbmRvdy5hcHA7XG4gICAgY29uc3QgeyB0ZW1wbGF0ZSwgZm9ybWF0LCBmb2xkZXIgfSA9IGdldFF1YXJ0ZXJseU5vdGVTZXR0aW5ncygpO1xuICAgIGNvbnN0IFt0ZW1wbGF0ZUNvbnRlbnRzLCBJRm9sZEluZm9dID0gYXdhaXQgZ2V0VGVtcGxhdGVJbmZvKHRlbXBsYXRlKTtcbiAgICBjb25zdCBmaWxlbmFtZSA9IGRhdGUuZm9ybWF0KGZvcm1hdCk7XG4gICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSBhd2FpdCBnZXROb3RlUGF0aChmb2xkZXIsIGZpbGVuYW1lKTtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBjcmVhdGVkRmlsZSA9IGF3YWl0IHZhdWx0LmNyZWF0ZShub3JtYWxpemVkUGF0aCwgdGVtcGxhdGVDb250ZW50c1xuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKihkYXRlfHRpbWUpXFxzKigoWystXVxcZCspKFt5cW13ZGhzXSkpP1xccyooOi4rPyk/fX0vZ2ksIChfLCBfdGltZU9yRGF0ZSwgY2FsYywgdGltZURlbHRhLCB1bml0LCBtb21lbnRGb3JtYXQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHdpbmRvdy5tb21lbnQoKTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnREYXRlID0gZGF0ZS5jbG9uZSgpLnNldCh7XG4gICAgICAgICAgICAgICAgaG91cjogbm93LmdldChcImhvdXJcIiksXG4gICAgICAgICAgICAgICAgbWludXRlOiBub3cuZ2V0KFwibWludXRlXCIpLFxuICAgICAgICAgICAgICAgIHNlY29uZDogbm93LmdldChcInNlY29uZFwiKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGNhbGMpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50RGF0ZS5hZGQocGFyc2VJbnQodGltZURlbHRhLCAxMCksIHVuaXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1vbWVudEZvcm1hdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50RGF0ZS5mb3JtYXQobW9tZW50Rm9ybWF0LnN1YnN0cmluZygxKS50cmltKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnREYXRlLmZvcm1hdChmb3JtYXQpO1xuICAgICAgICB9KVxuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKmRhdGVcXHMqfX0vZ2ksIGZpbGVuYW1lKVxuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKnRpbWVcXHMqfX0vZ2ksIHdpbmRvdy5tb21lbnQoKS5mb3JtYXQoXCJISDptbVwiKSlcbiAgICAgICAgICAgIC5yZXBsYWNlKC97e1xccyp0aXRsZVxccyp9fS9naSwgZmlsZW5hbWUpKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgd2luZG93LmFwcC5mb2xkTWFuYWdlci5zYXZlKGNyZWF0ZWRGaWxlLCBJRm9sZEluZm8pO1xuICAgICAgICByZXR1cm4gY3JlYXRlZEZpbGU7XG4gICAgfVxuICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBmaWxlOiAnJHtub3JtYWxpemVkUGF0aH0nYCwgZXJyKTtcbiAgICAgICAgbmV3IG9ic2lkaWFuLk5vdGljZShcIlVuYWJsZSB0byBjcmVhdGUgbmV3IGZpbGUuXCIpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldFF1YXJ0ZXJseU5vdGUoZGF0ZSwgcXVhcnRlcmx5KSB7XG4gICAgcmV0dXJuIHF1YXJ0ZXJseVtnZXREYXRlVUlEKGRhdGUsIFwicXVhcnRlclwiKV0gPz8gbnVsbDtcbn1cbmZ1bmN0aW9uIGdldEFsbFF1YXJ0ZXJseU5vdGVzKCkge1xuICAgIGNvbnN0IHF1YXJ0ZXJseSA9IHt9O1xuICAgIGlmICghYXBwSGFzUXVhcnRlcmx5Tm90ZXNQbHVnaW5Mb2FkZWQoKSkge1xuICAgICAgICByZXR1cm4gcXVhcnRlcmx5O1xuICAgIH1cbiAgICBjb25zdCB7IHZhdWx0IH0gPSB3aW5kb3cuYXBwO1xuICAgIGNvbnN0IHsgZm9sZGVyIH0gPSBnZXRRdWFydGVybHlOb3RlU2V0dGluZ3MoKTtcbiAgICBjb25zdCBxdWFydGVybHlGb2xkZXIgPSB2YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgob2JzaWRpYW4ubm9ybWFsaXplUGF0aChmb2xkZXIpKTtcbiAgICBpZiAoIXF1YXJ0ZXJseUZvbGRlcikge1xuICAgICAgICB0aHJvdyBuZXcgUXVhcnRlcmx5Tm90ZXNGb2xkZXJNaXNzaW5nRXJyb3IoXCJGYWlsZWQgdG8gZmluZCBxdWFydGVybHkgbm90ZXMgZm9sZGVyXCIpO1xuICAgIH1cbiAgICBvYnNpZGlhbi5WYXVsdC5yZWN1cnNlQ2hpbGRyZW4ocXVhcnRlcmx5Rm9sZGVyLCAobm90ZSkgPT4ge1xuICAgICAgICBpZiAobm90ZSBpbnN0YW5jZW9mIG9ic2lkaWFuLlRGaWxlKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRlID0gZ2V0RGF0ZUZyb21GaWxlKG5vdGUsIFwicXVhcnRlclwiKTtcbiAgICAgICAgICAgIGlmIChkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZVN0cmluZyA9IGdldERhdGVVSUQoZGF0ZSwgXCJxdWFydGVyXCIpO1xuICAgICAgICAgICAgICAgIHF1YXJ0ZXJseVtkYXRlU3RyaW5nXSA9IG5vdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcXVhcnRlcmx5O1xufVxuXG5jbGFzcyBZZWFybHlOb3Rlc0ZvbGRlck1pc3NpbmdFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBtaW1pY3MgdGhlIGJlaGF2aW9yIG9mIHRoZSBkYWlseS1ub3RlcyBwbHVnaW5cbiAqIHNvIGl0IHdpbGwgcmVwbGFjZSB7e2RhdGV9fSwge3t0aXRsZX19LCBhbmQge3t0aW1lfX0gd2l0aCB0aGVcbiAqIGZvcm1hdHRlZCB0aW1lc3RhbXAuXG4gKlxuICogTm90ZTogaXQgaGFzIGFuIGFkZGVkIGJvbnVzIHRoYXQgaXQncyBub3QgJ3RvZGF5JyBzcGVjaWZpYy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gY3JlYXRlWWVhcmx5Tm90ZShkYXRlKSB7XG4gICAgY29uc3QgeyB2YXVsdCB9ID0gd2luZG93LmFwcDtcbiAgICBjb25zdCB7IHRlbXBsYXRlLCBmb3JtYXQsIGZvbGRlciB9ID0gZ2V0WWVhcmx5Tm90ZVNldHRpbmdzKCk7XG4gICAgY29uc3QgW3RlbXBsYXRlQ29udGVudHMsIElGb2xkSW5mb10gPSBhd2FpdCBnZXRUZW1wbGF0ZUluZm8odGVtcGxhdGUpO1xuICAgIGNvbnN0IGZpbGVuYW1lID0gZGF0ZS5mb3JtYXQoZm9ybWF0KTtcbiAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IGF3YWl0IGdldE5vdGVQYXRoKGZvbGRlciwgZmlsZW5hbWUpO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRGaWxlID0gYXdhaXQgdmF1bHQuY3JlYXRlKG5vcm1hbGl6ZWRQYXRoLCB0ZW1wbGF0ZUNvbnRlbnRzXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqKGRhdGV8dGltZSlcXHMqKChbKy1dXFxkKykoW3lxbXdkaHNdKSk/XFxzKig6Lis/KT99fS9naSwgKF8sIF90aW1lT3JEYXRlLCBjYWxjLCB0aW1lRGVsdGEsIHVuaXQsIG1vbWVudEZvcm1hdCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gd2luZG93Lm1vbWVudCgpO1xuICAgICAgICAgICAgY29uc3QgY3VycmVudERhdGUgPSBkYXRlLmNsb25lKCkuc2V0KHtcbiAgICAgICAgICAgICAgICBob3VyOiBub3cuZ2V0KFwiaG91clwiKSxcbiAgICAgICAgICAgICAgICBtaW51dGU6IG5vdy5nZXQoXCJtaW51dGVcIiksXG4gICAgICAgICAgICAgICAgc2Vjb25kOiBub3cuZ2V0KFwic2Vjb25kXCIpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoY2FsYykge1xuICAgICAgICAgICAgICAgIGN1cnJlbnREYXRlLmFkZChwYXJzZUludCh0aW1lRGVsdGEsIDEwKSwgdW5pdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobW9tZW50Rm9ybWF0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnREYXRlLmZvcm1hdChtb21lbnRGb3JtYXQuc3Vic3RyaW5nKDEpLnRyaW0oKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudERhdGUuZm9ybWF0KGZvcm1hdCk7XG4gICAgICAgIH0pXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqZGF0ZVxccyp9fS9naSwgZmlsZW5hbWUpXG4gICAgICAgICAgICAucmVwbGFjZSgve3tcXHMqdGltZVxccyp9fS9naSwgd2luZG93Lm1vbWVudCgpLmZvcm1hdChcIkhIOm1tXCIpKVxuICAgICAgICAgICAgLnJlcGxhY2UoL3t7XFxzKnRpdGxlXFxzKn19L2dpLCBmaWxlbmFtZSkpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICB3aW5kb3cuYXBwLmZvbGRNYW5hZ2VyLnNhdmUoY3JlYXRlZEZpbGUsIElGb2xkSW5mbyk7XG4gICAgICAgIHJldHVybiBjcmVhdGVkRmlsZTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIGZpbGU6ICcke25vcm1hbGl6ZWRQYXRofSdgLCBlcnIpO1xuICAgICAgICBuZXcgb2JzaWRpYW4uTm90aWNlKFwiVW5hYmxlIHRvIGNyZWF0ZSBuZXcgZmlsZS5cIik7XG4gICAgfVxufVxuZnVuY3Rpb24gZ2V0WWVhcmx5Tm90ZShkYXRlLCB5ZWFybHlOb3Rlcykge1xuICAgIHJldHVybiB5ZWFybHlOb3Rlc1tnZXREYXRlVUlEKGRhdGUsIFwieWVhclwiKV0gPz8gbnVsbDtcbn1cbmZ1bmN0aW9uIGdldEFsbFllYXJseU5vdGVzKCkge1xuICAgIGNvbnN0IHllYXJseU5vdGVzID0ge307XG4gICAgaWYgKCFhcHBIYXNZZWFybHlOb3Rlc1BsdWdpbkxvYWRlZCgpKSB7XG4gICAgICAgIHJldHVybiB5ZWFybHlOb3RlcztcbiAgICB9XG4gICAgY29uc3QgeyB2YXVsdCB9ID0gd2luZG93LmFwcDtcbiAgICBjb25zdCB7IGZvbGRlciB9ID0gZ2V0WWVhcmx5Tm90ZVNldHRpbmdzKCk7XG4gICAgY29uc3QgeWVhcmx5Tm90ZXNGb2xkZXIgPSB2YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgob2JzaWRpYW4ubm9ybWFsaXplUGF0aChmb2xkZXIpKTtcbiAgICBpZiAoIXllYXJseU5vdGVzRm9sZGVyKSB7XG4gICAgICAgIHRocm93IG5ldyBZZWFybHlOb3Rlc0ZvbGRlck1pc3NpbmdFcnJvcihcIkZhaWxlZCB0byBmaW5kIHllYXJseSBub3RlcyBmb2xkZXJcIik7XG4gICAgfVxuICAgIG9ic2lkaWFuLlZhdWx0LnJlY3Vyc2VDaGlsZHJlbih5ZWFybHlOb3Rlc0ZvbGRlciwgKG5vdGUpID0+IHtcbiAgICAgICAgaWYgKG5vdGUgaW5zdGFuY2VvZiBvYnNpZGlhbi5URmlsZSkge1xuICAgICAgICAgICAgY29uc3QgZGF0ZSA9IGdldERhdGVGcm9tRmlsZShub3RlLCBcInllYXJcIik7XG4gICAgICAgICAgICBpZiAoZGF0ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGVTdHJpbmcgPSBnZXREYXRlVUlEKGRhdGUsIFwieWVhclwiKTtcbiAgICAgICAgICAgICAgICB5ZWFybHlOb3Rlc1tkYXRlU3RyaW5nXSA9IG5vdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4geWVhcmx5Tm90ZXM7XG59XG5cbmZ1bmN0aW9uIGFwcEhhc0RhaWx5Tm90ZXNQbHVnaW5Mb2FkZWQoKSB7XG4gICAgY29uc3QgeyBhcHAgfSA9IHdpbmRvdztcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IGRhaWx5Tm90ZXNQbHVnaW4gPSBhcHAuaW50ZXJuYWxQbHVnaW5zLnBsdWdpbnNbXCJkYWlseS1ub3Rlc1wiXTtcbiAgICBpZiAoZGFpbHlOb3Rlc1BsdWdpbiAmJiBkYWlseU5vdGVzUGx1Z2luLmVuYWJsZWQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgcGVyaW9kaWNOb3RlcyA9IGFwcC5wbHVnaW5zLmdldFBsdWdpbihcInBlcmlvZGljLW5vdGVzXCIpO1xuICAgIHJldHVybiBwZXJpb2RpY05vdGVzICYmIHBlcmlvZGljTm90ZXMuc2V0dGluZ3M/LmRhaWx5Py5lbmFibGVkO1xufVxuLyoqXG4gKiBYWFg6IFwiV2Vla2x5IE5vdGVzXCIgbGl2ZSBpbiBlaXRoZXIgdGhlIENhbGVuZGFyIHBsdWdpbiBvciB0aGUgcGVyaW9kaWMtbm90ZXMgcGx1Z2luLlxuICogQ2hlY2sgYm90aCB1bnRpbCB0aGUgd2Vla2x5IG5vdGVzIGZlYXR1cmUgaXMgcmVtb3ZlZCBmcm9tIHRoZSBDYWxlbmRhciBwbHVnaW4uXG4gKi9cbmZ1bmN0aW9uIGFwcEhhc1dlZWtseU5vdGVzUGx1Z2luTG9hZGVkKCkge1xuICAgIGNvbnN0IHsgYXBwIH0gPSB3aW5kb3c7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBpZiAoYXBwLnBsdWdpbnMuZ2V0UGx1Z2luKFwiY2FsZW5kYXJcIikpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgcGVyaW9kaWNOb3RlcyA9IGFwcC5wbHVnaW5zLmdldFBsdWdpbihcInBlcmlvZGljLW5vdGVzXCIpO1xuICAgIHJldHVybiBwZXJpb2RpY05vdGVzICYmIHBlcmlvZGljTm90ZXMuc2V0dGluZ3M/LndlZWtseT8uZW5hYmxlZDtcbn1cbmZ1bmN0aW9uIGFwcEhhc01vbnRobHlOb3Rlc1BsdWdpbkxvYWRlZCgpIHtcbiAgICBjb25zdCB7IGFwcCB9ID0gd2luZG93O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgcGVyaW9kaWNOb3RlcyA9IGFwcC5wbHVnaW5zLmdldFBsdWdpbihcInBlcmlvZGljLW5vdGVzXCIpO1xuICAgIHJldHVybiBwZXJpb2RpY05vdGVzICYmIHBlcmlvZGljTm90ZXMuc2V0dGluZ3M/Lm1vbnRobHk/LmVuYWJsZWQ7XG59XG5mdW5jdGlvbiBhcHBIYXNRdWFydGVybHlOb3Rlc1BsdWdpbkxvYWRlZCgpIHtcbiAgICBjb25zdCB7IGFwcCB9ID0gd2luZG93O1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgcGVyaW9kaWNOb3RlcyA9IGFwcC5wbHVnaW5zLmdldFBsdWdpbihcInBlcmlvZGljLW5vdGVzXCIpO1xuICAgIHJldHVybiBwZXJpb2RpY05vdGVzICYmIHBlcmlvZGljTm90ZXMuc2V0dGluZ3M/LnF1YXJ0ZXJseT8uZW5hYmxlZDtcbn1cbmZ1bmN0aW9uIGFwcEhhc1llYXJseU5vdGVzUGx1Z2luTG9hZGVkKCkge1xuICAgIGNvbnN0IHsgYXBwIH0gPSB3aW5kb3c7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBwZXJpb2RpY05vdGVzID0gYXBwLnBsdWdpbnMuZ2V0UGx1Z2luKFwicGVyaW9kaWMtbm90ZXNcIik7XG4gICAgcmV0dXJuIHBlcmlvZGljTm90ZXMgJiYgcGVyaW9kaWNOb3Rlcy5zZXR0aW5ncz8ueWVhcmx5Py5lbmFibGVkO1xufVxuZnVuY3Rpb24gZ2V0UGVyaW9kaWNOb3RlU2V0dGluZ3MoZ3JhbnVsYXJpdHkpIHtcbiAgICBjb25zdCBnZXRTZXR0aW5ncyA9IHtcbiAgICAgICAgZGF5OiBnZXREYWlseU5vdGVTZXR0aW5ncyxcbiAgICAgICAgd2VlazogZ2V0V2Vla2x5Tm90ZVNldHRpbmdzLFxuICAgICAgICBtb250aDogZ2V0TW9udGhseU5vdGVTZXR0aW5ncyxcbiAgICAgICAgcXVhcnRlcjogZ2V0UXVhcnRlcmx5Tm90ZVNldHRpbmdzLFxuICAgICAgICB5ZWFyOiBnZXRZZWFybHlOb3RlU2V0dGluZ3MsXG4gICAgfVtncmFudWxhcml0eV07XG4gICAgcmV0dXJuIGdldFNldHRpbmdzKCk7XG59XG5mdW5jdGlvbiBjcmVhdGVQZXJpb2RpY05vdGUoZ3JhbnVsYXJpdHksIGRhdGUpIHtcbiAgICBjb25zdCBjcmVhdGVGbiA9IHtcbiAgICAgICAgZGF5OiBjcmVhdGVEYWlseU5vdGUsXG4gICAgICAgIG1vbnRoOiBjcmVhdGVNb250aGx5Tm90ZSxcbiAgICAgICAgd2VlazogY3JlYXRlV2Vla2x5Tm90ZSxcbiAgICB9O1xuICAgIHJldHVybiBjcmVhdGVGbltncmFudWxhcml0eV0oZGF0ZSk7XG59XG5cbmV4cG9ydHMuREVGQVVMVF9EQUlMWV9OT1RFX0ZPUk1BVCA9IERFRkFVTFRfREFJTFlfTk9URV9GT1JNQVQ7XG5leHBvcnRzLkRFRkFVTFRfTU9OVEhMWV9OT1RFX0ZPUk1BVCA9IERFRkFVTFRfTU9OVEhMWV9OT1RFX0ZPUk1BVDtcbmV4cG9ydHMuREVGQVVMVF9RVUFSVEVSTFlfTk9URV9GT1JNQVQgPSBERUZBVUxUX1FVQVJURVJMWV9OT1RFX0ZPUk1BVDtcbmV4cG9ydHMuREVGQVVMVF9XRUVLTFlfTk9URV9GT1JNQVQgPSBERUZBVUxUX1dFRUtMWV9OT1RFX0ZPUk1BVDtcbmV4cG9ydHMuREVGQVVMVF9ZRUFSTFlfTk9URV9GT1JNQVQgPSBERUZBVUxUX1lFQVJMWV9OT1RFX0ZPUk1BVDtcbmV4cG9ydHMuYXBwSGFzRGFpbHlOb3Rlc1BsdWdpbkxvYWRlZCA9IGFwcEhhc0RhaWx5Tm90ZXNQbHVnaW5Mb2FkZWQ7XG5leHBvcnRzLmFwcEhhc01vbnRobHlOb3Rlc1BsdWdpbkxvYWRlZCA9IGFwcEhhc01vbnRobHlOb3Rlc1BsdWdpbkxvYWRlZDtcbmV4cG9ydHMuYXBwSGFzUXVhcnRlcmx5Tm90ZXNQbHVnaW5Mb2FkZWQgPSBhcHBIYXNRdWFydGVybHlOb3Rlc1BsdWdpbkxvYWRlZDtcbmV4cG9ydHMuYXBwSGFzV2Vla2x5Tm90ZXNQbHVnaW5Mb2FkZWQgPSBhcHBIYXNXZWVrbHlOb3Rlc1BsdWdpbkxvYWRlZDtcbmV4cG9ydHMuYXBwSGFzWWVhcmx5Tm90ZXNQbHVnaW5Mb2FkZWQgPSBhcHBIYXNZZWFybHlOb3Rlc1BsdWdpbkxvYWRlZDtcbmV4cG9ydHMuY3JlYXRlRGFpbHlOb3RlID0gY3JlYXRlRGFpbHlOb3RlO1xuZXhwb3J0cy5jcmVhdGVNb250aGx5Tm90ZSA9IGNyZWF0ZU1vbnRobHlOb3RlO1xuZXhwb3J0cy5jcmVhdGVQZXJpb2RpY05vdGUgPSBjcmVhdGVQZXJpb2RpY05vdGU7XG5leHBvcnRzLmNyZWF0ZVF1YXJ0ZXJseU5vdGUgPSBjcmVhdGVRdWFydGVybHlOb3RlO1xuZXhwb3J0cy5jcmVhdGVXZWVrbHlOb3RlID0gY3JlYXRlV2Vla2x5Tm90ZTtcbmV4cG9ydHMuY3JlYXRlWWVhcmx5Tm90ZSA9IGNyZWF0ZVllYXJseU5vdGU7XG5leHBvcnRzLmdldEFsbERhaWx5Tm90ZXMgPSBnZXRBbGxEYWlseU5vdGVzO1xuZXhwb3J0cy5nZXRBbGxNb250aGx5Tm90ZXMgPSBnZXRBbGxNb250aGx5Tm90ZXM7XG5leHBvcnRzLmdldEFsbFF1YXJ0ZXJseU5vdGVzID0gZ2V0QWxsUXVhcnRlcmx5Tm90ZXM7XG5leHBvcnRzLmdldEFsbFdlZWtseU5vdGVzID0gZ2V0QWxsV2Vla2x5Tm90ZXM7XG5leHBvcnRzLmdldEFsbFllYXJseU5vdGVzID0gZ2V0QWxsWWVhcmx5Tm90ZXM7XG5leHBvcnRzLmdldERhaWx5Tm90ZSA9IGdldERhaWx5Tm90ZTtcbmV4cG9ydHMuZ2V0RGFpbHlOb3RlU2V0dGluZ3MgPSBnZXREYWlseU5vdGVTZXR0aW5ncztcbmV4cG9ydHMuZ2V0RGF0ZUZyb21GaWxlID0gZ2V0RGF0ZUZyb21GaWxlO1xuZXhwb3J0cy5nZXREYXRlRnJvbVBhdGggPSBnZXREYXRlRnJvbVBhdGg7XG5leHBvcnRzLmdldERhdGVVSUQgPSBnZXREYXRlVUlEO1xuZXhwb3J0cy5nZXRNb250aGx5Tm90ZSA9IGdldE1vbnRobHlOb3RlO1xuZXhwb3J0cy5nZXRNb250aGx5Tm90ZVNldHRpbmdzID0gZ2V0TW9udGhseU5vdGVTZXR0aW5ncztcbmV4cG9ydHMuZ2V0UGVyaW9kaWNOb3RlU2V0dGluZ3MgPSBnZXRQZXJpb2RpY05vdGVTZXR0aW5ncztcbmV4cG9ydHMuZ2V0UXVhcnRlcmx5Tm90ZSA9IGdldFF1YXJ0ZXJseU5vdGU7XG5leHBvcnRzLmdldFF1YXJ0ZXJseU5vdGVTZXR0aW5ncyA9IGdldFF1YXJ0ZXJseU5vdGVTZXR0aW5ncztcbmV4cG9ydHMuZ2V0VGVtcGxhdGVJbmZvID0gZ2V0VGVtcGxhdGVJbmZvO1xuZXhwb3J0cy5nZXRXZWVrbHlOb3RlID0gZ2V0V2Vla2x5Tm90ZTtcbmV4cG9ydHMuZ2V0V2Vla2x5Tm90ZVNldHRpbmdzID0gZ2V0V2Vla2x5Tm90ZVNldHRpbmdzO1xuZXhwb3J0cy5nZXRZZWFybHlOb3RlID0gZ2V0WWVhcmx5Tm90ZTtcbmV4cG9ydHMuZ2V0WWVhcmx5Tm90ZVNldHRpbmdzID0gZ2V0WWVhcmx5Tm90ZVNldHRpbmdzO1xuIiwgImltcG9ydCB7IFBsdWdpbiwgVEZpbGUgfSBmcm9tICdvYnNpZGlhbic7XG5pbXBvcnQgeyBWSUVXX1RZUEUgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBERUZBVUxUX1NFVFRJTkdTLCBZYW90cFNldHRpbmdzLCBZYW90cFNldHRpbmdUYWIgfSBmcm9tICcuL3NldHRpbmdzJztcbmltcG9ydCB7IFRhc2tGaWxlVmlldyB9IGZyb20gJy4vdmlldy9UYXNrRmlsZVZpZXcnO1xuaW1wb3J0IHsgaW5zdGFsbEZpbGVJbnRlcmNlcHQsIHVuaW5zdGFsbEZpbGVJbnRlcmNlcHQgfSBmcm9tICcuL2ZpbGUtaW50ZXJjZXB0JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgWWFvdHBQbHVnaW4gZXh0ZW5kcyBQbHVnaW4ge1xuICBzZXR0aW5nczogWWFvdHBTZXR0aW5ncyA9IHsgLi4uREVGQVVMVF9TRVRUSU5HUyB9O1xuXG4gIHByaXZhdGUgdGFza1JlZ2V4OiBSZWdFeHAgPSBuZXcgUmVnRXhwKERFRkFVTFRfU0VUVElOR1MudGFza0ZpbGVSZWdleCk7XG5cbiAgYXN5bmMgb25sb2FkKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMubG9hZFNldHRpbmdzKCk7XG4gICAgdGhpcy5yZWJ1aWxkUmVnZXgoKTtcblxuICAgIC8vIFJlZ2lzdGVyIHRoZSBjdXN0b20gdmlld1xuICAgIHRoaXMucmVnaXN0ZXJWaWV3KFxuICAgICAgVklFV19UWVBFLFxuICAgICAgKGxlYWYpID0+XG4gICAgICAgIG5ldyBUYXNrRmlsZVZpZXcobGVhZiwgdGhpcy5zZXR0aW5ncywgKCkgPT4gdGhpcy5nZXRUYXNrRmlsZXMoKSlcbiAgICApO1xuXG4gICAgLy8gSW50ZXJjZXB0IGZpbGUgb3BlbnMgZm9yIHRhc2sgZmlsZXNcbiAgICBpbnN0YWxsRmlsZUludGVyY2VwdCgocGF0aCkgPT4gdGhpcy5pc1Rhc2tGaWxlKHBhdGgpKTtcblxuICAgIC8vIE9wZW4gZXhpc3RpbmcgdGFzay1maWxlIGxlYXZlcyBpbiB0aGUgY3VzdG9tIHZpZXcgb24gc3RhcnR1cFxuICAgIHRoaXMuYXBwLndvcmtzcGFjZS5vbkxheW91dFJlYWR5KCgpID0+IHtcbiAgICAgIHRoaXMucmVkaXJlY3RFeGlzdGluZ0xlYXZlcygpO1xuICAgIH0pO1xuXG4gICAgLy8gU2V0dGluZ3MgdGFiXG4gICAgdGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBZYW90cFNldHRpbmdUYWIodGhpcy5hcHAsIHRoaXMpKTtcblxuICB9XG5cbiAgb251bmxvYWQoKTogdm9pZCB7XG4gICAgdW5pbnN0YWxsRmlsZUludGVyY2VwdCgpO1xuICB9XG5cbiAgYXN5bmMgbG9hZFNldHRpbmdzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xuICB9XG5cbiAgYXN5bmMgc2F2ZVNldHRpbmdzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XG4gICAgdGhpcy5yZWJ1aWxkUmVnZXgoKTtcbiAgfVxuXG4gIGlzVGFza0ZpbGUocGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudGFza1JlZ2V4LnRlc3QocGF0aCk7XG4gIH1cblxuICBnZXRUYXNrRmlsZXMoKTogVEZpbGVbXSB7XG4gICAgcmV0dXJuIHRoaXMuYXBwLnZhdWx0XG4gICAgICAuZ2V0TWFya2Rvd25GaWxlcygpXG4gICAgICAuZmlsdGVyKChmKSA9PiB0aGlzLmlzVGFza0ZpbGUoZi5wYXRoKSk7XG4gIH1cblxuICBwcml2YXRlIHJlYnVpbGRSZWdleCgpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy50YXNrUmVnZXggPSBuZXcgUmVnRXhwKHRoaXMuc2V0dGluZ3MudGFza0ZpbGVSZWdleCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBGYWxsIGJhY2sgdG8gZGVmYXVsdCBpZiB0aGUgc2V0dGluZyBpcyBpbnZhbGlkXG4gICAgICB0aGlzLnRhc2tSZWdleCA9IG5ldyBSZWdFeHAoREVGQVVMVF9TRVRUSU5HUy50YXNrRmlsZVJlZ2V4KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlZGlyZWN0RXhpc3RpbmdMZWF2ZXMoKTogdm9pZCB7XG4gICAgdGhpcy5hcHAud29ya3NwYWNlLml0ZXJhdGVBbGxMZWF2ZXMoKGxlYWYpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRlID0gbGVhZi5nZXRWaWV3U3RhdGUoKTtcbiAgICAgIGlmIChcbiAgICAgICAgc3RhdGUudHlwZSA9PT0gJ21hcmtkb3duJyAmJlxuICAgICAgICBzdGF0ZS5zdGF0ZT8uZmlsZSAmJlxuICAgICAgICB0aGlzLmlzVGFza0ZpbGUoc3RhdGUuc3RhdGUuZmlsZSBhcyBzdHJpbmcpXG4gICAgICApIHtcbiAgICAgICAgbGVhZi5zZXRWaWV3U3RhdGUoeyAuLi5zdGF0ZSwgdHlwZTogVklFV19UWVBFIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbn1cbiIsICJleHBvcnQgY29uc3QgVklFV19UWVBFID0gJ3lhb3RwLXRhc2stdmlldyc7XG5leHBvcnQgY29uc3QgVklFV19JQ09OID0gJ2NoZWNrLXNxdWFyZSc7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0lOQk9YX1BBVEggPSAnVGFza3MvSW5ib3gubWQnO1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfVEFTS19SRUdFWCA9ICdeVGFza3NcXFxcLy4qXFxcXC5tZCQnO1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfREFJTFlfTk9URV9GT1JNQVQgPSAnWVlZWS1NTS1ERCc7XG5leHBvcnQgY29uc3QgREVGQVVMVF9EQUlMWV9OT1RFX0ZPTERFUiA9ICcnO1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfVEFTS19GSUxFX0ZPTERFUiA9ICdUYXNrcyc7XG5cbmV4cG9ydCBjb25zdCBEQUlMWV9OT1RFX1RBU0tTX0hFQURJTkcgPSAnIyMjIyBUYXNrcyc7XG4iLCAiaW1wb3J0IHsgQXBwLCBQbHVnaW5TZXR0aW5nVGFiLCBTZXR0aW5nIH0gZnJvbSAnb2JzaWRpYW4nO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9EQUlMWV9OT1RFX0ZPTERFUixcbiAgREVGQVVMVF9EQUlMWV9OT1RFX0ZPUk1BVCxcbiAgREVGQVVMVF9JTkJPWF9QQVRILFxuICBERUZBVUxUX1RBU0tfRklMRV9GT0xERVIsXG4gIERFRkFVTFRfVEFTS19SRUdFWCxcbn0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHR5cGUgWWFvdHBQbHVnaW4gZnJvbSAnLi9tYWluJztcblxuZXhwb3J0IGludGVyZmFjZSBZYW90cFNldHRpbmdzIHtcbiAgaW5ib3hQYXRoOiBzdHJpbmc7XG4gIHRhc2tGaWxlUmVnZXg6IHN0cmluZztcbiAgdGFza0ZpbGVGb2xkZXI6IHN0cmluZztcbiAgZGFpbHlOb3RlRm9ybWF0OiBzdHJpbmc7XG4gIGRhaWx5Tm90ZUZvbGRlcjogc3RyaW5nO1xufVxuXG5leHBvcnQgY29uc3QgREVGQVVMVF9TRVRUSU5HUzogWWFvdHBTZXR0aW5ncyA9IHtcbiAgaW5ib3hQYXRoOiBERUZBVUxUX0lOQk9YX1BBVEgsXG4gIHRhc2tGaWxlUmVnZXg6IERFRkFVTFRfVEFTS19SRUdFWCxcbiAgdGFza0ZpbGVGb2xkZXI6IERFRkFVTFRfVEFTS19GSUxFX0ZPTERFUixcbiAgZGFpbHlOb3RlRm9ybWF0OiBERUZBVUxUX0RBSUxZX05PVEVfRk9STUFULFxuICBkYWlseU5vdGVGb2xkZXI6IERFRkFVTFRfREFJTFlfTk9URV9GT0xERVIsXG59O1xuXG5leHBvcnQgY2xhc3MgWWFvdHBTZXR0aW5nVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XG4gIHBsdWdpbjogWWFvdHBQbHVnaW47XG5cbiAgY29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogWWFvdHBQbHVnaW4pIHtcbiAgICBzdXBlcihhcHAsIHBsdWdpbik7XG4gICAgdGhpcy5wbHVnaW4gPSBwbHVnaW47XG4gIH1cblxuICBkaXNwbGF5KCk6IHZvaWQge1xuICAgIGNvbnN0IHsgY29udGFpbmVyRWwgfSA9IHRoaXM7XG4gICAgY29udGFpbmVyRWwuZW1wdHkoKTtcblxuICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgLnNldE5hbWUoJ0luYm94IGZpbGUgcGF0aCcpXG4gICAgICAuc2V0RGVzYygnVmF1bHQtcmVsYXRpdmUgcGF0aCB0byB0aGUgZGVmYXVsdCBJbmJveCB0YXNrIGZpbGUuJylcbiAgICAgIC5hZGRUZXh0KCh0ZXh0KSA9PlxuICAgICAgICB0ZXh0XG4gICAgICAgICAgLnNldFBsYWNlaG9sZGVyKCdUYXNrcy9JbmJveC5tZCcpXG4gICAgICAgICAgLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmluYm94UGF0aClcbiAgICAgICAgICAub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5pbmJveFBhdGggPSB2YWx1ZS50cmltKCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgLnNldE5hbWUoJ1Rhc2sgZmlsZSByZWdleCcpXG4gICAgICAuc2V0RGVzYyhcbiAgICAgICAgJ1JlZ3VsYXIgZXhwcmVzc2lvbiBtYXRjaGVkIGFnYWluc3QgdmF1bHQtcmVsYXRpdmUgZmlsZSBwYXRocyB0byBpZGVudGlmeSB0YXNrIGZpbGVzLidcbiAgICAgIClcbiAgICAgIC5hZGRUZXh0KCh0ZXh0KSA9PiB7XG4gICAgICAgIHRleHRcbiAgICAgICAgICAuc2V0UGxhY2Vob2xkZXIoJ15UYXNrc1xcXFwvLipcXFxcLm1kJCcpXG4gICAgICAgICAgLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnRhc2tGaWxlUmVnZXgpXG4gICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgLy8gVmFsaWRhdGUgYmVmb3JlIHNhdmluZ1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgbmV3IFJlZ0V4cCh2YWx1ZSk7XG4gICAgICAgICAgICAgIHRleHQuaW5wdXRFbC5yZW1vdmVDbGFzcygneWFvdHAtc2V0dGluZy1lcnJvcicpO1xuICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy50YXNrRmlsZVJlZ2V4ID0gdmFsdWUudHJpbSgpO1xuICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICB0ZXh0LmlucHV0RWwuYWRkQ2xhc3MoJ3lhb3RwLXNldHRpbmctZXJyb3InKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgdGV4dC5pbnB1dEVsLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgICAgfSk7XG5cbiAgICBuZXcgU2V0dGluZyhjb250YWluZXJFbClcbiAgICAgIC5zZXROYW1lKCdUYXNrIGZpbGUgZm9sZGVyJylcbiAgICAgIC5zZXREZXNjKCdWYXVsdC1yZWxhdGl2ZSBmb2xkZXIgd2hlcmUgbmV3IHRhc2sgbGlzdHMgYXJlIGNyZWF0ZWQuIExlYXZlIGVtcHR5IGZvciB0aGUgdmF1bHQgcm9vdC4nKVxuICAgICAgLmFkZFRleHQoKHRleHQpID0+XG4gICAgICAgIHRleHRcbiAgICAgICAgICAuc2V0UGxhY2Vob2xkZXIoJ1Rhc2tzJylcbiAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudGFza0ZpbGVGb2xkZXIpXG4gICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MudGFza0ZpbGVGb2xkZXIgPSB2YWx1ZS50cmltKCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgLnNldE5hbWUoJ0RhaWx5IG5vdGUgZGF0ZSBmb3JtYXQnKVxuICAgICAgLnNldERlc2MoXG4gICAgICAgICdNb21lbnQuanMgZGF0ZSBmb3JtYXQgZm9yIGRhaWx5IG5vdGVzLiBTaG91bGQgbWF0Y2ggeW91ciBEYWlseSBOb3RlcyBwbHVnaW4gc2V0dGluZy4nXG4gICAgICApXG4gICAgICAuYWRkVGV4dCgodGV4dCkgPT5cbiAgICAgICAgdGV4dFxuICAgICAgICAgIC5zZXRQbGFjZWhvbGRlcignWVlZWS1NTS1ERCcpXG4gICAgICAgICAgLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmRhaWx5Tm90ZUZvcm1hdClcbiAgICAgICAgICAub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5kYWlseU5vdGVGb3JtYXQgPSB2YWx1ZS50cmltKCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgLnNldE5hbWUoJ0RhaWx5IG5vdGUgZm9sZGVyJylcbiAgICAgIC5zZXREZXNjKFxuICAgICAgICAnRm9sZGVyIHdoZXJlIGRhaWx5IG5vdGVzIGFyZSBzdG9yZWQuIExlYXZlIGVtcHR5IGZvciB0aGUgdmF1bHQgcm9vdC4gU2hvdWxkIG1hdGNoIHlvdXIgRGFpbHkgTm90ZXMgcGx1Z2luIHNldHRpbmcuJ1xuICAgICAgKVxuICAgICAgLmFkZFRleHQoKHRleHQpID0+XG4gICAgICAgIHRleHRcbiAgICAgICAgICAuc2V0UGxhY2Vob2xkZXIoJ0RhaWx5IE5vdGVzJylcbiAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZGFpbHlOb3RlRm9sZGVyKVxuICAgICAgICAgIC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmRhaWx5Tm90ZUZvbGRlciA9IHZhbHVlLnRyaW0oKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgIH0pXG4gICAgICApO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgQXBwLCBOb3RpY2UsIFRleHRGaWxlVmlldywgVEZpbGUsIFdvcmtzcGFjZUxlYWYgfSBmcm9tICdvYnNpZGlhbic7XG5pbXBvcnQgeyBwYXJzZVRhc2tGaWxlLCBzZXJpYWxpemVUYXNrRmlsZSB9IGZyb20gJy4uL3BhcnNlcic7XG5pbXBvcnQgeyBhcHBlbmRUYXNrVG9EYWlseU5vdGUgfSBmcm9tICcuLi9kYWlseS1ub3Rlcyc7XG5pbXBvcnQgeyBUYXNrTGlzdENvbXBvbmVudCB9IGZyb20gJy4vVGFza0xpc3RDb21wb25lbnQnO1xuaW1wb3J0IHsgYnVpbGRGaWxlU3dpdGNoZXJCYXIgfSBmcm9tICcuL0ZpbGVTd2l0Y2hlckJhcic7XG5pbXBvcnQgeyBUYXNrRWRpdG9yTW9kYWwgfSBmcm9tICcuL1Rhc2tFZGl0b3JNb2RhbCc7XG5pbXBvcnQgeyBWSUVXX0lDT04sIFZJRVdfVFlQRSB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBhbGxvd01hcmtkb3duT25jZSB9IGZyb20gJy4uL2ZpbGUtaW50ZXJjZXB0JztcbmltcG9ydCB0eXBlIHsgVGFzayB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB0eXBlIHsgWWFvdHBTZXR0aW5ncyB9IGZyb20gJy4uL3NldHRpbmdzJztcblxuZXhwb3J0IGNsYXNzIFRhc2tGaWxlVmlldyBleHRlbmRzIFRleHRGaWxlVmlldyB7XG4gIHByaXZhdGUgdGFza3M6IFRhc2tbXSA9IFtdO1xuICBwcml2YXRlIGZpbGVIZWFkZXI6IHN0cmluZyA9ICcnO1xuICBwcml2YXRlIHRhc2tMaXN0OiBUYXNrTGlzdENvbXBvbmVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJvb3RFbDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsaXN0RWw6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc2V0dGluZ3M6IFlhb3RwU2V0dGluZ3M7XG4gIHByaXZhdGUgZ2V0VGFza0ZpbGVzOiAoKSA9PiBURmlsZVtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGxlYWY6IFdvcmtzcGFjZUxlYWYsXG4gICAgc2V0dGluZ3M6IFlhb3RwU2V0dGluZ3MsXG4gICAgZ2V0VGFza0ZpbGVzOiAoKSA9PiBURmlsZVtdXG4gICkge1xuICAgIHN1cGVyKGxlYWYpO1xuICAgIHRoaXMuc2V0dGluZ3MgPSBzZXR0aW5ncztcbiAgICB0aGlzLmdldFRhc2tGaWxlcyA9IGdldFRhc2tGaWxlcztcbiAgfVxuXG4gIGdldFZpZXdUeXBlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFZJRVdfVFlQRTtcbiAgfVxuXG4gIGdldERpc3BsYXlUZXh0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZmlsZT8uYmFzZW5hbWUgPz8gJ1Rhc2tzJztcbiAgfVxuXG4gIGdldEljb24oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gVklFV19JQ09OO1xuICB9XG5cbiAgLy8gQ2FsbGVkIGJ5IE9ic2lkaWFuIHdoZW4gdGhlIGZpbGUgY29udGVudCBpcyBsb2FkZWQgb3IgY2hhbmdlcyBleHRlcm5hbGx5LlxuICBzZXRWaWV3RGF0YShkYXRhOiBzdHJpbmcsIF9jbGVhcjogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IHsgaGVhZGVyLCB0YXNrcyB9ID0gcGFyc2VUYXNrRmlsZShkYXRhKTtcbiAgICB0aGlzLmZpbGVIZWFkZXIgPSBoZWFkZXI7XG4gICAgdGhpcy50YXNrcyA9IHRhc2tzO1xuICAgIHRoaXMucmVuZGVyVmlldygpO1xuICB9XG5cbiAgLy8gQ2FsbGVkIGJ5IE9ic2lkaWFuIHdoZW4gaXQgbmVlZHMgdG8gcmVhZCBiYWNrIHRoZSBmaWxlIGNvbnRlbnQuXG4gIGdldFZpZXdEYXRhKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHNlcmlhbGl6ZVRhc2tGaWxlKHsgaGVhZGVyOiB0aGlzLmZpbGVIZWFkZXIsIHRhc2tzOiB0aGlzLnRhc2tzIH0pO1xuICB9XG5cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgdGhpcy5maWxlSGVhZGVyID0gJyc7XG4gICAgdGhpcy50YXNrcyA9IFtdO1xuICAgIHRoaXMucmVuZGVyVmlldygpO1xuICB9XG5cbiAgLy8gT2JzaWRpYW4gY2FsbHMgdGhpcyBhZnRlciB0aGUgdmlldyBpcyBhdHRhY2hlZCB0byB0aGUgRE9NLlxuICBhc3luYyBvbk9wZW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5jb250ZW50RWwuYWRkQ2xhc3MoJ3lhb3RwLXZpZXcnKTtcbiAgICB0aGlzLnJvb3RFbCA9IHRoaXMuY29udGVudEVsO1xuXG4gICAgdGhpcy5hZGRBY3Rpb24oJ3BlbmNpbCcsICdFZGl0IHNvdXJjZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGlmICghdGhpcy5maWxlKSByZXR1cm47XG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHRoaXMuZmlsZS5wYXRoO1xuICAgICAgLy8gRmlyc3QgY2FsbDogYnlwYXNzIHRoZSBpbnRlcmNlcHQgdG8gbGFuZCBpbiBtYXJrZG93biAoT2JzaWRpYW4gbWF5XG4gICAgICAvLyBvcGVuIGluIExpdmUgUHJldmlldyByZWdhcmRsZXNzIG9mIHRoZSBtb2RlIHdlIHBhc3MgaGVyZSkuXG4gICAgICBhbGxvd01hcmtkb3duT25jZSh0aGlzLmxlYWYpO1xuICAgICAgYXdhaXQgdGhpcy5sZWFmLnNldFZpZXdTdGF0ZSh7XG4gICAgICAgIHR5cGU6ICdtYXJrZG93bicsXG4gICAgICAgIHN0YXRlOiB7IGZpbGU6IGZpbGVQYXRoIH0sXG4gICAgICB9KTtcbiAgICAgIC8vIFNlY29uZCBjYWxsOiBub3cgdGhlIGxlYWYgaXMgbWFya2Rvd24gKyBzYW1lIGZpbGUsIHNvIHRoZSBpbnRlcmNlcHRcbiAgICAgIC8vIHRyZWF0cyB0aGlzIGFzIGEgbW9kZSBjaGFuZ2UgYW5kIGxldHMgaXQgdGhyb3VnaC5cbiAgICAgIGF3YWl0IHRoaXMubGVhZi5zZXRWaWV3U3RhdGUoe1xuICAgICAgICB0eXBlOiAnbWFya2Rvd24nLFxuICAgICAgICBzdGF0ZTogeyBmaWxlOiBmaWxlUGF0aCwgbW9kZTogJ3NvdXJjZScgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgb25DbG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnRhc2tMaXN0Py5kZXN0cm95KCk7XG4gICAgdGhpcy50YXNrTGlzdCA9IG51bGw7XG4gIH1cblxuICAvLyBcdTI1MDBcdTI1MDAgUHJpdmF0ZSBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcblxuICBwcml2YXRlIHJlbmRlclZpZXcoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJvb3RFbCkgcmV0dXJuO1xuXG4gICAgdGhpcy5yb290RWwuZW1wdHkoKTtcblxuICAgIC8vIFN3aXRjaGVyIGJhclxuICAgIGlmICh0aGlzLmZpbGUpIHtcbiAgICAgIGNvbnN0IHRhc2tGaWxlcyA9IHRoaXMuZ2V0VGFza0ZpbGVzKCk7XG4gICAgICBjb25zdCBiYXIgPSBidWlsZEZpbGVTd2l0Y2hlckJhcih7XG4gICAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICAgIGN1cnJlbnRGaWxlOiB0aGlzLmZpbGUsXG4gICAgICAgIHRhc2tGaWxlcyxcbiAgICAgICAgaW5ib3hQYXRoOiB0aGlzLnNldHRpbmdzLmluYm94UGF0aCxcbiAgICAgICAgb25Td2l0Y2hGaWxlOiAoZmlsZSkgPT4gdGhpcy5vcGVuRmlsZShmaWxlKSxcbiAgICAgICAgb25DcmVhdGVGaWxlOiAobmFtZSkgPT4gdGhpcy5jcmVhdGVBbmRPcGVuRmlsZShuYW1lKSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5yb290RWwuYXBwZW5kQ2hpbGQoYmFyKTtcbiAgICB9XG5cbiAgICAvLyBBZGQtdGFzayByb3cgXHUyMDE0IG91dHNpZGUgdGhlIHNjcm9sbCBjb250YWluZXIgc28gaXQgc3RheXMgdmlzaWJsZSB3aGVuXG4gICAgLy8gdGhlIEFuZHJvaWQga2V5Ym9hcmQgb3BlbnMgYW5kIHRoZSB2aWV3cG9ydCBzaHJpbmtzLlxuICAgIGNvbnN0IGFkZEl0ZW0gPSB0aGlzLnJvb3RFbC5jcmVhdGVEaXYoeyBjbHM6ICd5YW90cC10YXNrLWl0ZW0geWFvdHAtYWRkLXRhc2staXRlbScgfSk7XG4gICAgY29uc3QgYWRkSGFuZGxlID0gYWRkSXRlbS5jcmVhdGVEaXYoeyBjbHM6ICd5YW90cC1kcmFnLWhhbmRsZSB5YW90cC1kcmFnLWhhbmRsZS1kaXNhYmxlZCcgfSk7XG4gICAgYWRkSGFuZGxlLmlubmVySFRNTCA9ICcmIzg5NDI7JztcbiAgICBhZGRJdGVtLmNyZWF0ZUVsKCdpbnB1dCcsIHtcbiAgICAgIGNsczogJ3lhb3RwLWNoZWNrYm94JyxcbiAgICAgIHR5cGU6ICdjaGVja2JveCcsXG4gICAgICBhdHRyOiB7IGRpc2FibGVkOiB0cnVlLCAnYXJpYS1oaWRkZW4nOiAndHJ1ZScgfSxcbiAgICB9KTtcbiAgICBjb25zdCBhZGRJbnB1dCA9IGFkZEl0ZW0uY3JlYXRlRWwoJ2lucHV0Jywge1xuICAgICAgY2xzOiAneWFvdHAtbmV3LXRhc2staW5wdXQnLFxuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgYXR0cjogeyBwbGFjZWhvbGRlcjogJ0VudGVyIG5ldyB0YXNrLi4uJyB9LFxuICAgIH0pIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgYWRkSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChlKSA9PiB7XG4gICAgICBpZiAoZS5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGFkZElucHV0LnZhbHVlLnRyaW0oKTtcbiAgICAgICAgaWYgKHRleHQpIHRoaXMuYWRkVGFzayh0ZXh0KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFRhc2sgbGlzdCBjb250YWluZXJcbiAgICB0aGlzLmxpc3RFbCA9IHRoaXMucm9vdEVsLmNyZWF0ZURpdih7IGNsczogJ3lhb3RwLWxpc3QtY29udGFpbmVyJyB9KTtcblxuICAgIHRoaXMudGFza0xpc3QgPSBuZXcgVGFza0xpc3RDb21wb25lbnQodGhpcy5saXN0RWwsIHtcbiAgICAgIG9uQ29tcGxldGU6IChpbmRleCkgPT4gdGhpcy5jb21wbGV0ZVRhc2soaW5kZXgpLFxuICAgICAgb25FZGl0OiAoaW5kZXgpID0+IHRoaXMuZWRpdFRhc2soaW5kZXgpLFxuICAgICAgb25SZW9yZGVyOiAob2xkSW5kZXgsIG5ld0luZGV4KSA9PiB0aGlzLnJlb3JkZXJUYXNrKG9sZEluZGV4LCBuZXdJbmRleCksXG4gICAgfSk7XG4gICAgdGhpcy50YXNrTGlzdC5yZW5kZXIodGhpcy50YXNrcyk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBlcnNpc3RUYXNrcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuZmlsZSkgcmV0dXJuO1xuICAgIGF3YWl0IHRoaXMuYXBwLnZhdWx0Lm1vZGlmeShcbiAgICAgIHRoaXMuZmlsZSxcbiAgICAgIHNlcmlhbGl6ZVRhc2tGaWxlKHsgaGVhZGVyOiB0aGlzLmZpbGVIZWFkZXIsIHRhc2tzOiB0aGlzLnRhc2tzIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYWRkVGFzayh0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnRhc2tzLnVuc2hpZnQoeyB0ZXh0LCBub3RlczogW10sIGNvbXBsZXRlZDogZmFsc2UgfSk7XG4gICAgYXdhaXQgdGhpcy5wZXJzaXN0VGFza3MoKTtcbiAgICB0aGlzLnJlbmRlclZpZXcoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY29tcGxldGVUYXNrKGluZGV4OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0YXNrID0gdGhpcy50YXNrc1tpbmRleF07XG4gICAgaWYgKCF0YXNrKSByZXR1cm47XG5cbiAgICAvLyBNYXJrIGNvbXBsZXRlZCBhbmQgcmVtb3ZlIGZyb20gdGhpcyBmaWxlXG4gICAgdGFzay5jb21wbGV0ZWQgPSB0cnVlO1xuICAgIHRoaXMudGFza3Muc3BsaWNlKGluZGV4LCAxKTtcbiAgICBhd2FpdCB0aGlzLnBlcnNpc3RUYXNrcygpO1xuXG4gICAgLy8gQXBwZW5kIHRvIGRhaWx5IG5vdGVcbiAgICBhd2FpdCBhcHBlbmRUYXNrVG9EYWlseU5vdGUodGFzaywgdGhpcy5hcHApO1xuXG4gICAgdGhpcy5yZW5kZXJWaWV3KCk7XG4gIH1cblxuICBwcml2YXRlIGVkaXRUYXNrKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCB0YXNrID0gdGhpcy50YXNrc1tpbmRleF07XG4gICAgaWYgKCF0YXNrIHx8ICF0aGlzLmZpbGUpIHJldHVybjtcblxuICAgIGNvbnN0IHRhc2tGaWxlcyA9IHRoaXMuZ2V0VGFza0ZpbGVzKCk7XG5cbiAgICBjb25zdCBtb2RhbCA9IG5ldyBUYXNrRWRpdG9yTW9kYWwoXG4gICAgICB0aGlzLmFwcCxcbiAgICAgIHRhc2ssXG4gICAgICB0YXNrRmlsZXMsXG4gICAgICB0aGlzLmZpbGUsXG4gICAgICBhc3luYyAocmVzdWx0KSA9PiB7XG4gICAgICAgIHRhc2sudGV4dCA9IHJlc3VsdC50ZXh0O1xuICAgICAgICB0YXNrLm5vdGVzID0gcmVzdWx0Lm5vdGVzO1xuXG4gICAgICAgIGlmIChyZXN1bHQudGFyZ2V0RmlsZSAmJiByZXN1bHQudGFyZ2V0RmlsZS5wYXRoICE9PSB0aGlzLmZpbGU/LnBhdGgpIHtcbiAgICAgICAgICAvLyBNb3ZlIHRhc2sgdG8gYW5vdGhlciBmaWxlXG4gICAgICAgICAgdGhpcy50YXNrcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgIGF3YWl0IHRoaXMucGVyc2lzdFRhc2tzKCk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5hcHBlbmRUYXNrVG9GaWxlKHRhc2ssIHJlc3VsdC50YXJnZXRGaWxlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnBlcnNpc3RUYXNrcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW5kZXJWaWV3KCk7XG4gICAgICB9LFxuICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICB0aGlzLnRhc2tzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgIGF3YWl0IHRoaXMucGVyc2lzdFRhc2tzKCk7XG4gICAgICAgIHRoaXMucmVuZGVyVmlldygpO1xuICAgICAgfVxuICAgICk7XG4gICAgbW9kYWwub3BlbigpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW9yZGVyVGFzayhvbGRJbmRleDogbnVtYmVyLCBuZXdJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgbW92ZWQgPSB0aGlzLnRhc2tzLnNwbGljZShvbGRJbmRleCwgMSlbMF07XG4gICAgdGhpcy50YXNrcy5zcGxpY2UobmV3SW5kZXgsIDAsIG1vdmVkKTtcbiAgICB0aGlzLnBlcnNpc3RUYXNrcygpO1xuICAgIC8vIE5vIG5lZWQgdG8gcmUtcmVuZGVyOyBTb3J0YWJsZUpTIGFscmVhZHkgdXBkYXRlZCB0aGUgRE9NXG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFwcGVuZFRhc2tUb0ZpbGUodGFzazogVGFzaywgZmlsZTogVEZpbGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgdGhpcy5hcHAudmF1bHQucmVhZChmaWxlKTtcbiAgICBjb25zdCBkYXRhID0gcGFyc2VUYXNrRmlsZShjb250ZW50KTtcbiAgICBkYXRhLnRhc2tzLnB1c2godGFzayk7XG4gICAgYXdhaXQgdGhpcy5hcHAudmF1bHQubW9kaWZ5KGZpbGUsIHNlcmlhbGl6ZVRhc2tGaWxlKGRhdGEpKTtcbiAgfVxuXG4gIHByaXZhdGUgb3BlbkZpbGUoZmlsZTogVEZpbGUpOiB2b2lkIHtcbiAgICB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhZihmYWxzZSkub3BlbkZpbGUoZmlsZSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNyZWF0ZUFuZE9wZW5GaWxlKG5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGZvbGRlciA9IHRoaXMuc2V0dGluZ3MudGFza0ZpbGVGb2xkZXI7XG4gICAgY29uc3QgcGF0aCA9IGZvbGRlciA/IGAke2ZvbGRlcn0vJHtuYW1lfS5tZGAgOiBgJHtuYW1lfS5tZGA7XG5cbiAgICBsZXQgZmlsZSA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChwYXRoKSBhcyBURmlsZSB8IG51bGw7XG4gICAgaWYgKCFmaWxlKSB7XG4gICAgICB0cnkge1xuICAgICAgICBmaWxlID0gYXdhaXQgdGhpcy5hcHAudmF1bHQuY3JlYXRlKHBhdGgsICcnKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbmV3IE5vdGljZShgWUFPVFA6IENvdWxkIG5vdCBjcmVhdGUgZmlsZTogJHtwYXRofWApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMub3BlbkZpbGUoZmlsZSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IFRhc2sgfSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgQ0hFQ0tMSVNUX1JFID0gL14tIFxcWyhbIHhYXSlcXF0gKC4qKSQvO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRhc2tGaWxlRGF0YSB7XG4gIC8qKiBSYXcgdGV4dCBiZWZvcmUgdGhlIGZpcnN0IGNoZWNrbGlzdCBpdGVtLCBwcmVzZXJ2ZWQgdmVyYmF0aW0gb24gc2VyaWFsaXplLiAqL1xuICBoZWFkZXI6IHN0cmluZztcbiAgdGFza3M6IFRhc2tbXTtcbn1cblxuLyoqXG4gKiBQYXJzZSBhIHRhc2sgZmlsZSdzIG1hcmtkb3duIGNvbnRlbnQgaW50byBoZWFkZXIgdGV4dCBhbmQgYW4gYXJyYXkgb2YgVGFza3MuXG4gKlxuICogRm9ybWF0IGV4cGVjdGVkOlxuICogICAtIFsgXSBUYXNrIHRpdGxlXG4gKlxuICogICBub3RlcyBsaW5lIDFcbiAqICAgbm90ZXMgbGluZSAyXG4gKlxuICogICAtIFsgXSBOZXh0IHRhc2tcbiAqXG4gKiBBbnkgbm9uLWNoZWNrbGlzdCBsaW5lcyBiZWZvcmUgdGhlIGZpcnN0IHRhc2sgYXJlIGNhcHR1cmVkIGFzIGBoZWFkZXJgIGFuZFxuICogcm91bmQtdHJpcHBlZCB1bmNoYW5nZWQuIE5vdGVzIGFyZSBsaW5lcyBiZXR3ZWVuIHR3byBibGFuay1saW5lIGJvdW5kYXJpZXNcbiAqIGZvbGxvd2luZyBhIGNoZWNrbGlzdCBpdGVtLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUYXNrRmlsZShtYXJrZG93bjogc3RyaW5nKTogVGFza0ZpbGVEYXRhIHtcbiAgY29uc3QgbGluZXMgPSBtYXJrZG93bi5zcGxpdCgnXFxuJyk7XG4gIGNvbnN0IHRhc2tzOiBUYXNrW10gPSBbXTtcbiAgY29uc3QgaGVhZGVyTGluZXM6IHN0cmluZ1tdID0gW107XG4gIGxldCBjdXJyZW50OiBUYXNrIHwgbnVsbCA9IG51bGw7XG4gIC8vIFN0YXRlOiAnaWRsZScgfCAnYWZ0ZXItdGFzaycgfCAnaW4tbm90ZXMnXG4gIC8vIGFmdGVyLXRhc2s6IHNhdyBjaGVja2xpc3QgbGluZSwgd2FpdGluZyBmb3IgYmxhbmsgbGluZSBvciBuZXh0IGNoZWNrbGlzdFxuICAvLyBpbi1ub3RlczogICBzYXcgYmxhbmsgbGluZSBhZnRlciBjaGVja2xpc3QsIGNvbGxlY3Rpbmcgbm90ZSBsaW5lc1xuICBsZXQgc3RhdGU6ICdpZGxlJyB8ICdhZnRlci10YXNrJyB8ICdpbi1ub3RlcycgPSAnaWRsZSc7XG4gIGxldCBub3RlQnVmZmVyOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGNvbnN0IGZsdXNoID0gKCkgPT4ge1xuICAgIGlmIChjdXJyZW50KSB7XG4gICAgICAvLyBUcmltIHRyYWlsaW5nIGJsYW5rIGxpbmVzIGZyb20gbm90ZXNcbiAgICAgIHdoaWxlIChub3RlQnVmZmVyLmxlbmd0aCA+IDAgJiYgbm90ZUJ1ZmZlcltub3RlQnVmZmVyLmxlbmd0aCAtIDFdLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgICAgbm90ZUJ1ZmZlci5wb3AoKTtcbiAgICAgIH1cbiAgICAgIGN1cnJlbnQubm90ZXMgPSBub3RlQnVmZmVyO1xuICAgICAgdGFza3MucHVzaChjdXJyZW50KTtcbiAgICAgIGN1cnJlbnQgPSBudWxsO1xuICAgICAgbm90ZUJ1ZmZlciA9IFtdO1xuICAgIH1cbiAgfTtcblxuICBmb3IgKGNvbnN0IGxpbmUgb2YgbGluZXMpIHtcbiAgICBjb25zdCBtYXRjaCA9IENIRUNLTElTVF9SRS5leGVjKGxpbmUpO1xuXG4gICAgaWYgKG1hdGNoKSB7XG4gICAgICAvLyBTdGFydCBvZiBhIG5ldyB0YXNrIFx1MjAxNCBmbHVzaCB0aGUgcHJldmlvdXMgb25lIGZpcnN0XG4gICAgICBmbHVzaCgpO1xuICAgICAgY3VycmVudCA9IHtcbiAgICAgICAgdGV4dDogbWF0Y2hbMl0sXG4gICAgICAgIG5vdGVzOiBbXSxcbiAgICAgICAgY29tcGxldGVkOiBtYXRjaFsxXS50b0xvd2VyQ2FzZSgpID09PSAneCcsXG4gICAgICB9O1xuICAgICAgc3RhdGUgPSAnYWZ0ZXItdGFzayc7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgLy8gQmVmb3JlIHRoZSBmaXJzdCB0YXNrIFx1MjAxNCBjYXB0dXJlIGFzIGhlYWRlclxuICAgICAgaGVhZGVyTGluZXMucHVzaChsaW5lKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGlzQmxhbmsgPSBsaW5lLnRyaW0oKSA9PT0gJyc7XG5cbiAgICBpZiAoc3RhdGUgPT09ICdhZnRlci10YXNrJykge1xuICAgICAgaWYgKGlzQmxhbmspIHtcbiAgICAgICAgLy8gQmxhbmsgbGluZSBhZnRlciB0YXNrIFx1MjAxNCB0cmFuc2l0aW9uIHRvIG5vdGUtY29sbGVjdGlvbiBtb2RlXG4gICAgICAgIHN0YXRlID0gJ2luLW5vdGVzJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE5vbi1ibGFuaywgbm9uLWNoZWNrbGlzdCBsaW5lIGltbWVkaWF0ZWx5IGFmdGVyIHRhc2sgKG5vIHNlcGFyYXRvciBibGFuaylcbiAgICAgICAgLy8gVHJlYXQgYXMgYSBub3RlIGFueXdheSwgZm9yIHJvYnVzdG5lc3NcbiAgICAgICAgbm90ZUJ1ZmZlci5wdXNoKGxpbmUpO1xuICAgICAgICBzdGF0ZSA9ICdpbi1ub3Rlcyc7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUgPT09ICdpbi1ub3RlcycpIHtcbiAgICAgIG5vdGVCdWZmZXIucHVzaChsaW5lKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgfVxuXG4gIGZsdXNoKCk7XG5cbiAgLy8gVHJpbSB0cmFpbGluZyBibGFuayBsaW5lcyBmcm9tIGhlYWRlclxuICB3aGlsZSAoaGVhZGVyTGluZXMubGVuZ3RoID4gMCAmJiBoZWFkZXJMaW5lc1toZWFkZXJMaW5lcy5sZW5ndGggLSAxXS50cmltKCkgPT09ICcnKSB7XG4gICAgaGVhZGVyTGluZXMucG9wKCk7XG4gIH1cbiAgY29uc3QgaGVhZGVyID0gaGVhZGVyTGluZXMubGVuZ3RoID4gMCA/IGhlYWRlckxpbmVzLmpvaW4oJ1xcbicpICsgJ1xcbicgOiAnJztcblxuICByZXR1cm4geyBoZWFkZXIsIHRhc2tzIH07XG59XG5cbi8qKlxuICogU2VyaWFsaXplIGEgVGFza0ZpbGVEYXRhIGJhY2sgdG8gY2Fub25pY2FsIG1hcmtkb3duLlxuICpcbiAqIFRoZSBoZWFkZXIgKGlmIGFueSkgaXMgd3JpdHRlbiB2ZXJiYXRpbSBmaXJzdCwgc2VwYXJhdGVkIGZyb20gdGFza3MgYnkgYVxuICogYmxhbmsgbGluZS4gVGFzayBmb3JtYXQ6XG4gKlxuICogICAtIFsgXSBUYXNrIHRpdGxlXG4gKlxuICogICBub3RlcyBsaW5lIDFcbiAqICAgbm90ZXMgbGluZSAyXG4gKlxuICogICAtIFsgXSBOZXh0IHRhc2tcbiAqXG4gKiBUYXNrcyB3aXRoIG5vdGVzIGFsd2F5cyBoYXZlIGEgYmxhbmsgbGluZSBiZXR3ZWVuIHRoZSBjaGVja2xpc3QgbGluZSBhbmQgdGhlXG4gKiBmaXJzdCBub3RlIGxpbmUuIENvbXBsZXRlZCBpdGVtcyB1c2UgYC0gW3hdIFx1MjAyNmAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVUYXNrRmlsZShkYXRhOiBUYXNrRmlsZURhdGEpOiBzdHJpbmcge1xuICBjb25zdCB7IGhlYWRlciwgdGFza3MgfSA9IGRhdGE7XG5cbiAgaWYgKHRhc2tzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGhlYWRlciB8fCAnJztcblxuICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcblxuICBmb3IgKGNvbnN0IHRhc2sgb2YgdGFza3MpIHtcbiAgICBjb25zdCBtYXJrZXIgPSB0YXNrLmNvbXBsZXRlZCA/ICd4JyA6ICcgJztcbiAgICBwYXJ0cy5wdXNoKGAtIFske21hcmtlcn1dICR7dGFzay50ZXh0fWApO1xuXG4gICAgaWYgKHRhc2subm90ZXMubGVuZ3RoID4gMCkge1xuICAgICAgcGFydHMucHVzaCgnJyk7XG4gICAgICBmb3IgKGNvbnN0IG5vdGUgb2YgdGFzay5ub3Rlcykge1xuICAgICAgICBwYXJ0cy5wdXNoKG5vdGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHBhcnRzLnB1c2goJycpO1xuICB9XG5cbiAgLy8gSm9pbiBhbmQgZW5zdXJlIHNpbmdsZSB0cmFpbGluZyBuZXdsaW5lXG4gIGNvbnN0IHRhc2tDb250ZW50ID0gcGFydHMuam9pbignXFxuJykucmVwbGFjZSgvXFxuKyQvLCAnJykgKyAnXFxuJztcblxuICAvLyBoZWFkZXIgYWxyZWFkeSBlbmRzIHdpdGggJ1xcbic7IGFkZCBvbmUgbW9yZSBmb3IgdGhlIGJsYW5rIHNlcGFyYXRvciBsaW5lXG4gIHJldHVybiBoZWFkZXIgPyBoZWFkZXIgKyAnXFxuJyArIHRhc2tDb250ZW50IDogdGFza0NvbnRlbnQ7XG59XG4iLCAiaW1wb3J0IHsgQXBwLCBOb3RpY2UsIFRGaWxlIH0gZnJvbSAnb2JzaWRpYW4nO1xuaW1wb3J0IHR5cGUgeyBUYXNrIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBEQUlMWV9OT1RFX1RBU0tTX0hFQURJTkcgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5cbi8vIG9ic2lkaWFuLWRhaWx5LW5vdGVzLWludGVyZmFjZSByZS1leHBvcnRzIG1vbWVudCBmcm9tIE9ic2lkaWFuJ3MgYnVuZGxlLlxuLy8gV2UgaW1wb3J0IGl0IHRoaXMgd2F5IHNvIGVzYnVpbGQgdHJlYXRzIG1vbWVudCBhcyBleHRlcm5hbC5cbmRlY2xhcmUgY29uc3QgbW9tZW50OiAoZGF0ZT86IHVua25vd24pID0+IHtcbiAgZm9ybWF0KGZtdDogc3RyaW5nKTogc3RyaW5nO1xufTtcblxuaW50ZXJmYWNlIERhaWx5Tm90ZXNJbnRlcmZhY2Uge1xuICBhcHBIYXNEYWlseU5vdGVzUGx1Z2luTG9hZGVkKGFwcDogQXBwKTogYm9vbGVhbjtcbiAgZ2V0RGFpbHlOb3RlKFxuICAgIGRhdGU6IFJldHVyblR5cGU8dHlwZW9mIG1vbWVudD4sXG4gICAgbm90ZXM6IFJlY29yZDxzdHJpbmcsIFRGaWxlPlxuICApOiBURmlsZSB8IG51bGw7XG4gIGNyZWF0ZURhaWx5Tm90ZShkYXRlOiBSZXR1cm5UeXBlPHR5cGVvZiBtb21lbnQ+KTogUHJvbWlzZTxURmlsZT47XG4gIGdldEFsbERhaWx5Tm90ZXMoKTogUmVjb3JkPHN0cmluZywgVEZpbGU+O1xufVxuXG5sZXQgZG5pOiBEYWlseU5vdGVzSW50ZXJmYWNlIHwgbnVsbCA9IG51bGw7XG5cbmFzeW5jIGZ1bmN0aW9uIGdldERuaSgpOiBQcm9taXNlPERhaWx5Tm90ZXNJbnRlcmZhY2U+IHtcbiAgaWYgKCFkbmkpIHtcbiAgICBkbmkgPSBhd2FpdCBpbXBvcnQoJ29ic2lkaWFuLWRhaWx5LW5vdGVzLWludGVyZmFjZScpIGFzIHVua25vd24gYXMgRGFpbHlOb3Rlc0ludGVyZmFjZTtcbiAgfVxuICByZXR1cm4gZG5pO1xufVxuXG4vKipcbiAqIEFwcGVuZCBhIGNvbXBsZXRlZCB0YXNrIChhbmQgaXRzIG5vdGVzKSB0byB0aGUgYCMjIyMgVGFza3NgIHNlY3Rpb25cbiAqIG9mIHRvZGF5J3MgZGFpbHkgbm90ZSwgY3JlYXRpbmcgdGhlIHNlY3Rpb24gYW5kL29yIHRoZSBub3RlIGlmIG5lZWRlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFwcGVuZFRhc2tUb0RhaWx5Tm90ZSh0YXNrOiBUYXNrLCBhcHA6IEFwcCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBsaWIgPSBhd2FpdCBnZXREbmkoKTtcblxuICBpZiAoIWxpYi5hcHBIYXNEYWlseU5vdGVzUGx1Z2luTG9hZGVkKGFwcCkpIHtcbiAgICBuZXcgTm90aWNlKFxuICAgICAgJ1lBT1RQOiBEYWlseSBOb3RlcyBwbHVnaW4gaXMgbm90IGVuYWJsZWQuICcgK1xuICAgICAgICAnUGxlYXNlIGVuYWJsZSBpdCBpbiBTZXR0aW5ncyBcdTIxOTIgQ29yZSBwbHVnaW5zLidcbiAgICApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGFsbCA9IGxpYi5nZXRBbGxEYWlseU5vdGVzKCk7XG4gIC8vIG1vbWVudCBpcyBhdmFpbGFibGUgYXMgYSBnbG9iYWwgaW4gT2JzaWRpYW4ncyBydW50aW1lXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIGNvbnN0IHRvZGF5ID0gKHdpbmRvdyBhcyBhbnkpLm1vbWVudCgpO1xuICBsZXQgZmlsZTogVEZpbGUgfCBudWxsID0gbGliLmdldERhaWx5Tm90ZSh0b2RheSwgYWxsKTtcblxuICBpZiAoIWZpbGUpIHtcbiAgICBmaWxlID0gYXdhaXQgbGliLmNyZWF0ZURhaWx5Tm90ZSh0b2RheSk7XG4gIH1cblxuICBjb25zdCBleGlzdGluZyA9IGF3YWl0IGFwcC52YXVsdC5yZWFkKGZpbGUpO1xuICBjb25zdCBhcHBlbmRlZCA9IGJ1aWxkQXBwZW5kZWRDb250ZW50KGV4aXN0aW5nLCB0YXNrKTtcbiAgYXdhaXQgYXBwLnZhdWx0Lm1vZGlmeShmaWxlLCBhcHBlbmRlZCk7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkQXBwZW5kZWRDb250ZW50KGV4aXN0aW5nOiBzdHJpbmcsIHRhc2s6IFRhc2spOiBzdHJpbmcge1xuICBjb25zdCB0YXNrTGluZSA9IGAtIFt4XSAke3Rhc2sudGV4dH1gO1xuICBjb25zdCBub3Rlc0Jsb2NrID1cbiAgICB0YXNrLm5vdGVzLmxlbmd0aCA+IDAgPyAnXFxuXFxuJyArIHRhc2subm90ZXMuam9pbignXFxuJykgOiAnJztcbiAgY29uc3QgZW50cnkgPSB0YXNrTGluZSArIG5vdGVzQmxvY2s7XG5cbiAgY29uc3QgaGVhZGluZ0luZGV4ID0gZXhpc3RpbmcubGFzdEluZGV4T2YoREFJTFlfTk9URV9UQVNLU19IRUFESU5HKTtcblxuICBpZiAoaGVhZGluZ0luZGV4ID09PSAtMSkge1xuICAgIC8vIFNlY3Rpb24gZG9lc24ndCBleGlzdCBcdTIwMTQgYXBwZW5kIGl0IGF0IHRoZSBlbmRcbiAgICBjb25zdCBiYXNlID0gZXhpc3RpbmcudHJpbUVuZCgpO1xuICAgIHJldHVybiBiYXNlICsgKGJhc2UubGVuZ3RoID4gMCA/ICdcXG5cXG4nIDogJycpICsgREFJTFlfTk9URV9UQVNLU19IRUFESU5HICsgJ1xcblxcbicgKyBlbnRyeSArICdcXG4nO1xuICB9XG5cbiAgLy8gU2VjdGlvbiBleGlzdHMgXHUyMDE0IGluc2VydCBhZnRlciBoZWFkaW5nIGFuZCBhbnkgZXhpc3RpbmcgaXRlbXNcbiAgY29uc3QgYWZ0ZXJIZWFkaW5nID0gZXhpc3Rpbmcuc2xpY2UoaGVhZGluZ0luZGV4ICsgREFJTFlfTk9URV9UQVNLU19IRUFESU5HLmxlbmd0aCk7XG4gIC8vIEZpbmQgd2hlcmUgdGhlIG5leHQgc2FtZS1vci1oaWdoZXItbGV2ZWwgaGVhZGluZyBzdGFydHMgKGlmIGFueSlcbiAgY29uc3QgbmV4dEhlYWRpbmdNYXRjaCA9IGFmdGVySGVhZGluZy5tYXRjaCgvXFxuI3sxLDR9IC8pO1xuICBjb25zdCBpbnNlcnRpb25SZWxhdGl2ZSA9IG5leHRIZWFkaW5nTWF0Y2g/LmluZGV4ID8/IGFmdGVySGVhZGluZy5sZW5ndGg7XG5cbiAgY29uc3QgYmVmb3JlID0gZXhpc3Rpbmcuc2xpY2UoMCwgaGVhZGluZ0luZGV4ICsgREFJTFlfTk9URV9UQVNLU19IRUFESU5HLmxlbmd0aCk7XG4gIGNvbnN0IHNlY3Rpb25Db250ZW50ID0gYWZ0ZXJIZWFkaW5nLnNsaWNlKDAsIGluc2VydGlvblJlbGF0aXZlKS50cmltRW5kKCk7XG4gIGNvbnN0IGFmdGVyID0gYWZ0ZXJIZWFkaW5nLnNsaWNlKGluc2VydGlvblJlbGF0aXZlKTtcblxuICByZXR1cm4gYmVmb3JlICsgc2VjdGlvbkNvbnRlbnQgKyAnXFxuXFxuJyArIGVudHJ5ICsgKGFmdGVyLmxlbmd0aCA+IDAgPyAnXFxuJyArIGFmdGVyIDogJ1xcbicpO1xufVxuIiwgIi8qKiFcbiAqIFNvcnRhYmxlIDEuMTUuN1xuICogQGF1dGhvclx0UnViYVhhICAgPHRyYXNoQHJ1YmF4YS5vcmc+XG4gKiBAYXV0aG9yXHRvd2VubSAgICA8b3dlbjIzMzU1QGdtYWlsLmNvbT5cbiAqIEBsaWNlbnNlIE1JVFxuICovXG5mdW5jdGlvbiBfYXJyYXlMaWtlVG9BcnJheShyLCBhKSB7XG4gIChudWxsID09IGEgfHwgYSA+IHIubGVuZ3RoKSAmJiAoYSA9IHIubGVuZ3RoKTtcbiAgZm9yICh2YXIgZSA9IDAsIG4gPSBBcnJheShhKTsgZSA8IGE7IGUrKykgbltlXSA9IHJbZV07XG4gIHJldHVybiBuO1xufVxuZnVuY3Rpb24gX2FycmF5V2l0aG91dEhvbGVzKHIpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkocikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShyKTtcbn1cbmZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0eShlLCByLCB0KSB7XG4gIHJldHVybiAociA9IF90b1Byb3BlcnR5S2V5KHIpKSBpbiBlID8gT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsIHIsIHtcbiAgICB2YWx1ZTogdCxcbiAgICBlbnVtZXJhYmxlOiAhMCxcbiAgICBjb25maWd1cmFibGU6ICEwLFxuICAgIHdyaXRhYmxlOiAhMFxuICB9KSA6IGVbcl0gPSB0LCBlO1xufVxuZnVuY3Rpb24gX2V4dGVuZHMoKSB7XG4gIHJldHVybiBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gPyBPYmplY3QuYXNzaWduLmJpbmQoKSA6IGZ1bmN0aW9uIChuKSB7XG4gICAgZm9yICh2YXIgZSA9IDE7IGUgPCBhcmd1bWVudHMubGVuZ3RoOyBlKyspIHtcbiAgICAgIHZhciB0ID0gYXJndW1lbnRzW2VdO1xuICAgICAgZm9yICh2YXIgciBpbiB0KSAoe30pLmhhc093blByb3BlcnR5LmNhbGwodCwgcikgJiYgKG5bcl0gPSB0W3JdKTtcbiAgICB9XG4gICAgcmV0dXJuIG47XG4gIH0sIF9leHRlbmRzLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG59XG5mdW5jdGlvbiBfaXRlcmFibGVUb0FycmF5KHIpIHtcbiAgaWYgKFwidW5kZWZpbmVkXCIgIT0gdHlwZW9mIFN5bWJvbCAmJiBudWxsICE9IHJbU3ltYm9sLml0ZXJhdG9yXSB8fCBudWxsICE9IHJbXCJAQGl0ZXJhdG9yXCJdKSByZXR1cm4gQXJyYXkuZnJvbShyKTtcbn1cbmZ1bmN0aW9uIF9ub25JdGVyYWJsZVNwcmVhZCgpIHtcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBzcHJlYWQgbm9uLWl0ZXJhYmxlIGluc3RhbmNlLlxcbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC5cIik7XG59XG5mdW5jdGlvbiBvd25LZXlzKGUsIHIpIHtcbiAgdmFyIHQgPSBPYmplY3Qua2V5cyhlKTtcbiAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcbiAgICB2YXIgbyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZSk7XG4gICAgciAmJiAobyA9IG8uZmlsdGVyKGZ1bmN0aW9uIChyKSB7XG4gICAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlLCByKS5lbnVtZXJhYmxlO1xuICAgIH0pKSwgdC5wdXNoLmFwcGx5KHQsIG8pO1xuICB9XG4gIHJldHVybiB0O1xufVxuZnVuY3Rpb24gX29iamVjdFNwcmVhZDIoZSkge1xuICBmb3IgKHZhciByID0gMTsgciA8IGFyZ3VtZW50cy5sZW5ndGg7IHIrKykge1xuICAgIHZhciB0ID0gbnVsbCAhPSBhcmd1bWVudHNbcl0gPyBhcmd1bWVudHNbcl0gOiB7fTtcbiAgICByICUgMiA/IG93bktleXMoT2JqZWN0KHQpLCAhMCkuZm9yRWFjaChmdW5jdGlvbiAocikge1xuICAgICAgX2RlZmluZVByb3BlcnR5KGUsIHIsIHRbcl0pO1xuICAgIH0pIDogT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhlLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyh0KSkgOiBvd25LZXlzKE9iamVjdCh0KSkuZm9yRWFjaChmdW5jdGlvbiAocikge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsIHIsIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodCwgcikpO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBlO1xufVxuZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKGUsIHQpIHtcbiAgaWYgKG51bGwgPT0gZSkgcmV0dXJuIHt9O1xuICB2YXIgbyxcbiAgICByLFxuICAgIGkgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXNMb29zZShlLCB0KTtcbiAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcbiAgICB2YXIgbiA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZSk7XG4gICAgZm9yIChyID0gMDsgciA8IG4ubGVuZ3RoOyByKyspIG8gPSBuW3JdLCAtMSA9PT0gdC5pbmRleE9mKG8pICYmIHt9LnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoZSwgbykgJiYgKGlbb10gPSBlW29dKTtcbiAgfVxuICByZXR1cm4gaTtcbn1cbmZ1bmN0aW9uIF9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlKHIsIGUpIHtcbiAgaWYgKG51bGwgPT0gcikgcmV0dXJuIHt9O1xuICB2YXIgdCA9IHt9O1xuICBmb3IgKHZhciBuIGluIHIpIGlmICh7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHIsIG4pKSB7XG4gICAgaWYgKC0xICE9PSBlLmluZGV4T2YobikpIGNvbnRpbnVlO1xuICAgIHRbbl0gPSByW25dO1xuICB9XG4gIHJldHVybiB0O1xufVxuZnVuY3Rpb24gX3RvQ29uc3VtYWJsZUFycmF5KHIpIHtcbiAgcmV0dXJuIF9hcnJheVdpdGhvdXRIb2xlcyhyKSB8fCBfaXRlcmFibGVUb0FycmF5KHIpIHx8IF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShyKSB8fCBfbm9uSXRlcmFibGVTcHJlYWQoKTtcbn1cbmZ1bmN0aW9uIF90b1ByaW1pdGl2ZSh0LCByKSB7XG4gIGlmIChcIm9iamVjdFwiICE9IHR5cGVvZiB0IHx8ICF0KSByZXR1cm4gdDtcbiAgdmFyIGUgPSB0W1N5bWJvbC50b1ByaW1pdGl2ZV07XG4gIGlmICh2b2lkIDAgIT09IGUpIHtcbiAgICB2YXIgaSA9IGUuY2FsbCh0LCByIHx8IFwiZGVmYXVsdFwiKTtcbiAgICBpZiAoXCJvYmplY3RcIiAhPSB0eXBlb2YgaSkgcmV0dXJuIGk7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkBAdG9QcmltaXRpdmUgbXVzdCByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUuXCIpO1xuICB9XG4gIHJldHVybiAoXCJzdHJpbmdcIiA9PT0gciA/IFN0cmluZyA6IE51bWJlcikodCk7XG59XG5mdW5jdGlvbiBfdG9Qcm9wZXJ0eUtleSh0KSB7XG4gIHZhciBpID0gX3RvUHJpbWl0aXZlKHQsIFwic3RyaW5nXCIpO1xuICByZXR1cm4gXCJzeW1ib2xcIiA9PSB0eXBlb2YgaSA/IGkgOiBpICsgXCJcIjtcbn1cbmZ1bmN0aW9uIF90eXBlb2Yobykge1xuICBcIkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mXCI7XG5cbiAgcmV0dXJuIF90eXBlb2YgPSBcImZ1bmN0aW9uXCIgPT0gdHlwZW9mIFN5bWJvbCAmJiBcInN5bWJvbFwiID09IHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPyBmdW5jdGlvbiAobykge1xuICAgIHJldHVybiB0eXBlb2YgbztcbiAgfSA6IGZ1bmN0aW9uIChvKSB7XG4gICAgcmV0dXJuIG8gJiYgXCJmdW5jdGlvblwiID09IHR5cGVvZiBTeW1ib2wgJiYgby5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG8gIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG87XG4gIH0sIF90eXBlb2Yobyk7XG59XG5mdW5jdGlvbiBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkociwgYSkge1xuICBpZiAocikge1xuICAgIGlmIChcInN0cmluZ1wiID09IHR5cGVvZiByKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkociwgYSk7XG4gICAgdmFyIHQgPSB7fS50b1N0cmluZy5jYWxsKHIpLnNsaWNlKDgsIC0xKTtcbiAgICByZXR1cm4gXCJPYmplY3RcIiA9PT0gdCAmJiByLmNvbnN0cnVjdG9yICYmICh0ID0gci5jb25zdHJ1Y3Rvci5uYW1lKSwgXCJNYXBcIiA9PT0gdCB8fCBcIlNldFwiID09PSB0ID8gQXJyYXkuZnJvbShyKSA6IFwiQXJndW1lbnRzXCIgPT09IHQgfHwgL14oPzpVaXxJKW50KD86OHwxNnwzMikoPzpDbGFtcGVkKT9BcnJheSQvLnRlc3QodCkgPyBfYXJyYXlMaWtlVG9BcnJheShyLCBhKSA6IHZvaWQgMDtcbiAgfVxufVxuXG52YXIgdmVyc2lvbiA9IFwiMS4xNS43XCI7XG5cbmZ1bmN0aW9uIHVzZXJBZ2VudChwYXR0ZXJuKSB7XG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cubmF2aWdhdG9yKSB7XG4gICAgcmV0dXJuICEhIC8qQF9fUFVSRV9fKi9uYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKHBhdHRlcm4pO1xuICB9XG59XG52YXIgSUUxMU9yTGVzcyA9IHVzZXJBZ2VudCgvKD86VHJpZGVudC4qcnZbIDpdPzExXFwufG1zaWV8aWVtb2JpbGV8V2luZG93cyBQaG9uZSkvaSk7XG52YXIgRWRnZSA9IHVzZXJBZ2VudCgvRWRnZS9pKTtcbnZhciBGaXJlRm94ID0gdXNlckFnZW50KC9maXJlZm94L2kpO1xudmFyIFNhZmFyaSA9IHVzZXJBZ2VudCgvc2FmYXJpL2kpICYmICF1c2VyQWdlbnQoL2Nocm9tZS9pKSAmJiAhdXNlckFnZW50KC9hbmRyb2lkL2kpO1xudmFyIElPUyA9IHVzZXJBZ2VudCgvaVAoYWR8b2R8aG9uZSkvaSk7XG52YXIgQ2hyb21lRm9yQW5kcm9pZCA9IHVzZXJBZ2VudCgvY2hyb21lL2kpICYmIHVzZXJBZ2VudCgvYW5kcm9pZC9pKTtcblxudmFyIGNhcHR1cmVNb2RlID0ge1xuICBjYXB0dXJlOiBmYWxzZSxcbiAgcGFzc2l2ZTogZmFsc2Vcbn07XG5mdW5jdGlvbiBvbihlbCwgZXZlbnQsIGZuKSB7XG4gIGVsLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGZuLCAhSUUxMU9yTGVzcyAmJiBjYXB0dXJlTW9kZSk7XG59XG5mdW5jdGlvbiBvZmYoZWwsIGV2ZW50LCBmbikge1xuICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBmbiwgIUlFMTFPckxlc3MgJiYgY2FwdHVyZU1vZGUpO1xufVxuZnVuY3Rpb24gbWF0Y2hlcyggLyoqSFRNTEVsZW1lbnQqL2VsLCAvKipTdHJpbmcqL3NlbGVjdG9yKSB7XG4gIGlmICghc2VsZWN0b3IpIHJldHVybjtcbiAgc2VsZWN0b3JbMF0gPT09ICc+JyAmJiAoc2VsZWN0b3IgPSBzZWxlY3Rvci5zdWJzdHJpbmcoMSkpO1xuICBpZiAoZWwpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKGVsLm1hdGNoZXMpIHtcbiAgICAgICAgcmV0dXJuIGVsLm1hdGNoZXMoc2VsZWN0b3IpO1xuICAgICAgfSBlbHNlIGlmIChlbC5tc01hdGNoZXNTZWxlY3Rvcikge1xuICAgICAgICByZXR1cm4gZWwubXNNYXRjaGVzU2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgICAgfSBlbHNlIGlmIChlbC53ZWJraXRNYXRjaGVzU2VsZWN0b3IpIHtcbiAgICAgICAgcmV0dXJuIGVsLndlYmtpdE1hdGNoZXNTZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoXykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBnZXRQYXJlbnRPckhvc3QoZWwpIHtcbiAgcmV0dXJuIGVsLmhvc3QgJiYgZWwgIT09IGRvY3VtZW50ICYmIGVsLmhvc3Qubm9kZVR5cGUgJiYgZWwuaG9zdCAhPT0gZWwgPyBlbC5ob3N0IDogZWwucGFyZW50Tm9kZTtcbn1cbmZ1bmN0aW9uIGNsb3Nlc3QoIC8qKkhUTUxFbGVtZW50Ki9lbCwgLyoqU3RyaW5nKi9zZWxlY3RvciwgLyoqSFRNTEVsZW1lbnQqL2N0eCwgaW5jbHVkZUNUWCkge1xuICBpZiAoZWwpIHtcbiAgICBjdHggPSBjdHggfHwgZG9jdW1lbnQ7XG4gICAgZG8ge1xuICAgICAgaWYgKHNlbGVjdG9yICE9IG51bGwgJiYgKHNlbGVjdG9yWzBdID09PSAnPicgPyBlbC5wYXJlbnROb2RlID09PSBjdHggJiYgbWF0Y2hlcyhlbCwgc2VsZWN0b3IpIDogbWF0Y2hlcyhlbCwgc2VsZWN0b3IpKSB8fCBpbmNsdWRlQ1RYICYmIGVsID09PSBjdHgpIHtcbiAgICAgICAgcmV0dXJuIGVsO1xuICAgICAgfVxuICAgICAgaWYgKGVsID09PSBjdHgpIGJyZWFrO1xuICAgICAgLyoganNoaW50IGJvc3M6dHJ1ZSAqL1xuICAgIH0gd2hpbGUgKGVsID0gZ2V0UGFyZW50T3JIb3N0KGVsKSk7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG52YXIgUl9TUEFDRSA9IC9cXHMrL2c7XG5mdW5jdGlvbiB0b2dnbGVDbGFzcyhlbCwgbmFtZSwgc3RhdGUpIHtcbiAgaWYgKGVsICYmIG5hbWUpIHtcbiAgICBpZiAoZWwuY2xhc3NMaXN0KSB7XG4gICAgICBlbC5jbGFzc0xpc3Rbc3RhdGUgPyAnYWRkJyA6ICdyZW1vdmUnXShuYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGNsYXNzTmFtZSA9ICgnICcgKyBlbC5jbGFzc05hbWUgKyAnICcpLnJlcGxhY2UoUl9TUEFDRSwgJyAnKS5yZXBsYWNlKCcgJyArIG5hbWUgKyAnICcsICcgJyk7XG4gICAgICBlbC5jbGFzc05hbWUgPSAoY2xhc3NOYW1lICsgKHN0YXRlID8gJyAnICsgbmFtZSA6ICcnKSkucmVwbGFjZShSX1NQQUNFLCAnICcpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gY3NzKGVsLCBwcm9wLCB2YWwpIHtcbiAgdmFyIHN0eWxlID0gZWwgJiYgZWwuc3R5bGU7XG4gIGlmIChzdHlsZSkge1xuICAgIGlmICh2YWwgPT09IHZvaWQgMCkge1xuICAgICAgaWYgKGRvY3VtZW50LmRlZmF1bHRWaWV3ICYmIGRvY3VtZW50LmRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGUpIHtcbiAgICAgICAgdmFsID0gZG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShlbCwgJycpO1xuICAgICAgfSBlbHNlIGlmIChlbC5jdXJyZW50U3R5bGUpIHtcbiAgICAgICAgdmFsID0gZWwuY3VycmVudFN0eWxlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHByb3AgPT09IHZvaWQgMCA/IHZhbCA6IHZhbFtwcm9wXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCEocHJvcCBpbiBzdHlsZSkgJiYgcHJvcC5pbmRleE9mKCd3ZWJraXQnKSA9PT0gLTEpIHtcbiAgICAgICAgcHJvcCA9ICctd2Via2l0LScgKyBwcm9wO1xuICAgICAgfVxuICAgICAgc3R5bGVbcHJvcF0gPSB2YWwgKyAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgPyAnJyA6ICdweCcpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWF0cml4KGVsLCBzZWxmT25seSkge1xuICB2YXIgYXBwbGllZFRyYW5zZm9ybXMgPSAnJztcbiAgaWYgKHR5cGVvZiBlbCA9PT0gJ3N0cmluZycpIHtcbiAgICBhcHBsaWVkVHJhbnNmb3JtcyA9IGVsO1xuICB9IGVsc2Uge1xuICAgIGRvIHtcbiAgICAgIHZhciB0cmFuc2Zvcm0gPSBjc3MoZWwsICd0cmFuc2Zvcm0nKTtcbiAgICAgIGlmICh0cmFuc2Zvcm0gJiYgdHJhbnNmb3JtICE9PSAnbm9uZScpIHtcbiAgICAgICAgYXBwbGllZFRyYW5zZm9ybXMgPSB0cmFuc2Zvcm0gKyAnICcgKyBhcHBsaWVkVHJhbnNmb3JtcztcbiAgICAgIH1cbiAgICAgIC8qIGpzaGludCBib3NzOnRydWUgKi9cbiAgICB9IHdoaWxlICghc2VsZk9ubHkgJiYgKGVsID0gZWwucGFyZW50Tm9kZSkpO1xuICB9XG4gIHZhciBtYXRyaXhGbiA9IHdpbmRvdy5ET01NYXRyaXggfHwgd2luZG93LldlYktpdENTU01hdHJpeCB8fCB3aW5kb3cuQ1NTTWF0cml4IHx8IHdpbmRvdy5NU0NTU01hdHJpeDtcbiAgLypqc2hpbnQgLVcwNTYgKi9cbiAgcmV0dXJuIG1hdHJpeEZuICYmIG5ldyBtYXRyaXhGbihhcHBsaWVkVHJhbnNmb3Jtcyk7XG59XG5mdW5jdGlvbiBmaW5kKGN0eCwgdGFnTmFtZSwgaXRlcmF0b3IpIHtcbiAgaWYgKGN0eCkge1xuICAgIHZhciBsaXN0ID0gY3R4LmdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZ05hbWUpLFxuICAgICAgaSA9IDAsXG4gICAgICBuID0gbGlzdC5sZW5ndGg7XG4gICAgaWYgKGl0ZXJhdG9yKSB7XG4gICAgICBmb3IgKDsgaSA8IG47IGkrKykge1xuICAgICAgICBpdGVyYXRvcihsaXN0W2ldLCBpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxpc3Q7XG4gIH1cbiAgcmV0dXJuIFtdO1xufVxuZnVuY3Rpb24gZ2V0V2luZG93U2Nyb2xsaW5nRWxlbWVudCgpIHtcbiAgdmFyIHNjcm9sbGluZ0VsZW1lbnQgPSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50O1xuICBpZiAoc2Nyb2xsaW5nRWxlbWVudCkge1xuICAgIHJldHVybiBzY3JvbGxpbmdFbGVtZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gIH1cbn1cblxuLyoqXHJcbiAqIFJldHVybnMgdGhlIFwiYm91bmRpbmcgY2xpZW50IHJlY3RcIiBvZiBnaXZlbiBlbGVtZW50XHJcbiAqIEBwYXJhbSAge0hUTUxFbGVtZW50fSBlbCAgICAgICAgICAgICAgICAgICAgICAgVGhlIGVsZW1lbnQgd2hvc2UgYm91bmRpbmdDbGllbnRSZWN0IGlzIHdhbnRlZFxyXG4gKiBAcGFyYW0gIHtbQm9vbGVhbl19IHJlbGF0aXZlVG9Db250YWluaW5nQmxvY2sgIFdoZXRoZXIgdGhlIHJlY3Qgc2hvdWxkIGJlIHJlbGF0aXZlIHRvIHRoZSBjb250YWluaW5nIGJsb2NrIG9mIChpbmNsdWRpbmcpIHRoZSBjb250YWluZXJcclxuICogQHBhcmFtICB7W0Jvb2xlYW5dfSByZWxhdGl2ZVRvTm9uU3RhdGljUGFyZW50ICBXaGV0aGVyIHRoZSByZWN0IHNob3VsZCBiZSByZWxhdGl2ZSB0byB0aGUgcmVsYXRpdmUgcGFyZW50IG9mIChpbmNsdWRpbmcpIHRoZSBjb250YWllbnJcclxuICogQHBhcmFtICB7W0Jvb2xlYW5dfSB1bmRvU2NhbGUgICAgICAgICAgICAgICAgICBXaGV0aGVyIHRoZSBjb250YWluZXIncyBzY2FsZSgpIHNob3VsZCBiZSB1bmRvbmVcclxuICogQHBhcmFtICB7W0hUTUxFbGVtZW50XX0gY29udGFpbmVyICAgICAgICAgICAgICBUaGUgcGFyZW50IHRoZSBlbGVtZW50IHdpbGwgYmUgcGxhY2VkIGluXHJcbiAqIEByZXR1cm4ge09iamVjdH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhlIGJvdW5kaW5nQ2xpZW50UmVjdCBvZiBlbCwgd2l0aCBzcGVjaWZpZWQgYWRqdXN0bWVudHNcclxuICovXG5mdW5jdGlvbiBnZXRSZWN0KGVsLCByZWxhdGl2ZVRvQ29udGFpbmluZ0Jsb2NrLCByZWxhdGl2ZVRvTm9uU3RhdGljUGFyZW50LCB1bmRvU2NhbGUsIGNvbnRhaW5lcikge1xuICBpZiAoIWVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCAmJiBlbCAhPT0gd2luZG93KSByZXR1cm47XG4gIHZhciBlbFJlY3QsIHRvcCwgbGVmdCwgYm90dG9tLCByaWdodCwgaGVpZ2h0LCB3aWR0aDtcbiAgaWYgKGVsICE9PSB3aW5kb3cgJiYgZWwucGFyZW50Tm9kZSAmJiBlbCAhPT0gZ2V0V2luZG93U2Nyb2xsaW5nRWxlbWVudCgpKSB7XG4gICAgZWxSZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgdG9wID0gZWxSZWN0LnRvcDtcbiAgICBsZWZ0ID0gZWxSZWN0LmxlZnQ7XG4gICAgYm90dG9tID0gZWxSZWN0LmJvdHRvbTtcbiAgICByaWdodCA9IGVsUmVjdC5yaWdodDtcbiAgICBoZWlnaHQgPSBlbFJlY3QuaGVpZ2h0O1xuICAgIHdpZHRoID0gZWxSZWN0LndpZHRoO1xuICB9IGVsc2Uge1xuICAgIHRvcCA9IDA7XG4gICAgbGVmdCA9IDA7XG4gICAgYm90dG9tID0gd2luZG93LmlubmVySGVpZ2h0O1xuICAgIHJpZ2h0ID0gd2luZG93LmlubmVyV2lkdGg7XG4gICAgaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuICAgIHdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XG4gIH1cbiAgaWYgKChyZWxhdGl2ZVRvQ29udGFpbmluZ0Jsb2NrIHx8IHJlbGF0aXZlVG9Ob25TdGF0aWNQYXJlbnQpICYmIGVsICE9PSB3aW5kb3cpIHtcbiAgICAvLyBBZGp1c3QgZm9yIHRyYW5zbGF0ZSgpXG4gICAgY29udGFpbmVyID0gY29udGFpbmVyIHx8IGVsLnBhcmVudE5vZGU7XG5cbiAgICAvLyBzb2x2ZXMgIzExMjMgKHNlZTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM3OTUzODA2LzYwODgzMTIpXG4gICAgLy8gTm90IG5lZWRlZCBvbiA8PSBJRTExXG4gICAgaWYgKCFJRTExT3JMZXNzKSB7XG4gICAgICBkbyB7XG4gICAgICAgIGlmIChjb250YWluZXIgJiYgY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCAmJiAoY3NzKGNvbnRhaW5lciwgJ3RyYW5zZm9ybScpICE9PSAnbm9uZScgfHwgcmVsYXRpdmVUb05vblN0YXRpY1BhcmVudCAmJiBjc3MoY29udGFpbmVyLCAncG9zaXRpb24nKSAhPT0gJ3N0YXRpYycpKSB7XG4gICAgICAgICAgdmFyIGNvbnRhaW5lclJlY3QgPSBjb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgICAgICAvLyBTZXQgcmVsYXRpdmUgdG8gZWRnZXMgb2YgcGFkZGluZyBib3ggb2YgY29udGFpbmVyXG4gICAgICAgICAgdG9wIC09IGNvbnRhaW5lclJlY3QudG9wICsgcGFyc2VJbnQoY3NzKGNvbnRhaW5lciwgJ2JvcmRlci10b3Atd2lkdGgnKSk7XG4gICAgICAgICAgbGVmdCAtPSBjb250YWluZXJSZWN0LmxlZnQgKyBwYXJzZUludChjc3MoY29udGFpbmVyLCAnYm9yZGVyLWxlZnQtd2lkdGgnKSk7XG4gICAgICAgICAgYm90dG9tID0gdG9wICsgZWxSZWN0LmhlaWdodDtcbiAgICAgICAgICByaWdodCA9IGxlZnQgKyBlbFJlY3Qud2lkdGg7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgLyoganNoaW50IGJvc3M6dHJ1ZSAqL1xuICAgICAgfSB3aGlsZSAoY29udGFpbmVyID0gY29udGFpbmVyLnBhcmVudE5vZGUpO1xuICAgIH1cbiAgfVxuICBpZiAodW5kb1NjYWxlICYmIGVsICE9PSB3aW5kb3cpIHtcbiAgICAvLyBBZGp1c3QgZm9yIHNjYWxlKClcbiAgICB2YXIgZWxNYXRyaXggPSBtYXRyaXgoY29udGFpbmVyIHx8IGVsKSxcbiAgICAgIHNjYWxlWCA9IGVsTWF0cml4ICYmIGVsTWF0cml4LmEsXG4gICAgICBzY2FsZVkgPSBlbE1hdHJpeCAmJiBlbE1hdHJpeC5kO1xuICAgIGlmIChlbE1hdHJpeCkge1xuICAgICAgdG9wIC89IHNjYWxlWTtcbiAgICAgIGxlZnQgLz0gc2NhbGVYO1xuICAgICAgd2lkdGggLz0gc2NhbGVYO1xuICAgICAgaGVpZ2h0IC89IHNjYWxlWTtcbiAgICAgIGJvdHRvbSA9IHRvcCArIGhlaWdodDtcbiAgICAgIHJpZ2h0ID0gbGVmdCArIHdpZHRoO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIHRvcDogdG9wLFxuICAgIGxlZnQ6IGxlZnQsXG4gICAgYm90dG9tOiBib3R0b20sXG4gICAgcmlnaHQ6IHJpZ2h0LFxuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodFxuICB9O1xufVxuXG4vKipcclxuICogQ2hlY2tzIGlmIGEgc2lkZSBvZiBhbiBlbGVtZW50IGlzIHNjcm9sbGVkIHBhc3QgYSBzaWRlIG9mIGl0cyBwYXJlbnRzXHJcbiAqIEBwYXJhbSAge0hUTUxFbGVtZW50fSAgZWwgICAgICAgICAgIFRoZSBlbGVtZW50IHdobydzIHNpZGUgYmVpbmcgc2Nyb2xsZWQgb3V0IG9mIHZpZXcgaXMgaW4gcXVlc3Rpb25cclxuICogQHBhcmFtICB7U3RyaW5nfSAgICAgICBlbFNpZGUgICAgICAgU2lkZSBvZiB0aGUgZWxlbWVudCBpbiBxdWVzdGlvbiAoJ3RvcCcsICdsZWZ0JywgJ3JpZ2h0JywgJ2JvdHRvbScpXHJcbiAqIEBwYXJhbSAge1N0cmluZ30gICAgICAgcGFyZW50U2lkZSAgIFNpZGUgb2YgdGhlIHBhcmVudCBpbiBxdWVzdGlvbiAoJ3RvcCcsICdsZWZ0JywgJ3JpZ2h0JywgJ2JvdHRvbScpXHJcbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fSAgICAgICAgICAgICAgIFRoZSBwYXJlbnQgc2Nyb2xsIGVsZW1lbnQgdGhhdCB0aGUgZWwncyBzaWRlIGlzIHNjcm9sbGVkIHBhc3QsIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8gc3VjaCBlbGVtZW50XHJcbiAqL1xuZnVuY3Rpb24gaXNTY3JvbGxlZFBhc3QoZWwsIGVsU2lkZSwgcGFyZW50U2lkZSkge1xuICB2YXIgcGFyZW50ID0gZ2V0UGFyZW50QXV0b1Njcm9sbEVsZW1lbnQoZWwsIHRydWUpLFxuICAgIGVsU2lkZVZhbCA9IGdldFJlY3QoZWwpW2VsU2lkZV07XG5cbiAgLyoganNoaW50IGJvc3M6dHJ1ZSAqL1xuICB3aGlsZSAocGFyZW50KSB7XG4gICAgdmFyIHBhcmVudFNpZGVWYWwgPSBnZXRSZWN0KHBhcmVudClbcGFyZW50U2lkZV0sXG4gICAgICB2aXNpYmxlID0gdm9pZCAwO1xuICAgIGlmIChwYXJlbnRTaWRlID09PSAndG9wJyB8fCBwYXJlbnRTaWRlID09PSAnbGVmdCcpIHtcbiAgICAgIHZpc2libGUgPSBlbFNpZGVWYWwgPj0gcGFyZW50U2lkZVZhbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmlzaWJsZSA9IGVsU2lkZVZhbCA8PSBwYXJlbnRTaWRlVmFsO1xuICAgIH1cbiAgICBpZiAoIXZpc2libGUpIHJldHVybiBwYXJlbnQ7XG4gICAgaWYgKHBhcmVudCA9PT0gZ2V0V2luZG93U2Nyb2xsaW5nRWxlbWVudCgpKSBicmVhaztcbiAgICBwYXJlbnQgPSBnZXRQYXJlbnRBdXRvU2Nyb2xsRWxlbWVudChwYXJlbnQsIGZhbHNlKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxyXG4gKiBHZXRzIG50aCBjaGlsZCBvZiBlbCwgaWdub3JpbmcgaGlkZGVuIGNoaWxkcmVuLCBzb3J0YWJsZSdzIGVsZW1lbnRzIChkb2VzIG5vdCBpZ25vcmUgY2xvbmUgaWYgaXQncyB2aXNpYmxlKVxyXG4gKiBhbmQgbm9uLWRyYWdnYWJsZSBlbGVtZW50c1xyXG4gKiBAcGFyYW0gIHtIVE1MRWxlbWVudH0gZWwgICAgICAgVGhlIHBhcmVudCBlbGVtZW50XHJcbiAqIEBwYXJhbSAge051bWJlcn0gY2hpbGROdW0gICAgICBUaGUgaW5kZXggb2YgdGhlIGNoaWxkXHJcbiAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9ucyAgICAgICBQYXJlbnQgU29ydGFibGUncyBvcHRpb25zXHJcbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fSAgICAgICAgICBUaGUgY2hpbGQgYXQgaW5kZXggY2hpbGROdW0sIG9yIG51bGwgaWYgbm90IGZvdW5kXHJcbiAqL1xuZnVuY3Rpb24gZ2V0Q2hpbGQoZWwsIGNoaWxkTnVtLCBvcHRpb25zLCBpbmNsdWRlRHJhZ0VsKSB7XG4gIHZhciBjdXJyZW50Q2hpbGQgPSAwLFxuICAgIGkgPSAwLFxuICAgIGNoaWxkcmVuID0gZWwuY2hpbGRyZW47XG4gIHdoaWxlIChpIDwgY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgaWYgKGNoaWxkcmVuW2ldLnN0eWxlLmRpc3BsYXkgIT09ICdub25lJyAmJiBjaGlsZHJlbltpXSAhPT0gU29ydGFibGUuZ2hvc3QgJiYgKGluY2x1ZGVEcmFnRWwgfHwgY2hpbGRyZW5baV0gIT09IFNvcnRhYmxlLmRyYWdnZWQpICYmIGNsb3Nlc3QoY2hpbGRyZW5baV0sIG9wdGlvbnMuZHJhZ2dhYmxlLCBlbCwgZmFsc2UpKSB7XG4gICAgICBpZiAoY3VycmVudENoaWxkID09PSBjaGlsZE51bSkge1xuICAgICAgICByZXR1cm4gY2hpbGRyZW5baV07XG4gICAgICB9XG4gICAgICBjdXJyZW50Q2hpbGQrKztcbiAgICB9XG4gICAgaSsrO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcclxuICogR2V0cyB0aGUgbGFzdCBjaGlsZCBpbiB0aGUgZWwsIGlnbm9yaW5nIGdob3N0RWwgb3IgaW52aXNpYmxlIGVsZW1lbnRzIChjbG9uZXMpXHJcbiAqIEBwYXJhbSAge0hUTUxFbGVtZW50fSBlbCAgICAgICBQYXJlbnQgZWxlbWVudFxyXG4gKiBAcGFyYW0gIHtzZWxlY3Rvcn0gc2VsZWN0b3IgICAgQW55IG90aGVyIGVsZW1lbnRzIHRoYXQgc2hvdWxkIGJlIGlnbm9yZWRcclxuICogQHJldHVybiB7SFRNTEVsZW1lbnR9ICAgICAgICAgIFRoZSBsYXN0IGNoaWxkLCBpZ25vcmluZyBnaG9zdEVsXHJcbiAqL1xuZnVuY3Rpb24gbGFzdENoaWxkKGVsLCBzZWxlY3Rvcikge1xuICB2YXIgbGFzdCA9IGVsLmxhc3RFbGVtZW50Q2hpbGQ7XG4gIHdoaWxlIChsYXN0ICYmIChsYXN0ID09PSBTb3J0YWJsZS5naG9zdCB8fCBjc3MobGFzdCwgJ2Rpc3BsYXknKSA9PT0gJ25vbmUnIHx8IHNlbGVjdG9yICYmICFtYXRjaGVzKGxhc3QsIHNlbGVjdG9yKSkpIHtcbiAgICBsYXN0ID0gbGFzdC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nO1xuICB9XG4gIHJldHVybiBsYXN0IHx8IG51bGw7XG59XG5cbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBpbmRleCBvZiBhbiBlbGVtZW50IHdpdGhpbiBpdHMgcGFyZW50IGZvciBhIHNlbGVjdGVkIHNldCBvZlxyXG4gKiBlbGVtZW50c1xyXG4gKiBAcGFyYW0gIHtIVE1MRWxlbWVudH0gZWxcclxuICogQHBhcmFtICB7c2VsZWN0b3J9IHNlbGVjdG9yXHJcbiAqIEByZXR1cm4ge251bWJlcn1cclxuICovXG5mdW5jdGlvbiBpbmRleChlbCwgc2VsZWN0b3IpIHtcbiAgdmFyIGluZGV4ID0gMDtcbiAgaWYgKCFlbCB8fCAhZWwucGFyZW50Tm9kZSkge1xuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIC8qIGpzaGludCBib3NzOnRydWUgKi9cbiAgd2hpbGUgKGVsID0gZWwucHJldmlvdXNFbGVtZW50U2libGluZykge1xuICAgIGlmIChlbC5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpICE9PSAnVEVNUExBVEUnICYmIGVsICE9PSBTb3J0YWJsZS5jbG9uZSAmJiAoIXNlbGVjdG9yIHx8IG1hdGNoZXMoZWwsIHNlbGVjdG9yKSkpIHtcbiAgICAgIGluZGV4Kys7XG4gICAgfVxuICB9XG4gIHJldHVybiBpbmRleDtcbn1cblxuLyoqXHJcbiAqIFJldHVybnMgdGhlIHNjcm9sbCBvZmZzZXQgb2YgdGhlIGdpdmVuIGVsZW1lbnQsIGFkZGVkIHdpdGggYWxsIHRoZSBzY3JvbGwgb2Zmc2V0cyBvZiBwYXJlbnQgZWxlbWVudHMuXHJcbiAqIFRoZSB2YWx1ZSBpcyByZXR1cm5lZCBpbiByZWFsIHBpeGVscy5cclxuICogQHBhcmFtICB7SFRNTEVsZW1lbnR9IGVsXHJcbiAqIEByZXR1cm4ge0FycmF5fSAgICAgICAgICAgICBPZmZzZXRzIGluIHRoZSBmb3JtYXQgb2YgW2xlZnQsIHRvcF1cclxuICovXG5mdW5jdGlvbiBnZXRSZWxhdGl2ZVNjcm9sbE9mZnNldChlbCkge1xuICB2YXIgb2Zmc2V0TGVmdCA9IDAsXG4gICAgb2Zmc2V0VG9wID0gMCxcbiAgICB3aW5TY3JvbGxlciA9IGdldFdpbmRvd1Njcm9sbGluZ0VsZW1lbnQoKTtcbiAgaWYgKGVsKSB7XG4gICAgZG8ge1xuICAgICAgdmFyIGVsTWF0cml4ID0gbWF0cml4KGVsKSxcbiAgICAgICAgc2NhbGVYID0gZWxNYXRyaXguYSxcbiAgICAgICAgc2NhbGVZID0gZWxNYXRyaXguZDtcbiAgICAgIG9mZnNldExlZnQgKz0gZWwuc2Nyb2xsTGVmdCAqIHNjYWxlWDtcbiAgICAgIG9mZnNldFRvcCArPSBlbC5zY3JvbGxUb3AgKiBzY2FsZVk7XG4gICAgfSB3aGlsZSAoZWwgIT09IHdpblNjcm9sbGVyICYmIChlbCA9IGVsLnBhcmVudE5vZGUpKTtcbiAgfVxuICByZXR1cm4gW29mZnNldExlZnQsIG9mZnNldFRvcF07XG59XG5cbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgb2JqZWN0IHdpdGhpbiB0aGUgZ2l2ZW4gYXJyYXlcclxuICogQHBhcmFtICB7QXJyYXl9IGFyciAgIEFycmF5IHRoYXQgbWF5IG9yIG1heSBub3QgaG9sZCB0aGUgb2JqZWN0XHJcbiAqIEBwYXJhbSAge09iamVjdH0gb2JqICBBbiBvYmplY3QgdGhhdCBoYXMgYSBrZXktdmFsdWUgcGFpciB1bmlxdWUgdG8gYW5kIGlkZW50aWNhbCB0byBhIGtleS12YWx1ZSBwYWlyIGluIHRoZSBvYmplY3QgeW91IHdhbnQgdG8gZmluZFxyXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgVGhlIGluZGV4IG9mIHRoZSBvYmplY3QgaW4gdGhlIGFycmF5LCBvciAtMVxyXG4gKi9cbmZ1bmN0aW9uIGluZGV4T2ZPYmplY3QoYXJyLCBvYmopIHtcbiAgZm9yICh2YXIgaSBpbiBhcnIpIHtcbiAgICBpZiAoIWFyci5oYXNPd25Qcm9wZXJ0eShpKSkgY29udGludWU7XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIG9ialtrZXldID09PSBhcnJbaV1ba2V5XSkgcmV0dXJuIE51bWJlcihpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuZnVuY3Rpb24gZ2V0UGFyZW50QXV0b1Njcm9sbEVsZW1lbnQoZWwsIGluY2x1ZGVTZWxmKSB7XG4gIC8vIHNraXAgdG8gd2luZG93XG4gIGlmICghZWwgfHwgIWVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCkgcmV0dXJuIGdldFdpbmRvd1Njcm9sbGluZ0VsZW1lbnQoKTtcbiAgdmFyIGVsZW0gPSBlbDtcbiAgdmFyIGdvdFNlbGYgPSBmYWxzZTtcbiAgZG8ge1xuICAgIC8vIHdlIGRvbid0IG5lZWQgdG8gZ2V0IGVsZW0gY3NzIGlmIGl0IGlzbid0IGV2ZW4gb3ZlcmZsb3dpbmcgaW4gdGhlIGZpcnN0IHBsYWNlIChwZXJmb3JtYW5jZSlcbiAgICBpZiAoZWxlbS5jbGllbnRXaWR0aCA8IGVsZW0uc2Nyb2xsV2lkdGggfHwgZWxlbS5jbGllbnRIZWlnaHQgPCBlbGVtLnNjcm9sbEhlaWdodCkge1xuICAgICAgdmFyIGVsZW1DU1MgPSBjc3MoZWxlbSk7XG4gICAgICBpZiAoZWxlbS5jbGllbnRXaWR0aCA8IGVsZW0uc2Nyb2xsV2lkdGggJiYgKGVsZW1DU1Mub3ZlcmZsb3dYID09ICdhdXRvJyB8fCBlbGVtQ1NTLm92ZXJmbG93WCA9PSAnc2Nyb2xsJykgfHwgZWxlbS5jbGllbnRIZWlnaHQgPCBlbGVtLnNjcm9sbEhlaWdodCAmJiAoZWxlbUNTUy5vdmVyZmxvd1kgPT0gJ2F1dG8nIHx8IGVsZW1DU1Mub3ZlcmZsb3dZID09ICdzY3JvbGwnKSkge1xuICAgICAgICBpZiAoIWVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0IHx8IGVsZW0gPT09IGRvY3VtZW50LmJvZHkpIHJldHVybiBnZXRXaW5kb3dTY3JvbGxpbmdFbGVtZW50KCk7XG4gICAgICAgIGlmIChnb3RTZWxmIHx8IGluY2x1ZGVTZWxmKSByZXR1cm4gZWxlbTtcbiAgICAgICAgZ290U2VsZiA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIC8qIGpzaGludCBib3NzOnRydWUgKi9cbiAgfSB3aGlsZSAoZWxlbSA9IGVsZW0ucGFyZW50Tm9kZSk7XG4gIHJldHVybiBnZXRXaW5kb3dTY3JvbGxpbmdFbGVtZW50KCk7XG59XG5mdW5jdGlvbiBleHRlbmQoZHN0LCBzcmMpIHtcbiAgaWYgKGRzdCAmJiBzcmMpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gc3JjKSB7XG4gICAgICBpZiAoc3JjLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgZHN0W2tleV0gPSBzcmNba2V5XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRzdDtcbn1cbmZ1bmN0aW9uIGlzUmVjdEVxdWFsKHJlY3QxLCByZWN0Mikge1xuICByZXR1cm4gTWF0aC5yb3VuZChyZWN0MS50b3ApID09PSBNYXRoLnJvdW5kKHJlY3QyLnRvcCkgJiYgTWF0aC5yb3VuZChyZWN0MS5sZWZ0KSA9PT0gTWF0aC5yb3VuZChyZWN0Mi5sZWZ0KSAmJiBNYXRoLnJvdW5kKHJlY3QxLmhlaWdodCkgPT09IE1hdGgucm91bmQocmVjdDIuaGVpZ2h0KSAmJiBNYXRoLnJvdW5kKHJlY3QxLndpZHRoKSA9PT0gTWF0aC5yb3VuZChyZWN0Mi53aWR0aCk7XG59XG52YXIgX3Rocm90dGxlVGltZW91dDtcbmZ1bmN0aW9uIHRocm90dGxlKGNhbGxiYWNrLCBtcykge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmICghX3Rocm90dGxlVGltZW91dCkge1xuICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIF90aGlzID0gdGhpcztcbiAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBjYWxsYmFjay5jYWxsKF90aGlzLCBhcmdzWzBdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrLmFwcGx5KF90aGlzLCBhcmdzKTtcbiAgICAgIH1cbiAgICAgIF90aHJvdHRsZVRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3Rocm90dGxlVGltZW91dCA9IHZvaWQgMDtcbiAgICAgIH0sIG1zKTtcbiAgICB9XG4gIH07XG59XG5mdW5jdGlvbiBjYW5jZWxUaHJvdHRsZSgpIHtcbiAgY2xlYXJUaW1lb3V0KF90aHJvdHRsZVRpbWVvdXQpO1xuICBfdGhyb3R0bGVUaW1lb3V0ID0gdm9pZCAwO1xufVxuZnVuY3Rpb24gc2Nyb2xsQnkoZWwsIHgsIHkpIHtcbiAgZWwuc2Nyb2xsTGVmdCArPSB4O1xuICBlbC5zY3JvbGxUb3AgKz0geTtcbn1cbmZ1bmN0aW9uIGNsb25lKGVsKSB7XG4gIHZhciBQb2x5bWVyID0gd2luZG93LlBvbHltZXI7XG4gIHZhciAkID0gd2luZG93LmpRdWVyeSB8fCB3aW5kb3cuWmVwdG87XG4gIGlmIChQb2x5bWVyICYmIFBvbHltZXIuZG9tKSB7XG4gICAgcmV0dXJuIFBvbHltZXIuZG9tKGVsKS5jbG9uZU5vZGUodHJ1ZSk7XG4gIH0gZWxzZSBpZiAoJCkge1xuICAgIHJldHVybiAkKGVsKS5jbG9uZSh0cnVlKVswXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZWwuY2xvbmVOb2RlKHRydWUpO1xuICB9XG59XG5mdW5jdGlvbiBzZXRSZWN0KGVsLCByZWN0KSB7XG4gIGNzcyhlbCwgJ3Bvc2l0aW9uJywgJ2Fic29sdXRlJyk7XG4gIGNzcyhlbCwgJ3RvcCcsIHJlY3QudG9wKTtcbiAgY3NzKGVsLCAnbGVmdCcsIHJlY3QubGVmdCk7XG4gIGNzcyhlbCwgJ3dpZHRoJywgcmVjdC53aWR0aCk7XG4gIGNzcyhlbCwgJ2hlaWdodCcsIHJlY3QuaGVpZ2h0KTtcbn1cbmZ1bmN0aW9uIHVuc2V0UmVjdChlbCkge1xuICBjc3MoZWwsICdwb3NpdGlvbicsICcnKTtcbiAgY3NzKGVsLCAndG9wJywgJycpO1xuICBjc3MoZWwsICdsZWZ0JywgJycpO1xuICBjc3MoZWwsICd3aWR0aCcsICcnKTtcbiAgY3NzKGVsLCAnaGVpZ2h0JywgJycpO1xufVxuZnVuY3Rpb24gZ2V0Q2hpbGRDb250YWluaW5nUmVjdEZyb21FbGVtZW50KGNvbnRhaW5lciwgb3B0aW9ucywgZ2hvc3RFbCkge1xuICB2YXIgcmVjdCA9IHt9O1xuICBBcnJheS5mcm9tKGNvbnRhaW5lci5jaGlsZHJlbikuZm9yRWFjaChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICB2YXIgX3JlY3QkbGVmdCwgX3JlY3QkdG9wLCBfcmVjdCRyaWdodCwgX3JlY3QkYm90dG9tO1xuICAgIGlmICghY2xvc2VzdChjaGlsZCwgb3B0aW9ucy5kcmFnZ2FibGUsIGNvbnRhaW5lciwgZmFsc2UpIHx8IGNoaWxkLmFuaW1hdGVkIHx8IGNoaWxkID09PSBnaG9zdEVsKSByZXR1cm47XG4gICAgdmFyIGNoaWxkUmVjdCA9IGdldFJlY3QoY2hpbGQpO1xuICAgIHJlY3QubGVmdCA9IE1hdGgubWluKChfcmVjdCRsZWZ0ID0gcmVjdC5sZWZ0KSAhPT0gbnVsbCAmJiBfcmVjdCRsZWZ0ICE9PSB2b2lkIDAgPyBfcmVjdCRsZWZ0IDogSW5maW5pdHksIGNoaWxkUmVjdC5sZWZ0KTtcbiAgICByZWN0LnRvcCA9IE1hdGgubWluKChfcmVjdCR0b3AgPSByZWN0LnRvcCkgIT09IG51bGwgJiYgX3JlY3QkdG9wICE9PSB2b2lkIDAgPyBfcmVjdCR0b3AgOiBJbmZpbml0eSwgY2hpbGRSZWN0LnRvcCk7XG4gICAgcmVjdC5yaWdodCA9IE1hdGgubWF4KChfcmVjdCRyaWdodCA9IHJlY3QucmlnaHQpICE9PSBudWxsICYmIF9yZWN0JHJpZ2h0ICE9PSB2b2lkIDAgPyBfcmVjdCRyaWdodCA6IC1JbmZpbml0eSwgY2hpbGRSZWN0LnJpZ2h0KTtcbiAgICByZWN0LmJvdHRvbSA9IE1hdGgubWF4KChfcmVjdCRib3R0b20gPSByZWN0LmJvdHRvbSkgIT09IG51bGwgJiYgX3JlY3QkYm90dG9tICE9PSB2b2lkIDAgPyBfcmVjdCRib3R0b20gOiAtSW5maW5pdHksIGNoaWxkUmVjdC5ib3R0b20pO1xuICB9KTtcbiAgcmVjdC53aWR0aCA9IHJlY3QucmlnaHQgLSByZWN0LmxlZnQ7XG4gIHJlY3QuaGVpZ2h0ID0gcmVjdC5ib3R0b20gLSByZWN0LnRvcDtcbiAgcmVjdC54ID0gcmVjdC5sZWZ0O1xuICByZWN0LnkgPSByZWN0LnRvcDtcbiAgcmV0dXJuIHJlY3Q7XG59XG52YXIgZXhwYW5kbyA9ICdTb3J0YWJsZScgKyBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuZnVuY3Rpb24gQW5pbWF0aW9uU3RhdGVNYW5hZ2VyKCkge1xuICB2YXIgYW5pbWF0aW9uU3RhdGVzID0gW10sXG4gICAgYW5pbWF0aW9uQ2FsbGJhY2tJZDtcbiAgcmV0dXJuIHtcbiAgICBjYXB0dXJlQW5pbWF0aW9uU3RhdGU6IGZ1bmN0aW9uIGNhcHR1cmVBbmltYXRpb25TdGF0ZSgpIHtcbiAgICAgIGFuaW1hdGlvblN0YXRlcyA9IFtdO1xuICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuYW5pbWF0aW9uKSByZXR1cm47XG4gICAgICB2YXIgY2hpbGRyZW4gPSBbXS5zbGljZS5jYWxsKHRoaXMuZWwuY2hpbGRyZW4pO1xuICAgICAgY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgaWYgKGNzcyhjaGlsZCwgJ2Rpc3BsYXknKSA9PT0gJ25vbmUnIHx8IGNoaWxkID09PSBTb3J0YWJsZS5naG9zdCkgcmV0dXJuO1xuICAgICAgICBhbmltYXRpb25TdGF0ZXMucHVzaCh7XG4gICAgICAgICAgdGFyZ2V0OiBjaGlsZCxcbiAgICAgICAgICByZWN0OiBnZXRSZWN0KGNoaWxkKVxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGZyb21SZWN0ID0gX29iamVjdFNwcmVhZDIoe30sIGFuaW1hdGlvblN0YXRlc1thbmltYXRpb25TdGF0ZXMubGVuZ3RoIC0gMV0ucmVjdCk7XG5cbiAgICAgICAgLy8gSWYgYW5pbWF0aW5nOiBjb21wZW5zYXRlIGZvciBjdXJyZW50IGFuaW1hdGlvblxuICAgICAgICBpZiAoY2hpbGQudGhpc0FuaW1hdGlvbkR1cmF0aW9uKSB7XG4gICAgICAgICAgdmFyIGNoaWxkTWF0cml4ID0gbWF0cml4KGNoaWxkLCB0cnVlKTtcbiAgICAgICAgICBpZiAoY2hpbGRNYXRyaXgpIHtcbiAgICAgICAgICAgIGZyb21SZWN0LnRvcCAtPSBjaGlsZE1hdHJpeC5mO1xuICAgICAgICAgICAgZnJvbVJlY3QubGVmdCAtPSBjaGlsZE1hdHJpeC5lO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjaGlsZC5mcm9tUmVjdCA9IGZyb21SZWN0O1xuICAgICAgfSk7XG4gICAgfSxcbiAgICBhZGRBbmltYXRpb25TdGF0ZTogZnVuY3Rpb24gYWRkQW5pbWF0aW9uU3RhdGUoc3RhdGUpIHtcbiAgICAgIGFuaW1hdGlvblN0YXRlcy5wdXNoKHN0YXRlKTtcbiAgICB9LFxuICAgIHJlbW92ZUFuaW1hdGlvblN0YXRlOiBmdW5jdGlvbiByZW1vdmVBbmltYXRpb25TdGF0ZSh0YXJnZXQpIHtcbiAgICAgIGFuaW1hdGlvblN0YXRlcy5zcGxpY2UoaW5kZXhPZk9iamVjdChhbmltYXRpb25TdGF0ZXMsIHtcbiAgICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICAgIH0pLCAxKTtcbiAgICB9LFxuICAgIGFuaW1hdGVBbGw6IGZ1bmN0aW9uIGFuaW1hdGVBbGwoY2FsbGJhY2spIHtcbiAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICBpZiAoIXRoaXMub3B0aW9ucy5hbmltYXRpb24pIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGFuaW1hdGlvbkNhbGxiYWNrSWQpO1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSBjYWxsYmFjaygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgYW5pbWF0aW5nID0gZmFsc2UsXG4gICAgICAgIGFuaW1hdGlvblRpbWUgPSAwO1xuICAgICAgYW5pbWF0aW9uU3RhdGVzLmZvckVhY2goZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgICAgIHZhciB0aW1lID0gMCxcbiAgICAgICAgICB0YXJnZXQgPSBzdGF0ZS50YXJnZXQsXG4gICAgICAgICAgZnJvbVJlY3QgPSB0YXJnZXQuZnJvbVJlY3QsXG4gICAgICAgICAgdG9SZWN0ID0gZ2V0UmVjdCh0YXJnZXQpLFxuICAgICAgICAgIHByZXZGcm9tUmVjdCA9IHRhcmdldC5wcmV2RnJvbVJlY3QsXG4gICAgICAgICAgcHJldlRvUmVjdCA9IHRhcmdldC5wcmV2VG9SZWN0LFxuICAgICAgICAgIGFuaW1hdGluZ1JlY3QgPSBzdGF0ZS5yZWN0LFxuICAgICAgICAgIHRhcmdldE1hdHJpeCA9IG1hdHJpeCh0YXJnZXQsIHRydWUpO1xuICAgICAgICBpZiAodGFyZ2V0TWF0cml4KSB7XG4gICAgICAgICAgLy8gQ29tcGVuc2F0ZSBmb3IgY3VycmVudCBhbmltYXRpb25cbiAgICAgICAgICB0b1JlY3QudG9wIC09IHRhcmdldE1hdHJpeC5mO1xuICAgICAgICAgIHRvUmVjdC5sZWZ0IC09IHRhcmdldE1hdHJpeC5lO1xuICAgICAgICB9XG4gICAgICAgIHRhcmdldC50b1JlY3QgPSB0b1JlY3Q7XG4gICAgICAgIGlmICh0YXJnZXQudGhpc0FuaW1hdGlvbkR1cmF0aW9uKSB7XG4gICAgICAgICAgLy8gQ291bGQgYWxzbyBjaGVjayBpZiBhbmltYXRpbmdSZWN0IGlzIGJldHdlZW4gZnJvbVJlY3QgYW5kIHRvUmVjdFxuICAgICAgICAgIGlmIChpc1JlY3RFcXVhbChwcmV2RnJvbVJlY3QsIHRvUmVjdCkgJiYgIWlzUmVjdEVxdWFsKGZyb21SZWN0LCB0b1JlY3QpICYmXG4gICAgICAgICAgLy8gTWFrZSBzdXJlIGFuaW1hdGluZ1JlY3QgaXMgb24gbGluZSBiZXR3ZWVuIHRvUmVjdCAmIGZyb21SZWN0XG4gICAgICAgICAgKGFuaW1hdGluZ1JlY3QudG9wIC0gdG9SZWN0LnRvcCkgLyAoYW5pbWF0aW5nUmVjdC5sZWZ0IC0gdG9SZWN0LmxlZnQpID09PSAoZnJvbVJlY3QudG9wIC0gdG9SZWN0LnRvcCkgLyAoZnJvbVJlY3QubGVmdCAtIHRvUmVjdC5sZWZ0KSkge1xuICAgICAgICAgICAgLy8gSWYgcmV0dXJuaW5nIHRvIHNhbWUgcGxhY2UgYXMgc3RhcnRlZCBmcm9tIGFuaW1hdGlvbiBhbmQgb24gc2FtZSBheGlzXG4gICAgICAgICAgICB0aW1lID0gY2FsY3VsYXRlUmVhbFRpbWUoYW5pbWF0aW5nUmVjdCwgcHJldkZyb21SZWN0LCBwcmV2VG9SZWN0LCBfdGhpcy5vcHRpb25zKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBmcm9tUmVjdCAhPSB0b1JlY3Q6IGFuaW1hdGVcbiAgICAgICAgaWYgKCFpc1JlY3RFcXVhbCh0b1JlY3QsIGZyb21SZWN0KSkge1xuICAgICAgICAgIHRhcmdldC5wcmV2RnJvbVJlY3QgPSBmcm9tUmVjdDtcbiAgICAgICAgICB0YXJnZXQucHJldlRvUmVjdCA9IHRvUmVjdDtcbiAgICAgICAgICBpZiAoIXRpbWUpIHtcbiAgICAgICAgICAgIHRpbWUgPSBfdGhpcy5vcHRpb25zLmFuaW1hdGlvbjtcbiAgICAgICAgICB9XG4gICAgICAgICAgX3RoaXMuYW5pbWF0ZSh0YXJnZXQsIGFuaW1hdGluZ1JlY3QsIHRvUmVjdCwgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRpbWUpIHtcbiAgICAgICAgICBhbmltYXRpbmcgPSB0cnVlO1xuICAgICAgICAgIGFuaW1hdGlvblRpbWUgPSBNYXRoLm1heChhbmltYXRpb25UaW1lLCB0aW1lKTtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGFyZ2V0LmFuaW1hdGlvblJlc2V0VGltZXIpO1xuICAgICAgICAgIHRhcmdldC5hbmltYXRpb25SZXNldFRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0YXJnZXQuYW5pbWF0aW9uVGltZSA9IDA7XG4gICAgICAgICAgICB0YXJnZXQucHJldkZyb21SZWN0ID0gbnVsbDtcbiAgICAgICAgICAgIHRhcmdldC5mcm9tUmVjdCA9IG51bGw7XG4gICAgICAgICAgICB0YXJnZXQucHJldlRvUmVjdCA9IG51bGw7XG4gICAgICAgICAgICB0YXJnZXQudGhpc0FuaW1hdGlvbkR1cmF0aW9uID0gbnVsbDtcbiAgICAgICAgICB9LCB0aW1lKTtcbiAgICAgICAgICB0YXJnZXQudGhpc0FuaW1hdGlvbkR1cmF0aW9uID0gdGltZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjbGVhclRpbWVvdXQoYW5pbWF0aW9uQ2FsbGJhY2tJZCk7XG4gICAgICBpZiAoIWFuaW1hdGluZykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSBjYWxsYmFjaygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYW5pbWF0aW9uQ2FsbGJhY2tJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIGNhbGxiYWNrKCk7XG4gICAgICAgIH0sIGFuaW1hdGlvblRpbWUpO1xuICAgICAgfVxuICAgICAgYW5pbWF0aW9uU3RhdGVzID0gW107XG4gICAgfSxcbiAgICBhbmltYXRlOiBmdW5jdGlvbiBhbmltYXRlKHRhcmdldCwgY3VycmVudFJlY3QsIHRvUmVjdCwgZHVyYXRpb24pIHtcbiAgICAgIGlmIChkdXJhdGlvbikge1xuICAgICAgICBjc3ModGFyZ2V0LCAndHJhbnNpdGlvbicsICcnKTtcbiAgICAgICAgY3NzKHRhcmdldCwgJ3RyYW5zZm9ybScsICcnKTtcbiAgICAgICAgdmFyIGVsTWF0cml4ID0gbWF0cml4KHRoaXMuZWwpLFxuICAgICAgICAgIHNjYWxlWCA9IGVsTWF0cml4ICYmIGVsTWF0cml4LmEsXG4gICAgICAgICAgc2NhbGVZID0gZWxNYXRyaXggJiYgZWxNYXRyaXguZCxcbiAgICAgICAgICB0cmFuc2xhdGVYID0gKGN1cnJlbnRSZWN0LmxlZnQgLSB0b1JlY3QubGVmdCkgLyAoc2NhbGVYIHx8IDEpLFxuICAgICAgICAgIHRyYW5zbGF0ZVkgPSAoY3VycmVudFJlY3QudG9wIC0gdG9SZWN0LnRvcCkgLyAoc2NhbGVZIHx8IDEpO1xuICAgICAgICB0YXJnZXQuYW5pbWF0aW5nWCA9ICEhdHJhbnNsYXRlWDtcbiAgICAgICAgdGFyZ2V0LmFuaW1hdGluZ1kgPSAhIXRyYW5zbGF0ZVk7XG4gICAgICAgIGNzcyh0YXJnZXQsICd0cmFuc2Zvcm0nLCAndHJhbnNsYXRlM2QoJyArIHRyYW5zbGF0ZVggKyAncHgsJyArIHRyYW5zbGF0ZVkgKyAncHgsMCknKTtcbiAgICAgICAgdGhpcy5mb3JSZXBhaW50RHVtbXkgPSByZXBhaW50KHRhcmdldCk7IC8vIHJlcGFpbnRcblxuICAgICAgICBjc3ModGFyZ2V0LCAndHJhbnNpdGlvbicsICd0cmFuc2Zvcm0gJyArIGR1cmF0aW9uICsgJ21zJyArICh0aGlzLm9wdGlvbnMuZWFzaW5nID8gJyAnICsgdGhpcy5vcHRpb25zLmVhc2luZyA6ICcnKSk7XG4gICAgICAgIGNzcyh0YXJnZXQsICd0cmFuc2Zvcm0nLCAndHJhbnNsYXRlM2QoMCwwLDApJyk7XG4gICAgICAgIHR5cGVvZiB0YXJnZXQuYW5pbWF0ZWQgPT09ICdudW1iZXInICYmIGNsZWFyVGltZW91dCh0YXJnZXQuYW5pbWF0ZWQpO1xuICAgICAgICB0YXJnZXQuYW5pbWF0ZWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjc3ModGFyZ2V0LCAndHJhbnNpdGlvbicsICcnKTtcbiAgICAgICAgICBjc3ModGFyZ2V0LCAndHJhbnNmb3JtJywgJycpO1xuICAgICAgICAgIHRhcmdldC5hbmltYXRlZCA9IGZhbHNlO1xuICAgICAgICAgIHRhcmdldC5hbmltYXRpbmdYID0gZmFsc2U7XG4gICAgICAgICAgdGFyZ2V0LmFuaW1hdGluZ1kgPSBmYWxzZTtcbiAgICAgICAgfSwgZHVyYXRpb24pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cbmZ1bmN0aW9uIHJlcGFpbnQodGFyZ2V0KSB7XG4gIHJldHVybiB0YXJnZXQub2Zmc2V0V2lkdGg7XG59XG5mdW5jdGlvbiBjYWxjdWxhdGVSZWFsVGltZShhbmltYXRpbmdSZWN0LCBmcm9tUmVjdCwgdG9SZWN0LCBvcHRpb25zKSB7XG4gIHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3coZnJvbVJlY3QudG9wIC0gYW5pbWF0aW5nUmVjdC50b3AsIDIpICsgTWF0aC5wb3coZnJvbVJlY3QubGVmdCAtIGFuaW1hdGluZ1JlY3QubGVmdCwgMikpIC8gTWF0aC5zcXJ0KE1hdGgucG93KGZyb21SZWN0LnRvcCAtIHRvUmVjdC50b3AsIDIpICsgTWF0aC5wb3coZnJvbVJlY3QubGVmdCAtIHRvUmVjdC5sZWZ0LCAyKSkgKiBvcHRpb25zLmFuaW1hdGlvbjtcbn1cblxudmFyIHBsdWdpbnMgPSBbXTtcbnZhciBkZWZhdWx0cyA9IHtcbiAgaW5pdGlhbGl6ZUJ5RGVmYXVsdDogdHJ1ZVxufTtcbnZhciBQbHVnaW5NYW5hZ2VyID0ge1xuICBtb3VudDogZnVuY3Rpb24gbW91bnQocGx1Z2luKSB7XG4gICAgLy8gU2V0IGRlZmF1bHQgc3RhdGljIHByb3BlcnRpZXNcbiAgICBmb3IgKHZhciBvcHRpb24gaW4gZGVmYXVsdHMpIHtcbiAgICAgIGlmIChkZWZhdWx0cy5oYXNPd25Qcm9wZXJ0eShvcHRpb24pICYmICEob3B0aW9uIGluIHBsdWdpbikpIHtcbiAgICAgICAgcGx1Z2luW29wdGlvbl0gPSBkZWZhdWx0c1tvcHRpb25dO1xuICAgICAgfVxuICAgIH1cbiAgICBwbHVnaW5zLmZvckVhY2goZnVuY3Rpb24gKHApIHtcbiAgICAgIGlmIChwLnBsdWdpbk5hbWUgPT09IHBsdWdpbi5wbHVnaW5OYW1lKSB7XG4gICAgICAgIHRocm93IFwiU29ydGFibGU6IENhbm5vdCBtb3VudCBwbHVnaW4gXCIuY29uY2F0KHBsdWdpbi5wbHVnaW5OYW1lLCBcIiBtb3JlIHRoYW4gb25jZVwiKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBwbHVnaW5zLnB1c2gocGx1Z2luKTtcbiAgfSxcbiAgcGx1Z2luRXZlbnQ6IGZ1bmN0aW9uIHBsdWdpbkV2ZW50KGV2ZW50TmFtZSwgc29ydGFibGUsIGV2dCkge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgdGhpcy5ldmVudENhbmNlbGVkID0gZmFsc2U7XG4gICAgZXZ0LmNhbmNlbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIF90aGlzLmV2ZW50Q2FuY2VsZWQgPSB0cnVlO1xuICAgIH07XG4gICAgdmFyIGV2ZW50TmFtZUdsb2JhbCA9IGV2ZW50TmFtZSArICdHbG9iYWwnO1xuICAgIHBsdWdpbnMuZm9yRWFjaChmdW5jdGlvbiAocGx1Z2luKSB7XG4gICAgICBpZiAoIXNvcnRhYmxlW3BsdWdpbi5wbHVnaW5OYW1lXSkgcmV0dXJuO1xuICAgICAgLy8gRmlyZSBnbG9iYWwgZXZlbnRzIGlmIGl0IGV4aXN0cyBpbiB0aGlzIHNvcnRhYmxlXG4gICAgICBpZiAoc29ydGFibGVbcGx1Z2luLnBsdWdpbk5hbWVdW2V2ZW50TmFtZUdsb2JhbF0pIHtcbiAgICAgICAgc29ydGFibGVbcGx1Z2luLnBsdWdpbk5hbWVdW2V2ZW50TmFtZUdsb2JhbF0oX29iamVjdFNwcmVhZDIoe1xuICAgICAgICAgIHNvcnRhYmxlOiBzb3J0YWJsZVxuICAgICAgICB9LCBldnQpKTtcbiAgICAgIH1cblxuICAgICAgLy8gT25seSBmaXJlIHBsdWdpbiBldmVudCBpZiBwbHVnaW4gaXMgZW5hYmxlZCBpbiB0aGlzIHNvcnRhYmxlLFxuICAgICAgLy8gYW5kIHBsdWdpbiBoYXMgZXZlbnQgZGVmaW5lZFxuICAgICAgaWYgKHNvcnRhYmxlLm9wdGlvbnNbcGx1Z2luLnBsdWdpbk5hbWVdICYmIHNvcnRhYmxlW3BsdWdpbi5wbHVnaW5OYW1lXVtldmVudE5hbWVdKSB7XG4gICAgICAgIHNvcnRhYmxlW3BsdWdpbi5wbHVnaW5OYW1lXVtldmVudE5hbWVdKF9vYmplY3RTcHJlYWQyKHtcbiAgICAgICAgICBzb3J0YWJsZTogc29ydGFibGVcbiAgICAgICAgfSwgZXZ0KSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0sXG4gIGluaXRpYWxpemVQbHVnaW5zOiBmdW5jdGlvbiBpbml0aWFsaXplUGx1Z2lucyhzb3J0YWJsZSwgZWwsIGRlZmF1bHRzLCBvcHRpb25zKSB7XG4gICAgcGx1Z2lucy5mb3JFYWNoKGZ1bmN0aW9uIChwbHVnaW4pIHtcbiAgICAgIHZhciBwbHVnaW5OYW1lID0gcGx1Z2luLnBsdWdpbk5hbWU7XG4gICAgICBpZiAoIXNvcnRhYmxlLm9wdGlvbnNbcGx1Z2luTmFtZV0gJiYgIXBsdWdpbi5pbml0aWFsaXplQnlEZWZhdWx0KSByZXR1cm47XG4gICAgICB2YXIgaW5pdGlhbGl6ZWQgPSBuZXcgcGx1Z2luKHNvcnRhYmxlLCBlbCwgc29ydGFibGUub3B0aW9ucyk7XG4gICAgICBpbml0aWFsaXplZC5zb3J0YWJsZSA9IHNvcnRhYmxlO1xuICAgICAgaW5pdGlhbGl6ZWQub3B0aW9ucyA9IHNvcnRhYmxlLm9wdGlvbnM7XG4gICAgICBzb3J0YWJsZVtwbHVnaW5OYW1lXSA9IGluaXRpYWxpemVkO1xuXG4gICAgICAvLyBBZGQgZGVmYXVsdCBvcHRpb25zIGZyb20gcGx1Z2luXG4gICAgICBfZXh0ZW5kcyhkZWZhdWx0cywgaW5pdGlhbGl6ZWQuZGVmYXVsdHMpO1xuICAgIH0pO1xuICAgIGZvciAodmFyIG9wdGlvbiBpbiBzb3J0YWJsZS5vcHRpb25zKSB7XG4gICAgICBpZiAoIXNvcnRhYmxlLm9wdGlvbnMuaGFzT3duUHJvcGVydHkob3B0aW9uKSkgY29udGludWU7XG4gICAgICB2YXIgbW9kaWZpZWQgPSB0aGlzLm1vZGlmeU9wdGlvbihzb3J0YWJsZSwgb3B0aW9uLCBzb3J0YWJsZS5vcHRpb25zW29wdGlvbl0pO1xuICAgICAgaWYgKHR5cGVvZiBtb2RpZmllZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc29ydGFibGUub3B0aW9uc1tvcHRpb25dID0gbW9kaWZpZWQ7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBnZXRFdmVudFByb3BlcnRpZXM6IGZ1bmN0aW9uIGdldEV2ZW50UHJvcGVydGllcyhuYW1lLCBzb3J0YWJsZSkge1xuICAgIHZhciBldmVudFByb3BlcnRpZXMgPSB7fTtcbiAgICBwbHVnaW5zLmZvckVhY2goZnVuY3Rpb24gKHBsdWdpbikge1xuICAgICAgaWYgKHR5cGVvZiBwbHVnaW4uZXZlbnRQcm9wZXJ0aWVzICE9PSAnZnVuY3Rpb24nKSByZXR1cm47XG4gICAgICBfZXh0ZW5kcyhldmVudFByb3BlcnRpZXMsIHBsdWdpbi5ldmVudFByb3BlcnRpZXMuY2FsbChzb3J0YWJsZVtwbHVnaW4ucGx1Z2luTmFtZV0sIG5hbWUpKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZXZlbnRQcm9wZXJ0aWVzO1xuICB9LFxuICBtb2RpZnlPcHRpb246IGZ1bmN0aW9uIG1vZGlmeU9wdGlvbihzb3J0YWJsZSwgbmFtZSwgdmFsdWUpIHtcbiAgICB2YXIgbW9kaWZpZWRWYWx1ZTtcbiAgICBwbHVnaW5zLmZvckVhY2goZnVuY3Rpb24gKHBsdWdpbikge1xuICAgICAgLy8gUGx1Z2luIG11c3QgZXhpc3Qgb24gdGhlIFNvcnRhYmxlXG4gICAgICBpZiAoIXNvcnRhYmxlW3BsdWdpbi5wbHVnaW5OYW1lXSkgcmV0dXJuO1xuXG4gICAgICAvLyBJZiBzdGF0aWMgb3B0aW9uIGxpc3RlbmVyIGV4aXN0cyBmb3IgdGhpcyBvcHRpb24sIGNhbGwgaW4gdGhlIGNvbnRleHQgb2YgdGhlIFNvcnRhYmxlJ3MgaW5zdGFuY2Ugb2YgdGhpcyBwbHVnaW5cbiAgICAgIGlmIChwbHVnaW4ub3B0aW9uTGlzdGVuZXJzICYmIHR5cGVvZiBwbHVnaW4ub3B0aW9uTGlzdGVuZXJzW25hbWVdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIG1vZGlmaWVkVmFsdWUgPSBwbHVnaW4ub3B0aW9uTGlzdGVuZXJzW25hbWVdLmNhbGwoc29ydGFibGVbcGx1Z2luLnBsdWdpbk5hbWVdLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIG1vZGlmaWVkVmFsdWU7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGRpc3BhdGNoRXZlbnQoX3JlZikge1xuICB2YXIgc29ydGFibGUgPSBfcmVmLnNvcnRhYmxlLFxuICAgIHJvb3RFbCA9IF9yZWYucm9vdEVsLFxuICAgIG5hbWUgPSBfcmVmLm5hbWUsXG4gICAgdGFyZ2V0RWwgPSBfcmVmLnRhcmdldEVsLFxuICAgIGNsb25lRWwgPSBfcmVmLmNsb25lRWwsXG4gICAgdG9FbCA9IF9yZWYudG9FbCxcbiAgICBmcm9tRWwgPSBfcmVmLmZyb21FbCxcbiAgICBvbGRJbmRleCA9IF9yZWYub2xkSW5kZXgsXG4gICAgbmV3SW5kZXggPSBfcmVmLm5ld0luZGV4LFxuICAgIG9sZERyYWdnYWJsZUluZGV4ID0gX3JlZi5vbGREcmFnZ2FibGVJbmRleCxcbiAgICBuZXdEcmFnZ2FibGVJbmRleCA9IF9yZWYubmV3RHJhZ2dhYmxlSW5kZXgsXG4gICAgb3JpZ2luYWxFdmVudCA9IF9yZWYub3JpZ2luYWxFdmVudCxcbiAgICBwdXRTb3J0YWJsZSA9IF9yZWYucHV0U29ydGFibGUsXG4gICAgZXh0cmFFdmVudFByb3BlcnRpZXMgPSBfcmVmLmV4dHJhRXZlbnRQcm9wZXJ0aWVzO1xuICBzb3J0YWJsZSA9IHNvcnRhYmxlIHx8IHJvb3RFbCAmJiByb290RWxbZXhwYW5kb107XG4gIGlmICghc29ydGFibGUpIHJldHVybjtcbiAgdmFyIGV2dCxcbiAgICBvcHRpb25zID0gc29ydGFibGUub3B0aW9ucyxcbiAgICBvbk5hbWUgPSAnb24nICsgbmFtZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIG5hbWUuc3Vic3RyKDEpO1xuICAvLyBTdXBwb3J0IGZvciBuZXcgQ3VzdG9tRXZlbnQgZmVhdHVyZVxuICBpZiAod2luZG93LkN1c3RvbUV2ZW50ICYmICFJRTExT3JMZXNzICYmICFFZGdlKSB7XG4gICAgZXZ0ID0gbmV3IEN1c3RvbUV2ZW50KG5hbWUsIHtcbiAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICBjYW5jZWxhYmxlOiB0cnVlXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgZXZ0ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0V2ZW50Jyk7XG4gICAgZXZ0LmluaXRFdmVudChuYW1lLCB0cnVlLCB0cnVlKTtcbiAgfVxuICBldnQudG8gPSB0b0VsIHx8IHJvb3RFbDtcbiAgZXZ0LmZyb20gPSBmcm9tRWwgfHwgcm9vdEVsO1xuICBldnQuaXRlbSA9IHRhcmdldEVsIHx8IHJvb3RFbDtcbiAgZXZ0LmNsb25lID0gY2xvbmVFbDtcbiAgZXZ0Lm9sZEluZGV4ID0gb2xkSW5kZXg7XG4gIGV2dC5uZXdJbmRleCA9IG5ld0luZGV4O1xuICBldnQub2xkRHJhZ2dhYmxlSW5kZXggPSBvbGREcmFnZ2FibGVJbmRleDtcbiAgZXZ0Lm5ld0RyYWdnYWJsZUluZGV4ID0gbmV3RHJhZ2dhYmxlSW5kZXg7XG4gIGV2dC5vcmlnaW5hbEV2ZW50ID0gb3JpZ2luYWxFdmVudDtcbiAgZXZ0LnB1bGxNb2RlID0gcHV0U29ydGFibGUgPyBwdXRTb3J0YWJsZS5sYXN0UHV0TW9kZSA6IHVuZGVmaW5lZDtcbiAgdmFyIGFsbEV2ZW50UHJvcGVydGllcyA9IF9vYmplY3RTcHJlYWQyKF9vYmplY3RTcHJlYWQyKHt9LCBleHRyYUV2ZW50UHJvcGVydGllcyksIFBsdWdpbk1hbmFnZXIuZ2V0RXZlbnRQcm9wZXJ0aWVzKG5hbWUsIHNvcnRhYmxlKSk7XG4gIGZvciAodmFyIG9wdGlvbiBpbiBhbGxFdmVudFByb3BlcnRpZXMpIHtcbiAgICBldnRbb3B0aW9uXSA9IGFsbEV2ZW50UHJvcGVydGllc1tvcHRpb25dO1xuICB9XG4gIGlmIChyb290RWwpIHtcbiAgICByb290RWwuZGlzcGF0Y2hFdmVudChldnQpO1xuICB9XG4gIGlmIChvcHRpb25zW29uTmFtZV0pIHtcbiAgICBvcHRpb25zW29uTmFtZV0uY2FsbChzb3J0YWJsZSwgZXZ0KTtcbiAgfVxufVxuXG52YXIgX2V4Y2x1ZGVkID0gW1wiZXZ0XCJdO1xudmFyIHBsdWdpbkV2ZW50ID0gZnVuY3Rpb24gcGx1Z2luRXZlbnQoZXZlbnROYW1lLCBzb3J0YWJsZSkge1xuICB2YXIgX3JlZiA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDoge30sXG4gICAgb3JpZ2luYWxFdmVudCA9IF9yZWYuZXZ0LFxuICAgIGRhdGEgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMoX3JlZiwgX2V4Y2x1ZGVkKTtcbiAgUGx1Z2luTWFuYWdlci5wbHVnaW5FdmVudC5iaW5kKFNvcnRhYmxlKShldmVudE5hbWUsIHNvcnRhYmxlLCBfb2JqZWN0U3ByZWFkMih7XG4gICAgZHJhZ0VsOiBkcmFnRWwsXG4gICAgcGFyZW50RWw6IHBhcmVudEVsLFxuICAgIGdob3N0RWw6IGdob3N0RWwsXG4gICAgcm9vdEVsOiByb290RWwsXG4gICAgbmV4dEVsOiBuZXh0RWwsXG4gICAgbGFzdERvd25FbDogbGFzdERvd25FbCxcbiAgICBjbG9uZUVsOiBjbG9uZUVsLFxuICAgIGNsb25lSGlkZGVuOiBjbG9uZUhpZGRlbixcbiAgICBkcmFnU3RhcnRlZDogbW92ZWQsXG4gICAgcHV0U29ydGFibGU6IHB1dFNvcnRhYmxlLFxuICAgIGFjdGl2ZVNvcnRhYmxlOiBTb3J0YWJsZS5hY3RpdmUsXG4gICAgb3JpZ2luYWxFdmVudDogb3JpZ2luYWxFdmVudCxcbiAgICBvbGRJbmRleDogb2xkSW5kZXgsXG4gICAgb2xkRHJhZ2dhYmxlSW5kZXg6IG9sZERyYWdnYWJsZUluZGV4LFxuICAgIG5ld0luZGV4OiBuZXdJbmRleCxcbiAgICBuZXdEcmFnZ2FibGVJbmRleDogbmV3RHJhZ2dhYmxlSW5kZXgsXG4gICAgaGlkZUdob3N0Rm9yVGFyZ2V0OiBfaGlkZUdob3N0Rm9yVGFyZ2V0LFxuICAgIHVuaGlkZUdob3N0Rm9yVGFyZ2V0OiBfdW5oaWRlR2hvc3RGb3JUYXJnZXQsXG4gICAgY2xvbmVOb3dIaWRkZW46IGZ1bmN0aW9uIGNsb25lTm93SGlkZGVuKCkge1xuICAgICAgY2xvbmVIaWRkZW4gPSB0cnVlO1xuICAgIH0sXG4gICAgY2xvbmVOb3dTaG93bjogZnVuY3Rpb24gY2xvbmVOb3dTaG93bigpIHtcbiAgICAgIGNsb25lSGlkZGVuID0gZmFsc2U7XG4gICAgfSxcbiAgICBkaXNwYXRjaFNvcnRhYmxlRXZlbnQ6IGZ1bmN0aW9uIGRpc3BhdGNoU29ydGFibGVFdmVudChuYW1lKSB7XG4gICAgICBfZGlzcGF0Y2hFdmVudCh7XG4gICAgICAgIHNvcnRhYmxlOiBzb3J0YWJsZSxcbiAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgb3JpZ2luYWxFdmVudDogb3JpZ2luYWxFdmVudFxuICAgICAgfSk7XG4gICAgfVxuICB9LCBkYXRhKSk7XG59O1xuZnVuY3Rpb24gX2Rpc3BhdGNoRXZlbnQoaW5mbykge1xuICBkaXNwYXRjaEV2ZW50KF9vYmplY3RTcHJlYWQyKHtcbiAgICBwdXRTb3J0YWJsZTogcHV0U29ydGFibGUsXG4gICAgY2xvbmVFbDogY2xvbmVFbCxcbiAgICB0YXJnZXRFbDogZHJhZ0VsLFxuICAgIHJvb3RFbDogcm9vdEVsLFxuICAgIG9sZEluZGV4OiBvbGRJbmRleCxcbiAgICBvbGREcmFnZ2FibGVJbmRleDogb2xkRHJhZ2dhYmxlSW5kZXgsXG4gICAgbmV3SW5kZXg6IG5ld0luZGV4LFxuICAgIG5ld0RyYWdnYWJsZUluZGV4OiBuZXdEcmFnZ2FibGVJbmRleFxuICB9LCBpbmZvKSk7XG59XG52YXIgZHJhZ0VsLFxuICBwYXJlbnRFbCxcbiAgZ2hvc3RFbCxcbiAgcm9vdEVsLFxuICBuZXh0RWwsXG4gIGxhc3REb3duRWwsXG4gIGNsb25lRWwsXG4gIGNsb25lSGlkZGVuLFxuICBvbGRJbmRleCxcbiAgbmV3SW5kZXgsXG4gIG9sZERyYWdnYWJsZUluZGV4LFxuICBuZXdEcmFnZ2FibGVJbmRleCxcbiAgYWN0aXZlR3JvdXAsXG4gIHB1dFNvcnRhYmxlLFxuICBhd2FpdGluZ0RyYWdTdGFydGVkID0gZmFsc2UsXG4gIGlnbm9yZU5leHRDbGljayA9IGZhbHNlLFxuICBzb3J0YWJsZXMgPSBbXSxcbiAgdGFwRXZ0LFxuICB0b3VjaEV2dCxcbiAgbGFzdER4LFxuICBsYXN0RHksXG4gIHRhcERpc3RhbmNlTGVmdCxcbiAgdGFwRGlzdGFuY2VUb3AsXG4gIG1vdmVkLFxuICBsYXN0VGFyZ2V0LFxuICBsYXN0RGlyZWN0aW9uLFxuICBwYXN0Rmlyc3RJbnZlcnRUaHJlc2ggPSBmYWxzZSxcbiAgaXNDaXJjdW1zdGFudGlhbEludmVydCA9IGZhbHNlLFxuICB0YXJnZXRNb3ZlRGlzdGFuY2UsXG4gIC8vIEZvciBwb3NpdGlvbmluZyBnaG9zdCBhYnNvbHV0ZWx5XG4gIGdob3N0UmVsYXRpdmVQYXJlbnQsXG4gIGdob3N0UmVsYXRpdmVQYXJlbnRJbml0aWFsU2Nyb2xsID0gW10sXG4gIC8vIChsZWZ0LCB0b3ApXG5cbiAgX3NpbGVudCA9IGZhbHNlLFxuICBzYXZlZElucHV0Q2hlY2tlZCA9IFtdO1xuXG4vKiogQGNvbnN0ICovXG52YXIgZG9jdW1lbnRFeGlzdHMgPSB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnLFxuICBQb3NpdGlvbkdob3N0QWJzb2x1dGVseSA9IElPUyxcbiAgQ1NTRmxvYXRQcm9wZXJ0eSA9IEVkZ2UgfHwgSUUxMU9yTGVzcyA/ICdjc3NGbG9hdCcgOiAnZmxvYXQnLFxuICAvLyBUaGlzIHdpbGwgbm90IHBhc3MgZm9yIElFOSwgYmVjYXVzZSBJRTkgRG5EIG9ubHkgd29ya3Mgb24gYW5jaG9yc1xuICBzdXBwb3J0RHJhZ2dhYmxlID0gZG9jdW1lbnRFeGlzdHMgJiYgIUNocm9tZUZvckFuZHJvaWQgJiYgIUlPUyAmJiAnZHJhZ2dhYmxlJyBpbiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSxcbiAgc3VwcG9ydENzc1BvaW50ZXJFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFkb2N1bWVudEV4aXN0cykgcmV0dXJuO1xuICAgIC8vIGZhbHNlIHdoZW4gPD0gSUUxMVxuICAgIGlmIChJRTExT3JMZXNzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3gnKTtcbiAgICBlbC5zdHlsZS5jc3NUZXh0ID0gJ3BvaW50ZXItZXZlbnRzOmF1dG8nO1xuICAgIHJldHVybiBlbC5zdHlsZS5wb2ludGVyRXZlbnRzID09PSAnYXV0byc7XG4gIH0oKSxcbiAgX2RldGVjdERpcmVjdGlvbiA9IGZ1bmN0aW9uIF9kZXRlY3REaXJlY3Rpb24oZWwsIG9wdGlvbnMpIHtcbiAgICB2YXIgZWxDU1MgPSBjc3MoZWwpLFxuICAgICAgZWxXaWR0aCA9IHBhcnNlSW50KGVsQ1NTLndpZHRoKSAtIHBhcnNlSW50KGVsQ1NTLnBhZGRpbmdMZWZ0KSAtIHBhcnNlSW50KGVsQ1NTLnBhZGRpbmdSaWdodCkgLSBwYXJzZUludChlbENTUy5ib3JkZXJMZWZ0V2lkdGgpIC0gcGFyc2VJbnQoZWxDU1MuYm9yZGVyUmlnaHRXaWR0aCksXG4gICAgICBjaGlsZDEgPSBnZXRDaGlsZChlbCwgMCwgb3B0aW9ucyksXG4gICAgICBjaGlsZDIgPSBnZXRDaGlsZChlbCwgMSwgb3B0aW9ucyksXG4gICAgICBmaXJzdENoaWxkQ1NTID0gY2hpbGQxICYmIGNzcyhjaGlsZDEpLFxuICAgICAgc2Vjb25kQ2hpbGRDU1MgPSBjaGlsZDIgJiYgY3NzKGNoaWxkMiksXG4gICAgICBmaXJzdENoaWxkV2lkdGggPSBmaXJzdENoaWxkQ1NTICYmIHBhcnNlSW50KGZpcnN0Q2hpbGRDU1MubWFyZ2luTGVmdCkgKyBwYXJzZUludChmaXJzdENoaWxkQ1NTLm1hcmdpblJpZ2h0KSArIGdldFJlY3QoY2hpbGQxKS53aWR0aCxcbiAgICAgIHNlY29uZENoaWxkV2lkdGggPSBzZWNvbmRDaGlsZENTUyAmJiBwYXJzZUludChzZWNvbmRDaGlsZENTUy5tYXJnaW5MZWZ0KSArIHBhcnNlSW50KHNlY29uZENoaWxkQ1NTLm1hcmdpblJpZ2h0KSArIGdldFJlY3QoY2hpbGQyKS53aWR0aDtcbiAgICBpZiAoZWxDU1MuZGlzcGxheSA9PT0gJ2ZsZXgnKSB7XG4gICAgICByZXR1cm4gZWxDU1MuZmxleERpcmVjdGlvbiA9PT0gJ2NvbHVtbicgfHwgZWxDU1MuZmxleERpcmVjdGlvbiA9PT0gJ2NvbHVtbi1yZXZlcnNlJyA/ICd2ZXJ0aWNhbCcgOiAnaG9yaXpvbnRhbCc7XG4gICAgfVxuICAgIGlmIChlbENTUy5kaXNwbGF5ID09PSAnZ3JpZCcpIHtcbiAgICAgIHJldHVybiBlbENTUy5ncmlkVGVtcGxhdGVDb2x1bW5zLnNwbGl0KCcgJykubGVuZ3RoIDw9IDEgPyAndmVydGljYWwnIDogJ2hvcml6b250YWwnO1xuICAgIH1cbiAgICBpZiAoY2hpbGQxICYmIGZpcnN0Q2hpbGRDU1NbXCJmbG9hdFwiXSAmJiBmaXJzdENoaWxkQ1NTW1wiZmxvYXRcIl0gIT09ICdub25lJykge1xuICAgICAgdmFyIHRvdWNoaW5nU2lkZUNoaWxkMiA9IGZpcnN0Q2hpbGRDU1NbXCJmbG9hdFwiXSA9PT0gJ2xlZnQnID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgICAgIHJldHVybiBjaGlsZDIgJiYgKHNlY29uZENoaWxkQ1NTLmNsZWFyID09PSAnYm90aCcgfHwgc2Vjb25kQ2hpbGRDU1MuY2xlYXIgPT09IHRvdWNoaW5nU2lkZUNoaWxkMikgPyAndmVydGljYWwnIDogJ2hvcml6b250YWwnO1xuICAgIH1cbiAgICByZXR1cm4gY2hpbGQxICYmIChmaXJzdENoaWxkQ1NTLmRpc3BsYXkgPT09ICdibG9jaycgfHwgZmlyc3RDaGlsZENTUy5kaXNwbGF5ID09PSAnZmxleCcgfHwgZmlyc3RDaGlsZENTUy5kaXNwbGF5ID09PSAndGFibGUnIHx8IGZpcnN0Q2hpbGRDU1MuZGlzcGxheSA9PT0gJ2dyaWQnIHx8IGZpcnN0Q2hpbGRXaWR0aCA+PSBlbFdpZHRoICYmIGVsQ1NTW0NTU0Zsb2F0UHJvcGVydHldID09PSAnbm9uZScgfHwgY2hpbGQyICYmIGVsQ1NTW0NTU0Zsb2F0UHJvcGVydHldID09PSAnbm9uZScgJiYgZmlyc3RDaGlsZFdpZHRoICsgc2Vjb25kQ2hpbGRXaWR0aCA+IGVsV2lkdGgpID8gJ3ZlcnRpY2FsJyA6ICdob3Jpem9udGFsJztcbiAgfSxcbiAgX2RyYWdFbEluUm93Q29sdW1uID0gZnVuY3Rpb24gX2RyYWdFbEluUm93Q29sdW1uKGRyYWdSZWN0LCB0YXJnZXRSZWN0LCB2ZXJ0aWNhbCkge1xuICAgIHZhciBkcmFnRWxTMU9wcCA9IHZlcnRpY2FsID8gZHJhZ1JlY3QubGVmdCA6IGRyYWdSZWN0LnRvcCxcbiAgICAgIGRyYWdFbFMyT3BwID0gdmVydGljYWwgPyBkcmFnUmVjdC5yaWdodCA6IGRyYWdSZWN0LmJvdHRvbSxcbiAgICAgIGRyYWdFbE9wcExlbmd0aCA9IHZlcnRpY2FsID8gZHJhZ1JlY3Qud2lkdGggOiBkcmFnUmVjdC5oZWlnaHQsXG4gICAgICB0YXJnZXRTMU9wcCA9IHZlcnRpY2FsID8gdGFyZ2V0UmVjdC5sZWZ0IDogdGFyZ2V0UmVjdC50b3AsXG4gICAgICB0YXJnZXRTMk9wcCA9IHZlcnRpY2FsID8gdGFyZ2V0UmVjdC5yaWdodCA6IHRhcmdldFJlY3QuYm90dG9tLFxuICAgICAgdGFyZ2V0T3BwTGVuZ3RoID0gdmVydGljYWwgPyB0YXJnZXRSZWN0LndpZHRoIDogdGFyZ2V0UmVjdC5oZWlnaHQ7XG4gICAgcmV0dXJuIGRyYWdFbFMxT3BwID09PSB0YXJnZXRTMU9wcCB8fCBkcmFnRWxTMk9wcCA9PT0gdGFyZ2V0UzJPcHAgfHwgZHJhZ0VsUzFPcHAgKyBkcmFnRWxPcHBMZW5ndGggLyAyID09PSB0YXJnZXRTMU9wcCArIHRhcmdldE9wcExlbmd0aCAvIDI7XG4gIH0sXG4gIC8qKlxyXG4gICAqIERldGVjdHMgZmlyc3QgbmVhcmVzdCBlbXB0eSBzb3J0YWJsZSB0byBYIGFuZCBZIHBvc2l0aW9uIHVzaW5nIGVtcHR5SW5zZXJ0VGhyZXNob2xkLlxyXG4gICAqIEBwYXJhbSAge051bWJlcn0geCAgICAgIFggcG9zaXRpb25cclxuICAgKiBAcGFyYW0gIHtOdW1iZXJ9IHkgICAgICBZIHBvc2l0aW9uXHJcbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR9ICAgRWxlbWVudCBvZiB0aGUgZmlyc3QgZm91bmQgbmVhcmVzdCBTb3J0YWJsZVxyXG4gICAqL1xuICBfZGV0ZWN0TmVhcmVzdEVtcHR5U29ydGFibGUgPSBmdW5jdGlvbiBfZGV0ZWN0TmVhcmVzdEVtcHR5U29ydGFibGUoeCwgeSkge1xuICAgIHZhciByZXQ7XG4gICAgc29ydGFibGVzLnNvbWUoZnVuY3Rpb24gKHNvcnRhYmxlKSB7XG4gICAgICB2YXIgdGhyZXNob2xkID0gc29ydGFibGVbZXhwYW5kb10ub3B0aW9ucy5lbXB0eUluc2VydFRocmVzaG9sZDtcbiAgICAgIGlmICghdGhyZXNob2xkIHx8IGxhc3RDaGlsZChzb3J0YWJsZSkpIHJldHVybjtcbiAgICAgIHZhciByZWN0ID0gZ2V0UmVjdChzb3J0YWJsZSksXG4gICAgICAgIGluc2lkZUhvcml6b250YWxseSA9IHggPj0gcmVjdC5sZWZ0IC0gdGhyZXNob2xkICYmIHggPD0gcmVjdC5yaWdodCArIHRocmVzaG9sZCxcbiAgICAgICAgaW5zaWRlVmVydGljYWxseSA9IHkgPj0gcmVjdC50b3AgLSB0aHJlc2hvbGQgJiYgeSA8PSByZWN0LmJvdHRvbSArIHRocmVzaG9sZDtcbiAgICAgIGlmIChpbnNpZGVIb3Jpem9udGFsbHkgJiYgaW5zaWRlVmVydGljYWxseSkge1xuICAgICAgICByZXR1cm4gcmV0ID0gc29ydGFibGU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJldDtcbiAgfSxcbiAgX3ByZXBhcmVHcm91cCA9IGZ1bmN0aW9uIF9wcmVwYXJlR3JvdXAob3B0aW9ucykge1xuICAgIGZ1bmN0aW9uIHRvRm4odmFsdWUsIHB1bGwpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbiAodG8sIGZyb20sIGRyYWdFbCwgZXZ0KSB7XG4gICAgICAgIHZhciBzYW1lR3JvdXAgPSB0by5vcHRpb25zLmdyb3VwLm5hbWUgJiYgZnJvbS5vcHRpb25zLmdyb3VwLm5hbWUgJiYgdG8ub3B0aW9ucy5ncm91cC5uYW1lID09PSBmcm9tLm9wdGlvbnMuZ3JvdXAubmFtZTtcbiAgICAgICAgaWYgKHZhbHVlID09IG51bGwgJiYgKHB1bGwgfHwgc2FtZUdyb3VwKSkge1xuICAgICAgICAgIC8vIERlZmF1bHQgcHVsbCB2YWx1ZVxuICAgICAgICAgIC8vIERlZmF1bHQgcHVsbCBhbmQgcHV0IHZhbHVlIGlmIHNhbWUgZ3JvdXBcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSBudWxsIHx8IHZhbHVlID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSBlbHNlIGlmIChwdWxsICYmIHZhbHVlID09PSAnY2xvbmUnKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHJldHVybiB0b0ZuKHZhbHVlKHRvLCBmcm9tLCBkcmFnRWwsIGV2dCksIHB1bGwpKHRvLCBmcm9tLCBkcmFnRWwsIGV2dCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIG90aGVyR3JvdXAgPSAocHVsbCA/IHRvIDogZnJvbSkub3B0aW9ucy5ncm91cC5uYW1lO1xuICAgICAgICAgIHJldHVybiB2YWx1ZSA9PT0gdHJ1ZSB8fCB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlID09PSBvdGhlckdyb3VwIHx8IHZhbHVlLmpvaW4gJiYgdmFsdWUuaW5kZXhPZihvdGhlckdyb3VwKSA+IC0xO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cbiAgICB2YXIgZ3JvdXAgPSB7fTtcbiAgICB2YXIgb3JpZ2luYWxHcm91cCA9IG9wdGlvbnMuZ3JvdXA7XG4gICAgaWYgKCFvcmlnaW5hbEdyb3VwIHx8IF90eXBlb2Yob3JpZ2luYWxHcm91cCkgIT0gJ29iamVjdCcpIHtcbiAgICAgIG9yaWdpbmFsR3JvdXAgPSB7XG4gICAgICAgIG5hbWU6IG9yaWdpbmFsR3JvdXBcbiAgICAgIH07XG4gICAgfVxuICAgIGdyb3VwLm5hbWUgPSBvcmlnaW5hbEdyb3VwLm5hbWU7XG4gICAgZ3JvdXAuY2hlY2tQdWxsID0gdG9GbihvcmlnaW5hbEdyb3VwLnB1bGwsIHRydWUpO1xuICAgIGdyb3VwLmNoZWNrUHV0ID0gdG9GbihvcmlnaW5hbEdyb3VwLnB1dCk7XG4gICAgZ3JvdXAucmV2ZXJ0Q2xvbmUgPSBvcmlnaW5hbEdyb3VwLnJldmVydENsb25lO1xuICAgIG9wdGlvbnMuZ3JvdXAgPSBncm91cDtcbiAgfSxcbiAgX2hpZGVHaG9zdEZvclRhcmdldCA9IGZ1bmN0aW9uIF9oaWRlR2hvc3RGb3JUYXJnZXQoKSB7XG4gICAgaWYgKCFzdXBwb3J0Q3NzUG9pbnRlckV2ZW50cyAmJiBnaG9zdEVsKSB7XG4gICAgICBjc3MoZ2hvc3RFbCwgJ2Rpc3BsYXknLCAnbm9uZScpO1xuICAgIH1cbiAgfSxcbiAgX3VuaGlkZUdob3N0Rm9yVGFyZ2V0ID0gZnVuY3Rpb24gX3VuaGlkZUdob3N0Rm9yVGFyZ2V0KCkge1xuICAgIGlmICghc3VwcG9ydENzc1BvaW50ZXJFdmVudHMgJiYgZ2hvc3RFbCkge1xuICAgICAgY3NzKGdob3N0RWwsICdkaXNwbGF5JywgJycpO1xuICAgIH1cbiAgfTtcblxuLy8gIzExODQgZml4IC0gUHJldmVudCBjbGljayBldmVudCBvbiBmYWxsYmFjayBpZiBkcmFnZ2VkIGJ1dCBpdGVtIG5vdCBjaGFuZ2VkIHBvc2l0aW9uXG5pZiAoZG9jdW1lbnRFeGlzdHMgJiYgIUNocm9tZUZvckFuZHJvaWQpIHtcbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgaWYgKGlnbm9yZU5leHRDbGljaykge1xuICAgICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBldnQuc3RvcFByb3BhZ2F0aW9uICYmIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2dC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gJiYgZXZ0LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgaWdub3JlTmV4dENsaWNrID0gZmFsc2U7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9LCB0cnVlKTtcbn1cbnZhciBuZWFyZXN0RW1wdHlJbnNlcnREZXRlY3RFdmVudCA9IGZ1bmN0aW9uIG5lYXJlc3RFbXB0eUluc2VydERldGVjdEV2ZW50KGV2dCkge1xuICBpZiAoZHJhZ0VsKSB7XG4gICAgZXZ0ID0gZXZ0LnRvdWNoZXMgPyBldnQudG91Y2hlc1swXSA6IGV2dDtcbiAgICB2YXIgbmVhcmVzdCA9IF9kZXRlY3ROZWFyZXN0RW1wdHlTb3J0YWJsZShldnQuY2xpZW50WCwgZXZ0LmNsaWVudFkpO1xuICAgIGlmIChuZWFyZXN0KSB7XG4gICAgICAvLyBDcmVhdGUgaW1pdGF0aW9uIGV2ZW50XG4gICAgICB2YXIgZXZlbnQgPSB7fTtcbiAgICAgIGZvciAodmFyIGkgaW4gZXZ0KSB7XG4gICAgICAgIGlmIChldnQuaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgICAgICBldmVudFtpXSA9IGV2dFtpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZXZlbnQudGFyZ2V0ID0gZXZlbnQucm9vdEVsID0gbmVhcmVzdDtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0ID0gdm9pZCAwO1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uID0gdm9pZCAwO1xuICAgICAgbmVhcmVzdFtleHBhbmRvXS5fb25EcmFnT3ZlcihldmVudCk7XG4gICAgfVxuICB9XG59O1xudmFyIF9jaGVja091dHNpZGVUYXJnZXRFbCA9IGZ1bmN0aW9uIF9jaGVja091dHNpZGVUYXJnZXRFbChldnQpIHtcbiAgaWYgKGRyYWdFbCkge1xuICAgIGRyYWdFbC5wYXJlbnROb2RlW2V4cGFuZG9dLl9pc091dHNpZGVUaGlzRWwoZXZ0LnRhcmdldCk7XG4gIH1cbn07XG5cbi8qKlxyXG4gKiBAY2xhc3MgIFNvcnRhYmxlXHJcbiAqIEBwYXJhbSAge0hUTUxFbGVtZW50fSAgZWxcclxuICogQHBhcmFtICB7T2JqZWN0fSAgICAgICBbb3B0aW9uc11cclxuICovXG5mdW5jdGlvbiBTb3J0YWJsZShlbCwgb3B0aW9ucykge1xuICBpZiAoIShlbCAmJiBlbC5ub2RlVHlwZSAmJiBlbC5ub2RlVHlwZSA9PT0gMSkpIHtcbiAgICB0aHJvdyBcIlNvcnRhYmxlOiBgZWxgIG11c3QgYmUgYW4gSFRNTEVsZW1lbnQsIG5vdCBcIi5jb25jYXQoe30udG9TdHJpbmcuY2FsbChlbCkpO1xuICB9XG4gIHRoaXMuZWwgPSBlbDsgLy8gcm9vdCBlbGVtZW50XG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgPSBfZXh0ZW5kcyh7fSwgb3B0aW9ucyk7XG5cbiAgLy8gRXhwb3J0IGluc3RhbmNlXG4gIGVsW2V4cGFuZG9dID0gdGhpcztcbiAgdmFyIGRlZmF1bHRzID0ge1xuICAgIGdyb3VwOiBudWxsLFxuICAgIHNvcnQ6IHRydWUsXG4gICAgZGlzYWJsZWQ6IGZhbHNlLFxuICAgIHN0b3JlOiBudWxsLFxuICAgIGhhbmRsZTogbnVsbCxcbiAgICBkcmFnZ2FibGU6IC9eW3VvXWwkL2kudGVzdChlbC5ub2RlTmFtZSkgPyAnPmxpJyA6ICc+KicsXG4gICAgc3dhcFRocmVzaG9sZDogMSxcbiAgICAvLyBwZXJjZW50YWdlOyAwIDw9IHggPD0gMVxuICAgIGludmVydFN3YXA6IGZhbHNlLFxuICAgIC8vIGludmVydCBhbHdheXNcbiAgICBpbnZlcnRlZFN3YXBUaHJlc2hvbGQ6IG51bGwsXG4gICAgLy8gd2lsbCBiZSBzZXQgdG8gc2FtZSBhcyBzd2FwVGhyZXNob2xkIGlmIGRlZmF1bHRcbiAgICByZW1vdmVDbG9uZU9uSGlkZTogdHJ1ZSxcbiAgICBkaXJlY3Rpb246IGZ1bmN0aW9uIGRpcmVjdGlvbigpIHtcbiAgICAgIHJldHVybiBfZGV0ZWN0RGlyZWN0aW9uKGVsLCB0aGlzLm9wdGlvbnMpO1xuICAgIH0sXG4gICAgZ2hvc3RDbGFzczogJ3NvcnRhYmxlLWdob3N0JyxcbiAgICBjaG9zZW5DbGFzczogJ3NvcnRhYmxlLWNob3NlbicsXG4gICAgZHJhZ0NsYXNzOiAnc29ydGFibGUtZHJhZycsXG4gICAgaWdub3JlOiAnYSwgaW1nJyxcbiAgICBmaWx0ZXI6IG51bGwsXG4gICAgcHJldmVudE9uRmlsdGVyOiB0cnVlLFxuICAgIGFuaW1hdGlvbjogMCxcbiAgICBlYXNpbmc6IG51bGwsXG4gICAgc2V0RGF0YTogZnVuY3Rpb24gc2V0RGF0YShkYXRhVHJhbnNmZXIsIGRyYWdFbCkge1xuICAgICAgZGF0YVRyYW5zZmVyLnNldERhdGEoJ1RleHQnLCBkcmFnRWwudGV4dENvbnRlbnQpO1xuICAgIH0sXG4gICAgZHJvcEJ1YmJsZTogZmFsc2UsXG4gICAgZHJhZ292ZXJCdWJibGU6IGZhbHNlLFxuICAgIGRhdGFJZEF0dHI6ICdkYXRhLWlkJyxcbiAgICBkZWxheTogMCxcbiAgICBkZWxheU9uVG91Y2hPbmx5OiBmYWxzZSxcbiAgICB0b3VjaFN0YXJ0VGhyZXNob2xkOiAoTnVtYmVyLnBhcnNlSW50ID8gTnVtYmVyIDogd2luZG93KS5wYXJzZUludCh3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbywgMTApIHx8IDEsXG4gICAgZm9yY2VGYWxsYmFjazogZmFsc2UsXG4gICAgZmFsbGJhY2tDbGFzczogJ3NvcnRhYmxlLWZhbGxiYWNrJyxcbiAgICBmYWxsYmFja09uQm9keTogZmFsc2UsXG4gICAgZmFsbGJhY2tUb2xlcmFuY2U6IDAsXG4gICAgZmFsbGJhY2tPZmZzZXQ6IHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiAwXG4gICAgfSxcbiAgICAvLyBEaXNhYmxlZCBvbiBTYWZhcmk6ICMxNTcxOyBFbmFibGVkIG9uIFNhZmFyaSBJT1M6ICMyMjQ0XG4gICAgc3VwcG9ydFBvaW50ZXI6IFNvcnRhYmxlLnN1cHBvcnRQb2ludGVyICE9PSBmYWxzZSAmJiAnUG9pbnRlckV2ZW50JyBpbiB3aW5kb3cgJiYgKCFTYWZhcmkgfHwgSU9TKSxcbiAgICBlbXB0eUluc2VydFRocmVzaG9sZDogNVxuICB9O1xuICBQbHVnaW5NYW5hZ2VyLmluaXRpYWxpemVQbHVnaW5zKHRoaXMsIGVsLCBkZWZhdWx0cyk7XG5cbiAgLy8gU2V0IGRlZmF1bHQgb3B0aW9uc1xuICBmb3IgKHZhciBuYW1lIGluIGRlZmF1bHRzKSB7XG4gICAgIShuYW1lIGluIG9wdGlvbnMpICYmIChvcHRpb25zW25hbWVdID0gZGVmYXVsdHNbbmFtZV0pO1xuICB9XG4gIF9wcmVwYXJlR3JvdXAob3B0aW9ucyk7XG5cbiAgLy8gQmluZCBhbGwgcHJpdmF0ZSBtZXRob2RzXG4gIGZvciAodmFyIGZuIGluIHRoaXMpIHtcbiAgICBpZiAoZm4uY2hhckF0KDApID09PSAnXycgJiYgdHlwZW9mIHRoaXNbZm5dID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzW2ZuXSA9IHRoaXNbZm5dLmJpbmQodGhpcyk7XG4gICAgfVxuICB9XG5cbiAgLy8gU2V0dXAgZHJhZyBtb2RlXG4gIHRoaXMubmF0aXZlRHJhZ2dhYmxlID0gb3B0aW9ucy5mb3JjZUZhbGxiYWNrID8gZmFsc2UgOiBzdXBwb3J0RHJhZ2dhYmxlO1xuICBpZiAodGhpcy5uYXRpdmVEcmFnZ2FibGUpIHtcbiAgICAvLyBUb3VjaCBzdGFydCB0aHJlc2hvbGQgY2Fubm90IGJlIGdyZWF0ZXIgdGhhbiB0aGUgbmF0aXZlIGRyYWdzdGFydCB0aHJlc2hvbGRcbiAgICB0aGlzLm9wdGlvbnMudG91Y2hTdGFydFRocmVzaG9sZCA9IDE7XG4gIH1cblxuICAvLyBCaW5kIGV2ZW50c1xuICBpZiAob3B0aW9ucy5zdXBwb3J0UG9pbnRlcikge1xuICAgIG9uKGVsLCAncG9pbnRlcmRvd24nLCB0aGlzLl9vblRhcFN0YXJ0KTtcbiAgfSBlbHNlIHtcbiAgICBvbihlbCwgJ21vdXNlZG93bicsIHRoaXMuX29uVGFwU3RhcnQpO1xuICAgIG9uKGVsLCAndG91Y2hzdGFydCcsIHRoaXMuX29uVGFwU3RhcnQpO1xuICB9XG4gIGlmICh0aGlzLm5hdGl2ZURyYWdnYWJsZSkge1xuICAgIG9uKGVsLCAnZHJhZ292ZXInLCB0aGlzKTtcbiAgICBvbihlbCwgJ2RyYWdlbnRlcicsIHRoaXMpO1xuICB9XG4gIHNvcnRhYmxlcy5wdXNoKHRoaXMuZWwpO1xuXG4gIC8vIFJlc3RvcmUgc29ydGluZ1xuICBvcHRpb25zLnN0b3JlICYmIG9wdGlvbnMuc3RvcmUuZ2V0ICYmIHRoaXMuc29ydChvcHRpb25zLnN0b3JlLmdldCh0aGlzKSB8fCBbXSk7XG5cbiAgLy8gQWRkIGFuaW1hdGlvbiBzdGF0ZSBtYW5hZ2VyXG4gIF9leHRlbmRzKHRoaXMsIEFuaW1hdGlvblN0YXRlTWFuYWdlcigpKTtcbn1cblNvcnRhYmxlLnByb3RvdHlwZSA9IC8qKiBAbGVuZHMgU29ydGFibGUucHJvdG90eXBlICove1xuICBjb25zdHJ1Y3RvcjogU29ydGFibGUsXG4gIF9pc091dHNpZGVUaGlzRWw6IGZ1bmN0aW9uIF9pc091dHNpZGVUaGlzRWwodGFyZ2V0KSB7XG4gICAgaWYgKCF0aGlzLmVsLmNvbnRhaW5zKHRhcmdldCkgJiYgdGFyZ2V0ICE9PSB0aGlzLmVsKSB7XG4gICAgICBsYXN0VGFyZ2V0ID0gbnVsbDtcbiAgICB9XG4gIH0sXG4gIF9nZXREaXJlY3Rpb246IGZ1bmN0aW9uIF9nZXREaXJlY3Rpb24oZXZ0LCB0YXJnZXQpIHtcbiAgICByZXR1cm4gdHlwZW9mIHRoaXMub3B0aW9ucy5kaXJlY3Rpb24gPT09ICdmdW5jdGlvbicgPyB0aGlzLm9wdGlvbnMuZGlyZWN0aW9uLmNhbGwodGhpcywgZXZ0LCB0YXJnZXQsIGRyYWdFbCkgOiB0aGlzLm9wdGlvbnMuZGlyZWN0aW9uO1xuICB9LFxuICBfb25UYXBTdGFydDogZnVuY3Rpb24gX29uVGFwU3RhcnQoIC8qKiBFdmVudHxUb3VjaEV2ZW50ICovZXZ0KSB7XG4gICAgaWYgKCFldnQuY2FuY2VsYWJsZSkgcmV0dXJuO1xuICAgIHZhciBfdGhpcyA9IHRoaXMsXG4gICAgICBlbCA9IHRoaXMuZWwsXG4gICAgICBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuICAgICAgcHJldmVudE9uRmlsdGVyID0gb3B0aW9ucy5wcmV2ZW50T25GaWx0ZXIsXG4gICAgICB0eXBlID0gZXZ0LnR5cGUsXG4gICAgICB0b3VjaCA9IGV2dC50b3VjaGVzICYmIGV2dC50b3VjaGVzWzBdIHx8IGV2dC5wb2ludGVyVHlwZSAmJiBldnQucG9pbnRlclR5cGUgPT09ICd0b3VjaCcgJiYgZXZ0LFxuICAgICAgdGFyZ2V0ID0gKHRvdWNoIHx8IGV2dCkudGFyZ2V0LFxuICAgICAgb3JpZ2luYWxUYXJnZXQgPSBldnQudGFyZ2V0LnNoYWRvd1Jvb3QgJiYgKGV2dC5wYXRoICYmIGV2dC5wYXRoWzBdIHx8IGV2dC5jb21wb3NlZFBhdGggJiYgZXZ0LmNvbXBvc2VkUGF0aCgpWzBdKSB8fCB0YXJnZXQsXG4gICAgICBmaWx0ZXIgPSBvcHRpb25zLmZpbHRlcjtcbiAgICBfc2F2ZUlucHV0Q2hlY2tlZFN0YXRlKGVsKTtcblxuICAgIC8vIERvbid0IHRyaWdnZXIgc3RhcnQgZXZlbnQgd2hlbiBhbiBlbGVtZW50IGlzIGJlZW4gZHJhZ2dlZCwgb3RoZXJ3aXNlIHRoZSBldnQub2xkaW5kZXggYWx3YXlzIHdyb25nIHdoZW4gc2V0IG9wdGlvbi5ncm91cC5cbiAgICBpZiAoZHJhZ0VsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICgvbW91c2Vkb3dufHBvaW50ZXJkb3duLy50ZXN0KHR5cGUpICYmIGV2dC5idXR0b24gIT09IDAgfHwgb3B0aW9ucy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuOyAvLyBvbmx5IGxlZnQgYnV0dG9uIGFuZCBlbmFibGVkXG4gICAgfVxuXG4gICAgLy8gY2FuY2VsIGRuZCBpZiBvcmlnaW5hbCB0YXJnZXQgaXMgY29udGVudCBlZGl0YWJsZVxuICAgIGlmIChvcmlnaW5hbFRhcmdldC5pc0NvbnRlbnRFZGl0YWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNhZmFyaSBpZ25vcmVzIGZ1cnRoZXIgZXZlbnQgaGFuZGxpbmcgYWZ0ZXIgbW91c2Vkb3duXG4gICAgaWYgKCF0aGlzLm5hdGl2ZURyYWdnYWJsZSAmJiBTYWZhcmkgJiYgdGFyZ2V0ICYmIHRhcmdldC50YWdOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICdTRUxFQ1QnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRhcmdldCA9IGNsb3Nlc3QodGFyZ2V0LCBvcHRpb25zLmRyYWdnYWJsZSwgZWwsIGZhbHNlKTtcbiAgICBpZiAodGFyZ2V0ICYmIHRhcmdldC5hbmltYXRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAobGFzdERvd25FbCA9PT0gdGFyZ2V0KSB7XG4gICAgICAvLyBJZ25vcmluZyBkdXBsaWNhdGUgYGRvd25gXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gR2V0IHRoZSBpbmRleCBvZiB0aGUgZHJhZ2dlZCBlbGVtZW50IHdpdGhpbiBpdHMgcGFyZW50XG4gICAgb2xkSW5kZXggPSBpbmRleCh0YXJnZXQpO1xuICAgIG9sZERyYWdnYWJsZUluZGV4ID0gaW5kZXgodGFyZ2V0LCBvcHRpb25zLmRyYWdnYWJsZSk7XG5cbiAgICAvLyBDaGVjayBmaWx0ZXJcbiAgICBpZiAodHlwZW9mIGZpbHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKGZpbHRlci5jYWxsKHRoaXMsIGV2dCwgdGFyZ2V0LCB0aGlzKSkge1xuICAgICAgICBfZGlzcGF0Y2hFdmVudCh7XG4gICAgICAgICAgc29ydGFibGU6IF90aGlzLFxuICAgICAgICAgIHJvb3RFbDogb3JpZ2luYWxUYXJnZXQsXG4gICAgICAgICAgbmFtZTogJ2ZpbHRlcicsXG4gICAgICAgICAgdGFyZ2V0RWw6IHRhcmdldCxcbiAgICAgICAgICB0b0VsOiBlbCxcbiAgICAgICAgICBmcm9tRWw6IGVsXG4gICAgICAgIH0pO1xuICAgICAgICBwbHVnaW5FdmVudCgnZmlsdGVyJywgX3RoaXMsIHtcbiAgICAgICAgICBldnQ6IGV2dFxuICAgICAgICB9KTtcbiAgICAgICAgcHJldmVudE9uRmlsdGVyICYmIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByZXR1cm47IC8vIGNhbmNlbCBkbmRcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGZpbHRlcikge1xuICAgICAgZmlsdGVyID0gZmlsdGVyLnNwbGl0KCcsJykuc29tZShmdW5jdGlvbiAoY3JpdGVyaWEpIHtcbiAgICAgICAgY3JpdGVyaWEgPSBjbG9zZXN0KG9yaWdpbmFsVGFyZ2V0LCBjcml0ZXJpYS50cmltKCksIGVsLCBmYWxzZSk7XG4gICAgICAgIGlmIChjcml0ZXJpYSkge1xuICAgICAgICAgIF9kaXNwYXRjaEV2ZW50KHtcbiAgICAgICAgICAgIHNvcnRhYmxlOiBfdGhpcyxcbiAgICAgICAgICAgIHJvb3RFbDogY3JpdGVyaWEsXG4gICAgICAgICAgICBuYW1lOiAnZmlsdGVyJyxcbiAgICAgICAgICAgIHRhcmdldEVsOiB0YXJnZXQsXG4gICAgICAgICAgICBmcm9tRWw6IGVsLFxuICAgICAgICAgICAgdG9FbDogZWxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwbHVnaW5FdmVudCgnZmlsdGVyJywgX3RoaXMsIHtcbiAgICAgICAgICAgIGV2dDogZXZ0XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKGZpbHRlcikge1xuICAgICAgICBwcmV2ZW50T25GaWx0ZXIgJiYgZXZ0LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybjsgLy8gY2FuY2VsIGRuZFxuICAgICAgfVxuICAgIH1cbiAgICBpZiAob3B0aW9ucy5oYW5kbGUgJiYgIWNsb3Nlc3Qob3JpZ2luYWxUYXJnZXQsIG9wdGlvbnMuaGFuZGxlLCBlbCwgZmFsc2UpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUHJlcGFyZSBgZHJhZ3N0YXJ0YFxuICAgIHRoaXMuX3ByZXBhcmVEcmFnU3RhcnQoZXZ0LCB0b3VjaCwgdGFyZ2V0KTtcbiAgfSxcbiAgX3ByZXBhcmVEcmFnU3RhcnQ6IGZ1bmN0aW9uIF9wcmVwYXJlRHJhZ1N0YXJ0KCAvKiogRXZlbnQgKi9ldnQsIC8qKiBUb3VjaCAqL3RvdWNoLCAvKiogSFRNTEVsZW1lbnQgKi90YXJnZXQpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzLFxuICAgICAgZWwgPSBfdGhpcy5lbCxcbiAgICAgIG9wdGlvbnMgPSBfdGhpcy5vcHRpb25zLFxuICAgICAgb3duZXJEb2N1bWVudCA9IGVsLm93bmVyRG9jdW1lbnQsXG4gICAgICBkcmFnU3RhcnRGbjtcbiAgICBpZiAodGFyZ2V0ICYmICFkcmFnRWwgJiYgdGFyZ2V0LnBhcmVudE5vZGUgPT09IGVsKSB7XG4gICAgICB2YXIgZHJhZ1JlY3QgPSBnZXRSZWN0KHRhcmdldCk7XG4gICAgICByb290RWwgPSBlbDtcbiAgICAgIGRyYWdFbCA9IHRhcmdldDtcbiAgICAgIHBhcmVudEVsID0gZHJhZ0VsLnBhcmVudE5vZGU7XG4gICAgICBuZXh0RWwgPSBkcmFnRWwubmV4dFNpYmxpbmc7XG4gICAgICBsYXN0RG93bkVsID0gdGFyZ2V0O1xuICAgICAgYWN0aXZlR3JvdXAgPSBvcHRpb25zLmdyb3VwO1xuICAgICAgU29ydGFibGUuZHJhZ2dlZCA9IGRyYWdFbDtcbiAgICAgIHRhcEV2dCA9IHtcbiAgICAgICAgdGFyZ2V0OiBkcmFnRWwsXG4gICAgICAgIGNsaWVudFg6ICh0b3VjaCB8fCBldnQpLmNsaWVudFgsXG4gICAgICAgIGNsaWVudFk6ICh0b3VjaCB8fCBldnQpLmNsaWVudFlcbiAgICAgIH07XG4gICAgICB0YXBEaXN0YW5jZUxlZnQgPSB0YXBFdnQuY2xpZW50WCAtIGRyYWdSZWN0LmxlZnQ7XG4gICAgICB0YXBEaXN0YW5jZVRvcCA9IHRhcEV2dC5jbGllbnRZIC0gZHJhZ1JlY3QudG9wO1xuICAgICAgdGhpcy5fbGFzdFggPSAodG91Y2ggfHwgZXZ0KS5jbGllbnRYO1xuICAgICAgdGhpcy5fbGFzdFkgPSAodG91Y2ggfHwgZXZ0KS5jbGllbnRZO1xuICAgICAgZHJhZ0VsLnN0eWxlWyd3aWxsLWNoYW5nZSddID0gJ2FsbCc7XG4gICAgICBkcmFnU3RhcnRGbiA9IGZ1bmN0aW9uIGRyYWdTdGFydEZuKCkge1xuICAgICAgICBwbHVnaW5FdmVudCgnZGVsYXlFbmRlZCcsIF90aGlzLCB7XG4gICAgICAgICAgZXZ0OiBldnRcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChTb3J0YWJsZS5ldmVudENhbmNlbGVkKSB7XG4gICAgICAgICAgX3RoaXMuX29uRHJvcCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBEZWxheWVkIGRyYWcgaGFzIGJlZW4gdHJpZ2dlcmVkXG4gICAgICAgIC8vIHdlIGNhbiByZS1lbmFibGUgdGhlIGV2ZW50czogdG91Y2htb3ZlL21vdXNlbW92ZVxuICAgICAgICBfdGhpcy5fZGlzYWJsZURlbGF5ZWREcmFnRXZlbnRzKCk7XG4gICAgICAgIGlmICghRmlyZUZveCAmJiBfdGhpcy5uYXRpdmVEcmFnZ2FibGUpIHtcbiAgICAgICAgICBkcmFnRWwuZHJhZ2dhYmxlID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJpbmQgdGhlIGV2ZW50czogZHJhZ3N0YXJ0L2RyYWdlbmRcbiAgICAgICAgX3RoaXMuX3RyaWdnZXJEcmFnU3RhcnQoZXZ0LCB0b3VjaCk7XG5cbiAgICAgICAgLy8gRHJhZyBzdGFydCBldmVudFxuICAgICAgICBfZGlzcGF0Y2hFdmVudCh7XG4gICAgICAgICAgc29ydGFibGU6IF90aGlzLFxuICAgICAgICAgIG5hbWU6ICdjaG9vc2UnLFxuICAgICAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2dFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDaG9zZW4gaXRlbVxuICAgICAgICB0b2dnbGVDbGFzcyhkcmFnRWwsIG9wdGlvbnMuY2hvc2VuQ2xhc3MsIHRydWUpO1xuICAgICAgfTtcblxuICAgICAgLy8gRGlzYWJsZSBcImRyYWdnYWJsZVwiXG4gICAgICBvcHRpb25zLmlnbm9yZS5zcGxpdCgnLCcpLmZvckVhY2goZnVuY3Rpb24gKGNyaXRlcmlhKSB7XG4gICAgICAgIGZpbmQoZHJhZ0VsLCBjcml0ZXJpYS50cmltKCksIF9kaXNhYmxlRHJhZ2dhYmxlKTtcbiAgICAgIH0pO1xuICAgICAgb24ob3duZXJEb2N1bWVudCwgJ2RyYWdvdmVyJywgbmVhcmVzdEVtcHR5SW5zZXJ0RGV0ZWN0RXZlbnQpO1xuICAgICAgb24ob3duZXJEb2N1bWVudCwgJ21vdXNlbW92ZScsIG5lYXJlc3RFbXB0eUluc2VydERldGVjdEV2ZW50KTtcbiAgICAgIG9uKG93bmVyRG9jdW1lbnQsICd0b3VjaG1vdmUnLCBuZWFyZXN0RW1wdHlJbnNlcnREZXRlY3RFdmVudCk7XG4gICAgICBpZiAob3B0aW9ucy5zdXBwb3J0UG9pbnRlcikge1xuICAgICAgICBvbihvd25lckRvY3VtZW50LCAncG9pbnRlcnVwJywgX3RoaXMuX29uRHJvcCk7XG4gICAgICAgIC8vIE5hdGl2ZSBEJkQgdHJpZ2dlcnMgcG9pbnRlcmNhbmNlbFxuICAgICAgICAhdGhpcy5uYXRpdmVEcmFnZ2FibGUgJiYgb24ob3duZXJEb2N1bWVudCwgJ3BvaW50ZXJjYW5jZWwnLCBfdGhpcy5fb25Ecm9wKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9uKG93bmVyRG9jdW1lbnQsICdtb3VzZXVwJywgX3RoaXMuX29uRHJvcCk7XG4gICAgICAgIG9uKG93bmVyRG9jdW1lbnQsICd0b3VjaGVuZCcsIF90aGlzLl9vbkRyb3ApO1xuICAgICAgICBvbihvd25lckRvY3VtZW50LCAndG91Y2hjYW5jZWwnLCBfdGhpcy5fb25Ecm9wKTtcbiAgICAgIH1cblxuICAgICAgLy8gTWFrZSBkcmFnRWwgZHJhZ2dhYmxlIChtdXN0IGJlIGJlZm9yZSBkZWxheSBmb3IgRmlyZUZveClcbiAgICAgIGlmIChGaXJlRm94ICYmIHRoaXMubmF0aXZlRHJhZ2dhYmxlKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucy50b3VjaFN0YXJ0VGhyZXNob2xkID0gNDtcbiAgICAgICAgZHJhZ0VsLmRyYWdnYWJsZSA9IHRydWU7XG4gICAgICB9XG4gICAgICBwbHVnaW5FdmVudCgnZGVsYXlTdGFydCcsIHRoaXMsIHtcbiAgICAgICAgZXZ0OiBldnRcbiAgICAgIH0pO1xuXG4gICAgICAvLyBEZWxheSBpcyBpbXBvc3NpYmxlIGZvciBuYXRpdmUgRG5EIGluIEVkZ2Ugb3IgSUVcbiAgICAgIGlmIChvcHRpb25zLmRlbGF5ICYmICghb3B0aW9ucy5kZWxheU9uVG91Y2hPbmx5IHx8IHRvdWNoKSAmJiAoIXRoaXMubmF0aXZlRHJhZ2dhYmxlIHx8ICEoRWRnZSB8fCBJRTExT3JMZXNzKSkpIHtcbiAgICAgICAgaWYgKFNvcnRhYmxlLmV2ZW50Q2FuY2VsZWQpIHtcbiAgICAgICAgICB0aGlzLl9vbkRyb3AoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgdGhlIHVzZXIgbW92ZXMgdGhlIHBvaW50ZXIgb3IgbGV0IGdvIHRoZSBjbGljayBvciB0b3VjaFxuICAgICAgICAvLyBiZWZvcmUgdGhlIGRlbGF5IGhhcyBiZWVuIHJlYWNoZWQ6XG4gICAgICAgIC8vIGRpc2FibGUgdGhlIGRlbGF5ZWQgZHJhZ1xuICAgICAgICBpZiAob3B0aW9ucy5zdXBwb3J0UG9pbnRlcikge1xuICAgICAgICAgIG9uKG93bmVyRG9jdW1lbnQsICdwb2ludGVydXAnLCBfdGhpcy5fZGlzYWJsZURlbGF5ZWREcmFnKTtcbiAgICAgICAgICBvbihvd25lckRvY3VtZW50LCAncG9pbnRlcmNhbmNlbCcsIF90aGlzLl9kaXNhYmxlRGVsYXllZERyYWcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9uKG93bmVyRG9jdW1lbnQsICdtb3VzZXVwJywgX3RoaXMuX2Rpc2FibGVEZWxheWVkRHJhZyk7XG4gICAgICAgICAgb24ob3duZXJEb2N1bWVudCwgJ3RvdWNoZW5kJywgX3RoaXMuX2Rpc2FibGVEZWxheWVkRHJhZyk7XG4gICAgICAgICAgb24ob3duZXJEb2N1bWVudCwgJ3RvdWNoY2FuY2VsJywgX3RoaXMuX2Rpc2FibGVEZWxheWVkRHJhZyk7XG4gICAgICAgIH1cbiAgICAgICAgb24ob3duZXJEb2N1bWVudCwgJ21vdXNlbW92ZScsIF90aGlzLl9kZWxheWVkRHJhZ1RvdWNoTW92ZUhhbmRsZXIpO1xuICAgICAgICBvbihvd25lckRvY3VtZW50LCAndG91Y2htb3ZlJywgX3RoaXMuX2RlbGF5ZWREcmFnVG91Y2hNb3ZlSGFuZGxlcik7XG4gICAgICAgIG9wdGlvbnMuc3VwcG9ydFBvaW50ZXIgJiYgb24ob3duZXJEb2N1bWVudCwgJ3BvaW50ZXJtb3ZlJywgX3RoaXMuX2RlbGF5ZWREcmFnVG91Y2hNb3ZlSGFuZGxlcik7XG4gICAgICAgIF90aGlzLl9kcmFnU3RhcnRUaW1lciA9IHNldFRpbWVvdXQoZHJhZ1N0YXJ0Rm4sIG9wdGlvbnMuZGVsYXkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZHJhZ1N0YXJ0Rm4oKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIF9kZWxheWVkRHJhZ1RvdWNoTW92ZUhhbmRsZXI6IGZ1bmN0aW9uIF9kZWxheWVkRHJhZ1RvdWNoTW92ZUhhbmRsZXIoIC8qKiBUb3VjaEV2ZW50fFBvaW50ZXJFdmVudCAqKi9lKSB7XG4gICAgdmFyIHRvdWNoID0gZS50b3VjaGVzID8gZS50b3VjaGVzWzBdIDogZTtcbiAgICBpZiAoTWF0aC5tYXgoTWF0aC5hYnModG91Y2guY2xpZW50WCAtIHRoaXMuX2xhc3RYKSwgTWF0aC5hYnModG91Y2guY2xpZW50WSAtIHRoaXMuX2xhc3RZKSkgPj0gTWF0aC5mbG9vcih0aGlzLm9wdGlvbnMudG91Y2hTdGFydFRocmVzaG9sZCAvICh0aGlzLm5hdGl2ZURyYWdnYWJsZSAmJiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyB8fCAxKSkpIHtcbiAgICAgIHRoaXMuX2Rpc2FibGVEZWxheWVkRHJhZygpO1xuICAgIH1cbiAgfSxcbiAgX2Rpc2FibGVEZWxheWVkRHJhZzogZnVuY3Rpb24gX2Rpc2FibGVEZWxheWVkRHJhZygpIHtcbiAgICBkcmFnRWwgJiYgX2Rpc2FibGVEcmFnZ2FibGUoZHJhZ0VsKTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5fZHJhZ1N0YXJ0VGltZXIpO1xuICAgIHRoaXMuX2Rpc2FibGVEZWxheWVkRHJhZ0V2ZW50cygpO1xuICB9LFxuICBfZGlzYWJsZURlbGF5ZWREcmFnRXZlbnRzOiBmdW5jdGlvbiBfZGlzYWJsZURlbGF5ZWREcmFnRXZlbnRzKCkge1xuICAgIHZhciBvd25lckRvY3VtZW50ID0gdGhpcy5lbC5vd25lckRvY3VtZW50O1xuICAgIG9mZihvd25lckRvY3VtZW50LCAnbW91c2V1cCcsIHRoaXMuX2Rpc2FibGVEZWxheWVkRHJhZyk7XG4gICAgb2ZmKG93bmVyRG9jdW1lbnQsICd0b3VjaGVuZCcsIHRoaXMuX2Rpc2FibGVEZWxheWVkRHJhZyk7XG4gICAgb2ZmKG93bmVyRG9jdW1lbnQsICd0b3VjaGNhbmNlbCcsIHRoaXMuX2Rpc2FibGVEZWxheWVkRHJhZyk7XG4gICAgb2ZmKG93bmVyRG9jdW1lbnQsICdwb2ludGVydXAnLCB0aGlzLl9kaXNhYmxlRGVsYXllZERyYWcpO1xuICAgIG9mZihvd25lckRvY3VtZW50LCAncG9pbnRlcmNhbmNlbCcsIHRoaXMuX2Rpc2FibGVEZWxheWVkRHJhZyk7XG4gICAgb2ZmKG93bmVyRG9jdW1lbnQsICdtb3VzZW1vdmUnLCB0aGlzLl9kZWxheWVkRHJhZ1RvdWNoTW92ZUhhbmRsZXIpO1xuICAgIG9mZihvd25lckRvY3VtZW50LCAndG91Y2htb3ZlJywgdGhpcy5fZGVsYXllZERyYWdUb3VjaE1vdmVIYW5kbGVyKTtcbiAgICBvZmYob3duZXJEb2N1bWVudCwgJ3BvaW50ZXJtb3ZlJywgdGhpcy5fZGVsYXllZERyYWdUb3VjaE1vdmVIYW5kbGVyKTtcbiAgfSxcbiAgX3RyaWdnZXJEcmFnU3RhcnQ6IGZ1bmN0aW9uIF90cmlnZ2VyRHJhZ1N0YXJ0KCAvKiogRXZlbnQgKi9ldnQsIC8qKiBUb3VjaCAqL3RvdWNoKSB7XG4gICAgdG91Y2ggPSB0b3VjaCB8fCBldnQucG9pbnRlclR5cGUgPT0gJ3RvdWNoJyAmJiBldnQ7XG4gICAgaWYgKCF0aGlzLm5hdGl2ZURyYWdnYWJsZSB8fCB0b3VjaCkge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5zdXBwb3J0UG9pbnRlcikge1xuICAgICAgICBvbihkb2N1bWVudCwgJ3BvaW50ZXJtb3ZlJywgdGhpcy5fb25Ub3VjaE1vdmUpO1xuICAgICAgfSBlbHNlIGlmICh0b3VjaCkge1xuICAgICAgICBvbihkb2N1bWVudCwgJ3RvdWNobW92ZScsIHRoaXMuX29uVG91Y2hNb3ZlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9uKGRvY3VtZW50LCAnbW91c2Vtb3ZlJywgdGhpcy5fb25Ub3VjaE1vdmUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvbihkcmFnRWwsICdkcmFnZW5kJywgdGhpcyk7XG4gICAgICBvbihyb290RWwsICdkcmFnc3RhcnQnLCB0aGlzLl9vbkRyYWdTdGFydCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBpZiAoZG9jdW1lbnQuc2VsZWN0aW9uKSB7XG4gICAgICAgIF9uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZG9jdW1lbnQuc2VsZWN0aW9uLmVtcHR5KCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2luZG93LmdldFNlbGVjdGlvbigpLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge31cbiAgfSxcbiAgX2RyYWdTdGFydGVkOiBmdW5jdGlvbiBfZHJhZ1N0YXJ0ZWQoZmFsbGJhY2ssIGV2dCkge1xuICAgIGF3YWl0aW5nRHJhZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICBpZiAocm9vdEVsICYmIGRyYWdFbCkge1xuICAgICAgcGx1Z2luRXZlbnQoJ2RyYWdTdGFydGVkJywgdGhpcywge1xuICAgICAgICBldnQ6IGV2dFxuICAgICAgfSk7XG4gICAgICBpZiAodGhpcy5uYXRpdmVEcmFnZ2FibGUpIHtcbiAgICAgICAgb24oZG9jdW1lbnQsICdkcmFnb3ZlcicsIF9jaGVja091dHNpZGVUYXJnZXRFbCk7XG4gICAgICB9XG4gICAgICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcblxuICAgICAgLy8gQXBwbHkgZWZmZWN0XG4gICAgICAhZmFsbGJhY2sgJiYgdG9nZ2xlQ2xhc3MoZHJhZ0VsLCBvcHRpb25zLmRyYWdDbGFzcywgZmFsc2UpO1xuICAgICAgdG9nZ2xlQ2xhc3MoZHJhZ0VsLCBvcHRpb25zLmdob3N0Q2xhc3MsIHRydWUpO1xuICAgICAgU29ydGFibGUuYWN0aXZlID0gdGhpcztcbiAgICAgIGZhbGxiYWNrICYmIHRoaXMuX2FwcGVuZEdob3N0KCk7XG5cbiAgICAgIC8vIERyYWcgc3RhcnQgZXZlbnRcbiAgICAgIF9kaXNwYXRjaEV2ZW50KHtcbiAgICAgICAgc29ydGFibGU6IHRoaXMsXG4gICAgICAgIG5hbWU6ICdzdGFydCcsXG4gICAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2dFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX251bGxpbmcoKTtcbiAgICB9XG4gIH0sXG4gIF9lbXVsYXRlRHJhZ092ZXI6IGZ1bmN0aW9uIF9lbXVsYXRlRHJhZ092ZXIoKSB7XG4gICAgaWYgKHRvdWNoRXZ0KSB7XG4gICAgICB0aGlzLl9sYXN0WCA9IHRvdWNoRXZ0LmNsaWVudFg7XG4gICAgICB0aGlzLl9sYXN0WSA9IHRvdWNoRXZ0LmNsaWVudFk7XG4gICAgICBfaGlkZUdob3N0Rm9yVGFyZ2V0KCk7XG4gICAgICB2YXIgdGFyZ2V0ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludCh0b3VjaEV2dC5jbGllbnRYLCB0b3VjaEV2dC5jbGllbnRZKTtcbiAgICAgIHZhciBwYXJlbnQgPSB0YXJnZXQ7XG4gICAgICB3aGlsZSAodGFyZ2V0ICYmIHRhcmdldC5zaGFkb3dSb290KSB7XG4gICAgICAgIHRhcmdldCA9IHRhcmdldC5zaGFkb3dSb290LmVsZW1lbnRGcm9tUG9pbnQodG91Y2hFdnQuY2xpZW50WCwgdG91Y2hFdnQuY2xpZW50WSk7XG4gICAgICAgIGlmICh0YXJnZXQgPT09IHBhcmVudCkgYnJlYWs7XG4gICAgICAgIHBhcmVudCA9IHRhcmdldDtcbiAgICAgIH1cbiAgICAgIGRyYWdFbC5wYXJlbnROb2RlW2V4cGFuZG9dLl9pc091dHNpZGVUaGlzRWwodGFyZ2V0KTtcbiAgICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgZG8ge1xuICAgICAgICAgIGlmIChwYXJlbnRbZXhwYW5kb10pIHtcbiAgICAgICAgICAgIHZhciBpbnNlcnRlZCA9IHZvaWQgMDtcbiAgICAgICAgICAgIGluc2VydGVkID0gcGFyZW50W2V4cGFuZG9dLl9vbkRyYWdPdmVyKHtcbiAgICAgICAgICAgICAgY2xpZW50WDogdG91Y2hFdnQuY2xpZW50WCxcbiAgICAgICAgICAgICAgY2xpZW50WTogdG91Y2hFdnQuY2xpZW50WSxcbiAgICAgICAgICAgICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgICAgICAgICAgIHJvb3RFbDogcGFyZW50XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChpbnNlcnRlZCAmJiAhdGhpcy5vcHRpb25zLmRyYWdvdmVyQnViYmxlKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICB0YXJnZXQgPSBwYXJlbnQ7IC8vIHN0b3JlIGxhc3QgZWxlbWVudFxuICAgICAgICB9XG4gICAgICAgIC8qIGpzaGludCBib3NzOnRydWUgKi8gd2hpbGUgKHBhcmVudCA9IGdldFBhcmVudE9ySG9zdChwYXJlbnQpKTtcbiAgICAgIH1cbiAgICAgIF91bmhpZGVHaG9zdEZvclRhcmdldCgpO1xuICAgIH1cbiAgfSxcbiAgX29uVG91Y2hNb3ZlOiBmdW5jdGlvbiBfb25Ub3VjaE1vdmUoIC8qKlRvdWNoRXZlbnQqL2V2dCkge1xuICAgIGlmICh0YXBFdnQpIHtcbiAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuICAgICAgICBmYWxsYmFja1RvbGVyYW5jZSA9IG9wdGlvbnMuZmFsbGJhY2tUb2xlcmFuY2UsXG4gICAgICAgIGZhbGxiYWNrT2Zmc2V0ID0gb3B0aW9ucy5mYWxsYmFja09mZnNldCxcbiAgICAgICAgdG91Y2ggPSBldnQudG91Y2hlcyA/IGV2dC50b3VjaGVzWzBdIDogZXZ0LFxuICAgICAgICBnaG9zdE1hdHJpeCA9IGdob3N0RWwgJiYgbWF0cml4KGdob3N0RWwsIHRydWUpLFxuICAgICAgICBzY2FsZVggPSBnaG9zdEVsICYmIGdob3N0TWF0cml4ICYmIGdob3N0TWF0cml4LmEsXG4gICAgICAgIHNjYWxlWSA9IGdob3N0RWwgJiYgZ2hvc3RNYXRyaXggJiYgZ2hvc3RNYXRyaXguZCxcbiAgICAgICAgcmVsYXRpdmVTY3JvbGxPZmZzZXQgPSBQb3NpdGlvbkdob3N0QWJzb2x1dGVseSAmJiBnaG9zdFJlbGF0aXZlUGFyZW50ICYmIGdldFJlbGF0aXZlU2Nyb2xsT2Zmc2V0KGdob3N0UmVsYXRpdmVQYXJlbnQpLFxuICAgICAgICBkeCA9ICh0b3VjaC5jbGllbnRYIC0gdGFwRXZ0LmNsaWVudFggKyBmYWxsYmFja09mZnNldC54KSAvIChzY2FsZVggfHwgMSkgKyAocmVsYXRpdmVTY3JvbGxPZmZzZXQgPyByZWxhdGl2ZVNjcm9sbE9mZnNldFswXSAtIGdob3N0UmVsYXRpdmVQYXJlbnRJbml0aWFsU2Nyb2xsWzBdIDogMCkgLyAoc2NhbGVYIHx8IDEpLFxuICAgICAgICBkeSA9ICh0b3VjaC5jbGllbnRZIC0gdGFwRXZ0LmNsaWVudFkgKyBmYWxsYmFja09mZnNldC55KSAvIChzY2FsZVkgfHwgMSkgKyAocmVsYXRpdmVTY3JvbGxPZmZzZXQgPyByZWxhdGl2ZVNjcm9sbE9mZnNldFsxXSAtIGdob3N0UmVsYXRpdmVQYXJlbnRJbml0aWFsU2Nyb2xsWzFdIDogMCkgLyAoc2NhbGVZIHx8IDEpO1xuXG4gICAgICAvLyBvbmx5IHNldCB0aGUgc3RhdHVzIHRvIGRyYWdnaW5nLCB3aGVuIHdlIGFyZSBhY3R1YWxseSBkcmFnZ2luZ1xuICAgICAgaWYgKCFTb3J0YWJsZS5hY3RpdmUgJiYgIWF3YWl0aW5nRHJhZ1N0YXJ0ZWQpIHtcbiAgICAgICAgaWYgKGZhbGxiYWNrVG9sZXJhbmNlICYmIE1hdGgubWF4KE1hdGguYWJzKHRvdWNoLmNsaWVudFggLSB0aGlzLl9sYXN0WCksIE1hdGguYWJzKHRvdWNoLmNsaWVudFkgLSB0aGlzLl9sYXN0WSkpIDwgZmFsbGJhY2tUb2xlcmFuY2UpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fb25EcmFnU3RhcnQoZXZ0LCB0cnVlKTtcbiAgICAgIH1cbiAgICAgIGlmIChnaG9zdEVsKSB7XG4gICAgICAgIGlmIChnaG9zdE1hdHJpeCkge1xuICAgICAgICAgIGdob3N0TWF0cml4LmUgKz0gZHggLSAobGFzdER4IHx8IDApO1xuICAgICAgICAgIGdob3N0TWF0cml4LmYgKz0gZHkgLSAobGFzdER5IHx8IDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGdob3N0TWF0cml4ID0ge1xuICAgICAgICAgICAgYTogMSxcbiAgICAgICAgICAgIGI6IDAsXG4gICAgICAgICAgICBjOiAwLFxuICAgICAgICAgICAgZDogMSxcbiAgICAgICAgICAgIGU6IGR4LFxuICAgICAgICAgICAgZjogZHlcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHZhciBjc3NNYXRyaXggPSBcIm1hdHJpeChcIi5jb25jYXQoZ2hvc3RNYXRyaXguYSwgXCIsXCIpLmNvbmNhdChnaG9zdE1hdHJpeC5iLCBcIixcIikuY29uY2F0KGdob3N0TWF0cml4LmMsIFwiLFwiKS5jb25jYXQoZ2hvc3RNYXRyaXguZCwgXCIsXCIpLmNvbmNhdChnaG9zdE1hdHJpeC5lLCBcIixcIikuY29uY2F0KGdob3N0TWF0cml4LmYsIFwiKVwiKTtcbiAgICAgICAgY3NzKGdob3N0RWwsICd3ZWJraXRUcmFuc2Zvcm0nLCBjc3NNYXRyaXgpO1xuICAgICAgICBjc3MoZ2hvc3RFbCwgJ21velRyYW5zZm9ybScsIGNzc01hdHJpeCk7XG4gICAgICAgIGNzcyhnaG9zdEVsLCAnbXNUcmFuc2Zvcm0nLCBjc3NNYXRyaXgpO1xuICAgICAgICBjc3MoZ2hvc3RFbCwgJ3RyYW5zZm9ybScsIGNzc01hdHJpeCk7XG4gICAgICAgIGxhc3REeCA9IGR4O1xuICAgICAgICBsYXN0RHkgPSBkeTtcbiAgICAgICAgdG91Y2hFdnQgPSB0b3VjaDtcbiAgICAgIH1cbiAgICAgIGV2dC5jYW5jZWxhYmxlICYmIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfSxcbiAgX2FwcGVuZEdob3N0OiBmdW5jdGlvbiBfYXBwZW5kR2hvc3QoKSB7XG4gICAgLy8gQnVnIGlmIHVzaW5nIHNjYWxlKCk6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzI2MzcwNThcbiAgICAvLyBOb3QgYmVpbmcgYWRqdXN0ZWQgZm9yXG4gICAgaWYgKCFnaG9zdEVsKSB7XG4gICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5vcHRpb25zLmZhbGxiYWNrT25Cb2R5ID8gZG9jdW1lbnQuYm9keSA6IHJvb3RFbCxcbiAgICAgICAgcmVjdCA9IGdldFJlY3QoZHJhZ0VsLCB0cnVlLCBQb3NpdGlvbkdob3N0QWJzb2x1dGVseSwgdHJ1ZSwgY29udGFpbmVyKSxcbiAgICAgICAgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcblxuICAgICAgLy8gUG9zaXRpb24gYWJzb2x1dGVseVxuICAgICAgaWYgKFBvc2l0aW9uR2hvc3RBYnNvbHV0ZWx5KSB7XG4gICAgICAgIC8vIEdldCByZWxhdGl2ZWx5IHBvc2l0aW9uZWQgcGFyZW50XG4gICAgICAgIGdob3N0UmVsYXRpdmVQYXJlbnQgPSBjb250YWluZXI7XG4gICAgICAgIHdoaWxlIChjc3MoZ2hvc3RSZWxhdGl2ZVBhcmVudCwgJ3Bvc2l0aW9uJykgPT09ICdzdGF0aWMnICYmIGNzcyhnaG9zdFJlbGF0aXZlUGFyZW50LCAndHJhbnNmb3JtJykgPT09ICdub25lJyAmJiBnaG9zdFJlbGF0aXZlUGFyZW50ICE9PSBkb2N1bWVudCkge1xuICAgICAgICAgIGdob3N0UmVsYXRpdmVQYXJlbnQgPSBnaG9zdFJlbGF0aXZlUGFyZW50LnBhcmVudE5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdob3N0UmVsYXRpdmVQYXJlbnQgIT09IGRvY3VtZW50LmJvZHkgJiYgZ2hvc3RSZWxhdGl2ZVBhcmVudCAhPT0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7XG4gICAgICAgICAgaWYgKGdob3N0UmVsYXRpdmVQYXJlbnQgPT09IGRvY3VtZW50KSBnaG9zdFJlbGF0aXZlUGFyZW50ID0gZ2V0V2luZG93U2Nyb2xsaW5nRWxlbWVudCgpO1xuICAgICAgICAgIHJlY3QudG9wICs9IGdob3N0UmVsYXRpdmVQYXJlbnQuc2Nyb2xsVG9wO1xuICAgICAgICAgIHJlY3QubGVmdCArPSBnaG9zdFJlbGF0aXZlUGFyZW50LnNjcm9sbExlZnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZ2hvc3RSZWxhdGl2ZVBhcmVudCA9IGdldFdpbmRvd1Njcm9sbGluZ0VsZW1lbnQoKTtcbiAgICAgICAgfVxuICAgICAgICBnaG9zdFJlbGF0aXZlUGFyZW50SW5pdGlhbFNjcm9sbCA9IGdldFJlbGF0aXZlU2Nyb2xsT2Zmc2V0KGdob3N0UmVsYXRpdmVQYXJlbnQpO1xuICAgICAgfVxuICAgICAgZ2hvc3RFbCA9IGRyYWdFbC5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICB0b2dnbGVDbGFzcyhnaG9zdEVsLCBvcHRpb25zLmdob3N0Q2xhc3MsIGZhbHNlKTtcbiAgICAgIHRvZ2dsZUNsYXNzKGdob3N0RWwsIG9wdGlvbnMuZmFsbGJhY2tDbGFzcywgdHJ1ZSk7XG4gICAgICB0b2dnbGVDbGFzcyhnaG9zdEVsLCBvcHRpb25zLmRyYWdDbGFzcywgdHJ1ZSk7XG4gICAgICBjc3MoZ2hvc3RFbCwgJ3RyYW5zaXRpb24nLCAnJyk7XG4gICAgICBjc3MoZ2hvc3RFbCwgJ3RyYW5zZm9ybScsICcnKTtcbiAgICAgIGNzcyhnaG9zdEVsLCAnYm94LXNpemluZycsICdib3JkZXItYm94Jyk7XG4gICAgICBjc3MoZ2hvc3RFbCwgJ21hcmdpbicsIDApO1xuICAgICAgY3NzKGdob3N0RWwsICd0b3AnLCByZWN0LnRvcCk7XG4gICAgICBjc3MoZ2hvc3RFbCwgJ2xlZnQnLCByZWN0LmxlZnQpO1xuICAgICAgY3NzKGdob3N0RWwsICd3aWR0aCcsIHJlY3Qud2lkdGgpO1xuICAgICAgY3NzKGdob3N0RWwsICdoZWlnaHQnLCByZWN0LmhlaWdodCk7XG4gICAgICBjc3MoZ2hvc3RFbCwgJ29wYWNpdHknLCAnMC44Jyk7XG4gICAgICBjc3MoZ2hvc3RFbCwgJ3Bvc2l0aW9uJywgUG9zaXRpb25HaG9zdEFic29sdXRlbHkgPyAnYWJzb2x1dGUnIDogJ2ZpeGVkJyk7XG4gICAgICBjc3MoZ2hvc3RFbCwgJ3pJbmRleCcsICcxMDAwMDAnKTtcbiAgICAgIGNzcyhnaG9zdEVsLCAncG9pbnRlckV2ZW50cycsICdub25lJyk7XG4gICAgICBTb3J0YWJsZS5naG9zdCA9IGdob3N0RWw7XG4gICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoZ2hvc3RFbCk7XG5cbiAgICAgIC8vIFNldCB0cmFuc2Zvcm0tb3JpZ2luXG4gICAgICBjc3MoZ2hvc3RFbCwgJ3RyYW5zZm9ybS1vcmlnaW4nLCB0YXBEaXN0YW5jZUxlZnQgLyBwYXJzZUludChnaG9zdEVsLnN0eWxlLndpZHRoKSAqIDEwMCArICclICcgKyB0YXBEaXN0YW5jZVRvcCAvIHBhcnNlSW50KGdob3N0RWwuc3R5bGUuaGVpZ2h0KSAqIDEwMCArICclJyk7XG4gICAgfVxuICB9LFxuICBfb25EcmFnU3RhcnQ6IGZ1bmN0aW9uIF9vbkRyYWdTdGFydCggLyoqRXZlbnQqL2V2dCwgLyoqYm9vbGVhbiovZmFsbGJhY2spIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgIHZhciBkYXRhVHJhbnNmZXIgPSBldnQuZGF0YVRyYW5zZmVyO1xuICAgIHZhciBvcHRpb25zID0gX3RoaXMub3B0aW9ucztcbiAgICBwbHVnaW5FdmVudCgnZHJhZ1N0YXJ0JywgdGhpcywge1xuICAgICAgZXZ0OiBldnRcbiAgICB9KTtcbiAgICBpZiAoU29ydGFibGUuZXZlbnRDYW5jZWxlZCkge1xuICAgICAgdGhpcy5fb25Ecm9wKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHBsdWdpbkV2ZW50KCdzZXR1cENsb25lJywgdGhpcyk7XG4gICAgaWYgKCFTb3J0YWJsZS5ldmVudENhbmNlbGVkKSB7XG4gICAgICBjbG9uZUVsID0gY2xvbmUoZHJhZ0VsKTtcbiAgICAgIGNsb25lRWwucmVtb3ZlQXR0cmlidXRlKFwiaWRcIik7XG4gICAgICBjbG9uZUVsLmRyYWdnYWJsZSA9IGZhbHNlO1xuICAgICAgY2xvbmVFbC5zdHlsZVsnd2lsbC1jaGFuZ2UnXSA9ICcnO1xuICAgICAgdGhpcy5faGlkZUNsb25lKCk7XG4gICAgICB0b2dnbGVDbGFzcyhjbG9uZUVsLCB0aGlzLm9wdGlvbnMuY2hvc2VuQ2xhc3MsIGZhbHNlKTtcbiAgICAgIFNvcnRhYmxlLmNsb25lID0gY2xvbmVFbDtcbiAgICB9XG5cbiAgICAvLyAjMTE0MzogSUZyYW1lIHN1cHBvcnQgd29ya2Fyb3VuZFxuICAgIF90aGlzLmNsb25lSWQgPSBfbmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgcGx1Z2luRXZlbnQoJ2Nsb25lJywgX3RoaXMpO1xuICAgICAgaWYgKFNvcnRhYmxlLmV2ZW50Q2FuY2VsZWQpIHJldHVybjtcbiAgICAgIGlmICghX3RoaXMub3B0aW9ucy5yZW1vdmVDbG9uZU9uSGlkZSkge1xuICAgICAgICByb290RWwuaW5zZXJ0QmVmb3JlKGNsb25lRWwsIGRyYWdFbCk7XG4gICAgICB9XG4gICAgICBfdGhpcy5faGlkZUNsb25lKCk7XG4gICAgICBfZGlzcGF0Y2hFdmVudCh7XG4gICAgICAgIHNvcnRhYmxlOiBfdGhpcyxcbiAgICAgICAgbmFtZTogJ2Nsb25lJ1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgIWZhbGxiYWNrICYmIHRvZ2dsZUNsYXNzKGRyYWdFbCwgb3B0aW9ucy5kcmFnQ2xhc3MsIHRydWUpO1xuXG4gICAgLy8gU2V0IHByb3BlciBkcm9wIGV2ZW50c1xuICAgIGlmIChmYWxsYmFjaykge1xuICAgICAgaWdub3JlTmV4dENsaWNrID0gdHJ1ZTtcbiAgICAgIF90aGlzLl9sb29wSWQgPSBzZXRJbnRlcnZhbChfdGhpcy5fZW11bGF0ZURyYWdPdmVyLCA1MCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFVuZG8gd2hhdCB3YXMgc2V0IGluIF9wcmVwYXJlRHJhZ1N0YXJ0IGJlZm9yZSBkcmFnIHN0YXJ0ZWRcbiAgICAgIG9mZihkb2N1bWVudCwgJ21vdXNldXAnLCBfdGhpcy5fb25Ecm9wKTtcbiAgICAgIG9mZihkb2N1bWVudCwgJ3RvdWNoZW5kJywgX3RoaXMuX29uRHJvcCk7XG4gICAgICBvZmYoZG9jdW1lbnQsICd0b3VjaGNhbmNlbCcsIF90aGlzLl9vbkRyb3ApO1xuICAgICAgaWYgKGRhdGFUcmFuc2Zlcikge1xuICAgICAgICBkYXRhVHJhbnNmZXIuZWZmZWN0QWxsb3dlZCA9ICdtb3ZlJztcbiAgICAgICAgb3B0aW9ucy5zZXREYXRhICYmIG9wdGlvbnMuc2V0RGF0YS5jYWxsKF90aGlzLCBkYXRhVHJhbnNmZXIsIGRyYWdFbCk7XG4gICAgICB9XG4gICAgICBvbihkb2N1bWVudCwgJ2Ryb3AnLCBfdGhpcyk7XG5cbiAgICAgIC8vICMxMjc2IGZpeDpcbiAgICAgIGNzcyhkcmFnRWwsICd0cmFuc2Zvcm0nLCAndHJhbnNsYXRlWigwKScpO1xuICAgIH1cbiAgICBhd2FpdGluZ0RyYWdTdGFydGVkID0gdHJ1ZTtcbiAgICBfdGhpcy5fZHJhZ1N0YXJ0SWQgPSBfbmV4dFRpY2soX3RoaXMuX2RyYWdTdGFydGVkLmJpbmQoX3RoaXMsIGZhbGxiYWNrLCBldnQpKTtcbiAgICBvbihkb2N1bWVudCwgJ3NlbGVjdHN0YXJ0JywgX3RoaXMpO1xuICAgIG1vdmVkID0gdHJ1ZTtcbiAgICB3aW5kb3cuZ2V0U2VsZWN0aW9uKCkucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgaWYgKFNhZmFyaSkge1xuICAgICAgY3NzKGRvY3VtZW50LmJvZHksICd1c2VyLXNlbGVjdCcsICdub25lJyk7XG4gICAgfVxuICB9LFxuICAvLyBSZXR1cm5zIHRydWUgLSBpZiBubyBmdXJ0aGVyIGFjdGlvbiBpcyBuZWVkZWQgKGVpdGhlciBpbnNlcnRlZCBvciBhbm90aGVyIGNvbmRpdGlvbilcbiAgX29uRHJhZ092ZXI6IGZ1bmN0aW9uIF9vbkRyYWdPdmVyKCAvKipFdmVudCovZXZ0KSB7XG4gICAgdmFyIGVsID0gdGhpcy5lbCxcbiAgICAgIHRhcmdldCA9IGV2dC50YXJnZXQsXG4gICAgICBkcmFnUmVjdCxcbiAgICAgIHRhcmdldFJlY3QsXG4gICAgICByZXZlcnQsXG4gICAgICBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuICAgICAgZ3JvdXAgPSBvcHRpb25zLmdyb3VwLFxuICAgICAgYWN0aXZlU29ydGFibGUgPSBTb3J0YWJsZS5hY3RpdmUsXG4gICAgICBpc093bmVyID0gYWN0aXZlR3JvdXAgPT09IGdyb3VwLFxuICAgICAgY2FuU29ydCA9IG9wdGlvbnMuc29ydCxcbiAgICAgIGZyb21Tb3J0YWJsZSA9IHB1dFNvcnRhYmxlIHx8IGFjdGl2ZVNvcnRhYmxlLFxuICAgICAgdmVydGljYWwsXG4gICAgICBfdGhpcyA9IHRoaXMsXG4gICAgICBjb21wbGV0ZWRGaXJlZCA9IGZhbHNlO1xuICAgIGlmIChfc2lsZW50KSByZXR1cm47XG4gICAgZnVuY3Rpb24gZHJhZ092ZXJFdmVudChuYW1lLCBleHRyYSkge1xuICAgICAgcGx1Z2luRXZlbnQobmFtZSwgX3RoaXMsIF9vYmplY3RTcHJlYWQyKHtcbiAgICAgICAgZXZ0OiBldnQsXG4gICAgICAgIGlzT3duZXI6IGlzT3duZXIsXG4gICAgICAgIGF4aXM6IHZlcnRpY2FsID8gJ3ZlcnRpY2FsJyA6ICdob3Jpem9udGFsJyxcbiAgICAgICAgcmV2ZXJ0OiByZXZlcnQsXG4gICAgICAgIGRyYWdSZWN0OiBkcmFnUmVjdCxcbiAgICAgICAgdGFyZ2V0UmVjdDogdGFyZ2V0UmVjdCxcbiAgICAgICAgY2FuU29ydDogY2FuU29ydCxcbiAgICAgICAgZnJvbVNvcnRhYmxlOiBmcm9tU29ydGFibGUsXG4gICAgICAgIHRhcmdldDogdGFyZ2V0LFxuICAgICAgICBjb21wbGV0ZWQ6IGNvbXBsZXRlZCxcbiAgICAgICAgb25Nb3ZlOiBmdW5jdGlvbiBvbk1vdmUodGFyZ2V0LCBhZnRlcikge1xuICAgICAgICAgIHJldHVybiBfb25Nb3ZlKHJvb3RFbCwgZWwsIGRyYWdFbCwgZHJhZ1JlY3QsIHRhcmdldCwgZ2V0UmVjdCh0YXJnZXQpLCBldnQsIGFmdGVyKTtcbiAgICAgICAgfSxcbiAgICAgICAgY2hhbmdlZDogY2hhbmdlZFxuICAgICAgfSwgZXh0cmEpKTtcbiAgICB9XG5cbiAgICAvLyBDYXB0dXJlIGFuaW1hdGlvbiBzdGF0ZVxuICAgIGZ1bmN0aW9uIGNhcHR1cmUoKSB7XG4gICAgICBkcmFnT3ZlckV2ZW50KCdkcmFnT3ZlckFuaW1hdGlvbkNhcHR1cmUnKTtcbiAgICAgIF90aGlzLmNhcHR1cmVBbmltYXRpb25TdGF0ZSgpO1xuICAgICAgaWYgKF90aGlzICE9PSBmcm9tU29ydGFibGUpIHtcbiAgICAgICAgZnJvbVNvcnRhYmxlLmNhcHR1cmVBbmltYXRpb25TdGF0ZSgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJldHVybiBpbnZvY2F0aW9uIHdoZW4gZHJhZ0VsIGlzIGluc2VydGVkIChvciBjb21wbGV0ZWQpXG4gICAgZnVuY3Rpb24gY29tcGxldGVkKGluc2VydGlvbikge1xuICAgICAgZHJhZ092ZXJFdmVudCgnZHJhZ092ZXJDb21wbGV0ZWQnLCB7XG4gICAgICAgIGluc2VydGlvbjogaW5zZXJ0aW9uXG4gICAgICB9KTtcbiAgICAgIGlmIChpbnNlcnRpb24pIHtcbiAgICAgICAgLy8gQ2xvbmVzIG11c3QgYmUgaGlkZGVuIGJlZm9yZSBmb2xkaW5nIGFuaW1hdGlvbiB0byBjYXB0dXJlIGRyYWdSZWN0QWJzb2x1dGUgcHJvcGVybHlcbiAgICAgICAgaWYgKGlzT3duZXIpIHtcbiAgICAgICAgICBhY3RpdmVTb3J0YWJsZS5faGlkZUNsb25lKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWN0aXZlU29ydGFibGUuX3Nob3dDbG9uZShfdGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKF90aGlzICE9PSBmcm9tU29ydGFibGUpIHtcbiAgICAgICAgICAvLyBTZXQgZ2hvc3QgY2xhc3MgdG8gbmV3IHNvcnRhYmxlJ3MgZ2hvc3QgY2xhc3NcbiAgICAgICAgICB0b2dnbGVDbGFzcyhkcmFnRWwsIHB1dFNvcnRhYmxlID8gcHV0U29ydGFibGUub3B0aW9ucy5naG9zdENsYXNzIDogYWN0aXZlU29ydGFibGUub3B0aW9ucy5naG9zdENsYXNzLCBmYWxzZSk7XG4gICAgICAgICAgdG9nZ2xlQ2xhc3MoZHJhZ0VsLCBvcHRpb25zLmdob3N0Q2xhc3MsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwdXRTb3J0YWJsZSAhPT0gX3RoaXMgJiYgX3RoaXMgIT09IFNvcnRhYmxlLmFjdGl2ZSkge1xuICAgICAgICAgIHB1dFNvcnRhYmxlID0gX3RoaXM7XG4gICAgICAgIH0gZWxzZSBpZiAoX3RoaXMgPT09IFNvcnRhYmxlLmFjdGl2ZSAmJiBwdXRTb3J0YWJsZSkge1xuICAgICAgICAgIHB1dFNvcnRhYmxlID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFuaW1hdGlvblxuICAgICAgICBpZiAoZnJvbVNvcnRhYmxlID09PSBfdGhpcykge1xuICAgICAgICAgIF90aGlzLl9pZ25vcmVXaGlsZUFuaW1hdGluZyA9IHRhcmdldDtcbiAgICAgICAgfVxuICAgICAgICBfdGhpcy5hbmltYXRlQWxsKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkcmFnT3ZlckV2ZW50KCdkcmFnT3ZlckFuaW1hdGlvbkNvbXBsZXRlJyk7XG4gICAgICAgICAgX3RoaXMuX2lnbm9yZVdoaWxlQW5pbWF0aW5nID0gbnVsbDtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChfdGhpcyAhPT0gZnJvbVNvcnRhYmxlKSB7XG4gICAgICAgICAgZnJvbVNvcnRhYmxlLmFuaW1hdGVBbGwoKTtcbiAgICAgICAgICBmcm9tU29ydGFibGUuX2lnbm9yZVdoaWxlQW5pbWF0aW5nID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBOdWxsIGxhc3RUYXJnZXQgaWYgaXQgaXMgbm90IGluc2lkZSBhIHByZXZpb3VzbHkgc3dhcHBlZCBlbGVtZW50XG4gICAgICBpZiAodGFyZ2V0ID09PSBkcmFnRWwgJiYgIWRyYWdFbC5hbmltYXRlZCB8fCB0YXJnZXQgPT09IGVsICYmICF0YXJnZXQuYW5pbWF0ZWQpIHtcbiAgICAgICAgbGFzdFRhcmdldCA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIC8vIG5vIGJ1YmJsaW5nIGFuZCBub3QgZmFsbGJhY2tcbiAgICAgIGlmICghb3B0aW9ucy5kcmFnb3ZlckJ1YmJsZSAmJiAhZXZ0LnJvb3RFbCAmJiB0YXJnZXQgIT09IGRvY3VtZW50KSB7XG4gICAgICAgIGRyYWdFbC5wYXJlbnROb2RlW2V4cGFuZG9dLl9pc091dHNpZGVUaGlzRWwoZXZ0LnRhcmdldCk7XG5cbiAgICAgICAgLy8gRG8gbm90IGRldGVjdCBmb3IgZW1wdHkgaW5zZXJ0IGlmIGFscmVhZHkgaW5zZXJ0ZWRcbiAgICAgICAgIWluc2VydGlvbiAmJiBuZWFyZXN0RW1wdHlJbnNlcnREZXRlY3RFdmVudChldnQpO1xuICAgICAgfVxuICAgICAgIW9wdGlvbnMuZHJhZ292ZXJCdWJibGUgJiYgZXZ0LnN0b3BQcm9wYWdhdGlvbiAmJiBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICByZXR1cm4gY29tcGxldGVkRmlyZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIENhbGwgd2hlbiBkcmFnRWwgaGFzIGJlZW4gaW5zZXJ0ZWRcbiAgICBmdW5jdGlvbiBjaGFuZ2VkKCkge1xuICAgICAgbmV3SW5kZXggPSBpbmRleChkcmFnRWwpO1xuICAgICAgbmV3RHJhZ2dhYmxlSW5kZXggPSBpbmRleChkcmFnRWwsIG9wdGlvbnMuZHJhZ2dhYmxlKTtcbiAgICAgIF9kaXNwYXRjaEV2ZW50KHtcbiAgICAgICAgc29ydGFibGU6IF90aGlzLFxuICAgICAgICBuYW1lOiAnY2hhbmdlJyxcbiAgICAgICAgdG9FbDogZWwsXG4gICAgICAgIG5ld0luZGV4OiBuZXdJbmRleCxcbiAgICAgICAgbmV3RHJhZ2dhYmxlSW5kZXg6IG5ld0RyYWdnYWJsZUluZGV4LFxuICAgICAgICBvcmlnaW5hbEV2ZW50OiBldnRcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoZXZ0LnByZXZlbnREZWZhdWx0ICE9PSB2b2lkIDApIHtcbiAgICAgIGV2dC5jYW5jZWxhYmxlICYmIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgICB0YXJnZXQgPSBjbG9zZXN0KHRhcmdldCwgb3B0aW9ucy5kcmFnZ2FibGUsIGVsLCB0cnVlKTtcbiAgICBkcmFnT3ZlckV2ZW50KCdkcmFnT3ZlcicpO1xuICAgIGlmIChTb3J0YWJsZS5ldmVudENhbmNlbGVkKSByZXR1cm4gY29tcGxldGVkRmlyZWQ7XG4gICAgaWYgKGRyYWdFbC5jb250YWlucyhldnQudGFyZ2V0KSB8fCB0YXJnZXQuYW5pbWF0ZWQgJiYgdGFyZ2V0LmFuaW1hdGluZ1ggJiYgdGFyZ2V0LmFuaW1hdGluZ1kgfHwgX3RoaXMuX2lnbm9yZVdoaWxlQW5pbWF0aW5nID09PSB0YXJnZXQpIHtcbiAgICAgIHJldHVybiBjb21wbGV0ZWQoZmFsc2UpO1xuICAgIH1cbiAgICBpZ25vcmVOZXh0Q2xpY2sgPSBmYWxzZTtcbiAgICBpZiAoYWN0aXZlU29ydGFibGUgJiYgIW9wdGlvbnMuZGlzYWJsZWQgJiYgKGlzT3duZXIgPyBjYW5Tb3J0IHx8IChyZXZlcnQgPSBwYXJlbnRFbCAhPT0gcm9vdEVsKSAvLyBSZXZlcnRpbmcgaXRlbSBpbnRvIHRoZSBvcmlnaW5hbCBsaXN0XG4gICAgOiBwdXRTb3J0YWJsZSA9PT0gdGhpcyB8fCAodGhpcy5sYXN0UHV0TW9kZSA9IGFjdGl2ZUdyb3VwLmNoZWNrUHVsbCh0aGlzLCBhY3RpdmVTb3J0YWJsZSwgZHJhZ0VsLCBldnQpKSAmJiBncm91cC5jaGVja1B1dCh0aGlzLCBhY3RpdmVTb3J0YWJsZSwgZHJhZ0VsLCBldnQpKSkge1xuICAgICAgdmVydGljYWwgPSB0aGlzLl9nZXREaXJlY3Rpb24oZXZ0LCB0YXJnZXQpID09PSAndmVydGljYWwnO1xuICAgICAgZHJhZ1JlY3QgPSBnZXRSZWN0KGRyYWdFbCk7XG4gICAgICBkcmFnT3ZlckV2ZW50KCdkcmFnT3ZlclZhbGlkJyk7XG4gICAgICBpZiAoU29ydGFibGUuZXZlbnRDYW5jZWxlZCkgcmV0dXJuIGNvbXBsZXRlZEZpcmVkO1xuICAgICAgaWYgKHJldmVydCkge1xuICAgICAgICBwYXJlbnRFbCA9IHJvb3RFbDsgLy8gYWN0dWFsaXphdGlvblxuICAgICAgICBjYXB0dXJlKCk7XG4gICAgICAgIHRoaXMuX2hpZGVDbG9uZSgpO1xuICAgICAgICBkcmFnT3ZlckV2ZW50KCdyZXZlcnQnKTtcbiAgICAgICAgaWYgKCFTb3J0YWJsZS5ldmVudENhbmNlbGVkKSB7XG4gICAgICAgICAgaWYgKG5leHRFbCkge1xuICAgICAgICAgICAgcm9vdEVsLmluc2VydEJlZm9yZShkcmFnRWwsIG5leHRFbCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJvb3RFbC5hcHBlbmRDaGlsZChkcmFnRWwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29tcGxldGVkKHRydWUpO1xuICAgICAgfVxuICAgICAgdmFyIGVsTGFzdENoaWxkID0gbGFzdENoaWxkKGVsLCBvcHRpb25zLmRyYWdnYWJsZSk7XG4gICAgICBpZiAoIWVsTGFzdENoaWxkIHx8IF9naG9zdElzTGFzdChldnQsIHZlcnRpY2FsLCB0aGlzKSAmJiAhZWxMYXN0Q2hpbGQuYW5pbWF0ZWQpIHtcbiAgICAgICAgLy8gSW5zZXJ0IHRvIGVuZCBvZiBsaXN0XG5cbiAgICAgICAgLy8gSWYgYWxyZWFkeSBhdCBlbmQgb2YgbGlzdDogRG8gbm90IGluc2VydFxuICAgICAgICBpZiAoZWxMYXN0Q2hpbGQgPT09IGRyYWdFbCkge1xuICAgICAgICAgIHJldHVybiBjb21wbGV0ZWQoZmFsc2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgdGhlcmUgaXMgYSBsYXN0IGVsZW1lbnQsIGl0IGlzIHRoZSB0YXJnZXRcbiAgICAgICAgaWYgKGVsTGFzdENoaWxkICYmIGVsID09PSBldnQudGFyZ2V0KSB7XG4gICAgICAgICAgdGFyZ2V0ID0gZWxMYXN0Q2hpbGQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhcmdldCkge1xuICAgICAgICAgIHRhcmdldFJlY3QgPSBnZXRSZWN0KHRhcmdldCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKF9vbk1vdmUocm9vdEVsLCBlbCwgZHJhZ0VsLCBkcmFnUmVjdCwgdGFyZ2V0LCB0YXJnZXRSZWN0LCBldnQsICEhdGFyZ2V0KSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICBjYXB0dXJlKCk7XG4gICAgICAgICAgaWYgKGVsTGFzdENoaWxkICYmIGVsTGFzdENoaWxkLm5leHRTaWJsaW5nKSB7XG4gICAgICAgICAgICAvLyB0aGUgbGFzdCBkcmFnZ2FibGUgZWxlbWVudCBpcyBub3QgdGhlIGxhc3Qgbm9kZVxuICAgICAgICAgICAgZWwuaW5zZXJ0QmVmb3JlKGRyYWdFbCwgZWxMYXN0Q2hpbGQubmV4dFNpYmxpbmcpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlbC5hcHBlbmRDaGlsZChkcmFnRWwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwYXJlbnRFbCA9IGVsOyAvLyBhY3R1YWxpemF0aW9uXG5cbiAgICAgICAgICBjaGFuZ2VkKCk7XG4gICAgICAgICAgcmV0dXJuIGNvbXBsZXRlZCh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChlbExhc3RDaGlsZCAmJiBfZ2hvc3RJc0ZpcnN0KGV2dCwgdmVydGljYWwsIHRoaXMpKSB7XG4gICAgICAgIC8vIEluc2VydCB0byBzdGFydCBvZiBsaXN0XG4gICAgICAgIHZhciBmaXJzdENoaWxkID0gZ2V0Q2hpbGQoZWwsIDAsIG9wdGlvbnMsIHRydWUpO1xuICAgICAgICBpZiAoZmlyc3RDaGlsZCA9PT0gZHJhZ0VsKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbXBsZXRlZChmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGFyZ2V0ID0gZmlyc3RDaGlsZDtcbiAgICAgICAgdGFyZ2V0UmVjdCA9IGdldFJlY3QodGFyZ2V0KTtcbiAgICAgICAgaWYgKF9vbk1vdmUocm9vdEVsLCBlbCwgZHJhZ0VsLCBkcmFnUmVjdCwgdGFyZ2V0LCB0YXJnZXRSZWN0LCBldnQsIGZhbHNlKSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICBjYXB0dXJlKCk7XG4gICAgICAgICAgZWwuaW5zZXJ0QmVmb3JlKGRyYWdFbCwgZmlyc3RDaGlsZCk7XG4gICAgICAgICAgcGFyZW50RWwgPSBlbDsgLy8gYWN0dWFsaXphdGlvblxuXG4gICAgICAgICAgY2hhbmdlZCgpO1xuICAgICAgICAgIHJldHVybiBjb21wbGV0ZWQodHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodGFyZ2V0LnBhcmVudE5vZGUgPT09IGVsKSB7XG4gICAgICAgIHRhcmdldFJlY3QgPSBnZXRSZWN0KHRhcmdldCk7XG4gICAgICAgIHZhciBkaXJlY3Rpb24gPSAwLFxuICAgICAgICAgIHRhcmdldEJlZm9yZUZpcnN0U3dhcCxcbiAgICAgICAgICBkaWZmZXJlbnRMZXZlbCA9IGRyYWdFbC5wYXJlbnROb2RlICE9PSBlbCxcbiAgICAgICAgICBkaWZmZXJlbnRSb3dDb2wgPSAhX2RyYWdFbEluUm93Q29sdW1uKGRyYWdFbC5hbmltYXRlZCAmJiBkcmFnRWwudG9SZWN0IHx8IGRyYWdSZWN0LCB0YXJnZXQuYW5pbWF0ZWQgJiYgdGFyZ2V0LnRvUmVjdCB8fCB0YXJnZXRSZWN0LCB2ZXJ0aWNhbCksXG4gICAgICAgICAgc2lkZTEgPSB2ZXJ0aWNhbCA/ICd0b3AnIDogJ2xlZnQnLFxuICAgICAgICAgIHNjcm9sbGVkUGFzdFRvcCA9IGlzU2Nyb2xsZWRQYXN0KHRhcmdldCwgJ3RvcCcsICd0b3AnKSB8fCBpc1Njcm9sbGVkUGFzdChkcmFnRWwsICd0b3AnLCAndG9wJyksXG4gICAgICAgICAgc2Nyb2xsQmVmb3JlID0gc2Nyb2xsZWRQYXN0VG9wID8gc2Nyb2xsZWRQYXN0VG9wLnNjcm9sbFRvcCA6IHZvaWQgMDtcbiAgICAgICAgaWYgKGxhc3RUYXJnZXQgIT09IHRhcmdldCkge1xuICAgICAgICAgIHRhcmdldEJlZm9yZUZpcnN0U3dhcCA9IHRhcmdldFJlY3Rbc2lkZTFdO1xuICAgICAgICAgIHBhc3RGaXJzdEludmVydFRocmVzaCA9IGZhbHNlO1xuICAgICAgICAgIGlzQ2lyY3Vtc3RhbnRpYWxJbnZlcnQgPSAhZGlmZmVyZW50Um93Q29sICYmIG9wdGlvbnMuaW52ZXJ0U3dhcCB8fCBkaWZmZXJlbnRMZXZlbDtcbiAgICAgICAgfVxuICAgICAgICBkaXJlY3Rpb24gPSBfZ2V0U3dhcERpcmVjdGlvbihldnQsIHRhcmdldCwgdGFyZ2V0UmVjdCwgdmVydGljYWwsIGRpZmZlcmVudFJvd0NvbCA/IDEgOiBvcHRpb25zLnN3YXBUaHJlc2hvbGQsIG9wdGlvbnMuaW52ZXJ0ZWRTd2FwVGhyZXNob2xkID09IG51bGwgPyBvcHRpb25zLnN3YXBUaHJlc2hvbGQgOiBvcHRpb25zLmludmVydGVkU3dhcFRocmVzaG9sZCwgaXNDaXJjdW1zdGFudGlhbEludmVydCwgbGFzdFRhcmdldCA9PT0gdGFyZ2V0KTtcbiAgICAgICAgdmFyIHNpYmxpbmc7XG4gICAgICAgIGlmIChkaXJlY3Rpb24gIT09IDApIHtcbiAgICAgICAgICAvLyBDaGVjayBpZiB0YXJnZXQgaXMgYmVzaWRlIGRyYWdFbCBpbiByZXNwZWN0aXZlIGRpcmVjdGlvbiAoaWdub3JpbmcgaGlkZGVuIGVsZW1lbnRzKVxuICAgICAgICAgIHZhciBkcmFnSW5kZXggPSBpbmRleChkcmFnRWwpO1xuICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgIGRyYWdJbmRleCAtPSBkaXJlY3Rpb247XG4gICAgICAgICAgICBzaWJsaW5nID0gcGFyZW50RWwuY2hpbGRyZW5bZHJhZ0luZGV4XTtcbiAgICAgICAgICB9IHdoaWxlIChzaWJsaW5nICYmIChjc3Moc2libGluZywgJ2Rpc3BsYXknKSA9PT0gJ25vbmUnIHx8IHNpYmxpbmcgPT09IGdob3N0RWwpKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiBkcmFnRWwgaXMgYWxyZWFkeSBiZXNpZGUgdGFyZ2V0OiBEbyBub3QgaW5zZXJ0XG4gICAgICAgIGlmIChkaXJlY3Rpb24gPT09IDAgfHwgc2libGluZyA9PT0gdGFyZ2V0KSB7XG4gICAgICAgICAgcmV0dXJuIGNvbXBsZXRlZChmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgbGFzdFRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgbGFzdERpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbiAgICAgICAgdmFyIG5leHRTaWJsaW5nID0gdGFyZ2V0Lm5leHRFbGVtZW50U2libGluZyxcbiAgICAgICAgICBhZnRlciA9IGZhbHNlO1xuICAgICAgICBhZnRlciA9IGRpcmVjdGlvbiA9PT0gMTtcbiAgICAgICAgdmFyIG1vdmVWZWN0b3IgPSBfb25Nb3ZlKHJvb3RFbCwgZWwsIGRyYWdFbCwgZHJhZ1JlY3QsIHRhcmdldCwgdGFyZ2V0UmVjdCwgZXZ0LCBhZnRlcik7XG4gICAgICAgIGlmIChtb3ZlVmVjdG9yICE9PSBmYWxzZSkge1xuICAgICAgICAgIGlmIChtb3ZlVmVjdG9yID09PSAxIHx8IG1vdmVWZWN0b3IgPT09IC0xKSB7XG4gICAgICAgICAgICBhZnRlciA9IG1vdmVWZWN0b3IgPT09IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIF9zaWxlbnQgPSB0cnVlO1xuICAgICAgICAgIHNldFRpbWVvdXQoX3Vuc2lsZW50LCAzMCk7XG4gICAgICAgICAgY2FwdHVyZSgpO1xuICAgICAgICAgIGlmIChhZnRlciAmJiAhbmV4dFNpYmxpbmcpIHtcbiAgICAgICAgICAgIGVsLmFwcGVuZENoaWxkKGRyYWdFbCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRhcmdldC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShkcmFnRWwsIGFmdGVyID8gbmV4dFNpYmxpbmcgOiB0YXJnZXQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFVuZG8gY2hyb21lJ3Mgc2Nyb2xsIGFkanVzdG1lbnQgKGhhcyBubyBlZmZlY3Qgb24gb3RoZXIgYnJvd3NlcnMpXG4gICAgICAgICAgaWYgKHNjcm9sbGVkUGFzdFRvcCkge1xuICAgICAgICAgICAgc2Nyb2xsQnkoc2Nyb2xsZWRQYXN0VG9wLCAwLCBzY3JvbGxCZWZvcmUgLSBzY3JvbGxlZFBhc3RUb3Auc2Nyb2xsVG9wKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGFyZW50RWwgPSBkcmFnRWwucGFyZW50Tm9kZTsgLy8gYWN0dWFsaXphdGlvblxuXG4gICAgICAgICAgLy8gbXVzdCBiZSBkb25lIGJlZm9yZSBhbmltYXRpb25cbiAgICAgICAgICBpZiAodGFyZ2V0QmVmb3JlRmlyc3RTd2FwICE9PSB1bmRlZmluZWQgJiYgIWlzQ2lyY3Vtc3RhbnRpYWxJbnZlcnQpIHtcbiAgICAgICAgICAgIHRhcmdldE1vdmVEaXN0YW5jZSA9IE1hdGguYWJzKHRhcmdldEJlZm9yZUZpcnN0U3dhcCAtIGdldFJlY3QodGFyZ2V0KVtzaWRlMV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjaGFuZ2VkKCk7XG4gICAgICAgICAgcmV0dXJuIGNvbXBsZXRlZCh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGVsLmNvbnRhaW5zKGRyYWdFbCkpIHtcbiAgICAgICAgcmV0dXJuIGNvbXBsZXRlZChmYWxzZSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcbiAgX2lnbm9yZVdoaWxlQW5pbWF0aW5nOiBudWxsLFxuICBfb2ZmTW92ZUV2ZW50czogZnVuY3Rpb24gX29mZk1vdmVFdmVudHMoKSB7XG4gICAgb2ZmKGRvY3VtZW50LCAnbW91c2Vtb3ZlJywgdGhpcy5fb25Ub3VjaE1vdmUpO1xuICAgIG9mZihkb2N1bWVudCwgJ3RvdWNobW92ZScsIHRoaXMuX29uVG91Y2hNb3ZlKTtcbiAgICBvZmYoZG9jdW1lbnQsICdwb2ludGVybW92ZScsIHRoaXMuX29uVG91Y2hNb3ZlKTtcbiAgICBvZmYoZG9jdW1lbnQsICdkcmFnb3ZlcicsIG5lYXJlc3RFbXB0eUluc2VydERldGVjdEV2ZW50KTtcbiAgICBvZmYoZG9jdW1lbnQsICdtb3VzZW1vdmUnLCBuZWFyZXN0RW1wdHlJbnNlcnREZXRlY3RFdmVudCk7XG4gICAgb2ZmKGRvY3VtZW50LCAndG91Y2htb3ZlJywgbmVhcmVzdEVtcHR5SW5zZXJ0RGV0ZWN0RXZlbnQpO1xuICB9LFxuICBfb2ZmVXBFdmVudHM6IGZ1bmN0aW9uIF9vZmZVcEV2ZW50cygpIHtcbiAgICB2YXIgb3duZXJEb2N1bWVudCA9IHRoaXMuZWwub3duZXJEb2N1bWVudDtcbiAgICBvZmYob3duZXJEb2N1bWVudCwgJ21vdXNldXAnLCB0aGlzLl9vbkRyb3ApO1xuICAgIG9mZihvd25lckRvY3VtZW50LCAndG91Y2hlbmQnLCB0aGlzLl9vbkRyb3ApO1xuICAgIG9mZihvd25lckRvY3VtZW50LCAncG9pbnRlcnVwJywgdGhpcy5fb25Ecm9wKTtcbiAgICBvZmYob3duZXJEb2N1bWVudCwgJ3BvaW50ZXJjYW5jZWwnLCB0aGlzLl9vbkRyb3ApO1xuICAgIG9mZihvd25lckRvY3VtZW50LCAndG91Y2hjYW5jZWwnLCB0aGlzLl9vbkRyb3ApO1xuICAgIG9mZihkb2N1bWVudCwgJ3NlbGVjdHN0YXJ0JywgdGhpcyk7XG4gIH0sXG4gIF9vbkRyb3A6IGZ1bmN0aW9uIF9vbkRyb3AoIC8qKkV2ZW50Ki9ldnQpIHtcbiAgICB2YXIgZWwgPSB0aGlzLmVsLFxuICAgICAgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcblxuICAgIC8vIEdldCB0aGUgaW5kZXggb2YgdGhlIGRyYWdnZWQgZWxlbWVudCB3aXRoaW4gaXRzIHBhcmVudFxuICAgIG5ld0luZGV4ID0gaW5kZXgoZHJhZ0VsKTtcbiAgICBuZXdEcmFnZ2FibGVJbmRleCA9IGluZGV4KGRyYWdFbCwgb3B0aW9ucy5kcmFnZ2FibGUpO1xuICAgIHBsdWdpbkV2ZW50KCdkcm9wJywgdGhpcywge1xuICAgICAgZXZ0OiBldnRcbiAgICB9KTtcbiAgICBwYXJlbnRFbCA9IGRyYWdFbCAmJiBkcmFnRWwucGFyZW50Tm9kZTtcblxuICAgIC8vIEdldCBhZ2FpbiBhZnRlciBwbHVnaW4gZXZlbnRcbiAgICBuZXdJbmRleCA9IGluZGV4KGRyYWdFbCk7XG4gICAgbmV3RHJhZ2dhYmxlSW5kZXggPSBpbmRleChkcmFnRWwsIG9wdGlvbnMuZHJhZ2dhYmxlKTtcbiAgICBpZiAoU29ydGFibGUuZXZlbnRDYW5jZWxlZCkge1xuICAgICAgdGhpcy5fbnVsbGluZygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhd2FpdGluZ0RyYWdTdGFydGVkID0gZmFsc2U7XG4gICAgaXNDaXJjdW1zdGFudGlhbEludmVydCA9IGZhbHNlO1xuICAgIHBhc3RGaXJzdEludmVydFRocmVzaCA9IGZhbHNlO1xuICAgIGNsZWFySW50ZXJ2YWwodGhpcy5fbG9vcElkKTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5fZHJhZ1N0YXJ0VGltZXIpO1xuICAgIF9jYW5jZWxOZXh0VGljayh0aGlzLmNsb25lSWQpO1xuICAgIF9jYW5jZWxOZXh0VGljayh0aGlzLl9kcmFnU3RhcnRJZCk7XG5cbiAgICAvLyBVbmJpbmQgZXZlbnRzXG4gICAgaWYgKHRoaXMubmF0aXZlRHJhZ2dhYmxlKSB7XG4gICAgICBvZmYoZG9jdW1lbnQsICdkcm9wJywgdGhpcyk7XG4gICAgICBvZmYoZWwsICdkcmFnc3RhcnQnLCB0aGlzLl9vbkRyYWdTdGFydCk7XG4gICAgfVxuICAgIHRoaXMuX29mZk1vdmVFdmVudHMoKTtcbiAgICB0aGlzLl9vZmZVcEV2ZW50cygpO1xuICAgIGlmIChTYWZhcmkpIHtcbiAgICAgIGNzcyhkb2N1bWVudC5ib2R5LCAndXNlci1zZWxlY3QnLCAnJyk7XG4gICAgfVxuICAgIGNzcyhkcmFnRWwsICd0cmFuc2Zvcm0nLCAnJyk7XG4gICAgaWYgKGV2dCkge1xuICAgICAgaWYgKG1vdmVkKSB7XG4gICAgICAgIGV2dC5jYW5jZWxhYmxlICYmIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAhb3B0aW9ucy5kcm9wQnViYmxlICYmIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIH1cbiAgICAgIGdob3N0RWwgJiYgZ2hvc3RFbC5wYXJlbnROb2RlICYmIGdob3N0RWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChnaG9zdEVsKTtcbiAgICAgIGlmIChyb290RWwgPT09IHBhcmVudEVsIHx8IHB1dFNvcnRhYmxlICYmIHB1dFNvcnRhYmxlLmxhc3RQdXRNb2RlICE9PSAnY2xvbmUnKSB7XG4gICAgICAgIC8vIFJlbW92ZSBjbG9uZShzKVxuICAgICAgICBjbG9uZUVsICYmIGNsb25lRWwucGFyZW50Tm9kZSAmJiBjbG9uZUVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY2xvbmVFbCk7XG4gICAgICB9XG4gICAgICBpZiAoZHJhZ0VsKSB7XG4gICAgICAgIGlmICh0aGlzLm5hdGl2ZURyYWdnYWJsZSkge1xuICAgICAgICAgIG9mZihkcmFnRWwsICdkcmFnZW5kJywgdGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgX2Rpc2FibGVEcmFnZ2FibGUoZHJhZ0VsKTtcbiAgICAgICAgZHJhZ0VsLnN0eWxlWyd3aWxsLWNoYW5nZSddID0gJyc7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGNsYXNzZXNcbiAgICAgICAgLy8gZ2hvc3RDbGFzcyBpcyBhZGRlZCBpbiBkcmFnU3RhcnRlZFxuICAgICAgICBpZiAobW92ZWQgJiYgIWF3YWl0aW5nRHJhZ1N0YXJ0ZWQpIHtcbiAgICAgICAgICB0b2dnbGVDbGFzcyhkcmFnRWwsIHB1dFNvcnRhYmxlID8gcHV0U29ydGFibGUub3B0aW9ucy5naG9zdENsYXNzIDogdGhpcy5vcHRpb25zLmdob3N0Q2xhc3MsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICB0b2dnbGVDbGFzcyhkcmFnRWwsIHRoaXMub3B0aW9ucy5jaG9zZW5DbGFzcywgZmFsc2UpO1xuXG4gICAgICAgIC8vIERyYWcgc3RvcCBldmVudFxuICAgICAgICBfZGlzcGF0Y2hFdmVudCh7XG4gICAgICAgICAgc29ydGFibGU6IHRoaXMsXG4gICAgICAgICAgbmFtZTogJ3VuY2hvb3NlJyxcbiAgICAgICAgICB0b0VsOiBwYXJlbnRFbCxcbiAgICAgICAgICBuZXdJbmRleDogbnVsbCxcbiAgICAgICAgICBuZXdEcmFnZ2FibGVJbmRleDogbnVsbCxcbiAgICAgICAgICBvcmlnaW5hbEV2ZW50OiBldnRcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyb290RWwgIT09IHBhcmVudEVsKSB7XG4gICAgICAgICAgaWYgKG5ld0luZGV4ID49IDApIHtcbiAgICAgICAgICAgIC8vIEFkZCBldmVudFxuICAgICAgICAgICAgX2Rpc3BhdGNoRXZlbnQoe1xuICAgICAgICAgICAgICByb290RWw6IHBhcmVudEVsLFxuICAgICAgICAgICAgICBuYW1lOiAnYWRkJyxcbiAgICAgICAgICAgICAgdG9FbDogcGFyZW50RWwsXG4gICAgICAgICAgICAgIGZyb21FbDogcm9vdEVsLFxuICAgICAgICAgICAgICBvcmlnaW5hbEV2ZW50OiBldnRcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgZXZlbnRcbiAgICAgICAgICAgIF9kaXNwYXRjaEV2ZW50KHtcbiAgICAgICAgICAgICAgc29ydGFibGU6IHRoaXMsXG4gICAgICAgICAgICAgIG5hbWU6ICdyZW1vdmUnLFxuICAgICAgICAgICAgICB0b0VsOiBwYXJlbnRFbCxcbiAgICAgICAgICAgICAgb3JpZ2luYWxFdmVudDogZXZ0XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gZHJhZyBmcm9tIG9uZSBsaXN0IGFuZCBkcm9wIGludG8gYW5vdGhlclxuICAgICAgICAgICAgX2Rpc3BhdGNoRXZlbnQoe1xuICAgICAgICAgICAgICByb290RWw6IHBhcmVudEVsLFxuICAgICAgICAgICAgICBuYW1lOiAnc29ydCcsXG4gICAgICAgICAgICAgIHRvRWw6IHBhcmVudEVsLFxuICAgICAgICAgICAgICBmcm9tRWw6IHJvb3RFbCxcbiAgICAgICAgICAgICAgb3JpZ2luYWxFdmVudDogZXZ0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIF9kaXNwYXRjaEV2ZW50KHtcbiAgICAgICAgICAgICAgc29ydGFibGU6IHRoaXMsXG4gICAgICAgICAgICAgIG5hbWU6ICdzb3J0JyxcbiAgICAgICAgICAgICAgdG9FbDogcGFyZW50RWwsXG4gICAgICAgICAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2dFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHB1dFNvcnRhYmxlICYmIHB1dFNvcnRhYmxlLnNhdmUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAobmV3SW5kZXggIT09IG9sZEluZGV4KSB7XG4gICAgICAgICAgICBpZiAobmV3SW5kZXggPj0gMCkge1xuICAgICAgICAgICAgICAvLyBkcmFnICYgZHJvcCB3aXRoaW4gdGhlIHNhbWUgbGlzdFxuICAgICAgICAgICAgICBfZGlzcGF0Y2hFdmVudCh7XG4gICAgICAgICAgICAgICAgc29ydGFibGU6IHRoaXMsXG4gICAgICAgICAgICAgICAgbmFtZTogJ3VwZGF0ZScsXG4gICAgICAgICAgICAgICAgdG9FbDogcGFyZW50RWwsXG4gICAgICAgICAgICAgICAgb3JpZ2luYWxFdmVudDogZXZ0XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBfZGlzcGF0Y2hFdmVudCh7XG4gICAgICAgICAgICAgICAgc29ydGFibGU6IHRoaXMsXG4gICAgICAgICAgICAgICAgbmFtZTogJ3NvcnQnLFxuICAgICAgICAgICAgICAgIHRvRWw6IHBhcmVudEVsLFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2dFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFNvcnRhYmxlLmFjdGl2ZSkge1xuICAgICAgICAgIC8qIGpzaGludCBlcW51bGw6dHJ1ZSAqL1xuICAgICAgICAgIGlmIChuZXdJbmRleCA9PSBudWxsIHx8IG5ld0luZGV4ID09PSAtMSkge1xuICAgICAgICAgICAgbmV3SW5kZXggPSBvbGRJbmRleDtcbiAgICAgICAgICAgIG5ld0RyYWdnYWJsZUluZGV4ID0gb2xkRHJhZ2dhYmxlSW5kZXg7XG4gICAgICAgICAgfVxuICAgICAgICAgIF9kaXNwYXRjaEV2ZW50KHtcbiAgICAgICAgICAgIHNvcnRhYmxlOiB0aGlzLFxuICAgICAgICAgICAgbmFtZTogJ2VuZCcsXG4gICAgICAgICAgICB0b0VsOiBwYXJlbnRFbCxcbiAgICAgICAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2dFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gU2F2ZSBzb3J0aW5nXG4gICAgICAgICAgdGhpcy5zYXZlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5fbnVsbGluZygpO1xuICB9LFxuICBfbnVsbGluZzogZnVuY3Rpb24gX251bGxpbmcoKSB7XG4gICAgcGx1Z2luRXZlbnQoJ251bGxpbmcnLCB0aGlzKTtcbiAgICByb290RWwgPSBkcmFnRWwgPSBwYXJlbnRFbCA9IGdob3N0RWwgPSBuZXh0RWwgPSBjbG9uZUVsID0gbGFzdERvd25FbCA9IGNsb25lSGlkZGVuID0gdGFwRXZ0ID0gdG91Y2hFdnQgPSBtb3ZlZCA9IG5ld0luZGV4ID0gbmV3RHJhZ2dhYmxlSW5kZXggPSBvbGRJbmRleCA9IG9sZERyYWdnYWJsZUluZGV4ID0gbGFzdFRhcmdldCA9IGxhc3REaXJlY3Rpb24gPSBwdXRTb3J0YWJsZSA9IGFjdGl2ZUdyb3VwID0gU29ydGFibGUuZHJhZ2dlZCA9IFNvcnRhYmxlLmdob3N0ID0gU29ydGFibGUuY2xvbmUgPSBTb3J0YWJsZS5hY3RpdmUgPSBudWxsO1xuICAgIHZhciBlbCA9IHRoaXMuZWw7XG4gICAgc2F2ZWRJbnB1dENoZWNrZWQuZm9yRWFjaChmdW5jdGlvbiAoY2hlY2tFbCkge1xuICAgICAgaWYgKGVsLmNvbnRhaW5zKGNoZWNrRWwpKSB7XG4gICAgICAgIGNoZWNrRWwuY2hlY2tlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgc2F2ZWRJbnB1dENoZWNrZWQubGVuZ3RoID0gbGFzdER4ID0gbGFzdER5ID0gMDtcbiAgfSxcbiAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uIGhhbmRsZUV2ZW50KCAvKipFdmVudCovZXZ0KSB7XG4gICAgc3dpdGNoIChldnQudHlwZSkge1xuICAgICAgY2FzZSAnZHJvcCc6XG4gICAgICBjYXNlICdkcmFnZW5kJzpcbiAgICAgICAgdGhpcy5fb25Ecm9wKGV2dCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZHJhZ2VudGVyJzpcbiAgICAgIGNhc2UgJ2RyYWdvdmVyJzpcbiAgICAgICAgaWYgKGRyYWdFbCkge1xuICAgICAgICAgIHRoaXMuX29uRHJhZ092ZXIoZXZ0KTtcbiAgICAgICAgICBfZ2xvYmFsRHJhZ092ZXIoZXZ0KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3NlbGVjdHN0YXJ0JzpcbiAgICAgICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfSxcbiAgLyoqXHJcbiAgICogU2VyaWFsaXplcyB0aGUgaXRlbSBpbnRvIGFuIGFycmF5IG9mIHN0cmluZy5cclxuICAgKiBAcmV0dXJucyB7U3RyaW5nW119XHJcbiAgICovXG4gIHRvQXJyYXk6IGZ1bmN0aW9uIHRvQXJyYXkoKSB7XG4gICAgdmFyIG9yZGVyID0gW10sXG4gICAgICBlbCxcbiAgICAgIGNoaWxkcmVuID0gdGhpcy5lbC5jaGlsZHJlbixcbiAgICAgIGkgPSAwLFxuICAgICAgbiA9IGNoaWxkcmVuLmxlbmd0aCxcbiAgICAgIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgZm9yICg7IGkgPCBuOyBpKyspIHtcbiAgICAgIGVsID0gY2hpbGRyZW5baV07XG4gICAgICBpZiAoY2xvc2VzdChlbCwgb3B0aW9ucy5kcmFnZ2FibGUsIHRoaXMuZWwsIGZhbHNlKSkge1xuICAgICAgICBvcmRlci5wdXNoKGVsLmdldEF0dHJpYnV0ZShvcHRpb25zLmRhdGFJZEF0dHIpIHx8IF9nZW5lcmF0ZUlkKGVsKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvcmRlcjtcbiAgfSxcbiAgLyoqXHJcbiAgICogU29ydHMgdGhlIGVsZW1lbnRzIGFjY29yZGluZyB0byB0aGUgYXJyYXkuXHJcbiAgICogQHBhcmFtICB7U3RyaW5nW119ICBvcmRlciAgb3JkZXIgb2YgdGhlIGl0ZW1zXHJcbiAgICovXG4gIHNvcnQ6IGZ1bmN0aW9uIHNvcnQob3JkZXIsIHVzZUFuaW1hdGlvbikge1xuICAgIHZhciBpdGVtcyA9IHt9LFxuICAgICAgcm9vdEVsID0gdGhpcy5lbDtcbiAgICB0aGlzLnRvQXJyYXkoKS5mb3JFYWNoKGZ1bmN0aW9uIChpZCwgaSkge1xuICAgICAgdmFyIGVsID0gcm9vdEVsLmNoaWxkcmVuW2ldO1xuICAgICAgaWYgKGNsb3Nlc3QoZWwsIHRoaXMub3B0aW9ucy5kcmFnZ2FibGUsIHJvb3RFbCwgZmFsc2UpKSB7XG4gICAgICAgIGl0ZW1zW2lkXSA9IGVsO1xuICAgICAgfVxuICAgIH0sIHRoaXMpO1xuICAgIHVzZUFuaW1hdGlvbiAmJiB0aGlzLmNhcHR1cmVBbmltYXRpb25TdGF0ZSgpO1xuICAgIG9yZGVyLmZvckVhY2goZnVuY3Rpb24gKGlkKSB7XG4gICAgICBpZiAoaXRlbXNbaWRdKSB7XG4gICAgICAgIHJvb3RFbC5yZW1vdmVDaGlsZChpdGVtc1tpZF0pO1xuICAgICAgICByb290RWwuYXBwZW5kQ2hpbGQoaXRlbXNbaWRdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB1c2VBbmltYXRpb24gJiYgdGhpcy5hbmltYXRlQWxsKCk7XG4gIH0sXG4gIC8qKlxyXG4gICAqIFNhdmUgdGhlIGN1cnJlbnQgc29ydGluZ1xyXG4gICAqL1xuICBzYXZlOiBmdW5jdGlvbiBzYXZlKCkge1xuICAgIHZhciBzdG9yZSA9IHRoaXMub3B0aW9ucy5zdG9yZTtcbiAgICBzdG9yZSAmJiBzdG9yZS5zZXQgJiYgc3RvcmUuc2V0KHRoaXMpO1xuICB9LFxuICAvKipcclxuICAgKiBGb3IgZWFjaCBlbGVtZW50IGluIHRoZSBzZXQsIGdldCB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IG1hdGNoZXMgdGhlIHNlbGVjdG9yIGJ5IHRlc3RpbmcgdGhlIGVsZW1lbnQgaXRzZWxmIGFuZCB0cmF2ZXJzaW5nIHVwIHRocm91Z2ggaXRzIGFuY2VzdG9ycyBpbiB0aGUgRE9NIHRyZWUuXHJcbiAgICogQHBhcmFtICAge0hUTUxFbGVtZW50fSAgZWxcclxuICAgKiBAcGFyYW0gICB7U3RyaW5nfSAgICAgICBbc2VsZWN0b3JdICBkZWZhdWx0OiBgb3B0aW9ucy5kcmFnZ2FibGVgXHJcbiAgICogQHJldHVybnMge0hUTUxFbGVtZW50fG51bGx9XHJcbiAgICovXG4gIGNsb3Nlc3Q6IGZ1bmN0aW9uIGNsb3Nlc3QkMShlbCwgc2VsZWN0b3IpIHtcbiAgICByZXR1cm4gY2xvc2VzdChlbCwgc2VsZWN0b3IgfHwgdGhpcy5vcHRpb25zLmRyYWdnYWJsZSwgdGhpcy5lbCwgZmFsc2UpO1xuICB9LFxuICAvKipcclxuICAgKiBTZXQvZ2V0IG9wdGlvblxyXG4gICAqIEBwYXJhbSAgIHtzdHJpbmd9IG5hbWVcclxuICAgKiBAcGFyYW0gICB7Kn0gICAgICBbdmFsdWVdXHJcbiAgICogQHJldHVybnMgeyp9XHJcbiAgICovXG4gIG9wdGlvbjogZnVuY3Rpb24gb3B0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgaWYgKHZhbHVlID09PSB2b2lkIDApIHtcbiAgICAgIHJldHVybiBvcHRpb25zW25hbWVdO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbW9kaWZpZWRWYWx1ZSA9IFBsdWdpbk1hbmFnZXIubW9kaWZ5T3B0aW9uKHRoaXMsIG5hbWUsIHZhbHVlKTtcbiAgICAgIGlmICh0eXBlb2YgbW9kaWZpZWRWYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgb3B0aW9uc1tuYW1lXSA9IG1vZGlmaWVkVmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcHRpb25zW25hbWVdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAobmFtZSA9PT0gJ2dyb3VwJykge1xuICAgICAgICBfcHJlcGFyZUdyb3VwKG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgLyoqXHJcbiAgICogRGVzdHJveVxyXG4gICAqL1xuICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgIHBsdWdpbkV2ZW50KCdkZXN0cm95JywgdGhpcyk7XG4gICAgdmFyIGVsID0gdGhpcy5lbDtcbiAgICBlbFtleHBhbmRvXSA9IG51bGw7XG4gICAgb2ZmKGVsLCAnbW91c2Vkb3duJywgdGhpcy5fb25UYXBTdGFydCk7XG4gICAgb2ZmKGVsLCAndG91Y2hzdGFydCcsIHRoaXMuX29uVGFwU3RhcnQpO1xuICAgIG9mZihlbCwgJ3BvaW50ZXJkb3duJywgdGhpcy5fb25UYXBTdGFydCk7XG4gICAgaWYgKHRoaXMubmF0aXZlRHJhZ2dhYmxlKSB7XG4gICAgICBvZmYoZWwsICdkcmFnb3ZlcicsIHRoaXMpO1xuICAgICAgb2ZmKGVsLCAnZHJhZ2VudGVyJywgdGhpcyk7XG4gICAgfVxuICAgIC8vIFJlbW92ZSBkcmFnZ2FibGUgYXR0cmlidXRlc1xuICAgIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwoZWwucXVlcnlTZWxlY3RvckFsbCgnW2RyYWdnYWJsZV0nKSwgZnVuY3Rpb24gKGVsKSB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2RyYWdnYWJsZScpO1xuICAgIH0pO1xuICAgIHRoaXMuX29uRHJvcCgpO1xuICAgIHRoaXMuX2Rpc2FibGVEZWxheWVkRHJhZ0V2ZW50cygpO1xuICAgIHNvcnRhYmxlcy5zcGxpY2Uoc29ydGFibGVzLmluZGV4T2YodGhpcy5lbCksIDEpO1xuICAgIHRoaXMuZWwgPSBlbCA9IG51bGw7XG4gIH0sXG4gIF9oaWRlQ2xvbmU6IGZ1bmN0aW9uIF9oaWRlQ2xvbmUoKSB7XG4gICAgaWYgKCFjbG9uZUhpZGRlbikge1xuICAgICAgcGx1Z2luRXZlbnQoJ2hpZGVDbG9uZScsIHRoaXMpO1xuICAgICAgaWYgKFNvcnRhYmxlLmV2ZW50Q2FuY2VsZWQpIHJldHVybjtcbiAgICAgIGNzcyhjbG9uZUVsLCAnZGlzcGxheScsICdub25lJyk7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnJlbW92ZUNsb25lT25IaWRlICYmIGNsb25lRWwucGFyZW50Tm9kZSkge1xuICAgICAgICBjbG9uZUVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY2xvbmVFbCk7XG4gICAgICB9XG4gICAgICBjbG9uZUhpZGRlbiA9IHRydWU7XG4gICAgfVxuICB9LFxuICBfc2hvd0Nsb25lOiBmdW5jdGlvbiBfc2hvd0Nsb25lKHB1dFNvcnRhYmxlKSB7XG4gICAgaWYgKHB1dFNvcnRhYmxlLmxhc3RQdXRNb2RlICE9PSAnY2xvbmUnKSB7XG4gICAgICB0aGlzLl9oaWRlQ2xvbmUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGNsb25lSGlkZGVuKSB7XG4gICAgICBwbHVnaW5FdmVudCgnc2hvd0Nsb25lJywgdGhpcyk7XG4gICAgICBpZiAoU29ydGFibGUuZXZlbnRDYW5jZWxlZCkgcmV0dXJuO1xuXG4gICAgICAvLyBzaG93IGNsb25lIGF0IGRyYWdFbCBvciBvcmlnaW5hbCBwb3NpdGlvblxuICAgICAgaWYgKGRyYWdFbC5wYXJlbnROb2RlID09IHJvb3RFbCAmJiAhdGhpcy5vcHRpb25zLmdyb3VwLnJldmVydENsb25lKSB7XG4gICAgICAgIHJvb3RFbC5pbnNlcnRCZWZvcmUoY2xvbmVFbCwgZHJhZ0VsKTtcbiAgICAgIH0gZWxzZSBpZiAobmV4dEVsKSB7XG4gICAgICAgIHJvb3RFbC5pbnNlcnRCZWZvcmUoY2xvbmVFbCwgbmV4dEVsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJvb3RFbC5hcHBlbmRDaGlsZChjbG9uZUVsKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuZ3JvdXAucmV2ZXJ0Q2xvbmUpIHtcbiAgICAgICAgdGhpcy5hbmltYXRlKGRyYWdFbCwgY2xvbmVFbCk7XG4gICAgICB9XG4gICAgICBjc3MoY2xvbmVFbCwgJ2Rpc3BsYXknLCAnJyk7XG4gICAgICBjbG9uZUhpZGRlbiA9IGZhbHNlO1xuICAgIH1cbiAgfVxufTtcbmZ1bmN0aW9uIF9nbG9iYWxEcmFnT3ZlciggLyoqRXZlbnQqL2V2dCkge1xuICBpZiAoZXZ0LmRhdGFUcmFuc2Zlcikge1xuICAgIGV2dC5kYXRhVHJhbnNmZXIuZHJvcEVmZmVjdCA9ICdtb3ZlJztcbiAgfVxuICBldnQuY2FuY2VsYWJsZSAmJiBldnQucHJldmVudERlZmF1bHQoKTtcbn1cbmZ1bmN0aW9uIF9vbk1vdmUoZnJvbUVsLCB0b0VsLCBkcmFnRWwsIGRyYWdSZWN0LCB0YXJnZXRFbCwgdGFyZ2V0UmVjdCwgb3JpZ2luYWxFdmVudCwgd2lsbEluc2VydEFmdGVyKSB7XG4gIHZhciBldnQsXG4gICAgc29ydGFibGUgPSBmcm9tRWxbZXhwYW5kb10sXG4gICAgb25Nb3ZlRm4gPSBzb3J0YWJsZS5vcHRpb25zLm9uTW92ZSxcbiAgICByZXRWYWw7XG4gIC8vIFN1cHBvcnQgZm9yIG5ldyBDdXN0b21FdmVudCBmZWF0dXJlXG4gIGlmICh3aW5kb3cuQ3VzdG9tRXZlbnQgJiYgIUlFMTFPckxlc3MgJiYgIUVkZ2UpIHtcbiAgICBldnQgPSBuZXcgQ3VzdG9tRXZlbnQoJ21vdmUnLCB7XG4gICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgY2FuY2VsYWJsZTogdHJ1ZVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdFdmVudCcpO1xuICAgIGV2dC5pbml0RXZlbnQoJ21vdmUnLCB0cnVlLCB0cnVlKTtcbiAgfVxuICBldnQudG8gPSB0b0VsO1xuICBldnQuZnJvbSA9IGZyb21FbDtcbiAgZXZ0LmRyYWdnZWQgPSBkcmFnRWw7XG4gIGV2dC5kcmFnZ2VkUmVjdCA9IGRyYWdSZWN0O1xuICBldnQucmVsYXRlZCA9IHRhcmdldEVsIHx8IHRvRWw7XG4gIGV2dC5yZWxhdGVkUmVjdCA9IHRhcmdldFJlY3QgfHwgZ2V0UmVjdCh0b0VsKTtcbiAgZXZ0LndpbGxJbnNlcnRBZnRlciA9IHdpbGxJbnNlcnRBZnRlcjtcbiAgZXZ0Lm9yaWdpbmFsRXZlbnQgPSBvcmlnaW5hbEV2ZW50O1xuICBmcm9tRWwuZGlzcGF0Y2hFdmVudChldnQpO1xuICBpZiAob25Nb3ZlRm4pIHtcbiAgICByZXRWYWwgPSBvbk1vdmVGbi5jYWxsKHNvcnRhYmxlLCBldnQsIG9yaWdpbmFsRXZlbnQpO1xuICB9XG4gIHJldHVybiByZXRWYWw7XG59XG5mdW5jdGlvbiBfZGlzYWJsZURyYWdnYWJsZShlbCkge1xuICBlbC5kcmFnZ2FibGUgPSBmYWxzZTtcbn1cbmZ1bmN0aW9uIF91bnNpbGVudCgpIHtcbiAgX3NpbGVudCA9IGZhbHNlO1xufVxuZnVuY3Rpb24gX2dob3N0SXNGaXJzdChldnQsIHZlcnRpY2FsLCBzb3J0YWJsZSkge1xuICB2YXIgZmlyc3RFbFJlY3QgPSBnZXRSZWN0KGdldENoaWxkKHNvcnRhYmxlLmVsLCAwLCBzb3J0YWJsZS5vcHRpb25zLCB0cnVlKSk7XG4gIHZhciBjaGlsZENvbnRhaW5pbmdSZWN0ID0gZ2V0Q2hpbGRDb250YWluaW5nUmVjdEZyb21FbGVtZW50KHNvcnRhYmxlLmVsLCBzb3J0YWJsZS5vcHRpb25zLCBnaG9zdEVsKTtcbiAgdmFyIHNwYWNlciA9IDEwO1xuICByZXR1cm4gdmVydGljYWwgPyBldnQuY2xpZW50WCA8IGNoaWxkQ29udGFpbmluZ1JlY3QubGVmdCAtIHNwYWNlciB8fCBldnQuY2xpZW50WSA8IGZpcnN0RWxSZWN0LnRvcCAmJiBldnQuY2xpZW50WCA8IGZpcnN0RWxSZWN0LnJpZ2h0IDogZXZ0LmNsaWVudFkgPCBjaGlsZENvbnRhaW5pbmdSZWN0LnRvcCAtIHNwYWNlciB8fCBldnQuY2xpZW50WSA8IGZpcnN0RWxSZWN0LmJvdHRvbSAmJiBldnQuY2xpZW50WCA8IGZpcnN0RWxSZWN0LmxlZnQ7XG59XG5mdW5jdGlvbiBfZ2hvc3RJc0xhc3QoZXZ0LCB2ZXJ0aWNhbCwgc29ydGFibGUpIHtcbiAgdmFyIGxhc3RFbFJlY3QgPSBnZXRSZWN0KGxhc3RDaGlsZChzb3J0YWJsZS5lbCwgc29ydGFibGUub3B0aW9ucy5kcmFnZ2FibGUpKTtcbiAgdmFyIGNoaWxkQ29udGFpbmluZ1JlY3QgPSBnZXRDaGlsZENvbnRhaW5pbmdSZWN0RnJvbUVsZW1lbnQoc29ydGFibGUuZWwsIHNvcnRhYmxlLm9wdGlvbnMsIGdob3N0RWwpO1xuICB2YXIgc3BhY2VyID0gMTA7XG4gIHJldHVybiB2ZXJ0aWNhbCA/IGV2dC5jbGllbnRYID4gY2hpbGRDb250YWluaW5nUmVjdC5yaWdodCArIHNwYWNlciB8fCBldnQuY2xpZW50WSA+IGxhc3RFbFJlY3QuYm90dG9tICYmIGV2dC5jbGllbnRYID4gbGFzdEVsUmVjdC5sZWZ0IDogZXZ0LmNsaWVudFkgPiBjaGlsZENvbnRhaW5pbmdSZWN0LmJvdHRvbSArIHNwYWNlciB8fCBldnQuY2xpZW50WCA+IGxhc3RFbFJlY3QucmlnaHQgJiYgZXZ0LmNsaWVudFkgPiBsYXN0RWxSZWN0LnRvcDtcbn1cbmZ1bmN0aW9uIF9nZXRTd2FwRGlyZWN0aW9uKGV2dCwgdGFyZ2V0LCB0YXJnZXRSZWN0LCB2ZXJ0aWNhbCwgc3dhcFRocmVzaG9sZCwgaW52ZXJ0ZWRTd2FwVGhyZXNob2xkLCBpbnZlcnRTd2FwLCBpc0xhc3RUYXJnZXQpIHtcbiAgdmFyIG1vdXNlT25BeGlzID0gdmVydGljYWwgPyBldnQuY2xpZW50WSA6IGV2dC5jbGllbnRYLFxuICAgIHRhcmdldExlbmd0aCA9IHZlcnRpY2FsID8gdGFyZ2V0UmVjdC5oZWlnaHQgOiB0YXJnZXRSZWN0LndpZHRoLFxuICAgIHRhcmdldFMxID0gdmVydGljYWwgPyB0YXJnZXRSZWN0LnRvcCA6IHRhcmdldFJlY3QubGVmdCxcbiAgICB0YXJnZXRTMiA9IHZlcnRpY2FsID8gdGFyZ2V0UmVjdC5ib3R0b20gOiB0YXJnZXRSZWN0LnJpZ2h0LFxuICAgIGludmVydCA9IGZhbHNlO1xuICBpZiAoIWludmVydFN3YXApIHtcbiAgICAvLyBOZXZlciBpbnZlcnQgb3IgY3JlYXRlIGRyYWdFbCBzaGFkb3cgd2hlbiB0YXJnZXQgbW92ZW1lbmV0IGNhdXNlcyBtb3VzZSB0byBtb3ZlIHBhc3QgdGhlIGVuZCBvZiByZWd1bGFyIHN3YXBUaHJlc2hvbGRcbiAgICBpZiAoaXNMYXN0VGFyZ2V0ICYmIHRhcmdldE1vdmVEaXN0YW5jZSA8IHRhcmdldExlbmd0aCAqIHN3YXBUaHJlc2hvbGQpIHtcbiAgICAgIC8vIG11bHRpcGxpZWQgb25seSBieSBzd2FwVGhyZXNob2xkIGJlY2F1c2UgbW91c2Ugd2lsbCBhbHJlYWR5IGJlIGluc2lkZSB0YXJnZXQgYnkgKDEgLSB0aHJlc2hvbGQpICogdGFyZ2V0TGVuZ3RoIC8gMlxuICAgICAgLy8gY2hlY2sgaWYgcGFzdCBmaXJzdCBpbnZlcnQgdGhyZXNob2xkIG9uIHNpZGUgb3Bwb3NpdGUgb2YgbGFzdERpcmVjdGlvblxuICAgICAgaWYgKCFwYXN0Rmlyc3RJbnZlcnRUaHJlc2ggJiYgKGxhc3REaXJlY3Rpb24gPT09IDEgPyBtb3VzZU9uQXhpcyA+IHRhcmdldFMxICsgdGFyZ2V0TGVuZ3RoICogaW52ZXJ0ZWRTd2FwVGhyZXNob2xkIC8gMiA6IG1vdXNlT25BeGlzIDwgdGFyZ2V0UzIgLSB0YXJnZXRMZW5ndGggKiBpbnZlcnRlZFN3YXBUaHJlc2hvbGQgLyAyKSkge1xuICAgICAgICAvLyBwYXN0IGZpcnN0IGludmVydCB0aHJlc2hvbGQsIGRvIG5vdCByZXN0cmljdCBpbnZlcnRlZCB0aHJlc2hvbGQgdG8gZHJhZ0VsIHNoYWRvd1xuICAgICAgICBwYXN0Rmlyc3RJbnZlcnRUaHJlc2ggPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKCFwYXN0Rmlyc3RJbnZlcnRUaHJlc2gpIHtcbiAgICAgICAgLy8gZHJhZ0VsIHNoYWRvdyAodGFyZ2V0IG1vdmUgZGlzdGFuY2Ugc2hhZG93KVxuICAgICAgICBpZiAobGFzdERpcmVjdGlvbiA9PT0gMSA/IG1vdXNlT25BeGlzIDwgdGFyZ2V0UzEgKyB0YXJnZXRNb3ZlRGlzdGFuY2UgLy8gb3ZlciBkcmFnRWwgc2hhZG93XG4gICAgICAgIDogbW91c2VPbkF4aXMgPiB0YXJnZXRTMiAtIHRhcmdldE1vdmVEaXN0YW5jZSkge1xuICAgICAgICAgIHJldHVybiAtbGFzdERpcmVjdGlvbjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW52ZXJ0ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmVndWxhclxuICAgICAgaWYgKG1vdXNlT25BeGlzID4gdGFyZ2V0UzEgKyB0YXJnZXRMZW5ndGggKiAoMSAtIHN3YXBUaHJlc2hvbGQpIC8gMiAmJiBtb3VzZU9uQXhpcyA8IHRhcmdldFMyIC0gdGFyZ2V0TGVuZ3RoICogKDEgLSBzd2FwVGhyZXNob2xkKSAvIDIpIHtcbiAgICAgICAgcmV0dXJuIF9nZXRJbnNlcnREaXJlY3Rpb24odGFyZ2V0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaW52ZXJ0ID0gaW52ZXJ0IHx8IGludmVydFN3YXA7XG4gIGlmIChpbnZlcnQpIHtcbiAgICAvLyBJbnZlcnQgb2YgcmVndWxhclxuICAgIGlmIChtb3VzZU9uQXhpcyA8IHRhcmdldFMxICsgdGFyZ2V0TGVuZ3RoICogaW52ZXJ0ZWRTd2FwVGhyZXNob2xkIC8gMiB8fCBtb3VzZU9uQXhpcyA+IHRhcmdldFMyIC0gdGFyZ2V0TGVuZ3RoICogaW52ZXJ0ZWRTd2FwVGhyZXNob2xkIC8gMikge1xuICAgICAgcmV0dXJuIG1vdXNlT25BeGlzID4gdGFyZ2V0UzEgKyB0YXJnZXRMZW5ndGggLyAyID8gMSA6IC0xO1xuICAgIH1cbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLyoqXHJcbiAqIEdldHMgdGhlIGRpcmVjdGlvbiBkcmFnRWwgbXVzdCBiZSBzd2FwcGVkIHJlbGF0aXZlIHRvIHRhcmdldCBpbiBvcmRlciB0byBtYWtlIGl0XHJcbiAqIHNlZW0gdGhhdCBkcmFnRWwgaGFzIGJlZW4gXCJpbnNlcnRlZFwiIGludG8gdGhhdCBlbGVtZW50J3MgcG9zaXRpb25cclxuICogQHBhcmFtICB7SFRNTEVsZW1lbnR9IHRhcmdldCAgICAgICBUaGUgdGFyZ2V0IHdob3NlIHBvc2l0aW9uIGRyYWdFbCBpcyBiZWluZyBpbnNlcnRlZCBhdFxyXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgICAgICAgICAgICAgIERpcmVjdGlvbiBkcmFnRWwgbXVzdCBiZSBzd2FwcGVkXHJcbiAqL1xuZnVuY3Rpb24gX2dldEluc2VydERpcmVjdGlvbih0YXJnZXQpIHtcbiAgaWYgKGluZGV4KGRyYWdFbCkgPCBpbmRleCh0YXJnZXQpKSB7XG4gICAgcmV0dXJuIDE7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG59XG5cbi8qKlxyXG4gKiBHZW5lcmF0ZSBpZFxyXG4gKiBAcGFyYW0gICB7SFRNTEVsZW1lbnR9IGVsXHJcbiAqIEByZXR1cm5zIHtTdHJpbmd9XHJcbiAqIEBwcml2YXRlXHJcbiAqL1xuZnVuY3Rpb24gX2dlbmVyYXRlSWQoZWwpIHtcbiAgdmFyIHN0ciA9IGVsLnRhZ05hbWUgKyBlbC5jbGFzc05hbWUgKyBlbC5zcmMgKyBlbC5ocmVmICsgZWwudGV4dENvbnRlbnQsXG4gICAgaSA9IHN0ci5sZW5ndGgsXG4gICAgc3VtID0gMDtcbiAgd2hpbGUgKGktLSkge1xuICAgIHN1bSArPSBzdHIuY2hhckNvZGVBdChpKTtcbiAgfVxuICByZXR1cm4gc3VtLnRvU3RyaW5nKDM2KTtcbn1cbmZ1bmN0aW9uIF9zYXZlSW5wdXRDaGVja2VkU3RhdGUocm9vdCkge1xuICBzYXZlZElucHV0Q2hlY2tlZC5sZW5ndGggPSAwO1xuICB2YXIgaW5wdXRzID0gcm9vdC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaW5wdXQnKTtcbiAgdmFyIGlkeCA9IGlucHV0cy5sZW5ndGg7XG4gIHdoaWxlIChpZHgtLSkge1xuICAgIHZhciBlbCA9IGlucHV0c1tpZHhdO1xuICAgIGVsLmNoZWNrZWQgJiYgc2F2ZWRJbnB1dENoZWNrZWQucHVzaChlbCk7XG4gIH1cbn1cbmZ1bmN0aW9uIF9uZXh0VGljayhmbikge1xuICByZXR1cm4gc2V0VGltZW91dChmbiwgMCk7XG59XG5mdW5jdGlvbiBfY2FuY2VsTmV4dFRpY2soaWQpIHtcbiAgcmV0dXJuIGNsZWFyVGltZW91dChpZCk7XG59XG5cbi8vIEZpeGVkICM5NzM6XG5pZiAoZG9jdW1lbnRFeGlzdHMpIHtcbiAgb24oZG9jdW1lbnQsICd0b3VjaG1vdmUnLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgaWYgKChTb3J0YWJsZS5hY3RpdmUgfHwgYXdhaXRpbmdEcmFnU3RhcnRlZCkgJiYgZXZ0LmNhbmNlbGFibGUpIHtcbiAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfSk7XG59XG5cbi8vIEV4cG9ydCB1dGlsc1xuU29ydGFibGUudXRpbHMgPSB7XG4gIG9uOiBvbixcbiAgb2ZmOiBvZmYsXG4gIGNzczogY3NzLFxuICBmaW5kOiBmaW5kLFxuICBpczogZnVuY3Rpb24gaXMoZWwsIHNlbGVjdG9yKSB7XG4gICAgcmV0dXJuICEhY2xvc2VzdChlbCwgc2VsZWN0b3IsIGVsLCBmYWxzZSk7XG4gIH0sXG4gIGV4dGVuZDogZXh0ZW5kLFxuICB0aHJvdHRsZTogdGhyb3R0bGUsXG4gIGNsb3Nlc3Q6IGNsb3Nlc3QsXG4gIHRvZ2dsZUNsYXNzOiB0b2dnbGVDbGFzcyxcbiAgY2xvbmU6IGNsb25lLFxuICBpbmRleDogaW5kZXgsXG4gIG5leHRUaWNrOiBfbmV4dFRpY2ssXG4gIGNhbmNlbE5leHRUaWNrOiBfY2FuY2VsTmV4dFRpY2ssXG4gIGRldGVjdERpcmVjdGlvbjogX2RldGVjdERpcmVjdGlvbixcbiAgZ2V0Q2hpbGQ6IGdldENoaWxkLFxuICBleHBhbmRvOiBleHBhbmRvXG59O1xuXG4vKipcclxuICogR2V0IHRoZSBTb3J0YWJsZSBpbnN0YW5jZSBvZiBhbiBlbGVtZW50XHJcbiAqIEBwYXJhbSAge0hUTUxFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50XHJcbiAqIEByZXR1cm4ge1NvcnRhYmxlfHVuZGVmaW5lZH0gICAgICAgICBUaGUgaW5zdGFuY2Ugb2YgU29ydGFibGVcclxuICovXG5Tb3J0YWJsZS5nZXQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudFtleHBhbmRvXTtcbn07XG5cbi8qKlxyXG4gKiBNb3VudCBhIHBsdWdpbiB0byBTb3J0YWJsZVxyXG4gKiBAcGFyYW0gIHsuLi5Tb3J0YWJsZVBsdWdpbnxTb3J0YWJsZVBsdWdpbltdfSBwbHVnaW5zICAgICAgIFBsdWdpbnMgYmVpbmcgbW91bnRlZFxyXG4gKi9cblNvcnRhYmxlLm1vdW50ID0gZnVuY3Rpb24gKCkge1xuICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgcGx1Z2lucyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICBwbHVnaW5zW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICB9XG4gIGlmIChwbHVnaW5zWzBdLmNvbnN0cnVjdG9yID09PSBBcnJheSkgcGx1Z2lucyA9IHBsdWdpbnNbMF07XG4gIHBsdWdpbnMuZm9yRWFjaChmdW5jdGlvbiAocGx1Z2luKSB7XG4gICAgaWYgKCFwbHVnaW4ucHJvdG90eXBlIHx8ICFwbHVnaW4ucHJvdG90eXBlLmNvbnN0cnVjdG9yKSB7XG4gICAgICB0aHJvdyBcIlNvcnRhYmxlOiBNb3VudGVkIHBsdWdpbiBtdXN0IGJlIGEgY29uc3RydWN0b3IgZnVuY3Rpb24sIG5vdCBcIi5jb25jYXQoe30udG9TdHJpbmcuY2FsbChwbHVnaW4pKTtcbiAgICB9XG4gICAgaWYgKHBsdWdpbi51dGlscykgU29ydGFibGUudXRpbHMgPSBfb2JqZWN0U3ByZWFkMihfb2JqZWN0U3ByZWFkMih7fSwgU29ydGFibGUudXRpbHMpLCBwbHVnaW4udXRpbHMpO1xuICAgIFBsdWdpbk1hbmFnZXIubW91bnQocGx1Z2luKTtcbiAgfSk7XG59O1xuXG4vKipcclxuICogQ3JlYXRlIHNvcnRhYmxlIGluc3RhbmNlXHJcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9ICBlbFxyXG4gKiBAcGFyYW0ge09iamVjdH0gICAgICBbb3B0aW9uc11cclxuICovXG5Tb3J0YWJsZS5jcmVhdGUgPSBmdW5jdGlvbiAoZWwsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBTb3J0YWJsZShlbCwgb3B0aW9ucyk7XG59O1xuXG4vLyBFeHBvcnRcblNvcnRhYmxlLnZlcnNpb24gPSB2ZXJzaW9uO1xuXG52YXIgYXV0b1Njcm9sbHMgPSBbXSxcbiAgc2Nyb2xsRWwsXG4gIHNjcm9sbFJvb3RFbCxcbiAgc2Nyb2xsaW5nID0gZmFsc2UsXG4gIGxhc3RBdXRvU2Nyb2xsWCxcbiAgbGFzdEF1dG9TY3JvbGxZLFxuICB0b3VjaEV2dCQxLFxuICBwb2ludGVyRWxlbUNoYW5nZWRJbnRlcnZhbDtcbmZ1bmN0aW9uIEF1dG9TY3JvbGxQbHVnaW4oKSB7XG4gIGZ1bmN0aW9uIEF1dG9TY3JvbGwoKSB7XG4gICAgdGhpcy5kZWZhdWx0cyA9IHtcbiAgICAgIHNjcm9sbDogdHJ1ZSxcbiAgICAgIGZvcmNlQXV0b1Njcm9sbEZhbGxiYWNrOiBmYWxzZSxcbiAgICAgIHNjcm9sbFNlbnNpdGl2aXR5OiAzMCxcbiAgICAgIHNjcm9sbFNwZWVkOiAxMCxcbiAgICAgIGJ1YmJsZVNjcm9sbDogdHJ1ZVxuICAgIH07XG5cbiAgICAvLyBCaW5kIGFsbCBwcml2YXRlIG1ldGhvZHNcbiAgICBmb3IgKHZhciBmbiBpbiB0aGlzKSB7XG4gICAgICBpZiAoZm4uY2hhckF0KDApID09PSAnXycgJiYgdHlwZW9mIHRoaXNbZm5dID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRoaXNbZm5dID0gdGhpc1tmbl0uYmluZCh0aGlzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgQXV0b1Njcm9sbC5wcm90b3R5cGUgPSB7XG4gICAgZHJhZ1N0YXJ0ZWQ6IGZ1bmN0aW9uIGRyYWdTdGFydGVkKF9yZWYpIHtcbiAgICAgIHZhciBvcmlnaW5hbEV2ZW50ID0gX3JlZi5vcmlnaW5hbEV2ZW50O1xuICAgICAgaWYgKHRoaXMuc29ydGFibGUubmF0aXZlRHJhZ2dhYmxlKSB7XG4gICAgICAgIG9uKGRvY3VtZW50LCAnZHJhZ292ZXInLCB0aGlzLl9oYW5kbGVBdXRvU2Nyb2xsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc3VwcG9ydFBvaW50ZXIpIHtcbiAgICAgICAgICBvbihkb2N1bWVudCwgJ3BvaW50ZXJtb3ZlJywgdGhpcy5faGFuZGxlRmFsbGJhY2tBdXRvU2Nyb2xsKTtcbiAgICAgICAgfSBlbHNlIGlmIChvcmlnaW5hbEV2ZW50LnRvdWNoZXMpIHtcbiAgICAgICAgICBvbihkb2N1bWVudCwgJ3RvdWNobW92ZScsIHRoaXMuX2hhbmRsZUZhbGxiYWNrQXV0b1Njcm9sbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb24oZG9jdW1lbnQsICdtb3VzZW1vdmUnLCB0aGlzLl9oYW5kbGVGYWxsYmFja0F1dG9TY3JvbGwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBkcmFnT3ZlckNvbXBsZXRlZDogZnVuY3Rpb24gZHJhZ092ZXJDb21wbGV0ZWQoX3JlZjIpIHtcbiAgICAgIHZhciBvcmlnaW5hbEV2ZW50ID0gX3JlZjIub3JpZ2luYWxFdmVudDtcbiAgICAgIC8vIEZvciB3aGVuIGJ1YmJsaW5nIGlzIGNhbmNlbGVkIGFuZCB1c2luZyBmYWxsYmFjayAoZmFsbGJhY2sgJ3RvdWNobW92ZScgYWx3YXlzIHJlYWNoZWQpXG4gICAgICBpZiAoIXRoaXMub3B0aW9ucy5kcmFnT3ZlckJ1YmJsZSAmJiAhb3JpZ2luYWxFdmVudC5yb290RWwpIHtcbiAgICAgICAgdGhpcy5faGFuZGxlQXV0b1Njcm9sbChvcmlnaW5hbEV2ZW50KTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGRyb3A6IGZ1bmN0aW9uIGRyb3AoKSB7XG4gICAgICBpZiAodGhpcy5zb3J0YWJsZS5uYXRpdmVEcmFnZ2FibGUpIHtcbiAgICAgICAgb2ZmKGRvY3VtZW50LCAnZHJhZ292ZXInLCB0aGlzLl9oYW5kbGVBdXRvU2Nyb2xsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9mZihkb2N1bWVudCwgJ3BvaW50ZXJtb3ZlJywgdGhpcy5faGFuZGxlRmFsbGJhY2tBdXRvU2Nyb2xsKTtcbiAgICAgICAgb2ZmKGRvY3VtZW50LCAndG91Y2htb3ZlJywgdGhpcy5faGFuZGxlRmFsbGJhY2tBdXRvU2Nyb2xsKTtcbiAgICAgICAgb2ZmKGRvY3VtZW50LCAnbW91c2Vtb3ZlJywgdGhpcy5faGFuZGxlRmFsbGJhY2tBdXRvU2Nyb2xsKTtcbiAgICAgIH1cbiAgICAgIGNsZWFyUG9pbnRlckVsZW1DaGFuZ2VkSW50ZXJ2YWwoKTtcbiAgICAgIGNsZWFyQXV0b1Njcm9sbHMoKTtcbiAgICAgIGNhbmNlbFRocm90dGxlKCk7XG4gICAgfSxcbiAgICBudWxsaW5nOiBmdW5jdGlvbiBudWxsaW5nKCkge1xuICAgICAgdG91Y2hFdnQkMSA9IHNjcm9sbFJvb3RFbCA9IHNjcm9sbEVsID0gc2Nyb2xsaW5nID0gcG9pbnRlckVsZW1DaGFuZ2VkSW50ZXJ2YWwgPSBsYXN0QXV0b1Njcm9sbFggPSBsYXN0QXV0b1Njcm9sbFkgPSBudWxsO1xuICAgICAgYXV0b1Njcm9sbHMubGVuZ3RoID0gMDtcbiAgICB9LFxuICAgIF9oYW5kbGVGYWxsYmFja0F1dG9TY3JvbGw6IGZ1bmN0aW9uIF9oYW5kbGVGYWxsYmFja0F1dG9TY3JvbGwoZXZ0KSB7XG4gICAgICB0aGlzLl9oYW5kbGVBdXRvU2Nyb2xsKGV2dCwgdHJ1ZSk7XG4gICAgfSxcbiAgICBfaGFuZGxlQXV0b1Njcm9sbDogZnVuY3Rpb24gX2hhbmRsZUF1dG9TY3JvbGwoZXZ0LCBmYWxsYmFjaykge1xuICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgIHZhciB4ID0gKGV2dC50b3VjaGVzID8gZXZ0LnRvdWNoZXNbMF0gOiBldnQpLmNsaWVudFgsXG4gICAgICAgIHkgPSAoZXZ0LnRvdWNoZXMgPyBldnQudG91Y2hlc1swXSA6IGV2dCkuY2xpZW50WSxcbiAgICAgICAgZWxlbSA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoeCwgeSk7XG4gICAgICB0b3VjaEV2dCQxID0gZXZ0O1xuXG4gICAgICAvLyBJRSBkb2VzIG5vdCBzZWVtIHRvIGhhdmUgbmF0aXZlIGF1dG9zY3JvbGwsXG4gICAgICAvLyBFZGdlJ3MgYXV0b3Njcm9sbCBzZWVtcyB0b28gY29uZGl0aW9uYWwsXG4gICAgICAvLyBNQUNPUyBTYWZhcmkgZG9lcyBub3QgaGF2ZSBhdXRvc2Nyb2xsLFxuICAgICAgLy8gRmlyZWZveCBhbmQgQ2hyb21lIGFyZSBnb29kXG4gICAgICBpZiAoZmFsbGJhY2sgfHwgdGhpcy5vcHRpb25zLmZvcmNlQXV0b1Njcm9sbEZhbGxiYWNrIHx8IEVkZ2UgfHwgSUUxMU9yTGVzcyB8fCBTYWZhcmkpIHtcbiAgICAgICAgYXV0b1Njcm9sbChldnQsIHRoaXMub3B0aW9ucywgZWxlbSwgZmFsbGJhY2spO1xuXG4gICAgICAgIC8vIExpc3RlbmVyIGZvciBwb2ludGVyIGVsZW1lbnQgY2hhbmdlXG4gICAgICAgIHZhciBvZ0VsZW1TY3JvbGxlciA9IGdldFBhcmVudEF1dG9TY3JvbGxFbGVtZW50KGVsZW0sIHRydWUpO1xuICAgICAgICBpZiAoc2Nyb2xsaW5nICYmICghcG9pbnRlckVsZW1DaGFuZ2VkSW50ZXJ2YWwgfHwgeCAhPT0gbGFzdEF1dG9TY3JvbGxYIHx8IHkgIT09IGxhc3RBdXRvU2Nyb2xsWSkpIHtcbiAgICAgICAgICBwb2ludGVyRWxlbUNoYW5nZWRJbnRlcnZhbCAmJiBjbGVhclBvaW50ZXJFbGVtQ2hhbmdlZEludGVydmFsKCk7XG4gICAgICAgICAgLy8gRGV0ZWN0IGZvciBwb2ludGVyIGVsZW0gY2hhbmdlLCBlbXVsYXRpbmcgbmF0aXZlIERuRCBiZWhhdmlvdXJcbiAgICAgICAgICBwb2ludGVyRWxlbUNoYW5nZWRJbnRlcnZhbCA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBuZXdFbGVtID0gZ2V0UGFyZW50QXV0b1Njcm9sbEVsZW1lbnQoZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludCh4LCB5KSwgdHJ1ZSk7XG4gICAgICAgICAgICBpZiAobmV3RWxlbSAhPT0gb2dFbGVtU2Nyb2xsZXIpIHtcbiAgICAgICAgICAgICAgb2dFbGVtU2Nyb2xsZXIgPSBuZXdFbGVtO1xuICAgICAgICAgICAgICBjbGVhckF1dG9TY3JvbGxzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhdXRvU2Nyb2xsKGV2dCwgX3RoaXMub3B0aW9ucywgbmV3RWxlbSwgZmFsbGJhY2spO1xuICAgICAgICAgIH0sIDEwKTtcbiAgICAgICAgICBsYXN0QXV0b1Njcm9sbFggPSB4O1xuICAgICAgICAgIGxhc3RBdXRvU2Nyb2xsWSA9IHk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGlmIERuRCBpcyBlbmFibGVkIChhbmQgYnJvd3NlciBoYXMgZ29vZCBhdXRvc2Nyb2xsaW5nKSwgZmlyc3QgYXV0b3Njcm9sbCB3aWxsIGFscmVhZHkgc2Nyb2xsLCBzbyBnZXQgcGFyZW50IGF1dG9zY3JvbGwgb2YgZmlyc3QgYXV0b3Njcm9sbFxuICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5idWJibGVTY3JvbGwgfHwgZ2V0UGFyZW50QXV0b1Njcm9sbEVsZW1lbnQoZWxlbSwgdHJ1ZSkgPT09IGdldFdpbmRvd1Njcm9sbGluZ0VsZW1lbnQoKSkge1xuICAgICAgICAgIGNsZWFyQXV0b1Njcm9sbHMoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgYXV0b1Njcm9sbChldnQsIHRoaXMub3B0aW9ucywgZ2V0UGFyZW50QXV0b1Njcm9sbEVsZW1lbnQoZWxlbSwgZmFsc2UpLCBmYWxzZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICByZXR1cm4gX2V4dGVuZHMoQXV0b1Njcm9sbCwge1xuICAgIHBsdWdpbk5hbWU6ICdzY3JvbGwnLFxuICAgIGluaXRpYWxpemVCeURlZmF1bHQ6IHRydWVcbiAgfSk7XG59XG5mdW5jdGlvbiBjbGVhckF1dG9TY3JvbGxzKCkge1xuICBhdXRvU2Nyb2xscy5mb3JFYWNoKGZ1bmN0aW9uIChhdXRvU2Nyb2xsKSB7XG4gICAgY2xlYXJJbnRlcnZhbChhdXRvU2Nyb2xsLnBpZCk7XG4gIH0pO1xuICBhdXRvU2Nyb2xscyA9IFtdO1xufVxuZnVuY3Rpb24gY2xlYXJQb2ludGVyRWxlbUNoYW5nZWRJbnRlcnZhbCgpIHtcbiAgY2xlYXJJbnRlcnZhbChwb2ludGVyRWxlbUNoYW5nZWRJbnRlcnZhbCk7XG59XG52YXIgYXV0b1Njcm9sbCA9IHRocm90dGxlKGZ1bmN0aW9uIChldnQsIG9wdGlvbnMsIHJvb3RFbCwgaXNGYWxsYmFjaykge1xuICAvLyBCdWc6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTUwNTUyMVxuICBpZiAoIW9wdGlvbnMuc2Nyb2xsKSByZXR1cm47XG4gIHZhciB4ID0gKGV2dC50b3VjaGVzID8gZXZ0LnRvdWNoZXNbMF0gOiBldnQpLmNsaWVudFgsXG4gICAgeSA9IChldnQudG91Y2hlcyA/IGV2dC50b3VjaGVzWzBdIDogZXZ0KS5jbGllbnRZLFxuICAgIHNlbnMgPSBvcHRpb25zLnNjcm9sbFNlbnNpdGl2aXR5LFxuICAgIHNwZWVkID0gb3B0aW9ucy5zY3JvbGxTcGVlZCxcbiAgICB3aW5TY3JvbGxlciA9IGdldFdpbmRvd1Njcm9sbGluZ0VsZW1lbnQoKTtcbiAgdmFyIHNjcm9sbFRoaXNJbnN0YW5jZSA9IGZhbHNlLFxuICAgIHNjcm9sbEN1c3RvbUZuO1xuXG4gIC8vIE5ldyBzY3JvbGwgcm9vdCwgc2V0IHNjcm9sbEVsXG4gIGlmIChzY3JvbGxSb290RWwgIT09IHJvb3RFbCkge1xuICAgIHNjcm9sbFJvb3RFbCA9IHJvb3RFbDtcbiAgICBjbGVhckF1dG9TY3JvbGxzKCk7XG4gICAgc2Nyb2xsRWwgPSBvcHRpb25zLnNjcm9sbDtcbiAgICBzY3JvbGxDdXN0b21GbiA9IG9wdGlvbnMuc2Nyb2xsRm47XG4gICAgaWYgKHNjcm9sbEVsID09PSB0cnVlKSB7XG4gICAgICBzY3JvbGxFbCA9IGdldFBhcmVudEF1dG9TY3JvbGxFbGVtZW50KHJvb3RFbCwgdHJ1ZSk7XG4gICAgfVxuICB9XG4gIHZhciBsYXllcnNPdXQgPSAwO1xuICB2YXIgY3VycmVudFBhcmVudCA9IHNjcm9sbEVsO1xuICBkbyB7XG4gICAgdmFyIGVsID0gY3VycmVudFBhcmVudCxcbiAgICAgIHJlY3QgPSBnZXRSZWN0KGVsKSxcbiAgICAgIHRvcCA9IHJlY3QudG9wLFxuICAgICAgYm90dG9tID0gcmVjdC5ib3R0b20sXG4gICAgICBsZWZ0ID0gcmVjdC5sZWZ0LFxuICAgICAgcmlnaHQgPSByZWN0LnJpZ2h0LFxuICAgICAgd2lkdGggPSByZWN0LndpZHRoLFxuICAgICAgaGVpZ2h0ID0gcmVjdC5oZWlnaHQsXG4gICAgICBjYW5TY3JvbGxYID0gdm9pZCAwLFxuICAgICAgY2FuU2Nyb2xsWSA9IHZvaWQgMCxcbiAgICAgIHNjcm9sbFdpZHRoID0gZWwuc2Nyb2xsV2lkdGgsXG4gICAgICBzY3JvbGxIZWlnaHQgPSBlbC5zY3JvbGxIZWlnaHQsXG4gICAgICBlbENTUyA9IGNzcyhlbCksXG4gICAgICBzY3JvbGxQb3NYID0gZWwuc2Nyb2xsTGVmdCxcbiAgICAgIHNjcm9sbFBvc1kgPSBlbC5zY3JvbGxUb3A7XG4gICAgaWYgKGVsID09PSB3aW5TY3JvbGxlcikge1xuICAgICAgY2FuU2Nyb2xsWCA9IHdpZHRoIDwgc2Nyb2xsV2lkdGggJiYgKGVsQ1NTLm92ZXJmbG93WCA9PT0gJ2F1dG8nIHx8IGVsQ1NTLm92ZXJmbG93WCA9PT0gJ3Njcm9sbCcgfHwgZWxDU1Mub3ZlcmZsb3dYID09PSAndmlzaWJsZScpO1xuICAgICAgY2FuU2Nyb2xsWSA9IGhlaWdodCA8IHNjcm9sbEhlaWdodCAmJiAoZWxDU1Mub3ZlcmZsb3dZID09PSAnYXV0bycgfHwgZWxDU1Mub3ZlcmZsb3dZID09PSAnc2Nyb2xsJyB8fCBlbENTUy5vdmVyZmxvd1kgPT09ICd2aXNpYmxlJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhblNjcm9sbFggPSB3aWR0aCA8IHNjcm9sbFdpZHRoICYmIChlbENTUy5vdmVyZmxvd1ggPT09ICdhdXRvJyB8fCBlbENTUy5vdmVyZmxvd1ggPT09ICdzY3JvbGwnKTtcbiAgICAgIGNhblNjcm9sbFkgPSBoZWlnaHQgPCBzY3JvbGxIZWlnaHQgJiYgKGVsQ1NTLm92ZXJmbG93WSA9PT0gJ2F1dG8nIHx8IGVsQ1NTLm92ZXJmbG93WSA9PT0gJ3Njcm9sbCcpO1xuICAgIH1cbiAgICB2YXIgdnggPSBjYW5TY3JvbGxYICYmIChNYXRoLmFicyhyaWdodCAtIHgpIDw9IHNlbnMgJiYgc2Nyb2xsUG9zWCArIHdpZHRoIDwgc2Nyb2xsV2lkdGgpIC0gKE1hdGguYWJzKGxlZnQgLSB4KSA8PSBzZW5zICYmICEhc2Nyb2xsUG9zWCk7XG4gICAgdmFyIHZ5ID0gY2FuU2Nyb2xsWSAmJiAoTWF0aC5hYnMoYm90dG9tIC0geSkgPD0gc2VucyAmJiBzY3JvbGxQb3NZICsgaGVpZ2h0IDwgc2Nyb2xsSGVpZ2h0KSAtIChNYXRoLmFicyh0b3AgLSB5KSA8PSBzZW5zICYmICEhc2Nyb2xsUG9zWSk7XG4gICAgaWYgKCFhdXRvU2Nyb2xsc1tsYXllcnNPdXRdKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8PSBsYXllcnNPdXQ7IGkrKykge1xuICAgICAgICBpZiAoIWF1dG9TY3JvbGxzW2ldKSB7XG4gICAgICAgICAgYXV0b1Njcm9sbHNbaV0gPSB7fTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoYXV0b1Njcm9sbHNbbGF5ZXJzT3V0XS52eCAhPSB2eCB8fCBhdXRvU2Nyb2xsc1tsYXllcnNPdXRdLnZ5ICE9IHZ5IHx8IGF1dG9TY3JvbGxzW2xheWVyc091dF0uZWwgIT09IGVsKSB7XG4gICAgICBhdXRvU2Nyb2xsc1tsYXllcnNPdXRdLmVsID0gZWw7XG4gICAgICBhdXRvU2Nyb2xsc1tsYXllcnNPdXRdLnZ4ID0gdng7XG4gICAgICBhdXRvU2Nyb2xsc1tsYXllcnNPdXRdLnZ5ID0gdnk7XG4gICAgICBjbGVhckludGVydmFsKGF1dG9TY3JvbGxzW2xheWVyc091dF0ucGlkKTtcbiAgICAgIGlmICh2eCAhPSAwIHx8IHZ5ICE9IDApIHtcbiAgICAgICAgc2Nyb2xsVGhpc0luc3RhbmNlID0gdHJ1ZTtcbiAgICAgICAgLyoganNoaW50IGxvb3BmdW5jOnRydWUgKi9cbiAgICAgICAgYXV0b1Njcm9sbHNbbGF5ZXJzT3V0XS5waWQgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgLy8gZW11bGF0ZSBkcmFnIG92ZXIgZHVyaW5nIGF1dG9zY3JvbGwgKGZhbGxiYWNrKSwgZW11bGF0aW5nIG5hdGl2ZSBEbkQgYmVoYXZpb3VyXG4gICAgICAgICAgaWYgKGlzRmFsbGJhY2sgJiYgdGhpcy5sYXllciA9PT0gMCkge1xuICAgICAgICAgICAgU29ydGFibGUuYWN0aXZlLl9vblRvdWNoTW92ZSh0b3VjaEV2dCQxKTsgLy8gVG8gbW92ZSBnaG9zdCBpZiBpdCBpcyBwb3NpdGlvbmVkIGFic29sdXRlbHlcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIHNjcm9sbE9mZnNldFkgPSBhdXRvU2Nyb2xsc1t0aGlzLmxheWVyXS52eSA/IGF1dG9TY3JvbGxzW3RoaXMubGF5ZXJdLnZ5ICogc3BlZWQgOiAwO1xuICAgICAgICAgIHZhciBzY3JvbGxPZmZzZXRYID0gYXV0b1Njcm9sbHNbdGhpcy5sYXllcl0udnggPyBhdXRvU2Nyb2xsc1t0aGlzLmxheWVyXS52eCAqIHNwZWVkIDogMDtcbiAgICAgICAgICBpZiAodHlwZW9mIHNjcm9sbEN1c3RvbUZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBpZiAoc2Nyb2xsQ3VzdG9tRm4uY2FsbChTb3J0YWJsZS5kcmFnZ2VkLnBhcmVudE5vZGVbZXhwYW5kb10sIHNjcm9sbE9mZnNldFgsIHNjcm9sbE9mZnNldFksIGV2dCwgdG91Y2hFdnQkMSwgYXV0b1Njcm9sbHNbdGhpcy5sYXllcl0uZWwpICE9PSAnY29udGludWUnKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgc2Nyb2xsQnkoYXV0b1Njcm9sbHNbdGhpcy5sYXllcl0uZWwsIHNjcm9sbE9mZnNldFgsIHNjcm9sbE9mZnNldFkpO1xuICAgICAgICB9LmJpbmQoe1xuICAgICAgICAgIGxheWVyOiBsYXllcnNPdXRcbiAgICAgICAgfSksIDI0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGF5ZXJzT3V0Kys7XG4gIH0gd2hpbGUgKG9wdGlvbnMuYnViYmxlU2Nyb2xsICYmIGN1cnJlbnRQYXJlbnQgIT09IHdpblNjcm9sbGVyICYmIChjdXJyZW50UGFyZW50ID0gZ2V0UGFyZW50QXV0b1Njcm9sbEVsZW1lbnQoY3VycmVudFBhcmVudCwgZmFsc2UpKSk7XG4gIHNjcm9sbGluZyA9IHNjcm9sbFRoaXNJbnN0YW5jZTsgLy8gaW4gY2FzZSBhbm90aGVyIGZ1bmN0aW9uIGNhdGNoZXMgc2Nyb2xsaW5nIGFzIGZhbHNlIGluIGJldHdlZW4gd2hlbiBpdCBpcyBub3Rcbn0sIDMwKTtcblxudmFyIGRyb3AgPSBmdW5jdGlvbiBkcm9wKF9yZWYpIHtcbiAgdmFyIG9yaWdpbmFsRXZlbnQgPSBfcmVmLm9yaWdpbmFsRXZlbnQsXG4gICAgcHV0U29ydGFibGUgPSBfcmVmLnB1dFNvcnRhYmxlLFxuICAgIGRyYWdFbCA9IF9yZWYuZHJhZ0VsLFxuICAgIGFjdGl2ZVNvcnRhYmxlID0gX3JlZi5hY3RpdmVTb3J0YWJsZSxcbiAgICBkaXNwYXRjaFNvcnRhYmxlRXZlbnQgPSBfcmVmLmRpc3BhdGNoU29ydGFibGVFdmVudCxcbiAgICBoaWRlR2hvc3RGb3JUYXJnZXQgPSBfcmVmLmhpZGVHaG9zdEZvclRhcmdldCxcbiAgICB1bmhpZGVHaG9zdEZvclRhcmdldCA9IF9yZWYudW5oaWRlR2hvc3RGb3JUYXJnZXQ7XG4gIGlmICghb3JpZ2luYWxFdmVudCkgcmV0dXJuO1xuICB2YXIgdG9Tb3J0YWJsZSA9IHB1dFNvcnRhYmxlIHx8IGFjdGl2ZVNvcnRhYmxlO1xuICBoaWRlR2hvc3RGb3JUYXJnZXQoKTtcbiAgdmFyIHRvdWNoID0gb3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlcyAmJiBvcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzLmxlbmd0aCA/IG9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0gOiBvcmlnaW5hbEV2ZW50O1xuICB2YXIgdGFyZ2V0ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludCh0b3VjaC5jbGllbnRYLCB0b3VjaC5jbGllbnRZKTtcbiAgdW5oaWRlR2hvc3RGb3JUYXJnZXQoKTtcbiAgaWYgKHRvU29ydGFibGUgJiYgIXRvU29ydGFibGUuZWwuY29udGFpbnModGFyZ2V0KSkge1xuICAgIGRpc3BhdGNoU29ydGFibGVFdmVudCgnc3BpbGwnKTtcbiAgICB0aGlzLm9uU3BpbGwoe1xuICAgICAgZHJhZ0VsOiBkcmFnRWwsXG4gICAgICBwdXRTb3J0YWJsZTogcHV0U29ydGFibGVcbiAgICB9KTtcbiAgfVxufTtcbmZ1bmN0aW9uIFJldmVydCgpIHt9XG5SZXZlcnQucHJvdG90eXBlID0ge1xuICBzdGFydEluZGV4OiBudWxsLFxuICBkcmFnU3RhcnQ6IGZ1bmN0aW9uIGRyYWdTdGFydChfcmVmMikge1xuICAgIHZhciBvbGREcmFnZ2FibGVJbmRleCA9IF9yZWYyLm9sZERyYWdnYWJsZUluZGV4O1xuICAgIHRoaXMuc3RhcnRJbmRleCA9IG9sZERyYWdnYWJsZUluZGV4O1xuICB9LFxuICBvblNwaWxsOiBmdW5jdGlvbiBvblNwaWxsKF9yZWYzKSB7XG4gICAgdmFyIGRyYWdFbCA9IF9yZWYzLmRyYWdFbCxcbiAgICAgIHB1dFNvcnRhYmxlID0gX3JlZjMucHV0U29ydGFibGU7XG4gICAgdGhpcy5zb3J0YWJsZS5jYXB0dXJlQW5pbWF0aW9uU3RhdGUoKTtcbiAgICBpZiAocHV0U29ydGFibGUpIHtcbiAgICAgIHB1dFNvcnRhYmxlLmNhcHR1cmVBbmltYXRpb25TdGF0ZSgpO1xuICAgIH1cbiAgICB2YXIgbmV4dFNpYmxpbmcgPSBnZXRDaGlsZCh0aGlzLnNvcnRhYmxlLmVsLCB0aGlzLnN0YXJ0SW5kZXgsIHRoaXMub3B0aW9ucyk7XG4gICAgaWYgKG5leHRTaWJsaW5nKSB7XG4gICAgICB0aGlzLnNvcnRhYmxlLmVsLmluc2VydEJlZm9yZShkcmFnRWwsIG5leHRTaWJsaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zb3J0YWJsZS5lbC5hcHBlbmRDaGlsZChkcmFnRWwpO1xuICAgIH1cbiAgICB0aGlzLnNvcnRhYmxlLmFuaW1hdGVBbGwoKTtcbiAgICBpZiAocHV0U29ydGFibGUpIHtcbiAgICAgIHB1dFNvcnRhYmxlLmFuaW1hdGVBbGwoKTtcbiAgICB9XG4gIH0sXG4gIGRyb3A6IGRyb3Bcbn07XG5fZXh0ZW5kcyhSZXZlcnQsIHtcbiAgcGx1Z2luTmFtZTogJ3JldmVydE9uU3BpbGwnXG59KTtcbmZ1bmN0aW9uIFJlbW92ZSgpIHt9XG5SZW1vdmUucHJvdG90eXBlID0ge1xuICBvblNwaWxsOiBmdW5jdGlvbiBvblNwaWxsKF9yZWY0KSB7XG4gICAgdmFyIGRyYWdFbCA9IF9yZWY0LmRyYWdFbCxcbiAgICAgIHB1dFNvcnRhYmxlID0gX3JlZjQucHV0U29ydGFibGU7XG4gICAgdmFyIHBhcmVudFNvcnRhYmxlID0gcHV0U29ydGFibGUgfHwgdGhpcy5zb3J0YWJsZTtcbiAgICBwYXJlbnRTb3J0YWJsZS5jYXB0dXJlQW5pbWF0aW9uU3RhdGUoKTtcbiAgICBkcmFnRWwucGFyZW50Tm9kZSAmJiBkcmFnRWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChkcmFnRWwpO1xuICAgIHBhcmVudFNvcnRhYmxlLmFuaW1hdGVBbGwoKTtcbiAgfSxcbiAgZHJvcDogZHJvcFxufTtcbl9leHRlbmRzKFJlbW92ZSwge1xuICBwbHVnaW5OYW1lOiAncmVtb3ZlT25TcGlsbCdcbn0pO1xuXG52YXIgbGFzdFN3YXBFbDtcbmZ1bmN0aW9uIFN3YXBQbHVnaW4oKSB7XG4gIGZ1bmN0aW9uIFN3YXAoKSB7XG4gICAgdGhpcy5kZWZhdWx0cyA9IHtcbiAgICAgIHN3YXBDbGFzczogJ3NvcnRhYmxlLXN3YXAtaGlnaGxpZ2h0J1xuICAgIH07XG4gIH1cbiAgU3dhcC5wcm90b3R5cGUgPSB7XG4gICAgZHJhZ1N0YXJ0OiBmdW5jdGlvbiBkcmFnU3RhcnQoX3JlZikge1xuICAgICAgdmFyIGRyYWdFbCA9IF9yZWYuZHJhZ0VsO1xuICAgICAgbGFzdFN3YXBFbCA9IGRyYWdFbDtcbiAgICB9LFxuICAgIGRyYWdPdmVyVmFsaWQ6IGZ1bmN0aW9uIGRyYWdPdmVyVmFsaWQoX3JlZjIpIHtcbiAgICAgIHZhciBjb21wbGV0ZWQgPSBfcmVmMi5jb21wbGV0ZWQsXG4gICAgICAgIHRhcmdldCA9IF9yZWYyLnRhcmdldCxcbiAgICAgICAgb25Nb3ZlID0gX3JlZjIub25Nb3ZlLFxuICAgICAgICBhY3RpdmVTb3J0YWJsZSA9IF9yZWYyLmFjdGl2ZVNvcnRhYmxlLFxuICAgICAgICBjaGFuZ2VkID0gX3JlZjIuY2hhbmdlZCxcbiAgICAgICAgY2FuY2VsID0gX3JlZjIuY2FuY2VsO1xuICAgICAgaWYgKCFhY3RpdmVTb3J0YWJsZS5vcHRpb25zLnN3YXApIHJldHVybjtcbiAgICAgIHZhciBlbCA9IHRoaXMuc29ydGFibGUuZWwsXG4gICAgICAgIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICBpZiAodGFyZ2V0ICYmIHRhcmdldCAhPT0gZWwpIHtcbiAgICAgICAgdmFyIHByZXZTd2FwRWwgPSBsYXN0U3dhcEVsO1xuICAgICAgICBpZiAob25Nb3ZlKHRhcmdldCkgIT09IGZhbHNlKSB7XG4gICAgICAgICAgdG9nZ2xlQ2xhc3ModGFyZ2V0LCBvcHRpb25zLnN3YXBDbGFzcywgdHJ1ZSk7XG4gICAgICAgICAgbGFzdFN3YXBFbCA9IHRhcmdldDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsYXN0U3dhcEVsID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJldlN3YXBFbCAmJiBwcmV2U3dhcEVsICE9PSBsYXN0U3dhcEVsKSB7XG4gICAgICAgICAgdG9nZ2xlQ2xhc3MocHJldlN3YXBFbCwgb3B0aW9ucy5zd2FwQ2xhc3MsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2hhbmdlZCgpO1xuICAgICAgY29tcGxldGVkKHRydWUpO1xuICAgICAgY2FuY2VsKCk7XG4gICAgfSxcbiAgICBkcm9wOiBmdW5jdGlvbiBkcm9wKF9yZWYzKSB7XG4gICAgICB2YXIgYWN0aXZlU29ydGFibGUgPSBfcmVmMy5hY3RpdmVTb3J0YWJsZSxcbiAgICAgICAgcHV0U29ydGFibGUgPSBfcmVmMy5wdXRTb3J0YWJsZSxcbiAgICAgICAgZHJhZ0VsID0gX3JlZjMuZHJhZ0VsO1xuICAgICAgdmFyIHRvU29ydGFibGUgPSBwdXRTb3J0YWJsZSB8fCB0aGlzLnNvcnRhYmxlO1xuICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICBsYXN0U3dhcEVsICYmIHRvZ2dsZUNsYXNzKGxhc3RTd2FwRWwsIG9wdGlvbnMuc3dhcENsYXNzLCBmYWxzZSk7XG4gICAgICBpZiAobGFzdFN3YXBFbCAmJiAob3B0aW9ucy5zd2FwIHx8IHB1dFNvcnRhYmxlICYmIHB1dFNvcnRhYmxlLm9wdGlvbnMuc3dhcCkpIHtcbiAgICAgICAgaWYgKGRyYWdFbCAhPT0gbGFzdFN3YXBFbCkge1xuICAgICAgICAgIHRvU29ydGFibGUuY2FwdHVyZUFuaW1hdGlvblN0YXRlKCk7XG4gICAgICAgICAgaWYgKHRvU29ydGFibGUgIT09IGFjdGl2ZVNvcnRhYmxlKSBhY3RpdmVTb3J0YWJsZS5jYXB0dXJlQW5pbWF0aW9uU3RhdGUoKTtcbiAgICAgICAgICBzd2FwTm9kZXMoZHJhZ0VsLCBsYXN0U3dhcEVsKTtcbiAgICAgICAgICB0b1NvcnRhYmxlLmFuaW1hdGVBbGwoKTtcbiAgICAgICAgICBpZiAodG9Tb3J0YWJsZSAhPT0gYWN0aXZlU29ydGFibGUpIGFjdGl2ZVNvcnRhYmxlLmFuaW1hdGVBbGwoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgbnVsbGluZzogZnVuY3Rpb24gbnVsbGluZygpIHtcbiAgICAgIGxhc3RTd2FwRWwgPSBudWxsO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIF9leHRlbmRzKFN3YXAsIHtcbiAgICBwbHVnaW5OYW1lOiAnc3dhcCcsXG4gICAgZXZlbnRQcm9wZXJ0aWVzOiBmdW5jdGlvbiBldmVudFByb3BlcnRpZXMoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzd2FwSXRlbTogbGFzdFN3YXBFbFxuICAgICAgfTtcbiAgICB9XG4gIH0pO1xufVxuZnVuY3Rpb24gc3dhcE5vZGVzKG4xLCBuMikge1xuICB2YXIgcDEgPSBuMS5wYXJlbnROb2RlLFxuICAgIHAyID0gbjIucGFyZW50Tm9kZSxcbiAgICBpMSxcbiAgICBpMjtcbiAgaWYgKCFwMSB8fCAhcDIgfHwgcDEuaXNFcXVhbE5vZGUobjIpIHx8IHAyLmlzRXF1YWxOb2RlKG4xKSkgcmV0dXJuO1xuICBpMSA9IGluZGV4KG4xKTtcbiAgaTIgPSBpbmRleChuMik7XG4gIGlmIChwMS5pc0VxdWFsTm9kZShwMikgJiYgaTEgPCBpMikge1xuICAgIGkyKys7XG4gIH1cbiAgcDEuaW5zZXJ0QmVmb3JlKG4yLCBwMS5jaGlsZHJlbltpMV0pO1xuICBwMi5pbnNlcnRCZWZvcmUobjEsIHAyLmNoaWxkcmVuW2kyXSk7XG59XG5cbnZhciBtdWx0aURyYWdFbGVtZW50cyA9IFtdLFxuICBtdWx0aURyYWdDbG9uZXMgPSBbXSxcbiAgbGFzdE11bHRpRHJhZ1NlbGVjdCxcbiAgLy8gZm9yIHNlbGVjdGlvbiB3aXRoIG1vZGlmaWVyIGtleSBkb3duIChTSElGVClcbiAgbXVsdGlEcmFnU29ydGFibGUsXG4gIGluaXRpYWxGb2xkaW5nID0gZmFsc2UsXG4gIC8vIEluaXRpYWwgbXVsdGktZHJhZyBmb2xkIHdoZW4gZHJhZyBzdGFydGVkXG4gIGZvbGRpbmcgPSBmYWxzZSxcbiAgLy8gRm9sZGluZyBhbnkgb3RoZXIgdGltZVxuICBkcmFnU3RhcnRlZCA9IGZhbHNlLFxuICBkcmFnRWwkMSxcbiAgY2xvbmVzRnJvbVJlY3QsXG4gIGNsb25lc0hpZGRlbjtcbmZ1bmN0aW9uIE11bHRpRHJhZ1BsdWdpbigpIHtcbiAgZnVuY3Rpb24gTXVsdGlEcmFnKHNvcnRhYmxlKSB7XG4gICAgLy8gQmluZCBhbGwgcHJpdmF0ZSBtZXRob2RzXG4gICAgZm9yICh2YXIgZm4gaW4gdGhpcykge1xuICAgICAgaWYgKGZuLmNoYXJBdCgwKSA9PT0gJ18nICYmIHR5cGVvZiB0aGlzW2ZuXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzW2ZuXSA9IHRoaXNbZm5dLmJpbmQodGhpcyk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghc29ydGFibGUub3B0aW9ucy5hdm9pZEltcGxpY2l0RGVzZWxlY3QpIHtcbiAgICAgIGlmIChzb3J0YWJsZS5vcHRpb25zLnN1cHBvcnRQb2ludGVyKSB7XG4gICAgICAgIG9uKGRvY3VtZW50LCAncG9pbnRlcnVwJywgdGhpcy5fZGVzZWxlY3RNdWx0aURyYWcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb24oZG9jdW1lbnQsICdtb3VzZXVwJywgdGhpcy5fZGVzZWxlY3RNdWx0aURyYWcpO1xuICAgICAgICBvbihkb2N1bWVudCwgJ3RvdWNoZW5kJywgdGhpcy5fZGVzZWxlY3RNdWx0aURyYWcpO1xuICAgICAgfVxuICAgIH1cbiAgICBvbihkb2N1bWVudCwgJ2tleWRvd24nLCB0aGlzLl9jaGVja0tleURvd24pO1xuICAgIG9uKGRvY3VtZW50LCAna2V5dXAnLCB0aGlzLl9jaGVja0tleVVwKTtcbiAgICB0aGlzLmRlZmF1bHRzID0ge1xuICAgICAgc2VsZWN0ZWRDbGFzczogJ3NvcnRhYmxlLXNlbGVjdGVkJyxcbiAgICAgIG11bHRpRHJhZ0tleTogbnVsbCxcbiAgICAgIGF2b2lkSW1wbGljaXREZXNlbGVjdDogZmFsc2UsXG4gICAgICBzZXREYXRhOiBmdW5jdGlvbiBzZXREYXRhKGRhdGFUcmFuc2ZlciwgZHJhZ0VsKSB7XG4gICAgICAgIHZhciBkYXRhID0gJyc7XG4gICAgICAgIGlmIChtdWx0aURyYWdFbGVtZW50cy5sZW5ndGggJiYgbXVsdGlEcmFnU29ydGFibGUgPT09IHNvcnRhYmxlKSB7XG4gICAgICAgICAgbXVsdGlEcmFnRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAobXVsdGlEcmFnRWxlbWVudCwgaSkge1xuICAgICAgICAgICAgZGF0YSArPSAoIWkgPyAnJyA6ICcsICcpICsgbXVsdGlEcmFnRWxlbWVudC50ZXh0Q29udGVudDtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkYXRhID0gZHJhZ0VsLnRleHRDb250ZW50O1xuICAgICAgICB9XG4gICAgICAgIGRhdGFUcmFuc2Zlci5zZXREYXRhKCdUZXh0JywgZGF0YSk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuICBNdWx0aURyYWcucHJvdG90eXBlID0ge1xuICAgIG11bHRpRHJhZ0tleURvd246IGZhbHNlLFxuICAgIGlzTXVsdGlEcmFnOiBmYWxzZSxcbiAgICBkZWxheVN0YXJ0R2xvYmFsOiBmdW5jdGlvbiBkZWxheVN0YXJ0R2xvYmFsKF9yZWYpIHtcbiAgICAgIHZhciBkcmFnZ2VkID0gX3JlZi5kcmFnRWw7XG4gICAgICBkcmFnRWwkMSA9IGRyYWdnZWQ7XG4gICAgfSxcbiAgICBkZWxheUVuZGVkOiBmdW5jdGlvbiBkZWxheUVuZGVkKCkge1xuICAgICAgdGhpcy5pc011bHRpRHJhZyA9IH5tdWx0aURyYWdFbGVtZW50cy5pbmRleE9mKGRyYWdFbCQxKTtcbiAgICB9LFxuICAgIHNldHVwQ2xvbmU6IGZ1bmN0aW9uIHNldHVwQ2xvbmUoX3JlZjIpIHtcbiAgICAgIHZhciBzb3J0YWJsZSA9IF9yZWYyLnNvcnRhYmxlLFxuICAgICAgICBjYW5jZWwgPSBfcmVmMi5jYW5jZWw7XG4gICAgICBpZiAoIXRoaXMuaXNNdWx0aURyYWcpIHJldHVybjtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXVsdGlEcmFnRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbXVsdGlEcmFnQ2xvbmVzLnB1c2goY2xvbmUobXVsdGlEcmFnRWxlbWVudHNbaV0pKTtcbiAgICAgICAgbXVsdGlEcmFnQ2xvbmVzW2ldLnNvcnRhYmxlSW5kZXggPSBtdWx0aURyYWdFbGVtZW50c1tpXS5zb3J0YWJsZUluZGV4O1xuICAgICAgICBtdWx0aURyYWdDbG9uZXNbaV0uZHJhZ2dhYmxlID0gZmFsc2U7XG4gICAgICAgIG11bHRpRHJhZ0Nsb25lc1tpXS5zdHlsZVsnd2lsbC1jaGFuZ2UnXSA9ICcnO1xuICAgICAgICB0b2dnbGVDbGFzcyhtdWx0aURyYWdDbG9uZXNbaV0sIHRoaXMub3B0aW9ucy5zZWxlY3RlZENsYXNzLCBmYWxzZSk7XG4gICAgICAgIG11bHRpRHJhZ0VsZW1lbnRzW2ldID09PSBkcmFnRWwkMSAmJiB0b2dnbGVDbGFzcyhtdWx0aURyYWdDbG9uZXNbaV0sIHRoaXMub3B0aW9ucy5jaG9zZW5DbGFzcywgZmFsc2UpO1xuICAgICAgfVxuICAgICAgc29ydGFibGUuX2hpZGVDbG9uZSgpO1xuICAgICAgY2FuY2VsKCk7XG4gICAgfSxcbiAgICBjbG9uZTogZnVuY3Rpb24gY2xvbmUoX3JlZjMpIHtcbiAgICAgIHZhciBzb3J0YWJsZSA9IF9yZWYzLnNvcnRhYmxlLFxuICAgICAgICByb290RWwgPSBfcmVmMy5yb290RWwsXG4gICAgICAgIGRpc3BhdGNoU29ydGFibGVFdmVudCA9IF9yZWYzLmRpc3BhdGNoU29ydGFibGVFdmVudCxcbiAgICAgICAgY2FuY2VsID0gX3JlZjMuY2FuY2VsO1xuICAgICAgaWYgKCF0aGlzLmlzTXVsdGlEcmFnKSByZXR1cm47XG4gICAgICBpZiAoIXRoaXMub3B0aW9ucy5yZW1vdmVDbG9uZU9uSGlkZSkge1xuICAgICAgICBpZiAobXVsdGlEcmFnRWxlbWVudHMubGVuZ3RoICYmIG11bHRpRHJhZ1NvcnRhYmxlID09PSBzb3J0YWJsZSkge1xuICAgICAgICAgIGluc2VydE11bHRpRHJhZ0Nsb25lcyh0cnVlLCByb290RWwpO1xuICAgICAgICAgIGRpc3BhdGNoU29ydGFibGVFdmVudCgnY2xvbmUnKTtcbiAgICAgICAgICBjYW5jZWwoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgc2hvd0Nsb25lOiBmdW5jdGlvbiBzaG93Q2xvbmUoX3JlZjQpIHtcbiAgICAgIHZhciBjbG9uZU5vd1Nob3duID0gX3JlZjQuY2xvbmVOb3dTaG93bixcbiAgICAgICAgcm9vdEVsID0gX3JlZjQucm9vdEVsLFxuICAgICAgICBjYW5jZWwgPSBfcmVmNC5jYW5jZWw7XG4gICAgICBpZiAoIXRoaXMuaXNNdWx0aURyYWcpIHJldHVybjtcbiAgICAgIGluc2VydE11bHRpRHJhZ0Nsb25lcyhmYWxzZSwgcm9vdEVsKTtcbiAgICAgIG11bHRpRHJhZ0Nsb25lcy5mb3JFYWNoKGZ1bmN0aW9uIChjbG9uZSkge1xuICAgICAgICBjc3MoY2xvbmUsICdkaXNwbGF5JywgJycpO1xuICAgICAgfSk7XG4gICAgICBjbG9uZU5vd1Nob3duKCk7XG4gICAgICBjbG9uZXNIaWRkZW4gPSBmYWxzZTtcbiAgICAgIGNhbmNlbCgpO1xuICAgIH0sXG4gICAgaGlkZUNsb25lOiBmdW5jdGlvbiBoaWRlQ2xvbmUoX3JlZjUpIHtcbiAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICB2YXIgc29ydGFibGUgPSBfcmVmNS5zb3J0YWJsZSxcbiAgICAgICAgY2xvbmVOb3dIaWRkZW4gPSBfcmVmNS5jbG9uZU5vd0hpZGRlbixcbiAgICAgICAgY2FuY2VsID0gX3JlZjUuY2FuY2VsO1xuICAgICAgaWYgKCF0aGlzLmlzTXVsdGlEcmFnKSByZXR1cm47XG4gICAgICBtdWx0aURyYWdDbG9uZXMuZm9yRWFjaChmdW5jdGlvbiAoY2xvbmUpIHtcbiAgICAgICAgY3NzKGNsb25lLCAnZGlzcGxheScsICdub25lJyk7XG4gICAgICAgIGlmIChfdGhpcy5vcHRpb25zLnJlbW92ZUNsb25lT25IaWRlICYmIGNsb25lLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICBjbG9uZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNsb25lKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjbG9uZU5vd0hpZGRlbigpO1xuICAgICAgY2xvbmVzSGlkZGVuID0gdHJ1ZTtcbiAgICAgIGNhbmNlbCgpO1xuICAgIH0sXG4gICAgZHJhZ1N0YXJ0R2xvYmFsOiBmdW5jdGlvbiBkcmFnU3RhcnRHbG9iYWwoX3JlZjYpIHtcbiAgICAgIHZhciBzb3J0YWJsZSA9IF9yZWY2LnNvcnRhYmxlO1xuICAgICAgaWYgKCF0aGlzLmlzTXVsdGlEcmFnICYmIG11bHRpRHJhZ1NvcnRhYmxlKSB7XG4gICAgICAgIG11bHRpRHJhZ1NvcnRhYmxlLm11bHRpRHJhZy5fZGVzZWxlY3RNdWx0aURyYWcoKTtcbiAgICAgIH1cbiAgICAgIG11bHRpRHJhZ0VsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKG11bHRpRHJhZ0VsZW1lbnQpIHtcbiAgICAgICAgbXVsdGlEcmFnRWxlbWVudC5zb3J0YWJsZUluZGV4ID0gaW5kZXgobXVsdGlEcmFnRWxlbWVudCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gU29ydCBtdWx0aS1kcmFnIGVsZW1lbnRzXG4gICAgICBtdWx0aURyYWdFbGVtZW50cyA9IG11bHRpRHJhZ0VsZW1lbnRzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIGEuc29ydGFibGVJbmRleCAtIGIuc29ydGFibGVJbmRleDtcbiAgICAgIH0pO1xuICAgICAgZHJhZ1N0YXJ0ZWQgPSB0cnVlO1xuICAgIH0sXG4gICAgZHJhZ1N0YXJ0ZWQ6IGZ1bmN0aW9uIGRyYWdTdGFydGVkKF9yZWY3KSB7XG4gICAgICB2YXIgX3RoaXMyID0gdGhpcztcbiAgICAgIHZhciBzb3J0YWJsZSA9IF9yZWY3LnNvcnRhYmxlO1xuICAgICAgaWYgKCF0aGlzLmlzTXVsdGlEcmFnKSByZXR1cm47XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnNvcnQpIHtcbiAgICAgICAgLy8gQ2FwdHVyZSByZWN0cyxcbiAgICAgICAgLy8gaGlkZSBtdWx0aSBkcmFnIGVsZW1lbnRzIChieSBwb3NpdGlvbmluZyB0aGVtIGFic29sdXRlKSxcbiAgICAgICAgLy8gc2V0IG11bHRpIGRyYWcgZWxlbWVudHMgcmVjdHMgdG8gZHJhZ1JlY3QsXG4gICAgICAgIC8vIHNob3cgbXVsdGkgZHJhZyBlbGVtZW50cyxcbiAgICAgICAgLy8gYW5pbWF0ZSB0byByZWN0cyxcbiAgICAgICAgLy8gdW5zZXQgcmVjdHMgJiByZW1vdmUgZnJvbSBET01cblxuICAgICAgICBzb3J0YWJsZS5jYXB0dXJlQW5pbWF0aW9uU3RhdGUoKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5hbmltYXRpb24pIHtcbiAgICAgICAgICBtdWx0aURyYWdFbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChtdWx0aURyYWdFbGVtZW50KSB7XG4gICAgICAgICAgICBpZiAobXVsdGlEcmFnRWxlbWVudCA9PT0gZHJhZ0VsJDEpIHJldHVybjtcbiAgICAgICAgICAgIGNzcyhtdWx0aURyYWdFbGVtZW50LCAncG9zaXRpb24nLCAnYWJzb2x1dGUnKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB2YXIgZHJhZ1JlY3QgPSBnZXRSZWN0KGRyYWdFbCQxLCBmYWxzZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgICAgbXVsdGlEcmFnRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAobXVsdGlEcmFnRWxlbWVudCkge1xuICAgICAgICAgICAgaWYgKG11bHRpRHJhZ0VsZW1lbnQgPT09IGRyYWdFbCQxKSByZXR1cm47XG4gICAgICAgICAgICBzZXRSZWN0KG11bHRpRHJhZ0VsZW1lbnQsIGRyYWdSZWN0KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBmb2xkaW5nID0gdHJ1ZTtcbiAgICAgICAgICBpbml0aWFsRm9sZGluZyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHNvcnRhYmxlLmFuaW1hdGVBbGwoZnVuY3Rpb24gKCkge1xuICAgICAgICBmb2xkaW5nID0gZmFsc2U7XG4gICAgICAgIGluaXRpYWxGb2xkaW5nID0gZmFsc2U7XG4gICAgICAgIGlmIChfdGhpczIub3B0aW9ucy5hbmltYXRpb24pIHtcbiAgICAgICAgICBtdWx0aURyYWdFbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChtdWx0aURyYWdFbGVtZW50KSB7XG4gICAgICAgICAgICB1bnNldFJlY3QobXVsdGlEcmFnRWxlbWVudCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZW1vdmUgYWxsIGF1eGlsaWFyeSBtdWx0aWRyYWcgaXRlbXMgZnJvbSBlbCwgaWYgc29ydGluZyBlbmFibGVkXG4gICAgICAgIGlmIChfdGhpczIub3B0aW9ucy5zb3J0KSB7XG4gICAgICAgICAgcmVtb3ZlTXVsdGlEcmFnRWxlbWVudHMoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBkcmFnT3ZlcjogZnVuY3Rpb24gZHJhZ092ZXIoX3JlZjgpIHtcbiAgICAgIHZhciB0YXJnZXQgPSBfcmVmOC50YXJnZXQsXG4gICAgICAgIGNvbXBsZXRlZCA9IF9yZWY4LmNvbXBsZXRlZCxcbiAgICAgICAgY2FuY2VsID0gX3JlZjguY2FuY2VsO1xuICAgICAgaWYgKGZvbGRpbmcgJiYgfm11bHRpRHJhZ0VsZW1lbnRzLmluZGV4T2YodGFyZ2V0KSkge1xuICAgICAgICBjb21wbGV0ZWQoZmFsc2UpO1xuICAgICAgICBjYW5jZWwoKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIHJldmVydDogZnVuY3Rpb24gcmV2ZXJ0KF9yZWY5KSB7XG4gICAgICB2YXIgZnJvbVNvcnRhYmxlID0gX3JlZjkuZnJvbVNvcnRhYmxlLFxuICAgICAgICByb290RWwgPSBfcmVmOS5yb290RWwsXG4gICAgICAgIHNvcnRhYmxlID0gX3JlZjkuc29ydGFibGUsXG4gICAgICAgIGRyYWdSZWN0ID0gX3JlZjkuZHJhZ1JlY3Q7XG4gICAgICBpZiAobXVsdGlEcmFnRWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAvLyBTZXR1cCB1bmZvbGQgYW5pbWF0aW9uXG4gICAgICAgIG11bHRpRHJhZ0VsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKG11bHRpRHJhZ0VsZW1lbnQpIHtcbiAgICAgICAgICBzb3J0YWJsZS5hZGRBbmltYXRpb25TdGF0ZSh7XG4gICAgICAgICAgICB0YXJnZXQ6IG11bHRpRHJhZ0VsZW1lbnQsXG4gICAgICAgICAgICByZWN0OiBmb2xkaW5nID8gZ2V0UmVjdChtdWx0aURyYWdFbGVtZW50KSA6IGRyYWdSZWN0XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdW5zZXRSZWN0KG11bHRpRHJhZ0VsZW1lbnQpO1xuICAgICAgICAgIG11bHRpRHJhZ0VsZW1lbnQuZnJvbVJlY3QgPSBkcmFnUmVjdDtcbiAgICAgICAgICBmcm9tU29ydGFibGUucmVtb3ZlQW5pbWF0aW9uU3RhdGUobXVsdGlEcmFnRWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICBmb2xkaW5nID0gZmFsc2U7XG4gICAgICAgIGluc2VydE11bHRpRHJhZ0VsZW1lbnRzKCF0aGlzLm9wdGlvbnMucmVtb3ZlQ2xvbmVPbkhpZGUsIHJvb3RFbCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBkcmFnT3ZlckNvbXBsZXRlZDogZnVuY3Rpb24gZHJhZ092ZXJDb21wbGV0ZWQoX3JlZjEwKSB7XG4gICAgICB2YXIgc29ydGFibGUgPSBfcmVmMTAuc29ydGFibGUsXG4gICAgICAgIGlzT3duZXIgPSBfcmVmMTAuaXNPd25lcixcbiAgICAgICAgaW5zZXJ0aW9uID0gX3JlZjEwLmluc2VydGlvbixcbiAgICAgICAgYWN0aXZlU29ydGFibGUgPSBfcmVmMTAuYWN0aXZlU29ydGFibGUsXG4gICAgICAgIHBhcmVudEVsID0gX3JlZjEwLnBhcmVudEVsLFxuICAgICAgICBwdXRTb3J0YWJsZSA9IF9yZWYxMC5wdXRTb3J0YWJsZTtcbiAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgaWYgKGluc2VydGlvbikge1xuICAgICAgICAvLyBDbG9uZXMgbXVzdCBiZSBoaWRkZW4gYmVmb3JlIGZvbGRpbmcgYW5pbWF0aW9uIHRvIGNhcHR1cmUgZHJhZ1JlY3RBYnNvbHV0ZSBwcm9wZXJseVxuICAgICAgICBpZiAoaXNPd25lcikge1xuICAgICAgICAgIGFjdGl2ZVNvcnRhYmxlLl9oaWRlQ2xvbmUoKTtcbiAgICAgICAgfVxuICAgICAgICBpbml0aWFsRm9sZGluZyA9IGZhbHNlO1xuICAgICAgICAvLyBJZiBsZWF2aW5nIHNvcnQ6ZmFsc2Ugcm9vdCwgb3IgYWxyZWFkeSBmb2xkaW5nIC0gRm9sZCB0byBuZXcgbG9jYXRpb25cbiAgICAgICAgaWYgKG9wdGlvbnMuYW5pbWF0aW9uICYmIG11bHRpRHJhZ0VsZW1lbnRzLmxlbmd0aCA+IDEgJiYgKGZvbGRpbmcgfHwgIWlzT3duZXIgJiYgIWFjdGl2ZVNvcnRhYmxlLm9wdGlvbnMuc29ydCAmJiAhcHV0U29ydGFibGUpKSB7XG4gICAgICAgICAgLy8gRm9sZDogU2V0IGFsbCBtdWx0aSBkcmFnIGVsZW1lbnRzJ3MgcmVjdHMgdG8gZHJhZ0VsJ3MgcmVjdCB3aGVuIG11bHRpLWRyYWcgZWxlbWVudHMgYXJlIGludmlzaWJsZVxuICAgICAgICAgIHZhciBkcmFnUmVjdEFic29sdXRlID0gZ2V0UmVjdChkcmFnRWwkMSwgZmFsc2UsIHRydWUsIHRydWUpO1xuICAgICAgICAgIG11bHRpRHJhZ0VsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKG11bHRpRHJhZ0VsZW1lbnQpIHtcbiAgICAgICAgICAgIGlmIChtdWx0aURyYWdFbGVtZW50ID09PSBkcmFnRWwkMSkgcmV0dXJuO1xuICAgICAgICAgICAgc2V0UmVjdChtdWx0aURyYWdFbGVtZW50LCBkcmFnUmVjdEFic29sdXRlKTtcblxuICAgICAgICAgICAgLy8gTW92ZSBlbGVtZW50KHMpIHRvIGVuZCBvZiBwYXJlbnRFbCBzbyB0aGF0IGl0IGRvZXMgbm90IGludGVyZmVyZSB3aXRoIG11bHRpLWRyYWcgY2xvbmVzIGluc2VydGlvbiBpZiB0aGV5IGFyZSBpbnNlcnRlZFxuICAgICAgICAgICAgLy8gd2hpbGUgZm9sZGluZywgYW5kIHNvIHRoYXQgd2UgY2FuIGNhcHR1cmUgdGhlbSBhZ2FpbiBiZWNhdXNlIG9sZCBzb3J0YWJsZSB3aWxsIG5vIGxvbmdlciBiZSBmcm9tU29ydGFibGVcbiAgICAgICAgICAgIHBhcmVudEVsLmFwcGVuZENoaWxkKG11bHRpRHJhZ0VsZW1lbnQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGZvbGRpbmcgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2xvbmVzIG11c3QgYmUgc2hvd24gKGFuZCBjaGVjayB0byByZW1vdmUgbXVsdGkgZHJhZ3MpIGFmdGVyIGZvbGRpbmcgd2hlbiBpbnRlcmZlcmluZyBtdWx0aURyYWdFbGVtZW50cyBhcmUgbW92ZWQgb3V0XG4gICAgICAgIGlmICghaXNPd25lcikge1xuICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGlmIG5vdCBmb2xkaW5nIChmb2xkaW5nIHdpbGwgcmVtb3ZlIHRoZW0gYW55d2F5cylcbiAgICAgICAgICBpZiAoIWZvbGRpbmcpIHtcbiAgICAgICAgICAgIHJlbW92ZU11bHRpRHJhZ0VsZW1lbnRzKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChtdWx0aURyYWdFbGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICB2YXIgY2xvbmVzSGlkZGVuQmVmb3JlID0gY2xvbmVzSGlkZGVuO1xuICAgICAgICAgICAgYWN0aXZlU29ydGFibGUuX3Nob3dDbG9uZShzb3J0YWJsZSk7XG5cbiAgICAgICAgICAgIC8vIFVuZm9sZCBhbmltYXRpb24gZm9yIGNsb25lcyBpZiBzaG93aW5nIGZyb20gaGlkZGVuXG4gICAgICAgICAgICBpZiAoYWN0aXZlU29ydGFibGUub3B0aW9ucy5hbmltYXRpb24gJiYgIWNsb25lc0hpZGRlbiAmJiBjbG9uZXNIaWRkZW5CZWZvcmUpIHtcbiAgICAgICAgICAgICAgbXVsdGlEcmFnQ2xvbmVzLmZvckVhY2goZnVuY3Rpb24gKGNsb25lKSB7XG4gICAgICAgICAgICAgICAgYWN0aXZlU29ydGFibGUuYWRkQW5pbWF0aW9uU3RhdGUoe1xuICAgICAgICAgICAgICAgICAgdGFyZ2V0OiBjbG9uZSxcbiAgICAgICAgICAgICAgICAgIHJlY3Q6IGNsb25lc0Zyb21SZWN0XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY2xvbmUuZnJvbVJlY3QgPSBjbG9uZXNGcm9tUmVjdDtcbiAgICAgICAgICAgICAgICBjbG9uZS50aGlzQW5pbWF0aW9uRHVyYXRpb24gPSBudWxsO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWN0aXZlU29ydGFibGUuX3Nob3dDbG9uZShzb3J0YWJsZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBkcmFnT3ZlckFuaW1hdGlvbkNhcHR1cmU6IGZ1bmN0aW9uIGRyYWdPdmVyQW5pbWF0aW9uQ2FwdHVyZShfcmVmMTEpIHtcbiAgICAgIHZhciBkcmFnUmVjdCA9IF9yZWYxMS5kcmFnUmVjdCxcbiAgICAgICAgaXNPd25lciA9IF9yZWYxMS5pc093bmVyLFxuICAgICAgICBhY3RpdmVTb3J0YWJsZSA9IF9yZWYxMS5hY3RpdmVTb3J0YWJsZTtcbiAgICAgIG11bHRpRHJhZ0VsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKG11bHRpRHJhZ0VsZW1lbnQpIHtcbiAgICAgICAgbXVsdGlEcmFnRWxlbWVudC50aGlzQW5pbWF0aW9uRHVyYXRpb24gPSBudWxsO1xuICAgICAgfSk7XG4gICAgICBpZiAoYWN0aXZlU29ydGFibGUub3B0aW9ucy5hbmltYXRpb24gJiYgIWlzT3duZXIgJiYgYWN0aXZlU29ydGFibGUubXVsdGlEcmFnLmlzTXVsdGlEcmFnKSB7XG4gICAgICAgIGNsb25lc0Zyb21SZWN0ID0gX2V4dGVuZHMoe30sIGRyYWdSZWN0KTtcbiAgICAgICAgdmFyIGRyYWdNYXRyaXggPSBtYXRyaXgoZHJhZ0VsJDEsIHRydWUpO1xuICAgICAgICBjbG9uZXNGcm9tUmVjdC50b3AgLT0gZHJhZ01hdHJpeC5mO1xuICAgICAgICBjbG9uZXNGcm9tUmVjdC5sZWZ0IC09IGRyYWdNYXRyaXguZTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGRyYWdPdmVyQW5pbWF0aW9uQ29tcGxldGU6IGZ1bmN0aW9uIGRyYWdPdmVyQW5pbWF0aW9uQ29tcGxldGUoKSB7XG4gICAgICBpZiAoZm9sZGluZykge1xuICAgICAgICBmb2xkaW5nID0gZmFsc2U7XG4gICAgICAgIHJlbW92ZU11bHRpRHJhZ0VsZW1lbnRzKCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBkcm9wOiBmdW5jdGlvbiBkcm9wKF9yZWYxMikge1xuICAgICAgdmFyIGV2dCA9IF9yZWYxMi5vcmlnaW5hbEV2ZW50LFxuICAgICAgICByb290RWwgPSBfcmVmMTIucm9vdEVsLFxuICAgICAgICBwYXJlbnRFbCA9IF9yZWYxMi5wYXJlbnRFbCxcbiAgICAgICAgc29ydGFibGUgPSBfcmVmMTIuc29ydGFibGUsXG4gICAgICAgIGRpc3BhdGNoU29ydGFibGVFdmVudCA9IF9yZWYxMi5kaXNwYXRjaFNvcnRhYmxlRXZlbnQsXG4gICAgICAgIG9sZEluZGV4ID0gX3JlZjEyLm9sZEluZGV4LFxuICAgICAgICBwdXRTb3J0YWJsZSA9IF9yZWYxMi5wdXRTb3J0YWJsZTtcbiAgICAgIHZhciB0b1NvcnRhYmxlID0gcHV0U29ydGFibGUgfHwgdGhpcy5zb3J0YWJsZTtcbiAgICAgIGlmICghZXZ0KSByZXR1cm47XG4gICAgICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcbiAgICAgICAgY2hpbGRyZW4gPSBwYXJlbnRFbC5jaGlsZHJlbjtcblxuICAgICAgLy8gTXVsdGktZHJhZyBzZWxlY3Rpb25cbiAgICAgIGlmICghZHJhZ1N0YXJ0ZWQpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMubXVsdGlEcmFnS2V5ICYmICF0aGlzLm11bHRpRHJhZ0tleURvd24pIHtcbiAgICAgICAgICB0aGlzLl9kZXNlbGVjdE11bHRpRHJhZygpO1xuICAgICAgICB9XG4gICAgICAgIHRvZ2dsZUNsYXNzKGRyYWdFbCQxLCBvcHRpb25zLnNlbGVjdGVkQ2xhc3MsICF+bXVsdGlEcmFnRWxlbWVudHMuaW5kZXhPZihkcmFnRWwkMSkpO1xuICAgICAgICBpZiAoIX5tdWx0aURyYWdFbGVtZW50cy5pbmRleE9mKGRyYWdFbCQxKSkge1xuICAgICAgICAgIG11bHRpRHJhZ0VsZW1lbnRzLnB1c2goZHJhZ0VsJDEpO1xuICAgICAgICAgIGRpc3BhdGNoRXZlbnQoe1xuICAgICAgICAgICAgc29ydGFibGU6IHNvcnRhYmxlLFxuICAgICAgICAgICAgcm9vdEVsOiByb290RWwsXG4gICAgICAgICAgICBuYW1lOiAnc2VsZWN0JyxcbiAgICAgICAgICAgIHRhcmdldEVsOiBkcmFnRWwkMSxcbiAgICAgICAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2dFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gTW9kaWZpZXIgYWN0aXZhdGVkLCBzZWxlY3QgZnJvbSBsYXN0IHRvIGRyYWdFbFxuICAgICAgICAgIGlmIChldnQuc2hpZnRLZXkgJiYgbGFzdE11bHRpRHJhZ1NlbGVjdCAmJiBzb3J0YWJsZS5lbC5jb250YWlucyhsYXN0TXVsdGlEcmFnU2VsZWN0KSkge1xuICAgICAgICAgICAgdmFyIGxhc3RJbmRleCA9IGluZGV4KGxhc3RNdWx0aURyYWdTZWxlY3QpLFxuICAgICAgICAgICAgICBjdXJyZW50SW5kZXggPSBpbmRleChkcmFnRWwkMSk7XG4gICAgICAgICAgICBpZiAofmxhc3RJbmRleCAmJiB+Y3VycmVudEluZGV4ICYmIGxhc3RJbmRleCAhPT0gY3VycmVudEluZGV4KSB7XG4gICAgICAgICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgLy8gTXVzdCBpbmNsdWRlIGxhc3RNdWx0aURyYWdTZWxlY3QgKHNlbGVjdCBpdCksIGluIGNhc2UgbW9kaWZpZWQgc2VsZWN0aW9uIGZyb20gbm8gc2VsZWN0aW9uXG4gICAgICAgICAgICAgICAgLy8gKGJ1dCBwcmV2aW91cyBzZWxlY3Rpb24gZXhpc3RlZClcbiAgICAgICAgICAgICAgICB2YXIgbiwgaTtcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudEluZGV4ID4gbGFzdEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICBpID0gbGFzdEluZGV4O1xuICAgICAgICAgICAgICAgICAgbiA9IGN1cnJlbnRJbmRleDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgaSA9IGN1cnJlbnRJbmRleDtcbiAgICAgICAgICAgICAgICAgIG4gPSBsYXN0SW5kZXggKyAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgZmlsdGVyID0gb3B0aW9ucy5maWx0ZXI7XG4gICAgICAgICAgICAgICAgZm9yICg7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgIGlmICh+bXVsdGlEcmFnRWxlbWVudHMuaW5kZXhPZihjaGlsZHJlbltpXSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgZWxlbWVudCBpcyBkcmFnZ2FibGVcbiAgICAgICAgICAgICAgICAgIGlmICghY2xvc2VzdChjaGlsZHJlbltpXSwgb3B0aW9ucy5kcmFnZ2FibGUsIHBhcmVudEVsLCBmYWxzZSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgZWxlbWVudCBpcyBmaWx0ZXJlZFxuICAgICAgICAgICAgICAgICAgdmFyIGZpbHRlcmVkID0gZmlsdGVyICYmICh0eXBlb2YgZmlsdGVyID09PSAnZnVuY3Rpb24nID8gZmlsdGVyLmNhbGwoc29ydGFibGUsIGV2dCwgY2hpbGRyZW5baV0sIHNvcnRhYmxlKSA6IGZpbHRlci5zcGxpdCgnLCcpLnNvbWUoZnVuY3Rpb24gKGNyaXRlcmlhKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjbG9zZXN0KGNoaWxkcmVuW2ldLCBjcml0ZXJpYS50cmltKCksIHBhcmVudEVsLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgdG9nZ2xlQ2xhc3MoY2hpbGRyZW5baV0sIG9wdGlvbnMuc2VsZWN0ZWRDbGFzcywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICBtdWx0aURyYWdFbGVtZW50cy5wdXNoKGNoaWxkcmVuW2ldKTtcbiAgICAgICAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoe1xuICAgICAgICAgICAgICAgICAgICBzb3J0YWJsZTogc29ydGFibGUsXG4gICAgICAgICAgICAgICAgICAgIHJvb3RFbDogcm9vdEVsLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiAnc2VsZWN0JyxcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWw6IGNoaWxkcmVuW2ldLFxuICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbEV2ZW50OiBldnRcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGFzdE11bHRpRHJhZ1NlbGVjdCA9IGRyYWdFbCQxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBtdWx0aURyYWdTb3J0YWJsZSA9IHRvU29ydGFibGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbXVsdGlEcmFnRWxlbWVudHMuc3BsaWNlKG11bHRpRHJhZ0VsZW1lbnRzLmluZGV4T2YoZHJhZ0VsJDEpLCAxKTtcbiAgICAgICAgICBsYXN0TXVsdGlEcmFnU2VsZWN0ID0gbnVsbDtcbiAgICAgICAgICBkaXNwYXRjaEV2ZW50KHtcbiAgICAgICAgICAgIHNvcnRhYmxlOiBzb3J0YWJsZSxcbiAgICAgICAgICAgIHJvb3RFbDogcm9vdEVsLFxuICAgICAgICAgICAgbmFtZTogJ2Rlc2VsZWN0JyxcbiAgICAgICAgICAgIHRhcmdldEVsOiBkcmFnRWwkMSxcbiAgICAgICAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2dFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE11bHRpLWRyYWcgZHJvcFxuICAgICAgaWYgKGRyYWdTdGFydGVkICYmIHRoaXMuaXNNdWx0aURyYWcpIHtcbiAgICAgICAgZm9sZGluZyA9IGZhbHNlO1xuICAgICAgICAvLyBEbyBub3QgXCJ1bmZvbGRcIiBhZnRlciBhcm91bmQgZHJhZ0VsIGlmIHJldmVydGVkXG4gICAgICAgIGlmICgocGFyZW50RWxbZXhwYW5kb10ub3B0aW9ucy5zb3J0IHx8IHBhcmVudEVsICE9PSByb290RWwpICYmIG11bHRpRHJhZ0VsZW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICB2YXIgZHJhZ1JlY3QgPSBnZXRSZWN0KGRyYWdFbCQxKSxcbiAgICAgICAgICAgIG11bHRpRHJhZ0luZGV4ID0gaW5kZXgoZHJhZ0VsJDEsICc6bm90KC4nICsgdGhpcy5vcHRpb25zLnNlbGVjdGVkQ2xhc3MgKyAnKScpO1xuICAgICAgICAgIGlmICghaW5pdGlhbEZvbGRpbmcgJiYgb3B0aW9ucy5hbmltYXRpb24pIGRyYWdFbCQxLnRoaXNBbmltYXRpb25EdXJhdGlvbiA9IG51bGw7XG4gICAgICAgICAgdG9Tb3J0YWJsZS5jYXB0dXJlQW5pbWF0aW9uU3RhdGUoKTtcbiAgICAgICAgICBpZiAoIWluaXRpYWxGb2xkaW5nKSB7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5hbmltYXRpb24pIHtcbiAgICAgICAgICAgICAgZHJhZ0VsJDEuZnJvbVJlY3QgPSBkcmFnUmVjdDtcbiAgICAgICAgICAgICAgbXVsdGlEcmFnRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAobXVsdGlEcmFnRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIG11bHRpRHJhZ0VsZW1lbnQudGhpc0FuaW1hdGlvbkR1cmF0aW9uID0gbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAobXVsdGlEcmFnRWxlbWVudCAhPT0gZHJhZ0VsJDEpIHtcbiAgICAgICAgICAgICAgICAgIHZhciByZWN0ID0gZm9sZGluZyA/IGdldFJlY3QobXVsdGlEcmFnRWxlbWVudCkgOiBkcmFnUmVjdDtcbiAgICAgICAgICAgICAgICAgIG11bHRpRHJhZ0VsZW1lbnQuZnJvbVJlY3QgPSByZWN0O1xuXG4gICAgICAgICAgICAgICAgICAvLyBQcmVwYXJlIHVuZm9sZCBhbmltYXRpb25cbiAgICAgICAgICAgICAgICAgIHRvU29ydGFibGUuYWRkQW5pbWF0aW9uU3RhdGUoe1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXQ6IG11bHRpRHJhZ0VsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIHJlY3Q6IHJlY3RcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIE11bHRpIGRyYWcgZWxlbWVudHMgYXJlIG5vdCBuZWNlc3NhcmlseSByZW1vdmVkIGZyb20gdGhlIERPTSBvbiBkcm9wLCBzbyB0byByZWluc2VydFxuICAgICAgICAgICAgLy8gcHJvcGVybHkgdGhleSBtdXN0IGFsbCBiZSByZW1vdmVkXG4gICAgICAgICAgICByZW1vdmVNdWx0aURyYWdFbGVtZW50cygpO1xuICAgICAgICAgICAgbXVsdGlEcmFnRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAobXVsdGlEcmFnRWxlbWVudCkge1xuICAgICAgICAgICAgICBpZiAoY2hpbGRyZW5bbXVsdGlEcmFnSW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgcGFyZW50RWwuaW5zZXJ0QmVmb3JlKG11bHRpRHJhZ0VsZW1lbnQsIGNoaWxkcmVuW211bHRpRHJhZ0luZGV4XSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyZW50RWwuYXBwZW5kQ2hpbGQobXVsdGlEcmFnRWxlbWVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbXVsdGlEcmFnSW5kZXgrKztcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBJZiBpbml0aWFsIGZvbGRpbmcgaXMgZG9uZSwgdGhlIGVsZW1lbnRzIG1heSBoYXZlIGNoYW5nZWQgcG9zaXRpb24gYmVjYXVzZSB0aGV5IGFyZSBub3dcbiAgICAgICAgICAgIC8vIHVuZm9sZGluZyBhcm91bmQgZHJhZ0VsLCBldmVuIHRob3VnaCBkcmFnRWwgbWF5IG5vdCBoYXZlIGhpcyBpbmRleCBjaGFuZ2VkLCBzbyB1cGRhdGUgZXZlbnRcbiAgICAgICAgICAgIC8vIG11c3QgYmUgZmlyZWQgaGVyZSBhcyBTb3J0YWJsZSB3aWxsIG5vdC5cbiAgICAgICAgICAgIGlmIChvbGRJbmRleCA9PT0gaW5kZXgoZHJhZ0VsJDEpKSB7XG4gICAgICAgICAgICAgIHZhciB1cGRhdGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgbXVsdGlEcmFnRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAobXVsdGlEcmFnRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGlmIChtdWx0aURyYWdFbGVtZW50LnNvcnRhYmxlSW5kZXggIT09IGluZGV4KG11bHRpRHJhZ0VsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgICB1cGRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGlmICh1cGRhdGUpIHtcbiAgICAgICAgICAgICAgICBkaXNwYXRjaFNvcnRhYmxlRXZlbnQoJ3VwZGF0ZScpO1xuICAgICAgICAgICAgICAgIGRpc3BhdGNoU29ydGFibGVFdmVudCgnc29ydCcpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gTXVzdCBiZSBkb25lIGFmdGVyIGNhcHR1cmluZyBpbmRpdmlkdWFsIHJlY3RzIChzY3JvbGwgYmFyKVxuICAgICAgICAgIG11bHRpRHJhZ0VsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKG11bHRpRHJhZ0VsZW1lbnQpIHtcbiAgICAgICAgICAgIHVuc2V0UmVjdChtdWx0aURyYWdFbGVtZW50KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0b1NvcnRhYmxlLmFuaW1hdGVBbGwoKTtcbiAgICAgICAgfVxuICAgICAgICBtdWx0aURyYWdTb3J0YWJsZSA9IHRvU29ydGFibGU7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbW92ZSBjbG9uZXMgaWYgbmVjZXNzYXJ5XG4gICAgICBpZiAocm9vdEVsID09PSBwYXJlbnRFbCB8fCBwdXRTb3J0YWJsZSAmJiBwdXRTb3J0YWJsZS5sYXN0UHV0TW9kZSAhPT0gJ2Nsb25lJykge1xuICAgICAgICBtdWx0aURyYWdDbG9uZXMuZm9yRWFjaChmdW5jdGlvbiAoY2xvbmUpIHtcbiAgICAgICAgICBjbG9uZS5wYXJlbnROb2RlICYmIGNsb25lLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY2xvbmUpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9LFxuICAgIG51bGxpbmdHbG9iYWw6IGZ1bmN0aW9uIG51bGxpbmdHbG9iYWwoKSB7XG4gICAgICB0aGlzLmlzTXVsdGlEcmFnID0gZHJhZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgIG11bHRpRHJhZ0Nsb25lcy5sZW5ndGggPSAwO1xuICAgIH0sXG4gICAgZGVzdHJveUdsb2JhbDogZnVuY3Rpb24gZGVzdHJveUdsb2JhbCgpIHtcbiAgICAgIHRoaXMuX2Rlc2VsZWN0TXVsdGlEcmFnKCk7XG4gICAgICBvZmYoZG9jdW1lbnQsICdwb2ludGVydXAnLCB0aGlzLl9kZXNlbGVjdE11bHRpRHJhZyk7XG4gICAgICBvZmYoZG9jdW1lbnQsICdtb3VzZXVwJywgdGhpcy5fZGVzZWxlY3RNdWx0aURyYWcpO1xuICAgICAgb2ZmKGRvY3VtZW50LCAndG91Y2hlbmQnLCB0aGlzLl9kZXNlbGVjdE11bHRpRHJhZyk7XG4gICAgICBvZmYoZG9jdW1lbnQsICdrZXlkb3duJywgdGhpcy5fY2hlY2tLZXlEb3duKTtcbiAgICAgIG9mZihkb2N1bWVudCwgJ2tleXVwJywgdGhpcy5fY2hlY2tLZXlVcCk7XG4gICAgfSxcbiAgICBfZGVzZWxlY3RNdWx0aURyYWc6IGZ1bmN0aW9uIF9kZXNlbGVjdE11bHRpRHJhZyhldnQpIHtcbiAgICAgIGlmICh0eXBlb2YgZHJhZ1N0YXJ0ZWQgIT09IFwidW5kZWZpbmVkXCIgJiYgZHJhZ1N0YXJ0ZWQpIHJldHVybjtcblxuICAgICAgLy8gT25seSBkZXNlbGVjdCBpZiBzZWxlY3Rpb24gaXMgaW4gdGhpcyBzb3J0YWJsZVxuICAgICAgaWYgKG11bHRpRHJhZ1NvcnRhYmxlICE9PSB0aGlzLnNvcnRhYmxlKSByZXR1cm47XG5cbiAgICAgIC8vIE9ubHkgZGVzZWxlY3QgaWYgdGFyZ2V0IGlzIG5vdCBpdGVtIGluIHRoaXMgc29ydGFibGVcbiAgICAgIGlmIChldnQgJiYgY2xvc2VzdChldnQudGFyZ2V0LCB0aGlzLm9wdGlvbnMuZHJhZ2dhYmxlLCB0aGlzLnNvcnRhYmxlLmVsLCBmYWxzZSkpIHJldHVybjtcblxuICAgICAgLy8gT25seSBkZXNlbGVjdCBpZiBsZWZ0IGNsaWNrXG4gICAgICBpZiAoZXZ0ICYmIGV2dC5idXR0b24gIT09IDApIHJldHVybjtcbiAgICAgIHdoaWxlIChtdWx0aURyYWdFbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIGVsID0gbXVsdGlEcmFnRWxlbWVudHNbMF07XG4gICAgICAgIHRvZ2dsZUNsYXNzKGVsLCB0aGlzLm9wdGlvbnMuc2VsZWN0ZWRDbGFzcywgZmFsc2UpO1xuICAgICAgICBtdWx0aURyYWdFbGVtZW50cy5zaGlmdCgpO1xuICAgICAgICBkaXNwYXRjaEV2ZW50KHtcbiAgICAgICAgICBzb3J0YWJsZTogdGhpcy5zb3J0YWJsZSxcbiAgICAgICAgICByb290RWw6IHRoaXMuc29ydGFibGUuZWwsXG4gICAgICAgICAgbmFtZTogJ2Rlc2VsZWN0JyxcbiAgICAgICAgICB0YXJnZXRFbDogZWwsXG4gICAgICAgICAgb3JpZ2luYWxFdmVudDogZXZ0XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG4gICAgX2NoZWNrS2V5RG93bjogZnVuY3Rpb24gX2NoZWNrS2V5RG93bihldnQpIHtcbiAgICAgIGlmIChldnQua2V5ID09PSB0aGlzLm9wdGlvbnMubXVsdGlEcmFnS2V5KSB7XG4gICAgICAgIHRoaXMubXVsdGlEcmFnS2V5RG93biA9IHRydWU7XG4gICAgICB9XG4gICAgfSxcbiAgICBfY2hlY2tLZXlVcDogZnVuY3Rpb24gX2NoZWNrS2V5VXAoZXZ0KSB7XG4gICAgICBpZiAoZXZ0LmtleSA9PT0gdGhpcy5vcHRpb25zLm11bHRpRHJhZ0tleSkge1xuICAgICAgICB0aGlzLm11bHRpRHJhZ0tleURvd24gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHJldHVybiBfZXh0ZW5kcyhNdWx0aURyYWcsIHtcbiAgICAvLyBTdGF0aWMgbWV0aG9kcyAmIHByb3BlcnRpZXNcbiAgICBwbHVnaW5OYW1lOiAnbXVsdGlEcmFnJyxcbiAgICB1dGlsczoge1xuICAgICAgLyoqXHJcbiAgICAgICAqIFNlbGVjdHMgdGhlIHByb3ZpZGVkIG11bHRpLWRyYWcgaXRlbVxyXG4gICAgICAgKiBAcGFyYW0gIHtIVE1MRWxlbWVudH0gZWwgICAgVGhlIGVsZW1lbnQgdG8gYmUgc2VsZWN0ZWRcclxuICAgICAgICovXG4gICAgICBzZWxlY3Q6IGZ1bmN0aW9uIHNlbGVjdChlbCkge1xuICAgICAgICB2YXIgc29ydGFibGUgPSBlbC5wYXJlbnROb2RlW2V4cGFuZG9dO1xuICAgICAgICBpZiAoIXNvcnRhYmxlIHx8ICFzb3J0YWJsZS5vcHRpb25zLm11bHRpRHJhZyB8fCB+bXVsdGlEcmFnRWxlbWVudHMuaW5kZXhPZihlbCkpIHJldHVybjtcbiAgICAgICAgaWYgKG11bHRpRHJhZ1NvcnRhYmxlICYmIG11bHRpRHJhZ1NvcnRhYmxlICE9PSBzb3J0YWJsZSkge1xuICAgICAgICAgIG11bHRpRHJhZ1NvcnRhYmxlLm11bHRpRHJhZy5fZGVzZWxlY3RNdWx0aURyYWcoKTtcbiAgICAgICAgICBtdWx0aURyYWdTb3J0YWJsZSA9IHNvcnRhYmxlO1xuICAgICAgICB9XG4gICAgICAgIHRvZ2dsZUNsYXNzKGVsLCBzb3J0YWJsZS5vcHRpb25zLnNlbGVjdGVkQ2xhc3MsIHRydWUpO1xuICAgICAgICBtdWx0aURyYWdFbGVtZW50cy5wdXNoKGVsKTtcbiAgICAgIH0sXG4gICAgICAvKipcclxuICAgICAgICogRGVzZWxlY3RzIHRoZSBwcm92aWRlZCBtdWx0aS1kcmFnIGl0ZW1cclxuICAgICAgICogQHBhcmFtICB7SFRNTEVsZW1lbnR9IGVsICAgIFRoZSBlbGVtZW50IHRvIGJlIGRlc2VsZWN0ZWRcclxuICAgICAgICovXG4gICAgICBkZXNlbGVjdDogZnVuY3Rpb24gZGVzZWxlY3QoZWwpIHtcbiAgICAgICAgdmFyIHNvcnRhYmxlID0gZWwucGFyZW50Tm9kZVtleHBhbmRvXSxcbiAgICAgICAgICBpbmRleCA9IG11bHRpRHJhZ0VsZW1lbnRzLmluZGV4T2YoZWwpO1xuICAgICAgICBpZiAoIXNvcnRhYmxlIHx8ICFzb3J0YWJsZS5vcHRpb25zLm11bHRpRHJhZyB8fCAhfmluZGV4KSByZXR1cm47XG4gICAgICAgIHRvZ2dsZUNsYXNzKGVsLCBzb3J0YWJsZS5vcHRpb25zLnNlbGVjdGVkQ2xhc3MsIGZhbHNlKTtcbiAgICAgICAgbXVsdGlEcmFnRWxlbWVudHMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGV2ZW50UHJvcGVydGllczogZnVuY3Rpb24gZXZlbnRQcm9wZXJ0aWVzKCkge1xuICAgICAgdmFyIF90aGlzMyA9IHRoaXM7XG4gICAgICB2YXIgb2xkSW5kaWNpZXMgPSBbXSxcbiAgICAgICAgbmV3SW5kaWNpZXMgPSBbXTtcbiAgICAgIG11bHRpRHJhZ0VsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKG11bHRpRHJhZ0VsZW1lbnQpIHtcbiAgICAgICAgb2xkSW5kaWNpZXMucHVzaCh7XG4gICAgICAgICAgbXVsdGlEcmFnRWxlbWVudDogbXVsdGlEcmFnRWxlbWVudCxcbiAgICAgICAgICBpbmRleDogbXVsdGlEcmFnRWxlbWVudC5zb3J0YWJsZUluZGV4XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIG11bHRpRHJhZ0VsZW1lbnRzIHdpbGwgYWxyZWFkeSBiZSBzb3J0ZWQgaWYgZm9sZGluZ1xuICAgICAgICB2YXIgbmV3SW5kZXg7XG4gICAgICAgIGlmIChmb2xkaW5nICYmIG11bHRpRHJhZ0VsZW1lbnQgIT09IGRyYWdFbCQxKSB7XG4gICAgICAgICAgbmV3SW5kZXggPSAtMTtcbiAgICAgICAgfSBlbHNlIGlmIChmb2xkaW5nKSB7XG4gICAgICAgICAgbmV3SW5kZXggPSBpbmRleChtdWx0aURyYWdFbGVtZW50LCAnOm5vdCguJyArIF90aGlzMy5vcHRpb25zLnNlbGVjdGVkQ2xhc3MgKyAnKScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld0luZGV4ID0gaW5kZXgobXVsdGlEcmFnRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgbmV3SW5kaWNpZXMucHVzaCh7XG4gICAgICAgICAgbXVsdGlEcmFnRWxlbWVudDogbXVsdGlEcmFnRWxlbWVudCxcbiAgICAgICAgICBpbmRleDogbmV3SW5kZXhcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGl0ZW1zOiBfdG9Db25zdW1hYmxlQXJyYXkobXVsdGlEcmFnRWxlbWVudHMpLFxuICAgICAgICBjbG9uZXM6IFtdLmNvbmNhdChtdWx0aURyYWdDbG9uZXMpLFxuICAgICAgICBvbGRJbmRpY2llczogb2xkSW5kaWNpZXMsXG4gICAgICAgIG5ld0luZGljaWVzOiBuZXdJbmRpY2llc1xuICAgICAgfTtcbiAgICB9LFxuICAgIG9wdGlvbkxpc3RlbmVyczoge1xuICAgICAgbXVsdGlEcmFnS2V5OiBmdW5jdGlvbiBtdWx0aURyYWdLZXkoa2V5KSB7XG4gICAgICAgIGtleSA9IGtleS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoa2V5ID09PSAnY3RybCcpIHtcbiAgICAgICAgICBrZXkgPSAnQ29udHJvbCc7XG4gICAgICAgIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICBrZXkgPSBrZXkuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBrZXkuc3Vic3RyKDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbn1cbmZ1bmN0aW9uIGluc2VydE11bHRpRHJhZ0VsZW1lbnRzKGNsb25lc0luc2VydGVkLCByb290RWwpIHtcbiAgbXVsdGlEcmFnRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAobXVsdGlEcmFnRWxlbWVudCwgaSkge1xuICAgIHZhciB0YXJnZXQgPSByb290RWwuY2hpbGRyZW5bbXVsdGlEcmFnRWxlbWVudC5zb3J0YWJsZUluZGV4ICsgKGNsb25lc0luc2VydGVkID8gTnVtYmVyKGkpIDogMCldO1xuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgIHJvb3RFbC5pbnNlcnRCZWZvcmUobXVsdGlEcmFnRWxlbWVudCwgdGFyZ2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcm9vdEVsLmFwcGVuZENoaWxkKG11bHRpRHJhZ0VsZW1lbnQpO1xuICAgIH1cbiAgfSk7XG59XG5cbi8qKlxyXG4gKiBJbnNlcnQgbXVsdGktZHJhZyBjbG9uZXNcclxuICogQHBhcmFtICB7W0Jvb2xlYW5dfSBlbGVtZW50c0luc2VydGVkICBXaGV0aGVyIHRoZSBtdWx0aS1kcmFnIGVsZW1lbnRzIGFyZSBpbnNlcnRlZFxyXG4gKiBAcGFyYW0gIHtIVE1MRWxlbWVudH0gcm9vdEVsXHJcbiAqL1xuZnVuY3Rpb24gaW5zZXJ0TXVsdGlEcmFnQ2xvbmVzKGVsZW1lbnRzSW5zZXJ0ZWQsIHJvb3RFbCkge1xuICBtdWx0aURyYWdDbG9uZXMuZm9yRWFjaChmdW5jdGlvbiAoY2xvbmUsIGkpIHtcbiAgICB2YXIgdGFyZ2V0ID0gcm9vdEVsLmNoaWxkcmVuW2Nsb25lLnNvcnRhYmxlSW5kZXggKyAoZWxlbWVudHNJbnNlcnRlZCA/IE51bWJlcihpKSA6IDApXTtcbiAgICBpZiAodGFyZ2V0KSB7XG4gICAgICByb290RWwuaW5zZXJ0QmVmb3JlKGNsb25lLCB0YXJnZXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByb290RWwuYXBwZW5kQ2hpbGQoY2xvbmUpO1xuICAgIH1cbiAgfSk7XG59XG5mdW5jdGlvbiByZW1vdmVNdWx0aURyYWdFbGVtZW50cygpIHtcbiAgbXVsdGlEcmFnRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAobXVsdGlEcmFnRWxlbWVudCkge1xuICAgIGlmIChtdWx0aURyYWdFbGVtZW50ID09PSBkcmFnRWwkMSkgcmV0dXJuO1xuICAgIG11bHRpRHJhZ0VsZW1lbnQucGFyZW50Tm9kZSAmJiBtdWx0aURyYWdFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobXVsdGlEcmFnRWxlbWVudCk7XG4gIH0pO1xufVxuXG5Tb3J0YWJsZS5tb3VudChuZXcgQXV0b1Njcm9sbFBsdWdpbigpKTtcblNvcnRhYmxlLm1vdW50KFJlbW92ZSwgUmV2ZXJ0KTtcblxuZXhwb3J0IGRlZmF1bHQgU29ydGFibGU7XG5leHBvcnQgeyBNdWx0aURyYWdQbHVnaW4gYXMgTXVsdGlEcmFnLCBTb3J0YWJsZSwgU3dhcFBsdWdpbiBhcyBTd2FwIH07XG4iLCAiaW1wb3J0IFNvcnRhYmxlIGZyb20gJ3NvcnRhYmxlanMnO1xuaW1wb3J0IHR5cGUgeyBUYXNrIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRhc2tMaXN0Q2FsbGJhY2tzIHtcbiAgb25Db21wbGV0ZTogKGluZGV4OiBudW1iZXIpID0+IHZvaWQ7XG4gIG9uRWRpdDogKGluZGV4OiBudW1iZXIpID0+IHZvaWQ7XG4gIG9uUmVvcmRlcjogKG9sZEluZGV4OiBudW1iZXIsIG5ld0luZGV4OiBudW1iZXIpID0+IHZvaWQ7XG59XG5cbi8qKlxuICogQnVpbGRzIGFuZCBtYW5hZ2VzIHRoZSBzb3J0YWJsZSB0YXNrIGxpc3QgRE9NLlxuICovXG5leHBvcnQgY2xhc3MgVGFza0xpc3RDb21wb25lbnQge1xuICBwcml2YXRlIGNvbnRhaW5lcjogSFRNTEVsZW1lbnQ7XG4gIHByaXZhdGUgY2FsbGJhY2tzOiBUYXNrTGlzdENhbGxiYWNrcztcbiAgcHJpdmF0ZSBzb3J0YWJsZTogU29ydGFibGUgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3Rvcihjb250YWluZXI6IEhUTUxFbGVtZW50LCBjYWxsYmFja3M6IFRhc2tMaXN0Q2FsbGJhY2tzKSB7XG4gICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgdGhpcy5jYWxsYmFja3MgPSBjYWxsYmFja3M7XG4gIH1cblxuICByZW5kZXIodGFza3M6IFRhc2tbXSk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSgpO1xuICAgIHRoaXMuY29udGFpbmVyLmVtcHR5KCk7XG5cbiAgICBpZiAodGFza3MubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICBjb25zdCBsaXN0ID0gdGhpcy5jb250YWluZXIuY3JlYXRlRWwoJ3VsJywgeyBjbHM6ICd5YW90cC10YXNrLWxpc3QnIH0pO1xuXG4gICAgdGFza3MuZm9yRWFjaCgodGFzaywgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBsaXN0LmNyZWF0ZUVsKCdsaScsIHsgY2xzOiAneWFvdHAtdGFzay1pdGVtJyB9KTtcbiAgICAgIGlmICh0YXNrLmNvbXBsZXRlZCkgaXRlbS5hZGRDbGFzcygneWFvdHAtdGFzay1jb21wbGV0ZWQnKTtcbiAgICAgIGl0ZW0uZGF0YXNldC5pbmRleCA9IFN0cmluZyhpbmRleCk7XG5cbiAgICAgIC8vIERyYWcgaGFuZGxlXG4gICAgICBjb25zdCBoYW5kbGUgPSBpdGVtLmNyZWF0ZURpdih7IGNsczogJ3lhb3RwLWRyYWctaGFuZGxlJyB9KTtcbiAgICAgIGhhbmRsZS5pbm5lckhUTUwgPSAnJiM4OTQyOyc7IC8vIHZlcnRpY2FsIGVsbGlwc2lzIFx1MjJFRVxuXG4gICAgICAvLyBDaGVja2JveFxuICAgICAgY29uc3QgY2hlY2tib3ggPSBpdGVtLmNyZWF0ZUVsKCdpbnB1dCcsIHtcbiAgICAgICAgY2xzOiAneWFvdHAtY2hlY2tib3gnLFxuICAgICAgICB0eXBlOiAnY2hlY2tib3gnLFxuICAgICAgICBhdHRyOiB7ICdhcmlhLWxhYmVsJzogJ0NvbXBsZXRlIHRhc2snIH0sXG4gICAgICB9KSBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgY2hlY2tib3guY2hlY2tlZCA9IHRhc2suY29tcGxldGVkO1xuICAgICAgY2hlY2tib3guYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB0aGlzLmNhbGxiYWNrcy5vbkNvbXBsZXRlKGluZGV4KTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBUYXNrIHRleHQgKHdyYXBzKVxuICAgICAgY29uc3QgdGV4dEVsID0gaXRlbS5jcmVhdGVEaXYoeyBjbHM6ICd5YW90cC10YXNrLXRleHQnIH0pO1xuICAgICAgdGV4dEVsLnNldFRleHQodGFzay50ZXh0KTtcbiAgICAgIGlmICh0YXNrLm5vdGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGV4dEVsLmFkZENsYXNzKCd5YW90cC10YXNrLWhhcy1ub3RlcycpO1xuICAgICAgfVxuICAgICAgdGV4dEVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcy5vbkVkaXQoaW5kZXgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNvcnRhYmxlID0gU29ydGFibGUuY3JlYXRlKGxpc3QsIHtcbiAgICAgIGhhbmRsZTogJy55YW90cC1kcmFnLWhhbmRsZScsXG4gICAgICBhbmltYXRpb246IDE1MCxcbiAgICAgIGRlbGF5OiAzMDAsXG4gICAgICBkZWxheU9uVG91Y2hPbmx5OiB0cnVlLFxuICAgICAgb25FbmQ6IChldnQpID0+IHtcbiAgICAgICAgY29uc3Qgb2xkSW5kZXggPSBldnQub2xkSW5kZXg7XG4gICAgICAgIGNvbnN0IG5ld0luZGV4ID0gZXZ0Lm5ld0luZGV4O1xuICAgICAgICBpZiAob2xkSW5kZXggIT09IHVuZGVmaW5lZCAmJiBuZXdJbmRleCAhPT0gdW5kZWZpbmVkICYmIG9sZEluZGV4ICE9PSBuZXdJbmRleCkge1xuICAgICAgICAgIHRoaXMuY2FsbGJhY2tzLm9uUmVvcmRlcihvbGRJbmRleCwgbmV3SW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zb3J0YWJsZSkge1xuICAgICAgdGhpcy5zb3J0YWJsZS5kZXN0cm95KCk7XG4gICAgICB0aGlzLnNvcnRhYmxlID0gbnVsbDtcbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBURmlsZSB9IGZyb20gJ29ic2lkaWFuJztcblxuZXhwb3J0IGludGVyZmFjZSBGaWxlU3dpdGNoZXJCYXJPcHRpb25zIHtcbiAgYXBwOiB1bmtub3duOyAvLyBrZXB0IGZvciBpbnRlcmZhY2UgY29tcGF0aWJpbGl0eSwgdW51c2VkIGFmdGVyIG1vZGFsIHJlbW92YWxcbiAgY3VycmVudEZpbGU6IFRGaWxlO1xuICB0YXNrRmlsZXM6IFRGaWxlW107XG4gIGluYm94UGF0aDogc3RyaW5nO1xuICBvblN3aXRjaEZpbGU6IChmaWxlOiBURmlsZSkgPT4gdm9pZDtcbiAgb25DcmVhdGVGaWxlOiAobmFtZTogc3RyaW5nKSA9PiB2b2lkO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgYSBoZWFkZXIgYmFyIHdpdGggYSBmaWxlIHN3aXRjaGVyIGRyb3Bkb3duIGFuZCBhbiBpbmxpbmVcbiAqIFwiTmV3IHRhc2sgZmlsZVwiIGFmZm9yZGFuY2UuIFJldHVybnMgdGhlIGNvbnRhaW5lciBlbGVtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRGaWxlU3dpdGNoZXJCYXIob3B0czogRmlsZVN3aXRjaGVyQmFyT3B0aW9ucyk6IEhUTUxFbGVtZW50IHtcbiAgY29uc3QgeyBjdXJyZW50RmlsZSwgdGFza0ZpbGVzLCBpbmJveFBhdGgsIG9uU3dpdGNoRmlsZSwgb25DcmVhdGVGaWxlIH0gPSBvcHRzO1xuXG4gIGNvbnN0IGJhciA9IGNyZWF0ZURpdih7IGNsczogJ3lhb3RwLXN3aXRjaGVyLWJhcicgfSk7XG5cbiAgLy8gTGVmdCBzaWRlOiBmaWxlIHNlbGVjdG9yXG4gIGNvbnN0IHNlbGVjdFdyYXAgPSBiYXIuY3JlYXRlRGl2KHsgY2xzOiAneWFvdHAtc3dpdGNoZXItc2VsZWN0LXdyYXAnIH0pO1xuICBjb25zdCBzZWxlY3QgPSBzZWxlY3RXcmFwLmNyZWF0ZUVsKCdzZWxlY3QnLCB7IGNsczogJ3lhb3RwLXN3aXRjaGVyLXNlbGVjdCcgfSk7XG5cbiAgLy8gQWx3YXlzIHNob3cgSW5ib3ggZmlyc3QgaWYgaXQgZXhpc3RzIGluIHRoZSBsaXN0XG4gIGNvbnN0IGluYm94ID0gdGFza0ZpbGVzLmZpbmQoKGYpID0+IGYucGF0aCA9PT0gaW5ib3hQYXRoKTtcbiAgY29uc3Qgb3RoZXJzID0gdGFza0ZpbGVzLmZpbHRlcigoZikgPT4gZi5wYXRoICE9PSBpbmJveFBhdGgpO1xuICBmb3IgKGNvbnN0IGZpbGUgb2YgKGluYm94ID8gW2luYm94LCAuLi5vdGhlcnNdIDogb3RoZXJzKSkge1xuICAgIGNvbnN0IG9wdCA9IHNlbGVjdC5jcmVhdGVFbCgnb3B0aW9uJywgeyB0ZXh0OiBmaWxlLmJhc2VuYW1lLCB2YWx1ZTogZmlsZS5wYXRoIH0pO1xuICAgIGlmIChmaWxlLnBhdGggPT09IGN1cnJlbnRGaWxlLnBhdGgpIG9wdC5zZWxlY3RlZCA9IHRydWU7XG4gIH1cbiAgc2VsZWN0LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsICgpID0+IHtcbiAgICBjb25zdCBjaG9zZW4gPSB0YXNrRmlsZXMuZmluZCgoZikgPT4gZi5wYXRoID09PSBzZWxlY3QudmFsdWUpO1xuICAgIGlmIChjaG9zZW4pIG9uU3dpdGNoRmlsZShjaG9zZW4pO1xuICB9KTtcblxuICAvLyBSaWdodCBzaWRlOiBcIisgTmV3IGxpc3RcIiBidXR0b24gLyBpbmxpbmUgY3JlYXRlIGlucHV0IChtdXR1YWxseSBleGNsdXNpdmUpXG4gIGNvbnN0IG5ld0J0biA9IGJhci5jcmVhdGVFbCgnYnV0dG9uJywge1xuICAgIHRleHQ6ICcrIE5ldyBsaXN0JyxcbiAgICBjbHM6ICd5YW90cC1zd2l0Y2hlci1uZXctYnRuJyxcbiAgfSk7XG5cbiAgY29uc3QgY3JlYXRlR3JvdXAgPSBiYXIuY3JlYXRlRGl2KHsgY2xzOiAneWFvdHAtc3dpdGNoZXItY3JlYXRlLWdyb3VwJyB9KTtcbiAgY3JlYXRlR3JvdXAuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblxuICBjb25zdCBuYW1lSW5wdXQgPSBjcmVhdGVHcm91cC5jcmVhdGVFbCgnaW5wdXQnLCB7XG4gICAgdHlwZTogJ3RleHQnLFxuICAgIGNsczogJ3lhb3RwLXN3aXRjaGVyLW5hbWUtaW5wdXQnLFxuICAgIGF0dHI6IHsgcGxhY2Vob2xkZXI6ICdGaWxlIG5hbWUgKHdpdGhvdXQgLm1kKScgfSxcbiAgfSkgYXMgSFRNTElucHV0RWxlbWVudDtcblxuICBjb25zdCBjb25maXJtQnRuID0gY3JlYXRlR3JvdXAuY3JlYXRlRWwoJ2J1dHRvbicsIHtcbiAgICB0ZXh0OiAnQ3JlYXRlJyxcbiAgICBjbHM6ICdtb2QtY3RhIHlhb3RwLXN3aXRjaGVyLWNvbmZpcm0tYnRuJyxcbiAgfSk7XG4gIGNvbnN0IGNhbmNlbEJ0biA9IGNyZWF0ZUdyb3VwLmNyZWF0ZUVsKCdidXR0b24nLCB7XG4gICAgdGV4dDogJ1x1MjcxNScsXG4gICAgY2xzOiAneWFvdHAtc3dpdGNoZXItY2FuY2VsLWJ0bicsXG4gIH0pO1xuXG4gIGNvbnN0IHNob3dJbnB1dCA9ICgpID0+IHtcbiAgICBuZXdCdG4uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBjcmVhdGVHcm91cC5zdHlsZS5kaXNwbGF5ID0gJ2ZsZXgnO1xuICAgIG5hbWVJbnB1dC52YWx1ZSA9ICcnO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gbmFtZUlucHV0LmZvY3VzKCksIDApO1xuICB9O1xuXG4gIGNvbnN0IGhpZGVJbnB1dCA9ICgpID0+IHtcbiAgICBjcmVhdGVHcm91cC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIG5ld0J0bi5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gIH07XG5cbiAgY29uc3Qgc3VibWl0ID0gKCkgPT4ge1xuICAgIGNvbnN0IG5hbWUgPSBuYW1lSW5wdXQudmFsdWUudHJpbSgpO1xuICAgIGlmIChuYW1lKSB7XG4gICAgICBoaWRlSW5wdXQoKTtcbiAgICAgIG9uQ3JlYXRlRmlsZShuYW1lKTtcbiAgICB9XG4gIH07XG5cbiAgbmV3QnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgc2hvd0lucHV0KTtcbiAgY29uZmlybUJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHN1Ym1pdCk7XG4gIGNhbmNlbEJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGhpZGVJbnB1dCk7XG4gIG5hbWVJbnB1dC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgKGUpID0+IHtcbiAgICBpZiAoZS5rZXkgPT09ICdFbnRlcicpIHN1Ym1pdCgpO1xuICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScpIGhpZGVJbnB1dCgpO1xuICB9KTtcblxuICByZXR1cm4gYmFyO1xufVxuIiwgImltcG9ydCB7IEFwcCwgRnV6enlTdWdnZXN0TW9kYWwsIE1vZGFsLCBURmlsZSB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB0eXBlIHsgVGFzayB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBUYXNrRWRpdG9yUmVzdWx0IHtcbiAgdGV4dDogc3RyaW5nO1xuICBub3Rlczogc3RyaW5nW107XG4gIC8qKiBJZiBzZXQsIG1vdmUgdGhlIHRhc2sgdG8gdGhpcyBmaWxlLiAqL1xuICB0YXJnZXRGaWxlOiBURmlsZSB8IG51bGw7XG59XG5cbnR5cGUgU2F2ZUNhbGxiYWNrID0gKHJlc3VsdDogVGFza0VkaXRvclJlc3VsdCkgPT4gdm9pZDtcbnR5cGUgRGVsZXRlQ2FsbGJhY2sgPSAoKSA9PiB2b2lkO1xuXG4vKipcbiAqIE1vZGFsIGZvciBlZGl0aW5nIGEgdGFzaydzIHRleHQgYW5kIG5vdGVzIHRvZ2V0aGVyLCBhbmQgb3B0aW9uYWxseVxuICogbW92aW5nIGl0IHRvIGEgZGlmZmVyZW50IHRhc2sgZmlsZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFRhc2tFZGl0b3JNb2RhbCBleHRlbmRzIE1vZGFsIHtcbiAgcHJpdmF0ZSB0YXNrOiBUYXNrO1xuICBwcml2YXRlIHRhc2tGaWxlczogVEZpbGVbXTtcbiAgcHJpdmF0ZSBjdXJyZW50RmlsZTogVEZpbGU7XG4gIHByaXZhdGUgb25TYXZlOiBTYXZlQ2FsbGJhY2s7XG4gIHByaXZhdGUgb25EZWxldGU6IERlbGV0ZUNhbGxiYWNrO1xuICBwcml2YXRlIHRleHRhcmVhOiBIVE1MVGV4dEFyZWFFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc2VsZWN0ZWRGaWxlOiBURmlsZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGZpbGVMYWJlbDogSFRNTFNwYW5FbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUga2V5Ym9hcmRDbGVhbnVwOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBhcHA6IEFwcCxcbiAgICB0YXNrOiBUYXNrLFxuICAgIHRhc2tGaWxlczogVEZpbGVbXSxcbiAgICBjdXJyZW50RmlsZTogVEZpbGUsXG4gICAgb25TYXZlOiBTYXZlQ2FsbGJhY2ssXG4gICAgb25EZWxldGU6IERlbGV0ZUNhbGxiYWNrXG4gICkge1xuICAgIHN1cGVyKGFwcCk7XG4gICAgdGhpcy50YXNrID0gdGFzaztcbiAgICB0aGlzLnRhc2tGaWxlcyA9IHRhc2tGaWxlcztcbiAgICB0aGlzLmN1cnJlbnRGaWxlID0gY3VycmVudEZpbGU7XG4gICAgdGhpcy5vblNhdmUgPSBvblNhdmU7XG4gICAgdGhpcy5vbkRlbGV0ZSA9IG9uRGVsZXRlO1xuICB9XG5cbiAgb25PcGVuKCk6IHZvaWQge1xuICAgIGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xuICAgIGNvbnRlbnRFbC5hZGRDbGFzcygneWFvdHAtZWRpdG9yLW1vZGFsJyk7XG5cbiAgICAvLyBcdTI1MDBcdTI1MDAgQW5kcm9pZCBrZXlib2FyZCBhdm9pZGFuY2UgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG4gICAgLy8gT2JzaWRpYW4gQW5kcm9pZCAoQ2FwYWNpdG9yKSBkZWZhdWx0cyB0byBhZGp1c3ROb3RoaW5nIGtleWJvYXJkIG1vZGUsXG4gICAgLy8gbWVhbmluZyB0aGUga2V5Ym9hcmQgaXMgYSBwdXJlIG92ZXJsYXk6IG5laXRoZXIgd2luZG93LmlubmVySGVpZ2h0IG5vclxuICAgIC8vIHZpc3VhbFZpZXdwb3J0LmhlaWdodCBjaGFuZ2VzLiAgQ2FwYWNpdG9yIGZpcmVzIGl0cyBvd24ga2V5Ym9hcmQgZXZlbnRzXG4gICAgLy8gb24gd2luZG93IHdpdGggYW4gZXhwbGljaXQga2V5Ym9hcmRIZWlnaHQgc28gd2UgdXNlIHRob3NlIGFzIHRoZSBwcmltYXJ5XG4gICAgLy8gc2lnbmFsLCB3aXRoIGEgdmlzdWFsVmlld3BvcnQgZmFsbGJhY2sgZm9yIG90aGVyIGVudmlyb25tZW50cy5cblxuICAgIGNvbnN0IGFwcGx5TGF5b3V0ID0gKGtleWJvYXJkSGVpZ2h0OiBudW1iZXIpID0+IHtcbiAgICAgIGNvbnN0IGF2YWlsYWJsZSA9IHdpbmRvdy5pbm5lckhlaWdodCAtIGtleWJvYXJkSGVpZ2h0O1xuICAgICAgdGhpcy5jb250YWluZXJFbC5zdHlsZS5oZWlnaHQgPSBgJHthdmFpbGFibGV9cHhgO1xuICAgICAgdGhpcy5jb250YWluZXJFbC5zdHlsZS5hbGlnbkl0ZW1zID0gJ2ZsZXgtc3RhcnQnO1xuICAgICAgdGhpcy5jb250YWluZXJFbC5zdHlsZS5wYWRkaW5nVG9wID0gJzhweCc7XG4gICAgICB0aGlzLm1vZGFsRWwuc3R5bGUubWF4SGVpZ2h0ID0gYCR7YXZhaWxhYmxlIC0gMTZ9cHhgO1xuICAgIH07XG4gICAgY29uc3QgcmVzZXRMYXlvdXQgPSAoKSA9PiB7XG4gICAgICB0aGlzLmNvbnRhaW5lckVsLnN0eWxlLmhlaWdodCA9ICcnO1xuICAgICAgdGhpcy5jb250YWluZXJFbC5zdHlsZS5hbGlnbkl0ZW1zID0gJyc7XG4gICAgICB0aGlzLmNvbnRhaW5lckVsLnN0eWxlLnBhZGRpbmdUb3AgPSAnJztcbiAgICAgIHRoaXMubW9kYWxFbC5zdHlsZS5tYXhIZWlnaHQgPSAnJztcbiAgICB9O1xuXG4gICAgLy8gQ2FwYWNpdG9yIGV2ZW50cyBjYXJyeSBrZXlib2FyZEhlaWdodCBkaXJlY3RseS5cbiAgICBjb25zdCBvbkNhcGFjaXRvclNob3cgPSAoZTogRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGtoOiBudW1iZXIgPSAoZSBhcyBhbnkpLmtleWJvYXJkSGVpZ2h0XG4gICAgICAgID8/IChlIGFzIGFueSkuZGV0YWlsPy5rZXlib2FyZEhlaWdodFxuICAgICAgICA/PyAwO1xuICAgICAgaWYgKGtoID4gMCkgYXBwbHlMYXlvdXQoa2gpO1xuICAgIH07XG4gICAgY29uc3Qgb25DYXBhY2l0b3JIaWRlID0gKCkgPT4gcmVzZXRMYXlvdXQoKTtcblxuICAgIC8vIHZpc3VhbFZpZXdwb3J0IGZhbGxiYWNrOiB3b3JrcyB3aGVuIGFkanVzdFJlc2l6ZSAvIGFkanVzdFBhbiBpcyBhY3RpdmUuXG4gICAgY29uc3Qgb25WaWV3cG9ydCA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHZ2ID0gd2luZG93LnZpc3VhbFZpZXdwb3J0O1xuICAgICAgaWYgKCF2dikgcmV0dXJuO1xuICAgICAgY29uc3Qga2ggPSBNYXRoLm1heCgwLCB3aW5kb3cuaW5uZXJIZWlnaHQgLSB2di5oZWlnaHQgLSB2di5vZmZzZXRUb3ApO1xuICAgICAgaWYgKGtoID4gNTApIGFwcGx5TGF5b3V0KGtoKTtcbiAgICAgIGVsc2UgcmVzZXRMYXlvdXQoKTtcbiAgICB9O1xuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWJvYXJkV2lsbFNob3cnLCBvbkNhcGFjaXRvclNob3cpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdrZXlib2FyZERpZFNob3cnLCAgb25DYXBhY2l0b3JTaG93KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigna2V5Ym9hcmRXaWxsSGlkZScsIG9uQ2FwYWNpdG9ySGlkZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWJvYXJkRGlkSGlkZScsICBvbkNhcGFjaXRvckhpZGUpO1xuICAgIHdpbmRvdy52aXN1YWxWaWV3cG9ydD8uYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgb25WaWV3cG9ydCk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIG9uVmlld3BvcnQpO1xuXG4gICAgdGhpcy5rZXlib2FyZENsZWFudXAgPSAoKSA9PiB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5Ym9hcmRXaWxsU2hvdycsIG9uQ2FwYWNpdG9yU2hvdyk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5Ym9hcmREaWRTaG93JywgIG9uQ2FwYWNpdG9yU2hvdyk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5Ym9hcmRXaWxsSGlkZScsIG9uQ2FwYWNpdG9ySGlkZSk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5Ym9hcmREaWRIaWRlJywgIG9uQ2FwYWNpdG9ySGlkZSk7XG4gICAgICB3aW5kb3cudmlzdWFsVmlld3BvcnQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIG9uVmlld3BvcnQpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIG9uVmlld3BvcnQpO1xuICAgICAgcmVzZXRMYXlvdXQoKTtcbiAgICB9O1xuXG4gICAgLy8gVGl0bGVcbiAgICBjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnRWRpdCB0YXNrJyB9KTtcblxuICAgIC8vIFRleHRhcmVhOiBmaXJzdCBsaW5lID0gdGFzayB0ZXh0LCBibGFuayBsaW5lLCB0aGVuIG5vdGVzXG4gICAgY29uc3QgaW5pdGlhbFZhbHVlID1cbiAgICAgIHRoaXMudGFzay5ub3Rlcy5sZW5ndGggPiAwXG4gICAgICAgID8gW3RoaXMudGFzay50ZXh0LCAnJywgLi4udGhpcy50YXNrLm5vdGVzXS5qb2luKCdcXG4nKVxuICAgICAgICA6IHRoaXMudGFzay50ZXh0O1xuICAgIHRoaXMudGV4dGFyZWEgPSBjb250ZW50RWwuY3JlYXRlRWwoJ3RleHRhcmVhJywge1xuICAgICAgY2xzOiAneWFvdHAtZWRpdG9yLXRleHRhcmVhJyxcbiAgICAgIGF0dHI6IHsgcm93czogJzgnLCBwbGFjZWhvbGRlcjogJ1Rhc2sgdGl0bGVcXG5cXG5Ob3Rlc1x1MjAyNicgfSxcbiAgICB9KTtcbiAgICB0aGlzLnRleHRhcmVhLnZhbHVlID0gaW5pdGlhbFZhbHVlO1xuICAgIC8vIFRpbWVvdXQtYmFzZWQgZmFsbGJhY2s6IGlmIG5vbmUgb2YgdGhlIGV2ZW50cyBhYm92ZSBmaXJlZCB5ZXQsIHJlYWRcbiAgICAvLyB0aGUgdmlld3BvcnQgYWZ0ZXIgdGhlIGtleWJvYXJkIGFuaW1hdGlvbiBjb21wbGV0ZXMgKH41MDAgbXMgb24gbW9zdFxuICAgIC8vIGRldmljZXMpLiAgYmx1ciByZXNldHMgaW4gY2FzZSB0aGUga2V5Ym9hcmQgaGFzIGNsb3NlZC5cbiAgICB0aGlzLnRleHRhcmVhLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgKCkgPT4gc2V0VGltZW91dChvblZpZXdwb3J0LCA1MDApKTtcbiAgICB0aGlzLnRleHRhcmVhLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCAgKCkgPT4gc2V0VGltZW91dChyZXNldExheW91dCwgMTAwKSk7XG4gICAgLy8gQXV0by1mb2N1c1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy50ZXh0YXJlYT8uZm9jdXMoKSwgNTApO1xuXG4gICAgLy8gRmlsZSBzZWxlY3RvciByb3dcbiAgICBjb25zdCBmaWxlUm93ID0gY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogJ3lhb3RwLWVkaXRvci1maWxlLXJvdycgfSk7XG4gICAgZmlsZVJvdy5jcmVhdGVFbCgnc3BhbicsIHsgdGV4dDogJ0ZpbGU6ICcsIGNsczogJ3lhb3RwLWVkaXRvci1maWxlLWxhYmVsLXByZWZpeCcgfSk7XG4gICAgdGhpcy5maWxlTGFiZWwgPSBmaWxlUm93LmNyZWF0ZUVsKCdzcGFuJywge1xuICAgICAgdGV4dDogdGhpcy5jdXJyZW50RmlsZS5iYXNlbmFtZSxcbiAgICAgIGNsczogJ3lhb3RwLWVkaXRvci1maWxlLW5hbWUnLFxuICAgIH0pO1xuICAgIGNvbnN0IGNoYW5nZUJ0biA9IGZpbGVSb3cuY3JlYXRlRWwoJ2J1dHRvbicsIHtcbiAgICAgIHRleHQ6ICdDaGFuZ2VcdTIwMjYnLFxuICAgICAgY2xzOiAneWFvdHAtZWRpdG9yLWZpbGUtYnRuJyxcbiAgICB9KTtcbiAgICBjaGFuZ2VCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICBjb25zdCBwaWNrZXIgPSBuZXcgVGFza0ZpbGVQaWNrZXIoXG4gICAgICAgIHRoaXMuYXBwLFxuICAgICAgICB0aGlzLnRhc2tGaWxlcyxcbiAgICAgICAgKGZpbGUpID0+IHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkRmlsZSA9IGZpbGU7XG4gICAgICAgICAgaWYgKHRoaXMuZmlsZUxhYmVsKSB7XG4gICAgICAgICAgICB0aGlzLmZpbGVMYWJlbC5zZXRUZXh0KGZpbGUuYmFzZW5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICAgIHBpY2tlci5vcGVuKCk7XG4gICAgfSk7XG5cbiAgICAvLyBCdXR0b25zXG4gICAgY29uc3QgYnRuUm93ID0gY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogJ3lhb3RwLWVkaXRvci1idG4tcm93JyB9KTtcblxuICAgIGNvbnN0IGRlbGV0ZUJ0biA9IGJ0blJvdy5jcmVhdGVFbCgnYnV0dG9uJywge1xuICAgICAgdGV4dDogJ0RlbGV0ZScsXG4gICAgICBjbHM6ICd5YW90cC1lZGl0b3ItZGVsZXRlLWJ0bicsXG4gICAgfSk7XG4gICAgZGVsZXRlQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgbmV3IENvbmZpcm1Nb2RhbCh0aGlzLmFwcCwgJ0RlbGV0ZSB0aGlzIHRhc2s/IFRoaXMgY2Fubm90IGJlIHVuZG9uZS4nLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgdGhpcy5vbkRlbGV0ZSgpO1xuICAgICAgfSkub3BlbigpO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc2F2ZUJ0biA9IGJ0blJvdy5jcmVhdGVFbCgnYnV0dG9uJywge1xuICAgICAgdGV4dDogJ1NhdmUnLFxuICAgICAgY2xzOiAnbW9kLWN0YSB5YW90cC1lZGl0b3Itc2F2ZS1idG4nLFxuICAgIH0pO1xuICAgIHNhdmVCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0aGlzLnNhdmUoKSk7XG5cbiAgICBjb25zdCBjYW5jZWxCdG4gPSBidG5Sb3cuY3JlYXRlRWwoJ2J1dHRvbicsIHsgdGV4dDogJ0NhbmNlbCcgfSk7XG4gICAgY2FuY2VsQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gdGhpcy5jbG9zZSgpKTtcbiAgfVxuXG4gIG9uQ2xvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5rZXlib2FyZENsZWFudXA/LigpO1xuICAgIHRoaXMua2V5Ym9hcmRDbGVhbnVwID0gbnVsbDtcbiAgICB0aGlzLmNvbnRlbnRFbC5lbXB0eSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBzYXZlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy50ZXh0YXJlYSkgcmV0dXJuO1xuICAgIGNvbnN0IGxpbmVzID0gdGhpcy50ZXh0YXJlYS52YWx1ZS5zcGxpdCgnXFxuJyk7XG4gICAgY29uc3QgdGV4dCA9IGxpbmVzWzBdID8/ICcnO1xuICAgIGNvbnN0IG5vdGVzID0gbGluZXMuc2xpY2UoMSk7XG4gICAgLy8gVHJpbSBsZWFkaW5nIGJsYW5rIGxpbmVzIGZyb20gbm90ZXMgKHVzZXIgbWF5IGhhdmUgcmVtb3ZlZCBvciBhZGRlZCB0aGUgYmxhbmsgc2VwYXJhdG9yKVxuICAgIHdoaWxlIChub3Rlcy5sZW5ndGggPiAwICYmIG5vdGVzWzBdLnRyaW0oKSA9PT0gJycpIG5vdGVzLnNoaWZ0KCk7XG4gICAgdGhpcy5vblNhdmUoe1xuICAgICAgdGV4dCxcbiAgICAgIG5vdGVzLFxuICAgICAgdGFyZ2V0RmlsZTogdGhpcy5zZWxlY3RlZEZpbGUsXG4gICAgfSk7XG4gICAgdGhpcy5jbG9zZSgpO1xuICB9XG59XG5cbmNsYXNzIENvbmZpcm1Nb2RhbCBleHRlbmRzIE1vZGFsIHtcbiAgcHJpdmF0ZSBtZXNzYWdlOiBzdHJpbmc7XG4gIHByaXZhdGUgb25Db25maXJtOiAoKSA9PiB2b2lkO1xuXG4gIGNvbnN0cnVjdG9yKGFwcDogQXBwLCBtZXNzYWdlOiBzdHJpbmcsIG9uQ29uZmlybTogKCkgPT4gdm9pZCkge1xuICAgIHN1cGVyKGFwcCk7XG4gICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB0aGlzLm9uQ29uZmlybSA9IG9uQ29uZmlybTtcbiAgfVxuXG4gIG9uT3BlbigpOiB2b2lkIHtcbiAgICBjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcbiAgICBjb250ZW50RWwuY3JlYXRlRWwoJ3AnLCB7IHRleHQ6IHRoaXMubWVzc2FnZSB9KTtcbiAgICBjb25zdCByb3cgPSBjb250ZW50RWwuY3JlYXRlRGl2KHsgY2xzOiAneWFvdHAtZWRpdG9yLWJ0bi1yb3cnIH0pO1xuICAgIGNvbnN0IGNvbmZpcm1CdG4gPSByb3cuY3JlYXRlRWwoJ2J1dHRvbicsIHtcbiAgICAgIHRleHQ6ICdEZWxldGUnLFxuICAgICAgY2xzOiAnbW9kLXdhcm5pbmcgeWFvdHAtZWRpdG9yLWRlbGV0ZS1idG4nLFxuICAgIH0pO1xuICAgIGNvbmZpcm1CdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICB0aGlzLm9uQ29uZmlybSgpO1xuICAgICAgdGhpcy5jbG9zZSgpO1xuICAgIH0pO1xuICAgIGNvbnN0IGNhbmNlbEJ0biA9IHJvdy5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnQ2FuY2VsJyB9KTtcbiAgICBjYW5jZWxCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0aGlzLmNsb3NlKCkpO1xuICB9XG5cbiAgb25DbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRlbnRFbC5lbXB0eSgpO1xuICB9XG59XG5cbmNsYXNzIFRhc2tGaWxlUGlja2VyIGV4dGVuZHMgRnV6enlTdWdnZXN0TW9kYWw8VEZpbGU+IHtcbiAgcHJpdmF0ZSBmaWxlczogVEZpbGVbXTtcbiAgcHJpdmF0ZSBvblNlbGVjdDogKGZpbGU6IFRGaWxlKSA9PiB2b2lkO1xuXG4gIGNvbnN0cnVjdG9yKGFwcDogQXBwLCBmaWxlczogVEZpbGVbXSwgb25TZWxlY3Q6IChmaWxlOiBURmlsZSkgPT4gdm9pZCkge1xuICAgIHN1cGVyKGFwcCk7XG4gICAgdGhpcy5maWxlcyA9IGZpbGVzO1xuICAgIHRoaXMub25TZWxlY3QgPSBvblNlbGVjdDtcbiAgICB0aGlzLnNldFBsYWNlaG9sZGVyKCdTZWxlY3QgYSB0YXNrIGZpbGVcdTIwMjYnKTtcbiAgfVxuXG4gIGdldEl0ZW1zKCk6IFRGaWxlW10ge1xuICAgIHJldHVybiB0aGlzLmZpbGVzO1xuICB9XG5cbiAgZ2V0SXRlbVRleHQoZmlsZTogVEZpbGUpOiBzdHJpbmcge1xuICAgIHJldHVybiBmaWxlLnBhdGg7XG4gIH1cblxuICBvbkNob29zZUl0ZW0oZmlsZTogVEZpbGUpOiB2b2lkIHtcbiAgICB0aGlzLm9uU2VsZWN0KGZpbGUpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgV29ya3NwYWNlTGVhZiB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB7IFZJRVdfVFlQRSB9IGZyb20gJy4vY29uc3RhbnRzJztcblxudHlwZSBTZXRWaWV3U3RhdGUgPSBXb3Jrc3BhY2VMZWFmWydzZXRWaWV3U3RhdGUnXTtcblxubGV0IG9yaWdpbmFsU2V0Vmlld1N0YXRlOiBTZXRWaWV3U3RhdGUgfCBudWxsID0gbnVsbDtcblxuLyoqXG4gKiBMZWF2ZXMgdGhhdCBoYXZlIGJlZW4gZ3JhbnRlZCBhIG9uZS1zaG90IGJ5cGFzcyBvZiB0aGUgaW50ZXJjZXB0LlxuICogVXNlZCB0byBhbGxvdyB0aGUgdGFzayB2aWV3J3MgXCJTb3VyY2UgbW9kZVwiIGJ1dHRvbiB0byBzd2l0Y2ggdG8gdGhlXG4gKiBtYXJrZG93biBlZGl0b3Igd2l0aG91dCBiZWluZyByZWRpcmVjdGVkIGJhY2suXG4gKi9cbmNvbnN0IGJ5cGFzc0xlYXZlcyA9IG5ldyBXZWFrU2V0PFdvcmtzcGFjZUxlYWY+KCk7XG5cbi8qKlxuICogQWxsb3cgdGhlIG5leHQgc2V0Vmlld1N0YXRlIGNhbGwgb24gdGhpcyBsZWFmIHRvIHBhc3MgdGhyb3VnaCB0aGVcbiAqIGludGVyY2VwdCB1bm1vZGlmaWVkLiBDYWxsIHRoaXMgaW1tZWRpYXRlbHkgYmVmb3JlIHNldFZpZXdTdGF0ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFsbG93TWFya2Rvd25PbmNlKGxlYWY6IFdvcmtzcGFjZUxlYWYpOiB2b2lkIHtcbiAgYnlwYXNzTGVhdmVzLmFkZChsZWFmKTtcbn1cblxuLyoqXG4gKiBNb25rZXktcGF0Y2ggV29ya3NwYWNlTGVhZi5wcm90b3R5cGUuc2V0Vmlld1N0YXRlIHNvIHRoYXQgb3BlbmluZyBhXG4gKiB0YXNrIGZpbGUgKGlkZW50aWZpZWQgYnkgdGhlIGdpdmVuIHByZWRpY2F0ZSkgcmVkaXJlY3RzIHRvIG91ciBjdXN0b21cbiAqIHZpZXcgdHlwZSBpbnN0ZWFkIG9mIHRoZSBkZWZhdWx0IG1hcmtkb3duIGVkaXRvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluc3RhbGxGaWxlSW50ZXJjZXB0KGlzVGFza0ZpbGU6IChwYXRoOiBzdHJpbmcpID0+IGJvb2xlYW4pOiB2b2lkIHtcbiAgaWYgKG9yaWdpbmFsU2V0Vmlld1N0YXRlKSByZXR1cm47IC8vIGFscmVhZHkgaW5zdGFsbGVkXG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgY29uc3QgcHJvdG8gPSAoV29ya3NwYWNlTGVhZiBhcyBhbnkpLnByb3RvdHlwZTtcbiAgb3JpZ2luYWxTZXRWaWV3U3RhdGUgPSBwcm90by5zZXRWaWV3U3RhdGUgYXMgU2V0Vmlld1N0YXRlO1xuXG4gIHByb3RvLnNldFZpZXdTdGF0ZSA9IGZ1bmN0aW9uIChcbiAgICB0aGlzOiBXb3Jrc3BhY2VMZWFmLFxuICAgIHN0YXRlOiBQYXJhbWV0ZXJzPFNldFZpZXdTdGF0ZT5bMF0sXG4gICAgZVN0YXRlPzogUGFyYW1ldGVyczxTZXRWaWV3U3RhdGU+WzFdXG4gICkge1xuICAgIGlmIChcbiAgICAgIHN0YXRlPy50eXBlID09PSAnbWFya2Rvd24nICYmXG4gICAgICBzdGF0ZT8uc3RhdGU/LmZpbGUgJiZcbiAgICAgIGlzVGFza0ZpbGUoc3RhdGUuc3RhdGUuZmlsZSBhcyBzdHJpbmcpICYmXG4gICAgICAvLyBEb24ndCBpbnRlcmNlcHQgbW9kZS1vbmx5IGNoYW5nZXMgd2l0aGluIGFuIGFscmVhZHktb3BlbiBtYXJrZG93biB2aWV3XG4gICAgICAvLyBmb3IgdGhlIHNhbWUgZmlsZSAoZS5nLiBzd2l0Y2hpbmcgdG8gU291cmNlIG1vZGUgdmlhIHRoZSBjb250ZXh0IG1lbnUpLlxuICAgICAgLy8gV2UgRE8gc3RpbGwgaW50ZXJjZXB0IGlmIHRoZSBsZWFmIGlzIG1hcmtkb3duIGJ1dCBzaG93aW5nIGEgZGlmZmVyZW50XG4gICAgICAvLyBmaWxlLCBvciBpZiB0aGUgdmlldyBpcyBub3QgeWV0IG1hcmtkb3duIGF0IGFsbC5cbiAgICAgICEoXG4gICAgICAgIHRoaXMudmlldz8uZ2V0Vmlld1R5cGUoKSA9PT0gJ21hcmtkb3duJyAmJlxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAodGhpcy52aWV3IGFzIGFueSk/LmZpbGU/LnBhdGggPT09IChzdGF0ZS5zdGF0ZT8uZmlsZSBhcyBzdHJpbmcpXG4gICAgICApXG4gICAgKSB7XG4gICAgICBpZiAoYnlwYXNzTGVhdmVzLmhhcyh0aGlzKSkge1xuICAgICAgICBieXBhc3NMZWF2ZXMuZGVsZXRlKHRoaXMpO1xuICAgICAgICByZXR1cm4gb3JpZ2luYWxTZXRWaWV3U3RhdGUhLmNhbGwodGhpcywgc3RhdGUsIGVTdGF0ZSk7XG4gICAgICB9XG4gICAgICBjb25zdCBuZXdTdGF0ZSA9IHsgLi4uc3RhdGUsIHR5cGU6IFZJRVdfVFlQRSB9O1xuICAgICAgcmV0dXJuIG9yaWdpbmFsU2V0Vmlld1N0YXRlIS5jYWxsKHRoaXMsIG5ld1N0YXRlLCBlU3RhdGUpO1xuICAgIH1cbiAgICByZXR1cm4gb3JpZ2luYWxTZXRWaWV3U3RhdGUhLmNhbGwodGhpcywgc3RhdGUsIGVTdGF0ZSk7XG4gIH07XG59XG5cbi8qKlxuICogUmVzdG9yZSB0aGUgb3JpZ2luYWwgc2V0Vmlld1N0YXRlLiBDYWxsIGZyb20gUGx1Z2luLm9udW5sb2FkKCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bmluc3RhbGxGaWxlSW50ZXJjZXB0KCk6IHZvaWQge1xuICBpZiAoIW9yaWdpbmFsU2V0Vmlld1N0YXRlKSByZXR1cm47XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIChXb3Jrc3BhY2VMZWFmIGFzIGFueSkucHJvdG90eXBlLnNldFZpZXdTdGF0ZSA9IG9yaWdpbmFsU2V0Vmlld1N0YXRlO1xuICBvcmlnaW5hbFNldFZpZXdTdGF0ZSA9IG51bGw7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFFQSxXQUFPLGVBQWUsU0FBUyxjQUFjLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFFNUQsUUFBSSxXQUFXLFFBQVEsVUFBVTtBQUVqQyxRQUFNQSw2QkFBNEI7QUFDbEMsUUFBTSw2QkFBNkI7QUFDbkMsUUFBTSw4QkFBOEI7QUFDcEMsUUFBTSxnQ0FBZ0M7QUFDdEMsUUFBTSw2QkFBNkI7QUFFbkMsYUFBUywrQkFBK0IsYUFBYTtBQVpyRDtBQWNJLFlBQU0sZ0JBQWdCLE9BQU8sSUFBSSxRQUFRLFVBQVUsZ0JBQWdCO0FBQ25FLGFBQU8sbUJBQWlCLHlCQUFjLGFBQWQsbUJBQXlCLGlCQUF6QixtQkFBdUM7QUFBQSxJQUNuRTtBQUtBLGFBQVMsdUJBQXVCO0FBckJoQztBQXNCSSxVQUFJO0FBRUEsY0FBTSxF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ImZvcm1hdCIsICJmb2xkZXIiLCAidGVtcGxhdGUiLCAiaW1wb3J0X29ic2lkaWFuIiwgImltcG9ydF9vYnNpZGlhbiIsICJpbXBvcnRfb2JzaWRpYW4iLCAiciIsICJvIiwgImluZGV4IiwgImdob3N0RWwiLCAib3B0aW9uIiwgImRlZmF1bHRzIiwgInJvb3RFbCIsICJjbG9uZUVsIiwgIm9sZEluZGV4IiwgIm5ld0luZGV4IiwgIm9sZERyYWdnYWJsZUluZGV4IiwgIm5ld0RyYWdnYWJsZUluZGV4IiwgInB1dFNvcnRhYmxlIiwgInBsdWdpbkV2ZW50IiwgIl9kZXRlY3REaXJlY3Rpb24iLCAiX2RyYWdFbEluUm93Q29sdW1uIiwgIl9kZXRlY3ROZWFyZXN0RW1wdHlTb3J0YWJsZSIsICJfcHJlcGFyZUdyb3VwIiwgImRyYWdFbCIsICJfaGlkZUdob3N0Rm9yVGFyZ2V0IiwgIl91bmhpZGVHaG9zdEZvclRhcmdldCIsICJuZWFyZXN0RW1wdHlJbnNlcnREZXRlY3RFdmVudCIsICJfY2hlY2tPdXRzaWRlVGFyZ2V0RWwiLCAiZHJhZ1N0YXJ0Rm4iLCAidGFyZ2V0IiwgImFmdGVyIiwgImVsIiwgInBsdWdpbnMiLCAiZHJvcCIsICJhdXRvU2Nyb2xsIiwgIm9uU3BpbGwiLCAiaW5kZXgiLCAib2xkSW5kZXgiLCAibmV3SW5kZXgiLCAiaW1wb3J0X29ic2lkaWFuIiwgIl9hIiwgImltcG9ydF9vYnNpZGlhbiIsICJpbmRleCIsICJvbGRJbmRleCIsICJuZXdJbmRleCIsICJtb3ZlZCJdCn0K