From 30f6b7c06039a2826d0d8bebf12e7ad88f1a6514 Mon Sep 17 00:00:00 2001 From: stargrey <90321926+stargrey@users.noreply.github.com> Date: Tue, 28 Jun 2022 15:05:38 +0800 Subject: [PATCH] update to 1.0.7 --- README.md | 4 +- main.js | 278 ++++++++++++++++++++++++++++++++--------------- main.ts | 290 +++++++++++++++++++++++++++++++++++++++----------- manifest.json | 2 +- styles.css | 29 +++++ 5 files changed, 457 insertions(+), 146 deletions(-) diff --git a/README.md b/README.md index 83cb17c..c8ae2b7 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,9 @@ If you have a better idea, please submit an issue In version 1.0.4, add the language in the top right, like this: ![screenshots/image-20220601202203.png](screenshots/image-20220601202203.png) - +### Known issues +- Sometimes the auto linefeed error, can be solved by switching the preview mode once +- The PDF export cannot be auto linefeed ### Manually installing the plugin - Copy over `main.js`, `styles.css`, `manifest.json` to your vault `VaultFolder/.obsidian/plugins/obsidian-better-codeblock/`. diff --git a/main.js b/main.js index b8081a9..ce2fd20 100644 --- a/main.js +++ b/main.js @@ -56,6 +56,9 @@ var import_obsidian = __toModule(require("obsidian")); var DEFAULT_LANG = ""; var LANG_REG = /^language-/; var LINE_SPLIT_MARK = "\n"; +var titleRegExp = /TI:"([^"]*)"/i; +var highLightLinesRegExp = /HL:"([^"]*)"/i; +var foldRegExp = /"FOLD"/i; var CB_PADDING_TOP = "35px"; var DEFAULT_SETTINGS = { substitutionTokenForSpace: void 0, @@ -75,6 +78,9 @@ var BetterCodeBlock = class extends import_obsidian.Plugin { this.addSettingTab(new BetterCodeBlockTab(this.app, this)); this.registerMarkdownPostProcessor((el, ctx) => { BetterCodeBlocks(el, ctx, this); + app.workspace.on("resize", () => { + resizeNumWrapAndHLWrap(el, ctx); + }); }); }); } @@ -131,54 +137,76 @@ var BetterCodeBlockTab = class extends import_obsidian.PluginSettingTab { } }; function BetterCodeBlocks(el, context, plugin) { - const settings = plugin.settings; - const codeElm = el.querySelector("pre > code"); - if (!codeElm) { - return; - } - let lang = DEFAULT_LANG; - if (plugin.settings.excludeLangs.some((eLangName) => codeElm.classList.contains(`language-${eLangName}`))) { - return; - } - codeElm.classList.forEach((value, key, parent) => { - if (LANG_REG.test(value)) { - lang = value.replace("language-", ""); + return __async(this, null, function* () { + var _a; + const settings = plugin.settings; + const codeElm = el.querySelector("pre > code"); + if (!codeElm) { + return; + } + let lang = DEFAULT_LANG; + if (plugin.settings.excludeLangs.some((eLangName) => codeElm.classList.contains(`language-${eLangName}`))) { + return; + } + codeElm.classList.forEach((value, key, parent) => { + if (LANG_REG.test(value)) { + lang = value.replace("language-", ""); + return; + } + }); + if (lang == DEFAULT_LANG) { return; } + let codeBlock = context.getSectionInfo(codeElm); + let codeBlockFirstLine = ""; + if (codeBlock) { + let view = app.workspace.getActiveViewOfType(import_obsidian.MarkdownView); + codeBlockFirstLine = view.editor.getLine(codeBlock.lineStart); + } else { + let file = app.vault.getAbstractFileByPath(context.sourcePath); + let cache = app.metadataCache.getCache(context.sourcePath); + let fileContent = yield app.vault.cachedRead(file); + let fileContentLines = fileContent.split(/\n/g); + let codeBlockFirstLines = []; + let codeBlockSections = []; + (_a = cache.sections) == null ? void 0 : _a.forEach((element) => __async(this, null, function* () { + if (element.type == "code") { + let lineStart = element.position.start.line; + codeBlockFirstLine = fileContentLines[lineStart]; + codeBlockSections.push(element); + codeBlockFirstLines.push(codeBlockFirstLine); + } + })); + exportPDF(el, plugin, codeBlockFirstLines, codeBlockSections); + return; + } + let title = ""; + let highLightLines = []; + if (codeBlockFirstLine.match(titleRegExp) != null) { + title = codeBlockFirstLine.match(titleRegExp)[1]; + } + if (codeBlockFirstLine.match(highLightLinesRegExp) != null) { + let highLightLinesInfo = codeBlockFirstLine.match(highLightLinesRegExp)[1]; + highLightLines = analyseHighLightLines(highLightLinesInfo); + } + let isCollapse = false; + if (foldRegExp.test(codeBlockFirstLine)) { + isCollapse = true; + } + const pre = codeElm.parentElement; + const div = pre.parentElement; + const contentList = codeElm.textContent.split(LINE_SPLIT_MARK); + const lineSize = contentList.length - 1; + const cbMeta = { langName: lang, lineSize, pre, code: codeElm, title, isCollapse, div, contentList, highLightLines }; + const { showLineNumber } = plugin.settings; + addCodeTitleWrapper(plugin, pre, cbMeta); + addCodeTitle(plugin, pre, cbMeta); + if (showLineNumber) { + addLineNumber(plugin, cbMeta); + } + addLineHighLight(plugin, pre, cbMeta); + resizeNumWrapAndHLWrap(el, context); }); - if (lang == DEFAULT_LANG) { - return; - } - let titleRegExp = /TI:"([^"]*)"/i; - let highLightLinesRegExp = /HL:"([^"]*)"/i; - let foldRegExp = /"FOLD"/i; - let codeBlock = context.getSectionInfo(codeElm); - let view = app.workspace.getActiveViewOfType(import_obsidian.MarkdownView); - let codeBlockFirstLine = view.editor.getLine(codeBlock.lineStart); - let title = ""; - let highLightLines = []; - if (codeBlockFirstLine.match(titleRegExp) != null) { - title = codeBlockFirstLine.match(titleRegExp)[1]; - } - if (codeBlockFirstLine.match(highLightLinesRegExp) != null) { - let highLightLinesInfo = codeBlockFirstLine.match(highLightLinesRegExp)[1]; - highLightLines = analyseHighLightLines(highLightLinesInfo); - } - let isCollapse = false; - if (foldRegExp.test(codeBlockFirstLine)) { - isCollapse = true; - } - const pre = codeElm.parentElement; - const div = pre.parentElement; - const contentList = codeElm.textContent.split(LINE_SPLIT_MARK); - const lineSize = contentList.length - 1; - const cbMeta = { langName: lang, lineSize, pre, code: codeElm, title, isCollapse, div, contentList, highLightLines }; - const { showLineNumber } = plugin.settings; - addCodeTitle(plugin, pre, cbMeta); - if (showLineNumber) { - addLineNumber(plugin, cbMeta); - } - addLineHighLight(plugin, pre, cbMeta); } function createElement(tagName, defaultClassName) { const element = document.createElement(tagName); @@ -187,6 +215,47 @@ function createElement(tagName, defaultClassName) { } return element; } +function addCodeTitleWrapper(plugin, preElm, cbMeta) { + preElm.style.setProperty("position", "relative", "important"); + preElm.style.setProperty("padding-top", CB_PADDING_TOP, "important"); + let wrapper = document.createElement("pre"); + if (cbMeta.isCollapse) { + wrapper.setAttribute("closed", ""); + } + wrapper.className = "obsidian-embedded-code-title__code-block-title"; + wrapper.style.backgroundColor = plugin.settings.titleBackgroundColor || "#00000020"; + let collapser = createElement("div", "collapser"); + let handle = createElement("div", "handle"); + collapser.appendChild(handle); + wrapper.appendChild(collapser); + wrapper.addEventListener("click", function() { + if (wrapper.hasAttribute("closed")) { + wrapper.removeAttribute("closed"); + } else { + wrapper.setAttribute("closed", ""); + } + }); + preElm.appendChild(wrapper); +} +function addCodeTitle(plugin, preElm, cbMeta) { + let wrapper = preElm.querySelector(".obsidian-embedded-code-title__code-block-title"); + let titleElm = document.createElement("div"); + titleElm.className = "title"; + titleElm.appendText(cbMeta.title); + wrapper.appendChild(titleElm); + if (plugin.settings.titleFontColor) { + titleElm.style.setProperty("color", plugin.settings.titleFontColor, "important"); + } + if (plugin.settings.showLangNameInTopRight) { + let langName = document.createElement("div"); + let langNameString = cbMeta.langName; + langNameString = langNameString[0].toUpperCase() + langNameString.slice(1); + langName.appendText(langNameString); + langName.className = "langName"; + wrapper.appendChild(langName); + } + preElm.prepend(wrapper); +} function addLineNumber(plugin, cbMeta) { const { lineSize, pre, div } = cbMeta; div.classList.add("code-block-wrap"); @@ -202,42 +271,7 @@ function addLineNumber(plugin, cbMeta) { pre.appendChild(lineNumber); pre.classList.add("code-block-pre__has-linenum"); } -function addCodeTitle(plugin, wrapperElm, cbMeta) { - wrapperElm.style.setProperty("position", "relative", "important"); - wrapperElm.style.setProperty("padding-top", CB_PADDING_TOP, "important"); - wrapperElm.querySelectorAll(".obsidian-embedded-code-title__code-block-title").forEach((x) => x.remove()); - let d = document.createElement("pre"); - d.appendText(cbMeta.title); - if (cbMeta.isCollapse) { - d.setAttribute("closed", ""); - } - d.className = "obsidian-embedded-code-title__code-block-title"; - if (plugin.settings.titleFontColor) { - d.style.setProperty("color", plugin.settings.titleFontColor, "important"); - } - d.style.backgroundColor = plugin.settings.titleBackgroundColor || "#00000020"; - let collapser = createElement("div", "collapser"); - let handle = createElement("div", "handle"); - collapser.appendChild(handle); - d.appendChild(collapser); - if (plugin.settings.showLangNameInTopRight) { - let langName = document.createElement("div"); - let langNameString = cbMeta.langName; - langNameString = langNameString[0].toUpperCase() + langNameString.slice(1); - langName.appendText(langNameString); - langName.className = "langName"; - d.appendChild(langName); - } - d.addEventListener("click", function() { - if (d.hasAttribute("closed")) { - d.removeAttribute("closed"); - } else { - d.setAttribute("closed", ""); - } - }); - wrapperElm.prepend(d); -} -function addLineHighLight(plugin, wrapperElm, cbMeta) { +function addLineHighLight(plugin, preElm, cbMeta) { if (cbMeta.highLightLines.length == 0) return; let highLightWrap = document.createElement("pre"); @@ -249,7 +283,7 @@ function addLineHighLight(plugin, wrapperElm, cbMeta) { } highLightWrap.appendChild(singleLine); } - wrapperElm.appendChild(highLightWrap); + preElm.appendChild(highLightWrap); } function analyseHighLightLines(str) { str = str.replace(/\s*/g, ""); @@ -268,4 +302,82 @@ function analyseHighLightLines(str) { }); return result; } -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibWFpbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgbGlua1N5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBBcHAsIEVkaXRvciwgTWFya2Rvd25WaWV3LCBNb2RhbCwgTm90aWNlLCBQbHVnaW4sIFBsdWdpblNldHRpbmdUYWIsIFNldHRpbmcsIE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsIE1lbnUsIFNldHRpbmdUYWIsIFRBYnN0cmFjdEZpbGUsIFRGaWxlIH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5jb25zdCBERUZBVUxUX0xBTkdfQVRUUiA9ICdsYW5ndWFnZS10ZXh0J1xuY29uc3QgREVGQVVMVF9MQU5HID0gJydcbmNvbnN0IExBTkdfUkVHID0gL15sYW5ndWFnZS0vXG5jb25zdCBMSU5FX1NQTElUX01BUksgPSAnXFxuJ1xuXG5jb25zdCBDQl9QQURESU5HX1RPUCA9IFwiMzVweFwiIC8vIFx1NEVFM1x1NzgwMVx1NTc1N1x1NEUwQVx1OEZCOVx1OERERFxuXG5pbnRlcmZhY2UgU2V0dGluZ3Mge1xuXHRzdWJzdGl0dXRpb25Ub2tlbkZvclNwYWNlOiBzdHJpbmc7XG5cdHRpdGxlQmFja2dyb3VuZENvbG9yOiBzdHJpbmc7XG5cdHRpdGxlRm9udENvbG9yOiBzdHJpbmc7XG5cdGhpZ2hMaWdodENvbG9yOiBzdHJpbmc7XG5cblx0ZXhjbHVkZUxhbmdzOiBzdHJpbmdbXTsgLy8gXHU5NzAwXHU4OTgxXHU2MzkyXHU5NjY0XHU3Njg0XHU4QkVEXHU4QTAwXG5cblx0c2hvd0xpbmVOdW1iZXI6IGJvb2xlYW47IC8vIFx1NjYzRVx1NzkzQVx1ODg0Q1x1NTNGN1xuXHRzaG93RGl2aWRpbmdMaW5lOiBib29sZWFuO1xuXHRzaG93TGFuZ05hbWVJblRvcFJpZ2h0OiBib29sZWFuO1xufVxuXG5jb25zdCBERUZBVUxUX1NFVFRJTkdTOiBTZXR0aW5ncyA9IHtcblx0c3Vic3RpdHV0aW9uVG9rZW5Gb3JTcGFjZTogdW5kZWZpbmVkLFxuXHR0aXRsZUJhY2tncm91bmRDb2xvcjogXCIjMDAwMDAwMjBcIixcblx0dGl0bGVGb250Q29sb3I6IHVuZGVmaW5lZCxcblx0aGlnaExpZ2h0Q29sb3I6IFwiIzJkODJjYzIwXCIsXG5cblx0ZXhjbHVkZUxhbmdzOiBbXSxcblxuXHRzaG93TGluZU51bWJlcjogdHJ1ZSxcblx0c2hvd0RpdmlkaW5nTGluZTogZmFsc2UsXG5cdHNob3dMYW5nTmFtZUluVG9wUmlnaHQ6IHRydWVcbn07XG5cbmludGVyZmFjZSBDb2RlQmxvY2tNZXRhIHtcblx0Ly8gTGFuZ3VhZ2UgbmFtZVxuXHRsYW5nTmFtZTogc3RyaW5nO1xuXG5cdC8vIENvZGUgYmxvY2sgdG90YWwgbGluZSBzaXplXG5cdGxpbmVTaXplOiBudW1iZXI7XG5cblx0Ly8gQ29kZSBibG9jayAncHJlJyBIVE1MRWxlbWVudFxuXHRwcmU6IEhUTUxFbGVtZW50O1xuXG5cdC8vIENvZGUgYmxvY2sgJ2NvZGUnIEhUTUxFbGVtZW50XG5cdGNvZGU6IEhUTUxFbGVtZW50O1xuXG5cdHRpdGxlOiBzdHJpbmc7IC8vIFx1NEVFM1x1NzgwMVx1NTc1N1x1NjgwN1x1OTg5OFxuXHRpc0NvbGxhcHNlOmJvb2xlYW47IC8vIFx1NjYyRlx1NTQyNlx1OUVEOFx1OEJBNFx1NjI5OFx1NTNFMFxuXG5cdC8vIENvZGUgYmxvY2sgd3JhcCBkaXZcblx0ZGl2OiBIVE1MRWxlbWVudDtcblx0Y29udGVudExpc3Q6IHN0cmluZ1tdO1xuXHRoaWdoTGlnaHRMaW5lczogbnVtYmVyW107XG59XG5cbi8vIFJlZmVyIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2phL2RvY3MvV2ViL0phdmFTY3JpcHQvR3VpZGUvUmVndWxhcl9FeHByZXNzaW9ucyNlc2NhcGluZ1xuZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcblx0cmV0dXJuIHN0ci5yZXBsYWNlKC9bLiorP149IToke30oKXxbXFxdXFwvXFxcXF0vZywgXCJcXFxcJCZcIik7IC8vIFx1NEUzQVx1NzI3OVx1NkI4QVx1N0IyNlx1NTNGN1x1NTJBMFx1NEUwQVx1OEY2Q1x1NEU0OVx1N0IyNlx1NTNGN1wiXFxcIlxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCZXR0ZXJDb2RlQmxvY2sgZXh0ZW5kcyBQbHVnaW4ge1xuXHRzZXR0aW5nczogU2V0dGluZ3M7XG5cblx0YXN5bmMgb25sb2FkKCkge1xuXHRcdGNvbnNvbGUubG9nKFwiTG9hZGluZyBCZXR0ZXIgQ29kZSBCbG9jayBQbHVnaW5cIik7XG5cdFx0YXdhaXQgdGhpcy5sb2FkU2V0dGluZ3MoKTtcblx0XHR0aGlzLmFkZFNldHRpbmdUYWIobmV3IEJldHRlckNvZGVCbG9ja1RhYih0aGlzLmFwcCwgdGhpcykpO1xuXHRcdHRoaXMucmVnaXN0ZXJNYXJrZG93blBvc3RQcm9jZXNzb3IoKGVsLCBjdHgpID0+IHtcblx0XHRcdEJldHRlckNvZGVCbG9ja3MoZWwsIGN0eCwgdGhpcylcblx0XHR9KVxuXHR9XG5cblx0b251bmxvYWQgKCkge1xuXHRcdGNvbnNvbGUubG9nKCdVbmxvYWRpbmcgQmV0dGVyIENvZGUgQmxvY2sgUGx1Z2luJyk7XG5cdH1cblx0XG5cdGFzeW5jIGxvYWRTZXR0aW5ncygpIHtcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcblx0fVxuXHRcblx0YXN5bmMgc2F2ZVNldHRpbmdzKCkge1xuXHRcdGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XG5cdH1cbn1cblxuY2xhc3MgQmV0dGVyQ29kZUJsb2NrVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XG5cdHBsdWdpbjogQmV0dGVyQ29kZUJsb2NrO1xuICBcblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogQmV0dGVyQ29kZUJsb2NrKSB7XG5cdCAgc3VwZXIoYXBwLCBwbHVnaW4pO1xuXHQgIHRoaXMucGx1Z2luID0gcGx1Z2luO1xuXHR9XG4gIFxuXHRkaXNwbGF5KCk6IHZvaWQge1xuXHQgIGxldCB7IGNvbnRhaW5lckVsIH0gPSB0aGlzO1xuICBcblx0ICBjb250YWluZXJFbC5lbXB0eSgpO1xuXHRcblx0ICBuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0TmFtZShcIkV4Y2x1ZGUgbGFuZ3VhZ2UgbGlzdFwiKVxuXHRcdC5zZXREZXNjKFwiVGl0bGUgYW5kIGxpbmUgbnVtYmVycyBkbyBub3QgYXBwbHkgaW4gdGhlc2UgbGFuZ3VhZ2VzLCBzZXBhcmF0ZSBieSBgLGBcIilcblx0XHQuYWRkVGV4dCh0ZXh0ID0+IHRleHQuc2V0UGxhY2Vob2xkZXIoJ2xpa2UgdG9kb2lzdCxvdGhlciwuLi4nKVxuXHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlTGFuZ3Muam9pbignLCcpKVxuXHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVMYW5ncyA9IHZhbHVlLnNwbGl0KCcsJyk7XG5cdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHR9KVxuXHRcdClcbiAgXG5cdCAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpLnNldE5hbWUoXCJGb250IGNvbG9yIG9mIHRpdGxlXCIpLmFkZFRleHQoKHRjKSA9PlxuXHRcdHRjXG5cdFx0ICAuc2V0UGxhY2Vob2xkZXIoXCJFbnRlciBhIGNvbG9yXCIpXG5cdFx0ICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudGl0bGVGb250Q29sb3IpXG5cdFx0ICAub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy50aXRsZUZvbnRDb2xvciA9IHZhbHVlO1xuXHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0ICB9KVxuXHQgICk7XG4gIFxuXHQgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKFwiQmFja2dyb3VuZCBjb2xvciBvZiB0aXRsZVwiKVxuXHRcdC5hZGRUZXh0KCh0YykgPT5cblx0XHQgIHRjXG5cdFx0XHQuc2V0UGxhY2Vob2xkZXIoXCIjMDAwMDAwMjBcIilcblx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy50aXRsZUJhY2tncm91bmRDb2xvcilcblx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdCAgdGhpcy5wbHVnaW4uc2V0dGluZ3MudGl0bGVCYWNrZ3JvdW5kQ29sb3IgPSB2YWx1ZTtcblx0XHRcdCAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHR9KVxuXHRcdCk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0TmFtZShcIkhpZ2hMaWdodCBDb2xvclwiKVxuXHRcdC5hZGRUZXh0KCh0YykgPT5cblx0XHQgIHRjXG5cdFx0XHQuc2V0UGxhY2Vob2xkZXIoXCIjMmQ4MmNjMjBcIilcblx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5oaWdoTGlnaHRDb2xvcilcblx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdCAgdGhpcy5wbHVnaW4uc2V0dGluZ3MuaGlnaExpZ2h0Q29sb3IgPSB2YWx1ZTtcblx0XHRcdCAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHR9KVxuXHRcdCk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0TmFtZShcIlNob3cgbGluZSBudW1iZXJcIilcblx0XHQuYWRkVG9nZ2xlKCh0YykgPT4gXG5cdFx0dGMuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hvd0xpbmVOdW1iZXIpXG5cdFx0Lm9uQ2hhbmdlKGFzeW5jKHZhbHVlKSA9PiB7XG5cdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93TGluZU51bWJlciA9IHZhbHVlO1xuXHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0fSlcblx0XHQpXG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0TmFtZShcIlNob3cgZGl2aWRpbmcgbGluZVwiKVxuXHRcdC5hZGRUb2dnbGUoKHRjKSA9PlxuXHRcdHRjLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dEaXZpZGluZ0xpbmUpXG5cdFx0Lm9uQ2hhbmdlKGFzeW5jKHZhbHVlKSA9PiB7XG5cdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93RGl2aWRpbmdMaW5lID0gdmFsdWU7XG5cdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHR9KVxuXHRcdClcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKFwiU2hvdyBsYW5ndWFnZSBuYW1lIGluIHRoZSB0b3AgcmlnaHRcIilcblx0XHQuYWRkVG9nZ2xlKCh0YykgPT5cblx0XHR0Yy5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93TGFuZ05hbWVJblRvcFJpZ2h0KVxuXHRcdC5vbkNoYW5nZShhc3luYyh2YWx1ZSkgPT4ge1xuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hvd0xhbmdOYW1lSW5Ub3BSaWdodCA9IHZhbHVlO1xuXHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0fSlcblx0XHQpXG5cdH1cbiAgfVxuXG5leHBvcnQgZnVuY3Rpb24gQmV0dGVyQ29kZUJsb2NrcyhlbDogSFRNTEVsZW1lbnQsIGNvbnRleHQ6IE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsIHBsdWdpbjogQmV0dGVyQ29kZUJsb2NrKSB7XG5cdGNvbnN0IHNldHRpbmdzID0gcGx1Z2luLnNldHRpbmdzXG5cdFxuXHRjb25zdCBjb2RlRWxtOiBIVE1MRWxlbWVudCA9IGVsLnF1ZXJ5U2VsZWN0b3IoJ3ByZSA+IGNvZGUnKVxuXHQvLyBvbmx5IGNoYW5nZSBwcmU+Y29kZVxuXHRpZiAoIWNvZGVFbG0pIHtcblx0ICByZXR1cm5cblx0fVxuXG5cdGxldCBsYW5nID0gREVGQVVMVF9MQU5HXG5cdC8vIHJldHVybiB3aGVuIGxhbmcgaXMgaW4gZXhjbHVkZSBsaXN0XG5cdGlmIChwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUxhbmdzLnNvbWUoZUxhbmdOYW1lID0+IGNvZGVFbG0uY2xhc3NMaXN0LmNvbnRhaW5zKGBsYW5ndWFnZS0ke2VMYW5nTmFtZX1gKSkpIHtcblx0ICByZXR1cm5cblx0fVxuXHRcblx0Y29kZUVsbS5jbGFzc0xpc3QuZm9yRWFjaCgodmFsdWUsIGtleSwgcGFyZW50KSA9PiB7XG5cdCAgaWYgKExBTkdfUkVHLnRlc3QodmFsdWUpKSB7XG5cdFx0bGFuZyA9IHZhbHVlLnJlcGxhY2UoJ2xhbmd1YWdlLScsICcnKVxuXHRcdHJldHVyblxuXHQgIH1cblx0fSlcblxuXHQvLyBpZiB0aGUgY29kZSBibG9jayBpcyBub3QgZGVzY3JpYmVkLCByZXR1cm5cblx0aWYobGFuZyA9PSBERUZBVUxUX0xBTkcpIHtcblx0XHRyZXR1cm5cblx0fVxuXG5cdGxldCB0aXRsZVJlZ0V4cCA9IC9USTpcIihbXlwiXSopXCIvaVxuXHRsZXQgaGlnaExpZ2h0TGluZXNSZWdFeHAgPSAvSEw6XCIoW15cIl0qKVwiL2lcblx0bGV0IGZvbGRSZWdFeHAgPSAvXCJGT0xEXCIvaVxuXG5cdGxldCBjb2RlQmxvY2sgPSBjb250ZXh0LmdldFNlY3Rpb25JbmZvKGNvZGVFbG0pXG5cdGxldCB2aWV3ID0gYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldylcblx0bGV0IGNvZGVCbG9ja0ZpcnN0TGluZSA9IHZpZXcuZWRpdG9yLmdldExpbmUoY29kZUJsb2NrLmxpbmVTdGFydClcblxuXHRsZXQgdGl0bGU6IHN0cmluZyA9IFwiXCJcblx0bGV0IGhpZ2hMaWdodExpbmVzOiBudW1iZXJbXSA9IFtdXG5cdGlmKGNvZGVCbG9ja0ZpcnN0TGluZS5tYXRjaCh0aXRsZVJlZ0V4cCkgIT0gbnVsbCkge1xuXHRcdHRpdGxlID0gY29kZUJsb2NrRmlyc3RMaW5lLm1hdGNoKHRpdGxlUmVnRXhwKVsxXVxuXHR9XG5cdGlmKGNvZGVCbG9ja0ZpcnN0TGluZS5tYXRjaChoaWdoTGlnaHRMaW5lc1JlZ0V4cCkgIT0gbnVsbCkge1xuXHRcdGxldCBoaWdoTGlnaHRMaW5lc0luZm8gPSBjb2RlQmxvY2tGaXJzdExpbmUubWF0Y2goaGlnaExpZ2h0TGluZXNSZWdFeHApWzFdXG5cdFx0aGlnaExpZ2h0TGluZXMgPSBhbmFseXNlSGlnaExpZ2h0TGluZXMoaGlnaExpZ2h0TGluZXNJbmZvKVxuXHR9XG5cblx0bGV0IGlzQ29sbGFwc2UgPSBmYWxzZTtcblx0aWYoZm9sZFJlZ0V4cC50ZXN0KGNvZGVCbG9ja0ZpcnN0TGluZSkpIHtcblx0XHRpc0NvbGxhcHNlID0gdHJ1ZVxuXHR9XG5cblx0Y29uc3QgcHJlID0gY29kZUVsbS5wYXJlbnRFbGVtZW50IC8vIGNvZGUtYmxvY2stcHJlX19oYXMtbGluZW51bVxuXHRjb25zdCBkaXYgPSBwcmUucGFyZW50RWxlbWVudCAvLyBjbGFzcyBjb2RlLWJsb2NrLXdyYXBcblxuXHQvKiBjb25zdCB7IGxpbmVTdGFydCwgbGluZUVuZCB9ID0gY3R4LmdldFNlY3Rpb25JbmZvKGVsKVxuXHRjb25zdCBsaW5lU2l6ZSA9IGxpbmVFbmQgLSBsaW5lU3RhcnQgLSAxICovXG5cdGNvbnN0IGNvbnRlbnRMaXN0OiBzdHJpbmdbXSA9IGNvZGVFbG0udGV4dENvbnRlbnQuc3BsaXQoTElORV9TUExJVF9NQVJLKVxuXHRjb25zdCBsaW5lU2l6ZSA9IGNvbnRlbnRMaXN0Lmxlbmd0aCAtIDFcblxuXHRjb25zdCBjYk1ldGE6IENvZGVCbG9ja01ldGEgPSB7IGxhbmdOYW1lOiBsYW5nLCBsaW5lU2l6ZSwgcHJlLCBjb2RlOiBjb2RlRWxtLCB0aXRsZSwgaXNDb2xsYXBzZSwgZGl2LCBjb250ZW50TGlzdCwgaGlnaExpZ2h0TGluZXN9XG5cblx0Y29uc3Qge3Nob3dMaW5lTnVtYmVyfSA9IHBsdWdpbi5zZXR0aW5nc1xuXG5cdGFkZENvZGVUaXRsZShwbHVnaW4sIHByZSwgY2JNZXRhKTtcblxuXHQvLyBhZGQgbGluZSBudW1iZXJcblx0aWYgKHNob3dMaW5lTnVtYmVyKSB7XG5cdFx0YWRkTGluZU51bWJlcihwbHVnaW4sIGNiTWV0YSlcblx0fVxuXG5cdGFkZExpbmVIaWdoTGlnaHQocGx1Z2luLCBwcmUsIGNiTWV0YSlcbn1cblxuZnVuY3Rpb24gY3JlYXRlRWxlbWVudCAodGFnTmFtZTogc3RyaW5nLCBkZWZhdWx0Q2xhc3NOYW1lPzogc3RyaW5nKSB7XG5cdGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpXG5cdGlmIChkZWZhdWx0Q2xhc3NOYW1lKSB7XG5cdCAgZWxlbWVudC5jbGFzc05hbWUgPSBkZWZhdWx0Q2xhc3NOYW1lXG5cdH1cblx0cmV0dXJuIGVsZW1lbnRcbn1cblxuZnVuY3Rpb24gYWRkTGluZU51bWJlciAocGx1Z2luOiBCZXR0ZXJDb2RlQmxvY2ssIGNiTWV0YTogQ29kZUJsb2NrTWV0YSkge1xuXHRjb25zdCB7IGxpbmVTaXplLCBwcmUsIGRpdiB9ID0gY2JNZXRhXG5cdC8vIGxldCBkaXYgcG9zaXRpb246IHJlbGF0aXZlO1xuXHRkaXYuY2xhc3NMaXN0LmFkZCgnY29kZS1ibG9jay13cmFwJylcblx0Ly8gY29uc3QgeyBmb250U2l6ZSwgbGluZUhlaWdodCB9ID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoY2JNZXRhLmNvZGUpXG5cdGNvbnN0IGxpbmVOdW1iZXIgPSBjcmVhdGVFbGVtZW50KCdzcGFuJywgJ2NvZGUtYmxvY2stbGluZW51bS13cmFwJylcblx0bGluZU51bWJlci5zdHlsZS50b3AgPSBDQl9QQURESU5HX1RPUDtcblx0QXJyYXkuZnJvbSh7IGxlbmd0aDogbGluZVNpemUgfSwgKHYsIGspID0+IGspLmZvckVhY2goaSA9PiB7XG5cdCAgY29uc3Qgc2luZ2xlTGluZSA9IGNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCAnY29kZS1ibG9jay1saW5lbnVtJylcblx0ICAvLyBzaW5nbGVMaW5lLnN0eWxlLmZvbnRTaXplID0gZm9udFNpemVcblx0ICAvLyBzaW5nbGVMaW5lLnN0eWxlLmxpbmVIZWlnaHQgPSBsaW5lSGVpZ2h0XG5cdCAgbGluZU51bWJlci5hcHBlbmRDaGlsZChzaW5nbGVMaW5lKVxuXHR9KVxuXHRcblx0aWYocGx1Z2luLnNldHRpbmdzLnNob3dEaXZpZGluZ0xpbmUpIHtcblx0XHRsaW5lTnVtYmVyLnN0eWxlLmJvcmRlclJpZ2h0ID0gXCIxcHggY3VycmVudENvbG9yIHNvbGlkXCJcblx0fVxuXG5cdHByZS5hcHBlbmRDaGlsZChsaW5lTnVtYmVyKVxuXHRwcmUuY2xhc3NMaXN0LmFkZCgnY29kZS1ibG9jay1wcmVfX2hhcy1saW5lbnVtJylcbn1cblxuXG5mdW5jdGlvbiBhZGRDb2RlVGl0bGUgKHBsdWdpbjogQmV0dGVyQ29kZUJsb2NrLCB3cmFwcGVyRWxtOiBIVE1MRWxlbWVudCwgY2JNZXRhOiBDb2RlQmxvY2tNZXRhKSB7XG5cdHdyYXBwZXJFbG0uc3R5bGUuc2V0UHJvcGVydHkoXCJwb3NpdGlvblwiLCBcInJlbGF0aXZlXCIsIFwiaW1wb3J0YW50XCIpO1xuXHR3cmFwcGVyRWxtLnN0eWxlLnNldFByb3BlcnR5KFwicGFkZGluZy10b3BcIiwgQ0JfUEFERElOR19UT1AsIFwiaW1wb3J0YW50XCIpO1xuXG5cdHdyYXBwZXJFbG1cblx0ICAucXVlcnlTZWxlY3RvckFsbChcIi5vYnNpZGlhbi1lbWJlZGRlZC1jb2RlLXRpdGxlX19jb2RlLWJsb2NrLXRpdGxlXCIpXG5cdCAgLmZvckVhY2goKHgpID0+IHgucmVtb3ZlKCkpOyAvLyBcdTk2MzJcdTYyOTZcdTUyQThcblxuXHRsZXQgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJwcmVcIik7XG5cdC8vIGQuYXBwZW5kVGV4dChjYk1ldGEudGl0bGUpO1xuXHRkLmFwcGVuZFRleHQoY2JNZXRhLnRpdGxlKVxuXG5cdGlmKGNiTWV0YS5pc0NvbGxhcHNlKSB7XG5cdFx0ZC5zZXRBdHRyaWJ1dGUoXCJjbG9zZWRcIixcIlwiKVxuXHR9XG5cdGQuY2xhc3NOYW1lID0gXCJvYnNpZGlhbi1lbWJlZGRlZC1jb2RlLXRpdGxlX19jb2RlLWJsb2NrLXRpdGxlXCI7XG5cblx0aWYocGx1Z2luLnNldHRpbmdzLnRpdGxlRm9udENvbG9yKSB7XG5cdFx0ZC5zdHlsZS5zZXRQcm9wZXJ0eShcImNvbG9yXCIsIHBsdWdpbi5zZXR0aW5ncy50aXRsZUZvbnRDb2xvciwgXCJpbXBvcnRhbnRcIilcblx0fVxuXHRkLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHBsdWdpbi5zZXR0aW5ncy50aXRsZUJhY2tncm91bmRDb2xvciB8fCBcIiMwMDAwMDAyMFwiO1xuXG5cdGxldCBjb2xsYXBzZXIgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIsXCJjb2xsYXBzZXJcIilcblx0bGV0IGhhbmRsZSA9IGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgXCJoYW5kbGVcIilcblx0Y29sbGFwc2VyLmFwcGVuZENoaWxkKGhhbmRsZSlcblx0ZC5hcHBlbmRDaGlsZChjb2xsYXBzZXIpXG5cblx0aWYocGx1Z2luLnNldHRpbmdzLnNob3dMYW5nTmFtZUluVG9wUmlnaHQpIHtcblx0XHRsZXQgbGFuZ05hbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpOyAvLyBcdTU3MjhcdTUzRjNcdTRGQTdcdTZERkJcdTUyQTBcdTRFRTNcdTc4MDFcdTdDN0JcdTU3OEJcblx0XHRsZXQgbGFuZ05hbWVTdHJpbmcgPSBjYk1ldGEubGFuZ05hbWVcblx0XHRsYW5nTmFtZVN0cmluZyA9IGxhbmdOYW1lU3RyaW5nWzBdLnRvVXBwZXJDYXNlKCkgKyBsYW5nTmFtZVN0cmluZy5zbGljZSgxKSAvLyBcdTk5OTZcdTVCNTdcdTZCQ0RcdTU5MjdcdTUxOTlcblx0XHRsYW5nTmFtZS5hcHBlbmRUZXh0KGxhbmdOYW1lU3RyaW5nKTtcblx0XHRsYW5nTmFtZS5jbGFzc05hbWUgPSBcImxhbmdOYW1lXCI7XG5cdFx0ZC5hcHBlbmRDaGlsZChsYW5nTmFtZSk7XG5cdH1cblx0ZC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsZnVuY3Rpb24odGhpcykge1xuXHRcdGlmKGQuaGFzQXR0cmlidXRlKFwiY2xvc2VkXCIpKXtcblx0XHRcdGQucmVtb3ZlQXR0cmlidXRlKFwiY2xvc2VkXCIpXG5cdFx0fSBlbHNlIHtcblx0XHRcdGQuc2V0QXR0cmlidXRlKFwiY2xvc2VkXCIsJycpXG5cdFx0fVxuXHR9KVxuXHR3cmFwcGVyRWxtLnByZXBlbmQoZCk7XG59XG5cbmZ1bmN0aW9uIGFkZExpbmVIaWdoTGlnaHQocGx1Z2luOiBCZXR0ZXJDb2RlQmxvY2ssIHdyYXBwZXJFbG06IEhUTUxFbGVtZW50LCBjYk1ldGE6IENvZGVCbG9ja01ldGEpIHtcblx0aWYoY2JNZXRhLmhpZ2hMaWdodExpbmVzLmxlbmd0aCA9PSAwKSByZXR1cm5cblxuXHRsZXQgaGlnaExpZ2h0V3JhcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJwcmVcIilcblx0aGlnaExpZ2h0V3JhcC5jbGFzc05hbWUgPSBcImNvZGUtYmxvY2staGlnaGxpZ2h0LXdyYXBcIlxuXHRmb3IobGV0IGkgPSAwOyBpIDwgY2JNZXRhLmxpbmVTaXplOyBpKyspIHtcblx0XHRjb25zdCBzaW5nbGVMaW5lID0gY3JlYXRlRWxlbWVudChcInNwYW5cIiwgJ2NvZGUtYmxvY2staGlnaGxpZ2h0Jylcblx0XHRpZihjYk1ldGEuaGlnaExpZ2h0TGluZXMuY29udGFpbnMoaSsxKSkge1xuXHRcdFx0c2luZ2xlTGluZS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBwbHVnaW4uc2V0dGluZ3MuaGlnaExpZ2h0Q29sb3IgfHwgXCIjMmQ4MmNjMjBcIlxuXHRcdH1cblx0XHRoaWdoTGlnaHRXcmFwLmFwcGVuZENoaWxkKHNpbmdsZUxpbmUpXG5cdH1cblxuXHR3cmFwcGVyRWxtLmFwcGVuZENoaWxkKGhpZ2hMaWdodFdyYXApXG59XG5cbmZ1bmN0aW9uIGFuYWx5c2VIaWdoTGlnaHRMaW5lcyhzdHI6IHN0cmluZyk6IG51bWJlcltdIHtcblx0c3RyID0gc3RyLnJlcGxhY2UoL1xccyovZywgXCJcIikgLy8gXHU1M0JCXHU5NjY0XHU1QjU3XHU3QjI2XHU0RTMyXHU0RTJEXHU2MjQwXHU2NzA5XHU3QTdBXHU2ODNDXG5cdGNvbnN0IHJlc3VsdDogbnVtYmVyW10gPSBbXVxuXG5cdGxldCBzdHJzID0gc3RyLnNwbGl0KFwiLFwiKVxuXHRzdHJzLmZvckVhY2goaXQgPT4ge1xuXHRcdGlmKC9cXHcrLVxcdysvLnRlc3QoaXQpKSB7IC8vIFx1NTk4Mlx1Njc5Q1x1NTMzOVx1OTE0RCAxLTMgXHU4RkQ5XHU2ODM3XHU3Njg0XHU2ODNDXHU1RjBGXHVGRjBDXHU0RjlEXHU2QjIxXHU2REZCXHU1MkEwXHU2NTcwXHU1QjU3XG5cdFx0XHRsZXQgbGVmdCA9IE51bWJlcihpdC5zcGxpdCgnLScpWzBdKVxuXHRcdFx0bGV0IHJpZ2h0ID0gTnVtYmVyKGl0LnNwbGl0KCctJylbMV0pXG5cdFx0XHRmb3IobGV0IGkgPSBsZWZ0OyBpIDw9IHJpZ2h0OyBpKyspIHtcblx0XHRcdFx0cmVzdWx0LnB1c2goaSlcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0cmVzdWx0LnB1c2goTnVtYmVyKGl0KSlcblx0XHR9XG5cdH0pXG5cblx0cmV0dXJuIHJlc3VsdFxufSJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQSxzQkFBa0s7QUFHbEssSUFBTSxlQUFlO0FBQ3JCLElBQU0sV0FBVztBQUNqQixJQUFNLGtCQUFrQjtBQUV4QixJQUFNLGlCQUFpQjtBQWV2QixJQUFNLG1CQUE2QjtBQUFBLEVBQ2xDLDJCQUEyQjtBQUFBLEVBQzNCLHNCQUFzQjtBQUFBLEVBQ3RCLGdCQUFnQjtBQUFBLEVBQ2hCLGdCQUFnQjtBQUFBLEVBRWhCLGNBQWM7QUFBQSxFQUVkLGdCQUFnQjtBQUFBLEVBQ2hCLGtCQUFrQjtBQUFBLEVBQ2xCLHdCQUF3QjtBQUFBO0FBOEJ6QixvQ0FBNkMsdUJBQU87QUFBQSxFQUc3QyxTQUFTO0FBQUE7QUFDZCxjQUFRLElBQUk7QUFDWixZQUFNLEtBQUs7QUFDWCxXQUFLLGNBQWMsSUFBSSxtQkFBbUIsS0FBSyxLQUFLO0FBQ3BELFdBQUssOEJBQThCLENBQUMsSUFBSSxRQUFRO0FBQy9DLHlCQUFpQixJQUFJLEtBQUs7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUk1QixXQUFZO0FBQ1gsWUFBUSxJQUFJO0FBQUE7QUFBQSxFQUdQLGVBQWU7QUFBQTtBQUNwQixXQUFLLFdBQVcsT0FBTyxPQUFPLElBQUksa0JBQWtCLE1BQU0sS0FBSztBQUFBO0FBQUE7QUFBQSxFQUcxRCxlQUFlO0FBQUE7QUFDcEIsWUFBTSxLQUFLLFNBQVMsS0FBSztBQUFBO0FBQUE7QUFBQTtBQUkzQix1Q0FBaUMsaUNBQWlCO0FBQUEsRUFHakQsWUFBWSxNQUFVLFFBQXlCO0FBQzdDLFVBQU0sTUFBSztBQUNYLFNBQUssU0FBUztBQUFBO0FBQUEsRUFHaEIsVUFBZ0I7QUFDZCxRQUFJLEVBQUUsZ0JBQWdCO0FBRXRCLGdCQUFZO0FBRVosUUFBSSx3QkFBUSxhQUNaLFFBQVEseUJBQ1IsUUFBUSwyRUFDUixRQUFRLFVBQVEsS0FBSyxlQUFlLDBCQUNwQyxTQUFTLEtBQUssT0FBTyxTQUFTLGFBQWEsS0FBSyxNQUNoRCxTQUFTLENBQU8sVUFBVTtBQUMxQixXQUFLLE9BQU8sU0FBUyxlQUFlLE1BQU0sTUFBTTtBQUNoRCxZQUFNLEtBQUssT0FBTztBQUFBO0FBSWxCLFFBQUksd0JBQVEsYUFBYSxRQUFRLHVCQUF1QixRQUFRLENBQUMsT0FDbEUsR0FDRyxlQUFlLGlCQUNmLFNBQVMsS0FBSyxPQUFPLFNBQVMsZ0JBQzlCLFNBQVMsQ0FBTyxVQUFVO0FBQzVCLFdBQUssT0FBTyxTQUFTLGlCQUFpQjtBQUN0QyxZQUFNLEtBQUssT0FBTztBQUFBO0FBSWxCLFFBQUksd0JBQVEsYUFDWixRQUFRLDZCQUNSLFFBQVEsQ0FBQyxPQUNSLEdBQ0EsZUFBZSxhQUNmLFNBQVMsS0FBSyxPQUFPLFNBQVMsc0JBQzlCLFNBQVMsQ0FBTyxVQUFVO0FBQ3pCLFdBQUssT0FBTyxTQUFTLHVCQUF1QjtBQUM1QyxZQUFNLEtBQUssT0FBTztBQUFBO0FBSXJCLFFBQUksd0JBQVEsYUFDWCxRQUFRLG1CQUNSLFFBQVEsQ0FBQyxPQUNSLEdBQ0EsZUFBZSxhQUNmLFNBQVMsS0FBSyxPQUFPLFNBQVMsZ0JBQzlCLFNBQVMsQ0FBTyxVQUFVO0FBQ3pCLFdBQUssT0FBTyxTQUFTLGlCQUFpQjtBQUN0QyxZQUFNLEtBQUssT0FBTztBQUFBO0FBSXJCLFFBQUksd0JBQVEsYUFDWCxRQUFRLG9CQUNSLFVBQVUsQ0FBQyxPQUNaLEdBQUcsU0FBUyxLQUFLLE9BQU8sU0FBUyxnQkFDaEMsU0FBUyxDQUFNLFVBQVU7QUFDekIsV0FBSyxPQUFPLFNBQVMsaUJBQWlCO0FBQ3RDLFlBQU0sS0FBSyxPQUFPO0FBQUE7QUFJbkIsUUFBSSx3QkFBUSxhQUNYLFFBQVEsc0JBQ1IsVUFBVSxDQUFDLE9BQ1osR0FBRyxTQUFTLEtBQUssT0FBTyxTQUFTLGtCQUNoQyxTQUFTLENBQU0sVUFBVTtBQUN6QixXQUFLLE9BQU8sU0FBUyxtQkFBbUI7QUFDeEMsWUFBTSxLQUFLLE9BQU87QUFBQTtBQUluQixRQUFJLHdCQUFRLGFBQ1gsUUFBUSx1Q0FDUixVQUFVLENBQUMsT0FDWixHQUFHLFNBQVMsS0FBSyxPQUFPLFNBQVMsd0JBQ2hDLFNBQVMsQ0FBTSxVQUFVO0FBQ3pCLFdBQUssT0FBTyxTQUFTLHlCQUF5QjtBQUM5QyxZQUFNLEtBQUssT0FBTztBQUFBO0FBQUE7QUFBQTtBQU1kLDBCQUEwQixJQUFpQixTQUF1QyxRQUF5QjtBQUNqSCxRQUFNLFdBQVcsT0FBTztBQUV4QixRQUFNLFVBQXVCLEdBQUcsY0FBYztBQUU5QyxNQUFJLENBQUMsU0FBUztBQUNaO0FBQUE7QUFHRixNQUFJLE9BQU87QUFFWCxNQUFJLE9BQU8sU0FBUyxhQUFhLEtBQUssZUFBYSxRQUFRLFVBQVUsU0FBUyxZQUFZLGVBQWU7QUFDdkc7QUFBQTtBQUdGLFVBQVEsVUFBVSxRQUFRLENBQUMsT0FBTyxLQUFLLFdBQVc7QUFDaEQsUUFBSSxTQUFTLEtBQUssUUFBUTtBQUMzQixhQUFPLE1BQU0sUUFBUSxhQUFhO0FBQ2xDO0FBQUE7QUFBQTtBQUtELE1BQUcsUUFBUSxjQUFjO0FBQ3hCO0FBQUE7QUFHRCxNQUFJLGNBQWM7QUFDbEIsTUFBSSx1QkFBdUI7QUFDM0IsTUFBSSxhQUFhO0FBRWpCLE1BQUksWUFBWSxRQUFRLGVBQWU7QUFDdkMsTUFBSSxPQUFPLElBQUksVUFBVSxvQkFBb0I7QUFDN0MsTUFBSSxxQkFBcUIsS0FBSyxPQUFPLFFBQVEsVUFBVTtBQUV2RCxNQUFJLFFBQWdCO0FBQ3BCLE1BQUksaUJBQTJCO0FBQy9CLE1BQUcsbUJBQW1CLE1BQU0sZ0JBQWdCLE1BQU07QUFDakQsWUFBUSxtQkFBbUIsTUFBTSxhQUFhO0FBQUE7QUFFL0MsTUFBRyxtQkFBbUIsTUFBTSx5QkFBeUIsTUFBTTtBQUMxRCxRQUFJLHFCQUFxQixtQkFBbUIsTUFBTSxzQkFBc0I7QUFDeEUscUJBQWlCLHNCQUFzQjtBQUFBO0FBR3hDLE1BQUksYUFBYTtBQUNqQixNQUFHLFdBQVcsS0FBSyxxQkFBcUI7QUFDdkMsaUJBQWE7QUFBQTtBQUdkLFFBQU0sTUFBTSxRQUFRO0FBQ3BCLFFBQU0sTUFBTSxJQUFJO0FBSWhCLFFBQU0sY0FBd0IsUUFBUSxZQUFZLE1BQU07QUFDeEQsUUFBTSxXQUFXLFlBQVksU0FBUztBQUV0QyxRQUFNLFNBQXdCLEVBQUUsVUFBVSxNQUFNLFVBQVUsS0FBSyxNQUFNLFNBQVMsT0FBTyxZQUFZLEtBQUssYUFBYTtBQUVuSCxRQUFNLEVBQUMsbUJBQWtCLE9BQU87QUFFaEMsZUFBYSxRQUFRLEtBQUs7QUFHMUIsTUFBSSxnQkFBZ0I7QUFDbkIsa0JBQWMsUUFBUTtBQUFBO0FBR3ZCLG1CQUFpQixRQUFRLEtBQUs7QUFBQTtBQUcvQix1QkFBd0IsU0FBaUIsa0JBQTJCO0FBQ25FLFFBQU0sVUFBVSxTQUFTLGNBQWM7QUFDdkMsTUFBSSxrQkFBa0I7QUFDcEIsWUFBUSxZQUFZO0FBQUE7QUFFdEIsU0FBTztBQUFBO0FBR1IsdUJBQXdCLFFBQXlCLFFBQXVCO0FBQ3ZFLFFBQU0sRUFBRSxVQUFVLEtBQUssUUFBUTtBQUUvQixNQUFJLFVBQVUsSUFBSTtBQUVsQixRQUFNLGFBQWEsY0FBYyxRQUFRO0FBQ3pDLGFBQVcsTUFBTSxNQUFNO0FBQ3ZCLFFBQU0sS0FBSyxFQUFFLFFBQVEsWUFBWSxDQUFDLEdBQUcsTUFBTSxHQUFHLFFBQVEsT0FBSztBQUN6RCxVQUFNLGFBQWEsY0FBYyxRQUFRO0FBR3pDLGVBQVcsWUFBWTtBQUFBO0FBR3pCLE1BQUcsT0FBTyxTQUFTLGtCQUFrQjtBQUNwQyxlQUFXLE1BQU0sY0FBYztBQUFBO0FBR2hDLE1BQUksWUFBWTtBQUNoQixNQUFJLFVBQVUsSUFBSTtBQUFBO0FBSW5CLHNCQUF1QixRQUF5QixZQUF5QixRQUF1QjtBQUMvRixhQUFXLE1BQU0sWUFBWSxZQUFZLFlBQVk7QUFDckQsYUFBVyxNQUFNLFlBQVksZUFBZSxnQkFBZ0I7QUFFNUQsYUFDRyxpQkFBaUIsbURBQ2pCLFFBQVEsQ0FBQyxNQUFNLEVBQUU7QUFFcEIsTUFBSSxJQUFJLFNBQVMsY0FBYztBQUUvQixJQUFFLFdBQVcsT0FBTztBQUVwQixNQUFHLE9BQU8sWUFBWTtBQUNyQixNQUFFLGFBQWEsVUFBUztBQUFBO0FBRXpCLElBQUUsWUFBWTtBQUVkLE1BQUcsT0FBTyxTQUFTLGdCQUFnQjtBQUNsQyxNQUFFLE1BQU0sWUFBWSxTQUFTLE9BQU8sU0FBUyxnQkFBZ0I7QUFBQTtBQUU5RCxJQUFFLE1BQU0sa0JBQWtCLE9BQU8sU0FBUyx3QkFBd0I7QUFFbEUsTUFBSSxZQUFZLGNBQWMsT0FBTTtBQUNwQyxNQUFJLFNBQVMsY0FBYyxPQUFPO0FBQ2xDLFlBQVUsWUFBWTtBQUN0QixJQUFFLFlBQVk7QUFFZCxNQUFHLE9BQU8sU0FBUyx3QkFBd0I7QUFDMUMsUUFBSSxXQUFXLFNBQVMsY0FBYztBQUN0QyxRQUFJLGlCQUFpQixPQUFPO0FBQzVCLHFCQUFpQixlQUFlLEdBQUcsZ0JBQWdCLGVBQWUsTUFBTTtBQUN4RSxhQUFTLFdBQVc7QUFDcEIsYUFBUyxZQUFZO0FBQ3JCLE1BQUUsWUFBWTtBQUFBO0FBRWYsSUFBRSxpQkFBaUIsU0FBUSxXQUFlO0FBQ3pDLFFBQUcsRUFBRSxhQUFhLFdBQVU7QUFDM0IsUUFBRSxnQkFBZ0I7QUFBQSxXQUNaO0FBQ04sUUFBRSxhQUFhLFVBQVM7QUFBQTtBQUFBO0FBRzFCLGFBQVcsUUFBUTtBQUFBO0FBR3BCLDBCQUEwQixRQUF5QixZQUF5QixRQUF1QjtBQUNsRyxNQUFHLE9BQU8sZUFBZSxVQUFVO0FBQUc7QUFFdEMsTUFBSSxnQkFBZ0IsU0FBUyxjQUFjO0FBQzNDLGdCQUFjLFlBQVk7QUFDMUIsV0FBUSxJQUFJLEdBQUcsSUFBSSxPQUFPLFVBQVUsS0FBSztBQUN4QyxVQUFNLGFBQWEsY0FBYyxRQUFRO0FBQ3pDLFFBQUcsT0FBTyxlQUFlLFNBQVMsSUFBRSxJQUFJO0FBQ3ZDLGlCQUFXLE1BQU0sa0JBQWtCLE9BQU8sU0FBUyxrQkFBa0I7QUFBQTtBQUV0RSxrQkFBYyxZQUFZO0FBQUE7QUFHM0IsYUFBVyxZQUFZO0FBQUE7QUFHeEIsK0JBQStCLEtBQXVCO0FBQ3JELFFBQU0sSUFBSSxRQUFRLFFBQVE7QUFDMUIsUUFBTSxTQUFtQjtBQUV6QixNQUFJLE9BQU8sSUFBSSxNQUFNO0FBQ3JCLE9BQUssUUFBUSxRQUFNO0FBQ2xCLFFBQUcsVUFBVSxLQUFLLEtBQUs7QUFDdEIsVUFBSSxPQUFPLE9BQU8sR0FBRyxNQUFNLEtBQUs7QUFDaEMsVUFBSSxRQUFRLE9BQU8sR0FBRyxNQUFNLEtBQUs7QUFDakMsZUFBUSxJQUFJLE1BQU0sS0FBSyxPQUFPLEtBQUs7QUFDbEMsZUFBTyxLQUFLO0FBQUE7QUFBQSxXQUVQO0FBQ04sYUFBTyxLQUFLLE9BQU87QUFBQTtBQUFBO0FBSXJCLFNBQU87QUFBQTsiLAogICJuYW1lcyI6IFtdCn0K +function resizeNumWrapAndHLWrap(el, context) { + setTimeout(function() { + return __async(this, null, function* () { + let codeBlockEl = el.querySelector("pre > code"); + if (!codeBlockEl) + return; + let numWrap = el.querySelector(".code-block-linenum-wrap"); + let highWrap = el.querySelector(".code-block-highlight-wrap"); + let codeBlockInfo = context.getSectionInfo(codeBlockEl); + let view; + let codeBlockLineNum; + let lineStart = 0; + let lineEnd = 0; + if (codeBlockInfo) { + view = app.workspace.getActiveViewOfType(import_obsidian.MarkdownView); + codeBlockLineNum = codeBlockInfo.lineEnd - codeBlockInfo.lineStart - 1; + } else { + return; + } + let span = createElement("span"); + for (let i = 0; i < codeBlockLineNum; i++) { + let oneLineText; + if (view) { + oneLineText = view.editor.getLine(codeBlockInfo.lineStart + i + 1); + } else { + } + span.innerHTML = oneLineText || "0"; + codeBlockEl.appendChild(span); + span.style.display = "block"; + let lineHeight = span.getBoundingClientRect().height + "px"; + let numOneLine = numWrap ? numWrap.childNodes[i] : null; + let hlOneLine = highWrap ? highWrap.childNodes[i] : null; + if (numOneLine) + numOneLine.style.height = lineHeight; + if (hlOneLine) + hlOneLine.style.height = lineHeight; + span.remove(); + } + }); + }, 100); +} +function exportPDF(el, plugin, codeBlockFirstLines, codeBlockSections) { + let codeBlocks = el.querySelectorAll("pre > code"); + codeBlocks.forEach((codeElm, key) => { + let langName = "", title = "", highLightLines = []; + codeElm.classList.forEach((value) => { + if (LANG_REG.test(value)) { + langName = value.replace("language-", ""); + return; + } + }); + if (codeBlockFirstLines[key].match(titleRegExp) != null) { + title = codeBlockFirstLines[key].match(titleRegExp)[1]; + } + if (codeBlockFirstLines[key].match(highLightLinesRegExp) != null) { + let highLightLinesInfo = codeBlockFirstLines[key].match(highLightLinesRegExp)[1]; + highLightLines = analyseHighLightLines(highLightLinesInfo); + } + let lineSize = codeBlockSections[key].position.end.line - codeBlockSections[key].position.start.line - 1; + let cbMeta = { + langName, + lineSize, + pre: codeElm.parentElement, + code: codeElm, + title, + isCollapse: false, + div: codeElm.parentElement.parentElement, + contentList: [], + highLightLines + }; + addCodeTitleWrapper(plugin, codeElm.parentElement, cbMeta); + addCodeTitle(plugin, cbMeta.pre, cbMeta); + if (plugin.settings.showLineNumber) { + addLineNumber(plugin, cbMeta); + } + addLineHighLight(plugin, cbMeta.pre, cbMeta); + }); +} +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibWFpbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgbGlua1N5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBBcHAsIEVkaXRvciwgTWFya2Rvd25WaWV3LCBNb2RhbCwgTm90aWNlLCBQbHVnaW4sIFBsdWdpblNldHRpbmdUYWIsIFNldHRpbmcsIE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsIE1lbnUsIFNldHRpbmdUYWIsIFRBYnN0cmFjdEZpbGUsIFRGaWxlLCBTZWN0aW9uQ2FjaGUsIFZhdWx0IH0gZnJvbSAnb2JzaWRpYW4nO1xuaW1wb3J0IHsganNvbiB9IGZyb20gJ3N0cmVhbS9jb25zdW1lcnMnO1xuXG5jb25zdCBERUZBVUxUX0xBTkdfQVRUUiA9ICdsYW5ndWFnZS10ZXh0J1xuY29uc3QgREVGQVVMVF9MQU5HID0gJydcbmNvbnN0IExBTkdfUkVHID0gL15sYW5ndWFnZS0vXG5jb25zdCBMSU5FX1NQTElUX01BUksgPSAnXFxuJ1xuXG5jb25zdCB0aXRsZVJlZ0V4cCA9IC9USTpcIihbXlwiXSopXCIvaVxuY29uc3QgaGlnaExpZ2h0TGluZXNSZWdFeHAgPSAvSEw6XCIoW15cIl0qKVwiL2lcbmNvbnN0IGZvbGRSZWdFeHAgPSAvXCJGT0xEXCIvaVxuXG5jb25zdCBDQl9QQURESU5HX1RPUCA9IFwiMzVweFwiIC8vIFx1NEVFM1x1NzgwMVx1NTc1N1x1NEUwQVx1OEZCOVx1OERERFxuXG5pbnRlcmZhY2UgU2V0dGluZ3Mge1xuXHRzdWJzdGl0dXRpb25Ub2tlbkZvclNwYWNlOiBzdHJpbmc7XG5cdHRpdGxlQmFja2dyb3VuZENvbG9yOiBzdHJpbmc7XG5cdHRpdGxlRm9udENvbG9yOiBzdHJpbmc7XG5cdGhpZ2hMaWdodENvbG9yOiBzdHJpbmc7XG5cblx0ZXhjbHVkZUxhbmdzOiBzdHJpbmdbXTsgLy8gXHU5NzAwXHU4OTgxXHU2MzkyXHU5NjY0XHU3Njg0XHU4QkVEXHU4QTAwXG5cblx0c2hvd0xpbmVOdW1iZXI6IGJvb2xlYW47IC8vIFx1NjYzRVx1NzkzQVx1ODg0Q1x1NTNGN1xuXHRzaG93RGl2aWRpbmdMaW5lOiBib29sZWFuO1xuXHRzaG93TGFuZ05hbWVJblRvcFJpZ2h0OiBib29sZWFuO1xufVxuXG5jb25zdCBERUZBVUxUX1NFVFRJTkdTOiBTZXR0aW5ncyA9IHtcblx0c3Vic3RpdHV0aW9uVG9rZW5Gb3JTcGFjZTogdW5kZWZpbmVkLFxuXHR0aXRsZUJhY2tncm91bmRDb2xvcjogXCIjMDAwMDAwMjBcIixcblx0dGl0bGVGb250Q29sb3I6IHVuZGVmaW5lZCxcblx0aGlnaExpZ2h0Q29sb3I6IFwiIzJkODJjYzIwXCIsXG5cblx0ZXhjbHVkZUxhbmdzOiBbXSxcblxuXHRzaG93TGluZU51bWJlcjogdHJ1ZSxcblx0c2hvd0RpdmlkaW5nTGluZTogZmFsc2UsXG5cdHNob3dMYW5nTmFtZUluVG9wUmlnaHQ6IHRydWVcbn07XG5cbmludGVyZmFjZSBDb2RlQmxvY2tNZXRhIHtcblx0Ly8gTGFuZ3VhZ2UgbmFtZVxuXHRsYW5nTmFtZTogc3RyaW5nO1xuXG5cdC8vIENvZGUgYmxvY2sgdG90YWwgbGluZSBzaXplXG5cdGxpbmVTaXplOiBudW1iZXI7XG5cblx0Ly8gQ29kZSBibG9jayAncHJlJyBIVE1MRWxlbWVudFxuXHRwcmU6IEhUTUxFbGVtZW50O1xuXG5cdC8vIENvZGUgYmxvY2sgJ2NvZGUnIEhUTUxFbGVtZW50XG5cdGNvZGU6IEhUTUxFbGVtZW50O1xuXG5cdHRpdGxlOiBzdHJpbmc7IC8vIFx1NEVFM1x1NzgwMVx1NTc1N1x1NjgwN1x1OTg5OFxuXHRpc0NvbGxhcHNlOmJvb2xlYW47IC8vIFx1NjYyRlx1NTQyNlx1OUVEOFx1OEJBNFx1NjI5OFx1NTNFMFxuXG5cdC8vIENvZGUgYmxvY2sgd3JhcCBkaXZcblx0ZGl2OiBIVE1MRWxlbWVudDtcblx0Y29udGVudExpc3Q6IHN0cmluZ1tdO1xuXHRoaWdoTGlnaHRMaW5lczogbnVtYmVyW107XG59XG5cbi8vIFJlZmVyIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2phL2RvY3MvV2ViL0phdmFTY3JpcHQvR3VpZGUvUmVndWxhcl9FeHByZXNzaW9ucyNlc2NhcGluZ1xuZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcblx0cmV0dXJuIHN0ci5yZXBsYWNlKC9bLiorP149IToke30oKXxbXFxdXFwvXFxcXF0vZywgXCJcXFxcJCZcIik7IC8vIFx1NEUzQVx1NzI3OVx1NkI4QVx1N0IyNlx1NTNGN1x1NTJBMFx1NEUwQVx1OEY2Q1x1NEU0OVx1N0IyNlx1NTNGN1wiXFxcIlxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCZXR0ZXJDb2RlQmxvY2sgZXh0ZW5kcyBQbHVnaW4ge1xuXHRzZXR0aW5nczogU2V0dGluZ3M7XG5cblx0YXN5bmMgb25sb2FkKCkge1xuXHRcdGNvbnNvbGUubG9nKFwiTG9hZGluZyBCZXR0ZXIgQ29kZSBCbG9jayBQbHVnaW5cIik7XG5cdFx0YXdhaXQgdGhpcy5sb2FkU2V0dGluZ3MoKTtcblx0XHR0aGlzLmFkZFNldHRpbmdUYWIobmV3IEJldHRlckNvZGVCbG9ja1RhYih0aGlzLmFwcCwgdGhpcykpO1xuXHRcdHRoaXMucmVnaXN0ZXJNYXJrZG93blBvc3RQcm9jZXNzb3IoKGVsLCBjdHgpID0+IHtcblx0XHRcdEJldHRlckNvZGVCbG9ja3MoZWwsIGN0eCwgdGhpcylcblx0XHRcdGFwcC53b3Jrc3BhY2Uub24oJ3Jlc2l6ZScsICgpID0+IHtcblx0XHRcdFx0cmVzaXplTnVtV3JhcEFuZEhMV3JhcChlbCwgY3R4KVxuXHRcdFx0fSlcblx0XHR9KVxuXG5cdH1cblxuXHRvbnVubG9hZCAoKSB7XG5cdFx0Y29uc29sZS5sb2coJ1VubG9hZGluZyBCZXR0ZXIgQ29kZSBCbG9jayBQbHVnaW4nKTtcblx0fVxuXHRcblx0YXN5bmMgbG9hZFNldHRpbmdzKCkge1xuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xuXHR9XG5cdFxuXHRhc3luYyBzYXZlU2V0dGluZ3MoKSB7XG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcblx0fVxufVxuXG5jbGFzcyBCZXR0ZXJDb2RlQmxvY2tUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcblx0cGx1Z2luOiBCZXR0ZXJDb2RlQmxvY2s7XG4gIFxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBCZXR0ZXJDb2RlQmxvY2spIHtcblx0ICBzdXBlcihhcHAsIHBsdWdpbik7XG5cdCAgdGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cbiAgXG5cdGRpc3BsYXkoKTogdm9pZCB7XG5cdCAgbGV0IHsgY29udGFpbmVyRWwgfSA9IHRoaXM7XG4gIFxuXHQgIGNvbnRhaW5lckVsLmVtcHR5KCk7XG5cdFxuXHQgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKFwiRXhjbHVkZSBsYW5ndWFnZSBsaXN0XCIpXG5cdFx0LnNldERlc2MoXCJUaXRsZSBhbmQgbGluZSBudW1iZXJzIGRvIG5vdCBhcHBseSBpbiB0aGVzZSBsYW5ndWFnZXMsIHNlcGFyYXRlIGJ5IGAsYFwiKVxuXHRcdC5hZGRUZXh0KHRleHQgPT4gdGV4dC5zZXRQbGFjZWhvbGRlcignbGlrZSB0b2RvaXN0LG90aGVyLC4uLicpXG5cdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVMYW5ncy5qb2luKCcsJykpXG5cdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUxhbmdzID0gdmFsdWUuc3BsaXQoJywnKTtcblx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdH0pXG5cdFx0KVxuICBcblx0ICBuZXcgU2V0dGluZyhjb250YWluZXJFbCkuc2V0TmFtZShcIkZvbnQgY29sb3Igb2YgdGl0bGVcIikuYWRkVGV4dCgodGMpID0+XG5cdFx0dGNcblx0XHQgIC5zZXRQbGFjZWhvbGRlcihcIkVudGVyIGEgY29sb3JcIilcblx0XHQgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy50aXRsZUZvbnRDb2xvcilcblx0XHQgIC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnRpdGxlRm9udENvbG9yID0gdmFsdWU7XG5cdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHQgIH0pXG5cdCAgKTtcbiAgXG5cdCAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0LnNldE5hbWUoXCJCYWNrZ3JvdW5kIGNvbG9yIG9mIHRpdGxlXCIpXG5cdFx0LmFkZFRleHQoKHRjKSA9PlxuXHRcdCAgdGNcblx0XHRcdC5zZXRQbGFjZWhvbGRlcihcIiMwMDAwMDAyMFwiKVxuXHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnRpdGxlQmFja2dyb3VuZENvbG9yKVxuXHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0ICB0aGlzLnBsdWdpbi5zZXR0aW5ncy50aXRsZUJhY2tncm91bmRDb2xvciA9IHZhbHVlO1xuXHRcdFx0ICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKFwiSGlnaExpZ2h0IENvbG9yXCIpXG5cdFx0LmFkZFRleHQoKHRjKSA9PlxuXHRcdCAgdGNcblx0XHRcdC5zZXRQbGFjZWhvbGRlcihcIiMyZDgyY2MyMFwiKVxuXHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmhpZ2hMaWdodENvbG9yKVxuXHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0ICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5oaWdoTGlnaHRDb2xvciA9IHZhbHVlO1xuXHRcdFx0ICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKFwiU2hvdyBsaW5lIG51bWJlclwiKVxuXHRcdC5hZGRUb2dnbGUoKHRjKSA9PiBcblx0XHR0Yy5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93TGluZU51bWJlcilcblx0XHQub25DaGFuZ2UoYXN5bmModmFsdWUpID0+IHtcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dMaW5lTnVtYmVyID0gdmFsdWU7XG5cdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHR9KVxuXHRcdClcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKFwiU2hvdyBkaXZpZGluZyBsaW5lXCIpXG5cdFx0LmFkZFRvZ2dsZSgodGMpID0+XG5cdFx0dGMuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hvd0RpdmlkaW5nTGluZSlcblx0XHQub25DaGFuZ2UoYXN5bmModmFsdWUpID0+IHtcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dEaXZpZGluZ0xpbmUgPSB2YWx1ZTtcblx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdH0pXG5cdFx0KVxuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0LnNldE5hbWUoXCJTaG93IGxhbmd1YWdlIG5hbWUgaW4gdGhlIHRvcCByaWdodFwiKVxuXHRcdC5hZGRUb2dnbGUoKHRjKSA9PlxuXHRcdHRjLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dMYW5nTmFtZUluVG9wUmlnaHQpXG5cdFx0Lm9uQ2hhbmdlKGFzeW5jKHZhbHVlKSA9PiB7XG5cdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93TGFuZ05hbWVJblRvcFJpZ2h0ID0gdmFsdWU7XG5cdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHR9KVxuXHRcdClcblx0fVxuICB9XG5cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIEJldHRlckNvZGVCbG9ja3MoZWw6IEhUTUxFbGVtZW50LCBjb250ZXh0OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0LCBwbHVnaW46IEJldHRlckNvZGVCbG9jaykge1xuXHRjb25zdCBzZXR0aW5ncyA9IHBsdWdpbi5zZXR0aW5nc1xuXHRjb25zdCBjb2RlRWxtOiBIVE1MRWxlbWVudCA9IGVsLnF1ZXJ5U2VsZWN0b3IoJ3ByZSA+IGNvZGUnKVxuXHQvLyBvbmx5IGNoYW5nZSBwcmU+Y29kZVxuXHRpZiAoIWNvZGVFbG0pIHsgcmV0dXJuIH1cblxuXHRsZXQgbGFuZyA9IERFRkFVTFRfTEFOR1xuXHQvLyByZXR1cm4gd2hlbiBsYW5nIGlzIGluIGV4Y2x1ZGUgbGlzdFxuXHRpZiAocGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVMYW5ncy5zb21lKGVMYW5nTmFtZSA9PiBjb2RlRWxtLmNsYXNzTGlzdC5jb250YWlucyhgbGFuZ3VhZ2UtJHtlTGFuZ05hbWV9YCkpKSB7XG5cdCAgcmV0dXJuXG5cdH1cblx0XG5cdGNvZGVFbG0uY2xhc3NMaXN0LmZvckVhY2goKHZhbHVlLCBrZXksIHBhcmVudCkgPT4ge1xuXHQgIGlmIChMQU5HX1JFRy50ZXN0KHZhbHVlKSkge1xuXHRcdGxhbmcgPSB2YWx1ZS5yZXBsYWNlKCdsYW5ndWFnZS0nLCAnJylcblx0XHRyZXR1cm5cblx0ICB9XG5cdH0pXG5cblx0Ly8gaWYgdGhlIGNvZGUgYmxvY2sgaXMgbm90IGRlc2NyaWJlZCwgcmV0dXJuXG5cdGlmKGxhbmcgPT0gREVGQVVMVF9MQU5HKSB7XG5cdFx0cmV0dXJuXG5cdH1cblxuXHRsZXQgY29kZUJsb2NrID0gY29udGV4dC5nZXRTZWN0aW9uSW5mbyhjb2RlRWxtKVxuXHRsZXQgY29kZUJsb2NrRmlyc3RMaW5lID0gXCJcIlxuXG5cdGlmKGNvZGVCbG9jaykge1xuXHRcdGxldCB2aWV3ID0gYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldylcblx0XHRjb2RlQmxvY2tGaXJzdExpbmUgPSB2aWV3LmVkaXRvci5nZXRMaW5lKGNvZGVCbG9jay5saW5lU3RhcnQpXG5cdH0gZWxzZSB7IFxuXHRcdGxldCBmaWxlID0gYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChjb250ZXh0LnNvdXJjZVBhdGgpXG5cdFx0bGV0IGNhY2hlID0gYXBwLm1ldGFkYXRhQ2FjaGUuZ2V0Q2FjaGUoY29udGV4dC5zb3VyY2VQYXRoKVxuXHRcdGxldCBmaWxlQ29udGVudCA9IGF3YWl0IGFwcC52YXVsdC5jYWNoZWRSZWFkKDxURmlsZT4gZmlsZSlcblx0XHRsZXQgZmlsZUNvbnRlbnRMaW5lcyA9IGZpbGVDb250ZW50LnNwbGl0KC9cXG4vZylcblxuXHRcdGxldCBjb2RlQmxvY2tGaXJzdExpbmVzOiBzdHJpbmdbXSA9IFtdXG5cdFx0bGV0IGNvZGVCbG9ja1NlY3Rpb25zOiBTZWN0aW9uQ2FjaGVbXSA9IFtdXG5cblx0XHRjYWNoZS5zZWN0aW9ucz8uZm9yRWFjaChhc3luYyBlbGVtZW50ID0+IHtcblx0XHRcdGlmKGVsZW1lbnQudHlwZSA9PSBcImNvZGVcIikge1xuXHRcdFx0XHRsZXQgbGluZVN0YXJ0ID0gZWxlbWVudC5wb3NpdGlvbi5zdGFydC5saW5lXG5cdFx0XHRcdGNvZGVCbG9ja0ZpcnN0TGluZSA9IGZpbGVDb250ZW50TGluZXNbbGluZVN0YXJ0XVxuXHRcdFx0XHRjb2RlQmxvY2tTZWN0aW9ucy5wdXNoKGVsZW1lbnQpXG5cdFx0XHRcdGNvZGVCbG9ja0ZpcnN0TGluZXMucHVzaChjb2RlQmxvY2tGaXJzdExpbmUpXG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0ZXhwb3J0UERGKGVsLCBwbHVnaW4sIGNvZGVCbG9ja0ZpcnN0TGluZXMsIGNvZGVCbG9ja1NlY3Rpb25zKVxuXHRcdHJldHVyblxuXHR9XG5cblx0bGV0IHRpdGxlOiBzdHJpbmcgPSBcIlwiXG5cdGxldCBoaWdoTGlnaHRMaW5lczogbnVtYmVyW10gPSBbXVxuXHRpZihjb2RlQmxvY2tGaXJzdExpbmUubWF0Y2godGl0bGVSZWdFeHApICE9IG51bGwpIHtcblx0XHR0aXRsZSA9IGNvZGVCbG9ja0ZpcnN0TGluZS5tYXRjaCh0aXRsZVJlZ0V4cClbMV1cblx0fVxuXHRpZihjb2RlQmxvY2tGaXJzdExpbmUubWF0Y2goaGlnaExpZ2h0TGluZXNSZWdFeHApICE9IG51bGwpIHtcblx0XHRsZXQgaGlnaExpZ2h0TGluZXNJbmZvID0gY29kZUJsb2NrRmlyc3RMaW5lLm1hdGNoKGhpZ2hMaWdodExpbmVzUmVnRXhwKVsxXVxuXHRcdGhpZ2hMaWdodExpbmVzID0gYW5hbHlzZUhpZ2hMaWdodExpbmVzKGhpZ2hMaWdodExpbmVzSW5mbylcblx0fVxuXG5cdGxldCBpc0NvbGxhcHNlID0gZmFsc2U7XG5cdGlmKGZvbGRSZWdFeHAudGVzdChjb2RlQmxvY2tGaXJzdExpbmUpKSB7XG5cdFx0aXNDb2xsYXBzZSA9IHRydWVcblx0fVxuXG5cdGNvbnN0IHByZSA9IGNvZGVFbG0ucGFyZW50RWxlbWVudCAvLyBjb2RlLWJsb2NrLXByZV9faGFzLWxpbmVudW1cblx0Y29uc3QgZGl2ID0gcHJlLnBhcmVudEVsZW1lbnQgLy8gY2xhc3MgY29kZS1ibG9jay13cmFwXG5cblx0LyogY29uc3QgeyBsaW5lU3RhcnQsIGxpbmVFbmQgfSA9IGN0eC5nZXRTZWN0aW9uSW5mbyhlbClcblx0Y29uc3QgbGluZVNpemUgPSBsaW5lRW5kIC0gbGluZVN0YXJ0IC0gMSAqL1xuXHRjb25zdCBjb250ZW50TGlzdDogc3RyaW5nW10gPSBjb2RlRWxtLnRleHRDb250ZW50LnNwbGl0KExJTkVfU1BMSVRfTUFSSylcblx0Y29uc3QgbGluZVNpemUgPSBjb250ZW50TGlzdC5sZW5ndGggLSAxXG5cblx0Y29uc3QgY2JNZXRhID0geyBsYW5nTmFtZTogbGFuZywgbGluZVNpemUsIHByZSwgY29kZTogY29kZUVsbSwgdGl0bGUsIGlzQ29sbGFwc2UsIGRpdiwgY29udGVudExpc3QsIGhpZ2hMaWdodExpbmVzfVxuXG5cdGNvbnN0IHtzaG93TGluZU51bWJlcn0gPSBwbHVnaW4uc2V0dGluZ3NcblxuXHRhZGRDb2RlVGl0bGVXcmFwcGVyKHBsdWdpbiwgcHJlLCBjYk1ldGEpXG5cdC8vYWRkSWNvblRvVGl0bGUocGx1Z2luLCBwcmUsIGNiTWV0YSlcblx0YWRkQ29kZVRpdGxlKHBsdWdpbiwgcHJlLCBjYk1ldGEpO1xuXG5cdC8vIGFkZCBsaW5lIG51bWJlclxuXHRpZiAoc2hvd0xpbmVOdW1iZXIpIHtcblx0XHRhZGRMaW5lTnVtYmVyKHBsdWdpbiwgY2JNZXRhKVxuXHR9XG5cblx0YWRkTGluZUhpZ2hMaWdodChwbHVnaW4sIHByZSwgY2JNZXRhKVxuXG5cdHJlc2l6ZU51bVdyYXBBbmRITFdyYXAoZWwsY29udGV4dCkgLy8gXHU4QzAzXHU3NTI4XHU0RTAwXHU2QjIxXHU0RUU1XHU4OUUzXHU1MUIzXHU2N0QwXHU0RTlCXHU2NUY2XHU1MDE5XHU2MjUzXHU1RjAwXHU2NTg3XHU0RUY2XHU4ODRDXHU5QUQ4XHU2NzJBXHU4OEFCXHU5MUNEXHU4QkJFXHU5QUQ4XHU1RUE2XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQgKHRhZ05hbWU6IHN0cmluZywgZGVmYXVsdENsYXNzTmFtZT86IHN0cmluZykge1xuXHRjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKVxuXHRpZiAoZGVmYXVsdENsYXNzTmFtZSkge1xuXHQgIGVsZW1lbnQuY2xhc3NOYW1lID0gZGVmYXVsdENsYXNzTmFtZVxuXHR9XG5cdHJldHVybiBlbGVtZW50XG59XG5cbmZ1bmN0aW9uIGFkZENvZGVUaXRsZVdyYXBwZXIocGx1Z2luOiBCZXR0ZXJDb2RlQmxvY2ssIHByZUVsbTogSFRNTEVsZW1lbnQsIGNiTWV0YTogQ29kZUJsb2NrTWV0YSkge1xuXHRwcmVFbG0uc3R5bGUuc2V0UHJvcGVydHkoXCJwb3NpdGlvblwiLCBcInJlbGF0aXZlXCIsIFwiaW1wb3J0YW50XCIpO1xuXHRwcmVFbG0uc3R5bGUuc2V0UHJvcGVydHkoXCJwYWRkaW5nLXRvcFwiLCBDQl9QQURESU5HX1RPUCwgXCJpbXBvcnRhbnRcIik7XG5cblx0bGV0IHdyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwicHJlXCIpXG5cdGlmKGNiTWV0YS5pc0NvbGxhcHNlKSB7XG5cdFx0d3JhcHBlci5zZXRBdHRyaWJ1dGUoXCJjbG9zZWRcIixcIlwiKVxuXHR9XG5cdHdyYXBwZXIuY2xhc3NOYW1lID0gXCJvYnNpZGlhbi1lbWJlZGRlZC1jb2RlLXRpdGxlX19jb2RlLWJsb2NrLXRpdGxlXCJcblxuXHR3cmFwcGVyLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHBsdWdpbi5zZXR0aW5ncy50aXRsZUJhY2tncm91bmRDb2xvciB8fCBcIiMwMDAwMDAyMFwiO1xuXG5cdGxldCBjb2xsYXBzZXIgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIsXCJjb2xsYXBzZXJcIilcblx0bGV0IGhhbmRsZSA9IGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgXCJoYW5kbGVcIilcblx0Y29sbGFwc2VyLmFwcGVuZENoaWxkKGhhbmRsZSlcblx0d3JhcHBlci5hcHBlbmRDaGlsZChjb2xsYXBzZXIpXG5cblx0d3JhcHBlci5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsZnVuY3Rpb24odGhpczogYW55KSB7XG5cdFx0aWYod3JhcHBlci5oYXNBdHRyaWJ1dGUoXCJjbG9zZWRcIikpe1xuXHRcdFx0d3JhcHBlci5yZW1vdmVBdHRyaWJ1dGUoXCJjbG9zZWRcIilcblx0XHR9IGVsc2Uge1xuXHRcdFx0d3JhcHBlci5zZXRBdHRyaWJ1dGUoXCJjbG9zZWRcIiwnJylcblx0XHR9XG5cdH0pXG5cblx0cHJlRWxtLmFwcGVuZENoaWxkKHdyYXBwZXIpXG59XG5cbmZ1bmN0aW9uIGFkZENvZGVUaXRsZSAocGx1Z2luOiBCZXR0ZXJDb2RlQmxvY2ssIHByZUVsbTogSFRNTEVsZW1lbnQsIGNiTWV0YTogQ29kZUJsb2NrTWV0YSkge1xuXHRsZXQgd3JhcHBlciA9IHByZUVsbS5xdWVyeVNlbGVjdG9yKFwiLm9ic2lkaWFuLWVtYmVkZGVkLWNvZGUtdGl0bGVfX2NvZGUtYmxvY2stdGl0bGVcIilcblxuXHRsZXQgdGl0bGVFbG0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpXG5cdHRpdGxlRWxtLmNsYXNzTmFtZSA9IFwidGl0bGVcIlxuXG5cdHRpdGxlRWxtLmFwcGVuZFRleHQoY2JNZXRhLnRpdGxlKVxuXHR3cmFwcGVyLmFwcGVuZENoaWxkKHRpdGxlRWxtKVxuXG5cdGlmKHBsdWdpbi5zZXR0aW5ncy50aXRsZUZvbnRDb2xvcikge1xuXHRcdHRpdGxlRWxtLnN0eWxlLnNldFByb3BlcnR5KFwiY29sb3JcIiwgcGx1Z2luLnNldHRpbmdzLnRpdGxlRm9udENvbG9yLCBcImltcG9ydGFudFwiKVxuXHR9XG5cdFxuXHRpZihwbHVnaW4uc2V0dGluZ3Muc2hvd0xhbmdOYW1lSW5Ub3BSaWdodCkge1xuXHRcdGxldCBsYW5nTmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7IC8vIFx1NTcyOFx1NTNGM1x1NEZBN1x1NkRGQlx1NTJBMFx1NEVFM1x1NzgwMVx1N0M3Qlx1NTc4QlxuXHRcdGxldCBsYW5nTmFtZVN0cmluZyA9IGNiTWV0YS5sYW5nTmFtZVxuXHRcdGxhbmdOYW1lU3RyaW5nID0gbGFuZ05hbWVTdHJpbmdbMF0udG9VcHBlckNhc2UoKSArIGxhbmdOYW1lU3RyaW5nLnNsaWNlKDEpIC8vIFx1OTk5Nlx1NUI1N1x1NkJDRFx1NTkyN1x1NTE5OVxuXHRcdGxhbmdOYW1lLmFwcGVuZFRleHQobGFuZ05hbWVTdHJpbmcpO1xuXHRcdGxhbmdOYW1lLmNsYXNzTmFtZSA9IFwibGFuZ05hbWVcIjtcblx0XHR3cmFwcGVyLmFwcGVuZENoaWxkKGxhbmdOYW1lKTtcblx0fVxuXG5cdHByZUVsbS5wcmVwZW5kKHdyYXBwZXIpO1xuXG59XG5cbmZ1bmN0aW9uIGFkZExpbmVOdW1iZXIgKHBsdWdpbjogQmV0dGVyQ29kZUJsb2NrLCBjYk1ldGE6IENvZGVCbG9ja01ldGEpIHtcblx0Y29uc3QgeyBsaW5lU2l6ZSwgcHJlLCBkaXYgfSA9IGNiTWV0YVxuXHQvLyBsZXQgZGl2IHBvc2l0aW9uOiByZWxhdGl2ZTtcblx0ZGl2LmNsYXNzTGlzdC5hZGQoJ2NvZGUtYmxvY2std3JhcCcpXG5cblx0Ly8gY29uc3QgeyBmb250U2l6ZSwgbGluZUhlaWdodCB9ID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoY2JNZXRhLmNvZGUpXG5cdGNvbnN0IGxpbmVOdW1iZXIgPSBjcmVhdGVFbGVtZW50KCdzcGFuJywgJ2NvZGUtYmxvY2stbGluZW51bS13cmFwJylcblx0bGluZU51bWJlci5zdHlsZS50b3AgPSBDQl9QQURESU5HX1RPUDtcblx0QXJyYXkuZnJvbSh7IGxlbmd0aDogbGluZVNpemUgfSwgKHYsIGspID0+IGspLmZvckVhY2goaSA9PiB7XG5cdCAgY29uc3Qgc2luZ2xlTGluZSA9IGNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCAnY29kZS1ibG9jay1saW5lbnVtJylcblx0ICAvLyBzaW5nbGVMaW5lLnN0eWxlLmZvbnRTaXplID0gZm9udFNpemVcblx0ICAvLyBzaW5nbGVMaW5lLnN0eWxlLmxpbmVIZWlnaHQgPSBsaW5lSGVpZ2h0XG5cdCAgbGluZU51bWJlci5hcHBlbmRDaGlsZChzaW5nbGVMaW5lKVxuXHR9KVxuXHRcblx0aWYocGx1Z2luLnNldHRpbmdzLnNob3dEaXZpZGluZ0xpbmUpIHtcblx0XHRsaW5lTnVtYmVyLnN0eWxlLmJvcmRlclJpZ2h0ID0gXCIxcHggY3VycmVudENvbG9yIHNvbGlkXCJcblx0fVxuXG5cdHByZS5hcHBlbmRDaGlsZChsaW5lTnVtYmVyKVxuXHRwcmUuY2xhc3NMaXN0LmFkZCgnY29kZS1ibG9jay1wcmVfX2hhcy1saW5lbnVtJylcbn1cblxuZnVuY3Rpb24gYWRkTGluZUhpZ2hMaWdodChwbHVnaW46IEJldHRlckNvZGVCbG9jaywgcHJlRWxtOiBIVE1MRWxlbWVudCwgY2JNZXRhOiBDb2RlQmxvY2tNZXRhKSB7XG5cdGlmKGNiTWV0YS5oaWdoTGlnaHRMaW5lcy5sZW5ndGggPT0gMCkgcmV0dXJuXG5cblx0bGV0IGhpZ2hMaWdodFdyYXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwicHJlXCIpXG5cdGhpZ2hMaWdodFdyYXAuY2xhc3NOYW1lID0gXCJjb2RlLWJsb2NrLWhpZ2hsaWdodC13cmFwXCJcblx0Zm9yKGxldCBpID0gMDsgaSA8IGNiTWV0YS5saW5lU2l6ZTsgaSsrKSB7XG5cdFx0Y29uc3Qgc2luZ2xlTGluZSA9IGNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIsICdjb2RlLWJsb2NrLWhpZ2hsaWdodCcpXG5cdFx0aWYoY2JNZXRhLmhpZ2hMaWdodExpbmVzLmNvbnRhaW5zKGkrMSkpIHtcblx0XHRcdHNpbmdsZUxpbmUuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gcGx1Z2luLnNldHRpbmdzLmhpZ2hMaWdodENvbG9yIHx8IFwiIzJkODJjYzIwXCJcblx0XHR9XG5cdFx0aGlnaExpZ2h0V3JhcC5hcHBlbmRDaGlsZChzaW5nbGVMaW5lKVxuXHR9XG5cblx0cHJlRWxtLmFwcGVuZENoaWxkKGhpZ2hMaWdodFdyYXApXG59XG5cbmZ1bmN0aW9uIGFuYWx5c2VIaWdoTGlnaHRMaW5lcyhzdHI6IHN0cmluZyk6IG51bWJlcltdIHtcblx0c3RyID0gc3RyLnJlcGxhY2UoL1xccyovZywgXCJcIikgLy8gXHU1M0JCXHU5NjY0XHU1QjU3XHU3QjI2XHU0RTMyXHU0RTJEXHU2MjQwXHU2NzA5XHU3QTdBXHU2ODNDXG5cdGNvbnN0IHJlc3VsdDogbnVtYmVyW10gPSBbXVxuXG5cdGxldCBzdHJzID0gc3RyLnNwbGl0KFwiLFwiKVxuXHRzdHJzLmZvckVhY2goaXQgPT4ge1xuXHRcdGlmKC9cXHcrLVxcdysvLnRlc3QoaXQpKSB7IC8vIFx1NTk4Mlx1Njc5Q1x1NTMzOVx1OTE0RCAxLTMgXHU4RkQ5XHU2ODM3XHU3Njg0XHU2ODNDXHU1RjBGXHVGRjBDXHU0RjlEXHU2QjIxXHU2REZCXHU1MkEwXHU2NTcwXHU1QjU3XG5cdFx0XHRsZXQgbGVmdCA9IE51bWJlcihpdC5zcGxpdCgnLScpWzBdKVxuXHRcdFx0bGV0IHJpZ2h0ID0gTnVtYmVyKGl0LnNwbGl0KCctJylbMV0pXG5cdFx0XHRmb3IobGV0IGkgPSBsZWZ0OyBpIDw9IHJpZ2h0OyBpKyspIHtcblx0XHRcdFx0cmVzdWx0LnB1c2goaSlcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0cmVzdWx0LnB1c2goTnVtYmVyKGl0KSlcblx0XHR9XG5cdH0pXG5cblx0cmV0dXJuIHJlc3VsdFxufVxuXG5mdW5jdGlvbiBhZGRJY29uVG9UaXRsZShwbHVnaW46IEJldHRlckNvZGVCbG9jaywgcHJlRWxtOiBIVE1MRWxlbWVudCwgY2JNZXRhOiBDb2RlQmxvY2tNZXRhKSB7XG5cdGxldCB0aXRsZSA9IHByZUVsbS5xdWVyeVNlbGVjdG9yQWxsKFwiLm9ic2lkaWFuLWVtYmVkZGVkLWNvZGUtdGl0bGVfX2NvZGUtYmxvY2stdGl0bGVcIilcblxuXHR0aXRsZS5mb3JFYWNoKGl0ID0+IHtcblx0XHRsZXQgaWNvbldyYXAgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIsXCJpY29uLXdyYXBcIilcblx0XHRsZXQgaWNvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIilcblx0XHRpY29uLnNyYyA9IFwiXCJcblx0XHRpY29uV3JhcC5hcHBlbmRDaGlsZChpY29uKVxuXHRcdGl0LmFwcGVuZENoaWxkKGljb25XcmFwKVxuXHR9KVxuXHRcbn1cblxuLy8gXHU1NzI4XHU4MUVBXHU1MkE4XHU2MzYyXHU4ODRDXHU2NUY2XHU1QkY5XHU2NTcwXHU1QjU3XHU1NDhDXHU5QUQ4XHU0RUFFXHU4ODRDXHU5MUNEXHU2NUIwXHU4QkJFXHU3RjZFXHU5QUQ4XHU1RUE2XG4vLyBUaGVzZSBjb2RlcyByZWZlciB0byB0aGUgaHR0cHM6Ly9naXRodWIuY29tL2xpanl6ZS9vYnNpZGlhbi1hZHZhbmNlZC1jb2RlYmxvY2tcbmZ1bmN0aW9uIHJlc2l6ZU51bVdyYXBBbmRITFdyYXAoZWw6IEhUTUxFbGVtZW50LCBjb250ZXh0OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0KSB7XG5cdHNldFRpbWVvdXQoYXN5bmMgZnVuY3Rpb24oKXsgLy8gXHU1RUY2XHU2NUY2MTAwXHU2QkVCXHU3OUQyXHU0RUU1XHU4OUUzXHU1MUIzXHU2N0QwXHU0RTlCXHU2NUY2XHU1MDE5XHU2MjUzXHU1RjAwXHU2NTg3XHU0RUY2XHU4ODRDXHU5QUQ4XHU2NzJBXHU4OEFCXHU5MUNEXHU4QkJFXHU5QUQ4XHU1RUE2XG5cdFx0Ly8gY29uc29sZS5sb2coJ29uIGVzaXplJylcblx0XHRsZXQgY29kZUJsb2NrRWwgOiBIVE1MRWxlbWVudCA9IGVsLnF1ZXJ5U2VsZWN0b3IoJ3ByZSA+IGNvZGUnKVxuXHRcdGlmKCFjb2RlQmxvY2tFbCkgcmV0dXJuXG5cblx0XHRsZXQgbnVtV3JhcCA9IGVsLnF1ZXJ5U2VsZWN0b3IoJy5jb2RlLWJsb2NrLWxpbmVudW0td3JhcCcpXG5cdFx0bGV0IGhpZ2hXcmFwID0gZWwucXVlcnlTZWxlY3RvcignLmNvZGUtYmxvY2staGlnaGxpZ2h0LXdyYXAnKVxuXG5cdFx0bGV0IGNvZGVCbG9ja0luZm8gPSBjb250ZXh0LmdldFNlY3Rpb25JbmZvKGNvZGVCbG9ja0VsKVxuXHRcdC8vIGxldCB2aWV3ID0gYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldylcblx0XHQvLyBsZXQgY29kZUJsb2NrTGluZU51bSA9IGNvZGVCbG9ja0luZm8ubGluZUVuZCAtIGNvZGVCbG9ja0luZm8ubGluZVN0YXJ0IC0gMSAvLyBcdTk2NjRcdTUzQkJcdTk5OTZcdTVDM0VcdTRFMjRcdTg4NENcblx0XHRsZXQgdmlld1xuXHRcdGxldCBjb2RlQmxvY2tMaW5lTnVtXG5cblx0XHRsZXQgbGluZVN0YXJ0ID0gMFxuXHRcdGxldCBsaW5lRW5kID0gMFxuXHRcdGlmKGNvZGVCbG9ja0luZm8pIHtcblx0XHRcdHZpZXcgPSBhcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KVxuXHRcdFx0Y29kZUJsb2NrTGluZU51bSA9IGNvZGVCbG9ja0luZm8ubGluZUVuZCAtIGNvZGVCbG9ja0luZm8ubGluZVN0YXJ0IC0gMSAvLyBcdTk2NjRcdTUzQkJcdTk5OTZcdTVDM0VcdTRFMjRcdTg4NENcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuXG5cdFx0XHQvLyBsZXQgZmlsZSA9IGFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoY29udGV4dC5zb3VyY2VQYXRoKVxuXHRcdFx0Ly8gbGV0IGNhY2hlID0gYXBwLm1ldGFkYXRhQ2FjaGUuZ2V0Q2FjaGUoY29udGV4dC5zb3VyY2VQYXRoKVxuXHRcblx0XHRcdC8vIGNhY2hlLnNlY3Rpb25zPy5mb3JFYWNoKGFzeW5jIGVsZW1lbnQgPT4ge1xuXHRcdFx0Ly8gXHRpZihlbGVtZW50LnR5cGUgPT0gXCJjb2RlXCIpIHtcblx0XHRcdC8vIFx0XHRsaW5lU3RhcnQgPSBlbGVtZW50LnBvc2l0aW9uLnN0YXJ0LmxpbmVcblx0XHRcdC8vIFx0XHRsaW5lRW5kID0gZWxlbWVudC5wb3NpdGlvbi5lbmQubGluZVxuXHRcdFx0Ly8gXHRcdGNvZGVCbG9ja0xpbmVOdW0gPSBsaW5lRW5kIC0gbGluZVN0YXJ0IC0gMVxuXHRcdFx0Ly8gXHRcdHJldHVyblxuXHRcdFx0Ly8gXHR9XG5cdFx0XHQvLyB9KTtcblx0XHRcdC8vIGxldCBmaWxlID0gYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChjb250ZXh0LnNvdXJjZVBhdGgpXG5cdFx0XHQvLyBsZXQgY2FjaGUgPSBhcHAubWV0YWRhdGFDYWNoZS5nZXRDYWNoZShjb250ZXh0LnNvdXJjZVBhdGgpXG5cdFx0XHQvLyBsZXQgZmlsZUNvbnRlbnQgPSBhd2FpdCBhcHAudmF1bHQuY2FjaGVkUmVhZCg8VEZpbGU+IGZpbGUpXG5cdFx0XHQvLyBsZXQgZmlsZUNvbnRlbnRMaW5lcyA9IGZpbGVDb250ZW50LnNwbGl0KC9cXG4vZylcblx0XHR9XG5cblx0XHRsZXQgc3BhbiA9IGNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpXG5cblx0XHRmb3IobGV0IGkgPSAwOyBpIDwgY29kZUJsb2NrTGluZU51bTsgaSsrKSB7XG5cdFx0XHRsZXQgb25lTGluZVRleHRcblx0XHRcdGlmKHZpZXcpe1xuXHRcdFx0XHRvbmVMaW5lVGV4dCA9IHZpZXcuZWRpdG9yLmdldExpbmUoY29kZUJsb2NrSW5mby5saW5lU3RhcnQgKyBpICsgMSlcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIG9uZUxpbmVUZXh0ID0gZmlsZUNvbnRlbnRMaW5lc1tsaW5lU3RhcnQgKyAxICsgaV1cblx0XHRcdFx0Ly8gbGV0IGZpbGUgPSBhcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGNvbnRleHQuc291cmNlUGF0aClcblx0XHRcdFx0Ly8gbGV0IGNhY2hlID0gYXBwLm1ldGFkYXRhQ2FjaGUuZ2V0Q2FjaGUoY29udGV4dC5zb3VyY2VQYXRoKVxuXHRcdFx0XHQvLyBsZXQgZmlsZUNvbnRlbnQgPSBhd2FpdCBhcHAudmF1bHQuY2FjaGVkUmVhZCg8VEZpbGU+IGZpbGUpXG5cdFx0XHRcdC8vIGxldCBmaWxlQ29udGVudExpbmVzID0gZmlsZUNvbnRlbnQuc3BsaXQoL1xcbi9nKVxuXHRcdFx0XHQvLyBvbmVMaW5lVGV4dCA9IGZpbGVDb250ZW50TGluZXNbY2FjaGUuc2VjdGlvbnNdXG5cdFx0XHR9XG5cdFx0XHRzcGFuLmlubmVySFRNTCA9IG9uZUxpbmVUZXh0IHx8IFwiMFwiXG5cblx0XHRcdGNvZGVCbG9ja0VsLmFwcGVuZENoaWxkKHNwYW4pXG5cdFx0XHRzcGFuLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snXG5cblx0XHRcdGxldCBsaW5lSGVpZ2h0ID0gc3Bhbi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQgKyAncHgnIC8vIFx1NkQ0Qlx1OTFDRlx1NjcyQ1x1ODg0Q1x1NjU4N1x1NUI1N1x1NzY4NFx1OUFEOFx1NUVBNlxuXG5cdFx0XHQvLyBjb25zb2xlLmxvZyhsaW5lSGVpZ2h0ICsgJyAgICAnICsgc3Bhbi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCk7XG5cdFx0XHRcblx0XHRcdGxldCBudW1PbmVMaW5lID0gbnVtV3JhcD8gbnVtV3JhcC5jaGlsZE5vZGVzW2ldIGFzIEhUTUxFbGVtZW50IDogbnVsbFxuXHRcdFx0bGV0IGhsT25lTGluZSA9IGhpZ2hXcmFwPyBoaWdoV3JhcC5jaGlsZE5vZGVzW2ldIGFzIEhUTUxFbGVtZW50IDogbnVsbFxuXG5cdFx0XHRpZihudW1PbmVMaW5lKSBudW1PbmVMaW5lLnN0eWxlLmhlaWdodCA9IGxpbmVIZWlnaHQ7XG5cdFx0XHRpZihobE9uZUxpbmUpIGhsT25lTGluZS5zdHlsZS5oZWlnaHQgPSBsaW5lSGVpZ2h0O1xuXG5cdFx0XHRzcGFuLnJlbW92ZSgpIC8vIFx1NkQ0Qlx1OTFDRlx1NUI4Q1x1NTQwRVx1NTIyMFx1NjM4OVxuXHRcdH1cblx0fSwgMTAwKVxufVxuXG5mdW5jdGlvbiBleHBvcnRQREYoZWw6IEhUTUxFbGVtZW50LCBwbHVnaW46IEJldHRlckNvZGVCbG9jaywgY29kZUJsb2NrRmlyc3RMaW5lczogc3RyaW5nW10sIGNvZGVCbG9ja1NlY3Rpb25zOiBTZWN0aW9uQ2FjaGVbXSkge1xuXHRsZXQgY29kZUJsb2NrcyA9IGVsLnF1ZXJ5U2VsZWN0b3JBbGwoJ3ByZSA+IGNvZGUnKVxuXHRjb2RlQmxvY2tzLmZvckVhY2goKGNvZGVFbG0sIGtleSkgPT4ge1xuXHRcdGxldCBsYW5nTmFtZSA9IFwiXCIsIHRpdGxlID0gXCJcIiwgaGlnaExpZ2h0TGluZXM6IG51bWJlcltdID0gW11cblx0XHRjb2RlRWxtLmNsYXNzTGlzdC5mb3JFYWNoKHZhbHVlID0+IHtcblx0XHRcdGlmKExBTkdfUkVHLnRlc3QodmFsdWUpKSB7XG5cdFx0XHRcdGxhbmdOYW1lID0gdmFsdWUucmVwbGFjZSgnbGFuZ3VhZ2UtJywgJycpXG5cdFx0XHRcdHJldHVyblxuXHRcdFx0fVxuXHRcdH0pXG5cblx0XHRpZihjb2RlQmxvY2tGaXJzdExpbmVzW2tleV0ubWF0Y2godGl0bGVSZWdFeHApICE9IG51bGwpIHtcblx0XHRcdHRpdGxlID0gY29kZUJsb2NrRmlyc3RMaW5lc1trZXldLm1hdGNoKHRpdGxlUmVnRXhwKVsxXVxuXHRcdH1cblx0XHRpZihjb2RlQmxvY2tGaXJzdExpbmVzW2tleV0ubWF0Y2goaGlnaExpZ2h0TGluZXNSZWdFeHApICE9IG51bGwpIHtcblx0XHRcdGxldCBoaWdoTGlnaHRMaW5lc0luZm8gPSBjb2RlQmxvY2tGaXJzdExpbmVzW2tleV0ubWF0Y2goaGlnaExpZ2h0TGluZXNSZWdFeHApWzFdXG5cdFx0XHRoaWdoTGlnaHRMaW5lcyA9IGFuYWx5c2VIaWdoTGlnaHRMaW5lcyhoaWdoTGlnaHRMaW5lc0luZm8pXG5cdFx0fVxuXG5cdFx0bGV0IGxpbmVTaXplID0gY29kZUJsb2NrU2VjdGlvbnNba2V5XS5wb3NpdGlvbi5lbmQubGluZSAtIGNvZGVCbG9ja1NlY3Rpb25zW2tleV0ucG9zaXRpb24uc3RhcnQubGluZSAtIDFcblxuXHRcdGxldCBjYk1ldGE6IENvZGVCbG9ja01ldGEgPSB7XG5cdFx0XHRsYW5nTmFtZTogbGFuZ05hbWUsXG5cdFx0XHRsaW5lU2l6ZTogbGluZVNpemUsXG5cdFx0XHRwcmU6IGNvZGVFbG0ucGFyZW50RWxlbWVudCxcblx0XHRcdGNvZGU6IGNvZGVFbG0gYXMgSFRNTEVsZW1lbnQsXG5cdFx0XHR0aXRsZTogdGl0bGUsXG5cdFx0XHRpc0NvbGxhcHNlOiBmYWxzZSxcblx0XHRcdGRpdjogY29kZUVsbS5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQsXG5cdFx0XHRjb250ZW50TGlzdDogW10sXG5cdFx0XHRoaWdoTGlnaHRMaW5lczogaGlnaExpZ2h0TGluZXNcblx0XHR9XG5cdFx0YWRkQ29kZVRpdGxlV3JhcHBlcihwbHVnaW4sIGNvZGVFbG0ucGFyZW50RWxlbWVudCwgY2JNZXRhKSAvLyBcdTVCRkNcdTUxRkFcdTUzRDZcdTZEODhcdTRFRTNcdTc4MDFcdTU3NTdcdTYyOThcdTUzRTBcblx0XHRhZGRDb2RlVGl0bGUocGx1Z2luLCBjYk1ldGEucHJlLCBjYk1ldGEpXG5cdFx0aWYocGx1Z2luLnNldHRpbmdzLnNob3dMaW5lTnVtYmVyKSB7XG5cdFx0XHRhZGRMaW5lTnVtYmVyKHBsdWdpbiwgY2JNZXRhKVxuXHRcdH1cblx0XHRhZGRMaW5lSGlnaExpZ2h0KHBsdWdpbiwgY2JNZXRhLnByZSwgY2JNZXRhKVxuXHR9KVxufSJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQSxzQkFBdUw7QUFJdkwsSUFBTSxlQUFlO0FBQ3JCLElBQU0sV0FBVztBQUNqQixJQUFNLGtCQUFrQjtBQUV4QixJQUFNLGNBQWM7QUFDcEIsSUFBTSx1QkFBdUI7QUFDN0IsSUFBTSxhQUFhO0FBRW5CLElBQU0saUJBQWlCO0FBZXZCLElBQU0sbUJBQTZCO0FBQUEsRUFDbEMsMkJBQTJCO0FBQUEsRUFDM0Isc0JBQXNCO0FBQUEsRUFDdEIsZ0JBQWdCO0FBQUEsRUFDaEIsZ0JBQWdCO0FBQUEsRUFFaEIsY0FBYztBQUFBLEVBRWQsZ0JBQWdCO0FBQUEsRUFDaEIsa0JBQWtCO0FBQUEsRUFDbEIsd0JBQXdCO0FBQUE7QUE4QnpCLG9DQUE2Qyx1QkFBTztBQUFBLEVBRzdDLFNBQVM7QUFBQTtBQUNkLGNBQVEsSUFBSTtBQUNaLFlBQU0sS0FBSztBQUNYLFdBQUssY0FBYyxJQUFJLG1CQUFtQixLQUFLLEtBQUs7QUFDcEQsV0FBSyw4QkFBOEIsQ0FBQyxJQUFJLFFBQVE7QUFDL0MseUJBQWlCLElBQUksS0FBSztBQUMxQixZQUFJLFVBQVUsR0FBRyxVQUFVLE1BQU07QUFDaEMsaUNBQXVCLElBQUk7QUFBQTtBQUFBO0FB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 diff --git a/main.ts b/main.ts index 2efa67e..d4349f2 100644 --- a/main.ts +++ b/main.ts @@ -1,11 +1,16 @@ import { linkSync } from 'fs'; -import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting, MarkdownPostProcessorContext, Menu, SettingTab, TAbstractFile, TFile } from 'obsidian'; +import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting, MarkdownPostProcessorContext, Menu, SettingTab, TAbstractFile, TFile, SectionCache, Vault } from 'obsidian'; +import { json } from 'stream/consumers'; const DEFAULT_LANG_ATTR = 'language-text' const DEFAULT_LANG = '' const LANG_REG = /^language-/ const LINE_SPLIT_MARK = '\n' +const titleRegExp = /TI:"([^"]*)"/i +const highLightLinesRegExp = /HL:"([^"]*)"/i +const foldRegExp = /"FOLD"/i + const CB_PADDING_TOP = "35px" // 代码块上边距 interface Settings { @@ -70,7 +75,11 @@ export default class BetterCodeBlock extends Plugin { this.addSettingTab(new BetterCodeBlockTab(this.app, this)); this.registerMarkdownPostProcessor((el, ctx) => { BetterCodeBlocks(el, ctx, this) + app.workspace.on('resize', () => { + resizeNumWrapAndHLWrap(el, ctx) + }) }) + } onunload () { @@ -176,14 +185,12 @@ class BetterCodeBlockTab extends PluginSettingTab { } } -export function BetterCodeBlocks(el: HTMLElement, context: MarkdownPostProcessorContext, plugin: BetterCodeBlock) { + +export async function BetterCodeBlocks(el: HTMLElement, context: MarkdownPostProcessorContext, plugin: BetterCodeBlock) { const settings = plugin.settings - const codeElm: HTMLElement = el.querySelector('pre > code') // only change pre>code - if (!codeElm) { - return - } + if (!codeElm) { return } let lang = DEFAULT_LANG // return when lang is in exclude list @@ -203,13 +210,32 @@ export function BetterCodeBlocks(el: HTMLElement, context: MarkdownPostProcessor return } - let titleRegExp = /TI:"([^"]*)"/i - let highLightLinesRegExp = /HL:"([^"]*)"/i - let foldRegExp = /"FOLD"/i - let codeBlock = context.getSectionInfo(codeElm) - let view = app.workspace.getActiveViewOfType(MarkdownView) - let codeBlockFirstLine = view.editor.getLine(codeBlock.lineStart) + let codeBlockFirstLine = "" + + if(codeBlock) { + let view = app.workspace.getActiveViewOfType(MarkdownView) + codeBlockFirstLine = view.editor.getLine(codeBlock.lineStart) + } else { + let file = app.vault.getAbstractFileByPath(context.sourcePath) + let cache = app.metadataCache.getCache(context.sourcePath) + let fileContent = await app.vault.cachedRead( file) + let fileContentLines = fileContent.split(/\n/g) + + let codeBlockFirstLines: string[] = [] + let codeBlockSections: SectionCache[] = [] + + cache.sections?.forEach(async element => { + if(element.type == "code") { + let lineStart = element.position.start.line + codeBlockFirstLine = fileContentLines[lineStart] + codeBlockSections.push(element) + codeBlockFirstLines.push(codeBlockFirstLine) + } + }); + exportPDF(el, plugin, codeBlockFirstLines, codeBlockSections) + return + } let title: string = "" let highLightLines: number[] = [] @@ -234,10 +260,12 @@ export function BetterCodeBlocks(el: HTMLElement, context: MarkdownPostProcessor const contentList: string[] = codeElm.textContent.split(LINE_SPLIT_MARK) const lineSize = contentList.length - 1 - const cbMeta: CodeBlockMeta = { langName: lang, lineSize, pre, code: codeElm, title, isCollapse, div, contentList, highLightLines} + const cbMeta = { langName: lang, lineSize, pre, code: codeElm, title, isCollapse, div, contentList, highLightLines} const {showLineNumber} = plugin.settings + addCodeTitleWrapper(plugin, pre, cbMeta) + //addIconToTitle(plugin, pre, cbMeta) addCodeTitle(plugin, pre, cbMeta); // add line number @@ -246,6 +274,8 @@ export function BetterCodeBlocks(el: HTMLElement, context: MarkdownPostProcessor } addLineHighLight(plugin, pre, cbMeta) + + resizeNumWrapAndHLWrap(el,context) // 调用一次以解决某些时候打开文件行高未被重设高度 } function createElement (tagName: string, defaultClassName?: string) { @@ -256,10 +286,65 @@ function createElement (tagName: string, defaultClassName?: string) { return element } +function addCodeTitleWrapper(plugin: BetterCodeBlock, preElm: HTMLElement, cbMeta: CodeBlockMeta) { + preElm.style.setProperty("position", "relative", "important"); + preElm.style.setProperty("padding-top", CB_PADDING_TOP, "important"); + + let wrapper = document.createElement("pre") + if(cbMeta.isCollapse) { + wrapper.setAttribute("closed","") + } + wrapper.className = "obsidian-embedded-code-title__code-block-title" + + wrapper.style.backgroundColor = plugin.settings.titleBackgroundColor || "#00000020"; + + let collapser = createElement("div","collapser") + let handle = createElement("div", "handle") + collapser.appendChild(handle) + wrapper.appendChild(collapser) + + wrapper.addEventListener('click',function(this: any) { + if(wrapper.hasAttribute("closed")){ + wrapper.removeAttribute("closed") + } else { + wrapper.setAttribute("closed",'') + } + }) + + preElm.appendChild(wrapper) +} + +function addCodeTitle (plugin: BetterCodeBlock, preElm: HTMLElement, cbMeta: CodeBlockMeta) { + let wrapper = preElm.querySelector(".obsidian-embedded-code-title__code-block-title") + + let titleElm = document.createElement("div") + titleElm.className = "title" + + titleElm.appendText(cbMeta.title) + wrapper.appendChild(titleElm) + + if(plugin.settings.titleFontColor) { + titleElm.style.setProperty("color", plugin.settings.titleFontColor, "important") + } + + if(plugin.settings.showLangNameInTopRight) { + let langName = document.createElement("div"); // 在右侧添加代码类型 + let langNameString = cbMeta.langName + langNameString = langNameString[0].toUpperCase() + langNameString.slice(1) // 首字母大写 + langName.appendText(langNameString); + langName.className = "langName"; + wrapper.appendChild(langName); + } + + preElm.prepend(wrapper); + +} + function addLineNumber (plugin: BetterCodeBlock, cbMeta: CodeBlockMeta) { const { lineSize, pre, div } = cbMeta // let div position: relative; div.classList.add('code-block-wrap') + // const { fontSize, lineHeight } = window.getComputedStyle(cbMeta.code) const lineNumber = createElement('span', 'code-block-linenum-wrap') lineNumber.style.top = CB_PADDING_TOP; @@ -278,53 +363,7 @@ function addLineNumber (plugin: BetterCodeBlock, cbMeta: CodeBlockMeta) { pre.classList.add('code-block-pre__has-linenum') } - -function addCodeTitle (plugin: BetterCodeBlock, wrapperElm: HTMLElement, cbMeta: CodeBlockMeta) { - wrapperElm.style.setProperty("position", "relative", "important"); - wrapperElm.style.setProperty("padding-top", CB_PADDING_TOP, "important"); - - wrapperElm - .querySelectorAll(".obsidian-embedded-code-title__code-block-title") - .forEach((x) => x.remove()); // 防抖动 - - let d = document.createElement("pre"); - // d.appendText(cbMeta.title); - d.appendText(cbMeta.title) - - if(cbMeta.isCollapse) { - d.setAttribute("closed","") - } - d.className = "obsidian-embedded-code-title__code-block-title"; - - if(plugin.settings.titleFontColor) { - d.style.setProperty("color", plugin.settings.titleFontColor, "important") - } - d.style.backgroundColor = plugin.settings.titleBackgroundColor || "#00000020"; - - let collapser = createElement("div","collapser") - let handle = createElement("div", "handle") - collapser.appendChild(handle) - d.appendChild(collapser) - - if(plugin.settings.showLangNameInTopRight) { - let langName = document.createElement("div"); // 在右侧添加代码类型 - let langNameString = cbMeta.langName - langNameString = langNameString[0].toUpperCase() + langNameString.slice(1) // 首字母大写 - langName.appendText(langNameString); - langName.className = "langName"; - d.appendChild(langName); - } - d.addEventListener('click',function(this) { - if(d.hasAttribute("closed")){ - d.removeAttribute("closed") - } else { - d.setAttribute("closed",'') - } - }) - wrapperElm.prepend(d); -} - -function addLineHighLight(plugin: BetterCodeBlock, wrapperElm: HTMLElement, cbMeta: CodeBlockMeta) { +function addLineHighLight(plugin: BetterCodeBlock, preElm: HTMLElement, cbMeta: CodeBlockMeta) { if(cbMeta.highLightLines.length == 0) return let highLightWrap = document.createElement("pre") @@ -337,7 +376,7 @@ function addLineHighLight(plugin: BetterCodeBlock, wrapperElm: HTMLElement, cbMe highLightWrap.appendChild(singleLine) } - wrapperElm.appendChild(highLightWrap) + preElm.appendChild(highLightWrap) } function analyseHighLightLines(str: string): number[] { @@ -358,4 +397,133 @@ function analyseHighLightLines(str: string): number[] { }) return result +} + +function addIconToTitle(plugin: BetterCodeBlock, preElm: HTMLElement, cbMeta: CodeBlockMeta) { + let title = preElm.querySelectorAll(".obsidian-embedded-code-title__code-block-title") + + title.forEach(it => { + let iconWrap = createElement("div","icon-wrap") + let icon = document.createElement("img") + icon.src = "" + iconWrap.appendChild(icon) + it.appendChild(iconWrap) + }) + +} + +// 在自动换行时对数字和高亮行重新设置高度 +// These codes refer to the https://github.com/lijyze/obsidian-advanced-codeblock +function resizeNumWrapAndHLWrap(el: HTMLElement, context: MarkdownPostProcessorContext) { + setTimeout(async function(){ // 延时100毫秒以解决某些时候打开文件行高未被重设高度 + // console.log('on esize') + let codeBlockEl : HTMLElement = el.querySelector('pre > code') + if(!codeBlockEl) return + + let numWrap = el.querySelector('.code-block-linenum-wrap') + let highWrap = el.querySelector('.code-block-highlight-wrap') + + let codeBlockInfo = context.getSectionInfo(codeBlockEl) + // let view = app.workspace.getActiveViewOfType(MarkdownView) + // let codeBlockLineNum = codeBlockInfo.lineEnd - codeBlockInfo.lineStart - 1 // 除去首尾两行 + let view + let codeBlockLineNum + + let lineStart = 0 + let lineEnd = 0 + if(codeBlockInfo) { + view = app.workspace.getActiveViewOfType(MarkdownView) + codeBlockLineNum = codeBlockInfo.lineEnd - codeBlockInfo.lineStart - 1 // 除去首尾两行 + } else { + return + // let file = app.vault.getAbstractFileByPath(context.sourcePath) + // let cache = app.metadataCache.getCache(context.sourcePath) + + // cache.sections?.forEach(async element => { + // if(element.type == "code") { + // lineStart = element.position.start.line + // lineEnd = element.position.end.line + // codeBlockLineNum = lineEnd - lineStart - 1 + // return + // } + // }); + // let file = app.vault.getAbstractFileByPath(context.sourcePath) + // let cache = app.metadataCache.getCache(context.sourcePath) + // let fileContent = await app.vault.cachedRead( file) + // let fileContentLines = fileContent.split(/\n/g) + } + + let span = createElement("span") + + for(let i = 0; i < codeBlockLineNum; i++) { + let oneLineText + if(view){ + oneLineText = view.editor.getLine(codeBlockInfo.lineStart + i + 1) + } else { + // oneLineText = fileContentLines[lineStart + 1 + i] + // let file = app.vault.getAbstractFileByPath(context.sourcePath) + // let cache = app.metadataCache.getCache(context.sourcePath) + // let fileContent = await app.vault.cachedRead( file) + // let fileContentLines = fileContent.split(/\n/g) + // oneLineText = fileContentLines[cache.sections] + } + span.innerHTML = oneLineText || "0" + + codeBlockEl.appendChild(span) + span.style.display = 'block' + + let lineHeight = span.getBoundingClientRect().height + 'px' // 测量本行文字的高度 + + // console.log(lineHeight + ' ' + span.getBoundingClientRect().width); + + let numOneLine = numWrap? numWrap.childNodes[i] as HTMLElement : null + let hlOneLine = highWrap? highWrap.childNodes[i] as HTMLElement : null + + if(numOneLine) numOneLine.style.height = lineHeight; + if(hlOneLine) hlOneLine.style.height = lineHeight; + + span.remove() // 测量完后删掉 + } + }, 100) +} + +function exportPDF(el: HTMLElement, plugin: BetterCodeBlock, codeBlockFirstLines: string[], codeBlockSections: SectionCache[]) { + let codeBlocks = el.querySelectorAll('pre > code') + codeBlocks.forEach((codeElm, key) => { + let langName = "", title = "", highLightLines: number[] = [] + codeElm.classList.forEach(value => { + if(LANG_REG.test(value)) { + langName = value.replace('language-', '') + return + } + }) + + if(codeBlockFirstLines[key].match(titleRegExp) != null) { + title = codeBlockFirstLines[key].match(titleRegExp)[1] + } + if(codeBlockFirstLines[key].match(highLightLinesRegExp) != null) { + let highLightLinesInfo = codeBlockFirstLines[key].match(highLightLinesRegExp)[1] + highLightLines = analyseHighLightLines(highLightLinesInfo) + } + + let lineSize = codeBlockSections[key].position.end.line - codeBlockSections[key].position.start.line - 1 + + let cbMeta: CodeBlockMeta = { + langName: langName, + lineSize: lineSize, + pre: codeElm.parentElement, + code: codeElm as HTMLElement, + title: title, + isCollapse: false, + div: codeElm.parentElement.parentElement, + contentList: [], + highLightLines: highLightLines + } + addCodeTitleWrapper(plugin, codeElm.parentElement, cbMeta) // 导出取消代码块折叠 + addCodeTitle(plugin, cbMeta.pre, cbMeta) + if(plugin.settings.showLineNumber) { + addLineNumber(plugin, cbMeta) + } + addLineHighLight(plugin, cbMeta.pre, cbMeta) + }) } \ No newline at end of file diff --git a/manifest.json b/manifest.json index 99396ba..860272f 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-better-codeblock", "name": "Better CodeBlock", - "version": "1.0.6", + "version": "1.0.7", "minAppVersion": "0.12.0", "description": "Add title, line number to Obsidian code block", "author": "StarGrey", diff --git a/styles.css b/styles.css index d9e687b..3c9cc84 100644 --- a/styles.css +++ b/styles.css @@ -144,3 +144,32 @@ pre[class*=language-] .code-block-highlight-wrap span { .obsidian-embedded-code-title__code-block-title[closed] + code + span + span span{ visibility: hidden; } + +.obsidian-embedded-code-title__code-block-title > .title { + display: inline-block; + position: relative; + margin-left: 5px !important; + margin: 0; + padding: 0; + + top: 50%; + transform: translateY(-50%); +} + +/* .obsidian-embedded-code-title__code-block-title > .icon-wrap { + display: inline-block; + position: relative; + width: 20px; + height: 20px; + background-position: center; + + top: 50%; + transform: translateY(-50%); +} */ + +.code-block-wrap > pre > code[class*=language-]{ + padding: 0em 0em 0em 0em !important; + /* padding-top: 0 !important; */ + font-size: var(--editor-font-size) !important; + line-height: 1.5em !important; +} \ No newline at end of file