Files

611 lines
74 KiB
JavaScript
Raw Permalink Normal View History

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