tech-tips/.obsidian/plugins/obsidian-advanced-codeblock/main.js

611 lines
74 KiB
JavaScript

/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
__markAsModule(target);
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/main.ts
__export(exports, {
default: () => ObsidianAdvancedCodeblockPlugin
});
var import_obsidian3 = __toModule(require("obsidian"));
// src/postProcessor.ts
var import_obsidian2 = __toModule(require("obsidian"));
// src/util.ts
var paramRegex = /\{.+\}|\w+/g;
var braceSurroundingRegex = /^{.+}$/;
// src/extendPrism.ts
var import_obsidian = __toModule(require("obsidian"));
// lib/prism-line-numbers.js
function extendLineNumberPlugin(Prism) {
if (typeof Prism === "undefined" || typeof document === "undefined") {
return;
}
var PLUGIN_NAME = "line-numbers";
var NEW_LINE_EXP = /\n(?!$)/g;
var config = Prism.plugins.lineNumbers = {
getLine: function(element, number) {
if (element.tagName !== "PRE" || !element.classList.contains(PLUGIN_NAME)) {
return;
}
var lineNumberRows = element.querySelector(".line-numbers-rows");
if (!lineNumberRows) {
return;
}
var lineNumberStart = parseInt(element.getAttribute("data-start"), 10) || 1;
var lineNumberEnd = lineNumberStart + (lineNumberRows.children.length - 1);
if (number < lineNumberStart) {
number = lineNumberStart;
}
if (number > lineNumberEnd) {
number = lineNumberEnd;
}
var lineIndex = number - lineNumberStart;
return lineNumberRows.children[lineIndex];
},
resize: function(element) {
resizeElements([element]);
},
assumeViewportIndependence: true
};
function resizeElements(elements) {
elements = elements.filter(function(e) {
var codeStyles = getStyles(e);
var whiteSpace = codeStyles["white-space"];
return whiteSpace === "pre-wrap" || whiteSpace === "pre-line";
});
if (elements.length == 0) {
return;
}
var infos = elements.map(function(element) {
var codeElement = element.querySelector("code");
var lineNumbersWrapper = element.querySelector(".line-numbers-rows");
if (!codeElement || !lineNumbersWrapper) {
return void 0;
}
var lineNumberSizer = element.querySelector(".line-numbers-sizer");
var codeLines = codeElement.textContent.split(NEW_LINE_EXP);
if (!lineNumberSizer) {
lineNumberSizer = document.createElement("span");
lineNumberSizer.className = "line-numbers-sizer";
codeElement.appendChild(lineNumberSizer);
}
lineNumberSizer.innerHTML = "0";
lineNumberSizer.style.display = "block";
var oneLinerHeight = lineNumberSizer.getBoundingClientRect().height;
lineNumberSizer.innerHTML = "";
return {
element,
lines: codeLines,
lineHeights: [],
oneLinerHeight,
sizer: lineNumberSizer
};
}).filter(Boolean);
infos.forEach(function(info) {
var lineNumberSizer = info.sizer;
var lines = info.lines;
var lineHeights = info.lineHeights;
var oneLinerHeight = info.oneLinerHeight;
lineHeights[lines.length - 1] = void 0;
lines.forEach(function(line, index) {
if (line && line.length > 1) {
var e = lineNumberSizer.appendChild(document.createElement("span"));
e.style.display = "block";
e.textContent = line;
} else {
lineHeights[index] = oneLinerHeight;
}
});
});
infos.forEach(function(info) {
var lineNumberSizer = info.sizer;
var lineHeights = info.lineHeights;
var childIndex = 0;
for (var i = 0; i < lineHeights.length; i++) {
if (lineHeights[i] === void 0) {
lineHeights[i] = lineNumberSizer.children[childIndex++].getBoundingClientRect().height;
}
}
});
infos.forEach(function(info) {
var lineNumberSizer = info.sizer;
var wrapper = info.element.querySelector(".line-numbers-rows");
lineNumberSizer.style.display = "none";
lineNumberSizer.innerHTML = "";
info.lineHeights.forEach(function(height, lineNumber) {
wrapper.children[lineNumber].style.height = height + "px";
});
});
}
function getStyles(element) {
if (!element) {
return null;
}
return window.getComputedStyle ? getComputedStyle(element) : element.currentStyle || null;
}
Prism.hooks.add("complete", function(env) {
if (!env.code) {
return;
}
var code = env.element;
var pre = code.parentNode;
if (!pre || !/pre/i.test(pre.nodeName)) {
return;
}
if (code.querySelector(".line-numbers-rows")) {
return;
}
if (!Prism.util.isActive(code, PLUGIN_NAME)) {
return;
}
code.classList.remove(PLUGIN_NAME);
pre.classList.add(PLUGIN_NAME);
var match = env.code.match(NEW_LINE_EXP);
var linesNum = match ? match.length + 1 : 1;
var lineNumbersWrapper;
var lines = new Array(linesNum + 1).join("<span></span>");
lineNumbersWrapper = document.createElement("span");
lineNumbersWrapper.setAttribute("aria-hidden", "true");
lineNumbersWrapper.className = "line-numbers-rows";
lineNumbersWrapper.innerHTML = lines;
if (pre.hasAttribute("data-start")) {
pre.style.counterReset = "linenumber " + (parseInt(pre.getAttribute("data-start"), 10) - 1);
}
env.element.appendChild(lineNumbersWrapper);
resizeElements([pre]);
Prism.hooks.run("line-numbers", env);
});
Prism.hooks.add("line-numbers", function(env) {
env.plugins = env.plugins || {};
env.plugins.lineNumbers = true;
});
}
// lib/prism-line-highlight.js
function extendLineHighlightPlugin(Prism) {
if (typeof Prism === "undefined" || typeof document === "undefined" || !document.querySelector) {
return;
}
var LINE_NUMBERS_CLASS = "line-numbers";
var LINKABLE_LINE_NUMBERS_CLASS = "linkable-line-numbers";
var NEW_LINE_REGEX = /\n(?!$)/g;
function $$(selector, container) {
return Array.prototype.slice.call((container || document).querySelectorAll(selector));
}
function hasClass(element, className) {
return element.classList.contains(className);
}
function callFunction(func) {
func();
}
var isLineHeightRounded = function() {
var res;
return function() {
if (typeof res === "undefined") {
var d = document.createElement("div");
d.style.fontSize = "13px";
d.style.lineHeight = "1.5";
d.style.padding = "0";
d.style.border = "0";
d.innerHTML = "&nbsp;<br />&nbsp;";
document.body.appendChild(d);
res = d.offsetHeight === 38;
document.body.removeChild(d);
}
return res;
};
}();
function getContentBoxTopOffset(parent, child) {
var parentStyle = getComputedStyle(parent);
var childStyle = getComputedStyle(child);
function pxToNumber(px) {
return +px.substr(0, px.length - 2);
}
return child.offsetTop + pxToNumber(childStyle.borderTopWidth) + pxToNumber(childStyle.paddingTop) - pxToNumber(parentStyle.paddingTop);
}
function isActiveFor(pre) {
if (!pre || !/pre/i.test(pre.nodeName)) {
return false;
}
if (pre.hasAttribute("data-line")) {
return true;
}
if (pre.id && Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS)) {
return true;
}
return false;
}
var scrollIntoView = true;
Prism.plugins.lineHighlight = {
highlightLines: function highlightLines(pre, lines, classes) {
lines = typeof lines === "string" ? lines : pre.getAttribute("data-line") || "";
var ranges = lines.replace(/\s+/g, "").split(",").filter(Boolean);
var offset = +pre.getAttribute("data-line-offset") || 0;
var parseMethod = isLineHeightRounded() ? parseInt : parseFloat;
var codeElement = pre.querySelector("code");
var lineHeight = parseMethod(getComputedStyle(codeElement).lineHeight);
var hasLineNumbers = Prism.util.isActive(pre, LINE_NUMBERS_CLASS);
var parentElement = hasLineNumbers ? pre : codeElement || pre;
var mutateActions = [];
var lineBreakMatch = codeElement.textContent.match(NEW_LINE_REGEX);
var numberOfLines = lineBreakMatch ? lineBreakMatch.length + 1 : 1;
var codePreOffset = !codeElement || parentElement == codeElement ? 0 : getContentBoxTopOffset(pre, codeElement);
ranges.forEach(function(currentRange) {
var range = currentRange.split("-");
var start2 = +range[0];
var end = +range[1] || start2;
end = Math.min(numberOfLines, end);
if (end < start2)
return;
var line = pre.querySelector('.line-highlight[data-range="' + currentRange + '"]') || document.createElement("div");
mutateActions.push(function() {
line.setAttribute("aria-hidden", "true");
line.setAttribute("data-range", currentRange);
line.className = (classes || "") + " line-highlight";
});
if (hasLineNumbers && Prism.plugins.lineNumbers) {
var startNode = Prism.plugins.lineNumbers.getLine(pre, start2);
var endNode = Prism.plugins.lineNumbers.getLine(pre, end);
if (startNode) {
var top = startNode.offsetTop + codePreOffset + "px";
mutateActions.push(function() {
line.style.top = top;
});
}
if (endNode) {
var height = endNode.offsetTop - startNode.offsetTop + endNode.offsetHeight + "px";
mutateActions.push(function() {
line.style.height = height;
});
}
} else {
mutateActions.push(function() {
line.setAttribute("data-start", String(start2));
if (end > start2) {
line.setAttribute("data-end", String(end));
}
line.style.top = (start2 - offset - 1) * lineHeight + codePreOffset + "px";
line.textContent = new Array(end - start2 + 2).join(" \n");
});
}
mutateActions.push(function() {
line.style.width = pre.scrollWidth + "px";
});
mutateActions.push(function() {
parentElement.appendChild(line);
});
});
var id = pre.id;
if (hasLineNumbers && Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS) && id) {
if (!hasClass(pre, LINKABLE_LINE_NUMBERS_CLASS)) {
mutateActions.push(function() {
pre.classList.add(LINKABLE_LINE_NUMBERS_CLASS);
});
}
var start = parseInt(pre.getAttribute("data-start") || "1");
$$(".line-numbers-rows > span", pre).forEach(function(lineSpan, i) {
var lineNumber = i + start;
lineSpan.onclick = function() {
var hash = id + "." + lineNumber;
scrollIntoView = false;
location.hash = hash;
setTimeout(function() {
scrollIntoView = true;
}, 1);
};
});
}
return function() {
mutateActions.forEach(callFunction);
};
}
};
function applyHash() {
var hash = location.hash.slice(1);
$$(".temporary.line-highlight").forEach(function(line) {
line.parentNode.removeChild(line);
});
var range = (hash.match(/\.([\d,-]+)$/) || [, ""])[1];
if (!range || document.getElementById(hash)) {
return;
}
var id = hash.slice(0, hash.lastIndexOf("."));
var pre = document.getElementById(id);
if (!pre) {
return;
}
if (!pre.hasAttribute("data-line")) {
pre.setAttribute("data-line", "");
}
var mutateDom = Prism.plugins.lineHighlight.highlightLines(pre, range, "temporary ");
mutateDom();
if (scrollIntoView) {
document.querySelector(".temporary.line-highlight").scrollIntoView();
}
}
var fakeTimer = 0;
Prism.hooks.add("before-sanity-check", function(env) {
var pre = env.element.parentElement;
if (!isActiveFor(pre)) {
return;
}
var num = 0;
$$(".line-highlight", pre).forEach(function(line) {
num += line.textContent.length;
line.parentNode.removeChild(line);
});
if (num && /^(?: \n)+$/.test(env.code.slice(-num))) {
env.code = env.code.slice(0, -num);
}
});
Prism.hooks.add("complete", function completeHook(env) {
var pre = env.element.parentElement;
if (!isActiveFor(pre)) {
return;
}
clearTimeout(fakeTimer);
var hasLineNumbers = Prism.plugins.lineNumbers;
var isLineNumbersLoaded = env.plugins && env.plugins.lineNumbers;
if (hasClass(pre, LINE_NUMBERS_CLASS) && hasLineNumbers && !isLineNumbersLoaded) {
Prism.hooks.add("line-numbers", completeHook);
} else {
var mutateDom = Prism.plugins.lineHighlight.highlightLines(pre);
mutateDom();
fakeTimer = setTimeout(applyHash, 1);
}
});
window.addEventListener("hashchange", applyHash);
}
// src/extendPrism.ts
(0, import_obsidian.loadPrism)().then((val) => {
extendLineNumberPlugin(window.Prism);
extendLineHighlightPlugin(window.Prism);
});
// src/postProcessor.ts
function processParams(element, context, app) {
var _a;
const pre = element.querySelector("pre:not(.frontmatter)");
if (!pre)
return null;
const codeBlock = context.getSectionInfo(element);
if (!codeBlock)
return null;
const origin = (_a = app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView)) == null ? void 0 : _a.editor.getLine(codeBlock.lineStart).slice(3);
if (!origin)
return null;
const codeBlockInfo = origin.match(paramRegex);
const params = codeBlockInfo.slice(1);
if (!params.length)
return null;
return { pre, params };
}
function onMounted(element, onAttachCallback) {
const observer = new MutationObserver(function() {
function isAttached(el) {
if (el.parentNode === document) {
return true;
} else if (el.parentNode === null) {
return false;
} else {
return isAttached(el.parentNode);
}
}
if (isAttached(element)) {
observer.disconnect();
onAttachCallback();
}
});
observer.observe(document, {
childList: true,
subtree: true
});
}
function handleLineNumbers(pre, params, initHandlers) {
if (!params.includes("nums"))
return;
pre.classList.add("line-numbers");
const initLineNumbers = () => {
window.Prism.plugins.lineNumbers.resize(pre);
};
initHandlers.push(initLineNumbers);
}
function handleLineHighlight(pre, params, initHandlers) {
const lineHightlightParamIdx = params.findIndex((param) => braceSurroundingRegex.test(param));
if (lineHightlightParamIdx === -1)
return;
pre.dataset.line = params[lineHightlightParamIdx].slice(1, -1);
const initLineHighlight = () => {
window.Prism.plugins.lineHighlight.highlightLines(pre)();
};
initHandlers.push(initLineHighlight);
}
function commonCodeblockPostProcessor(element, context, app, plugin) {
const processResult = processParams(element, context, app);
if (!processResult)
return;
const { pre, params } = processResult;
const initHandlers = [];
handleLineNumbers(pre, params, initHandlers);
handleLineHighlight(pre, params, initHandlers);
onMounted(pre, () => {
initHandlers.forEach((handler) => {
handler();
});
});
plugin.registerEvent(app.workspace.on("resize", () => {
initHandlers.forEach((handler) => {
handler();
});
}));
}
// src/CM6Extensions.ts
var import_view = __toModule(require("@codemirror/view"));
var import_state = __toModule(require("@codemirror/state"));
var import_language = __toModule(require("@codemirror/language"));
var LineNumberWidget = class extends import_view.WidgetType {
constructor(idx) {
super();
this.idx = idx;
}
toDOM() {
const el = document.createElement("span");
el.className = "live-preview-codeblock-line-nums";
el.textContent = "" + this.idx;
return el;
}
};
var livePreviewCM6Extension = import_view.ViewPlugin.fromClass(class {
constructor(view) {
this.decorations = this.buildDecorations(view);
}
update(update) {
if (update.docChanged || update.viewportChanged)
this.decorations = this.buildDecorations(update.view);
}
destory() {
}
buildDecorations(view) {
const builder = new import_state.RangeSetBuilder();
const codeblockInfo = {
showLineNumbers: false,
highlightLines: null
};
let startLineNum;
for (const { from, to } of view.visibleRanges) {
try {
const tree = (0, import_language.syntaxTree)(view.state);
tree.iterate({
from,
to,
enter: ({ type, from: from2, to: to2 }) => {
var _a, _b;
const lineClasses = type.prop(import_language.lineClassNodeProp);
if (!lineClasses)
return;
const classes = new Set(lineClasses.split(" "));
const isCodeblockBegin = classes.has("HyperMD-codeblock-begin");
const isCodeblockLine = classes.has("HyperMD-codeblock-bg") && !classes.has("HyperMD-codeblock-begin") && !classes.has("HyperMD-codeblock-end");
if (isCodeblockBegin) {
const startLine = view.state.doc.lineAt(from2);
const codeblockParams = startLine.text.match(paramRegex).slice(1);
const highlightParam = (_a = codeblockParams.find((param) => braceSurroundingRegex.test(param))) == null ? void 0 : _a.slice(1, -1);
startLineNum = startLine.number;
codeblockInfo.showLineNumbers = false;
codeblockInfo.highlightLines = null;
if (codeblockParams.includes("nums"))
codeblockInfo.showLineNumbers = true;
if (highlightParam)
codeblockInfo.highlightLines = highlightParam.replace(" ", "").split(",").flatMap((line) => {
if (!+line) {
const res = [];
const [start, end] = line.split("-");
for (let i = +start; i <= +end; i++) {
res.push(i);
}
return res;
}
return [+line];
});
}
if (!isCodeblockLine)
return;
const currentLineNum = view.state.doc.lineAt(from2).number;
if (codeblockInfo.showLineNumbers) {
const deco = import_view.Decoration.widget({
widget: new LineNumberWidget(currentLineNum - startLineNum),
side: -1e4
});
builder.add(from2, from2, deco);
}
if (codeblockInfo.highlightLines) {
if (codeblockInfo.highlightLines.includes(currentLineNum - startLineNum)) {
const line = view.state.doc.lineAt(from2);
const deco = import_view.Decoration.line({
attributes: { class: "live-preview-codeblock-highlight" }
});
if ((_b = builder.last) == null ? void 0 : _b.startSide) {
deco.startSide = builder.last.startSide;
deco.endSide = deco.startSide;
}
builder.add(line.from, line.from, deco);
}
}
}
});
} catch (error) {
console.log(error);
}
}
return builder.finish();
}
}, {
decorations: (v) => v.decorations
});
// src/main.ts
var ObsidianAdvancedCodeblockPlugin = class extends import_obsidian3.Plugin {
onload() {
return __async(this, null, function* () {
console.log("Loading Advanced Codeblock");
this.registerEditorExtension([livePreviewCM6Extension]);
this.registerMarkdownPostProcessor((element, context) => {
commonCodeblockPostProcessor(element, context, this.app, this);
});
});
}
onunload() {
}
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAic3JjL3Bvc3RQcm9jZXNzb3IudHMiLCAic3JjL3V0aWwudHMiLCAic3JjL2V4dGVuZFByaXNtLnRzIiwgImxpYi9wcmlzbS1saW5lLW51bWJlcnMuanMiLCAibGliL3ByaXNtLWxpbmUtaGlnaGxpZ2h0LmpzIiwgInNyYy9DTTZFeHRlbnNpb25zLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBQbHVnaW4gfSBmcm9tIFwib2JzaWRpYW5cIjtcclxuaW1wb3J0IHsgY29tbW9uQ29kZWJsb2NrUG9zdFByb2Nlc3NvciB9IGZyb20gXCIuL3Bvc3RQcm9jZXNzb3JcIjtcclxuaW1wb3J0IHsgbGl2ZVByZXZpZXdDTTZFeHRlbnNpb24gfSBmcm9tICcuL0NNNkV4dGVuc2lvbnMnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgT2JzaWRpYW5BZHZhbmNlZENvZGVibG9ja1BsdWdpbiBleHRlbmRzIFBsdWdpbiB7XHJcblx0YXN5bmMgb25sb2FkKCkge1xyXG5cdFx0Y29uc29sZS5sb2coXCJMb2FkaW5nIEFkdmFuY2VkIENvZGVibG9ja1wiKTtcclxuXHJcblx0XHQvLyBBZGQgZnVuY3Rpb25hbGl0eSB0byBsaXZlLXByZXZpZXcgbW9kZVxyXG5cdFx0dGhpcy5yZWdpc3RlckVkaXRvckV4dGVuc2lvbihbbGl2ZVByZXZpZXdDTTZFeHRlbnNpb25dKTtcclxuXHJcblx0XHQvLyBBZGQgZnVuY3Rpb25hbGl0eSB0byBwcmV2aWV3IG1vZGVcclxuXHRcdHRoaXMucmVnaXN0ZXJNYXJrZG93blBvc3RQcm9jZXNzb3IoKGVsZW1lbnQsIGNvbnRleHQpID0+IHtcclxuXHRcdFx0Y29tbW9uQ29kZWJsb2NrUG9zdFByb2Nlc3NvcihlbGVtZW50LCBjb250ZXh0LCB0aGlzLmFwcCwgdGhpcyk7XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdG9udW5sb2FkKCkge31cclxufVxyXG4iLCAiaW1wb3J0IHtcclxuXHRBcHAsXHJcblx0TWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCxcclxuXHRNYXJrZG93blZpZXcsXHJcblx0UGx1Z2luLFxyXG59IGZyb20gXCJvYnNpZGlhblwiO1xyXG5pbXBvcnQgeyBwYXJhbVJlZ2V4LCBicmFjZVN1cnJvdW5kaW5nUmVnZXggfSBmcm9tIFwiLi91dGlsXCI7XHJcbmltcG9ydCBcIi4vZXh0ZW5kUHJpc21cIjtcclxuXHJcbnR5cGUgSGFuZGxlclNldCA9ICgoKSA9PiB2b2lkKVtdO1xyXG5cclxuZnVuY3Rpb24gcHJvY2Vzc1BhcmFtcyhcclxuXHRlbGVtZW50OiBIVE1MRWxlbWVudCxcclxuXHRjb250ZXh0OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0LFxyXG5cdGFwcDogQXBwXHJcbikge1xyXG5cdC8vIE9ubHkgd29ya3Mgd2l0aCBjb2RlIGJsb2NrcztcclxuXHRjb25zdCBwcmU6IEhUTUxQcmVFbGVtZW50ID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yKFwicHJlOm5vdCguZnJvbnRtYXR0ZXIpXCIpO1xyXG5cdGlmICghcHJlKSByZXR1cm4gbnVsbDtcclxuXHJcblx0Y29uc3QgY29kZUJsb2NrID0gY29udGV4dC5nZXRTZWN0aW9uSW5mbyhlbGVtZW50KTtcclxuXHRpZiAoIWNvZGVCbG9jaykgcmV0dXJuIG51bGw7XHJcblxyXG5cdGNvbnN0IG9yaWdpbiA9IGFwcC53b3Jrc3BhY2VcclxuXHRcdC5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldylcclxuXHRcdD8uZWRpdG9yLmdldExpbmUoY29kZUJsb2NrLmxpbmVTdGFydClcclxuXHRcdC5zbGljZSgzKTtcclxuXHJcblx0Ly8gbm90IHNwZWNpZnkgYW55dGhpbmcgb3Igbm8gYWN0aXZlIHZpZXdcclxuXHRpZiAoIW9yaWdpbikgcmV0dXJuIG51bGw7XHJcblxyXG5cdGNvbnN0IGNvZGVCbG9ja0luZm8gPSBvcmlnaW4ubWF0Y2gocGFyYW1SZWdleCk7XHJcblx0Y29uc3QgcGFyYW1zID0gY29kZUJsb2NrSW5mby5zbGljZSgxKTtcclxuXHJcblx0Ly8gcmV0dXJuIGlmIG5vIHBhcmFtXHJcblx0aWYgKCFwYXJhbXMubGVuZ3RoKSByZXR1cm4gbnVsbDtcclxuXHJcblx0cmV0dXJuIHsgcHJlLCBwYXJhbXMgfTtcclxufVxyXG5cclxuZnVuY3Rpb24gb25Nb3VudGVkKGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBvbkF0dGFjaENhbGxiYWNrOiAoKSA9PiB2b2lkKSB7XHJcblx0Y29uc3Qgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihmdW5jdGlvbiAoKSB7XHJcblx0XHRmdW5jdGlvbiBpc0F0dGFjaGVkKGVsOiBIVE1MRWxlbWVudCB8IG51bGwpOiBib29sZWFuIHtcclxuXHRcdFx0aWYgKGVsLnBhcmVudE5vZGUgPT09IGRvY3VtZW50KSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH0gZWxzZSBpZiAoZWwucGFyZW50Tm9kZSA9PT0gbnVsbCkge1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRyZXR1cm4gaXNBdHRhY2hlZChlbC5wYXJlbnROb2RlIGFzIEhUTUxFbGVtZW50KTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChpc0F0dGFjaGVkKGVsZW1lbnQpKSB7XHJcblx0XHRcdG9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcclxuXHRcdFx0b25BdHRhY2hDYWxsYmFjaygpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cclxuXHRvYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LCB7XHJcblx0XHRjaGlsZExpc3Q6IHRydWUsXHJcblx0XHRzdWJ0cmVlOiB0cnVlLFxyXG5cdH0pO1xyXG59XHJcblxyXG4vLyBoYW5kbGUgbGluZSBudW1iZXJcclxuZnVuY3Rpb24gaGFuZGxlTGluZU51bWJlcnMoXHJcblx0cHJlOiBIVE1MUHJlRWxlbWVudCxcclxuXHRwYXJhbXM6IHN0cmluZ1tdLFxyXG5cdGluaXRIYW5kbGVyczogSGFuZGxlclNldCxcclxuKSB7XHJcblx0aWYgKCFwYXJhbXMuaW5jbHVkZXMoXCJudW1zXCIpKSByZXR1cm47XHJcblxyXG5cdHByZS5jbGFzc0xpc3QuYWRkKFwibGluZS1udW1iZXJzXCIpO1xyXG5cclxuXHRjb25zdCBpbml0TGluZU51bWJlcnMgPSAoKSA9PiB7XHJcblx0XHR3aW5kb3cuUHJpc20ucGx1Z2lucy5saW5lTnVtYmVycy5yZXNpemUocHJlKTtcclxuXHR9XHJcblxyXG5cdGluaXRIYW5kbGVycy5wdXNoKGluaXRMaW5lTnVtYmVycyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGhhbmRsZUxpbmVIaWdobGlnaHQoXHJcblx0cHJlOiBIVE1MUHJlRWxlbWVudCxcclxuXHRwYXJhbXM6IHN0cmluZ1tdLFxyXG5cdGluaXRIYW5kbGVyczogSGFuZGxlclNldCxcclxuKSB7XHJcblx0Y29uc3QgbGluZUhpZ2h0bGlnaHRQYXJhbUlkeCA9IHBhcmFtcy5maW5kSW5kZXgoKHBhcmFtKSA9PlxyXG5cdFx0YnJhY2VTdXJyb3VuZGluZ1JlZ2V4LnRlc3QocGFyYW0pXHJcblx0KTtcclxuXHRpZiAobGluZUhpZ2h0bGlnaHRQYXJhbUlkeCA9PT0gLTEpIHJldHVybiA7XHJcblxyXG5cdHByZS5kYXRhc2V0LmxpbmUgPSBwYXJhbXNbbGluZUhpZ2h0bGlnaHRQYXJhbUlkeF0uc2xpY2UoMSwgLTEpO1xyXG5cclxuXHRjb25zdCBpbml0TGluZUhpZ2hsaWdodCA9ICgpID0+IHtcclxuXHRcdHdpbmRvdy5QcmlzbS5wbHVnaW5zLmxpbmVIaWdobGlnaHQuaGlnaGxpZ2h0TGluZXMocHJlKSgpO1xyXG5cdH1cclxuXHJcblx0aW5pdEhhbmRsZXJzLnB1c2goaW5pdExpbmVIaWdobGlnaHQpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY29tbW9uQ29kZWJsb2NrUG9zdFByb2Nlc3NvcihcclxuXHRlbGVtZW50OiBIVE1MRWxlbWVudCxcclxuXHRjb250ZXh0OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0LFxyXG5cdGFwcDogQXBwLFxyXG5cdHBsdWdpbjogUGx1Z2luXHJcbikge1xyXG5cdC8vIGNoZWNrIGlmIHByb2Nlc3NvciBzaG91bGQgcnVuXHJcblx0Y29uc3QgcHJvY2Vzc1Jlc3VsdCA9IHByb2Nlc3NQYXJhbXMoZWxlbWVudCwgY29udGV4dCwgYXBwKTtcclxuXHRpZiAoIXByb2Nlc3NSZXN1bHQpIHJldHVybjtcclxuXHJcblx0Y29uc3QgeyBwcmUsIHBhcmFtcyB9ID0gcHJvY2Vzc1Jlc3VsdDtcclxuXHRjb25zdCBpbml0SGFuZGxlcnM6IEhhbmRsZXJTZXQgPSBbXTtcclxuXHJcblx0Ly8gYWRkIGxpbmUgbnVtYmVycy5cclxuXHRoYW5kbGVMaW5lTnVtYmVycyhwcmUsIHBhcmFtcywgaW5pdEhhbmRsZXJzKTtcclxuXHJcblx0Ly8gYWRkIGxpbmUgaGlnaGxpZ2h0XHJcblx0aGFuZGxlTGluZUhpZ2hsaWdodChwcmUsIHBhcmFtcywgaW5pdEhhbmRsZXJzKTtcclxuXHJcblx0Ly8gUmVpbml0IGFmdGVyIG1vdW50XHJcblx0b25Nb3VudGVkKHByZSwgKCkgPT4ge1xyXG5cdFx0aW5pdEhhbmRsZXJzLmZvckVhY2goKGhhbmRsZXIpID0+IHtcclxuXHRcdFx0aGFuZGxlcigpO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblxyXG5cdC8vIFJlaW5pdCBhZnRlciByZXNpemVcclxuXHRwbHVnaW4ucmVnaXN0ZXJFdmVudChhcHAud29ya3NwYWNlLm9uKCdyZXNpemUnLCAoKSA9PiB7XHJcblx0XHRpbml0SGFuZGxlcnMuZm9yRWFjaCgoaGFuZGxlcikgPT4ge1xyXG5cdFx0XHRoYW5kbGVyKCk7XHJcblx0XHR9KVxyXG5cdH0pKVxyXG59XHJcbiIsICJleHBvcnQgY29uc3QgcGFyYW1SZWdleCA9IC9cXHsuK1xcfXxcXHcrL2c7XHJcbmV4cG9ydCBjb25zdCBicmFjZVN1cnJvdW5kaW5nUmVnZXggPSAvXnsuK30kLzsiLCAiaW1wb3J0IHsgbG9hZFByaXNtIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBleHRlbmRMaW5lTnVtYmVyUGx1Z2luIH0gZnJvbSAnLi8uLi9saWIvcHJpc20tbGluZS1udW1iZXJzJztcclxuaW1wb3J0IHsgZXh0ZW5kTGluZUhpZ2hsaWdodFBsdWdpbiB9IGZyb20gJy4vLi4vbGliL3ByaXNtLWxpbmUtaGlnaGxpZ2h0J1xyXG5cclxubG9hZFByaXNtKCkudGhlbigodmFsKSA9PiB7XHJcbiAgZXh0ZW5kTGluZU51bWJlclBsdWdpbih3aW5kb3cuUHJpc20pXHJcbiAgZXh0ZW5kTGluZUhpZ2hsaWdodFBsdWdpbih3aW5kb3cuUHJpc20pXHJcbn0pOyIsICJleHBvcnQgZnVuY3Rpb24gZXh0ZW5kTGluZU51bWJlclBsdWdpbiAoUHJpc20pIHtcclxuXHJcblx0aWYgKHR5cGVvZiBQcmlzbSA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogUGx1Z2luIG5hbWUgd2hpY2ggaXMgdXNlZCBhcyBhIGNsYXNzIG5hbWUgZm9yIDxwcmU+IHdoaWNoIGlzIGFjdGl2YXRpbmcgdGhlIHBsdWdpblxyXG5cdCAqXHJcblx0ICogQHR5cGUge3N0cmluZ31cclxuXHQgKi9cclxuXHR2YXIgUExVR0lOX05BTUUgPSAnbGluZS1udW1iZXJzJztcclxuXHJcblx0LyoqXHJcblx0ICogUmVndWxhciBleHByZXNzaW9uIHVzZWQgZm9yIGRldGVybWluaW5nIGxpbmUgYnJlYWtzXHJcblx0ICpcclxuXHQgKiBAdHlwZSB7UmVnRXhwfVxyXG5cdCAqL1xyXG5cdHZhciBORVdfTElORV9FWFAgPSAvXFxuKD8hJCkvZztcclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIEdsb2JhbCBleHBvcnRzXHJcblx0ICovXHJcblx0dmFyIGNvbmZpZyA9IFByaXNtLnBsdWdpbnMubGluZU51bWJlcnMgPSB7XHJcblx0XHQvKipcclxuXHRcdCAqIEdldCBub2RlIGZvciBwcm92aWRlZCBsaW5lIG51bWJlclxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBwcmUgZWxlbWVudFxyXG5cdFx0ICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBsaW5lIG51bWJlclxyXG5cdFx0ICogQHJldHVybnMge0VsZW1lbnR8dW5kZWZpbmVkfVxyXG5cdFx0ICovXHJcblx0XHRnZXRMaW5lOiBmdW5jdGlvbiAoZWxlbWVudCwgbnVtYmVyKSB7XHJcblx0XHRcdGlmIChlbGVtZW50LnRhZ05hbWUgIT09ICdQUkUnIHx8ICFlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhQTFVHSU5fTkFNRSkpIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHZhciBsaW5lTnVtYmVyUm93cyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcignLmxpbmUtbnVtYmVycy1yb3dzJyk7XHJcblx0XHRcdGlmICghbGluZU51bWJlclJvd3MpIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHRcdFx0dmFyIGxpbmVOdW1iZXJTdGFydCA9IHBhcnNlSW50KGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXN0YXJ0JyksIDEwKSB8fCAxO1xyXG5cdFx0XHR2YXIgbGluZU51bWJlckVuZCA9IGxpbmVOdW1iZXJTdGFydCArIChsaW5lTnVtYmVyUm93cy5jaGlsZHJlbi5sZW5ndGggLSAxKTtcclxuXHJcblx0XHRcdGlmIChudW1iZXIgPCBsaW5lTnVtYmVyU3RhcnQpIHtcclxuXHRcdFx0XHRudW1iZXIgPSBsaW5lTnVtYmVyU3RhcnQ7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKG51bWJlciA+IGxpbmVOdW1iZXJFbmQpIHtcclxuXHRcdFx0XHRudW1iZXIgPSBsaW5lTnVtYmVyRW5kO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR2YXIgbGluZUluZGV4ID0gbnVtYmVyIC0gbGluZU51bWJlclN0YXJ0O1xyXG5cclxuXHRcdFx0cmV0dXJuIGxpbmVOdW1iZXJSb3dzLmNoaWxkcmVuW2xpbmVJbmRleF07XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogUmVzaXplcyB0aGUgbGluZSBudW1iZXJzIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxyXG5cdFx0ICpcclxuXHRcdCAqIFRoaXMgZnVuY3Rpb24gd2lsbCBub3QgYWRkIGxpbmUgbnVtYmVycy4gSXQgd2lsbCBvbmx5IHJlc2l6ZSBleGlzdGluZyBvbmVzLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnQgQSBgPHByZT5gIGVsZW1lbnQgd2l0aCBsaW5lIG51bWJlcnMuXHJcblx0XHQgKiBAcmV0dXJucyB7dm9pZH1cclxuXHRcdCAqL1xyXG5cdFx0cmVzaXplOiBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG5cdFx0XHRyZXNpemVFbGVtZW50cyhbZWxlbWVudF0pO1xyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFdoZXRoZXIgdGhlIHBsdWdpbiBjYW4gYXNzdW1lIHRoYXQgdGhlIHVuaXRzIGZvbnQgc2l6ZXMgYW5kIG1hcmdpbnMgYXJlIG5vdCBkZXBlbmRlZCBvbiB0aGUgc2l6ZSBvZlxyXG5cdFx0ICogdGhlIGN1cnJlbnQgdmlld3BvcnQuXHJcblx0XHQgKlxyXG5cdFx0ICogU2V0dGluZyB0aGlzIHRvIGB0cnVlYCB3aWxsIGFsbG93IHRoZSBwbHVnaW4gdG8gZG8gY2VydGFpbiBvcHRpbWl6YXRpb25zIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UuXHJcblx0XHQgKlxyXG5cdFx0ICogU2V0IHRoaXMgdG8gYGZhbHNlYCBpZiB5b3UgdXNlIGFueSBvZiB0aGUgZm9sbG93aW5nIENTUyB1bml0czogYHZoYCwgYHZ3YCwgYHZtaW5gLCBgdm1heGAuXHJcblx0XHQgKlxyXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XHJcblx0XHQgKi9cclxuXHRcdGFzc3VtZVZpZXdwb3J0SW5kZXBlbmRlbmNlOiB0cnVlXHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogUmVzaXplcyB0aGUgZ2l2ZW4gZWxlbWVudHMuXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge0hUTUxFbGVtZW50W119IGVsZW1lbnRzXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gcmVzaXplRWxlbWVudHMoZWxlbWVudHMpIHtcclxuXHRcdGVsZW1lbnRzID0gZWxlbWVudHMuZmlsdGVyKGZ1bmN0aW9uIChlKSB7XHJcblx0XHRcdHZhciBjb2RlU3R5bGVzID0gZ2V0U3R5bGVzKGUpO1xyXG5cdFx0XHR2YXIgd2hpdGVTcGFjZSA9IGNvZGVTdHlsZXNbJ3doaXRlLXNwYWNlJ107XHJcblx0XHRcdHJldHVybiB3aGl0ZVNwYWNlID09PSAncHJlLXdyYXAnIHx8IHdoaXRlU3BhY2UgPT09ICdwcmUtbGluZSc7XHJcblx0XHR9KTtcclxuXHJcblx0XHRpZiAoZWxlbWVudHMubGVuZ3RoID09IDApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBpbmZvcyA9IGVsZW1lbnRzLm1hcChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG5cdFx0XHR2YXIgY29kZUVsZW1lbnQgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ2NvZGUnKTtcclxuXHRcdFx0dmFyIGxpbmVOdW1iZXJzV3JhcHBlciA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcignLmxpbmUtbnVtYmVycy1yb3dzJyk7XHJcblx0XHRcdGlmICghY29kZUVsZW1lbnQgfHwgIWxpbmVOdW1iZXJzV3JhcHBlcikge1xyXG5cdFx0XHRcdHJldHVybiB1bmRlZmluZWQ7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8qKiBAdHlwZSB7SFRNTEVsZW1lbnR9ICovXHJcblx0XHRcdHZhciBsaW5lTnVtYmVyU2l6ZXIgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5saW5lLW51bWJlcnMtc2l6ZXInKTtcclxuXHRcdFx0dmFyIGNvZGVMaW5lcyA9IGNvZGVFbGVtZW50LnRleHRDb250ZW50LnNwbGl0KE5FV19MSU5FX0VYUCk7XHJcblxyXG5cdFx0XHRpZiAoIWxpbmVOdW1iZXJTaXplcikge1xyXG5cdFx0XHRcdGxpbmVOdW1iZXJTaXplciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcclxuXHRcdFx0XHRsaW5lTnVtYmVyU2l6ZXIuY2xhc3NOYW1lID0gJ2xpbmUtbnVtYmVycy1zaXplcic7XHJcblxyXG5cdFx0XHRcdGNvZGVFbGVtZW50LmFwcGVuZENoaWxkKGxpbmVOdW1iZXJTaXplcik7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGxpbmVOdW1iZXJTaXplci5pbm5lckhUTUwgPSAnMCc7XHJcblx0XHRcdGxpbmVOdW1iZXJTaXplci5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuXHJcblx0XHRcdHZhciBvbmVMaW5lckhlaWdodCA9IGxpbmVOdW1iZXJTaXplci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7XHJcblx0XHRcdGxpbmVOdW1iZXJTaXplci5pbm5lckhUTUwgPSAnJztcclxuXHJcblx0XHRcdHJldHVybiB7XHJcblx0XHRcdFx0ZWxlbWVudDogZWxlbWVudCxcclxuXHRcdFx0XHRsaW5lczogY29kZUxpbmVzLFxyXG5cdFx0XHRcdGxpbmVIZWlnaHRzOiBbXSxcclxuXHRcdFx0XHRvbmVMaW5lckhlaWdodDogb25lTGluZXJIZWlnaHQsXHJcblx0XHRcdFx0c2l6ZXI6IGxpbmVOdW1iZXJTaXplcixcclxuXHRcdFx0fTtcclxuXHRcdH0pLmZpbHRlcihCb29sZWFuKTtcclxuXHJcblx0XHRpbmZvcy5mb3JFYWNoKGZ1bmN0aW9uIChpbmZvKSB7XHJcblx0XHRcdHZhciBsaW5lTnVtYmVyU2l6ZXIgPSBpbmZvLnNpemVyO1xyXG5cdFx0XHR2YXIgbGluZXMgPSBpbmZvLmxpbmVzO1xyXG5cdFx0XHR2YXIgbGluZUhlaWdodHMgPSBpbmZvLmxpbmVIZWlnaHRzO1xyXG5cdFx0XHR2YXIgb25lTGluZXJIZWlnaHQgPSBpbmZvLm9uZUxpbmVySGVpZ2h0O1xyXG5cclxuXHRcdFx0bGluZUhlaWdodHNbbGluZXMubGVuZ3RoIC0gMV0gPSB1bmRlZmluZWQ7XHJcblx0XHRcdGxpbmVzLmZvckVhY2goZnVuY3Rpb24gKGxpbmUsIGluZGV4KSB7XHJcblx0XHRcdFx0aWYgKGxpbmUgJiYgbGluZS5sZW5ndGggPiAxKSB7XHJcblx0XHRcdFx0XHR2YXIgZSA9IGxpbmVOdW1iZXJTaXplci5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJykpO1xyXG5cdFx0XHRcdFx0ZS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuXHRcdFx0XHRcdGUudGV4dENvbnRlbnQgPSBsaW5lO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRsaW5lSGVpZ2h0c1tpbmRleF0gPSBvbmVMaW5lckhlaWdodDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0aW5mb3MuZm9yRWFjaChmdW5jdGlvbiAoaW5mbykge1xyXG5cdFx0XHR2YXIgbGluZU51bWJlclNpemVyID0gaW5mby5zaXplcjtcclxuXHRcdFx0dmFyIGxpbmVIZWlnaHRzID0gaW5mby5saW5lSGVpZ2h0cztcclxuXHJcblx0XHRcdHZhciBjaGlsZEluZGV4ID0gMDtcclxuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lSGVpZ2h0cy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHRcdGlmIChsaW5lSGVpZ2h0c1tpXSA9PT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdFx0XHRsaW5lSGVpZ2h0c1tpXSA9IGxpbmVOdW1iZXJTaXplci5jaGlsZHJlbltjaGlsZEluZGV4KytdLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdGluZm9zLmZvckVhY2goZnVuY3Rpb24gKGluZm8pIHtcclxuXHRcdFx0dmFyIGxpbmVOdW1iZXJTaXplciA9IGluZm8uc2l6ZXI7XHJcblx0XHRcdHZhciB3cmFwcGVyID0gaW5mby5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5saW5lLW51bWJlcnMtcm93cycpO1xyXG5cclxuXHRcdFx0bGluZU51bWJlclNpemVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcblx0XHRcdGxpbmVOdW1iZXJTaXplci5pbm5lckhUTUwgPSAnJztcclxuXHJcblx0XHRcdGluZm8ubGluZUhlaWdodHMuZm9yRWFjaChmdW5jdGlvbiAoaGVpZ2h0LCBsaW5lTnVtYmVyKSB7XHJcblx0XHRcdFx0d3JhcHBlci5jaGlsZHJlbltsaW5lTnVtYmVyXS5zdHlsZS5oZWlnaHQgPSBoZWlnaHQgKyAncHgnO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyBzdHlsZSBkZWNsYXJhdGlvbnMgZm9yIHRoZSBlbGVtZW50XHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcclxuXHQgKi9cclxuXHRmdW5jdGlvbiBnZXRTdHlsZXMoZWxlbWVudCkge1xyXG5cdFx0aWYgKCFlbGVtZW50KSB7XHJcblx0XHRcdHJldHVybiBudWxsO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSA/IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkgOiAoZWxlbWVudC5jdXJyZW50U3R5bGUgfHwgbnVsbCk7XHJcblx0fVxyXG5cclxuXHQvLyB2YXIgbGFzdFdpZHRoID0gdW5kZWZpbmVkO1xyXG5cdC8vIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBmdW5jdGlvbiAoKSB7XHJcblx0Ly8gXHRpZiAoY29uZmlnLmFzc3VtZVZpZXdwb3J0SW5kZXBlbmRlbmNlICYmIGxhc3RXaWR0aCA9PT0gd2luZG93LmlubmVyV2lkdGgpIHtcclxuXHQvLyBcdFx0cmV0dXJuO1xyXG5cdC8vIFx0fVxyXG5cdC8vIFx0bGFzdFdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcblxyXG5cdC8vIFx0cmVzaXplRWxlbWVudHMoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgncHJlLicgKyBQTFVHSU5fTkFNRSkpKTtcclxuXHQvLyB9KTtcclxuXHJcblx0UHJpc20uaG9va3MuYWRkKCdjb21wbGV0ZScsIGZ1bmN0aW9uIChlbnYpIHtcclxuXHRcdGlmICghZW52LmNvZGUpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBjb2RlID0gLyoqIEB0eXBlIHtFbGVtZW50fSAqLyAoZW52LmVsZW1lbnQpO1xyXG5cdFx0dmFyIHByZSA9IC8qKiBAdHlwZSB7SFRNTEVsZW1lbnR9ICovIChjb2RlLnBhcmVudE5vZGUpO1xyXG5cclxuXHRcdC8vIHdvcmtzIG9ubHkgZm9yIDxjb2RlPiB3cmFwcGVkIGluc2lkZSA8cHJlPiAobm90IGlubGluZSlcclxuXHRcdGlmICghcHJlIHx8ICEvcHJlL2kudGVzdChwcmUubm9kZU5hbWUpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBBYm9ydCBpZiBsaW5lIG51bWJlcnMgYWxyZWFkeSBleGlzdHNcclxuXHRcdGlmIChjb2RlLnF1ZXJ5U2VsZWN0b3IoJy5saW5lLW51bWJlcnMtcm93cycpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBvbmx5IGFkZCBsaW5lIG51bWJlcnMgaWYgPGNvZGU+IG9yIG9uZSBvZiBpdHMgYW5jZXN0b3JzIGhhcyB0aGUgYGxpbmUtbnVtYmVyc2AgY2xhc3NcclxuXHRcdGlmICghUHJpc20udXRpbC5pc0FjdGl2ZShjb2RlLCBQTFVHSU5fTkFNRSkpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFJlbW92ZSB0aGUgY2xhc3MgJ2xpbmUtbnVtYmVycycgZnJvbSB0aGUgPGNvZGU+XHJcblx0XHRjb2RlLmNsYXNzTGlzdC5yZW1vdmUoUExVR0lOX05BTUUpO1xyXG5cdFx0Ly8gQWRkIHRoZSBjbGFzcyAnbGluZS1udW1iZXJzJyB0byB0aGUgPHByZT5cclxuXHRcdHByZS5jbGFzc0xpc3QuYWRkKFBMVUdJTl9OQU1FKTtcclxuXHJcblx0XHR2YXIgbWF0Y2ggPSBlbnYuY29kZS5tYXRjaChORVdfTElORV9FWFApO1xyXG5cdFx0dmFyIGxpbmVzTnVtID0gbWF0Y2ggPyBtYXRjaC5sZW5ndGggKyAxIDogMTtcclxuXHRcdHZhciBsaW5lTnVtYmVyc1dyYXBwZXI7XHJcblxyXG5cdFx0dmFyIGxpbmVzID0gbmV3IEFycmF5KGxpbmVzTnVtICsgMSkuam9pbignPHNwYW4+PC9zcGFuPicpO1xyXG5cclxuXHRcdGxpbmVOdW1iZXJzV3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcclxuXHRcdGxpbmVOdW1iZXJzV3JhcHBlci5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcclxuXHRcdGxpbmVOdW1iZXJzV3JhcHBlci5jbGFzc05hbWUgPSAnbGluZS1udW1iZXJzLXJvd3MnO1xyXG5cdFx0bGluZU51bWJlcnNXcmFwcGVyLmlubmVySFRNTCA9IGxpbmVzO1xyXG5cclxuXHRcdGlmIChwcmUuaGFzQXR0cmlidXRlKCdkYXRhLXN0YXJ0JykpIHtcclxuXHRcdFx0cHJlLnN0eWxlLmNvdW50ZXJSZXNldCA9ICdsaW5lbnVtYmVyICcgKyAocGFyc2VJbnQocHJlLmdldEF0dHJpYnV0ZSgnZGF0YS1zdGFydCcpLCAxMCkgLSAxKTtcclxuXHRcdH1cclxuXHJcblx0XHRlbnYuZWxlbWVudC5hcHBlbmRDaGlsZChsaW5lTnVtYmVyc1dyYXBwZXIpO1xyXG5cclxuXHRcdHJlc2l6ZUVsZW1lbnRzKFtwcmVdKTtcclxuXHJcblx0XHRQcmlzbS5ob29rcy5ydW4oJ2xpbmUtbnVtYmVycycsIGVudik7XHJcblx0fSk7XHJcblxyXG5cdFByaXNtLmhvb2tzLmFkZCgnbGluZS1udW1iZXJzJywgZnVuY3Rpb24gKGVudikge1xyXG5cdFx0ZW52LnBsdWdpbnMgPSBlbnYucGx1Z2lucyB8fCB7fTtcclxuXHRcdGVudi5wbHVnaW5zLmxpbmVOdW1iZXJzID0gdHJ1ZTtcclxuXHR9KTtcclxuXHJcbn1cclxuIiwgImV4cG9ydCBmdW5jdGlvbiBleHRlbmRMaW5lSGlnaGxpZ2h0UGx1Z2luIChQcmlzbSkge1xyXG5cclxuXHRpZiAodHlwZW9mIFByaXNtID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnIHx8ICFkb2N1bWVudC5xdWVyeVNlbGVjdG9yKSB7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cclxuXHR2YXIgTElORV9OVU1CRVJTX0NMQVNTID0gJ2xpbmUtbnVtYmVycyc7XHJcblx0dmFyIExJTktBQkxFX0xJTkVfTlVNQkVSU19DTEFTUyA9ICdsaW5rYWJsZS1saW5lLW51bWJlcnMnO1xyXG5cdHZhciBORVdfTElORV9SRUdFWCA9IC9cXG4oPyEkKS9nXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzZWxlY3RvclxyXG5cdCAqIEBwYXJhbSB7UGFyZW50Tm9kZX0gW2NvbnRhaW5lcl1cclxuXHQgKiBAcmV0dXJucyB7SFRNTEVsZW1lbnRbXX1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiAkJChzZWxlY3RvciwgY29udGFpbmVyKSB7XHJcblx0XHRyZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoKGNvbnRhaW5lciB8fCBkb2N1bWVudCkucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikpO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBlbGVtZW50IGhhcyB0aGUgZ2l2ZW4gY2xhc3MuXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lXHJcblx0ICogQHJldHVybnMge2Jvb2xlYW59XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gaGFzQ2xhc3MoZWxlbWVudCwgY2xhc3NOYW1lKSB7XHJcblx0XHRyZXR1cm4gZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENhbGxzIHRoZSBnaXZlbiBmdW5jdGlvbi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7KCkgPT4gYW55fSBmdW5jXHJcblx0ICogQHJldHVybnMge3ZvaWR9XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gY2FsbEZ1bmN0aW9uKGZ1bmMpIHtcclxuXHRcdGZ1bmMoKTtcclxuXHR9XHJcblxyXG5cdC8vIFNvbWUgYnJvd3NlcnMgcm91bmQgdGhlIGxpbmUtaGVpZ2h0LCBvdGhlcnMgZG9uJ3QuXHJcblx0Ly8gV2UgbmVlZCB0byB0ZXN0IGZvciBpdCB0byBwb3NpdGlvbiB0aGUgZWxlbWVudHMgcHJvcGVybHkuXHJcblx0dmFyIGlzTGluZUhlaWdodFJvdW5kZWQgPSAoZnVuY3Rpb24gKCkge1xyXG5cdFx0dmFyIHJlcztcclxuXHRcdHJldHVybiBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdGlmICh0eXBlb2YgcmVzID09PSAndW5kZWZpbmVkJykge1xyXG5cdFx0XHRcdHZhciBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcblx0XHRcdFx0ZC5zdHlsZS5mb250U2l6ZSA9ICcxM3B4JztcclxuXHRcdFx0XHRkLnN0eWxlLmxpbmVIZWlnaHQgPSAnMS41JztcclxuXHRcdFx0XHRkLnN0eWxlLnBhZGRpbmcgPSAnMCc7XHJcblx0XHRcdFx0ZC5zdHlsZS5ib3JkZXIgPSAnMCc7XHJcblx0XHRcdFx0ZC5pbm5lckhUTUwgPSAnJm5ic3A7PGJyIC8+Jm5ic3A7JztcclxuXHRcdFx0XHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGQpO1xyXG5cdFx0XHRcdC8vIEJyb3dzZXJzIHRoYXQgcm91bmQgdGhlIGxpbmUtaGVpZ2h0IHNob3VsZCBoYXZlIG9mZnNldEhlaWdodCA9PT0gMzhcclxuXHRcdFx0XHQvLyBUaGUgb3RoZXJzIHNob3VsZCBoYXZlIDM5LlxyXG5cdFx0XHRcdHJlcyA9IGQub2Zmc2V0SGVpZ2h0ID09PSAzODtcclxuXHRcdFx0XHRkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGQpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiByZXM7XHJcblx0XHR9O1xyXG5cdH0oKSk7XHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgdGhlIHRvcCBvZmZzZXQgb2YgdGhlIGNvbnRlbnQgYm94IG9mIHRoZSBnaXZlbiBwYXJlbnQgYW5kIHRoZSBjb250ZW50IGJveCBvZiBvbmUgb2YgaXRzIGNoaWxkcmVuLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcGFyZW50XHJcblx0ICogQHBhcmFtIHtIVE1MRWxlbWVudH0gY2hpbGRcclxuXHQgKi9cclxuXHRmdW5jdGlvbiBnZXRDb250ZW50Qm94VG9wT2Zmc2V0KHBhcmVudCwgY2hpbGQpIHtcclxuXHRcdHZhciBwYXJlbnRTdHlsZSA9IGdldENvbXB1dGVkU3R5bGUocGFyZW50KTtcclxuXHRcdHZhciBjaGlsZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShjaGlsZCk7XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBSZXR1cm5zIHRoZSBudW1lcmljIHZhbHVlIG9mIHRoZSBnaXZlbiBwaXhlbCB2YWx1ZS5cclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gcHhcclxuXHRcdCAqL1xyXG5cdFx0ZnVuY3Rpb24gcHhUb051bWJlcihweCkge1xyXG5cdFx0XHRyZXR1cm4gK3B4LnN1YnN0cigwLCBweC5sZW5ndGggLSAyKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gY2hpbGQub2Zmc2V0VG9wXHJcblx0XHRcdCsgcHhUb051bWJlcihjaGlsZFN0eWxlLmJvcmRlclRvcFdpZHRoKVxyXG5cdFx0XHQrIHB4VG9OdW1iZXIoY2hpbGRTdHlsZS5wYWRkaW5nVG9wKVxyXG5cdFx0XHQtIHB4VG9OdW1iZXIocGFyZW50U3R5bGUucGFkZGluZ1RvcCk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIExpbmUgSGlnaGxpZ2h0IHBsdWdpbiBpcyBhY3RpdmUgZm9yIHRoZSBnaXZlbiBlbGVtZW50LlxyXG5cdCAqXHJcblx0ICogSWYgdGhpcyBmdW5jdGlvbiByZXR1cm5zIGBmYWxzZWAsIGRvIG5vdCBjYWxsIGBoaWdobGlnaHRMaW5lc2AgZm9yIHRoZSBnaXZlbiBlbGVtZW50LlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtIVE1MRWxlbWVudCB8IG51bGwgfCB1bmRlZmluZWR9IHByZVxyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIGlzQWN0aXZlRm9yKHByZSkge1xyXG5cdFx0aWYgKCFwcmUgfHwgIS9wcmUvaS50ZXN0KHByZS5ub2RlTmFtZSkpIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChwcmUuaGFzQXR0cmlidXRlKCdkYXRhLWxpbmUnKSkge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAocHJlLmlkICYmIFByaXNtLnV0aWwuaXNBY3RpdmUocHJlLCBMSU5LQUJMRV9MSU5FX05VTUJFUlNfQ0xBU1MpKSB7XHJcblx0XHRcdC8vIFRlY2huaWNhbGx5LCB0aGUgbGluZSBudW1iZXJzIHBsdWdpbiBpcyBhbHNvIG5lY2Vzc2FyeSBidXQgdGhpcyBwbHVnaW4gZG9lc24ndCBjb250cm9sIHRoZSBjbGFzc2VzIG9mXHJcblx0XHRcdC8vIHRoZSBsaW5lIG51bWJlcnMgcGx1Z2luLCBzbyB3ZSBjYW4ndCBhc3N1bWUgdGhhdCB0aGV5IGFyZSBwcmVzZW50LlxyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG5cclxuXHR2YXIgc2Nyb2xsSW50b1ZpZXcgPSB0cnVlO1xyXG5cclxuXHRQcmlzbS5wbHVnaW5zLmxpbmVIaWdobGlnaHQgPSB7XHJcblx0XHQvKipcclxuXHRcdCAqIEhpZ2hsaWdodHMgdGhlIGxpbmVzIG9mIHRoZSBnaXZlbiBwcmUuXHJcblx0XHQgKlxyXG5cdFx0ICogVGhpcyBmdW5jdGlvbiBpcyBzcGxpdCBpbnRvIGEgRE9NIG1lYXN1cmluZyBhbmQgbXV0YXRlIHBoYXNlIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuXHJcblx0XHQgKiBUaGUgcmV0dXJuZWQgZnVuY3Rpb24gbXV0YXRlcyB0aGUgRE9NIHdoZW4gY2FsbGVkLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHByZVxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmcgfCBudWxsfSBbbGluZXNdXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gW2NsYXNzZXM9JyddXHJcblx0XHQgKiBAcmV0dXJucyB7KCkgPT4gdm9pZH1cclxuXHRcdCAqL1xyXG5cdFx0aGlnaGxpZ2h0TGluZXM6IGZ1bmN0aW9uIGhpZ2hsaWdodExpbmVzKHByZSwgbGluZXMsIGNsYXNzZXMpIHtcclxuXHRcdFx0bGluZXMgPSB0eXBlb2YgbGluZXMgPT09ICdzdHJpbmcnID8gbGluZXMgOiAocHJlLmdldEF0dHJpYnV0ZSgnZGF0YS1saW5lJykgfHwgJycpO1xyXG5cclxuXHRcdFx0dmFyIHJhbmdlcyA9IGxpbmVzLnJlcGxhY2UoL1xccysvZywgJycpLnNwbGl0KCcsJykuZmlsdGVyKEJvb2xlYW4pO1xyXG5cdFx0XHR2YXIgb2Zmc2V0ID0gK3ByZS5nZXRBdHRyaWJ1dGUoJ2RhdGEtbGluZS1vZmZzZXQnKSB8fCAwO1xyXG5cclxuXHRcdFx0dmFyIHBhcnNlTWV0aG9kID0gaXNMaW5lSGVpZ2h0Um91bmRlZCgpID8gcGFyc2VJbnQgOiBwYXJzZUZsb2F0O1xyXG5cdFx0XHR2YXIgY29kZUVsZW1lbnQgPSBwcmUucXVlcnlTZWxlY3RvcignY29kZScpO1xyXG5cdFx0XHR2YXIgbGluZUhlaWdodCA9IHBhcnNlTWV0aG9kKGdldENvbXB1dGVkU3R5bGUoY29kZUVsZW1lbnQpLmxpbmVIZWlnaHQpO1xyXG5cdFx0XHR2YXIgaGFzTGluZU51bWJlcnMgPSBQcmlzbS51dGlsLmlzQWN0aXZlKHByZSwgTElORV9OVU1CRVJTX0NMQVNTKTtcclxuXHRcdFx0dmFyIHBhcmVudEVsZW1lbnQgPSBoYXNMaW5lTnVtYmVycyA/IHByZSA6IGNvZGVFbGVtZW50IHx8IHByZTtcclxuXHRcdFx0dmFyIG11dGF0ZUFjdGlvbnMgPSAvKiogQHR5cGUgeygoKSA9PiB2b2lkKVtdfSAqLyAoW10pO1xyXG5cdFx0XHR2YXIgbGluZUJyZWFrTWF0Y2ggPSBjb2RlRWxlbWVudC50ZXh0Q29udGVudC5tYXRjaChORVdfTElORV9SRUdFWCk7XHJcblx0XHRcdHZhciBudW1iZXJPZkxpbmVzID0gbGluZUJyZWFrTWF0Y2g/IGxpbmVCcmVha01hdGNoLmxlbmd0aCArIDE6IDFcclxuXHJcblx0XHRcdC8qKlxyXG5cdFx0XHQgKiBUaGUgdG9wIG9mZnNldCBiZXR3ZWVuIHRoZSBjb250ZW50IGJveCBvZiB0aGUgPGNvZGU+IGVsZW1lbnQgYW5kIHRoZSBjb250ZW50IGJveCBvZiB0aGUgcGFyZW50IGVsZW1lbnQgb2ZcclxuXHRcdFx0ICogdGhlIGxpbmUgaGlnaGxpZ2h0IGVsZW1lbnQgKGVpdGhlciBgPHByZT5gIG9yIGA8Y29kZT5gKS5cclxuXHRcdFx0ICpcclxuXHRcdFx0ICogVGhpcyBvZmZzZXQgbWlnaHQgbm90IGJlIHplcm8gZm9yIHNvbWUgdGhlbWVzIHdoZXJlIHRoZSA8Y29kZT4gZWxlbWVudCBoYXMgYSB0b3AgbWFyZ2luLiBTb21lIHBsdWdpbnNcclxuXHRcdFx0ICogKG9yIHVzZXJzKSBtaWdodCBhbHNvIGFkZCBlbGVtZW50IGFib3ZlIHRoZSA8Y29kZT4gZWxlbWVudC4gQmVjYXVzZSB0aGUgbGluZSBoaWdobGlnaHQgaXMgYWxpZ25lZCByZWxhdGl2ZVxyXG5cdFx0XHQgKiB0byB0aGUgPHByZT4gZWxlbWVudCwgd2UgaGF2ZSB0byB0YWtlIHRoaXMgaW50byBhY2NvdW50LlxyXG5cdFx0XHQgKlxyXG5cdFx0XHQgKiBUaGlzIG9mZnNldCB3aWxsIGJlIDAgaWYgdGhlIHBhcmVudCBlbGVtZW50IG9mIHRoZSBsaW5lIGhpZ2hsaWdodCBlbGVtZW50IGlzIHRoZSBgPGNvZGU+YCBlbGVtZW50LlxyXG5cdFx0XHQgKi9cclxuXHRcdFx0dmFyIGNvZGVQcmVPZmZzZXQgPSAhY29kZUVsZW1lbnQgfHwgcGFyZW50RWxlbWVudCA9PSBjb2RlRWxlbWVudCA/IDAgOiBnZXRDb250ZW50Qm94VG9wT2Zmc2V0KHByZSwgY29kZUVsZW1lbnQpO1xyXG5cclxuXHRcdFx0cmFuZ2VzLmZvckVhY2goZnVuY3Rpb24gKGN1cnJlbnRSYW5nZSkge1xyXG5cdFx0XHRcdHZhciByYW5nZSA9IGN1cnJlbnRSYW5nZS5zcGxpdCgnLScpO1xyXG5cclxuXHRcdFx0XHR2YXIgc3RhcnQgPSArcmFuZ2VbMF07XHJcblx0XHRcdFx0dmFyIGVuZCA9ICtyYW5nZVsxXSB8fCBzdGFydDtcclxuXHRcdFx0XHRlbmQgPSBNYXRoLm1pbihudW1iZXJPZkxpbmVzLCBlbmQpO1xyXG5cclxuXHRcdFx0XHRpZiAoZW5kIDwgc3RhcnQpIHJldHVybiA7XHJcblxyXG5cdFx0XHRcdC8qKiBAdHlwZSB7SFRNTEVsZW1lbnR9ICovXHJcblx0XHRcdFx0dmFyIGxpbmUgPSBwcmUucXVlcnlTZWxlY3RvcignLmxpbmUtaGlnaGxpZ2h0W2RhdGEtcmFuZ2U9XCInICsgY3VycmVudFJhbmdlICsgJ1wiXScpIHx8IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG5cclxuXHRcdFx0XHRtdXRhdGVBY3Rpb25zLnB1c2goZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdFx0bGluZS5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcclxuXHRcdFx0XHRcdGxpbmUuc2V0QXR0cmlidXRlKCdkYXRhLXJhbmdlJywgY3VycmVudFJhbmdlKTtcclxuXHRcdFx0XHRcdGxpbmUuY2xhc3NOYW1lID0gKGNsYXNzZXMgfHwgJycpICsgJyBsaW5lLWhpZ2hsaWdodCc7XHJcblx0XHRcdFx0fSk7XHJcblxyXG5cdFx0XHRcdC8vIGlmIHRoZSBsaW5lLW51bWJlcnMgcGx1Z2luIGlzIGVuYWJsZWQsIHRoZW4gdGhlcmUgaXMgbm8gcmVhc29uIGZvciB0aGlzIHBsdWdpbiB0byBkaXNwbGF5IHRoZSBsaW5lIG51bWJlcnNcclxuXHRcdFx0XHRpZiAoaGFzTGluZU51bWJlcnMgJiYgUHJpc20ucGx1Z2lucy5saW5lTnVtYmVycykge1xyXG5cdFx0XHRcdFx0dmFyIHN0YXJ0Tm9kZSA9IFByaXNtLnBsdWdpbnMubGluZU51bWJlcnMuZ2V0TGluZShwcmUsIHN0YXJ0KTtcclxuXHRcdFx0XHRcdHZhciBlbmROb2RlID0gUHJpc20ucGx1Z2lucy5saW5lTnVtYmVycy5nZXRMaW5lKHByZSwgZW5kKTtcclxuXHJcblx0XHRcdFx0XHRpZiAoc3RhcnROb2RlKSB7XHJcblx0XHRcdFx0XHRcdHZhciB0b3AgPSBzdGFydE5vZGUub2Zmc2V0VG9wICsgY29kZVByZU9mZnNldCArICdweCc7XHJcblx0XHRcdFx0XHRcdG11dGF0ZUFjdGlvbnMucHVzaChmdW5jdGlvbiAoKSB7XHJcblx0XHRcdFx0XHRcdFx0bGluZS5zdHlsZS50b3AgPSB0b3A7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdGlmIChlbmROb2RlKSB7XHJcblx0XHRcdFx0XHRcdHZhciBoZWlnaHQgPSAoZW5kTm9kZS5vZmZzZXRUb3AgLSBzdGFydE5vZGUub2Zmc2V0VG9wKSArIGVuZE5vZGUub2Zmc2V0SGVpZ2h0ICsgJ3B4JztcclxuXHRcdFx0XHRcdFx0bXV0YXRlQWN0aW9ucy5wdXNoKGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRcdFx0XHRsaW5lLnN0eWxlLmhlaWdodCA9IGhlaWdodDtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0bXV0YXRlQWN0aW9ucy5wdXNoKGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRcdFx0bGluZS5zZXRBdHRyaWJ1dGUoJ2RhdGEtc3RhcnQnLCBTdHJpbmcoc3RhcnQpKTtcclxuXHJcblx0XHRcdFx0XHRcdGlmIChlbmQgPiBzdGFydCkge1xyXG5cdFx0XHRcdFx0XHRcdGxpbmUuc2V0QXR0cmlidXRlKCdkYXRhLWVuZCcsIFN0cmluZyhlbmQpKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0bGluZS5zdHlsZS50b3AgPSAoc3RhcnQgLSBvZmZzZXQgLSAxKSAqIGxpbmVIZWlnaHQgKyBjb2RlUHJlT2Zmc2V0ICsgJ3B4JztcclxuXHJcblx0XHRcdFx0XHRcdGxpbmUudGV4dENvbnRlbnQgPSBuZXcgQXJyYXkoZW5kIC0gc3RhcnQgKyAyKS5qb2luKCcgXFxuJyk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdG11dGF0ZUFjdGlvbnMucHVzaChmdW5jdGlvbiAoKSB7XHJcblx0XHRcdFx0XHRsaW5lLnN0eWxlLndpZHRoID0gcHJlLnNjcm9sbFdpZHRoICsgJ3B4JztcclxuXHRcdFx0XHR9KTtcclxuXHJcblx0XHRcdFx0bXV0YXRlQWN0aW9ucy5wdXNoKGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRcdC8vIGFsbG93IHRoaXMgdG8gcGxheSBuaWNlbHkgd2l0aCB0aGUgbGluZS1udW1iZXJzIHBsdWdpblxyXG5cdFx0XHRcdFx0Ly8gbmVlZCB0byBhdHRhY2sgdG8gcHJlIGFzIHdoZW4gbGluZS1udW1iZXJzIGlzIGVuYWJsZWQsIHRoZSBjb2RlIHRhZyBpcyByZWxhdGl2ZWx5IHdoaWNoIHNjcmV3cyB1cCB0aGUgcG9zaXRpb25pbmdcclxuXHRcdFx0XHRcdHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQobGluZSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0dmFyIGlkID0gcHJlLmlkO1xyXG5cdFx0XHRpZiAoaGFzTGluZU51bWJlcnMgJiYgUHJpc20udXRpbC5pc0FjdGl2ZShwcmUsIExJTktBQkxFX0xJTkVfTlVNQkVSU19DTEFTUykgJiYgaWQpIHtcclxuXHRcdFx0XHQvLyBUaGlzIGltcGxlbWVudHMgbGlua2FibGUgbGluZSBudW1iZXJzLiBMaW5rYWJsZSBsaW5lIG51bWJlcnMgdXNlIExpbmUgSGlnaGxpZ2h0IHRvIGNyZWF0ZSBhIGxpbmsgdG8gYVxyXG5cdFx0XHRcdC8vIHNwZWNpZmljIGxpbmUuIEZvciB0aGlzIHRvIHdvcmssIHRoZSBwcmUgZWxlbWVudCBoYXMgdG86XHJcblx0XHRcdFx0Ly8gIDEpIGhhdmUgbGluZSBudW1iZXJzLFxyXG5cdFx0XHRcdC8vICAyKSBoYXZlIHRoZSBgbGlua2FibGUtbGluZS1udW1iZXJzYCBjbGFzcyBvciBhbiBhc2NlbmRhbnQgdGhhdCBoYXMgdGhhdCBjbGFzcywgYW5kXHJcblx0XHRcdFx0Ly8gIDMpIGhhdmUgYW4gaWQuXHJcblxyXG5cdFx0XHRcdGlmICghaGFzQ2xhc3MocHJlLCBMSU5LQUJMRV9MSU5FX05VTUJFUlNfQ0xBU1MpKSB7XHJcblx0XHRcdFx0XHQvLyBhZGQgY2xhc3MgdG8gcHJlXHJcblx0XHRcdFx0XHRtdXRhdGVBY3Rpb25zLnB1c2goZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdFx0XHRwcmUuY2xhc3NMaXN0LmFkZChMSU5LQUJMRV9MSU5FX05VTUJFUlNfQ0xBU1MpO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHR2YXIgc3RhcnQgPSBwYXJzZUludChwcmUuZ2V0QXR0cmlidXRlKCdkYXRhLXN0YXJ0JykgfHwgJzEnKTtcclxuXHJcblx0XHRcdFx0Ly8gaXRlcmF0ZSBhbGwgbGluZSBudW1iZXIgc3BhbnNcclxuXHRcdFx0XHQkJCgnLmxpbmUtbnVtYmVycy1yb3dzID4gc3BhbicsIHByZSkuZm9yRWFjaChmdW5jdGlvbiAobGluZVNwYW4sIGkpIHtcclxuXHRcdFx0XHRcdHZhciBsaW5lTnVtYmVyID0gaSArIHN0YXJ0O1xyXG5cdFx0XHRcdFx0bGluZVNwYW4ub25jbGljayA9IGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRcdFx0dmFyIGhhc2ggPSBpZCArICcuJyArIGxpbmVOdW1iZXI7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyB0aGlzIHdpbGwgcHJldmVudCBzY3JvbGxpbmcgc2luY2UgdGhlIHNwYW4gaXMgb2J2aW91c2x5IGluIHZpZXdcclxuXHRcdFx0XHRcdFx0c2Nyb2xsSW50b1ZpZXcgPSBmYWxzZTtcclxuXHRcdFx0XHRcdFx0bG9jYXRpb24uaGFzaCA9IGhhc2g7XHJcblx0XHRcdFx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdFx0XHRcdHNjcm9sbEludG9WaWV3ID0gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0fSwgMSk7XHJcblx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdG11dGF0ZUFjdGlvbnMuZm9yRWFjaChjYWxsRnVuY3Rpb24pO1xyXG5cdFx0XHR9O1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cclxuXHRmdW5jdGlvbiBhcHBseUhhc2goKSB7XHJcblx0XHR2YXIgaGFzaCA9IGxvY2F0aW9uLmhhc2guc2xpY2UoMSk7XHJcblxyXG5cdFx0Ly8gUmVtb3ZlIHByZS1leGlzdGluZyB0ZW1wb3JhcnkgbGluZXNcclxuXHRcdCQkKCcudGVtcG9yYXJ5LmxpbmUtaGlnaGxpZ2h0JykuZm9yRWFjaChmdW5jdGlvbiAobGluZSkge1xyXG5cdFx0XHRsaW5lLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGluZSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHR2YXIgcmFuZ2UgPSAoaGFzaC5tYXRjaCgvXFwuKFtcXGQsLV0rKSQvKSB8fCBbLCAnJ10pWzFdO1xyXG5cclxuXHRcdGlmICghcmFuZ2UgfHwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaGFzaCkpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBpZCA9IGhhc2guc2xpY2UoMCwgaGFzaC5sYXN0SW5kZXhPZignLicpKTtcclxuXHRcdHZhciBwcmUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XHJcblxyXG5cdFx0aWYgKCFwcmUpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICghcHJlLmhhc0F0dHJpYnV0ZSgnZGF0YS1saW5lJykpIHtcclxuXHRcdFx0cHJlLnNldEF0dHJpYnV0ZSgnZGF0YS1saW5lJywgJycpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBtdXRhdGVEb20gPSBQcmlzbS5wbHVnaW5zLmxpbmVIaWdobGlnaHQuaGlnaGxpZ2h0TGluZXMocHJlLCByYW5nZSwgJ3RlbXBvcmFyeSAnKTtcclxuXHRcdG11dGF0ZURvbSgpO1xyXG5cclxuXHRcdGlmIChzY3JvbGxJbnRvVmlldykge1xyXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcudGVtcG9yYXJ5LmxpbmUtaGlnaGxpZ2h0Jykuc2Nyb2xsSW50b1ZpZXcoKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHZhciBmYWtlVGltZXIgPSAwOyAvLyBIYWNrIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgdGltZXMgYXBwbHlIYXNoKCkgcnVuc1xyXG5cclxuXHRQcmlzbS5ob29rcy5hZGQoJ2JlZm9yZS1zYW5pdHktY2hlY2snLCBmdW5jdGlvbiAoZW52KSB7XHJcblx0XHR2YXIgcHJlID0gZW52LmVsZW1lbnQucGFyZW50RWxlbWVudDtcclxuXHRcdGlmICghaXNBY3RpdmVGb3IocHJlKSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0LypcclxuXHRcdCAqIENsZWFudXAgZm9yIG90aGVyIHBsdWdpbnMgKGUuZy4gYXV0b2xvYWRlcikuXHJcblx0XHQgKlxyXG5cdFx0ICogU29tZXRpbWVzIDxjb2RlPiBibG9ja3MgYXJlIGhpZ2hsaWdodGVkIG11bHRpcGxlIHRpbWVzLiBJdCBpcyBuZWNlc3NhcnlcclxuXHRcdCAqIHRvIGNsZWFudXAgYW55IGxlZnQtb3ZlciB0YWdzLCBiZWNhdXNlIHRoZSB3aGl0ZXNwYWNlIGluc2lkZSBvZiB0aGUgPGRpdj5cclxuXHRcdCAqIHRhZ3MgY2hhbmdlIHRoZSBjb250ZW50IG9mIHRoZSA8Y29kZT4gdGFnLlxyXG5cdFx0ICovXHJcblx0XHR2YXIgbnVtID0gMDtcclxuXHRcdCQkKCcubGluZS1oaWdobGlnaHQnLCBwcmUpLmZvckVhY2goZnVuY3Rpb24gKGxpbmUpIHtcclxuXHRcdFx0bnVtICs9IGxpbmUudGV4dENvbnRlbnQubGVuZ3RoO1xyXG5cdFx0XHRsaW5lLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGluZSk7XHJcblx0XHR9KTtcclxuXHRcdC8vIFJlbW92ZSBleHRyYSB3aGl0ZXNwYWNlXHJcblx0XHRpZiAobnVtICYmIC9eKD86IFxcbikrJC8udGVzdChlbnYuY29kZS5zbGljZSgtbnVtKSkpIHtcclxuXHRcdFx0ZW52LmNvZGUgPSBlbnYuY29kZS5zbGljZSgwLCAtbnVtKTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHJcblx0UHJpc20uaG9va3MuYWRkKCdjb21wbGV0ZScsIGZ1bmN0aW9uIGNvbXBsZXRlSG9vayhlbnYpIHtcclxuXHRcdHZhciBwcmUgPSBlbnYuZWxlbWVudC5wYXJlbnRFbGVtZW50O1xyXG5cdFx0aWYgKCFpc0FjdGl2ZUZvcihwcmUpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRjbGVhclRpbWVvdXQoZmFrZVRpbWVyKTtcclxuXHJcblx0XHR2YXIgaGFzTGluZU51bWJlcnMgPSBQcmlzbS5wbHVnaW5zLmxpbmVOdW1iZXJzO1xyXG5cdFx0dmFyIGlzTGluZU51bWJlcnNMb2FkZWQgPSBlbnYucGx1Z2lucyAmJiBlbnYucGx1Z2lucy5saW5lTnVtYmVycztcclxuXHJcblx0XHRpZiAoaGFzQ2xhc3MocHJlLCBMSU5FX05VTUJFUlNfQ0xBU1MpICYmIGhhc0xpbmVOdW1iZXJzICYmICFpc0xpbmVOdW1iZXJzTG9hZGVkKSB7XHJcblx0XHRcdFByaXNtLmhvb2tzLmFkZCgnbGluZS1udW1iZXJzJywgY29tcGxldGVIb29rKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHZhciBtdXRhdGVEb20gPSBQcmlzbS5wbHVnaW5zLmxpbmVIaWdobGlnaHQuaGlnaGxpZ2h0TGluZXMocHJlKTtcclxuXHRcdFx0bXV0YXRlRG9tKCk7XHJcblx0XHRcdGZha2VUaW1lciA9IHNldFRpbWVvdXQoYXBwbHlIYXNoLCAxKTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHJcblx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2hhc2hjaGFuZ2UnLCBhcHBseUhhc2gpO1xyXG5cdC8vIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBmdW5jdGlvbiAoKSB7XHJcblx0Ly8gXHR2YXIgYWN0aW9ucyA9ICQkKCdwcmUnKVxyXG5cdC8vIFx0XHQuZmlsdGVyKGlzQWN0aXZlRm9yKVxyXG5cdC8vIFx0XHQubWFwKGZ1bmN0aW9uIChwcmUpIHtcclxuXHQvLyBcdFx0XHRyZXR1cm4gUHJpc20ucGx1Z2lucy5saW5lSGlnaGxpZ2h0LmhpZ2hsaWdodExpbmVzKHByZSk7XHJcblx0Ly8gXHRcdH0pO1xyXG5cdC8vIFx0YWN0aW9ucy5mb3JFYWNoKGNhbGxGdW5jdGlvbik7XHJcblx0Ly8gfSk7XHJcblxyXG59XHJcbiIsICJpbXBvcnQgeyBWaWV3UGx1Z2luLCBWaWV3VXBkYXRlLCBFZGl0b3JWaWV3LCBEZWNvcmF0aW9uU2V0LCBEZWNvcmF0aW9uLCBXaWRnZXRUeXBlIH0gZnJvbSAnQGNvZGVtaXJyb3IvdmlldydcclxuLy8gQHRzLWlnbm9yZVxyXG5pbXBvcnQgeyBSYW5nZVNldEJ1aWxkZXIgfSBmcm9tICdAY29kZW1pcnJvci9zdGF0ZSdcclxuLy8gQHRzLWlnbm9yZVxyXG5pbXBvcnQgeyBzeW50YXhUcmVlLCBsaW5lQ2xhc3NOb2RlUHJvcCB9IGZyb20gJ0Bjb2RlbWlycm9yL2xhbmd1YWdlJ1xyXG4vLyBpbXBvcnQgeyBsaW5lQ2xhc3NOb2RlUHJvcCB9IGZyb20gJ0Bjb2RlbWlycm9yL3N0cmVhbS1wYXJzZXInXHJcbmltcG9ydCB7IGJyYWNlU3Vycm91bmRpbmdSZWdleCwgcGFyYW1SZWdleCB9IGZyb20gJy4vdXRpbCdcclxuXHJcbmludGVyZmFjZSBDb2RlYmxvY2tJbmZvIHtcclxuICBzaG93TGluZU51bWJlcnM6IGJvb2xlYW47XHJcbiAgaGlnaGxpZ2h0TGluZXM6IG51bWJlcltdIHwgbnVsbDtcclxufVxyXG5cclxuY2xhc3MgTGluZU51bWJlcldpZGdldCBleHRlbmRzIFdpZGdldFR5cGUge1xyXG4gIGlkeDogbnVtYmVyO1xyXG5cclxuICBjb25zdHJ1Y3RvcihpZHg6IG51bWJlcikge1xyXG4gICAgc3VwZXIoKTtcclxuICAgIHRoaXMuaWR4ID0gaWR4XHJcbiAgfVxyXG5cclxuICB0b0RPTSgpIHtcclxuICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xyXG4gICAgZWwuY2xhc3NOYW1lID0gJ2xpdmUtcHJldmlldy1jb2RlYmxvY2stbGluZS1udW1zJztcclxuICAgIGVsLnRleHRDb250ZW50ID0gJycgKyB0aGlzLmlkeDtcclxuICAgIHJldHVybiBlbDtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBsaXZlUHJldmlld0NNNkV4dGVuc2lvbiA9IFZpZXdQbHVnaW4uZnJvbUNsYXNzKGNsYXNzIHtcclxuICBkZWNvcmF0aW9uczogRGVjb3JhdGlvblNldFxyXG5cclxuICBjb25zdHJ1Y3Rvcih2aWV3OiBFZGl0b3JWaWV3KSB7XHJcbiAgICB0aGlzLmRlY29yYXRpb25zID0gdGhpcy5idWlsZERlY29yYXRpb25zKHZpZXcpO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlKHVwZGF0ZTogVmlld1VwZGF0ZSkge1xyXG4gICAgaWYgKHVwZGF0ZS5kb2NDaGFuZ2VkIHx8IHVwZGF0ZS52aWV3cG9ydENoYW5nZWQpIHRoaXMuZGVjb3JhdGlvbnMgPSB0aGlzLmJ1aWxkRGVjb3JhdGlvbnModXBkYXRlLnZpZXcpO1xyXG4gIH1cclxuXHJcbiAgZGVzdG9yeSgpIHt9XHJcblxyXG4gIGJ1aWxkRGVjb3JhdGlvbnModmlldzogRWRpdG9yVmlldykge1xyXG4gICAgY29uc3QgYnVpbGRlciA9IG5ldyBSYW5nZVNldEJ1aWxkZXI8RGVjb3JhdGlvbj4oKTtcclxuICAgIGNvbnN0IGNvZGVibG9ja0luZm86IENvZGVibG9ja0luZm8gPSB7XHJcbiAgICAgIHNob3dMaW5lTnVtYmVyczogZmFsc2UsXHJcbiAgICAgIGhpZ2hsaWdodExpbmVzOiBudWxsLFxyXG4gICAgfVxyXG4gICAgbGV0IHN0YXJ0TGluZU51bTogbnVtYmVyO1xyXG5cclxuICAgIGZvciAoY29uc3Qge2Zyb20sIHRvfSBvZiB2aWV3LnZpc2libGVSYW5nZXMpIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjb25zdCB0cmVlID0gc3ludGF4VHJlZSh2aWV3LnN0YXRlKVxyXG5cclxuICAgICAgICB0cmVlLml0ZXJhdGUoe1xyXG4gICAgICAgICAgZnJvbSwgdG8sXHJcbiAgICAgICAgICAvLyBAdHMtaWdub3JlXHJcbiAgICAgICAgICBlbnRlcjogKHt0eXBlLCBmcm9tLCB0b30pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgbGluZUNsYXNzZXMgPSB0eXBlLnByb3AobGluZUNsYXNzTm9kZVByb3ApXHJcblxyXG4gICAgICAgICAgICBpZiAoIWxpbmVDbGFzc2VzKSByZXR1cm4gO1xyXG4gICAgICAgICAgICBjb25zdCBjbGFzc2VzID0gbmV3IFNldChsaW5lQ2xhc3Nlcy5zcGxpdCgnICcpKTtcclxuICAgICAgICAgICAgY29uc3QgaXNDb2RlYmxvY2tCZWdpbiA9IGNsYXNzZXMuaGFzKCdIeXBlck1ELWNvZGVibG9jay1iZWdpbicpO1xyXG4gICAgICAgICAgICBjb25zdCBpc0NvZGVibG9ja0xpbmUgPSBcclxuICAgICAgICAgICAgICBjbGFzc2VzLmhhcygnSHlwZXJNRC1jb2RlYmxvY2stYmcnKSBcclxuICAgICAgICAgICAgICAmJiAhY2xhc3Nlcy5oYXMoJ0h5cGVyTUQtY29kZWJsb2NrLWJlZ2luJylcclxuICAgICAgICAgICAgICAmJiAhY2xhc3Nlcy5oYXMoJ0h5cGVyTUQtY29kZWJsb2NrLWVuZCcpO1xyXG5cclxuICAgICAgICAgICAgLy8gcmVzZXQgZGF0YSB3aGVuIGZvdW5kIGNvZGVibG9jayBiZWdpbiBsaW5lLlxyXG4gICAgICAgICAgICBpZiAoaXNDb2RlYmxvY2tCZWdpbikge1xyXG4gICAgICAgICAgICAgIGNvbnN0IHN0YXJ0TGluZSA9IHZpZXcuc3RhdGUuZG9jLmxpbmVBdChmcm9tKTtcclxuICAgICAgICAgICAgICBjb25zdCBjb2RlYmxvY2tQYXJhbXMgPSBzdGFydExpbmUudGV4dC5tYXRjaChwYXJhbVJlZ2V4KS5zbGljZSgxKTtcclxuICAgICAgICAgICAgICBjb25zdCBoaWdobGlnaHRQYXJhbSA9IGNvZGVibG9ja1BhcmFtcy5maW5kKChwYXJhbSkgPT4gYnJhY2VTdXJyb3VuZGluZ1JlZ2V4LnRlc3QocGFyYW0pKT8uc2xpY2UoMSwgLTEpO1xyXG5cclxuICAgICAgICAgICAgICBzdGFydExpbmVOdW0gPSBzdGFydExpbmUubnVtYmVyO1xyXG4gICAgICAgICAgICAgIGNvZGVibG9ja0luZm8uc2hvd0xpbmVOdW1iZXJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgY29kZWJsb2NrSW5mby5oaWdobGlnaHRMaW5lcyA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICAgIGlmIChjb2RlYmxvY2tQYXJhbXMuaW5jbHVkZXMoJ251bXMnKSkgY29kZWJsb2NrSW5mby5zaG93TGluZU51bWJlcnMgPSB0cnVlO1xyXG4gICAgICAgICAgICAgIGlmIChoaWdobGlnaHRQYXJhbSkgY29kZWJsb2NrSW5mby5oaWdobGlnaHRMaW5lcyA9IGhpZ2hsaWdodFBhcmFtLnJlcGxhY2UoJyAnLCAnJykuc3BsaXQoJywnKS5mbGF0TWFwKChsaW5lKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIStsaW5lKSB7XHJcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICBjb25zdCBbc3RhcnQsIGVuZF0gPSBsaW5lLnNwbGl0KCctJyk7XHJcbiAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSArc3RhcnQ7IGkgPD0gK2VuZDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzLnB1c2goaSk7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgIHJldHVybiByZXM7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFsrbGluZV07XHJcbiAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghaXNDb2RlYmxvY2tMaW5lKSByZXR1cm4gO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY29uc3QgY3VycmVudExpbmVOdW0gPSB2aWV3LnN0YXRlLmRvYy5saW5lQXQoZnJvbSkubnVtYmVyO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNvZGVibG9ja0luZm8uc2hvd0xpbmVOdW1iZXJzKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgZGVjbyA9IERlY29yYXRpb24ud2lkZ2V0KHtcclxuICAgICAgICAgICAgICAgIHdpZGdldDogbmV3IExpbmVOdW1iZXJXaWRnZXQoY3VycmVudExpbmVOdW0gLSBzdGFydExpbmVOdW0pLFxyXG4gICAgICAgICAgICAgICAgc2lkZTogLTEwMDAwXHJcbiAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgYnVpbGRlci5hZGQoZnJvbSwgZnJvbSwgZGVjbyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChjb2RlYmxvY2tJbmZvLmhpZ2hsaWdodExpbmVzKSB7XHJcbiAgICAgICAgICAgICAgaWYgKGNvZGVibG9ja0luZm8uaGlnaGxpZ2h0TGluZXMuaW5jbHVkZXMoY3VycmVudExpbmVOdW0gLSBzdGFydExpbmVOdW0pKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBsaW5lID0gdmlldy5zdGF0ZS5kb2MubGluZUF0KGZyb20pO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGVjbyA9IERlY29yYXRpb24ubGluZSh7XHJcbiAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtjbGFzczogJ2xpdmUtcHJldmlldy1jb2RlYmxvY2staGlnaGxpZ2h0J31cclxuICAgICAgICAgICAgICAgIH0pXHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxyXG4gICAgICAgICAgICAgICAgaWYgKGJ1aWxkZXIubGFzdD8uc3RhcnRTaWRlKSB7XHJcbiAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcclxuICAgICAgICAgICAgICAgICAgZGVjby5zdGFydFNpZGUgPSBidWlsZGVyLmxhc3Quc3RhcnRTaWRlO1xyXG4gICAgICAgICAgICAgICAgICBkZWNvLmVuZFNpZGUgPSBkZWNvLnN0YXJ0U2lkZVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGJ1aWxkZXIuYWRkKGxpbmUuZnJvbSwgbGluZS5mcm9tLCBkZWNvKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKGVycm9yKVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGJ1aWxkZXIuZmluaXNoKCk7XHJcbiAgfVxyXG59LCBcclxue1xyXG4gIGRlY29yYXRpb25zOiB2ID0+IHYuZGVjb3JhdGlvbnNcclxufSkiXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBLHVCQUF1Qjs7O0FDQXZCLHVCQUtPOzs7QUNMQSxJQUFNLGFBQWE7QUFDbkIsSUFBTSx3QkFBd0I7OztBQ0RyQyxzQkFBMEI7OztBQ0FuQixnQ0FBaUMsT0FBTztBQUU5QyxNQUFJLE9BQU8sVUFBVSxlQUFlLE9BQU8sYUFBYSxhQUFhO0FBQ3BFO0FBQUE7QUFRRCxNQUFJLGNBQWM7QUFPbEIsTUFBSSxlQUFlO0FBTW5CLE1BQUksU0FBUyxNQUFNLFFBQVEsY0FBYztBQUFBLElBUXhDLFNBQVMsU0FBVSxTQUFTLFFBQVE7QUFDbkMsVUFBSSxRQUFRLFlBQVksU0FBUyxDQUFDLFFBQVEsVUFBVSxTQUFTLGNBQWM7QUFDMUU7QUFBQTtBQUdELFVBQUksaUJBQWlCLFFBQVEsY0FBYztBQUMzQyxVQUFJLENBQUMsZ0JBQWdCO0FBQ3BCO0FBQUE7QUFFRCxVQUFJLGtCQUFrQixTQUFTLFFBQVEsYUFBYSxlQUFlLE9BQU87QUFDMUUsVUFBSSxnQkFBZ0Isa0JBQW1CLGdCQUFlLFNBQVMsU0FBUztBQUV4RSxVQUFJLFNBQVMsaUJBQWlCO0FBQzdCLGlCQUFTO0FBQUE7QUFFVixVQUFJLFNBQVMsZUFBZTtBQUMzQixpQkFBUztBQUFBO0FBR1YsVUFBSSxZQUFZLFNBQVM7QUFFekIsYUFBTyxlQUFlLFNBQVM7QUFBQTtBQUFBLElBV2hDLFFBQVEsU0FBVSxTQUFTO0FBQzFCLHFCQUFlLENBQUM7QUFBQTtBQUFBLElBYWpCLDRCQUE0QjtBQUFBO0FBUTdCLDBCQUF3QixVQUFVO0FBQ2pDLGVBQVcsU0FBUyxPQUFPLFNBQVUsR0FBRztBQUN2QyxVQUFJLGFBQWEsVUFBVTtBQUMzQixVQUFJLGFBQWEsV0FBVztBQUM1QixhQUFPLGVBQWUsY0FBYyxlQUFlO0FBQUE7QUFHcEQsUUFBSSxTQUFTLFVBQVUsR0FBRztBQUN6QjtBQUFBO0FBR0QsUUFBSSxRQUFRLFNBQVMsSUFBSSxTQUFVLFNBQVM7QUFDM0MsVUFBSSxjQUFjLFFBQVEsY0FBYztBQUN4QyxVQUFJLHFCQUFxQixRQUFRLGNBQWM7QUFDL0MsVUFBSSxDQUFDLGVBQWUsQ0FBQyxvQkFBb0I7QUFDeEMsZUFBTztBQUFBO0FBSVIsVUFBSSxrQkFBa0IsUUFBUSxjQUFjO0FBQzVDLFVBQUksWUFBWSxZQUFZLFlBQVksTUFBTTtBQUU5QyxVQUFJLENBQUMsaUJBQWlCO0FBQ3JCLDBCQUFrQixTQUFTLGNBQWM7QUFDekMsd0JBQWdCLFlBQVk7QUFFNUIsb0JBQVksWUFBWTtBQUFBO0FBR3pCLHNCQUFnQixZQUFZO0FBQzVCLHNCQUFnQixNQUFNLFVBQVU7QUFFaEMsVUFBSSxpQkFBaUIsZ0JBQWdCLHdCQUF3QjtBQUM3RCxzQkFBZ0IsWUFBWTtBQUU1QixhQUFPO0FBQUEsUUFDTjtBQUFBLFFBQ0EsT0FBTztBQUFBLFFBQ1AsYUFBYTtBQUFBLFFBQ2I7QUFBQSxRQUNBLE9BQU87QUFBQTtBQUFBLE9BRU4sT0FBTztBQUVWLFVBQU0sUUFBUSxTQUFVLE1BQU07QUFDN0IsVUFBSSxrQkFBa0IsS0FBSztBQUMzQixVQUFJLFFBQVEsS0FBSztBQUNqQixVQUFJLGNBQWMsS0FBSztBQUN2QixVQUFJLGlCQUFpQixLQUFLO0FBRTFCLGtCQUFZLE1BQU0sU0FBUyxLQUFLO0FBQ2hDLFlBQU0sUUFBUSxTQUFVLE1BQU0sT0FBTztBQUNwQyxZQUFJLFFBQVEsS0FBSyxTQUFTLEdBQUc7QUFDNUIsY0FBSSxJQUFJLGdCQUFnQixZQUFZLFNBQVMsY0FBYztBQUMzRCxZQUFFLE1BQU0sVUFBVTtBQUNsQixZQUFFLGNBQWM7QUFBQSxlQUNWO0FBQ04sc0JBQVksU0FBUztBQUFBO0FBQUE7QUFBQTtBQUt4QixVQUFNLFFBQVEsU0FBVSxNQUFNO0FBQzdCLFVBQUksa0JBQWtCLEtBQUs7QUFDM0IsVUFBSSxjQUFjLEtBQUs7QUFFdkIsVUFBSSxhQUFhO0FBQ2pCLGVBQVMsSUFBSSxHQUFHLElBQUksWUFBWSxRQUFRLEtBQUs7QUFDNUMsWUFBSSxZQUFZLE9BQU8sUUFBVztBQUNqQyxzQkFBWSxLQUFLLGdCQUFnQixTQUFTLGNBQWMsd0JBQXdCO0FBQUE7QUFBQTtBQUFBO0FBS25GLFVBQU0sUUFBUSxTQUFVLE1BQU07QUFDN0IsVUFBSSxrQkFBa0IsS0FBSztBQUMzQixVQUFJLFVBQVUsS0FBSyxRQUFRLGNBQWM7QUFFekMsc0JBQWdCLE1BQU0sVUFBVTtBQUNoQyxzQkFBZ0IsWUFBWTtBQUU1QixXQUFLLFlBQVksUUFBUSxTQUFVLFFBQVEsWUFBWTtBQUN0RCxnQkFBUSxTQUFTLFlBQVksTUFBTSxTQUFTLFNBQVM7QUFBQTtBQUFBO0FBQUE7QUFVeEQscUJBQW1CLFNBQVM7QUFDM0IsUUFBSSxDQUFDLFNBQVM7QUFDYixhQUFPO0FBQUE7QUFHUixXQUFPLE9BQU8sbUJBQW1CLGlCQUFpQixXQUFZLFFBQVEsZ0JBQWdCO0FBQUE7QUFhdkYsUUFBTSxNQUFNLElBQUksWUFBWSxTQUFVLEtBQUs7QUFDMUMsUUFBSSxDQUFDLElBQUksTUFBTTtBQUNkO0FBQUE7QUFHRCxRQUFJLE9BQStCLElBQUk7QUFDdkMsUUFBSSxNQUFrQyxLQUFLO0FBRzNDLFFBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxLQUFLLElBQUksV0FBVztBQUN2QztBQUFBO0FBSUQsUUFBSSxLQUFLLGNBQWMsdUJBQXVCO0FBQzdDO0FBQUE7QUFJRCxRQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsTUFBTSxjQUFjO0FBQzVDO0FBQUE7QUFJRCxTQUFLLFVBQVUsT0FBTztBQUV0QixRQUFJLFVBQVUsSUFBSTtBQUVsQixRQUFJLFFBQVEsSUFBSSxLQUFLLE1BQU07QUFDM0IsUUFBSSxXQUFXLFFBQVEsTUFBTSxTQUFTLElBQUk7QUFDMUMsUUFBSTtBQUVKLFFBQUksUUFBUSxJQUFJLE1BQU0sV0FBVyxHQUFHLEtBQUs7QUFFekMseUJBQXFCLFNBQVMsY0FBYztBQUM1Qyx1QkFBbUIsYUFBYSxlQUFlO0FBQy9DLHVCQUFtQixZQUFZO0FBQy9CLHVCQUFtQixZQUFZO0FBRS9CLFFBQUksSUFBSSxhQUFhLGVBQWU7QUFDbkMsVUFBSSxNQUFNLGVBQWUsZ0JBQWlCLFVBQVMsSUFBSSxhQUFhLGVBQWUsTUFBTTtBQUFBO0FBRzFGLFFBQUksUUFBUSxZQUFZO0FBRXhCLG1CQUFlLENBQUM7QUFFaEIsVUFBTSxNQUFNLElBQUksZ0JBQWdCO0FBQUE7QUFHakMsUUFBTSxNQUFNLElBQUksZ0JBQWdCLFNBQVUsS0FBSztBQUM5QyxRQUFJLFVBQVUsSUFBSSxXQUFXO0FBQzdCLFFBQUksUUFBUSxjQUFjO0FBQUE7QUFBQTs7O0FDeFByQixtQ0FBb0MsT0FBTztBQUVqRCxNQUFJLE9BQU8sVUFBVSxlQUFlLE9BQU8sYUFBYSxlQUFlLENBQUMsU0FBUyxlQUFlO0FBQy9GO0FBQUE7QUFHRCxNQUFJLHFCQUFxQjtBQUN6QixNQUFJLDhCQUE4QjtBQUNsQyxNQUFJLGlCQUFpQjtBQU9yQixjQUFZLFVBQVUsV0FBVztBQUNoQyxXQUFPLE1BQU0sVUFBVSxNQUFNLEtBQU0sY0FBYSxVQUFVLGlCQUFpQjtBQUFBO0FBVTVFLG9CQUFrQixTQUFTLFdBQVc7QUFDckMsV0FBTyxRQUFRLFVBQVUsU0FBUztBQUFBO0FBU25DLHdCQUFzQixNQUFNO0FBQzNCO0FBQUE7QUFLRCxNQUFJLHNCQUF1QixXQUFZO0FBQ3RDLFFBQUk7QUFDSixXQUFPLFdBQVk7QUFDbEIsVUFBSSxPQUFPLFFBQVEsYUFBYTtBQUMvQixZQUFJLElBQUksU0FBUyxjQUFjO0FBQy9CLFVBQUUsTUFBTSxXQUFXO0FBQ25CLFVBQUUsTUFBTSxhQUFhO0FBQ3JCLFVBQUUsTUFBTSxVQUFVO0FBQ2xCLFVBQUUsTUFBTSxTQUFTO0FBQ2pCLFVBQUUsWUFBWTtBQUNkLGlCQUFTLEtBQUssWUFBWTtBQUcxQixjQUFNLEVBQUUsaUJBQWlCO0FBQ3pCLGlCQUFTLEtBQUssWUFBWTtBQUFBO0FBRTNCLGFBQU87QUFBQTtBQUFBO0FBVVQsa0NBQWdDLFFBQVEsT0FBTztBQUM5QyxRQUFJLGNBQWMsaUJBQWlCO0FBQ25DLFFBQUksYUFBYSxpQkFBaUI7QUFPbEMsd0JBQW9CLElBQUk7QUFDdkIsYUFBTyxDQUFDLEdBQUcsT0FBTyxHQUFHLEdBQUcsU0FBUztBQUFBO0FBR2xDLFdBQU8sTUFBTSxZQUNWLFdBQVcsV0FBVyxrQkFDdEIsV0FBVyxXQUFXLGNBQ3RCLFdBQVcsWUFBWTtBQUFBO0FBVzNCLHVCQUFxQixLQUFLO0FBQ3pCLFFBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxLQUFLLElBQUksV0FBVztBQUN2QyxhQUFPO0FBQUE7QUFHUixRQUFJLElBQUksYUFBYSxjQUFjO0FBQ2xDLGFBQU87QUFBQTtBQUdSLFFBQUksSUFBSSxNQUFNLE1BQU0sS0FBSyxTQUFTLEtBQUssOEJBQThCO0FBR3BFLGFBQU87QUFBQTtBQUdSLFdBQU87QUFBQTtBQUdSLE1BQUksaUJBQWlCO0FBRXJCLFFBQU0sUUFBUSxnQkFBZ0I7QUFBQSxJQVk3QixnQkFBZ0Isd0JBQXdCLEtBQUssT0FBTyxTQUFTO0FBQzVELGNBQVEsT0FBTyxVQUFVLFdBQVcsUUFBUyxJQUFJLGFBQWEsZ0JBQWdCO0FBRTlFLFVBQUksU0FBUyxNQUFNLFFBQVEsUUFBUSxJQUFJLE1BQU0sS0FBSyxPQUFPO0FBQ3pELFVBQUksU0FBUyxDQUFDLElBQUksYUFBYSx1QkFBdUI7QUFFdEQsVUFBSSxjQUFjLHdCQUF3QixXQUFXO0FBQ3JELFVBQUksY0FBYyxJQUFJLGNBQWM7QUFDcEMsVUFBSSxhQUFhLFlBQVksaUJBQWlCLGFBQWE7QUFDM0QsVUFBSSxpQkFBaUIsTUFBTSxLQUFLLFNBQVMsS0FBSztBQUM5QyxVQUFJLGdCQUFnQixpQkFBaUIsTUFBTSxlQUFlO0FBQzFELFVBQUksZ0JBQStDO0FBQ25ELFVBQUksaUJBQWlCLFlBQVksWUFBWSxNQUFNO0FBQ25ELFVBQUksZ0JBQWdCLGlCQUFnQixlQUFlLFNBQVMsSUFBRztBQVkvRCxVQUFJLGdCQUFnQixDQUFDLGVBQWUsaUJBQWlCLGNBQWMsSUFBSSx1QkFBdUIsS0FBSztBQUVuRyxhQUFPLFFBQVEsU0FBVSxjQUFjO0FBQ3RDLFlBQUksUUFBUSxhQUFhLE1BQU07QUFFL0IsWUFBSSxTQUFRLENBQUMsTUFBTTtBQUNuQixZQUFJLE1BQU0sQ0FBQyxNQUFNLE1BQU07QUFDdkIsY0FBTSxLQUFLLElBQUksZUFBZTtBQUU5QixZQUFJLE1BQU07QUFBTztBQUdqQixZQUFJLE9BQU8sSUFBSSxjQUFjLGlDQUFpQyxlQUFlLFNBQVMsU0FBUyxjQUFjO0FBRTdHLHNCQUFjLEtBQUssV0FBWTtBQUM5QixlQUFLLGFBQWEsZUFBZTtBQUNqQyxlQUFLLGFBQWEsY0FBYztBQUNoQyxlQUFLLFlBQWEsWUFBVyxNQUFNO0FBQUE7QUFJcEMsWUFBSSxrQkFBa0IsTUFBTSxRQUFRLGFBQWE7QUFDaEQsY0FBSSxZQUFZLE1BQU0sUUFBUSxZQUFZLFFBQVEsS0FBSztBQUN2RCxjQUFJLFVBQVUsTUFBTSxRQUFRLFlBQVksUUFBUSxLQUFLO0FBRXJELGNBQUksV0FBVztBQUNkLGdCQUFJLE1BQU0sVUFBVSxZQUFZLGdCQUFnQjtBQUNoRCwwQkFBYyxLQUFLLFdBQVk7QUFDOUIsbUJBQUssTUFBTSxNQUFNO0FBQUE7QUFBQTtBQUluQixjQUFJLFNBQVM7QUFDWixnQkFBSSxTQUFVLFFBQVEsWUFBWSxVQUFVLFlBQWEsUUFBUSxlQUFlO0FBQ2hGLDBCQUFjLEtBQUssV0FBWTtBQUM5QixtQkFBSyxNQUFNLFNBQVM7QUFBQTtBQUFBO0FBQUEsZUFJaEI7QUFDTix3QkFBYyxLQUFLLFdBQVk7QUFDOUIsaUJBQUssYUFBYSxjQUFjLE9BQU87QUFFdkMsZ0JBQUksTUFBTSxRQUFPO0FBQ2hCLG1CQUFLLGFBQWEsWUFBWSxPQUFPO0FBQUE7QUFHdEMsaUJBQUssTUFBTSxNQUFPLFVBQVEsU0FBUyxLQUFLLGFBQWEsZ0JBQWdCO0FBRXJFLGlCQUFLLGNBQWMsSUFBSSxNQUFNLE1BQU0sU0FBUSxHQUFHLEtBQUs7QUFBQTtBQUFBO0FBSXJELHNCQUFjLEtBQUssV0FBWTtBQUM5QixlQUFLLE1BQU0sUUFBUSxJQUFJLGNBQWM7QUFBQTtBQUd0QyxzQkFBYyxLQUFLLFdBQVk7QUFHOUIsd0JBQWMsWUFBWTtBQUFBO0FBQUE7QUFJNUIsVUFBSSxLQUFLLElBQUk7QUFDYixVQUFJLGtCQUFrQixNQUFNLEtBQUssU0FBUyxLQUFLLGdDQUFnQyxJQUFJO0FBT2xGLFlBQUksQ0FBQyxTQUFTLEtBQUssOEJBQThCO0FBRWhELHdCQUFjLEtBQUssV0FBWTtBQUM5QixnQkFBSSxVQUFVLElBQUk7QUFBQTtBQUFBO0FBSXBCLFlBQUksUUFBUSxTQUFTLElBQUksYUFBYSxpQkFBaUI7QUFHdkQsV0FBRyw2QkFBNkIsS0FBSyxRQUFRLFNBQVUsVUFBVSxHQUFHO0FBQ25FLGNBQUksYUFBYSxJQUFJO0FBQ3JCLG1CQUFTLFVBQVUsV0FBWTtBQUM5QixnQkFBSSxPQUFPLEtBQUssTUFBTTtBQUd0Qiw2QkFBaUI7QUFDakIscUJBQVMsT0FBTztBQUNoQix1QkFBVyxXQUFZO0FBQ3RCLCtCQUFpQjtBQUFBLGVBQ2Y7QUFBQTtBQUFBO0FBQUE7QUFLTixhQUFPLFdBQVk7QUFDbEIsc0JBQWMsUUFBUTtBQUFBO0FBQUE7QUFBQTtBQU16Qix1QkFBcUI7QUFDcEIsUUFBSSxPQUFPLFNBQVMsS0FBSyxNQUFNO0FBRy9CLE9BQUcsNkJBQTZCLFFBQVEsU0FBVSxNQUFNO0FBQ3ZELFdBQUssV0FBVyxZQUFZO0FBQUE7QUFHN0IsUUFBSSxRQUFTLE1BQUssTUFBTSxtQkFBbUIsQ0FBQyxFQUFFLEtBQUs7QUFFbkQsUUFBSSxDQUFDLFNBQVMsU0FBUyxlQUFlLE9BQU87QUFDNUM7QUFBQTtBQUdELFFBQUksS0FBSyxLQUFLLE1BQU0sR0FBRyxLQUFLLFlBQVk7QUFDeEMsUUFBSSxNQUFNLFNBQVMsZUFBZTtBQUVsQyxRQUFJLENBQUMsS0FBSztBQUNUO0FBQUE7QUFHRCxRQUFJLENBQUMsSUFBSSxhQUFhLGNBQWM7QUFDbkMsVUFBSSxhQUFhLGFBQWE7QUFBQTtBQUcvQixRQUFJLFlBQVksTUFBTSxRQUFRLGNBQWMsZUFBZSxLQUFLLE9BQU87QUFDdkU7QUFFQSxRQUFJLGdCQUFnQjtBQUNuQixlQUFTLGNBQWMsNkJBQTZCO0FBQUE7QUFBQTtBQUl0RCxNQUFJLFlBQVk7QUFFaEIsUUFBTSxNQUFNLElBQUksdUJBQXVCLFNBQVUsS0FBSztBQUNyRCxRQUFJLE1BQU0sSUFBSSxRQUFRO0FBQ3RCLFFBQUksQ0FBQyxZQUFZLE1BQU07QUFDdEI7QUFBQTtBQVVELFFBQUksTUFBTTtBQUNWLE9BQUcsbUJBQW1CLEtBQUssUUFBUSxTQUFVLE1BQU07QUFDbEQsYUFBTyxLQUFLLFlBQVk7QUFDeEIsV0FBSyxXQUFXLFlBQVk7QUFBQTtBQUc3QixRQUFJLE9BQU8sYUFBYSxLQUFLLElBQUksS0FBSyxNQUFNLENBQUMsT0FBTztBQUNuRCxVQUFJLE9BQU8sSUFBSSxLQUFLLE1BQU0sR0FBRyxDQUFDO0FBQUE7QUFBQTtBQUloQyxRQUFNLE1BQU0sSUFBSSxZQUFZLHNCQUFzQixLQUFLO0FBQ3RELFFBQUksTUFBTSxJQUFJLFFBQVE7QUFDdEIsUUFBSSxDQUFDLFlBQVksTUFBTTtBQUN0QjtBQUFBO0FBR0QsaUJBQWE7QUFFYixRQUFJLGlCQUFpQixNQUFNLFFBQVE7QUFDbkMsUUFBSSxzQkFBc0IsSUFBSSxXQUFXLElBQUksUUFBUTtBQUVyRCxRQUFJLFNBQVMsS0FBSyx1QkFBdUIsa0JBQWtCLENBQUMscUJBQXFCO0FBQ2hGLFlBQU0sTUFBTSxJQUFJLGdCQUFnQjtBQUFBLFdBQzFCO0FBQ04sVUFBSSxZQUFZLE1BQU0sUUFBUSxjQUFjLGVBQWU7QUFDM0Q7QUFDQSxrQkFBWSxXQUFXLFdBQVc7QUFBQTtBQUFBO0FBSXBDLFNBQU8saUJBQWlCLGNBQWM7QUFBQTs7O0FGM1V2QyxpQ0FBWSxLQUFLLENBQUMsUUFBUTtBQUN4Qix5QkFBdUIsT0FBTztBQUM5Qiw0QkFBMEIsT0FBTztBQUFBOzs7QUZLbkMsdUJBQ0MsU0FDQSxTQUNBLEtBQ0M7QUFmRjtBQWlCQyxRQUFNLE1BQXNCLFFBQVEsY0FBYztBQUNsRCxNQUFJLENBQUM7QUFBSyxXQUFPO0FBRWpCLFFBQU0sWUFBWSxRQUFRLGVBQWU7QUFDekMsTUFBSSxDQUFDO0FBQVcsV0FBTztBQUV2QixRQUFNLFNBQVMsVUFBSSxVQUNqQixvQkFBb0IsbUNBRFAsbUJBRVosT0FBTyxRQUFRLFVBQVUsV0FDMUIsTUFBTTtBQUdSLE1BQUksQ0FBQztBQUFRLFdBQU87QUFFcEIsUUFBTSxnQkFBZ0IsT0FBTyxNQUFNO0FBQ25DLFFBQU0sU0FBUyxjQUFjLE1BQU07QUFHbkMsTUFBSSxDQUFDLE9BQU87QUFBUSxXQUFPO0FBRTNCLFNBQU8sRUFBRSxLQUFLO0FBQUE7QUFHZixtQkFBbUIsU0FBc0Isa0JBQThCO0FBQ3RFLFFBQU0sV0FBVyxJQUFJLGlCQUFpQixXQUFZO0FBQ2pELHdCQUFvQixJQUFpQztBQUNwRCxVQUFJLEdBQUcsZUFBZSxVQUFVO0FBQy9CLGVBQU87QUFBQSxpQkFDRyxHQUFHLGVBQWUsTUFBTTtBQUNsQyxlQUFPO0FBQUEsYUFDRDtBQUNOLGVBQU8sV0FBVyxHQUFHO0FBQUE7QUFBQTtBQUl2QixRQUFJLFdBQVcsVUFBVTtBQUN4QixlQUFTO0FBQ1Q7QUFBQTtBQUFBO0FBSUYsV0FBUyxRQUFRLFVBQVU7QUFBQSxJQUMxQixXQUFXO0FBQUEsSUFDWCxTQUFTO0FBQUE7QUFBQTtBQUtYLDJCQUNDLEtBQ0EsUUFDQSxjQUNDO0FBQ0QsTUFBSSxDQUFDLE9BQU8sU0FBUztBQUFTO0FBRTlCLE1BQUksVUFBVSxJQUFJO0FBRWxCLFFBQU0sa0JBQWtCLE1BQU07QUFDN0IsV0FBTyxNQUFNLFFBQVEsWUFBWSxPQUFPO0FBQUE7QUFHekMsZUFBYSxLQUFLO0FBQUE7QUFHbkIsNkJBQ0MsS0FDQSxRQUNBLGNBQ0M7QUFDRCxRQUFNLHlCQUF5QixPQUFPLFVBQVUsQ0FBQyxVQUNoRCxzQkFBc0IsS0FBSztBQUU1QixNQUFJLDJCQUEyQjtBQUFJO0FBRW5DLE1BQUksUUFBUSxPQUFPLE9BQU8sd0JBQXdCLE1BQU0sR0FBRztBQUUzRCxRQUFNLG9CQUFvQixNQUFNO0FBQy9CLFdBQU8sTUFBTSxRQUFRLGNBQWMsZUFBZTtBQUFBO0FBR25ELGVBQWEsS0FBSztBQUFBO0FBR1osc0NBQ04sU0FDQSxTQUNBLEtBQ0EsUUFDQztBQUVELFFBQU0sZ0JBQWdCLGNBQWMsU0FBUyxTQUFTO0FBQ3RELE1BQUksQ0FBQztBQUFlO0FBRXBCLFFBQU0sRUFBRSxLQUFLLFdBQVc7QUFDeEIsUUFBTSxlQUEyQjtBQUdqQyxvQkFBa0IsS0FBSyxRQUFRO0FBRy9CLHNCQUFvQixLQUFLLFFBQVE7QUFHakMsWUFBVSxLQUFLLE1BQU07QUFDcEIsaUJBQWEsUUFBUSxDQUFDLFlBQVk7QUFDakM7QUFBQTtBQUFBO0FBS0YsU0FBTyxjQUFjLElBQUksVUFBVSxHQUFHLFVBQVUsTUFBTTtBQUNyRCxpQkFBYSxRQUFRLENBQUMsWUFBWTtBQUNqQztBQUFBO0FBQUE7QUFBQTs7O0FLaklILGtCQUEwRjtBQUUxRixtQkFBZ0M7QUFFaEMsc0JBQThDO0FBUzlDLHFDQUErQix1QkFBVztBQUFBLEVBR3hDLFlBQVksS0FBYTtBQUN2QjtBQUNBLFNBQUssTUFBTTtBQUFBO0FBQUEsRUFHYixRQUFRO0FBQ04sVUFBTSxLQUFLLFNBQVMsY0FBYztBQUNsQyxPQUFHLFlBQVk7QUFDZixPQUFHLGNBQWMsS0FBSyxLQUFLO0FBQzNCLFdBQU87QUFBQTtBQUFBO0FBSUosSUFBTSwwQkFBMEIsdUJBQVcsVUFBVSxNQUFNO0FBQUEsRUFHaEUsWUFBWSxNQUFrQjtBQUM1QixTQUFLLGNBQWMsS0FBSyxpQkFBaUI7QUFBQTtBQUFBLEVBRzNDLE9BQU8sUUFBb0I7QUFDekIsUUFBSSxPQUFPLGNBQWMsT0FBTztBQUFpQixXQUFLLGNBQWMsS0FBSyxpQkFBaUIsT0FBTztBQUFBO0FBQUEsRUFHbkcsVUFBVTtBQUFBO0FBQUEsRUFFVixpQkFBaUIsTUFBa0I7QUFDakMsVUFBTSxVQUFVLElBQUk7QUFDcEIsVUFBTSxnQkFBK0I7QUFBQSxNQUNuQyxpQkFBaUI7QUFBQSxNQUNqQixnQkFBZ0I7QUFBQTtBQUVsQixRQUFJO0FBRUosZUFBVyxFQUFDLE1BQU0sUUFBTyxLQUFLLGVBQWU7QUFDM0MsVUFBSTtBQUNGLGNBQU0sT0FBTyxnQ0FBVyxLQUFLO0FBRTdCLGFBQUssUUFBUTtBQUFBLFVBQ1g7QUFBQSxVQUFNO0FBQUEsVUFFTixPQUFPLENBQUMsRUFBQyxNQUFNLGFBQU0sY0FBUTtBQXpEdkM7QUEwRFksa0JBQU0sY0FBYyxLQUFLLEtBQUs7QUFFOUIsZ0JBQUksQ0FBQztBQUFhO0FBQ2xCLGtCQUFNLFVBQVUsSUFBSSxJQUFJLFlBQVksTUFBTTtBQUMxQyxrQkFBTSxtQkFBbUIsUUFBUSxJQUFJO0FBQ3JDLGtCQUFNLGtCQUNKLFFBQVEsSUFBSSwyQkFDVCxDQUFDLFFBQVEsSUFBSSw4QkFDYixDQUFDLFFBQVEsSUFBSTtBQUdsQixnQkFBSSxrQkFBa0I7QUFDcEIsb0JBQU0sWUFBWSxLQUFLLE1BQU0sSUFBSSxPQUFPO0FBQ3hDLG9CQUFNLGtCQUFrQixVQUFVLEtBQUssTUFBTSxZQUFZLE1BQU07QUFDL0Qsb0JBQU0saUJBQWlCLHNCQUFnQixLQUFLLENBQUMsVUFBVSxzQkFBc0IsS0FBSyxZQUEzRCxtQkFBb0UsTUFBTSxHQUFHO0FBRXBHLDZCQUFlLFVBQVU7QUFDekIsNEJBQWMsa0JBQWtCO0FBQ2hDLDRCQUFjLGlCQUFpQjtBQUUvQixrQkFBSSxnQkFBZ0IsU0FBUztBQUFTLDhCQUFjLGtCQUFrQjtBQUN0RSxrQkFBSTtBQUFnQiw4QkFBYyxpQkFBaUIsZUFBZSxRQUFRLEtBQUssSUFBSSxNQUFNLEtBQUssUUFBUSxDQUFDLFNBQVM7QUFDOUcsc0JBQUksQ0FBQyxDQUFDLE1BQU07QUFDViwwQkFBTSxNQUFNO0FBQ1osMEJBQU0sQ0FBQyxPQUFPLE9BQU8sS0FBSyxNQUFNO0FBQ2hDLDZCQUFTLElBQUksQ0FBQyxPQUFPLEtBQUssQ0FBQyxLQUFLLEtBQUs7QUFDbkMsMEJBQUksS0FBSztBQUFBO0FBR1gsMkJBQU87QUFBQTtBQUdULHlCQUFPLENBQUMsQ0FBQztBQUFBO0FBQUE7QUFJYixnQkFBSSxDQUFDO0FBQWlCO0FBRXRCLGtCQUFNLGlCQUFpQixLQUFLLE1BQU0sSUFBSSxPQUFPLE9BQU07QUFFbkQsZ0JBQUksY0FBYyxpQkFBaUI7QUFDakMsb0JBQU0sT0FBTyx1QkFBVyxPQUFPO0FBQUEsZ0JBQzdCLFFBQVEsSUFBSSxpQkFBaUIsaUJBQWlCO0FBQUEsZ0JBQzlDLE1BQU07QUFBQTtBQUVSLHNCQUFRLElBQUksT0FBTSxPQUFNO0FBQUE7QUFHMUIsZ0JBQUksY0FBYyxnQkFBZ0I7QUFDaEMsa0JBQUksY0FBYyxlQUFlLFNBQVMsaUJBQWlCLGVBQWU7QUFDeEUsc0JBQU0sT0FBTyxLQUFLLE1BQU0sSUFBSSxPQUFPO0FBQ25DLHNCQUFNLE9BQU8sdUJBQVcsS0FBSztBQUFBLGtCQUMzQixZQUFZLEVBQUMsT0FBTztBQUFBO0FBSXRCLG9CQUFJLGNBQVEsU0FBUixtQkFBYyxXQUFXO0FBRTNCLHVCQUFLLFlBQVksUUFBUSxLQUFLO0FBQzlCLHVCQUFLLFVBQVUsS0FBSztBQUFBO0FBR3RCLHdCQUFRLElBQUksS0FBSyxNQUFNLEtBQUssTUFBTTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsZUFLbkMsT0FBUDtBQUNBLGdCQUFRLElBQUk7QUFBQTtBQUFBO0FBSWhCLFdBQU8sUUFBUTtBQUFBO0FBQUEsR0FHbkI7QUFBQSxFQUNFLGFBQWEsT0FBSyxFQUFFO0FBQUE7OztBTmxJdEIsb0RBQTZELHdCQUFPO0FBQUEsRUFDN0QsU0FBUztBQUFBO0FBQ2QsY0FBUSxJQUFJO0FBR1osV0FBSyx3QkFBd0IsQ0FBQztBQUc5QixXQUFLLDhCQUE4QixDQUFDLFNBQVMsWUFBWTtBQUN4RCxxQ0FBNkIsU0FBUyxTQUFTLEtBQUssS0FBSztBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSTNELFdBQVc7QUFBQTtBQUFBOyIsCiAgIm5hbWVzIjogW10KfQo=