3614 lines
493 KiB
JavaScript
3614 lines
493 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 = "⋮";
|
|
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.keyboardHandler = null;
|
|
this.keyboardResetHandler = 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 adjust = () => {
|
|
const vv = window.visualViewport;
|
|
const availableHeight = vv ? vv.height : window.innerHeight;
|
|
const keyboardHeight = Math.max(0, window.innerHeight - availableHeight);
|
|
if (keyboardHeight > 50) {
|
|
this.containerEl.style.height = `${availableHeight}px`;
|
|
this.containerEl.style.alignItems = "flex-start";
|
|
this.containerEl.style.paddingTop = "8px";
|
|
this.modalEl.style.maxHeight = `${availableHeight - 16}px`;
|
|
} else {
|
|
this.containerEl.style.height = "";
|
|
this.containerEl.style.alignItems = "";
|
|
this.containerEl.style.paddingTop = "";
|
|
this.modalEl.style.maxHeight = "";
|
|
}
|
|
};
|
|
this.keyboardHandler = adjust;
|
|
this.keyboardResetHandler = () => {
|
|
this.containerEl.style.height = "";
|
|
this.containerEl.style.alignItems = "";
|
|
this.containerEl.style.paddingTop = "";
|
|
this.modalEl.style.maxHeight = "";
|
|
};
|
|
(_a = window.visualViewport) == null ? void 0 : _a.addEventListener("resize", adjust);
|
|
window.addEventListener("resize", adjust);
|
|
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(adjust, 300));
|
|
this.textarea.addEventListener("blur", () => setTimeout(adjust, 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, _b;
|
|
if (this.keyboardHandler) {
|
|
(_a = window.visualViewport) == null ? void 0 : _a.removeEventListener("resize", this.keyboardHandler);
|
|
window.removeEventListener("resize", this.keyboardHandler);
|
|
this.keyboardHandler = null;
|
|
}
|
|
(_b = this.keyboardResetHandler) == null ? void 0 : _b.call(this);
|
|
this.keyboardResetHandler = 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 = "⋮";
|
|
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+IHtcbiAgICBpZiAoZS5rZXkgPT09ICdFbnRlcicpIHN1Ym1pdCgpO1xuICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScpIGhpZGVJbnB1dCgpO1xuICB9KTtcblxuICByZXR1cm4gYmFyO1xufVxuIiwgImltcG9ydCB7IEFwcCwgRnV6enlTdWdnZXN0TW9kYWwsIE1vZGFsLCBURmlsZSB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB0eXBlIHsgVGFzayB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBUYXNrRWRpdG9yUmVzdWx0IHtcbiAgdGV4dDogc3RyaW5nO1xuICBub3Rlczogc3RyaW5nW107XG4gIC8qKiBJZiBzZXQsIG1vdmUgdGhlIHRhc2sgdG8gdGhpcyBmaWxlLiAqL1xuICB0YXJnZXRGaWxlOiBURmlsZSB8IG51bGw7XG59XG5cbnR5cGUgU2F2ZUNhbGxiYWNrID0gKHJlc3VsdDogVGFza0VkaXRvclJlc3VsdCkgPT4gdm9pZDtcbnR5cGUgRGVsZXRlQ2FsbGJhY2sgPSAoKSA9PiB2b2lkO1xuXG4vKipcbiAqIE1vZGFsIGZvciBlZGl0aW5nIGEgdGFzaydzIHRleHQgYW5kIG5vdGVzIHRvZ2V0aGVyLCBhbmQgb3B0aW9uYWxseVxuICogbW92aW5nIGl0IHRvIGEgZGlmZmVyZW50IHRhc2sgZmlsZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFRhc2tFZGl0b3JNb2RhbCBleHRlbmRzIE1vZGFsIHtcbiAgcHJpdmF0ZSB0YXNrOiBUYXNrO1xuICBwcml2YXRlIHRhc2tGaWxlczogVEZpbGVbXTtcbiAgcHJpdmF0ZSBjdXJyZW50RmlsZTogVEZpbGU7XG4gIHByaXZhdGUgb25TYXZlOiBTYXZlQ2FsbGJhY2s7XG4gIHByaXZhdGUgb25EZWxldGU6IERlbGV0ZUNhbGxiYWNrO1xuICBwcml2YXRlIHRleHRhcmVhOiBIVE1MVGV4dEFyZWFFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc2VsZWN0ZWRGaWxlOiBURmlsZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGZpbGVMYWJlbDogSFRNTFNwYW5FbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUga2V5Ym9hcmRIYW5kbGVyOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBrZXlib2FyZFJlc2V0SGFuZGxlcjogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgYXBwOiBBcHAsXG4gICAgdGFzazogVGFzayxcbiAgICB0YXNrRmlsZXM6IFRGaWxlW10sXG4gICAgY3VycmVudEZpbGU6IFRGaWxlLFxuICAgIG9uU2F2ZTogU2F2ZUNhbGxiYWNrLFxuICAgIG9uRGVsZXRlOiBEZWxldGVDYWxsYmFja1xuICApIHtcbiAgICBzdXBlcihhcHApO1xuICAgIHRoaXMudGFzayA9IHRhc2s7XG4gICAgdGhpcy50YXNrRmlsZXMgPSB0YXNrRmlsZXM7XG4gICAgdGhpcy5jdXJyZW50RmlsZSA9IGN1cnJlbnRGaWxlO1xuICAgIHRoaXMub25TYXZlID0gb25TYXZlO1xuICAgIHRoaXMub25EZWxldGUgPSBvbkRlbGV0ZTtcbiAgfVxuXG4gIG9uT3BlbigpOiB2b2lkIHtcbiAgICBjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcbiAgICBjb250ZW50RWwuYWRkQ2xhc3MoJ3lhb3RwLWVkaXRvci1tb2RhbCcpO1xuXG4gICAgLy8gT24gQW5kcm9pZCB0aGUgb24tc2NyZWVuIGtleWJvYXJkIGRvZXNuJ3QgcmVzaXplIHRoZSBsYXlvdXQgdmlld3BvcnQsIHNvXG4gICAgLy8gdGhlIGZpeGVkLXBvc2l0aW9uIG1vZGFsIGNvbnRhaW5lciBzdGF5cyBmdWxsLWhlaWdodCBhbmQgdGhlIG1vZGFsIGVuZHNcbiAgICAvLyB1cCBjZW50ZXJlZCBiZWhpbmQgdGhlIGtleWJvYXJkLiBXZSBmaXggdGhpcyBieTpcbiAgICAvLyAgIDEuIE9uIHRleHRhcmVhIGZvY3VzICgrIGEgc2hvcnQgZGVsYXkgZm9yIHRoZSBrZXlib2FyZCBhbmltYXRpb24pLFxuICAgIC8vICAgICAgcmVhZCB0aGUgdmlzdWFsIHZpZXdwb3J0IGhlaWdodCBhbmQgc2hyaW5rIHRoZSBjb250YWluZXIgdG8gdGhhdFxuICAgIC8vICAgICAgc2l6ZSwgdGhlbiBhbGlnbiB0aGUgbW9kYWwgdG8gdGhlIHRvcCBvZiB0aGUgY29udGFpbmVyLlxuICAgIC8vICAgMi4gT24gYmx1ciwgcmVzZXQgZXZlcnl0aGluZy5cbiAgICAvLyBXZSBhbHNvIGxpc3RlbiB0byB2aXN1YWxWaWV3cG9ydCBhbmQgd2luZG93IHJlc2l6ZSBhcyBzdXBwbGVtZW50YXJ5XG4gICAgLy8gdHJpZ2dlcnMgaW4gY2FzZSB0aGUga2V5Ym9hcmQgYXBwZWFycy9kaXNhcHBlYXJzIHdpdGhvdXQgYSBmb2N1cyBjaGFuZ2UuXG4gICAgY29uc3QgYWRqdXN0ID0gKCkgPT4ge1xuICAgICAgY29uc3QgdnYgPSB3aW5kb3cudmlzdWFsVmlld3BvcnQ7XG4gICAgICBjb25zdCBhdmFpbGFibGVIZWlnaHQgPSB2diA/IHZ2LmhlaWdodCA6IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICAgIGNvbnN0IGtleWJvYXJkSGVpZ2h0ID0gTWF0aC5tYXgoMCwgd2luZG93LmlubmVySGVpZ2h0IC0gYXZhaWxhYmxlSGVpZ2h0KTtcbiAgICAgIGlmIChrZXlib2FyZEhlaWdodCA+IDUwKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuc3R5bGUuaGVpZ2h0ID0gYCR7YXZhaWxhYmxlSGVpZ2h0fXB4YDtcbiAgICAgICAgdGhpcy5jb250YWluZXJFbC5zdHlsZS5hbGlnbkl0ZW1zID0gJ2ZsZXgtc3RhcnQnO1xuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLnN0eWxlLnBhZGRpbmdUb3AgPSAnOHB4JztcbiAgICAgICAgdGhpcy5tb2RhbEVsLnN0eWxlLm1heEhlaWdodCA9IGAke2F2YWlsYWJsZUhlaWdodCAtIDE2fXB4YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuc3R5bGUuaGVpZ2h0ID0gJyc7XG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuc3R5bGUuYWxpZ25JdGVtcyA9ICcnO1xuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLnN0eWxlLnBhZGRpbmdUb3AgPSAnJztcbiAgICAgICAgdGhpcy5tb2RhbEVsLnN0eWxlLm1heEhlaWdodCA9ICcnO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB0aGlzLmtleWJvYXJkSGFuZGxlciA9IGFkanVzdDtcbiAgICB0aGlzLmtleWJvYXJkUmVzZXRIYW5kbGVyID0gKCkgPT4ge1xuICAgICAgdGhpcy5jb250YWluZXJFbC5zdHlsZS5oZWlnaHQgPSAnJztcbiAgICAgIHRoaXMuY29udGFpbmVyRWwuc3R5bGUuYWxpZ25JdGVtcyA9ICcnO1xuICAgICAgdGhpcy5jb250YWluZXJFbC5zdHlsZS5wYWRkaW5nVG9wID0gJyc7XG4gICAgICB0aGlzLm1vZGFsRWwuc3R5bGUubWF4SGVpZ2h0ID0gJyc7XG4gICAgfTtcblxuICAgIHdpbmRvdy52aXN1YWxWaWV3cG9ydD8uYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgYWRqdXN0KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgYWRqdXN0KTtcblxuICAgIC8vIFRpdGxlXG4gICAgY29udGVudEVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ0VkaXQgdGFzaycgfSk7XG5cbiAgICAvLyBUZXh0YXJlYTogZmlyc3QgbGluZSA9IHRhc2sgdGV4dCwgYmxhbmsgbGluZSwgdGhlbiBub3Rlc1xuICAgIGNvbnN0IGluaXRpYWxWYWx1ZSA9XG4gICAgICB0aGlzLnRhc2subm90ZXMubGVuZ3RoID4gMFxuICAgICAgICA/IFt0aGlzLnRhc2sudGV4dCwgJycsIC4uLnRoaXMudGFzay5ub3Rlc10uam9pbignXFxuJylcbiAgICAgICAgOiB0aGlzLnRhc2sudGV4dDtcbiAgICB0aGlzLnRleHRhcmVhID0gY29udGVudEVsLmNyZWF0ZUVsKCd0ZXh0YXJlYScsIHtcbiAgICAgIGNsczogJ3lhb3RwLWVkaXRvci10ZXh0YXJlYScsXG4gICAgICBhdHRyOiB7IHJvd3M6ICc4JywgcGxhY2Vob2xkZXI6ICdUYXNrIHRpdGxlXFxuXFxuTm90ZXNcdTIwMjYnIH0sXG4gICAgfSk7XG4gICAgdGhpcy50ZXh0YXJlYS52YWx1ZSA9IGluaXRpYWxWYWx1ZTtcbiAgICB0aGlzLnRleHRhcmVhLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgKCkgPT4gc2V0VGltZW91dChhZGp1c3QsIDMwMCkpO1xuICAgIHRoaXMudGV4dGFyZWEuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsICAoKSA9PiBzZXRUaW1lb3V0KGFkanVzdCwgMTAwKSk7XG4gICAgLy8gQXV0by1mb2N1c1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy50ZXh0YXJlYT8uZm9jdXMoKSwgNTApO1xuXG4gICAgLy8gRmlsZSBzZWxlY3RvciByb3dcbiAgICBjb25zdCBmaWxlUm93ID0gY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogJ3lhb3RwLWVkaXRvci1maWxlLXJvdycgfSk7XG4gICAgZmlsZVJvdy5jcmVhdGVFbCgnc3BhbicsIHsgdGV4dDogJ0ZpbGU6ICcsIGNsczogJ3lhb3RwLWVkaXRvci1maWxlLWxhYmVsLXByZWZpeCcgfSk7XG4gICAgdGhpcy5maWxlTGFiZWwgPSBmaWxlUm93LmNyZWF0ZUVsKCdzcGFuJywge1xuICAgICAgdGV4dDogdGhpcy5jdXJyZW50RmlsZS5iYXNlbmFtZSxcbiAgICAgIGNsczogJ3lhb3RwLWVkaXRvci1maWxlLW5hbWUnLFxuICAgIH0pO1xuICAgIGNvbnN0IGNoYW5nZUJ0biA9IGZpbGVSb3cuY3JlYXRlRWwoJ2J1dHRvbicsIHtcbiAgICAgIHRleHQ6ICdDaGFuZ2VcdTIwMjYnLFxuICAgICAgY2xzOiAneWFvdHAtZWRpdG9yLWZpbGUtYnRuJyxcbiAgICB9KTtcbiAgICBjaGFuZ2VCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICBjb25zdCBwaWNrZXIgPSBuZXcgVGFza0ZpbGVQaWNrZXIoXG4gICAgICAgIHRoaXMuYXBwLFxuICAgICAgICB0aGlzLnRhc2tGaWxlcyxcbiAgICAgICAgKGZpbGUpID0+IHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkRmlsZSA9IGZpbGU7XG4gICAgICAgICAgaWYgKHRoaXMuZmlsZUxhYmVsKSB7XG4gICAgICAgICAgICB0aGlzLmZpbGVMYWJlbC5zZXRUZXh0KGZpbGUuYmFzZW5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICAgIHBpY2tlci5vcGVuKCk7XG4gICAgfSk7XG5cbiAgICAvLyBCdXR0b25zXG4gICAgY29uc3QgYnRuUm93ID0gY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogJ3lhb3RwLWVkaXRvci1idG4tcm93JyB9KTtcblxuICAgIGNvbnN0IGRlbGV0ZUJ0biA9IGJ0blJvdy5jcmVhdGVFbCgnYnV0dG9uJywge1xuICAgICAgdGV4dDogJ0RlbGV0ZScsXG4gICAgICBjbHM6ICd5YW90cC1lZGl0b3ItZGVsZXRlLWJ0bicsXG4gICAgfSk7XG4gICAgZGVsZXRlQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgbmV3IENvbmZpcm1Nb2RhbCh0aGlzLmFwcCwgJ0RlbGV0ZSB0aGlzIHRhc2s/IFRoaXMgY2Fubm90IGJlIHVuZG9uZS4nLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgdGhpcy5vbkRlbGV0ZSgpO1xuICAgICAgfSkub3BlbigpO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc2F2ZUJ0biA9IGJ0blJvdy5jcmVhdGVFbCgnYnV0dG9uJywge1xuICAgICAgdGV4dDogJ1NhdmUnLFxuICAgICAgY2xzOiAnbW9kLWN0YSB5YW90cC1lZGl0b3Itc2F2ZS1idG4nLFxuICAgIH0pO1xuICAgIHNhdmVCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0aGlzLnNhdmUoKSk7XG5cbiAgICBjb25zdCBjYW5jZWxCdG4gPSBidG5Sb3cuY3JlYXRlRWwoJ2J1dHRvbicsIHsgdGV4dDogJ0NhbmNlbCcgfSk7XG4gICAgY2FuY2VsQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gdGhpcy5jbG9zZSgpKTtcbiAgfVxuXG4gIG9uQ2xvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMua2V5Ym9hcmRIYW5kbGVyKSB7XG4gICAgICB3aW5kb3cudmlzdWFsVmlld3BvcnQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMua2V5Ym9hcmRIYW5kbGVyKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLmtleWJvYXJkSGFuZGxlcik7XG4gICAgICB0aGlzLmtleWJvYXJkSGFuZGxlciA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMua2V5Ym9hcmRSZXNldEhhbmRsZXI/LigpO1xuICAgIHRoaXMua2V5Ym9hcmRSZXNldEhhbmRsZXIgPSBudWxsO1xuICAgIHRoaXMuY29udGVudEVsLmVtcHR5KCk7XG4gIH1cblxuICBwcml2YXRlIHNhdmUoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnRleHRhcmVhKSByZXR1cm47XG4gICAgY29uc3QgbGluZXMgPSB0aGlzLnRleHRhcmVhLnZhbHVlLnNwbGl0KCdcXG4nKTtcbiAgICBjb25zdCB0ZXh0ID0gbGluZXNbMF0gPz8gJyc7XG4gICAgY29uc3Qgbm90ZXMgPSBsaW5lcy5zbGljZSgxKTtcbiAgICAvLyBUcmltIGxlYWRpbmcgYmxhbmsgbGluZXMgZnJvbSBub3RlcyAodXNlciBtYXkgaGF2ZSByZW1vdmVkIG9yIGFkZGVkIHRoZSBibGFuayBzZXBhcmF0b3IpXG4gICAgd2hpbGUgKG5vdGVzLmxlbmd0aCA+IDAgJiYgbm90ZXNbMF0udHJpbSgpID09PSAnJykgbm90ZXMuc2hpZnQoKTtcbiAgICB0aGlzLm9uU2F2ZSh7XG4gICAgICB0ZXh0LFxuICAgICAgbm90ZXMsXG4gICAgICB0YXJnZXRGaWxlOiB0aGlzLnNlbGVjdGVkRmlsZSxcbiAgICB9KTtcbiAgICB0aGlzLmNsb3NlKCk7XG4gIH1cbn1cblxuY2xhc3MgQ29uZmlybU1vZGFsIGV4dGVuZHMgTW9kYWwge1xuICBwcml2YXRlIG1lc3NhZ2U6IHN0cmluZztcbiAgcHJpdmF0ZSBvbkNvbmZpcm06ICgpID0+IHZvaWQ7XG5cbiAgY29uc3RydWN0b3IoYXBwOiBBcHAsIG1lc3NhZ2U6IHN0cmluZywgb25Db25maXJtOiAoKSA9PiB2b2lkKSB7XG4gICAgc3VwZXIoYXBwKTtcbiAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIHRoaXMub25Db25maXJtID0gb25Db25maXJtO1xuICB9XG5cbiAgb25PcGVuKCk6IHZvaWQge1xuICAgIGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xuICAgIGNvbnRlbnRFbC5jcmVhdGVFbCgncCcsIHsgdGV4dDogdGhpcy5tZXNzYWdlIH0pO1xuICAgIGNvbnN0IHJvdyA9IGNvbnRlbnRFbC5jcmVhdGVEaXYoeyBjbHM6ICd5YW90cC1lZGl0b3ItYnRuLXJvdycgfSk7XG4gICAgY29uc3QgY29uZmlybUJ0biA9IHJvdy5jcmVhdGVFbCgnYnV0dG9uJywge1xuICAgICAgdGV4dDogJ0RlbGV0ZScsXG4gICAgICBjbHM6ICdtb2Qtd2FybmluZyB5YW90cC1lZGl0b3ItZGVsZXRlLWJ0bicsXG4gICAgfSk7XG4gICAgY29uZmlybUJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgIHRoaXMub25Db25maXJtKCk7XG4gICAgICB0aGlzLmNsb3NlKCk7XG4gICAgfSk7XG4gICAgY29uc3QgY2FuY2VsQnRuID0gcm93LmNyZWF0ZUVsKCdidXR0b24nLCB7IHRleHQ6ICdDYW5jZWwnIH0pO1xuICAgIGNhbmNlbEJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHRoaXMuY2xvc2UoKSk7XG4gIH1cblxuICBvbkNsb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuY29udGVudEVsLmVtcHR5KCk7XG4gIH1cbn1cblxuY2xhc3MgVGFza0ZpbGVQaWNrZXIgZXh0ZW5kcyBGdXp6eVN1Z2dlc3RNb2RhbDxURmlsZT4ge1xuICBwcml2YXRlIGZpbGVzOiBURmlsZVtdO1xuICBwcml2YXRlIG9uU2VsZWN0OiAoZmlsZTogVEZpbGUpID0+IHZvaWQ7XG5cbiAgY29uc3RydWN0b3IoYXBwOiBBcHAsIGZpbGVzOiBURmlsZVtdLCBvblNlbGVjdDogKGZpbGU6IFRGaWxlKSA9PiB2b2lkKSB7XG4gICAgc3VwZXIoYXBwKTtcbiAgICB0aGlzLmZpbGVzID0gZmlsZXM7XG4gICAgdGhpcy5vblNlbGVjdCA9IG9uU2VsZWN0O1xuICAgIHRoaXMuc2V0UGxhY2Vob2xkZXIoJ1NlbGVjdCBhIHRhc2sgZmlsZVx1MjAyNicpO1xuICB9XG5cbiAgZ2V0SXRlbXMoKTogVEZpbGVbXSB7XG4gICAgcmV0dXJuIHRoaXMuZmlsZXM7XG4gIH1cblxuICBnZXRJdGVtVGV4dChmaWxlOiBURmlsZSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGZpbGUucGF0aDtcbiAgfVxuXG4gIG9uQ2hvb3NlSXRlbShmaWxlOiBURmlsZSk6IHZvaWQge1xuICAgIHRoaXMub25TZWxlY3QoZmlsZSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBXb3Jrc3BhY2VMZWFmIH0gZnJvbSAnb2JzaWRpYW4nO1xuaW1wb3J0IHsgVklFV19UWVBFIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuXG50eXBlIFNldFZpZXdTdGF0ZSA9IFdvcmtzcGFjZUxlYWZbJ3NldFZpZXdTdGF0ZSddO1xuXG5sZXQgb3JpZ2luYWxTZXRWaWV3U3RhdGU6IFNldFZpZXdTdGF0ZSB8IG51bGwgPSBudWxsO1xuXG4vKipcbiAqIExlYXZlcyB0aGF0IGhhdmUgYmVlbiBncmFudGVkIGEgb25lLXNob3QgYnlwYXNzIG9mIHRoZSBpbnRlcmNlcHQuXG4gKiBVc2VkIHRvIGFsbG93IHRoZSB0YXNrIHZpZXcncyBcIlNvdXJjZSBtb2RlXCIgYnV0dG9uIHRvIHN3aXRjaCB0byB0aGVcbiAqIG1hcmtkb3duIGVkaXRvciB3aXRob3V0IGJlaW5nIHJlZGlyZWN0ZWQgYmFjay5cbiAqL1xuY29uc3QgYnlwYXNzTGVhdmVzID0gbmV3IFdlYWtTZXQ8V29ya3NwYWNlTGVhZj4oKTtcblxuLyoqXG4gKiBBbGxvdyB0aGUgbmV4dCBzZXRWaWV3U3RhdGUgY2FsbCBvbiB0aGlzIGxlYWYgdG8gcGFzcyB0aHJvdWdoIHRoZVxuICogaW50ZXJjZXB0IHVubW9kaWZpZWQuIENhbGwgdGhpcyBpbW1lZGlhdGVseSBiZWZvcmUgc2V0Vmlld1N0YXRlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWxsb3dNYXJrZG93bk9uY2UobGVhZjogV29ya3NwYWNlTGVhZik6IHZvaWQge1xuICBieXBhc3NMZWF2ZXMuYWRkKGxlYWYpO1xufVxuXG4vKipcbiAqIE1vbmtleS1wYXRjaCBXb3Jrc3BhY2VMZWFmLnByb3RvdHlwZS5zZXRWaWV3U3RhdGUgc28gdGhhdCBvcGVuaW5nIGFcbiAqIHRhc2sgZmlsZSAoaWRlbnRpZmllZCBieSB0aGUgZ2l2ZW4gcHJlZGljYXRlKSByZWRpcmVjdHMgdG8gb3VyIGN1c3RvbVxuICogdmlldyB0eXBlIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgbWFya2Rvd24gZWRpdG9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5zdGFsbEZpbGVJbnRlcmNlcHQoaXNUYXNrRmlsZTogKHBhdGg6IHN0cmluZykgPT4gYm9vbGVhbik6IHZvaWQge1xuICBpZiAob3JpZ2luYWxTZXRWaWV3U3RhdGUpIHJldHVybjsgLy8gYWxyZWFkeSBpbnN0YWxsZWRcblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBjb25zdCBwcm90byA9IChXb3Jrc3BhY2VMZWFmIGFzIGFueSkucHJvdG90eXBlO1xuICBvcmlnaW5hbFNldFZpZXdTdGF0ZSA9IHByb3RvLnNldFZpZXdTdGF0ZSBhcyBTZXRWaWV3U3RhdGU7XG5cbiAgcHJvdG8uc2V0Vmlld1N0YXRlID0gZnVuY3Rpb24gKFxuICAgIHRoaXM6IFdvcmtzcGFjZUxlYWYsXG4gICAgc3RhdGU6IFBhcmFtZXRlcnM8U2V0Vmlld1N0YXRlPlswXSxcbiAgICBlU3RhdGU/OiBQYXJhbWV0ZXJzPFNldFZpZXdTdGF0ZT5bMV1cbiAgKSB7XG4gICAgaWYgKFxuICAgICAgc3RhdGU/LnR5cGUgPT09ICdtYXJrZG93bicgJiZcbiAgICAgIHN0YXRlPy5zdGF0ZT8uZmlsZSAmJlxuICAgICAgaXNUYXNrRmlsZShzdGF0ZS5zdGF0ZS5maWxlIGFzIHN0cmluZykgJiZcbiAgICAgIC8vIERvbid0IGludGVyY2VwdCBtb2RlLW9ubHkgY2hhbmdlcyB3aXRoaW4gYW4gYWxyZWFkeS1vcGVuIG1hcmtkb3duIHZpZXdcbiAgICAgIC8vIGZvciB0aGUgc2FtZSBmaWxlIChlLmcuIHN3aXRjaGluZyB0byBTb3VyY2UgbW9kZSB2aWEgdGhlIGNvbnRleHQgbWVudSkuXG4gICAgICAvLyBXZSBETyBzdGlsbCBpbnRlcmNlcHQgaWYgdGhlIGxlYWYgaXMgbWFya2Rvd24gYnV0IHNob3dpbmcgYSBkaWZmZXJlbnRcbiAgICAgIC8vIGZpbGUsIG9yIGlmIHRoZSB2aWV3IGlzIG5vdCB5ZXQgbWFya2Rvd24gYXQgYWxsLlxuICAgICAgIShcbiAgICAgICAgdGhpcy52aWV3Py5nZXRWaWV3VHlwZSgpID09PSAnbWFya2Rvd24nICYmXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICh0aGlzLnZpZXcgYXMgYW55KT8uZmlsZT8ucGF0aCA9PT0gKHN0YXRlLnN0YXRlPy5maWxlIGFzIHN0cmluZylcbiAgICAgIClcbiAgICApIHtcbiAgICAgIGlmIChieXBhc3NMZWF2ZXMuaGFzKHRoaXMpKSB7XG4gICAgICAgIGJ5cGFzc0xlYXZlcy5kZWxldGUodGhpcyk7XG4gICAgICAgIHJldHVybiBvcmlnaW5hbFNldFZpZXdTdGF0ZSEuY2FsbCh0aGlzLCBzdGF0ZSwgZVN0YXRlKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG5ld1N0YXRlID0geyAuLi5zdGF0ZSwgdHlwZTogVklFV19UWVBFIH07XG4gICAgICByZXR1cm4gb3JpZ2luYWxTZXRWaWV3U3RhdGUhLmNhbGwodGhpcywgbmV3U3RhdGUsIGVTdGF0ZSk7XG4gICAgfVxuICAgIHJldHVybiBvcmlnaW5hbFNldFZpZXdTdGF0ZSEuY2FsbCh0aGlzLCBzdGF0ZSwgZVN0YXRlKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXN0b3JlIHRoZSBvcmlnaW5hbCBzZXRWaWV3U3RhdGUuIENhbGwgZnJvbSBQbHVnaW4ub251bmxvYWQoKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVuaW5zdGFsbEZpbGVJbnRlcmNlcHQoKTogdm9pZCB7XG4gIGlmICghb3JpZ2luYWxTZXRWaWV3U3RhdGUpIHJldHVybjtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgKFdvcmtzcGFjZUxlYWYgYXMgYW55KS5wcm90b3R5cGUuc2V0Vmlld1N0YXRlID0gb3JpZ2luYWxTZXRWaWV3U3RhdGU7XG4gIG9yaWdpbmFsU2V0Vmlld1N0YXRlID0gbnVsbDtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUVBLFdBQU8sZUFBZSxTQUFTLGNBQWMsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUU1RCxRQUFJLFdBQVcsUUFBUSxVQUFVO0FBRWpDLFFBQU1BLDZCQUE0QjtBQUNsQyxRQUFNLDZCQUE2QjtBQUNuQyxRQUFNLDhCQUE4QjtBQUNwQyxRQUFNLGdDQUFnQztBQUN0QyxRQUFNLDZCQUE2QjtBQUVuQyxhQUFTLCtCQUErQixhQUFhO0FBWnJEO0FBY0ksWUFBTSxnQkFBZ0IsT0FBTyxJQUFJLFFBQVEsVUFBVSxnQkFBZ0I7QUFDbkUsYUFBTyxtQkFBaUIseUJBQWMsYUFBZCxtQkFBeUIsaUJBQXpCLG1CQUF1QztBQUFBLElBQ25FO0FBS0EsYUFBUyx1QkFBdUI7QUFyQmhDO0FBc0JJLFVBQUk7QUFFQSxjQUFNLEVBQUUsaUJBQWlCLFNBQUFDLFNBQVEsSUFBSSxPQUFPO0FBQzVDLFlBQUksK0JBQStCLE9BQU8sR0FB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TUFBTSxLQUFLLFdBQVcsRUFBRSxJQUFJLENBQUM7QUFBQSxFQUMxQztBQUFBLEVBRVEsZUFBcUI7QUFDM0IsUUFBSTtBQUNGLFdBQUssWUFBWSxJQUFJLE9BQU8sS0FBSyxTQUFTLGFBQWE7QUFBQSxJQUN6RCxTQUFRO0FBRU4sV0FBSyxZQUFZLElBQUksT0FBTyxpQkFBaUIsYUFBYTtBQUFBLElBQzVEO0FBQUEsRUFDRjtBQUFBLEVBRVEseUJBQStCO0FBQ3JDLFNBQUssSUFBSSxVQUFVLGlCQUFpQixDQUFDLFNBQVM7QUFwRWxEO0FBcUVNLFlBQU0sUUFBUSxLQUFLLGFBQWE7QUFDaEMsVUFDRSxNQUFNLFNBQVMsZ0JBQ2YsV0FBTSxVQUFOLG1CQUFhLFNBQ2IsS0FBSyxXQUFXLE1BQU0sTUFBTSxJQUFjLEdBQzFDO0FBQ0EsYUFBSyxhQUFhLEVBQUUsR0FBRyxPQUFPLE1BQU0sVUFBVSxDQUFDO0FBQUEsTUFDakQ7QUFBQSxJQUNGLENBQUM7QUFBQSxFQUNIO0FBRUY7IiwKICAibmFtZXMiOiBbIkRFRkFVTFRfREFJTFlfTk9URV9GT1JNQVQiLCAicGx1Z2lucyIsICJmb3JtYXQiLCAiZm9sZGVyIiwgInRlbXBsYXRlIiwgImltcG9ydF9vYnNpZGlhbiIsICJpbXBvcnRfb2JzaWRpYW4iLCAiaW1wb3J0X29ic2lkaWFuIiwgInIiLCAibyIsICJpbmRleCIsICJnaG9zdEVsIiwgIm9wdGlvbiIsICJkZWZhdWx0cyIsICJyb290RWwiLCAiY2xvbmVFbCIsICJvbGRJbmRleCIsICJuZXdJbmRleCIsICJvbGREcmFnZ2FibGVJbmRleCIsICJuZXdEcmFnZ2FibGVJbmRleCIsICJwdXRTb3J0YWJsZSIsICJwbHVnaW5FdmVudCIsICJfZGV0ZWN0RGlyZWN0aW9uIiwgIl9kcmFnRWxJblJvd0NvbHVtbiIsICJfZGV0ZWN0TmVhcmVzdEVtcHR5U29ydGFibGUiLCAiX3ByZXBhcmVHcm91cCIsICJkcmFnRWwiLCAiX2hpZGVHaG9zdEZvclRhcmdldCIsICJfdW5oaWRlR2hvc3RGb3JUYXJnZXQiLCAibmVhcmVzdEVtcHR5SW5zZXJ0RGV0ZWN0RXZlbnQiLCAiX2NoZWNrT3V0c2lkZVRhcmdldEVsIiwgImRyYWdTdGFydEZuIiwgInRhcmdldCIsICJhZnRlciIsICJlbCIsICJwbHVnaW5zIiwgImRyb3AiLCAiYXV0b1Njcm9sbCIsICJvblNwaWxsIiwgImluZGV4IiwgIm9sZEluZGV4IiwgIm5ld0luZGV4IiwgImltcG9ydF9vYnNpZGlhbiIsICJfYSIsICJpbXBvcnRfb2JzaWRpYW4iLCAiaW5kZXgiLCAib2xkSW5kZXgiLCAibmV3SW5kZXgiLCAibW92ZWQiXQp9Cg==
|