heekangpark_obsidian-hk-cod.../dist/main.js
Heekang Park 84d346d37d v0.2.0
2023-02-11 07:02:20 +09:00

749 lines
110 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 __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/main.ts
var main_exports = {};
__export(main_exports, {
default: () => HKCodeBlockPlugin
});
module.exports = __toCommonJS(main_exports);
var import_obsidian3 = require("obsidian");
// src/HKCodeBlockSettings.ts
var DEFAULT_SETTINGS = {
useTitleGlobal: "default off, but on when specified",
useCollapsibleGlobal: "default on, but off when specified",
defaultCollapse: "expand",
showCollapseBtn: true,
useLinenosGlobal: "default off, but on when specified",
defaultLinenosStart: 1,
showLinenosSplitter: true,
useHighlightGlobal: "default off, but on when specified",
highlightColor: "#ff0000",
useLanguageGlobal: "default on, but off when specified",
defaultLanguage: "plain text",
useCopyBtnGlobal: "default on, but off when specified",
usePromptGlobal: "default on, but off when specified",
promptingLanguages: ["bash"],
defaultPrompt: "$",
useResultGlobal: "enable",
defaultResultPrompt: "Result",
debugMode: false
};
// src/HKCodeBlockSettingTab.ts
var import_obsidian = require("obsidian");
var fragWithHTML = (text) => {
return createFragment((frag) => {
frag.createDiv().innerHTML = text.split("\n").map((line) => line.trim()).join("<br>");
});
};
var HKCodeBlockSettingTab = class extends import_obsidian.PluginSettingTab {
constructor(app2, plugin) {
super(app2, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
containerEl.createEl("h2", { text: "Title" });
new import_obsidian.Setting(containerEl).setName("Use Title").setDesc(fragWithHTML(`- <b>default off, but on when specified</b> : the title will only be shown if the title statement is specified
- <b>always off</b> : the title will never be shown`)).addDropdown(
(tc) => tc.addOptions({
"default off, but on when specified": "default off, but on when specified",
"always off": "always off"
}).setValue(this.plugin.settings.useTitleGlobal).onChange(async (value) => {
this.plugin.settings.useTitleGlobal = value;
await this.plugin.saveSettings();
})
);
containerEl.createEl("h2", { text: "Collapse" });
new import_obsidian.Setting(containerEl).setName("Use Collapse").setDesc(fragWithHTML(`- <b>always on</b> : the code block will always be collapsible
- <b>default on, but off when specified</b> : the code block will always be collapsible, but will not be collapsed if collapse statement is specified as false
- <b>default off, but on when specified</b> : the code block will only be collapsible if the collapse statement is specified as true
- <b>always off</b> : the code block will never be collapsible`)).addDropdown(
(tc) => tc.addOptions({
"always on": "always on",
"default on, but off when specified": "default on, but off when specified",
"default off, but on when specified": "default off, but on when specified",
"always off": "always off"
}).setValue(this.plugin.settings.useCollapsibleGlobal).onChange(async (value) => {
this.plugin.settings.useCollapsibleGlobal = value;
await this.plugin.saveSettings();
})
);
new import_obsidian.Setting(containerEl).setName("Default Collapse State").setDesc("The default collapse state of the code block.").addDropdown(
(tc) => tc.addOptions({
"collapse": "collapse",
"expand": "expand"
}).setValue(this.plugin.settings.defaultCollapse).onChange(async (value) => {
this.plugin.settings.defaultCollapse = value;
await this.plugin.saveSettings();
})
);
containerEl.createEl("h2", { text: "Line Numbers" });
new import_obsidian.Setting(containerEl).setName("Use Line Numbers").setDesc(fragWithHTML(`- <b>always on</b> : line numbers will always be shown
- <b>default on, but off when specified</b> : line numbers will always be shown, but will not be shown if linenos statement is specified as false
- <b>default off, but on when specified</b> : line numbers will only be shown if the linenos statement is specified as true
- <b>always off</b> : line numbers will never be shown`)).addDropdown(
(tc) => tc.addOptions({
"always on": "always on",
"default on, but off when specified": "default on, but off when specified",
"default off, but on when specified": "default off, but on when specified",
"always off": "always off"
}).setValue(this.plugin.settings.useLinenosGlobal).onChange(async (value) => {
this.plugin.settings.useLinenosGlobal = value;
await this.plugin.saveSettings();
})
);
new import_obsidian.Setting(containerEl).setName("Default Line Number Start").setDesc("The default line number start of the code block.").addText(
(tc) => tc.setValue(this.plugin.settings.defaultLinenosStart.toString()).onChange(async (value) => {
const num = parseInt(value);
if (isNaN(num))
return;
this.plugin.settings.defaultLinenosStart = num;
await this.plugin.saveSettings();
})
);
new import_obsidian.Setting(containerEl).setName("Show Line Number Splitter").addToggle(
(tc) => tc.setValue(this.plugin.settings.showLinenosSplitter).onChange(async (value) => {
this.plugin.settings.showLinenosSplitter = value;
await this.plugin.saveSettings();
})
);
containerEl.createEl("h2", { text: "Line Highlight" });
new import_obsidian.Setting(containerEl).setName("Use Line Highlight").setDesc(fragWithHTML(`- <b>default off, but on when specified</b> : line highlight will only be shown if the line highlight statement is specified
- <b>always off</b> : line highlight will never be shown`)).addDropdown(
(tc) => tc.addOptions({
"default off, but on when specified": "default off, but on when specified",
"always off": "always off"
}).setValue(this.plugin.settings.useHighlightGlobal).onChange(async (value) => {
this.plugin.settings.useHighlightGlobal = value;
await this.plugin.saveSettings();
})
);
new import_obsidian.Setting(containerEl).setName("Line Highlight Color").setDesc("The background color of the highlighted line. Note that the given color will be applied with 0.2 opacity.").addText(
(tc) => tc.setValue(this.plugin.settings.highlightColor).onChange(async (value) => {
this.plugin.settings.highlightColor = value;
await this.plugin.saveSettings();
})
);
containerEl.createEl("h2", { text: "Language Indicator" });
new import_obsidian.Setting(containerEl).setName("Use Language Indicator").setDesc(fragWithHTML(`- <b>always on</b> : language indicator will always be shown
- <b>default on, but off when specified</b> : language indicator will always be shown, but will not be shown if the language indicator statement is specified as false
- <b>default off, but on when specified</b> : language indicator will only be shown if the language indicator statement is specified as true
- <b>always off</b> : language indicator will never be shown`)).addDropdown(
(tc) => tc.addOptions({
"always on": "always on",
"default on, but off when specified": "default on, but off when specified",
"default off, but on when specified": "default off, but on when specified",
"always off": "always off"
}).setValue(this.plugin.settings.useLanguageGlobal).onChange(async (value) => {
this.plugin.settings.useLanguageGlobal = value;
await this.plugin.saveSettings();
})
);
new import_obsidian.Setting(containerEl).setName("Default Language").setDesc("The default language name of the code block if the language is not specified.").addText(
(tc) => tc.setValue(this.plugin.settings.defaultLanguage).onChange(async (value) => {
this.plugin.settings.defaultLanguage = value;
await this.plugin.saveSettings();
})
);
containerEl.createEl("h2", { text: "Copy Button" });
new import_obsidian.Setting(containerEl).setName("Use Copy Button").setDesc(fragWithHTML(`- <b>always on</b> : copy button will always be shown
- <b>default on, but off when specified</b> : copy button will always be shown, but will not be shown if the copy button statement is specified as false
- <b>default off, but on when specified</b> : copy button will only be shown if the copy button statement is specified as true
- <b>always off</b> : copy button will never be shown`)).addDropdown(
(tc) => tc.addOptions({
"always on": "always on",
"default on, but off when specified": "default on, but off when specified",
"default off, but on when specified": "default off, but on when specified",
"always off": "always off"
}).setValue(this.plugin.settings.useCopyBtnGlobal).onChange(async (value) => {
this.plugin.settings.useCopyBtnGlobal = value;
await this.plugin.saveSettings();
})
);
containerEl.createEl("h2", { text: "Prompt" });
new import_obsidian.Setting(containerEl).setName("Use Prompt").setDesc(fragWithHTML(`- <b>always on</b> : prompt will always be shown
- <b>default on, but off when specified</b> : prompt will always be shown, but will not be shown if the prompt statement is specified as false
- <b>default off, but on when specified</b> : prompt will only be shown if the prompt statement is specified as true
- <b>always off</b> : prompt will never be shown`)).addDropdown(
(tc) => tc.addOptions({
"always on": "always on",
"default on, but off when specified": "default on, but off when specified",
"default off, but on when specified": "default off, but on when specified",
"always off": "always off"
}).setValue(this.plugin.settings.usePromptGlobal).onChange(async (value) => {
this.plugin.settings.usePromptGlobal = value;
await this.plugin.saveSettings();
})
);
new import_obsidian.Setting(containerEl).setName("Prompting Languages").setDesc("The languages that will be prompted by default. You can specify multiple languages by separating them with enters.").addTextArea(
(tc) => tc.setValue(this.plugin.settings.promptingLanguages.join("\n")).onChange(async (value) => {
const lines = value.split("\n").filter((line) => line.trim() !== "");
this.plugin.settings.promptingLanguages = lines;
await this.plugin.saveSettings();
})
);
new import_obsidian.Setting(containerEl).setName("Default Prompt").setDesc("The default prompt of the bash code block.").addText(
(tc) => tc.setValue(this.plugin.settings.defaultPrompt).onChange(async (value) => {
this.plugin.settings.defaultPrompt = value;
await this.plugin.saveSettings();
})
);
containerEl.createEl("h2", { text: "Result" });
new import_obsidian.Setting(containerEl).setName("Use Result").setDesc(fragWithHTML(`- <b>enable</b> : treat the code block starts like \`\`\`\`result\` as the result of the adjacent previous code block
- <b>disable</b> : treat the code block with \`result\` as its language name as a normal code block`)).addDropdown(
(tc) => tc.addOptions({
"enable": "enable",
"disable": "disable"
}).setValue(this.plugin.settings.useResultGlobal).onChange(async (value) => {
this.plugin.settings.useResultGlobal = value;
await this.plugin.saveSettings();
})
);
new import_obsidian.Setting(containerEl).setName("Default Result Prompt").setDesc("The default prompt of the result code block.").addText(
(tc) => tc.setValue(this.plugin.settings.defaultResultPrompt).onChange(async (value) => {
this.plugin.settings.defaultResultPrompt = value;
await this.plugin.saveSettings();
})
);
containerEl.createEl("h2", { text: "Developers" });
new import_obsidian.Setting(containerEl).setName("Debug Mode").setDesc("Show logs in the console.").addToggle(
(tc) => tc.setValue(this.plugin.settings.debugMode).onChange(async (value) => {
this.plugin.settings.debugMode = value;
await this.plugin.saveSettings();
})
);
}
};
// src/HKCodeBlockProcessor.ts
var import_obsidian2 = require("obsidian");
var REGEX = {
TITLE: /\stitle:(?:'(.*?)'|"(.*?)")\s/,
COLLAPSIBLE_SIMPLE: /\scollapsible\s/,
COLLAPSIBLE_COMPLICATE: /\scollapsible:(true|false)\s/,
LINENOS_SIMPLE: /\slinenos\s/,
LINENOS_COMPLICATE: /\slinenos:(true|false|(-{0,1}\d+))\s/,
HIGHLIGHT: /\shighlight:(?:'(.*?)'|"(.*?)")\s/,
LANGUAGE_FROM_CLASS: /^language-(\w+)$/,
LANGUAGE_SIMPLE: /\slanguage\s/,
LANGUAGE_COMPLICATE: /\slanguage:(true|false|'(.*?)'|"(.*?)")\s/,
COPYBTN_SIMPLE: /\scopybtn\s/,
COPYBTN_COMPLICATE: /\scopybtn:(true|false)\s/,
RESULT: /^```result\s/,
PROMPT_SIMPLE: /\sprompt\s/,
PROMPT_COMPLICATE: /\sprompt:(true|false|'(.*?)'|"(.*?)")\s/
};
function getMeta(view, elem_code, section_code, settings) {
const firstline = view.editor.getLine(section_code.lineStart) + " ";
let showTitle = void 0;
let title = "";
const regexResult_title = REGEX.TITLE.exec(firstline);
if (regexResult_title) {
showTitle = true;
title = regexResult_title[1] || regexResult_title[2];
}
let isCollapsible = void 0;
const regexResult_collapsibleSimple = REGEX.COLLAPSIBLE_SIMPLE.exec(firstline);
const regexResult_collapsibleComplicate = REGEX.COLLAPSIBLE_COMPLICATE.exec(firstline);
if (regexResult_collapsibleSimple) {
isCollapsible = true;
} else if (regexResult_collapsibleComplicate) {
if (regexResult_collapsibleComplicate[1] === "true") {
isCollapsible = true;
} else if (regexResult_collapsibleComplicate[1] === "false") {
isCollapsible = false;
}
}
let showLinenos = void 0;
let linenosStart = settings.defaultLinenosStart;
const linenosNum = section_code.lineEnd - section_code.lineStart - 1;
const regexResult_linenosSimple = REGEX.LINENOS_SIMPLE.exec(firstline);
const regexResult_linenosComplicate = REGEX.LINENOS_COMPLICATE.exec(firstline);
if (regexResult_linenosSimple) {
showLinenos = true;
} else if (regexResult_linenosComplicate) {
if (regexResult_linenosComplicate[1] === "true") {
showLinenos = true;
} else if (regexResult_linenosComplicate[1] === "false") {
showLinenos = false;
} else {
showLinenos = true;
linenosStart = parseInt(regexResult_linenosComplicate[2]) || 1;
}
}
let showHighlight = void 0;
let highlightLines = [];
const regexResult_highlight = REGEX.HIGHLIGHT.exec(firstline);
if (regexResult_highlight) {
showHighlight = true;
const highlightLines_str = regexResult_highlight[1] || regexResult_highlight[2];
highlightLines = highlightLines_str.split(",").map((line) => parseInt(line));
if (highlightLines.some((line) => isNaN(line))) {
showHighlight = void 0;
highlightLines = [];
} else {
highlightLines = highlightLines.filter((line) => line >= linenosStart && line < linenosStart + linenosNum);
}
}
let showLanguage = void 0;
let language = (() => {
let language2 = settings.defaultLanguage;
elem_code.classList.forEach((className) => {
const regexResult_languageFromClass = REGEX.LANGUAGE_FROM_CLASS.exec(className.trim());
if (regexResult_languageFromClass)
language2 = regexResult_languageFromClass[1];
});
return language2;
})();
const regexResult_languageSimple = REGEX.LANGUAGE_SIMPLE.exec(firstline);
const regexResult_languageComplicate = REGEX.LANGUAGE_COMPLICATE.exec(firstline);
if (regexResult_languageSimple) {
showLanguage = true;
} else if (regexResult_languageComplicate) {
if (regexResult_languageComplicate[1] === "true") {
showLanguage = true;
} else if (regexResult_languageComplicate[1] === "false") {
showLanguage = false;
} else {
showLanguage = true;
language = regexResult_languageComplicate[2] || regexResult_languageComplicate[3];
}
}
let showCopyBtn = void 0;
const regexResult_copyBtnSimple = REGEX.COPYBTN_SIMPLE.exec(firstline);
const regexResult_copyBtnComplicate = REGEX.COPYBTN_COMPLICATE.exec(firstline);
if (regexResult_copyBtnSimple) {
showCopyBtn = true;
} else if (regexResult_copyBtnComplicate) {
if (regexResult_copyBtnComplicate[1] === "true") {
showCopyBtn = true;
} else if (regexResult_copyBtnComplicate[1] === "false") {
showCopyBtn = false;
}
}
let showPrompt = void 0;
let prompt = settings.defaultPrompt;
const regexResult_promptSimple = REGEX.PROMPT_SIMPLE.exec(firstline);
const regexResult_promptComplicate = REGEX.PROMPT_COMPLICATE.exec(firstline);
if (regexResult_promptSimple) {
showPrompt = true;
} else if (regexResult_promptComplicate) {
if (regexResult_promptComplicate[1] === "true") {
showPrompt = true;
} else if (regexResult_promptComplicate[1] === "false") {
showPrompt = false;
} else {
showPrompt = true;
prompt = regexResult_promptComplicate[2] || regexResult_promptComplicate[3];
}
}
let isResult = false;
let resultPrompt = settings.defaultResultPrompt;
const regexResult_result = REGEX.RESULT.exec(firstline);
const regexResultPrompt_result = REGEX.PROMPT_COMPLICATE.exec(firstline);
if (regexResult_result) {
isResult = true;
showTitle = false;
showLanguage = false;
showCopyBtn = false;
showPrompt = false;
if (regexResultPrompt_result) {
resultPrompt = regexResultPrompt_result[2] || regexResultPrompt_result[3];
}
}
return {
showTitle,
title,
isCollapsible,
showLinenos,
linenosStart,
linenosNum,
showHighlight,
highlightLines,
showLanguage,
language,
showCopyBtn,
isResult,
resultPrompt,
showPrompt,
prompt
};
}
async function HKCodeBlockProcessor(el, context, plugin) {
const settings = plugin.settings;
const view = app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
if (!view)
return;
const elem_code = el.querySelector("pre:not(.frontmatter) > code");
if (!elem_code)
return;
const elem_pre = elem_code.parentElement;
if (!elem_pre)
return;
const elem_div = elem_pre.parentElement;
if (!elem_div)
return;
const elem_copyBtn = elem_div.querySelector(".copy-code-button");
if (!elem_copyBtn)
return;
const section_code = context.getSectionInfo(elem_code);
if (!section_code)
return;
const {
showTitle,
title,
isCollapsible,
showLinenos,
linenosStart,
linenosNum,
showHighlight,
highlightLines,
showLanguage,
language,
showCopyBtn,
isResult,
resultPrompt,
showPrompt,
prompt
} = getMeta(view, elem_code, section_code, settings);
if (settings.debugMode) {
console.log({
showTitle,
title,
showLinenos,
linenosStart,
linenosNum,
showHighlight,
highlightLines,
showLanguage,
language,
showCopyBtn,
isResult,
resultPrompt,
showPrompt,
prompt
});
}
elem_div.classList.add("hk-codeblock");
elem_code.classList.add("hk-codeblock-code");
elem_copyBtn.remove();
let elem_title = void 0;
if (settings.useTitleGlobal === "default off, but on when specified" && showTitle === true) {
elem_div.classList.add("hk-codeblock-show-title");
elem_title = document.createElement("div");
elem_title.classList.add("hk-codeblock-title");
elem_title.innerHTML = title;
elem_div.insertBefore(elem_title, elem_pre);
}
if (settings.useCollapsibleGlobal === "always on" || settings.useCollapsibleGlobal === "default on, but off when specified" && (isCollapsible === void 0 || isCollapsible === true) || settings.useCollapsibleGlobal === "default off, but on when specified" && isCollapsible === true) {
elem_div.classList.add("hk-codeblock-collapsible");
if (settings.defaultCollapse === "collapse") {
elem_div.classList.add("hk-codeblock-collapsed");
}
if (elem_title) {
elem_title.addEventListener("click", (ev) => {
ev.stopPropagation();
ev.preventDefault();
if (elem_div.classList.contains("hk-codeblock-collapsed")) {
elem_div.classList.remove("hk-codeblock-collapsed");
} else {
elem_div.classList.add("hk-codeblock-collapsed");
}
});
const elem_collapseBtns = document.createElement("div");
elem_collapseBtns.classList.add("hk-codeblock-collapse-btns");
const elem_collapseBtn = document.createElement("div");
elem_collapseBtn.classList.add("hk-codeblock-collapse-btn", "hk-codeblock-collapsed-btn");
elem_collapseBtn.innerHTML = `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M10 19a1 1 0 0 1-.64-.23 1 1 0 0 1-.13-1.41L13.71 12 9.39 6.63a1 1 0 0 1 .15-1.41 1 1 0 0 1 1.46.15l4.83 6a1 1 0 0 1 0 1.27l-5 6A1 1 0 0 1 10 19z"/>
</svg>`;
elem_collapseBtns.appendChild(elem_collapseBtn);
const elem_expandBtn = document.createElement("div");
elem_expandBtn.classList.add("hk-codeblock-collapse-btn", "hk-codeblock-expanded-btn");
elem_expandBtn.innerHTML = `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M12 16a1 1 0 0 1-.64-.23l-6-5a1 1 0 1 1 1.28-1.54L12 13.71l5.36-4.32a1 1 0 0 1 1.41.15 1 1 0 0 1-.14 1.46l-6 4.83A1 1 0 0 1 12 16z"/>
</svg>`;
elem_collapseBtns.appendChild(elem_expandBtn);
elem_title.prepend(elem_collapseBtns);
}
}
if (settings.useLinenosGlobal === "always on" || settings.useLinenosGlobal === "default on, but off when specified" && (showLinenos === void 0 || showLinenos === true) || settings.useLinenosGlobal === "default off, but on when specified" && showLinenos === true) {
elem_div.classList.add("hk-codeblock-show-linenos");
const elem_linenos = document.createElement("code");
elem_linenos.classList.add("hk-codeblock-linenos");
elem_linenos.innerText = Array(linenosNum).fill(0).map((_, idx) => idx + linenosStart).join("\n");
elem_pre.insertBefore(elem_linenos, elem_code);
if (settings.showLinenosSplitter) {
elem_linenos.classList.add("show-splitter");
}
}
if (settings.useHighlightGlobal === "default off, but on when specified" && showHighlight === true) {
elem_div.classList.add("hk-codeblock-show-highlight");
elem_div.style.setProperty("--hk-codeblock-highlight-background-color", settings.highlightColor);
const elem_highlight = document.createElement("code");
elem_highlight.classList.add("hk-codeblock-highlight");
elem_highlight.innerHTML = Array(linenosNum).fill(0).map((_, idx) => {
const classNames = [];
if (highlightLines.includes(idx + linenosStart))
classNames.push("highlight");
return `<span class="line line-${idx + linenosStart} ${classNames.join(" ")}"> </span>`;
}).join("\n");
elem_pre.insertBefore(elem_highlight, elem_code);
}
if (settings.useLanguageGlobal === "always on" || settings.useLanguageGlobal === "default on, but off when specified" && (showLanguage === void 0 || showLanguage === true) || settings.useLanguageGlobal === "default off, but on when specified" && showLanguage === true) {
elem_div.classList.add("hk-codeblock-show-language");
const elem_language = document.createElement("div");
elem_language.classList.add("hk-codeblock-language");
elem_language.innerText = language;
elem_pre.prepend(elem_language);
}
if (settings.useCopyBtnGlobal === "always on" || settings.useCopyBtnGlobal === "default on, but off when specified" && (showCopyBtn === void 0 || showCopyBtn === true) || settings.useCopyBtnGlobal === "default off, but on when specified" && showCopyBtn === true) {
elem_div.classList.add("hk-codeblock-show-copybtn");
elem_pre.appendChild(elem_copyBtn);
}
if (settings.usePromptGlobal === "always on" && settings.promptingLanguages.includes(language) || settings.usePromptGlobal === "default on, but off when specified" && settings.promptingLanguages.includes(language) && (showPrompt === void 0 || showPrompt === true) || settings.usePromptGlobal === "default off, but on when specified" && showPrompt === true) {
elem_div.classList.add("hk-codeblock-show-prompt");
let code_lines = elem_code.innerText.split("\n");
if (code_lines[code_lines.length - 1].trim().length == 0)
code_lines.pop();
const no_prompt_line_idxs = code_lines.map((line, idx) => {
if (line.trim().length == 0)
return idx + 1;
if (line.startsWith("#"))
return idx + 1;
return -1;
}).filter((idx) => idx != -1);
elem_pre.classList.add("command-line");
elem_pre.setAttribute("data-prompt", prompt);
elem_pre.setAttribute("data-continuation-str", "\\");
elem_pre.setAttribute("data-continuation-prompt", " ".repeat(prompt.length));
elem_pre.setAttribute("data-output", no_prompt_line_idxs.join(", "));
}
if (settings.useResultGlobal === "enable" && isResult === true) {
elem_div.classList.add("hk-codeblock-result");
elem_code.classList.add("hk-codeblock-result-code");
elem_div.setAttribute("data-result-prompt", resultPrompt);
}
}
// src/prism-plugins/prism-command-line.js
function PrismPlugin_CommandLine(Prism) {
if (typeof Prism === "undefined" || typeof document === "undefined") {
return;
}
var CLASS_PATTERN = /(?:^|\s)command-line(?:\s|$)/;
var PROMPT_CLASS = "command-line-prompt";
var startsWith = "".startsWith ? function(s, p) {
return s.startsWith(p);
} : function(s, p) {
return s.indexOf(p) === 0;
};
var endsWith = "".endsWith ? function(str, suffix) {
return str.endsWith(suffix);
} : function(str, suffix) {
var len = str.length;
return str.substring(len - suffix.length, len) === suffix;
};
function hasCommandLineInfo(env) {
var vars = env.vars = env.vars || {};
return "command-line" in vars;
}
function getCommandLineInfo(env) {
var vars = env.vars = env.vars || {};
return vars["command-line"] = vars["command-line"] || {};
}
Prism.hooks.add("before-highlight", function(env) {
var commandLine = getCommandLineInfo(env);
if (commandLine.complete || !env.code) {
commandLine.complete = true;
return;
}
var pre = env.element.parentElement;
if (!pre || !/pre/i.test(pre.nodeName) || // Abort only if neither the <pre> nor the <code> have the class
!CLASS_PATTERN.test(pre.className) && !CLASS_PATTERN.test(env.element.className)) {
commandLine.complete = true;
return;
}
var existingPrompt = env.element.querySelector("." + PROMPT_CLASS);
if (existingPrompt) {
existingPrompt.remove();
}
var codeLines = env.code.split("\n");
if (codeLines[codeLines.length - 1].trim().length === 0) {
commandLine.numberOfLines = codeLines.length - 1;
} else {
commandLine.numberOfLines = codeLines.length;
}
var outputLines = commandLine.outputLines = [];
var outputSections = pre.getAttribute("data-output");
var outputFilter = pre.getAttribute("data-filter-output");
if (outputSections !== null) {
outputSections.split(",").forEach(function(section) {
var range = section.split("-");
var outputStart = parseInt(range[0], 10);
var outputEnd = range.length === 2 ? parseInt(range[1], 10) : outputStart;
if (!isNaN(outputStart) && !isNaN(outputEnd)) {
if (outputStart < 1) {
outputStart = 1;
}
if (outputEnd > codeLines.length) {
outputEnd = codeLines.length;
}
outputStart--;
outputEnd--;
for (var j2 = outputStart; j2 <= outputEnd; j2++) {
outputLines[j2] = codeLines[j2];
codeLines[j2] = "";
}
}
});
} else if (outputFilter) {
for (var i = 0; i < codeLines.length; i++) {
if (startsWith(codeLines[i], outputFilter)) {
outputLines[i] = codeLines[i].slice(outputFilter.length);
codeLines[i] = "";
}
}
}
var continuationLineIndicies = commandLine.continuationLineIndicies = /* @__PURE__ */ new Set();
var lineContinuationStr = pre.getAttribute("data-continuation-str");
var continuationFilter = pre.getAttribute("data-filter-continuation");
for (var j = 0; j < codeLines.length; j++) {
var line = codeLines[j];
if (!line) {
continue;
}
if (lineContinuationStr && endsWith(line, lineContinuationStr)) {
continuationLineIndicies.add(j + 1);
}
if (j > 0 && continuationFilter && startsWith(line, continuationFilter)) {
codeLines[j] = line.slice(continuationFilter.length);
continuationLineIndicies.add(j);
}
}
env.code = codeLines.join("\n");
});
Prism.hooks.add("before-insert", function(env) {
var commandLine = getCommandLineInfo(env);
if (commandLine.complete) {
return;
}
var codeLines = env.highlightedCode.split("\n");
var outputLines = commandLine.outputLines || [];
for (var i = 0, l = codeLines.length; i < l; i++) {
if (outputLines.hasOwnProperty(i)) {
codeLines[i] = '<span class="token output">' + Prism.util.encode(outputLines[i]) + "</span>";
} else {
codeLines[i] = '<span class="token command">' + codeLines[i] + "</span>";
}
}
env.highlightedCode = codeLines.join("\n");
});
Prism.hooks.add("complete", function(env) {
if (!hasCommandLineInfo(env)) {
return;
}
var commandLine = getCommandLineInfo(env);
if (commandLine.complete) {
return;
}
var pre = env.element.parentElement;
if (CLASS_PATTERN.test(env.element.className)) {
env.element.className = env.element.className.replace(CLASS_PATTERN, " ");
}
if (!CLASS_PATTERN.test(pre.className)) {
pre.className += " command-line";
}
function getAttribute(key, defaultValue) {
return (pre.getAttribute(key) || defaultValue).replace(/"/g, "&quot");
}
var promptLines = "";
var rowCount = commandLine.numberOfLines || 0;
var promptText = getAttribute("data-prompt", "");
var promptLine;
if (promptText !== "") {
promptLine = '<span data-prompt="' + promptText + '"></span>';
} else {
var user = getAttribute("data-user", "user");
var host = getAttribute("data-host", "localhost");
promptLine = '<span data-user="' + user + '" data-host="' + host + '"></span>';
}
var continuationLineIndicies = commandLine.continuationLineIndicies || /* @__PURE__ */ new Set();
var continuationPromptText = getAttribute("data-continuation-prompt", ">");
var continuationPromptLine = '<span data-continuation-prompt="' + continuationPromptText + '"></span>';
for (var j = 0; j < rowCount; j++) {
if (continuationLineIndicies.has(j)) {
promptLines += continuationPromptLine;
} else {
promptLines += promptLine;
}
}
var prompt = document.createElement("span");
prompt.className = PROMPT_CLASS;
prompt.innerHTML = promptLines;
var outputLines = commandLine.outputLines || [];
for (var i = 0, l = outputLines.length; i < l; i++) {
if (outputLines.hasOwnProperty(i)) {
var node = prompt.children[i];
node.removeAttribute("data-user");
node.removeAttribute("data-host");
node.removeAttribute("data-prompt");
}
}
env.element.insertBefore(prompt, env.element.firstChild);
commandLine.complete = true;
});
}
// src/main.ts
var HKCodeBlockPlugin = class extends import_obsidian3.Plugin {
async onload() {
await this.loadSettings();
if (this.settings.debugMode) {
console.log("loading HKCodeBlock plugin");
}
const Prism = await (0, import_obsidian3.loadPrism)();
PrismPlugin_CommandLine(Prism);
this.addSettingTab(new HKCodeBlockSettingTab(this.app, this));
const processor = this.registerMarkdownPostProcessor((el, ctx) => {
HKCodeBlockProcessor(el, ctx, this);
});
processor.sortOrder = 100;
}
onunload() {
if (this.settings.debugMode) {
console.log("unloading HKCodeBlock plugin");
}
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
}
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL21haW4udHMiLCAiLi4vc3JjL0hLQ29kZUJsb2NrU2V0dGluZ3MudHMiLCAiLi4vc3JjL0hLQ29kZUJsb2NrU2V0dGluZ1RhYi50cyIsICIuLi9zcmMvSEtDb2RlQmxvY2tQcm9jZXNzb3IudHMiLCAiLi4vc3JjL3ByaXNtLXBsdWdpbnMvcHJpc20tY29tbWFuZC1saW5lLmpzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBQbHVnaW4sIGxvYWRQcmlzbSB9IGZyb20gJ29ic2lkaWFuJztcblxuaW1wb3J0IHR5cGUgeyBIS0NvZGVCbG9ja1NldHRpbmdzIH0gZnJvbSAnLi9IS0NvZGVCbG9ja1NldHRpbmdzJztcbmltcG9ydCB7IERFRkFVTFRfU0VUVElOR1MgfSBmcm9tICcuL0hLQ29kZUJsb2NrU2V0dGluZ3MnO1xuaW1wb3J0IHsgSEtDb2RlQmxvY2tTZXR0aW5nVGFiIH0gZnJvbSAnLi9IS0NvZGVCbG9ja1NldHRpbmdUYWInO1xuaW1wb3J0IHsgSEtDb2RlQmxvY2tQcm9jZXNzb3IgfSBmcm9tICcuL0hLQ29kZUJsb2NrUHJvY2Vzc29yJztcblxuaW1wb3J0IHsgUHJpc21QbHVnaW5fQ29tbWFuZExpbmUgfSBmcm9tICcuL3ByaXNtLXBsdWdpbnMvcHJpc20tY29tbWFuZC1saW5lJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSEtDb2RlQmxvY2tQbHVnaW4gZXh0ZW5kcyBQbHVnaW4ge1xuXHRzZXR0aW5nczogSEtDb2RlQmxvY2tTZXR0aW5ncztcblxuXHRhc3luYyBvbmxvYWQoKSB7XG5cdFx0YXdhaXQgdGhpcy5sb2FkU2V0dGluZ3MoKTtcblx0XHRpZiAodGhpcy5zZXR0aW5ncy5kZWJ1Z01vZGUpIHtcblx0XHRcdGNvbnNvbGUubG9nKFwibG9hZGluZyBIS0NvZGVCbG9jayBwbHVnaW5cIik7XG5cdFx0fVxuXG5cdFx0Y29uc3QgUHJpc20gPSBhd2FpdCBsb2FkUHJpc20oKTtcblxuXHRcdC8vIGFjdGl2YXRlIFByaXNtLmpzIHBsdWdpbnNcblx0XHRQcmlzbVBsdWdpbl9Db21tYW5kTGluZShQcmlzbSk7XG5cblx0XHQvLyByZWdpc3RlciBzZXR0aW5ncyB0YWJcblx0XHR0aGlzLmFkZFNldHRpbmdUYWIobmV3IEhLQ29kZUJsb2NrU2V0dGluZ1RhYih0aGlzLmFwcCwgdGhpcykpO1xuXG5cdFx0Ly8gcmVnaXN0ZXIgbWFya2Rvd24gcG9zdCBwcm9jZXNzb3Jcblx0XHRjb25zdCBwcm9jZXNzb3IgPSB0aGlzLnJlZ2lzdGVyTWFya2Rvd25Qb3N0UHJvY2Vzc29yKChlbCwgY3R4KSA9PiB7XG5cdFx0XHRIS0NvZGVCbG9ja1Byb2Nlc3NvcihlbCwgY3R4LCB0aGlzKTtcblx0XHR9KTtcblxuXHRcdHByb2Nlc3Nvci5zb3J0T3JkZXIgPSAxMDA7IC8vIHJ1biBhZnRlciB0aGUgZGVmYXVsdCBjb2RlIGJsb2NrIHByb2Nlc3NvclxuXHR9XG5cblx0b251bmxvYWQoKSB7XG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MuZGVidWdNb2RlKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcInVubG9hZGluZyBIS0NvZGVCbG9jayBwbHVnaW5cIik7XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgbG9hZFNldHRpbmdzKCkge1xuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xuXHR9XG5cblx0YXN5bmMgc2F2ZVNldHRpbmdzKCkge1xuXHRcdGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XG5cdH1cbn0iLCAiZXhwb3J0IGludGVyZmFjZSBIS0NvZGVCbG9ja1NldHRpbmdzIHtcblx0dXNlVGl0bGVHbG9iYWw6IChcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIiB8IFwiYWx3YXlzIG9mZlwiKTtcblxuXHR1c2VDb2xsYXBzaWJsZUdsb2JhbDogKFwiYWx3YXlzIG9uXCIgfCBcImRlZmF1bHQgb24sIGJ1dCBvZmYgd2hlbiBzcGVjaWZpZWRcIiB8IFwiZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZFwiIHwgXCJhbHdheXMgb2ZmXCIpO1xuXHRkZWZhdWx0Q29sbGFwc2U6IChcImNvbGxhcHNlXCIgfCBcImV4cGFuZFwiKTtcblx0c2hvd0NvbGxhcHNlQnRuOiBib29sZWFuO1xuXG5cdHVzZUxpbmVub3NHbG9iYWw6IChcImFsd2F5cyBvblwiIHwgXCJkZWZhdWx0IG9uLCBidXQgb2ZmIHdoZW4gc3BlY2lmaWVkXCIgfCBcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIiB8IFwiYWx3YXlzIG9mZlwiKTtcblx0ZGVmYXVsdExpbmVub3NTdGFydDogbnVtYmVyO1xuXHRzaG93TGluZW5vc1NwbGl0dGVyOiBib29sZWFuO1xuXG5cdHVzZUhpZ2hsaWdodEdsb2JhbDogKFwiZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZFwiIHwgXCJhbHdheXMgb2ZmXCIpO1xuXHRoaWdobGlnaHRDb2xvcjogc3RyaW5nO1xuXG5cdHVzZUxhbmd1YWdlR2xvYmFsOiAoXCJhbHdheXMgb25cIiB8IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiIHwgXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIgfCBcImFsd2F5cyBvZmZcIik7XG5cdGRlZmF1bHRMYW5ndWFnZTogc3RyaW5nO1xuXHRcblx0dXNlQ29weUJ0bkdsb2JhbDogKFwiYWx3YXlzIG9uXCIgfCBcImRlZmF1bHQgb24sIGJ1dCBvZmYgd2hlbiBzcGVjaWZpZWRcIiB8IFwiZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZFwiIHwgXCJhbHdheXMgb2ZmXCIpO1xuXHRcblx0dXNlUHJvbXB0R2xvYmFsOiAoXCJhbHdheXMgb25cIiB8IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiIHwgXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIgfCBcImFsd2F5cyBvZmZcIik7XG5cdGRlZmF1bHRQcm9tcHQ6IHN0cmluZztcblx0XG5cdHVzZVJlc3VsdEdsb2JhbDogKFwiZW5hYmxlXCIgfCBcImRpc2FibGVcIik7XG5cdHByb21wdGluZ0xhbmd1YWdlczogc3RyaW5nW107XG5cdGRlZmF1bHRSZXN1bHRQcm9tcHQ6IHN0cmluZztcblxuXHRkZWJ1Z01vZGU6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NFVFRJTkdTOiBIS0NvZGVCbG9ja1NldHRpbmdzID0ge1xuXHR1c2VUaXRsZUdsb2JhbDogXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIsXG5cblx0dXNlQ29sbGFwc2libGVHbG9iYWw6IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiLFxuXHRkZWZhdWx0Q29sbGFwc2U6IFwiZXhwYW5kXCIsXG5cdHNob3dDb2xsYXBzZUJ0bjogdHJ1ZSxcblxuXHR1c2VMaW5lbm9zR2xvYmFsOiBcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIixcblx0ZGVmYXVsdExpbmVub3NTdGFydDogMSxcblx0c2hvd0xpbmVub3NTcGxpdHRlcjogdHJ1ZSxcblxuXHR1c2VIaWdobGlnaHRHbG9iYWw6IFwiZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZFwiLFxuXHRoaWdobGlnaHRDb2xvcjogXCIjZmYwMDAwXCIsXG5cblx0dXNlTGFuZ3VhZ2VHbG9iYWw6IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiLFxuXHRkZWZhdWx0TGFuZ3VhZ2U6IFwicGxhaW4gdGV4dFwiLFxuXG5cdHVzZUNvcHlCdG5HbG9iYWw6IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiLFxuXG5cdHVzZVByb21wdEdsb2JhbDogXCJkZWZhdWx0IG9uLCBidXQgb2ZmIHdoZW4gc3BlY2lmaWVkXCIsXG5cdHByb21wdGluZ0xhbmd1YWdlczogW1wiYmFzaFwiXSxcblx0ZGVmYXVsdFByb21wdDogXCIkXCIsXG5cblx0dXNlUmVzdWx0R2xvYmFsOiBcImVuYWJsZVwiLFxuXHRkZWZhdWx0UmVzdWx0UHJvbXB0OiBcIlJlc3VsdFwiLFxuXG5cdGRlYnVnTW9kZTogZmFsc2UsXG59IiwgImltcG9ydCB7IEFwcCwgUGx1Z2luU2V0dGluZ1RhYiwgU2V0dGluZyB9IGZyb20gJ29ic2lkaWFuJztcblxuaW1wb3J0IEhLQ29kZUJsb2NrUGx1Z2luIGZyb20gJy4vbWFpbic7XG5cbmV4cG9ydCBjb25zdCBmcmFnV2l0aEhUTUwgPSAodGV4dDogc3RyaW5nKSA9PiB7XG5cdHJldHVybiBjcmVhdGVGcmFnbWVudCgoZnJhZykgPT4ge1xuXHRcdGZyYWcuY3JlYXRlRGl2KCkuaW5uZXJIVE1MID0gdGV4dC5zcGxpdChcIlxcblwiKS5tYXAoKGxpbmUpID0+IGxpbmUudHJpbSgpKS5qb2luKFwiPGJyPlwiKTtcblx0fSk7XG59XG5cbmV4cG9ydCBjbGFzcyBIS0NvZGVCbG9ja1NldHRpbmdUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcblx0cGx1Z2luOiBIS0NvZGVCbG9ja1BsdWdpbjtcblxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBIS0NvZGVCbG9ja1BsdWdpbikge1xuXHRcdHN1cGVyKGFwcCwgcGx1Z2luKTtcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcblx0fVxuXG5cdGRpc3BsYXkoKTogdm9pZCB7XG5cdFx0Y29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcblx0XHRjb250YWluZXJFbC5lbXB0eSgpO1xuXG5cdFx0Ly8gdGl0bGVcblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdUaXRsZScgfSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKCdVc2UgVGl0bGUnKVxuXHRcdFx0LnNldERlc2MoZnJhZ1dpdGhIVE1MKGAtIDxiPmRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWQ8L2I+IDogdGhlIHRpdGxlIHdpbGwgb25seSBiZSBzaG93biBpZiB0aGUgdGl0bGUgc3RhdGVtZW50IGlzIHNwZWNpZmllZFxuXHRcdFx0XHQtIDxiPmFsd2F5cyBvZmY8L2I+IDogdGhlIHRpdGxlIHdpbGwgbmV2ZXIgYmUgc2hvd25gKSlcblx0XHRcdC5hZGREcm9wZG93bih0YyA9PlxuXHRcdFx0XHR0Yy5hZGRPcHRpb25zKHtcblx0XHRcdFx0XHRcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIjogXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIsXG5cdFx0XHRcdFx0XCJhbHdheXMgb2ZmXCI6IFwiYWx3YXlzIG9mZlwiLFxuXHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VUaXRsZUdsb2JhbClcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiBzdHJpbmcpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZVRpdGxlR2xvYmFsID0gdmFsdWUgYXMgKFwiZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZFwiIHwgXCJhbHdheXMgb2ZmXCIpO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHQvLyBjb2xsYXBzZVxuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ0NvbGxhcHNlJyB9KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ1VzZSBDb2xsYXBzZScpXG5cdFx0XHQuc2V0RGVzYyhmcmFnV2l0aEhUTUwoYC0gPGI+YWx3YXlzIG9uPC9iPiA6IHRoZSBjb2RlIGJsb2NrIHdpbGwgYWx3YXlzIGJlIGNvbGxhcHNpYmxlXG5cdFx0XHRcdC0gPGI+ZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZDwvYj4gOiB0aGUgY29kZSBibG9jayB3aWxsIGFsd2F5cyBiZSBjb2xsYXBzaWJsZSwgYnV0IHdpbGwgbm90IGJlIGNvbGxhcHNlZCBpZiBjb2xsYXBzZSBzdGF0ZW1lbnQgaXMgc3BlY2lmaWVkIGFzIGZhbHNlXG5cdFx0XHRcdC0gPGI+ZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZDwvYj4gOiB0aGUgY29kZSBibG9jayB3aWxsIG9ubHkgYmUgY29sbGFwc2libGUgaWYgdGhlIGNvbGxhcHNlIHN0YXRlbWVudCBpcyBzcGVjaWZpZWQgYXMgdHJ1ZVxuXHRcdFx0XHQtIDxiPmFsd2F5cyBvZmY8L2I+IDogdGhlIGNvZGUgYmxvY2sgd2lsbCBuZXZlciBiZSBjb2xsYXBzaWJsZWApKVxuXHRcdFx0LmFkZERyb3Bkb3duKHRjID0+XG5cdFx0XHRcdHRjLmFkZE9wdGlvbnMoe1xuXHRcdFx0XHRcdFwiYWx3YXlzIG9uXCI6IFwiYWx3YXlzIG9uXCIsXG5cdFx0XHRcdFx0XCJkZWZhdWx0IG9uLCBidXQgb2ZmIHdoZW4gc3BlY2lmaWVkXCI6IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiLFxuXHRcdFx0XHRcdFwiZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZFwiOiBcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIixcblx0XHRcdFx0XHRcImFsd2F5cyBvZmZcIjogXCJhbHdheXMgb2ZmXCIsXG5cdFx0XHRcdH0pXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZUNvbGxhcHNpYmxlR2xvYmFsKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWU6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlQ29sbGFwc2libGVHbG9iYWwgPSB2YWx1ZSBhcyAoXCJhbHdheXMgb25cIiB8IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiIHwgXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIgfCBcImFsd2F5cyBvZmZcIik7XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KVxuXHRcdFx0KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ0RlZmF1bHQgQ29sbGFwc2UgU3RhdGUnKVxuXHRcdFx0LnNldERlc2MoJ1RoZSBkZWZhdWx0IGNvbGxhcHNlIHN0YXRlIG9mIHRoZSBjb2RlIGJsb2NrLicpXG5cdFx0XHQuYWRkRHJvcGRvd24odGMgPT5cblx0XHRcdFx0dGMuYWRkT3B0aW9ucyh7XG5cdFx0XHRcdFx0XCJjb2xsYXBzZVwiOiBcImNvbGxhcHNlXCIsXG5cdFx0XHRcdFx0XCJleHBhbmRcIjogXCJleHBhbmRcIixcblx0XHRcdFx0fSlcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdENvbGxhcHNlKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWU6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdENvbGxhcHNlID0gdmFsdWUgYXMgKFwiY29sbGFwc2VcIiB8IFwiZXhwYW5kXCIpO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHQvLyBsaW5lIG51bWJlcnNcblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdMaW5lIE51bWJlcnMnIH0pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZSgnVXNlIExpbmUgTnVtYmVycycpXG5cdFx0XHQuc2V0RGVzYyhmcmFnV2l0aEhUTUwoYC0gPGI+YWx3YXlzIG9uPC9iPiA6IGxpbmUgbnVtYmVycyB3aWxsIGFsd2F5cyBiZSBzaG93blxuXHRcdFx0XHQtIDxiPmRlZmF1bHQgb24sIGJ1dCBvZmYgd2hlbiBzcGVjaWZpZWQ8L2I+IDogbGluZSBudW1iZXJzIHdpbGwgYWx3YXlzIGJlIHNob3duLCBidXQgd2lsbCBub3QgYmUgc2hvd24gaWYgbGluZW5vcyBzdGF0ZW1lbnQgaXMgc3BlY2lmaWVkIGFzIGZhbHNlXG5cdFx0XHRcdC0gPGI+ZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZDwvYj4gOiBsaW5lIG51bWJlcnMgd2lsbCBvbmx5IGJlIHNob3duIGlmIHRoZSBsaW5lbm9zIHN0YXRlbWVudCBpcyBzcGVjaWZpZWQgYXMgdHJ1ZVxuXHRcdFx0XHQtIDxiPmFsd2F5cyBvZmY8L2I+IDogbGluZSBudW1iZXJzIHdpbGwgbmV2ZXIgYmUgc2hvd25gKSlcblx0XHRcdC5hZGREcm9wZG93bih0YyA9PlxuXHRcdFx0XHR0Yy5hZGRPcHRpb25zKHtcblx0XHRcdFx0XHRcImFsd2F5cyBvblwiOiBcImFsd2F5cyBvblwiLFxuXHRcdFx0XHRcdFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiOiBcImRlZmF1bHQgb24sIGJ1dCBvZmYgd2hlbiBzcGVjaWZpZWRcIixcblx0XHRcdFx0XHRcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIjogXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIsXG5cdFx0XHRcdFx0XCJhbHdheXMgb2ZmXCI6IFwiYWx3YXlzIG9mZlwiLFxuXHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VMaW5lbm9zR2xvYmFsKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWU6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlTGluZW5vc0dsb2JhbCA9IHZhbHVlIGFzIChcImFsd2F5cyBvblwiIHwgXCJkZWZhdWx0IG9uLCBidXQgb2ZmIHdoZW4gc3BlY2lmaWVkXCIgfCBcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIiB8IFwiYWx3YXlzIG9mZlwiKTtcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHQpO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZSgnRGVmYXVsdCBMaW5lIE51bWJlciBTdGFydCcpXG5cdFx0XHQuc2V0RGVzYygnVGhlIGRlZmF1bHQgbGluZSBudW1iZXIgc3RhcnQgb2YgdGhlIGNvZGUgYmxvY2suJylcblx0XHRcdC5hZGRUZXh0KHRjID0+XG5cdFx0XHRcdHRjLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRMaW5lbm9zU3RhcnQudG9TdHJpbmcoKSlcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiBzdHJpbmcpID0+IHtcblx0XHRcdFx0XHRcdGNvbnN0IG51bSA9IHBhcnNlSW50KHZhbHVlKTtcblx0XHRcdFx0XHRcdGlmIChpc05hTihudW0pKSByZXR1cm47XG5cblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRMaW5lbm9zU3RhcnQgPSBudW07XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KVxuXHRcdFx0KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ1Nob3cgTGluZSBOdW1iZXIgU3BsaXR0ZXInKVxuXHRcdFx0LmFkZFRvZ2dsZSh0YyA9PlxuXHRcdFx0XHR0Yy5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93TGluZW5vc1NwbGl0dGVyKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWU6IGJvb2xlYW4pID0+IHtcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dMaW5lbm9zU3BsaXR0ZXIgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHQpO1xuXG5cdFx0Ly8gbGluZSBoaWdobGlnaHRcblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdMaW5lIEhpZ2hsaWdodCcgfSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKCdVc2UgTGluZSBIaWdobGlnaHQnKVxuXHRcdFx0LnNldERlc2MoZnJhZ1dpdGhIVE1MKGAtIDxiPmRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWQ8L2I+IDogbGluZSBoaWdobGlnaHQgd2lsbCBvbmx5IGJlIHNob3duIGlmIHRoZSBsaW5lIGhpZ2hsaWdodCBzdGF0ZW1lbnQgaXMgc3BlY2lmaWVkXG5cdFx0XHRcdC0gPGI+YWx3YXlzIG9mZjwvYj4gOiBsaW5lIGhpZ2hsaWdodCB3aWxsIG5ldmVyIGJlIHNob3duYCkpXG5cdFx0XHQuYWRkRHJvcGRvd24odGMgPT5cblx0XHRcdFx0dGMuYWRkT3B0aW9ucyh7XG5cdFx0XHRcdFx0XCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCI6IFwiZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZFwiLFxuXHRcdFx0XHRcdFwiYWx3YXlzIG9mZlwiOiBcImFsd2F5cyBvZmZcIixcblx0XHRcdFx0fSlcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlSGlnaGxpZ2h0R2xvYmFsKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWU6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlSGlnaGxpZ2h0R2xvYmFsID0gdmFsdWUgYXMgKFwiZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZFwiIHwgXCJhbHdheXMgb2ZmXCIpO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKCdMaW5lIEhpZ2hsaWdodCBDb2xvcicpXG5cdFx0XHQuc2V0RGVzYygnVGhlIGJhY2tncm91bmQgY29sb3Igb2YgdGhlIGhpZ2hsaWdodGVkIGxpbmUuIE5vdGUgdGhhdCB0aGUgZ2l2ZW4gY29sb3Igd2lsbCBiZSBhcHBsaWVkIHdpdGggMC4yIG9wYWNpdHkuJylcblx0XHRcdC5hZGRUZXh0KHRjID0+XG5cdFx0XHRcdHRjLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmhpZ2hsaWdodENvbG9yKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWU6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuaGlnaGxpZ2h0Q29sb3IgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHQpO1xuXG5cdFx0Ly8gbGFuZ3VhZ2Vcblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdMYW5ndWFnZSBJbmRpY2F0b3InIH0pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZSgnVXNlIExhbmd1YWdlIEluZGljYXRvcicpXG5cdFx0XHQuc2V0RGVzYyhmcmFnV2l0aEhUTUwoYC0gPGI+YWx3YXlzIG9uPC9iPiA6IGxhbmd1YWdlIGluZGljYXRvciB3aWxsIGFsd2F5cyBiZSBzaG93blxuXHRcdFx0XHQtIDxiPmRlZmF1bHQgb24sIGJ1dCBvZmYgd2hlbiBzcGVjaWZpZWQ8L2I+IDogbGFuZ3VhZ2UgaW5kaWNhdG9yIHdpbGwgYWx3YXlzIGJlIHNob3duLCBidXQgd2lsbCBub3QgYmUgc2hvd24gaWYgdGhlIGxhbmd1YWdlIGluZGljYXRvciBzdGF0ZW1lbnQgaXMgc3BlY2lmaWVkIGFzIGZhbHNlXG5cdFx0XHRcdC0gPGI+ZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZDwvYj4gOiBsYW5ndWFnZSBpbmRpY2F0b3Igd2lsbCBvbmx5IGJlIHNob3duIGlmIHRoZSBsYW5ndWFnZSBpbmRpY2F0b3Igc3RhdGVtZW50IGlzIHNwZWNpZmllZCBhcyB0cnVlXG5cdFx0XHRcdC0gPGI+YWx3YXlzIG9mZjwvYj4gOiBsYW5ndWFnZSBpbmRpY2F0b3Igd2lsbCBuZXZlciBiZSBzaG93bmApKVxuXHRcdFx0LmFkZERyb3Bkb3duKHRjID0+XG5cdFx0XHRcdHRjLmFkZE9wdGlvbnMoe1xuXHRcdFx0XHRcdFwiYWx3YXlzIG9uXCI6IFwiYWx3YXlzIG9uXCIsXG5cdFx0XHRcdFx0XCJkZWZhdWx0IG9uLCBidXQgb2ZmIHdoZW4gc3BlY2lmaWVkXCI6IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiLFxuXHRcdFx0XHRcdFwiZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZFwiOiBcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIixcblx0XHRcdFx0XHRcImFsd2F5cyBvZmZcIjogXCJhbHdheXMgb2ZmXCIsXG5cdFx0XHRcdH0pXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZUxhbmd1YWdlR2xvYmFsKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWU6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlTGFuZ3VhZ2VHbG9iYWwgPSB2YWx1ZSBhcyAoXCJhbHdheXMgb25cIiB8IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiIHwgXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIgfCBcImFsd2F5cyBvZmZcIik7XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KVxuXHRcdFx0KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ0RlZmF1bHQgTGFuZ3VhZ2UnKVxuXHRcdFx0LnNldERlc2MoJ1RoZSBkZWZhdWx0IGxhbmd1YWdlIG5hbWUgb2YgdGhlIGNvZGUgYmxvY2sgaWYgdGhlIGxhbmd1YWdlIGlzIG5vdCBzcGVjaWZpZWQuJylcblx0XHRcdC5hZGRUZXh0KHRjID0+XG5cdFx0XHRcdHRjLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRMYW5ndWFnZSlcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiBzdHJpbmcpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRMYW5ndWFnZSA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0XG5cdFx0Ly8gY29weSBidXR0b25cblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdDb3B5IEJ1dHRvbicgfSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKCdVc2UgQ29weSBCdXR0b24nKVxuXHRcdFx0LnNldERlc2MoZnJhZ1dpdGhIVE1MKGAtIDxiPmFsd2F5cyBvbjwvYj4gOiBjb3B5IGJ1dHRvbiB3aWxsIGFsd2F5cyBiZSBzaG93blxuXHRcdFx0XHQtIDxiPmRlZmF1bHQgb24sIGJ1dCBvZmYgd2hlbiBzcGVjaWZpZWQ8L2I+IDogY29weSBidXR0b24gd2lsbCBhbHdheXMgYmUgc2hvd24sIGJ1dCB3aWxsIG5vdCBiZSBzaG93biBpZiB0aGUgY29weSBidXR0b24gc3RhdGVtZW50IGlzIHNwZWNpZmllZCBhcyBmYWxzZVxuXHRcdFx0XHQtIDxiPmRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWQ8L2I+IDogY29weSBidXR0b24gd2lsbCBvbmx5IGJlIHNob3duIGlmIHRoZSBjb3B5IGJ1dHRvbiBzdGF0ZW1lbnQgaXMgc3BlY2lmaWVkIGFzIHRydWVcblx0XHRcdFx0LSA8Yj5hbHdheXMgb2ZmPC9iPiA6IGNvcHkgYnV0dG9uIHdpbGwgbmV2ZXIgYmUgc2hvd25gKSlcblx0XHRcdC5hZGREcm9wZG93bih0YyA9PlxuXHRcdFx0XHR0Yy5hZGRPcHRpb25zKHtcblx0XHRcdFx0XHRcImFsd2F5cyBvblwiOiBcImFsd2F5cyBvblwiLFxuXHRcdFx0XHRcdFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiOiBcImRlZmF1bHQgb24sIGJ1dCBvZmYgd2hlbiBzcGVjaWZpZWRcIixcblx0XHRcdFx0XHRcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIjogXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIsXG5cdFx0XHRcdFx0XCJhbHdheXMgb2ZmXCI6IFwiYWx3YXlzIG9mZlwiLFxuXHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VDb3B5QnRuR2xvYmFsKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWU6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlQ29weUJ0bkdsb2JhbCA9IHZhbHVlIGFzIChcImFsd2F5cyBvblwiIHwgXCJkZWZhdWx0IG9uLCBidXQgb2ZmIHdoZW4gc3BlY2lmaWVkXCIgfCBcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIiB8IFwiYWx3YXlzIG9mZlwiKTtcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHQpO1xuXG5cdFx0Ly8gcHJvbXB0XG5cdFx0Y29udGFpbmVyRWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnUHJvbXB0JyB9KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ1VzZSBQcm9tcHQnKVxuXHRcdFx0LnNldERlc2MoZnJhZ1dpdGhIVE1MKGAtIDxiPmFsd2F5cyBvbjwvYj4gOiBwcm9tcHQgd2lsbCBhbHdheXMgYmUgc2hvd25cblx0XHRcdFx0LSA8Yj5kZWZhdWx0IG9uLCBidXQgb2ZmIHdoZW4gc3BlY2lmaWVkPC9iPiA6IHByb21wdCB3aWxsIGFsd2F5cyBiZSBzaG93biwgYnV0IHdpbGwgbm90IGJlIHNob3duIGlmIHRoZSBwcm9tcHQgc3RhdGVtZW50IGlzIHNwZWNpZmllZCBhcyBmYWxzZVxuXHRcdFx0XHQtIDxiPmRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWQ8L2I+IDogcHJvbXB0IHdpbGwgb25seSBiZSBzaG93biBpZiB0aGUgcHJvbXB0IHN0YXRlbWVudCBpcyBzcGVjaWZpZWQgYXMgdHJ1ZVxuXHRcdFx0XHQtIDxiPmFsd2F5cyBvZmY8L2I+IDogcHJvbXB0IHdpbGwgbmV2ZXIgYmUgc2hvd25gKSlcblx0XHRcdC5hZGREcm9wZG93bih0YyA9PlxuXHRcdFx0XHR0Yy5hZGRPcHRpb25zKHtcblx0XHRcdFx0XHRcImFsd2F5cyBvblwiOiBcImFsd2F5cyBvblwiLFxuXHRcdFx0XHRcdFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiOiBcImRlZmF1bHQgb24sIGJ1dCBvZmYgd2hlbiBzcGVjaWZpZWRcIixcblx0XHRcdFx0XHRcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIjogXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIsXG5cdFx0XHRcdFx0XCJhbHdheXMgb2ZmXCI6IFwiYWx3YXlzIG9mZlwiLFxuXHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VQcm9tcHRHbG9iYWwpXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZTogc3RyaW5nKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VQcm9tcHRHbG9iYWwgPSB2YWx1ZSBhcyAoXCJhbHdheXMgb25cIiB8IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiIHwgXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIgfCBcImFsd2F5cyBvZmZcIik7XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KVxuXHRcdFx0KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ1Byb21wdGluZyBMYW5ndWFnZXMnKVxuXHRcdFx0LnNldERlc2MoJ1RoZSBsYW5ndWFnZXMgdGhhdCB3aWxsIGJlIHByb21wdGVkIGJ5IGRlZmF1bHQuIFlvdSBjYW4gc3BlY2lmeSBtdWx0aXBsZSBsYW5ndWFnZXMgYnkgc2VwYXJhdGluZyB0aGVtIHdpdGggZW50ZXJzLicpXG5cdFx0XHQuYWRkVGV4dEFyZWEodGMgPT5cblx0XHRcdFx0dGMuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MucHJvbXB0aW5nTGFuZ3VhZ2VzLmpvaW4oXCJcXG5cIikpXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZTogc3RyaW5nKSA9PiB7XG5cdFx0XHRcdFx0XHRjb25zdCBsaW5lcyA9IHZhbHVlLnNwbGl0KFwiXFxuXCIpLmZpbHRlcihsaW5lID0+IGxpbmUudHJpbSgpICE9PSBcIlwiKTtcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnByb21wdGluZ0xhbmd1YWdlcyA9IGxpbmVzO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiRGVmYXVsdCBQcm9tcHRcIilcblx0XHRcdC5zZXREZXNjKFwiVGhlIGRlZmF1bHQgcHJvbXB0IG9mIHRoZSBiYXNoIGNvZGUgYmxvY2suXCIpXG5cdFx0XHQuYWRkVGV4dCh0YyA9PlxuXHRcdFx0XHR0Yy5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0UHJvbXB0KVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWU6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdFByb21wdCA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHQvLyByZXN1bHRcblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdSZXN1bHQnIH0pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZSgnVXNlIFJlc3VsdCcpXG5cdFx0XHQuc2V0RGVzYyhmcmFnV2l0aEhUTUwoYC0gPGI+ZW5hYmxlPC9iPiA6IHRyZWF0IHRoZSBjb2RlIGJsb2NrIHN0YXJ0cyBsaWtlIFxcYFxcYFxcYFxcYHJlc3VsdFxcYCBhcyB0aGUgcmVzdWx0IG9mIHRoZSBhZGphY2VudCBwcmV2aW91cyBjb2RlIGJsb2NrXG5cdFx0XHRcdC0gPGI+ZGlzYWJsZTwvYj4gOiB0cmVhdCB0aGUgY29kZSBibG9jayB3aXRoIFxcYHJlc3VsdFxcYCBhcyBpdHMgbGFuZ3VhZ2UgbmFtZSBhcyBhIG5vcm1hbCBjb2RlIGJsb2NrYCkpXG5cdFx0XHQuYWRkRHJvcGRvd24odGMgPT5cblx0XHRcdFx0dGMuYWRkT3B0aW9ucyh7XG5cdFx0XHRcdFx0XCJlbmFibGVcIjogXCJlbmFibGVcIixcblx0XHRcdFx0XHRcImRpc2FibGVcIjogXCJkaXNhYmxlXCIsXG5cdFx0XHRcdH0pXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZVJlc3VsdEdsb2JhbClcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiBzdHJpbmcpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZVJlc3VsdEdsb2JhbCA9IHZhbHVlIGFzIChcImVuYWJsZVwiIHwgXCJkaXNhYmxlXCIpO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiRGVmYXVsdCBSZXN1bHQgUHJvbXB0XCIpXG5cdFx0XHQuc2V0RGVzYyhcIlRoZSBkZWZhdWx0IHByb21wdCBvZiB0aGUgcmVzdWx0IGNvZGUgYmxvY2suXCIpXG5cdFx0XHQuYWRkVGV4dCh0YyA9PlxuXHRcdFx0XHR0Yy5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0UmVzdWx0UHJvbXB0KVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWU6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdFJlc3VsdFByb21wdCA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHQvLyBmb3IgZGV2ZWxvcGVyc1xuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ0RldmVsb3BlcnMnIH0pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZSgnRGVidWcgTW9kZScpXG5cdFx0XHQuc2V0RGVzYygnU2hvdyBsb2dzIGluIHRoZSBjb25zb2xlLicpXG5cdFx0XHQuYWRkVG9nZ2xlKHRjID0+XG5cdFx0XHRcdHRjLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmRlYnVnTW9kZSlcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiBib29sZWFuKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWJ1Z01vZGUgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHQpO1xuXHR9XG59IiwgImltcG9ydCB7IE1hcmtkb3duVmlldyB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHR5cGUgeyBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0LCBNYXJrZG93blNlY3Rpb25JbmZvcm1hdGlvbiB9IGZyb20gXCJvYnNpZGlhblwiO1xuXG5pbXBvcnQgSEtDb2RlQmxvY2tQbHVnaW4gZnJvbSBcIi4vbWFpblwiO1xuaW1wb3J0IHR5cGUgeyBIS0NvZGVCbG9ja1NldHRpbmdzIH0gZnJvbSBcIi4vSEtDb2RlQmxvY2tTZXR0aW5nc1wiO1xuXG5jb25zdCBSRUdFWCA9IHtcbiAgVElUTEU6IC9cXHN0aXRsZTooPzonKC4qPyknfFwiKC4qPylcIilcXHMvLFxuICBDT0xMQVBTSUJMRV9TSU1QTEU6IC9cXHNjb2xsYXBzaWJsZVxccy8sXG4gIENPTExBUFNJQkxFX0NPTVBMSUNBVEU6IC9cXHNjb2xsYXBzaWJsZToodHJ1ZXxmYWxzZSlcXHMvLFxuICBMSU5FTk9TX1NJTVBMRTogL1xcc2xpbmVub3NcXHMvLFxuICBMSU5FTk9TX0NPTVBMSUNBVEU6IC9cXHNsaW5lbm9zOih0cnVlfGZhbHNlfCgtezAsMX1cXGQrKSlcXHMvLFxuICBISUdITElHSFQ6IC9cXHNoaWdobGlnaHQ6KD86JyguKj8pJ3xcIiguKj8pXCIpXFxzLyxcbiAgTEFOR1VBR0VfRlJPTV9DTEFTUzogL15sYW5ndWFnZS0oXFx3KykkLyxcbiAgTEFOR1VBR0VfU0lNUExFOiAvXFxzbGFuZ3VhZ2VcXHMvLFxuICBMQU5HVUFHRV9DT01QTElDQVRFOiAvXFxzbGFuZ3VhZ2U6KHRydWV8ZmFsc2V8JyguKj8pJ3xcIiguKj8pXCIpXFxzLyxcbiAgQ09QWUJUTl9TSU1QTEU6IC9cXHNjb3B5YnRuXFxzLyxcbiAgQ09QWUJUTl9DT01QTElDQVRFOiAvXFxzY29weWJ0bjoodHJ1ZXxmYWxzZSlcXHMvLFxuICBSRVNVTFQ6IC9eYGBgcmVzdWx0XFxzLyxcbiAgUFJPTVBUX1NJTVBMRTogL1xcc3Byb21wdFxccy8sXG4gIFBST01QVF9DT01QTElDQVRFOiAvXFxzcHJvbXB0Oih0cnVlfGZhbHNlfCcoLio/KSd8XCIoLio/KVwiKVxccy8sXG59XG5cbmZ1bmN0aW9uIGdldE1ldGEodmlldzogTWFya2Rvd25WaWV3LCBlbGVtX2NvZGU6IEhUTUxFbGVtZW50LCBzZWN0aW9uX2NvZGU6IE1hcmtkb3duU2VjdGlvbkluZm9ybWF0aW9uLCBzZXR0aW5nczogSEtDb2RlQmxvY2tTZXR0aW5ncyk6IHtcbiAgc2hvd1RpdGxlOiAoYm9vbGVhbiB8IHVuZGVmaW5lZCksXG4gIHRpdGxlOiBzdHJpbmcsXG4gIGlzQ29sbGFwc2libGU6IChib29sZWFuIHwgdW5kZWZpbmVkKSxcbiAgc2hvd0xpbmVub3M6IChib29sZWFuIHwgdW5kZWZpbmVkKSxcbiAgbGluZW5vc1N0YXJ0OiBudW1iZXIsXG4gIGxpbmVub3NOdW06IG51bWJlcixcbiAgc2hvd0hpZ2hsaWdodDogKGJvb2xlYW4gfCB1bmRlZmluZWQpLFxuICBoaWdobGlnaHRMaW5lczogbnVtYmVyW10sXG4gIHNob3dMYW5ndWFnZTogKGJvb2xlYW4gfCB1bmRlZmluZWQpLFxuICBsYW5ndWFnZTogc3RyaW5nLFxuICBzaG93Q29weUJ0bjogKGJvb2xlYW4gfCB1bmRlZmluZWQpLFxuICBpc1Jlc3VsdDogYm9vbGVhbixcbiAgcmVzdWx0UHJvbXB0OiBzdHJpbmcsXG4gIHNob3dQcm9tcHQ6IChib29sZWFuIHwgdW5kZWZpbmVkKSxcbiAgcHJvbXB0OiBzdHJpbmdcbn0ge1xuICBjb25zdCBmaXJzdGxpbmUgPSB2aWV3LmVkaXRvci5nZXRMaW5lKHNlY3Rpb25fY29kZS5saW5lU3RhcnQpICsgXCIgXCI7IC8vIGFkZCBhIHNwYWNlIHRvIHRoZSBlbmQgb2YgdGhlIGxpbmUgdG8gbWFrZSBzdXJlIHRoZSByZWdleCB3b3Jrc1xuXG4gIC8vIHRpdGxlXG4gIGxldCBzaG93VGl0bGU6IChib29sZWFuIHwgdW5kZWZpbmVkKSA9IHVuZGVmaW5lZDtcbiAgbGV0IHRpdGxlID0gXCJcIjtcbiAgY29uc3QgcmVnZXhSZXN1bHRfdGl0bGUgPSBSRUdFWC5USVRMRS5leGVjKGZpcnN0bGluZSk7XG4gIGlmIChyZWdleFJlc3VsdF90aXRsZSkge1xuICAgIHNob3dUaXRsZSA9IHRydWU7XG4gICAgdGl0bGUgPSByZWdleFJlc3VsdF90aXRsZVsxXSB8fCByZWdleFJlc3VsdF90aXRsZVsyXTtcbiAgfVxuXG4gIC8vIGNvbGxhcHNpYmxlXG4gIGxldCBpc0NvbGxhcHNpYmxlOiAoYm9vbGVhbiB8IHVuZGVmaW5lZCkgPSB1bmRlZmluZWQ7XG4gIGNvbnN0IHJlZ2V4UmVzdWx0X2NvbGxhcHNpYmxlU2ltcGxlID0gUkVHRVguQ09MTEFQU0lCTEVfU0lNUExFLmV4ZWMoZmlyc3RsaW5lKTtcbiAgY29uc3QgcmVnZXhSZXN1bHRfY29sbGFwc2libGVDb21wbGljYXRlID0gUkVHRVguQ09MTEFQU0lCTEVfQ09NUExJQ0FURS5leGVjKGZpcnN0bGluZSk7XG4gIGlmIChyZWdleFJlc3VsdF9jb2xsYXBzaWJsZVNpbXBsZSkge1xuICAgIGlzQ29sbGFwc2libGUgPSB0cnVlO1xuICB9IGVsc2UgaWYgKHJlZ2V4UmVzdWx0X2NvbGxhcHNpYmxlQ29tcGxpY2F0ZSkge1xuICAgIGlmIChyZWdleFJlc3VsdF9jb2xsYXBzaWJsZUNvbXBsaWNhdGVbMV0gPT09IFwidHJ1ZVwiKSB7XG4gICAgICBpc0NvbGxhcHNpYmxlID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHJlZ2V4UmVzdWx0X2NvbGxhcHNpYmxlQ29tcGxpY2F0ZVsxXSA9PT0gXCJmYWxzZVwiKSB7XG4gICAgICBpc0NvbGxhcHNpYmxlID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLy8gbGluZW5vc1xuICBsZXQgc2hvd0xpbmVub3M6IChib29sZWFuIHwgdW5kZWZpbmVkKSA9IHVuZGVmaW5lZDtcbiAgbGV0IGxpbmVub3NTdGFydCA9IHNldHRpbmdzLmRlZmF1bHRMaW5lbm9zU3RhcnQ7XG4gIGNvbnN0IGxpbmVub3NOdW0gPSBzZWN0aW9uX2NvZGUubGluZUVuZCAtIHNlY3Rpb25fY29kZS5saW5lU3RhcnQgLSAxO1xuICBjb25zdCByZWdleFJlc3VsdF9saW5lbm9zU2ltcGxlID0gUkVHRVguTElORU5PU19TSU1QTEUuZXhlYyhmaXJzdGxpbmUpO1xuICBjb25zdCByZWdleFJlc3VsdF9saW5lbm9zQ29tcGxpY2F0ZSA9IFJFR0VYLkxJTkVOT1NfQ09NUExJQ0FURS5leGVjKGZpcnN0bGluZSk7XG4gIGlmIChyZWdleFJlc3VsdF9saW5lbm9zU2ltcGxlKSB7XG4gICAgc2hvd0xpbmVub3MgPSB0cnVlO1xuICB9IGVsc2UgaWYgKHJlZ2V4UmVzdWx0X2xpbmVub3NDb21wbGljYXRlKSB7XG4gICAgaWYgKHJlZ2V4UmVzdWx0X2xpbmVub3NDb21wbGljYXRlWzFdID09PSBcInRydWVcIikge1xuICAgICAgc2hvd0xpbmVub3MgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAocmVnZXhSZXN1bHRfbGluZW5vc0NvbXBsaWNhdGVbMV0gPT09IFwiZmFsc2VcIikge1xuICAgICAgc2hvd0xpbmVub3MgPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2hvd0xpbmVub3MgPSB0cnVlO1xuICAgICAgbGluZW5vc1N0YXJ0ID0gcGFyc2VJbnQocmVnZXhSZXN1bHRfbGluZW5vc0NvbXBsaWNhdGVbMl0pIHx8IDE7XG4gICAgfVxuICB9XG5cbiAgLy8gaGlnaGxpZ2h0XG4gIGxldCBzaG93SGlnaGxpZ2h0OiAoYm9vbGVhbiB8IHVuZGVmaW5lZCkgPSB1bmRlZmluZWQ7XG4gIGxldCBoaWdobGlnaHRMaW5lczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgcmVnZXhSZXN1bHRfaGlnaGxpZ2h0ID0gUkVHRVguSElHSExJR0hULmV4ZWMoZmlyc3RsaW5lKTtcbiAgaWYgKHJlZ2V4UmVzdWx0X2hpZ2hsaWdodCkge1xuICAgIHNob3dIaWdobGlnaHQgPSB0cnVlO1xuICAgIGNvbnN0IGhpZ2hsaWdodExpbmVzX3N0ciA9IHJlZ2V4UmVzdWx0X2hpZ2hsaWdodFsxXSB8fCByZWdleFJlc3VsdF9oaWdobGlnaHRbMl07XG4gICAgaGlnaGxpZ2h0TGluZXMgPSBoaWdobGlnaHRMaW5lc19zdHIuc3BsaXQoXCIsXCIpLm1hcCgobGluZSkgPT4gcGFyc2VJbnQobGluZSkpO1xuXG4gICAgaWYgKGhpZ2hsaWdodExpbmVzLnNvbWUoKGxpbmUpID0+IGlzTmFOKGxpbmUpKSkge1xuICAgICAgLy8gaWYgYW55IGVsZW1lbnQgaXMgbmFuLCB0aGVuIHNldCBzaG93SGlnaGxpZ2h0IHRvIGZhbHNlXG4gICAgICBzaG93SGlnaGxpZ2h0ID0gdW5kZWZpbmVkO1xuICAgICAgaGlnaGxpZ2h0TGluZXMgPSBbXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdXNlIG9ubHkgdmFsaWQgbGluZSBudW1iZXJzXG4gICAgICBoaWdobGlnaHRMaW5lcyA9IGhpZ2hsaWdodExpbmVzLmZpbHRlcigobGluZSkgPT4gbGluZSA+PSBsaW5lbm9zU3RhcnQgJiYgbGluZSA8IGxpbmVub3NTdGFydCArIGxpbmVub3NOdW0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIGxhbmd1YWdlXG4gIGxldCBzaG93TGFuZ3VhZ2U6IChib29sZWFuIHwgdW5kZWZpbmVkKSA9IHVuZGVmaW5lZDtcbiAgbGV0IGxhbmd1YWdlID0gKCgpID0+IHtcbiAgICBsZXQgbGFuZ3VhZ2UgPSBzZXR0aW5ncy5kZWZhdWx0TGFuZ3VhZ2U7XG4gICAgZWxlbV9jb2RlLmNsYXNzTGlzdC5mb3JFYWNoKChjbGFzc05hbWUpID0+IHtcbiAgICAgIGNvbnN0IHJlZ2V4UmVzdWx0X2xhbmd1YWdlRnJvbUNsYXNzID0gUkVHRVguTEFOR1VBR0VfRlJPTV9DTEFTUy5leGVjKGNsYXNzTmFtZS50cmltKCkpO1xuICAgICAgaWYgKHJlZ2V4UmVzdWx0X2xhbmd1YWdlRnJvbUNsYXNzKSBsYW5ndWFnZSA9IHJlZ2V4UmVzdWx0X2xhbmd1YWdlRnJvbUNsYXNzWzFdO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGxhbmd1YWdlO1xuICB9KSgpO1xuICBjb25zdCByZWdleFJlc3VsdF9sYW5ndWFnZVNpbXBsZSA9IFJFR0VYLkxBTkdVQUdFX1NJTVBMRS5leGVjKGZpcnN0bGluZSk7XG4gIGNvbnN0IHJlZ2V4UmVzdWx0X2xhbmd1YWdlQ29tcGxpY2F0ZSA9IFJFR0VYLkxBTkdVQUdFX0NPTVBMSUNBVEUuZXhlYyhmaXJzdGxpbmUpO1xuICBpZiAocmVnZXhSZXN1bHRfbGFuZ3VhZ2VTaW1wbGUpIHtcbiAgICBzaG93TGFuZ3VhZ2UgPSB0cnVlO1xuICB9IGVsc2UgaWYgKHJlZ2V4UmVzdWx0X2xhbmd1YWdlQ29tcGxpY2F0ZSkge1xuICAgIGlmIChyZWdleFJlc3VsdF9sYW5ndWFnZUNvbXBsaWNhdGVbMV0gPT09IFwidHJ1ZVwiKSB7XG4gICAgICBzaG93TGFuZ3VhZ2UgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAocmVnZXhSZXN1bHRfbGFuZ3VhZ2VDb21wbGljYXRlWzFdID09PSBcImZhbHNlXCIpIHtcbiAgICAgIHNob3dMYW5ndWFnZSA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBzaG93TGFuZ3VhZ2UgPSB0cnVlO1xuICAgICAgbGFuZ3VhZ2UgPSByZWdleFJlc3VsdF9sYW5ndWFnZUNvbXBsaWNhdGVbMl0gfHwgcmVnZXhSZXN1bHRfbGFuZ3VhZ2VDb21wbGljYXRlWzNdO1xuICAgIH1cbiAgfVxuXG4gIC8vIGNvcHkgYnV0dG9uXG4gIGxldCBzaG93Q29weUJ0bjogKGJvb2xlYW4gfCB1bmRlZmluZWQpID0gdW5kZWZpbmVkO1xuICBjb25zdCByZWdleFJlc3VsdF9jb3B5QnRuU2ltcGxlID0gUkVHRVguQ09QWUJUTl9TSU1QTEUuZXhlYyhmaXJzdGxpbmUpO1xuICBjb25zdCByZWdleFJlc3VsdF9jb3B5QnRuQ29tcGxpY2F0ZSA9IFJFR0VYLkNPUFlCVE5fQ09NUExJQ0FURS5leGVjKGZpcnN0bGluZSk7XG4gIGlmIChyZWdleFJlc3VsdF9jb3B5QnRuU2ltcGxlKSB7XG4gICAgc2hvd0NvcHlCdG4gPSB0cnVlO1xuICB9IGVsc2UgaWYgKHJlZ2V4UmVzdWx0X2NvcHlCdG5Db21wbGljYXRlKSB7XG4gICAgaWYgKHJlZ2V4UmVzdWx0X2NvcHlCdG5Db21wbGljYXRlWzFdID09PSBcInRydWVcIikge1xuICAgICAgc2hvd0NvcHlCdG4gPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAocmVnZXhSZXN1bHRfY29weUJ0bkNvbXBsaWNhdGVbMV0gPT09IFwiZmFsc2VcIikge1xuICAgICAgc2hvd0NvcHlCdG4gPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvLyBwcm9tcHRcbiAgbGV0IHNob3dQcm9tcHQ6IChib29sZWFuIHwgdW5kZWZpbmVkKSA9IHVuZGVmaW5lZDtcbiAgbGV0IHByb21wdCA9IHNldHRpbmdzLmRlZmF1bHRQcm9tcHQ7XG4gIGNvbnN0IHJlZ2V4UmVzdWx0X3Byb21wdFNpbXBsZSA9IFJFR0VYLlBST01QVF9TSU1QTEUuZXhlYyhmaXJzdGxpbmUpO1xuICBjb25zdCByZWdleFJlc3VsdF9wcm9tcHRDb21wbGljYXRlID0gUkVHRVguUFJPTVBUX0NPTVBMSUNBVEUuZXhlYyhmaXJzdGxpbmUpO1xuICBpZiAocmVnZXhSZXN1bHRfcHJvbXB0U2ltcGxlKSB7XG4gICAgc2hvd1Byb21wdCA9IHRydWU7XG4gIH0gZWxzZSBpZiAocmVnZXhSZXN1bHRfcHJvbXB0Q29tcGxpY2F0ZSkge1xuICAgIGlmIChyZWdleFJlc3VsdF9wcm9tcHRDb21wbGljYXRlWzFdID09PSBcInRydWVcIikge1xuICAgICAgc2hvd1Byb21wdCA9IHRydWU7XG4gICAgfSBlbHNlIGlmIChyZWdleFJlc3VsdF9wcm9tcHRDb21wbGljYXRlWzFdID09PSBcImZhbHNlXCIpIHtcbiAgICAgIHNob3dQcm9tcHQgPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2hvd1Byb21wdCA9IHRydWU7XG4gICAgICBwcm9tcHQgPSByZWdleFJlc3VsdF9wcm9tcHRDb21wbGljYXRlWzJdIHx8IHJlZ2V4UmVzdWx0X3Byb21wdENvbXBsaWNhdGVbM107XG4gICAgfVxuICB9XG5cbiAgLy8gcmVzdWx0XG4gIGxldCBpc1Jlc3VsdCA9IGZhbHNlO1xuICBsZXQgcmVzdWx0UHJvbXB0ID0gc2V0dGluZ3MuZGVmYXVsdFJlc3VsdFByb21wdDtcbiAgY29uc3QgcmVnZXhSZXN1bHRfcmVzdWx0ID0gUkVHRVguUkVTVUxULmV4ZWMoZmlyc3RsaW5lKTtcbiAgY29uc3QgcmVnZXhSZXN1bHRQcm9tcHRfcmVzdWx0ID0gUkVHRVguUFJPTVBUX0NPTVBMSUNBVEUuZXhlYyhmaXJzdGxpbmUpO1xuICBpZiAocmVnZXhSZXN1bHRfcmVzdWx0KSB7XG4gICAgaXNSZXN1bHQgPSB0cnVlO1xuXG4gICAgLy8gb3ZlcnJpZGUgb3RoZXIgbWV0YSBkYXRhIDogb25seSBsaW5lbm9zLCBoaWdobGlnaHQgYXJlIGF2YWlsYWJsZVxuICAgIHNob3dUaXRsZSA9IGZhbHNlO1xuICAgIHNob3dMYW5ndWFnZSA9IGZhbHNlO1xuICAgIHNob3dDb3B5QnRuID0gZmFsc2U7XG4gICAgc2hvd1Byb21wdCA9IGZhbHNlO1xuXG4gICAgaWYgKHJlZ2V4UmVzdWx0UHJvbXB0X3Jlc3VsdCkge1xuICAgICAgcmVzdWx0UHJvbXB0ID0gcmVnZXhSZXN1bHRQcm9tcHRfcmVzdWx0WzJdIHx8IHJlZ2V4UmVzdWx0UHJvbXB0X3Jlc3VsdFszXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHNob3dUaXRsZTogc2hvd1RpdGxlLFxuICAgIHRpdGxlOiB0aXRsZSxcbiAgICBpc0NvbGxhcHNpYmxlOiBpc0NvbGxhcHNpYmxlLFxuICAgIHNob3dMaW5lbm9zOiBzaG93TGluZW5vcyxcbiAgICBsaW5lbm9zU3RhcnQ6IGxpbmVub3NTdGFydCxcbiAgICBsaW5lbm9zTnVtOiBsaW5lbm9zTnVtLFxuICAgIHNob3dIaWdobGlnaHQ6IHNob3dIaWdobGlnaHQsXG4gICAgaGlnaGxpZ2h0TGluZXM6IGhpZ2hsaWdodExpbmVzLFxuICAgIHNob3dMYW5ndWFnZTogc2hvd0xhbmd1YWdlLFxuICAgIGxhbmd1YWdlOiBsYW5ndWFnZSxcbiAgICBzaG93Q29weUJ0bjogc2hvd0NvcHlCdG4sXG4gICAgaXNSZXN1bHQ6IGlzUmVzdWx0LFxuICAgIHJlc3VsdFByb21wdDogcmVzdWx0UHJvbXB0LFxuICAgIHNob3dQcm9tcHQ6IHNob3dQcm9tcHQsXG4gICAgcHJvbXB0OiBwcm9tcHRcbiAgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIEhLQ29kZUJsb2NrUHJvY2Vzc29yKFxuICBlbDogSFRNTEVsZW1lbnQsXG4gIGNvbnRleHQ6IE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsXG4gIHBsdWdpbjogSEtDb2RlQmxvY2tQbHVnaW5cbikge1xuICBjb25zdCBzZXR0aW5ncyA9IHBsdWdpbi5zZXR0aW5ncztcblxuICBjb25zdCB2aWV3ID0gYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldyk7XG4gIGlmICghdmlldykgcmV0dXJuO1xuXG4gIGNvbnN0IGVsZW1fY29kZTogKEhUTUxFbGVtZW50IHwgbnVsbCkgPSBlbC5xdWVyeVNlbGVjdG9yKFwicHJlOm5vdCguZnJvbnRtYXR0ZXIpID4gY29kZVwiKTtcbiAgaWYgKCFlbGVtX2NvZGUpIHJldHVybjtcblxuICBjb25zdCBlbGVtX3ByZTogKEhUTUxFbGVtZW50IHwgbnVsbCkgPSBlbGVtX2NvZGUucGFyZW50RWxlbWVudDtcbiAgaWYgKCFlbGVtX3ByZSkgcmV0dXJuO1xuXG4gIGNvbnN0IGVsZW1fZGl2OiAoSFRNTEVsZW1lbnQgfCBudWxsKSA9IGVsZW1fcHJlLnBhcmVudEVsZW1lbnQ7XG4gIGlmICghZWxlbV9kaXYpIHJldHVybjtcblxuICBjb25zdCBlbGVtX2NvcHlCdG46IChIVE1MRWxlbWVudCB8IG51bGwpID0gZWxlbV9kaXYucXVlcnlTZWxlY3RvcihcIi5jb3B5LWNvZGUtYnV0dG9uXCIpO1xuICBpZiAoIWVsZW1fY29weUJ0bikgcmV0dXJuO1xuXG4gIGNvbnN0IHNlY3Rpb25fY29kZTogKE1hcmtkb3duU2VjdGlvbkluZm9ybWF0aW9uIHwgbnVsbCkgPSBjb250ZXh0LmdldFNlY3Rpb25JbmZvKGVsZW1fY29kZSk7XG4gIGlmICghc2VjdGlvbl9jb2RlKSByZXR1cm47XG5cbiAgLy8gZ2V0IG1ldGFkYXRhXG4gIGNvbnN0IHtcbiAgICBzaG93VGl0bGUsXG4gICAgdGl0bGUsXG4gICAgaXNDb2xsYXBzaWJsZSxcbiAgICBzaG93TGluZW5vcyxcbiAgICBsaW5lbm9zU3RhcnQsXG4gICAgbGluZW5vc051bSxcbiAgICBzaG93SGlnaGxpZ2h0LFxuICAgIGhpZ2hsaWdodExpbmVzLFxuICAgIHNob3dMYW5ndWFnZSxcbiAgICBsYW5ndWFnZSxcbiAgICBzaG93Q29weUJ0bixcbiAgICBpc1Jlc3VsdCxcbiAgICByZXN1bHRQcm9tcHQsXG4gICAgc2hvd1Byb21wdCxcbiAgICBwcm9tcHRcbiAgfSA9IGdldE1ldGEodmlldywgZWxlbV9jb2RlLCBzZWN0aW9uX2NvZGUsIHNldHRpbmdzKTtcblxuICBpZiAoc2V0dGluZ3MuZGVidWdNb2RlKSB7XG4gICAgY29uc29sZS5sb2coe1xuICAgICAgc2hvd1RpdGxlOiBzaG93VGl0bGUsXG4gICAgICB0aXRsZTogdGl0bGUsXG4gICAgICBzaG93TGluZW5vczogc2hvd0xpbmVub3MsXG4gICAgICBsaW5lbm9zU3RhcnQ6IGxpbmVub3NTdGFydCxcbiAgICAgIGxpbmVub3NOdW06IGxpbmVub3NOdW0sXG4gICAgICBzaG93SGlnaGxpZ2h0OiBzaG93SGlnaGxpZ2h0LFxuICAgICAgaGlnaGxpZ2h0TGluZXM6IGhpZ2hsaWdodExpbmVzLFxuICAgICAgc2hvd0xhbmd1YWdlOiBzaG93TGFuZ3VhZ2UsXG4gICAgICBsYW5ndWFnZTogbGFuZ3VhZ2UsXG4gICAgICBzaG93Q29weUJ0bjogc2hvd0NvcHlCdG4sXG4gICAgICBpc1Jlc3VsdDogaXNSZXN1bHQsXG4gICAgICByZXN1bHRQcm9tcHQ6IHJlc3VsdFByb21wdCxcbiAgICAgIHNob3dQcm9tcHQ6IHNob3dQcm9tcHQsXG4gICAgICBwcm9tcHQ6IHByb21wdCxcbiAgICB9KVxuICB9XG5cbiAgLy8gY3JlYXRlIEhUTUwgZWxlbWVudHNcbiAgZWxlbV9kaXYuY2xhc3NMaXN0LmFkZChcImhrLWNvZGVibG9ja1wiKTtcbiAgZWxlbV9jb2RlLmNsYXNzTGlzdC5hZGQoXCJoay1jb2RlYmxvY2stY29kZVwiKTtcbiAgZWxlbV9jb3B5QnRuLnJlbW92ZSgpOyAvLyByZW1vdmUgdGhlIG9yaWdpbmFsIGNvcHkgYnV0dG9uIGFzIGRlZmF1bHRcblxuICBsZXQgZWxlbV90aXRsZTogKEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkKSA9IHVuZGVmaW5lZDtcbiAgaWYgKHNldHRpbmdzLnVzZVRpdGxlR2xvYmFsID09PSBcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIiAmJiAoc2hvd1RpdGxlID09PSB0cnVlKSkge1xuICAgIGVsZW1fZGl2LmNsYXNzTGlzdC5hZGQoXCJoay1jb2RlYmxvY2stc2hvdy10aXRsZVwiKTtcblxuICAgIGVsZW1fdGl0bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIGVsZW1fdGl0bGUuY2xhc3NMaXN0LmFkZChcImhrLWNvZGVibG9jay10aXRsZVwiKTtcbiAgICBlbGVtX3RpdGxlLmlubmVySFRNTCA9IHRpdGxlO1xuICAgIGVsZW1fZGl2Lmluc2VydEJlZm9yZShlbGVtX3RpdGxlLCBlbGVtX3ByZSk7XG4gIH1cblxuICBpZiAoXG4gICAgKHNldHRpbmdzLnVzZUNvbGxhcHNpYmxlR2xvYmFsID09PSBcImFsd2F5cyBvblwiKSB8fFxuICAgIChzZXR0aW5ncy51c2VDb2xsYXBzaWJsZUdsb2JhbCA9PT0gXCJkZWZhdWx0IG9uLCBidXQgb2ZmIHdoZW4gc3BlY2lmaWVkXCIgJiYgKGlzQ29sbGFwc2libGUgPT09IHVuZGVmaW5lZCB8fCBpc0NvbGxhcHNpYmxlID09PSB0cnVlKSkgfHxcbiAgICAoc2V0dGluZ3MudXNlQ29sbGFwc2libGVHbG9iYWwgPT09IFwiZGVmYXVsdCBvZmYsIGJ1dCBvbiB3aGVuIHNwZWNpZmllZFwiICYmIChpc0NvbGxhcHNpYmxlID09PSB0cnVlKSlcbiAgKSB7XG4gICAgZWxlbV9kaXYuY2xhc3NMaXN0LmFkZChcImhrLWNvZGVibG9jay1jb2xsYXBzaWJsZVwiKTtcblxuICAgIGlmIChzZXR0aW5ncy5kZWZhdWx0Q29sbGFwc2UgPT09IFwiY29sbGFwc2VcIikge1xuICAgICAgZWxlbV9kaXYuY2xhc3NMaXN0LmFkZChcImhrLWNvZGVibG9jay1jb2xsYXBzZWRcIik7XG4gICAgfVxuXG4gICAgaWYgKGVsZW1fdGl0bGUpIHtcbiAgICAgIGVsZW1fdGl0bGUuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChldikgPT4ge1xuICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKGVsZW1fZGl2LmNsYXNzTGlzdC5jb250YWlucyhcImhrLWNvZGVibG9jay1jb2xsYXBzZWRcIikpIHtcbiAgICAgICAgICBlbGVtX2Rpdi5jbGFzc0xpc3QucmVtb3ZlKFwiaGstY29kZWJsb2NrLWNvbGxhcHNlZFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbGVtX2Rpdi5jbGFzc0xpc3QuYWRkKFwiaGstY29kZWJsb2NrLWNvbGxhcHNlZFwiKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGVsZW1fY29sbGFwc2VCdG5zID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgIGVsZW1fY29sbGFwc2VCdG5zLmNsYXNzTGlzdC5hZGQoXCJoay1jb2RlYmxvY2stY29sbGFwc2UtYnRuc1wiKTtcblxuICAgICAgY29uc3QgZWxlbV9jb2xsYXBzZUJ0biA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBlbGVtX2NvbGxhcHNlQnRuLmNsYXNzTGlzdC5hZGQoXCJoay1jb2RlYmxvY2stY29sbGFwc2UtYnRuXCIsIFwiaGstY29kZWJsb2NrLWNvbGxhcHNlZC1idG5cIik7XG4gICAgICBlbGVtX2NvbGxhcHNlQnRuLmlubmVySFRNTCA9IGA8c3ZnIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgIDxwYXRoIGQ9XCJNMTAgMTlhMSAxIDAgMCAxLS42NC0uMjMgMSAxIDAgMCAxLS4xMy0xLjQxTDEzLjcxIDEyIDkuMzkgNi42M2ExIDEgMCAwIDEgLjE1LTEuNDEgMSAxIDAgMCAxIDEuNDYuMTVsNC44MyA2YTEgMSAwIDAgMSAwIDEuMjdsLTUgNkExIDEgMCAwIDEgMTAgMTl6XCIvPlxuICAgICAgPC9zdmc+YDtcbiAgICAgIGVsZW1fY29sbGFwc2VCdG5zLmFwcGVuZENoaWxkKGVsZW1fY29sbGFwc2VCdG4pO1xuXG4gICAgICBjb25zdCBlbGVtX2V4cGFuZEJ0biA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBlbGVtX2V4cGFuZEJ0bi5jbGFzc0xpc3QuYWRkKFwiaGstY29kZWJsb2NrLWNvbGxhcHNlLWJ0blwiLCBcImhrLWNvZGVibG9jay1leHBhbmRlZC1idG5cIik7XG4gICAgICBlbGVtX2V4cGFuZEJ0bi5pbm5lckhUTUwgPSBgPHN2ZyB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICA8cGF0aCBkPVwiTTEyIDE2YTEgMSAwIDAgMS0uNjQtLjIzbC02LTVhMSAxIDAgMSAxIDEuMjgtMS41NEwxMiAxMy43MWw1LjM2LTQuMzJhMSAxIDAgMCAxIDEuNDEuMTUgMSAxIDAgMCAxLS4xNCAxLjQ2bC02IDQuODNBMSAxIDAgMCAxIDEyIDE2elwiLz5cbiAgICAgIDwvc3ZnPmA7XG4gICAgICBlbGVtX2NvbGxhcHNlQnRucy5hcHBlbmRDaGlsZChlbGVtX2V4cGFuZEJ0bik7XG5cbiAgICAgIGVsZW1fdGl0bGUucHJlcGVuZChlbGVtX2NvbGxhcHNlQnRucyk7XG4gICAgfVxuICB9XG5cblxuICBpZiAoXG4gICAgKHNldHRpbmdzLnVzZUxpbmVub3NHbG9iYWwgPT09IFwiYWx3YXlzIG9uXCIpIHx8XG4gICAgKHNldHRpbmdzLnVzZUxpbmVub3NHbG9iYWwgPT09IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiICYmIChzaG93TGluZW5vcyA9PT0gdW5kZWZpbmVkIHx8IHNob3dMaW5lbm9zID09PSB0cnVlKSkgfHxcbiAgICAoc2V0dGluZ3MudXNlTGluZW5vc0dsb2JhbCA9PT0gXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIgJiYgKHNob3dMaW5lbm9zID09PSB0cnVlKSlcbiAgKSB7XG4gICAgZWxlbV9kaXYuY2xhc3NMaXN0LmFkZChcImhrLWNvZGVibG9jay1zaG93LWxpbmVub3NcIik7XG5cbiAgICBjb25zdCBlbGVtX2xpbmVub3MgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY29kZVwiKTtcbiAgICBlbGVtX2xpbmVub3MuY2xhc3NMaXN0LmFkZChcImhrLWNvZGVibG9jay1saW5lbm9zXCIpO1xuICAgIGVsZW1fbGluZW5vcy5pbm5lclRleHQgPSBBcnJheShsaW5lbm9zTnVtKS5maWxsKDApLm1hcCgoXywgaWR4KSA9PiBpZHggKyBsaW5lbm9zU3RhcnQpLmpvaW4oXCJcXG5cIik7XG4gICAgZWxlbV9wcmUuaW5zZXJ0QmVmb3JlKGVsZW1fbGluZW5vcywgZWxlbV9jb2RlKTtcblxuICAgIGlmIChzZXR0aW5ncy5zaG93TGluZW5vc1NwbGl0dGVyKSB7XG4gICAgICBlbGVtX2xpbmVub3MuY2xhc3NMaXN0LmFkZChcInNob3ctc3BsaXR0ZXJcIik7XG4gICAgfVxuICB9XG5cbiAgaWYgKHNldHRpbmdzLnVzZUhpZ2hsaWdodEdsb2JhbCA9PT0gXCJkZWZhdWx0IG9mZiwgYnV0IG9uIHdoZW4gc3BlY2lmaWVkXCIgJiYgKHNob3dIaWdobGlnaHQgPT09IHRydWUpKSB7XG4gICAgZWxlbV9kaXYuY2xhc3NMaXN0LmFkZChcImhrLWNvZGVibG9jay1zaG93LWhpZ2hsaWdodFwiKTtcblxuICAgIGVsZW1fZGl2LnN0eWxlLnNldFByb3BlcnR5KFwiLS1oay1jb2RlYmxvY2staGlnaGxpZ2h0LWJhY2tncm91bmQtY29sb3JcIiwgc2V0dGluZ3MuaGlnaGxpZ2h0Q29sb3IpO1xuXG4gICAgY29uc3QgZWxlbV9oaWdobGlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY29kZVwiKTtcbiAgICBlbGVtX2hpZ2hsaWdodC5jbGFzc0xpc3QuYWRkKFwiaGstY29kZWJsb2NrLWhpZ2hsaWdodFwiKTtcbiAgICBlbGVtX2hpZ2hsaWdodC5pbm5lckhUTUwgPSBBcnJheShsaW5lbm9zTnVtKS5maWxsKDApLm1hcCgoXywgaWR4KSA9PiB7XG4gICAgICBjb25zdCBjbGFzc05hbWVzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgaWYgKGhpZ2hsaWdodExpbmVzLmluY2x1ZGVzKGlkeCArIGxpbmVub3NTdGFydCkpIGNsYXNzTmFtZXMucHVzaChcImhpZ2hsaWdodFwiKTtcbiAgICAgIHJldHVybiBgPHNwYW4gY2xhc3M9XCJsaW5lIGxpbmUtJHtpZHggKyBsaW5lbm9zU3RhcnR9ICR7Y2xhc3NOYW1lcy5qb2luKFwiIFwiKX1cIj4gPC9zcGFuPmA7XG4gICAgfSkuam9pbihcIlxcblwiKTtcbiAgICBlbGVtX3ByZS5pbnNlcnRCZWZvcmUoZWxlbV9oaWdobGlnaHQsIGVsZW1fY29kZSk7XG4gIH1cblxuICBpZiAoXG4gICAgKHNldHRpbmdzLnVzZUxhbmd1YWdlR2xvYmFsID09PSBcImFsd2F5cyBvblwiKSB8fFxuICAgIChzZXR0aW5ncy51c2VMYW5ndWFnZUdsb2JhbCA9PT0gXCJkZWZhdWx0IG9uLCBidXQgb2ZmIHdoZW4gc3BlY2lmaWVkXCIgJiYgKHNob3dMYW5ndWFnZSA9PT0gdW5kZWZpbmVkIHx8IHNob3dMYW5ndWFnZSA9PT0gdHJ1ZSkpIHx8XG4gICAgKHNldHRpbmdzLnVzZUxhbmd1YWdlR2xvYmFsID09PSBcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIiAmJiAoc2hvd0xhbmd1YWdlID09PSB0cnVlKSlcbiAgKSB7XG4gICAgZWxlbV9kaXYuY2xhc3NMaXN0LmFkZChcImhrLWNvZGVibG9jay1zaG93LWxhbmd1YWdlXCIpO1xuXG4gICAgY29uc3QgZWxlbV9sYW5ndWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgZWxlbV9sYW5ndWFnZS5jbGFzc0xpc3QuYWRkKFwiaGstY29kZWJsb2NrLWxhbmd1YWdlXCIpO1xuICAgIGVsZW1fbGFuZ3VhZ2UuaW5uZXJUZXh0ID0gbGFuZ3VhZ2U7XG4gICAgZWxlbV9wcmUucHJlcGVuZChlbGVtX2xhbmd1YWdlKTtcbiAgfVxuXG4gIGlmIChcbiAgICAoc2V0dGluZ3MudXNlQ29weUJ0bkdsb2JhbCA9PT0gXCJhbHdheXMgb25cIikgfHxcbiAgICAoc2V0dGluZ3MudXNlQ29weUJ0bkdsb2JhbCA9PT0gXCJkZWZhdWx0IG9uLCBidXQgb2ZmIHdoZW4gc3BlY2lmaWVkXCIgJiYgKHNob3dDb3B5QnRuID09PSB1bmRlZmluZWQgfHwgc2hvd0NvcHlCdG4gPT09IHRydWUpKSB8fFxuICAgIChzZXR0aW5ncy51c2VDb3B5QnRuR2xvYmFsID09PSBcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIiAmJiAoc2hvd0NvcHlCdG4gPT09IHRydWUpKVxuICApIHtcbiAgICBlbGVtX2Rpdi5jbGFzc0xpc3QuYWRkKFwiaGstY29kZWJsb2NrLXNob3ctY29weWJ0blwiKTtcblxuICAgIGVsZW1fcHJlLmFwcGVuZENoaWxkKGVsZW1fY29weUJ0bik7XG4gIH1cblxuICBpZiAoXG4gICAgKHNldHRpbmdzLnVzZVByb21wdEdsb2JhbCA9PT0gXCJhbHdheXMgb25cIiAmJiBzZXR0aW5ncy5wcm9tcHRpbmdMYW5ndWFnZXMuaW5jbHVkZXMobGFuZ3VhZ2UpKSB8fFxuICAgIChzZXR0aW5ncy51c2VQcm9tcHRHbG9iYWwgPT09IFwiZGVmYXVsdCBvbiwgYnV0IG9mZiB3aGVuIHNwZWNpZmllZFwiICYmIHNldHRpbmdzLnByb21wdGluZ0xhbmd1YWdlcy5pbmNsdWRlcyhsYW5ndWFnZSkgJiYgKHNob3dQcm9tcHQgPT09IHVuZGVmaW5lZCB8fCBzaG93UHJvbXB0ID09PSB0cnVlKSkgfHxcbiAgICAoc2V0dGluZ3MudXNlUHJvbXB0R2xvYmFsID09PSBcImRlZmF1bHQgb2ZmLCBidXQgb24gd2hlbiBzcGVjaWZpZWRcIiAmJiAoc2hvd1Byb21wdCA9PT0gdHJ1ZSkpXG4gICkge1xuICAgIGVsZW1fZGl2LmNsYXNzTGlzdC5hZGQoXCJoay1jb2RlYmxvY2stc2hvdy1wcm9tcHRcIik7XG5cbiAgICAvLyB1c2luZyBQcmlzbS5qcyBjb21tYW5kLWxpbmUgcGx1Z2luXG4gICAgbGV0IGNvZGVfbGluZXMgPSBlbGVtX2NvZGUuaW5uZXJUZXh0LnNwbGl0KFwiXFxuXCIpO1xuICAgIGlmIChjb2RlX2xpbmVzW2NvZGVfbGluZXMubGVuZ3RoIC0gMV0udHJpbSgpLmxlbmd0aCA9PSAwKSBjb2RlX2xpbmVzLnBvcCgpOyAvLyByZW1vdmUgbGFzdCBsaW5lIGlmIGVtcHR5XG5cbiAgICBjb25zdCBub19wcm9tcHRfbGluZV9pZHhzID0gY29kZV9saW5lcy5tYXAoKGxpbmUsIGlkeCkgPT4ge1xuICAgICAgaWYgKGxpbmUudHJpbSgpLmxlbmd0aCA9PSAwKSByZXR1cm4gKGlkeCArIDEpOyAvLyBlbXB0eSBsaW5lXG4gICAgICBpZiAobGluZS5zdGFydHNXaXRoKFwiI1wiKSkgcmV0dXJuIChpZHggKyAxKTsgLy8gY29tbWVudCBsaW5lXG4gICAgICByZXR1cm4gLTE7XG4gICAgfSkuZmlsdGVyKChpZHgpID0+IGlkeCAhPSAtMSk7XG5cbiAgICBlbGVtX3ByZS5jbGFzc0xpc3QuYWRkKFwiY29tbWFuZC1saW5lXCIpO1xuICAgIGVsZW1fcHJlLnNldEF0dHJpYnV0ZShcImRhdGEtcHJvbXB0XCIsIHByb21wdCk7XG4gICAgZWxlbV9wcmUuc2V0QXR0cmlidXRlKFwiZGF0YS1jb250aW51YXRpb24tc3RyXCIsIFwiXFxcXFwiKTtcbiAgICBlbGVtX3ByZS5zZXRBdHRyaWJ1dGUoXCJkYXRhLWNvbnRpbnVhdGlvbi1wcm9tcHRcIiwgXCIgXCIucmVwZWF0KHByb21wdC5sZW5ndGgpKTsgIC8vIHVzZSBzcGFjZXMgdG8gYWxpZ24gY29udGludWF0aW9uIHByb21wdFxuICAgIGVsZW1fcHJlLnNldEF0dHJpYnV0ZShcImRhdGEtb3V0cHV0XCIsIG5vX3Byb21wdF9saW5lX2lkeHMuam9pbihcIiwgXCIpKTtcbiAgfVxuXG4gIGlmIChzZXR0aW5ncy51c2VSZXN1bHRHbG9iYWwgPT09IFwiZW5hYmxlXCIgJiYgKGlzUmVzdWx0ID09PSB0cnVlKSkge1xuICAgIGVsZW1fZGl2LmNsYXNzTGlzdC5hZGQoXCJoay1jb2RlYmxvY2stcmVzdWx0XCIpO1xuICAgIGVsZW1fY29kZS5jbGFzc0xpc3QuYWRkKFwiaGstY29kZWJsb2NrLXJlc3VsdC1jb2RlXCIpO1xuXG4gICAgZWxlbV9kaXYuc2V0QXR0cmlidXRlKFwiZGF0YS1yZXN1bHQtcHJvbXB0XCIsIHJlc3VsdFByb21wdCk7XG4gIH1cbn0iLCAiZXhwb3J0IGZ1bmN0aW9uIFByaXNtUGx1Z2luX0NvbW1hbmRMaW5lKFByaXNtKSB7XG5cblx0aWYgKHR5cGVvZiBQcmlzbSA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdHZhciBDTEFTU19QQVRURVJOID0gLyg/Ol58XFxzKWNvbW1hbmQtbGluZSg/Olxcc3wkKS87XG5cdHZhciBQUk9NUFRfQ0xBU1MgPSAnY29tbWFuZC1saW5lLXByb21wdCc7XG5cblx0LyoqIEB0eXBlIHsoc3RyOiBzdHJpbmcsIHByZWZpeDogc3RyaW5nKSA9PiBib29sZWFufSAqL1xuXHR2YXIgc3RhcnRzV2l0aCA9ICcnLnN0YXJ0c1dpdGhcblx0XHQ/IGZ1bmN0aW9uIChzLCBwKSB7IHJldHVybiBzLnN0YXJ0c1dpdGgocCk7IH1cblx0XHQ6IGZ1bmN0aW9uIChzLCBwKSB7IHJldHVybiBzLmluZGV4T2YocCkgPT09IDA7IH07XG5cblx0Ly8gU3VwcG9ydCBmb3IgSUUxMSB0aGF0IGhhcyBubyBlbmRzV2l0aCgpXG5cdC8qKiBAdHlwZSB7KHN0cjogc3RyaW5nLCBzdWZmaXg6IHN0cmluZykgPT4gYm9vbGVhbn0gKi9cblx0dmFyIGVuZHNXaXRoID0gJycuZW5kc1dpdGhcblx0XHQ/IGZ1bmN0aW9uIChzdHIsIHN1ZmZpeCkge1xuXHRcdFx0cmV0dXJuIHN0ci5lbmRzV2l0aChzdWZmaXgpO1xuXHRcdH1cblx0XHQ6IGZ1bmN0aW9uIChzdHIsIHN1ZmZpeCkge1xuXHRcdFx0dmFyIGxlbiA9IHN0ci5sZW5ndGg7XG5cdFx0XHRyZXR1cm4gc3RyLnN1YnN0cmluZyhsZW4gLSBzdWZmaXgubGVuZ3RoLCBsZW4pID09PSBzdWZmaXg7XG5cdFx0fTtcblxuXHQvKipcblx0ICogUmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBob29rIGVudmlyb25tZW50IGhhcyBhIGNvbW1hbmQgbGluZSBpbmZvIG9iamVjdC5cblx0ICpcblx0ICogQHBhcmFtIHthbnl9IGVudlxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICovXG5cdGZ1bmN0aW9uIGhhc0NvbW1hbmRMaW5lSW5mbyhlbnYpIHtcblx0XHR2YXIgdmFycyA9IGVudi52YXJzID0gZW52LnZhcnMgfHwge307XG5cdFx0cmV0dXJuICdjb21tYW5kLWxpbmUnIGluIHZhcnM7XG5cdH1cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGNvbW1hbmQgbGluZSBpbmZvIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBob29rIGVudmlyb25tZW50LlxuXHQgKlxuXHQgKiBAcGFyYW0ge2FueX0gZW52XG5cdCAqIEByZXR1cm5zIHtDb21tYW5kTGluZUluZm99XG5cdCAqXG5cdCAqIEB0eXBlZGVmIENvbW1hbmRMaW5lSW5mb1xuXHQgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtjb21wbGV0ZV1cblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IFtudW1iZXJPZkxpbmVzXVxuXHQgKiBAcHJvcGVydHkge3N0cmluZ1tdfSBbb3V0cHV0TGluZXNdXG5cdCAqL1xuXHRmdW5jdGlvbiBnZXRDb21tYW5kTGluZUluZm8oZW52KSB7XG5cdFx0dmFyIHZhcnMgPSBlbnYudmFycyA9IGVudi52YXJzIHx8IHt9O1xuXHRcdHJldHVybiB2YXJzWydjb21tYW5kLWxpbmUnXSA9IHZhcnNbJ2NvbW1hbmQtbGluZSddIHx8IHt9O1xuXHR9XG5cblxuXHRQcmlzbS5ob29rcy5hZGQoJ2JlZm9yZS1oaWdobGlnaHQnLCBmdW5jdGlvbiAoZW52KSB7XG5cdFx0dmFyIGNvbW1hbmRMaW5lID0gZ2V0Q29tbWFuZExpbmVJbmZvKGVudik7XG5cblx0XHRpZiAoY29tbWFuZExpbmUuY29tcGxldGUgfHwgIWVudi5jb2RlKSB7XG5cdFx0XHRjb21tYW5kTGluZS5jb21wbGV0ZSA9IHRydWU7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gV29ya3Mgb25seSBmb3IgPGNvZGU+IHdyYXBwZWQgaW5zaWRlIDxwcmU+IChub3QgaW5saW5lKS5cblx0XHR2YXIgcHJlID0gZW52LmVsZW1lbnQucGFyZW50RWxlbWVudDtcblx0XHRpZiAoIXByZSB8fCAhL3ByZS9pLnRlc3QocHJlLm5vZGVOYW1lKSB8fCAvLyBBYm9ydCBvbmx5IGlmIG5laXRoZXIgdGhlIDxwcmU+IG5vciB0aGUgPGNvZGU+IGhhdmUgdGhlIGNsYXNzXG5cdFx0XHQoIUNMQVNTX1BBVFRFUk4udGVzdChwcmUuY2xhc3NOYW1lKSAmJiAhQ0xBU1NfUEFUVEVSTi50ZXN0KGVudi5lbGVtZW50LmNsYXNzTmFtZSkpKSB7XG5cdFx0XHRjb21tYW5kTGluZS5jb21wbGV0ZSA9IHRydWU7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gVGhlIGVsZW1lbnQgbWlnaHQgYmUgaGlnaGxpZ2h0ZWQgbXVsdGlwbGUgdGltZXMsIHNvIHdlIGp1c3QgcmVtb3ZlIHRoZSBwcmV2aW91cyBwcm9tcHRcblx0XHR2YXIgZXhpc3RpbmdQcm9tcHQgPSBlbnYuZWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuJyArIFBST01QVF9DTEFTUyk7XG5cdFx0aWYgKGV4aXN0aW5nUHJvbXB0KSB7XG5cdFx0XHRleGlzdGluZ1Byb21wdC5yZW1vdmUoKTtcblx0XHR9XG5cblx0XHR2YXIgY29kZUxpbmVzID0gZW52LmNvZGUuc3BsaXQoJ1xcbicpO1xuXG5cdFx0aWYoY29kZUxpbmVzW2NvZGVMaW5lcy5sZW5ndGggLSAxXS50cmltKCkubGVuZ3RoID09PSAwKSB7IC8vIGRvIG5vdCBjb3VudCB0aGUgbGFzdCBsaW5lIGlmIGl0IGlzIGVtcHR5XG5cdFx0XHRjb21tYW5kTGluZS5udW1iZXJPZkxpbmVzID0gY29kZUxpbmVzLmxlbmd0aCAtIDE7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbW1hbmRMaW5lLm51bWJlck9mTGluZXMgPSBjb2RlTGluZXMubGVuZ3RoO1xuXHRcdH1cblx0XHQvKiogQHR5cGUge3N0cmluZ1tdfSAqL1xuXHRcdHZhciBvdXRwdXRMaW5lcyA9IGNvbW1hbmRMaW5lLm91dHB1dExpbmVzID0gW107XG5cblx0XHR2YXIgb3V0cHV0U2VjdGlvbnMgPSBwcmUuZ2V0QXR0cmlidXRlKCdkYXRhLW91dHB1dCcpO1xuXHRcdHZhciBvdXRwdXRGaWx0ZXIgPSBwcmUuZ2V0QXR0cmlidXRlKCdkYXRhLWZpbHRlci1vdXRwdXQnKTtcblx0XHRpZiAob3V0cHV0U2VjdGlvbnMgIT09IG51bGwpIHsgLy8gVGhlIHVzZXIgc3BlY2lmaWVkIHRoZSBvdXRwdXQgbGluZXMuIC0tIGN3ZWxsc1xuXHRcdFx0b3V0cHV0U2VjdGlvbnMuc3BsaXQoJywnKS5mb3JFYWNoKGZ1bmN0aW9uIChzZWN0aW9uKSB7XG5cdFx0XHRcdHZhciByYW5nZSA9IHNlY3Rpb24uc3BsaXQoJy0nKTtcblx0XHRcdFx0dmFyIG91dHB1dFN0YXJ0ID0gcGFyc2VJbnQocmFuZ2VbMF0sIDEwKTtcblx0XHRcdFx0dmFyIG91dHB1dEVuZCA9IHJhbmdlLmxlbmd0aCA9PT0gMiA/IHBhcnNlSW50KHJhbmdlWzFdLCAxMCkgOiBvdXRwdXRTdGFydDtcblxuXHRcdFx0XHRpZiAoIWlzTmFOKG91dHB1dFN0YXJ0KSAmJiAhaXNOYU4ob3V0cHV0RW5kKSkge1xuXHRcdFx0XHRcdGlmIChvdXRwdXRTdGFydCA8IDEpIHtcblx0XHRcdFx0XHRcdG91dHB1dFN0YXJ0ID0gMTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKG91dHB1dEVuZCA+IGNvZGVMaW5lcy5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdG91dHB1dEVuZCA9IGNvZGVMaW5lcy5sZW5ndGg7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdC8vIENvbnZlcnQgc3RhcnQgYW5kIGVuZCB0byAwLWJhc2VkIHRvIHNpbXBsaWZ5IHRoZSBhcnJheXMuIC0tIGN3ZWxsc1xuXHRcdFx0XHRcdG91dHB1dFN0YXJ0LS07XG5cdFx0XHRcdFx0b3V0cHV0RW5kLS07XG5cdFx0XHRcdFx0Ly8gU2F2ZSB0aGUgb3V0cHV0IGxpbmUgaW4gYW4gYXJyYXkgYW5kIGNsZWFyIGl0IGluIHRoZSBjb2RlIHNvIGl0J3Mgbm90IGhpZ2hsaWdodGVkLiAtLSBjd2VsbHNcblx0XHRcdFx0XHRmb3IgKHZhciBqID0gb3V0cHV0U3RhcnQ7IGogPD0gb3V0cHV0RW5kOyBqKyspIHtcblx0XHRcdFx0XHRcdG91dHB1dExpbmVzW2pdID0gY29kZUxpbmVzW2pdO1xuXHRcdFx0XHRcdFx0Y29kZUxpbmVzW2pdID0gJyc7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9IGVsc2UgaWYgKG91dHB1dEZpbHRlcikgeyAvLyBUcmVhdCBsaW5lcyBiZWdpbm5pbmcgd2l0aCB0aGlzIHN0cmluZyBhcyBvdXRwdXQuIC0tIGN3ZWxsc1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBjb2RlTGluZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0aWYgKHN0YXJ0c1dpdGgoY29kZUxpbmVzW2ldLCBvdXRwdXRGaWx0ZXIpKSB7IC8vIFRoaXMgbGluZSBpcyBvdXRwdXQuIC0tIGN3ZWxsc1xuXHRcdFx0XHRcdG91dHB1dExpbmVzW2ldID0gY29kZUxpbmVzW2ldLnNsaWNlKG91dHB1dEZpbHRlci5sZW5ndGgpO1xuXHRcdFx0XHRcdGNvZGVMaW5lc1tpXSA9ICcnO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dmFyIGNvbnRpbnVhdGlvbkxpbmVJbmRpY2llcyA9IGNvbW1hbmRMaW5lLmNvbnRpbnVhdGlvbkxpbmVJbmRpY2llcyA9IG5ldyBTZXQoKTtcblx0XHR2YXIgbGluZUNvbnRpbnVhdGlvblN0ciA9IHByZS5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29udGludWF0aW9uLXN0cicpO1xuXHRcdHZhciBjb250aW51YXRpb25GaWx0ZXIgPSBwcmUuZ2V0QXR0cmlidXRlKCdkYXRhLWZpbHRlci1jb250aW51YXRpb24nKTtcblxuXHRcdC8vIElkZW50aWZ5IGNvZGUgbGluZXMgd2hlcmUgdGhlIGNvbW1hbmQgaGFzIGNvbnRpbnVlZCBvbnRvIHN1YnNlcXVlbnRcblx0XHQvLyBsaW5lcyBhbmQgdGh1cyBuZWVkIGEgZGlmZmVyZW50IHByb21wdC4gTmVlZCB0byBkbyB0aGlzIGFmdGVyIHRoZSBvdXRwdXRcblx0XHQvLyBsaW5lcyBoYXZlIGJlZW4gcmVtb3ZlZCB0byBlbnN1cmUgd2UgZG9uJ3QgcGljayB1cCBhIGNvbnRpbnVhdGlvbiBzdHJpbmdcblx0XHQvLyBpbiBhbiBvdXRwdXQgbGluZS5cblx0XHRmb3IgKHZhciBqID0gMDsgaiA8IGNvZGVMaW5lcy5sZW5ndGg7IGorKykge1xuXHRcdFx0dmFyIGxpbmUgPSBjb2RlTGluZXNbal07XG5cdFx0XHRpZiAoIWxpbmUpIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlY29yZCB0aGUgbmV4dCBsaW5lIGFzIGEgY29udGludWF0aW9uIGlmIHRoaXMgb25lIGVuZHMgaW4gYSBjb250aW51YXRpb24gc3RyLlxuXHRcdFx0aWYgKGxpbmVDb250aW51YXRpb25TdHIgJiYgZW5kc1dpdGgobGluZSwgbGluZUNvbnRpbnVhdGlvblN0cikpIHtcblx0XHRcdFx0Y29udGludWF0aW9uTGluZUluZGljaWVzLmFkZChqICsgMSk7XG5cdFx0XHR9XG5cdFx0XHQvLyBSZWNvcmQgdGhpcyBsaW5lIGFzIGEgY29udGludWF0aW9uIGlmIG1hcmtlZCB3aXRoIGEgY29udGludWF0aW9uIHByZWZpeFxuXHRcdFx0Ly8gKHRoYXQgd2Ugd2lsbCByZW1vdmUpLlxuXHRcdFx0aWYgKGogPiAwICYmIGNvbnRpbnVhdGlvbkZpbHRlciAmJiBzdGFydHNXaXRoKGxpbmUsIGNvbnRpbnVhdGlvbkZpbHRlcikpIHtcblx0XHRcdFx0Y29kZUxpbmVzW2pdID0gbGluZS5zbGljZShjb250aW51YXRpb25GaWx0ZXIubGVuZ3RoKTtcblx0XHRcdFx0Y29udGludWF0aW9uTGluZUluZGljaWVzLmFkZChqKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRlbnYuY29kZSA9IGNvZGVMaW5lcy5qb2luKCdcXG4nKTtcblx0fSk7XG5cblx0UHJpc20uaG9va3MuYWRkKCdiZWZvcmUtaW5zZXJ0JywgZnVuY3Rpb24gKGVudikge1xuXHRcdHZhciBjb21tYW5kTGluZSA9IGdldENvbW1hbmRMaW5lSW5mbyhlbnYpO1xuXG5cdFx0aWYgKGNvbW1hbmRMaW5lLmNvbXBsZXRlKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gUmVpbnNlcnQgdGhlIG91dHB1dCBsaW5lcyBpbnRvIHRoZSBoaWdobGlnaHRlZCBjb2RlLiAtLSBjd2VsbHNcblx0XHR2YXIgY29kZUxpbmVzID0gZW52LmhpZ2hsaWdodGVkQ29kZS5zcGxpdCgnXFxuJyk7XG5cdFx0dmFyIG91dHB1dExpbmVzID0gY29tbWFuZExpbmUub3V0cHV0TGluZXMgfHwgW107XG5cdFx0Zm9yICh2YXIgaSA9IDAsIGwgPSBjb2RlTGluZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG5cdFx0XHQvLyBBZGQgc3BhbnMgdG8gYWxsb3cgZGlzdGluY3Rpb24gb2YgaW5wdXQvb3V0cHV0IHRleHQgZm9yIHN0eWxpbmdcblx0XHRcdGlmIChvdXRwdXRMaW5lcy5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHQvLyBvdXRwdXRMaW5lcyB3ZXJlIHJlbW92ZWQgZnJvbSBjb2RlTGluZXMgc28gbWlzc2VkIG91dCBvbiBlc2NhcGluZ1xuXHRcdFx0XHQvLyBvZiBtYXJrdXAgc28gZG8gaXQgaGVyZS5cblx0XHRcdFx0Y29kZUxpbmVzW2ldID0gJzxzcGFuIGNsYXNzPVwidG9rZW4gb3V0cHV0XCI+J1xuXHRcdFx0XHRcdCsgUHJpc20udXRpbC5lbmNvZGUob3V0cHV0TGluZXNbaV0pICsgJzwvc3Bhbj4nO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29kZUxpbmVzW2ldID0gJzxzcGFuIGNsYXNzPVwidG9rZW4gY29tbWFuZFwiPidcblx0XHRcdFx0XHQrIGNvZGVMaW5lc1tpXSArICc8L3NwYW4+Jztcblx0XHRcdH1cblx0XHR9XG5cdFx0ZW52LmhpZ2hsaWdodGVkQ29kZSA9IGNvZGVMaW5lcy5qb2luKCdcXG4nKTtcblx0fSk7XG5cblx0UHJpc20uaG9va3MuYWRkKCdjb21wbGV0ZScsIGZ1bmN0aW9uIChlbnYpIHtcblx0XHRpZiAoIWhhc0NvbW1hbmRMaW5lSW5mbyhlbnYpKSB7XG5cdFx0XHQvLyB0aGUgcHJldmlvdXMgaG9va3MgbmV2ZXIgcmFuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIGNvbW1hbmRMaW5lID0gZ2V0Q29tbWFuZExpbmVJbmZvKGVudik7XG5cblx0XHRpZiAoY29tbWFuZExpbmUuY29tcGxldGUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgcHJlID0gZW52LmVsZW1lbnQucGFyZW50RWxlbWVudDtcblx0XHRpZiAoQ0xBU1NfUEFUVEVSTi50ZXN0KGVudi5lbGVtZW50LmNsYXNzTmFtZSkpIHsgLy8gUmVtb3ZlIHRoZSBjbGFzcyBcImNvbW1hbmQtbGluZVwiIGZyb20gdGhlIDxjb2RlPlxuXHRcdFx0ZW52LmVsZW1lbnQuY2xhc3NOYW1lID0gZW52LmVsZW1lbnQuY2xhc3NOYW1lLnJlcGxhY2UoQ0xBU1NfUEFUVEVSTiwgJyAnKTtcblx0XHR9XG5cdFx0aWYgKCFDTEFTU19QQVRURVJOLnRlc3QocHJlLmNsYXNzTmFtZSkpIHsgLy8gQWRkIHRoZSBjbGFzcyBcImNvbW1hbmQtbGluZVwiIHRvIHRoZSA8cHJlPlxuXHRcdFx0cHJlLmNsYXNzTmFtZSArPSAnIGNvbW1hbmQtbGluZSc7XG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gZ2V0QXR0cmlidXRlKGtleSwgZGVmYXVsdFZhbHVlKSB7XG5cdFx0XHRyZXR1cm4gKHByZS5nZXRBdHRyaWJ1dGUoa2V5KSB8fCBkZWZhdWx0VmFsdWUpLnJlcGxhY2UoL1wiL2csICcmcXVvdCcpO1xuXHRcdH1cblxuXHRcdC8vIENyZWF0ZSB0aGUgXCJyb3dzXCIgdGhhdCB3aWxsIGJlY29tZSB0aGUgY29tbWFuZC1saW5lIHByb21wdHMuIC0tIGN3ZWxsc1xuXHRcdHZhciBwcm9tcHRMaW5lcyA9ICcnO1xuXHRcdHZhciByb3dDb3VudCA9IGNvbW1hbmRMaW5lLm51bWJlck9mTGluZXMgfHwgMDtcblx0XHR2YXIgcHJvbXB0VGV4dCA9IGdldEF0dHJpYnV0ZSgnZGF0YS1wcm9tcHQnLCAnJyk7XG5cdFx0dmFyIHByb21wdExpbmU7XG5cdFx0aWYgKHByb21wdFRleHQgIT09ICcnKSB7XG5cdFx0XHRwcm9tcHRMaW5lID0gJzxzcGFuIGRhdGEtcHJvbXB0PVwiJyArIHByb21wdFRleHQgKyAnXCI+PC9zcGFuPic7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHZhciB1c2VyID0gZ2V0QXR0cmlidXRlKCdkYXRhLXVzZXInLCAndXNlcicpO1xuXHRcdFx0dmFyIGhvc3QgPSBnZXRBdHRyaWJ1dGUoJ2RhdGEtaG9zdCcsICdsb2NhbGhvc3QnKTtcblx0XHRcdHByb21wdExpbmUgPSAnPHNwYW4gZGF0YS11c2VyPVwiJyArIHVzZXIgKyAnXCIgZGF0YS1ob3N0PVwiJyArIGhvc3QgKyAnXCI+PC9zcGFuPic7XG5cdFx0fVxuXG5cdFx0dmFyIGNvbnRpbnVhdGlvbkxpbmVJbmRpY2llcyA9IGNvbW1hbmRMaW5lLmNvbnRpbnVhdGlvbkxpbmVJbmRpY2llcyB8fCBuZXcgU2V0KCk7XG5cdFx0dmFyIGNvbnRpbnVhdGlvblByb21wdFRleHQgPSBnZXRBdHRyaWJ1dGUoJ2RhdGEtY29udGludWF0aW9uLXByb21wdCcsICc+Jyk7XG5cdFx0dmFyIGNvbnRpbnVhdGlvblByb21wdExpbmUgPSAnPHNwYW4gZGF0YS1jb250aW51YXRpb24tcHJvbXB0PVwiJyArIGNvbnRpbnVhdGlvblByb21wdFRleHQgKyAnXCI+PC9zcGFuPic7XG5cblx0XHQvLyBBc3NlbWJsZSBhbGwgdGhlIGFwcHJvcHJpYXRlIHByb21wdC9jb250aW51YXRpb24gbGluZXNcblx0XHRmb3IgKHZhciBqID0gMDsgaiA8IHJvd0NvdW50OyBqKyspIHtcblx0XHRcdGlmIChjb250aW51YXRpb25MaW5lSW5kaWNpZXMuaGFzKGopKSB7XG5cdFx0XHRcdHByb21wdExpbmVzICs9IGNvbnRpbnVhdGlvblByb21wdExpbmU7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwcm9tcHRMaW5lcyArPSBwcm9tcHRMaW5lO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENyZWF0ZSB0aGUgd3JhcHBlciBlbGVtZW50LiAtLSBjd2VsbHNcblx0XHR2YXIgcHJvbXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuXHRcdHByb21wdC5jbGFzc05hbWUgPSBQUk9NUFRfQ0xBU1M7XG5cdFx0cHJvbXB0LmlubmVySFRNTCA9IHByb21wdExpbmVzO1xuXG5cdFx0Ly8gUmVtb3ZlIHRoZSBwcm9tcHQgZnJvbSB0aGUgb3V0cHV0IGxpbmVzLiAtLSBjd2VsbHNcblx0XHR2YXIgb3V0cHV0TGluZXMgPSBjb21tYW5kTGluZS5vdXRwdXRMaW5lcyB8fCBbXTtcblx0XHRmb3IgKHZhciBpID0gMCwgbCA9IG91dHB1dExpbmVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuXHRcdFx0aWYgKG91dHB1dExpbmVzLmhhc093blByb3BlcnR5KGkpKSB7XG5cdFx0XHRcdHZhciBub2RlID0gcHJvbXB0LmNoaWxkcmVuW2ldO1xuXHRcdFx0XHRub2RlLnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS11c2VyJyk7XG5cdFx0XHRcdG5vZGUucmVtb3ZlQXR0cmlidXRlKCdkYXRhLWhvc3QnKTtcblx0XHRcdFx0bm9kZS5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtcHJvbXB0Jyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0ZW52LmVsZW1lbnQuaW5zZXJ0QmVmb3JlKHByb21wdCwgZW52LmVsZW1lbnQuZmlyc3RDaGlsZCk7XG5cdFx0Y29tbWFuZExpbmUuY29tcGxldGUgPSB0cnVlO1xuXHR9KTtcblxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLElBQUFBLG1CQUFrQzs7O0FDNkIzQixJQUFNLG1CQUF3QztBQUFBLEVBQ3BELGdCQUFnQjtBQUFBLEVBRWhCLHNCQUFzQjtBQUFBLEVB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QUc7QUFDekUsUUFBSSx5QkFBeUIscUNBQXFDLHlCQUF5QjtBQUczRixhQUFTLElBQUksR0FBRyxJQUFJLFVBQVUsS0FBSztBQUNsQyxVQUFJLHlCQUF5QixJQUFJLENBQUMsR0FBRztBQUNwQyx1QkFBZTtBQUFBLE1BQ2hCLE9BQU87QUFDTix1QkFBZTtBQUFBLE1BQ2hCO0FBQUEsSUFDRDtBQUdBLFFBQUksU0FBUyxTQUFTLGNBQWMsTUFBTTtBQUMxQyxXQUFPLFlBQVk7QUFDbkIsV0FBTyxZQUFZO0FBR25CLFFBQUksY0FBYyxZQUFZLGVBQWUsQ0FBQztBQUM5QyxhQUFTLElBQUksR0FBRyxJQUFJLFlBQVksUUFBUSxJQUFJLEdBQUcsS0FBSztBQUNuRCxVQUFJLFlBQVksZUFBZSxDQUFDLEdBQUc7QUFDbEMsWUFBSSxPQUFPLE9BQU8sU0FBUyxDQUFDO0FBQzVCLGFBQUssZ0JBQWdCLFdBQVc7QUFDaEMsYUFBSyxnQkFBZ0IsV0FBVztBQUNoQyxhQUFLLGdCQUFnQixhQUFhO0FBQUEsTUFDbkM7QUFBQSxJQUNEO0FBRUEsUUFBSSxRQUFRLGFBQWEsUUFBUSxJQUFJLFFBQVEsVUFBVTtBQUN2RCxnQkFBWSxXQUFXO0FBQUEsRUFDeEIsQ0FBQztBQUVGOzs7QUp6T0EsSUFBcUIsb0JBQXJCLGNBQStDLHdCQUFPO0FBQUEsRUFHckQsTUFBTSxTQUFTO0FBQ2QsVUFBTSxLQUFLLGFBQWE7QUFDeEIsUUFBSSxLQUFLLFNBQVMsV0FBVztBQUM1QixjQUFRLElBQUksNEJBQTRCO0FBQUEsSUFDekM7QUFFQSxVQUFNLFFBQVEsVUFBTSw0QkFBVTtBQUc5Qiw0QkFBd0IsS0FBSztBQUc3QixTQUFLLGNBQWMsSUFBSSxzQkFBc0IsS0FBSyxLQUFLLElBQUksQ0FBQztBQUc1RCxVQUFNLFlBQVksS0FBSyw4QkFBOEIsQ0FBQyxJQUFJLFFBQVE7QUFDakUsMkJBQXFCLElBQUksS0FBSyxJQUFJO0FBQUEsSUFDbkMsQ0FBQztBQUVELGNBQVUsWUFBWTtBQUFBLEVBQ3ZCO0FBQUEsRUFFQSxXQUFXO0FBQ1YsUUFBSSxLQUFLLFNBQVMsV0FBVztBQUM1QixjQUFRLElBQUksOEJBQThCO0FBQUEsSUFDM0M7QUFBQSxFQUNEO0FBQUEsRUFFQSxNQUFNLGVBQWU7QUFDcEIsU0FBSyxXQUFXLE9BQU8sT0FBTyxDQUFDLEdBQUcsa0JBQWtCLE1BQU0sS0FBSyxTQUFTLENBQUM7QUFBQSxFQUMxRTtBQUFBLEVBRUEsTUFBTSxlQUFlO0FBQ3BCLFVBQU0sS0FBSyxTQUFTLEtBQUssUUFBUTtBQUFBLEVBQ2xDO0FBQ0Q7IiwKICAibmFtZXMiOiBbImltcG9ydF9vYnNpZGlhbiIsICJhcHAiLCAiaW1wb3J0X29ic2lkaWFuIiwgImxhbmd1YWdlIiwgImoiXQp9Cg==