/*
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
if you want to view the source visit the plugins github repository
*/

'use strict';

var require$$0 = require('obsidian');
var electron = require('electron');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);

/*! *****************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */

function __awaiter(thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
}

var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

function getDefaultExportFromCjs (x) {
	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}

function createCommonjsModule(fn, basedir, module) {
	return module = {
		path: basedir,
		exports: {},
		require: function (path, base) {
			return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
		}
	}, fn(module, module.exports), module.exports;
}

function commonjsRequire () {
	throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
}

var assertNever_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * Helper function for exhaustive checks of discriminated unions.
 * https://basarat.gitbooks.io/typescript/docs/types/discriminated-unions.html
 *
 * @example
 *
 *    type A = {type: 'a'};
 *    type B = {type: 'b'};
 *    type Union = A | B;
 *
 *    function doSomething(arg: Union) {
 *      if (arg.type === 'a') {
 *        return something;
 *      }
 *
 *      if (arg.type === 'b') {
 *        return somethingElse;
 *      }
 *
 *      // TS will error if there are other types in the union
 *      // Will throw an Error when called at runtime.
 *      // Use `assertNever(arg, true)` instead to fail silently.
 *      return assertNever(arg);
 *    }
 */
function assertNever(value, noThrow) {
    if (noThrow) {
        return value;
    }
    throw new Error("Unhandled discriminated union member: " + JSON.stringify(value));
}
exports.assertNever = assertNever;
exports.default = assertNever;
});

var assertNever = /*@__PURE__*/getDefaultExportFromCjs(assertNever_1);

function unload_math_preview(cm) {
    cm.setOption("hmdFoldMath", {
        onPreview: null,
        onPreviewEnd: null,
    });
}
function init_math_preview(cm) {
    if (require$$0.loadMathJax)
        require$$0.loadMathJax();
    if (!document.querySelector("#math-preview")) {
        const mathPreviewEl = document.createElement("div");
        mathPreviewEl.className = "float-win float-win-hidden";
        mathPreviewEl.id = "math-preview";
        const mathTitleEl = document.createElement("div");
        mathTitleEl.addClass("float-win-title");
        mathPreviewEl.appendChild(mathTitleEl);
        mathTitleEl.outerHTML = `<div class="float-win-title">
      <button class="float-win-close">
      <svg xmlns="http://www.w3.org/2000/svg" class="icon" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
      </button>
      Math Preview
      </div>`;
        const mathContentEl = document.createElement("div");
        mathContentEl.addClass("float-win-content");
        mathContentEl.id = "math-preview-content";
        mathPreviewEl.appendChild(mathContentEl);
        document.body.appendChild(mathPreviewEl);
    }
    let mathRenderer = null;
    const win = new FloatWin("math-preview");
    let supressed = false;
    win.closeBtn.addEventListener("click", function () {
        supressed = true; // for current TeX block
    }, false);
    function updatePreview(expr) {
        if (supressed)
            return;
        if (!mathRenderer) {
            // initialize renderer and preview window
            mathRenderer = cm.hmd.FoldMath.createRenderer(document.getElementById("math-preview-content"), "display");
            mathRenderer.onChanged = function () {
                // finished rendering. show the window
                if (!win.visible) {
                    const cursorPos = cm.charCoords(cm.getCursor(), "window");
                    win.moveTo(cursorPos.left, cursorPos.bottom);
                }
                win.show();
            };
        }
        if (!mathRenderer.isReady())
            return;
        mathRenderer.startRender(expr);
    }
    function hidePreview() {
        win.hide();
        supressed = false;
    }
    cm.setOption("hmdFoldMath", {
        onPreview: updatePreview,
        onPreviewEnd: hidePreview,
    });
}
function FloatWin(id) {
    const win = document.getElementById(id);
    // eslint-disable-next-line @typescript-eslint/no-this-alias
    const self = this;
    /** @type {HTMLDivElement} */
    const titlebar = win.querySelector(".float-win-title");
    titlebar.addEventListener("selectstart", function () {
        return false;
    }, false);
    /** @type {HTMLButtonElement} */
    const closeBtn = win.querySelector(".float-win-close");
    if (closeBtn) {
        closeBtn.addEventListener("click", function () {
            self.hide();
        }, false);
    }
    let boxX, boxY, mouseX, mouseY, offsetX, offsetY;
    titlebar.addEventListener("mousedown", function (e) {
        if (e.target === closeBtn)
            return;
        boxX = win.offsetLeft;
        boxY = win.offsetTop;
        mouseX = getMouseXY(e).x;
        mouseY = getMouseXY(e).y;
        offsetX = mouseX - boxX;
        offsetY = mouseY - boxY;
        document.addEventListener("mousemove", move, false);
        document.addEventListener("mouseup", up, false);
    }, false);
    function move(e) {
        let x = getMouseXY(e).x - offsetX;
        let y = getMouseXY(e).y - offsetY;
        const width = document.documentElement.clientWidth - titlebar.offsetWidth;
        const height = document.documentElement.clientHeight - titlebar.offsetHeight;
        x = Math.min(Math.max(0, x), width);
        y = Math.min(Math.max(0, y), height);
        win.style.left = x + "px";
        win.style.top = y + "px";
    }
    function up(e) {
        document.removeEventListener("mousemove", move, false);
        document.removeEventListener("mouseup", up, false);
    }
    function getMouseXY(e) {
        let x = 0, y = 0;
        e = e || window.event;
        if (e.pageX) {
            x = e.pageX;
            y = e.pageY;
        }
        else {
            x = e.clientX + document.body.scrollLeft - document.body.clientLeft;
            y = e.clientY + document.body.scrollTop - document.body.clientTop;
        }
        return {
            x: x,
            y: y,
        };
    }
    this.el = win;
    this.closeBtn = closeBtn;
    this.visible = !/float-win-hidden/.test(win.className);
}
FloatWin.prototype.show = function (moveToCenter) {
    if (this.visible)
        return;
    const el = this.el, 
    // eslint-disable-next-line @typescript-eslint/no-this-alias
    self = this;
    this.visible = true;
    el.className = this.el.className.replace(/\s*(float-win-hidden\s*)+/g, " ");
    if (moveToCenter) {
        setTimeout(function () {
            self.moveTo((window.innerWidth - el.offsetWidth) / 2, (window.innerHeight - el.offsetHeight) / 2);
        }, 0);
    }
};
FloatWin.prototype.hide = function () {
    if (!this.visible)
        return;
    this.visible = false;
    this.el.className += " float-win-hidden";
};
FloatWin.prototype.moveTo = function (x, y) {
    const s = this.el.style;
    s.left = x + "px";
    s.top = y + "px";
};

const DEFAULT_SETTINGS = {
    dynamicCursor: false,
    markSelection: false,
    activeLineOnSelect: false,
    enableCMinPreview: false,
    enablePrismJSStyling: false,
    editModeHideTokens: false,
    editModeClickHandler: false,
    showLineNums: false,
    copyButton: false,
    copyButtonOnPRE: false,
    enableOpenMD: false,
    cursorBlinkRate: 530,
    foldLinks: false,
    foldImages: false,
    containerAttributes: false,
    syntaxHighlighting: false,
    autoAlignTables: false,
    renderCode: false,
    renderHTML: false,
    renderChart: false,
    renderAdmonition: false,
    renderQuery: false,
    renderDataview: false,
    renderMath: false,
    renderMathPreview: false,
    renderBanner: false,
    renderEmbeds: false,
    renderEmoji: false,
    renderTasks: false,
    showBacklinks: false,
    styleCheckBox: true,
    allowedYamlKeys: "document-font-size",
    tokenList: "em|strong|strikethrough|code|linkText|task|internalLink|highlight",
};
class ObsidianCodeMirrorOptionsSettingsTab extends require$$0.PluginSettingTab {
    constructor(app, plugin) {
        super(app, plugin);
        this.plugin = plugin;
    }
    display() {
        const { containerEl } = this;
        containerEl.empty();
        containerEl.addClass("codemirror-options-settings");
        let tokenSettings;
        if (!this.app.vault.getConfig("legacyEditor")) {
            containerEl.createEl("h3", {
                text: "⚠️ Notice: Most of this plugin does not function when Live Preview mode is enabled.",
            });
        }
        if (this.app.vault.getConfig("legacyEditor")) {
            containerEl.createEl("h3", {
                text: "Markdown Parsing",
            });
            new require$$0.Setting(containerEl)
                .setName("⚠️ Hide Markdown Tokens")
                .setDesc(`Emulate WYSIWYG while editing by hiding markdown tokens. Markdown tokens will automatically hide once the cursor leaves the element.
         This mode will apply the class .hmd-inactive-line to all inactive lines and the class .hmd-hidden-token to all hidden tokens.`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.editModeHideTokens).onChange(value => {
                this.plugin.settings.editModeHideTokens = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateCodeMirrorOption("hmdHideToken", this.plugin.settings.editModeHideTokens ? this.plugin.settings.tokenList : false);
                this.plugin.applyBodyClasses();
                // hide the token list if the hide tokens setting is disabled
                this.plugin.settings.editModeHideTokens
                    ? tokenSettings.settingEl.removeClass("setting-disabled")
                    : tokenSettings.settingEl.addClass("setting-disabled");
            }));
            tokenSettings = new require$$0.Setting(this.containerEl)
                .setName("⚠️ Token List")
                .setDesc(`These markdown token types will be hidden. The default value will hide all currently supported tokens.
         Values must be pipe delimted with no spaces. Available options are: em|strong|strikethrough|code|linkText|task|internalLink|highlight`)
                .setClass("token-list-setting")
                .addText(textfield => {
                textfield.setPlaceholder(String("em|strong|strikethrough|code|linkText|task|internalLink|highlight"));
                textfield.inputEl.type = "text";
                textfield.setValue(String(this.plugin.settings.tokenList));
                textfield.onChange((value) => __awaiter(this, void 0, void 0, function* () {
                    this.plugin.settings.tokenList = value;
                    this.plugin.saveData(this.plugin.settings);
                    this.plugin.updateCodeMirrorOption("hmdHideToken", this.plugin.settings.editModeHideTokens ? this.plugin.settings.tokenList : false, true);
                }));
            });
            new require$$0.Setting(containerEl)
                .setName("⚠️ Enable OpenMD Mode")
                .setDesc(`Completely replace the HyperMD CodeMirror mode with a modified version of HyperMD that aims to
                replicate the default Obsidian edit mode parser while adding additional functionality such as
                improved internal link parsing.`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.enableOpenMD).onChange(value => {
                this.plugin.settings.enableOpenMD = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateCodeMirrorOption("mode", this.plugin.settings.enableOpenMD ? "openmd" : "hypermd");
            }));
            new require$$0.Setting(containerEl)
                .setName("⚠️ Collapse External Links")
                .setDesc(`This will collapse external links in edit mode so that the URL is hidden and only the link text is shown. 
                The full URL will display once you click into the link text.`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.foldLinks).onChange(value => {
                this.plugin.settings.foldLinks = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.applyBodyClasses();
                this.plugin.updateHmdOptions("hmdFold");
            }));
            new require$$0.Setting(containerEl)
                .setName("⚠️ Render Images Inline")
                .setDesc(`This will render images in edit mode inline. Clicking on the image will collapse the image down to its source view.`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.foldImages).onChange(value => {
                this.plugin.settings.foldImages = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.applyBodyClasses();
                this.plugin.updateHmdOptions("hmdFold");
            }));
            new require$$0.Setting(containerEl)
                .setName("Edit Mode Click Handler")
                .setDesc(`Allow mouse clicks to toggle checkboxes in edit mode.`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.editModeClickHandler).onChange(value => {
                this.plugin.settings.editModeClickHandler = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateCodeMirrorOption("hmdClick", this.plugin.settings.editModeClickHandler);
            }));
            new require$$0.Setting(containerEl)
                .setName("Style Checkboxes")
                .setDesc(`Disable this if you want to do your own styling of edit mode checkboxes. This setting does nothing if Hide Markdown Tokens is disabled`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.styleCheckBox).onChange(value => {
                this.plugin.settings.styleCheckBox = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.applyBodyClasses();
            }));
            containerEl.createEl("h3", {
                text: "Edit Mode Code Rendering",
            });
            new require$$0.Setting(containerEl)
                .setName("⚠️⚠️ Render Embeds")
                .setDesc(``)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderEmbeds).onChange(value => {
                this.plugin.settings.renderEmbeds = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateHmdOptions("hmdFold");
            }));
            new require$$0.Setting(containerEl)
                .setName("Render HTML")
                .setDesc(``)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderHTML).onChange(value => {
                this.plugin.settings.renderHTML = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateHmdOptions("hmdFold");
            }));
            new require$$0.Setting(containerEl)
                .setName("Render Math")
                .setDesc(``)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderMath).onChange(value => {
                this.plugin.settings.renderMath = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateHmdOptions("hmdFold");
            }));
            new require$$0.Setting(containerEl)
                .setName("Render Math Preview")
                .setDesc(``)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderMathPreview).onChange(value => {
                this.plugin.settings.renderMathPreview = value;
                this.plugin.saveData(this.plugin.settings);
                if (this.plugin.settings.renderMathPreview) {
                    this.app.workspace.iterateCodeMirrors(cm => {
                        init_math_preview(cm);
                    });
                }
                else {
                    const previewEl = document.querySelector("#math-preview");
                    if (previewEl) {
                        document.querySelector("#math-preview").detach();
                    }
                    this.app.workspace.iterateCodeMirrors(cm => {
                        unload_math_preview(cm);
                    });
                }
            }));
            new require$$0.Setting(containerEl)
                .setName("Render Emoji/Icon Shortcodes")
                .setDesc(createFragment(el => {
                el.appendText(`Render emoji/icon `);
                el.createEl("code", { text: ":shortcodes:" });
                el.appendText(` inline.`);
                el.createEl("br");
                el.createEl("a", {
                    href: "https://github.com/aidenlx/obsidian-icon-shortcodes",
                    text: "Icon Shortcodes v0.4.1+",
                });
                el.appendText(" Required. ");
            }))
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderEmoji).onChange(value => {
                this.plugin.settings.renderEmoji = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.applyBodyClasses();
                this.app.workspace.iterateCodeMirrors(cm => {
                    cm.refresh();
                });
            }));
            new require$$0.Setting(containerEl)
                .setName("Render Code Blocks")
                .setDesc(`If this is disabled, none of the options below will do anything`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderCode).onChange(value => {
                this.plugin.settings.renderCode = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateHmdOptions("hmdFold");
            }));
            new require$$0.Setting(containerEl)
                .setName("Render Admonitions")
                .setDesc(``)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderAdmonition).onChange(value => {
                this.plugin.settings.renderAdmonition = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateHmdOptions("hmdFoldCode");
            }));
            new require$$0.Setting(containerEl)
                .setName("Render Charts")
                .setDesc(``)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderChart).onChange(value => {
                this.plugin.settings.renderChart = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateHmdOptions("hmdFoldCode");
            }));
            new require$$0.Setting(containerEl)
                .setName("Render Embedded Search")
                .setDesc(``)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderQuery).onChange(value => {
                this.plugin.settings.renderQuery = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateHmdOptions("hmdFoldCode");
            }));
            new require$$0.Setting(containerEl)
                .setName("Render Dataview")
                .setDesc(``)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderDataview).onChange(value => {
                this.plugin.settings.renderDataview = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateHmdOptions("hmdFoldCode");
            }));
            new require$$0.Setting(containerEl)
                .setName("Render Tasks")
                .setDesc(``)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderTasks).onChange(value => {
                this.plugin.settings.renderTasks = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateHmdOptions("hmdFoldCode");
            }));
            new require$$0.Setting(containerEl)
                .setName("Render Banners")
                .setDesc(`This settings requires that the "Container Attributes" setting is enabled`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.renderBanner).onChange(value => {
                this.plugin.settings.renderBanner = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.applyBodyClasses();
                this.app.workspace.iterateCodeMirrors(cm => {
                    cm.refresh();
                });
            }));
            containerEl.createEl("h3", {
                text: "Visual Styling",
            });
            new require$$0.Setting(containerEl)
                .setName("Show Backlinks in Editor")
                .setDesc(`Append a backlinks component to the footer of edit mode documents`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.showBacklinks).onChange(value => {
                this.plugin.settings.showBacklinks = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.settings.showBacklinks
                    ? this.plugin.addBacklinksImmediately()
                    : this.plugin.removeBacklinksImmediately();
                // this.plugin.updateCodeMirrorHandlers("renderLine", this.plugin.onRenderLineBound, value, true);
            }));
            new require$$0.Setting(containerEl)
                .setName("Container Attributes")
                .setDesc(`Apply data attributes to the CodeMirror line div elements that describe the contained child elements. Think of
      this like Contextual Typography for Edit Mode.`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.containerAttributes).onChange(value => {
                this.plugin.settings.containerAttributes = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateCodeMirrorHandlers("renderLine", this.plugin.onRenderLineBound, value, true);
            }));
            new require$$0.Setting(this.containerEl)
                .setName("⚠️ Allowed Front Matter Keys")
                .setDesc(`A comma seperated list of front matter keys to turn into CSS variables and data attributes. This setting requires that the Container Attributes setting is enabled.`)
                .setClass("frontmatter-key-list-setting")
                .addText(textfield => {
                textfield.setPlaceholder(String(""));
                textfield.inputEl.type = "text";
                textfield.setValue(String(this.plugin.settings.allowedYamlKeys));
                textfield.onChange((value) => __awaiter(this, void 0, void 0, function* () {
                    this.plugin.settings.allowedYamlKeys = value;
                    this.plugin.saveData(this.plugin.settings);
                }));
            });
            new require$$0.Setting(containerEl)
                .setName("Auto Align Tables")
                .setDesc(`Automatically align markdown tables as they are being built. Note: This setting currently requires that OpenMD Mode be enabled.`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.autoAlignTables).onChange(value => {
                this.plugin.settings.autoAlignTables = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateCodeMirrorOption("hmdTableAlign", this.plugin.settings.autoAlignTables);
            }));
            new require$$0.Setting(containerEl)
                .setName("Dynamic cursor size")
                .setDesc(`When enabled, the cursor height will be determined by the max height of the entire line. 
         When disabled, the cursor's height is based on the height of the adjacent reference character.`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.dynamicCursor).onChange(value => {
                this.plugin.settings.dynamicCursor = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateCodeMirrorOption("singleCursorHeightPerLine", !this.plugin.settings.dynamicCursor);
            }));
            new require$$0.Setting(containerEl)
                .setName("Style active selection")
                .setDesc(`When enabled, selected text will be marked with the CSS class .CodeMirror-selectedtext. 
         Useful to force the styling of selected text when ::selection is not sufficient.`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.markSelection).onChange(value => {
                this.plugin.settings.markSelection = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateCodeMirrorOption("styleSelectedText", this.plugin.settings.markSelection);
                this.plugin.applyBodyClasses();
            }));
            new require$$0.Setting(containerEl)
                .setName("Retain active line on selection")
                .setDesc(`When enabled, text selection will not remove the .active-line class on the current line. 
         When disabled text selection on the active line will remove the .active-line class.`)
                .addToggle(toggle => toggle.setValue(this.plugin.settings.activeLineOnSelect).onChange(value => {
                this.plugin.settings.activeLineOnSelect = value;
                this.plugin.saveData(this.plugin.settings);
                this.plugin.updateCodeMirrorOption("styleActiveLine", this.plugin.settings.activeLineOnSelect ? { nonEmpty: true } : true);
            }));
            new require$$0.Setting(containerEl)
                .setName("Cursor Blink Rate")
                .setDesc(`Value is in milliseconds. Default is 530. Set to 0 to disable blinking.`)
                .addText(textfield => {
                textfield.setPlaceholder(String(530));
                textfield.inputEl.type = "number";
                textfield.setValue(String(this.plugin.settings.cursorBlinkRate));
                textfield.onChange((value) => __awaiter(this, void 0, void 0, function* () {
                    this.plugin.settings.cursorBlinkRate = Number(value);
                    this.plugin.saveData(this.plugin.settings);
                    this.plugin.updateCodeMirrorOption("cursorBlinkRate", this.plugin.settings.cursorBlinkRate);
                }));
            });
        }
        containerEl.createEl("h3", {
            text: "Syntax Highlighting",
        });
        let lineNums, copyButton, copyButtonPre;
        new require$$0.Setting(containerEl)
            .setName("Enable Edit Mode Syntax Highlighting Themes")
            .setDesc(`Apply syntax highlighting themes to code blocks in edit mode. The default theme is Material Pale Night
                but additional themes are available via the Style Settings plugin`)
            .addToggle(toggle => toggle.setValue(this.plugin.settings.syntaxHighlighting).onChange(value => {
            this.plugin.settings.syntaxHighlighting = value;
            this.plugin.saveData(this.plugin.settings);
            this.plugin.applyBodyClasses(true);
        }));
        new require$$0.Setting(containerEl)
            .setName("Enable Preview Mode Syntax Highlighting Themes")
            .setDesc(`Apply syntax highlighting themes to code blocks in preview mode. The default theme is Material Pale Night
        but additional themes are available via the Style Settings plugin`)
            .addToggle(toggle => toggle.setValue(this.plugin.settings.enablePrismJSStyling).onChange(value => {
            this.plugin.settings.enablePrismJSStyling = value;
            this.plugin.saveData(this.plugin.settings);
            this.plugin.applyBodyClasses(true);
        }));
        new require$$0.Setting(containerEl)
            .setName("Use CodeMirror for syntax highlighting in preview mode")
            .setDesc(`This setting creates consistent highlighting between edit and preview by using CodeMirror to highlight code in both modes.`)
            .addToggle(toggle => toggle.setValue(this.plugin.settings.enableCMinPreview).onChange(value => {
            this.plugin.settings.enableCMinPreview = value;
            this.plugin.saveData(this.plugin.settings);
            this.plugin.applyBodyClasses(true);
            this.plugin.settings.enableCMinPreview
                ? (lineNums.settingEl.removeClass("setting-disabled"),
                    copyButton.settingEl.removeClass("setting-disabled"),
                    copyButtonPre.settingEl.removeClass("setting-disabled"))
                : (lineNums.settingEl.addClass("setting-disabled"),
                    copyButton.settingEl.addClass("setting-disabled"),
                    copyButtonPre.settingEl.addClass("setting-disabled"));
        }));
        lineNums = new require$$0.Setting(containerEl)
            .setName("⚠️ Show line numbers for code blocks in preview mode")
            .setDesc(`This setting will add line numbers to code blocks in preview mode.`)
            .addToggle(toggle => toggle.setValue(this.plugin.settings.showLineNums).onChange(value => {
            this.plugin.settings.showLineNums = value;
            this.plugin.saveData(this.plugin.settings);
            this.plugin.applyBodyClasses(true);
        }));
        copyButton = new require$$0.Setting(containerEl)
            .setName("Enable copy button to code blocks in preview mode")
            .setDesc(`This setting will add a copy button to the bottom left corner of code blocks in preview mode. The button will show up on code block hover.`)
            .addToggle(toggle => toggle.setValue(this.plugin.settings.copyButton).onChange(value => {
            this.plugin.settings.copyButton = value;
            this.plugin.saveData(this.plugin.settings);
            this.plugin.applyBodyClasses(true);
        }));
        copyButtonPre = new require$$0.Setting(containerEl)
            .setName("⚠️ Enable copy button to all PRE blocks in preview mode")
            .setDesc(`This setting will add a copy button to any PRE element. This could negatively impact certain plugins that render PRE blocks.`)
            .addToggle(toggle => toggle.setValue(this.plugin.settings.copyButtonOnPRE).onChange(value => {
            this.plugin.settings.copyButtonOnPRE = value;
            this.plugin.saveData(this.plugin.settings);
            this.plugin.applyBodyClasses(true);
        }));
        containerEl.createEl("h3", {
            text: "Syntax Highlighting Theme",
        });
        new require$$0.Setting(containerEl)
            .setName("Refer to the Style Settings plugin")
            .setDesc(`To customize the syntax highlighting theme, 
    install the Style Settings plugin and expand the "CodeMirror Options" section`)
            .setClass("info");
        // update dynamic setting visibility
        this.plugin.settings.editModeHideTokens
            ? tokenSettings === null || tokenSettings === void 0 ? void 0 : tokenSettings.settingEl.removeClass("setting-disabled")
            : tokenSettings === null || tokenSettings === void 0 ? void 0 : tokenSettings.settingEl.addClass("setting-disabled");
        this.plugin.settings.enableCMinPreview
            ? (lineNums === null || lineNums === void 0 ? void 0 : lineNums.settingEl.removeClass("setting-disabled"),
                copyButton === null || copyButton === void 0 ? void 0 : copyButton.settingEl.removeClass("setting-disabled"),
                copyButtonPre === null || copyButtonPre === void 0 ? void 0 : copyButtonPre.settingEl.removeClass("setting-disabled"))
            : (lineNums === null || lineNums === void 0 ? void 0 : lineNums.settingEl.addClass("setting-disabled"),
                copyButton === null || copyButton === void 0 ? void 0 : copyButton.settingEl.addClass("setting-disabled"),
                copyButtonPre === null || copyButtonPre === void 0 ? void 0 : copyButtonPre.settingEl.addClass("setting-disabled"));
    }
}

// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE

function leftFillNum(num, targetLength) {
  return num.toString().padStart(targetLength, 0);
}

CodeMirror.runMode = function (string, modespec, callback, options) {
  var modeRef = CodeMirror.findModeByName(modespec);
  var mode = CodeMirror.getMode(CodeMirror.defaults, modeRef?.mime);
  var lineNumber = 1;
  if (callback.nodeType == 1) {
    var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
    var lineNums = (options && options.lineNums) || false;
    var node = callback,
      col = 0;
    node.innerHTML = "";
    callback = function (text, style) {
      if (text == "\n") {
        if (lineNums) {
          lineNumber++; //increment line number
          var lineNum = document.createElement("span");
          lineNum.addClass("cm-linenumber");
          var content = document.createTextNode(leftFillNum(lineNumber, 2) + " ");
          lineNum.appendChild(content);
          node.appendChild(document.createTextNode(text));
          node.appendChild(lineNum);
        } else {
          node.appendChild(document.createTextNode(text));
        }
        col = 0;
        return;
      }
      var content = "";
      // replace tabs
      for (var pos = 0; ; ) {
        var idx = text.indexOf("\t", pos);
        if (idx == -1) {
          content += text.slice(pos);
          col += text.length - pos;
          break;
        } else {
          col += idx - pos;
          content += text.slice(pos, idx);
          var size = tabSize - (col % tabSize);
          col += size;
          for (var i = 0; i < size; ++i) content += " ";
          pos = idx + 1;
        }
      }

      if (style) {
        var sp = node.appendChild(document.createElement("span"));
        sp.className = "cm-" + style.replace(/ +/g, " cm-");
        sp.appendChild(document.createTextNode(content));
      } else {
        node.appendChild(document.createTextNode(content));
      }
    };
  }

  var lines = CodeMirror.splitLines(string),
    state = (options && options.state) || CodeMirror.startState(mode);
  var lineLength = lineNums && mode.name !== "yaml" ? lines.length - 1 : lines.length;
  for (var i = 0, e = lineLength; i < e; ++i) {
    if (i) callback("\n");
    var stream = new CodeMirror.StringStream(lines[i]);
    while (!stream.eol()) {
      var style = mode.token(stream, state);
      callback(stream.current(), style, i, stream.start);
      stream.start = stream.pos;
    }
  }
  if (lineNums) {
    var outputDiv = node;
    var firstLine = document.createElement("span");
    firstLine.addClass("cm-linenumber");
    var content = document.createTextNode(leftFillNum(1, 2) + " ");
    firstLine.appendChild(content);
    outputDiv?.insertBefore(firstLine, outputDiv.firstChild);
  }
};

// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE

CodeMirror.colorize = (function () {
  var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/;

  function textContent(node, out) {
    if (node.nodeType == 3) return out.push(node.nodeValue);
    for (var ch = node.firstChild; ch; ch = ch.nextSibling) {
      textContent(ch, out);
      if (isBlock.test(node.nodeType)) out.push("\n");
    }
  }

  return function (collection, defaultMode, showLineNums = false) {
    if (!collection) collection = document.body.getElementsByTagName("pre");

    for (var i = 0; i < collection.length; ++i) {
      var node = collection[i];
      var mode = node.getAttribute("data-lang") || defaultMode;
      if (!mode) continue;

      var text = [];
      textContent(node, text);
      node.innerHTML = "";
      CodeMirror.runMode(text.join(""), mode, node, { lineNums: showLineNums });
      node.parentElement.className += " cm-s-obsidian";
    }
  };
})();

// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE

// Because sometimes you need to mark the selected *text*.
//
// Adds an option 'styleSelectedText' which, when enabled, gives
// selected text the CSS class given as option value, or
// "CodeMirror-selectedtext" when the value is not a string.

(function(mod) {
    mod(CodeMirror);
})(function(CodeMirror) {

  CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) {
    var prev = old && old != CodeMirror.Init;
    if (val && !prev) {
      cm.state.markedSelection = [];
      cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext";
      reset(cm);
      cm.on("cursorActivity", onCursorActivity);
      cm.on("change", onChange);
    } else if (!val && prev) {
      cm.off("cursorActivity", onCursorActivity);
      cm.off("change", onChange);
      clear(cm);
      cm.state.markedSelection = cm.state.markedSelectionStyle = null;
    }
  });

  function onCursorActivity(cm) {
    if (cm.state.markedSelection)
      cm.operation(function() { update(cm); });
  }

  function onChange(cm) {
    if (cm.state.markedSelection && cm.state.markedSelection.length)
      cm.operation(function() { clear(cm); });
  }

  var CHUNK_SIZE = 8;
  var Pos = CodeMirror.Pos;
  var cmp = CodeMirror.cmpPos;

  function coverRange(cm, from, to, addAt) {
    if (cmp(from, to) == 0) return;
    var array = cm.state.markedSelection;
    var cls = cm.state.markedSelectionStyle;
    for (var line = from.line;;) {
      var start = line == from.line ? from : Pos(line, 0);
      var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line;
      var end = atEnd ? to : Pos(endLine, 0);
      var mark = cm.markText(start, end, {className: cls});
      if (addAt == null) array.push(mark);
      else array.splice(addAt++, 0, mark);
      if (atEnd) break;
      line = endLine;
    }
  }

  function clear(cm) {
    var array = cm.state.markedSelection;
    for (var i = 0; i < array.length; ++i) array[i].clear();
    array.length = 0;
  }

  function reset(cm) {
    clear(cm);
    var ranges = cm.listSelections();
    for (var i = 0; i < ranges.length; i++)
      coverRange(cm, ranges[i].from(), ranges[i].to());
  }

  function update(cm) {
    if (!cm.somethingSelected()) return clear(cm);
    if (cm.listSelections().length > 1) return reset(cm);

    var from = cm.getCursor("start"), to = cm.getCursor("end");

    var array = cm.state.markedSelection;
    if (!array.length) return coverRange(cm, from, to);

    var coverStart = array[0].find(), coverEnd = array[array.length - 1].find();
    if (!coverStart || !coverEnd || to.line - from.line <= CHUNK_SIZE ||
        cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0)
      return reset(cm);

    while (cmp(from, coverStart.from) > 0) {
      array.shift().clear();
      coverStart = array[0].find();
    }
    if (cmp(from, coverStart.from) < 0) {
      if (coverStart.to.line - from.line < CHUNK_SIZE) {
        array.shift().clear();
        coverRange(cm, from, coverStart.to, 0);
      } else {
        coverRange(cm, from, coverStart.from, 0);
      }
    }

    while (cmp(to, coverEnd.to) < 0) {
      array.pop().clear();
      coverEnd = array[array.length - 1].find();
    }
    if (cmp(to, coverEnd.to) > 0) {
      if (to.line - coverEnd.from.line < CHUNK_SIZE) {
        array.pop().clear();
        coverRange(cm, coverEnd.from, to);
      } else {
        coverRange(cm, coverEnd.to, to);
      }
    }
  }
});

// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE

(function (mod) {
  mod(CodeMirror);
})(function (CodeMirror) {
  var WRAP_CLASS = "CodeMirror-activeline";
  var BACK_CLASS = "CodeMirror-activeline-background";
  var GUTT_CLASS = "CodeMirror-activeline-gutter";

  CodeMirror.defineOption("styleActiveLine", false, function (cm, val, old) {
    var prev = old == CodeMirror.Init ? false : old;
    if (val == prev) return;
    if (prev) {
      cm.off("beforeSelectionChange", selectionChange);
      clearActiveLines(cm);
      delete cm.state.activeLines;
    }
    if (val) {
      cm.state.activeLines = [];
      updateActiveLines(cm, cm.listSelections());
      cm.on("beforeSelectionChange", selectionChange);
      cm.refresh();
    }
  });

  function clearActiveLines(cm) {
    for (var i = 0; i < cm.state.activeLines.length; i++) {
      cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
      cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
      cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS);
    }
  }

  function sameArray(a, b) {
    if (a.length != b.length) return false;
    for (var i = 0; i < a.length; i++) if (a[i] != b[i]) return false;
    return true;
  }

  function updateActiveLines(cm, ranges) {
    var active = [];
    for (var i = 0; i < ranges.length; i++) {
      var range = ranges[i];
      var option = cm.getOption("styleActiveLine");
      // if (typeof option == "object" && option.nonEmpty ? range.anchor.line != range.head.line : !range.empty())
      // nothingislost: modified the nonEmpty option to support multiple selected lines
      if (typeof option == "object" && option.nonEmpty ? false : !range.empty()) continue;
      // nothingislost: support forwards and backwards multi line selections
      if (range.head.line > range.anchor.line) {
        var start = range.anchor.line,
          end = range.head.line;
      } else {
        var start = range.head.line,
          end = range.anchor.line;
      }
      // nothingislost: get the visual start for all lines in the selection
      for (var j = start; j < end + 1; ++j) {
        var line = cm.getLineHandleVisualStart(j);
        if (active[active.length - 1] != line) active.push(line);
      }
    }
    if (sameArray(cm.state.activeLines, active)) return;
    cm.operation(function () {
      clearActiveLines(cm);
      for (var i = 0; i < active.length; i++) {
        cm.addLineClass(active[i], "wrap", WRAP_CLASS);
        cm.addLineClass(active[i], "background", BACK_CLASS);
        cm.addLineClass(active[i], "gutter", GUTT_CLASS);
      }
      cm.state.activeLines = active;
    });
  }

  function selectionChange(cm, sel) {
    updateActiveLines(cm, sel.ranges);
  }
});

createCommonjsModule(function (module) {
/*!
 * HyperMD, copyright (c) by laobubu
 * Distributed under an MIT license: http://laobubu.net/HyperMD/LICENSE
 *
 * Break the Wall between writing and preview, in a Markdown Editor.
 *
 * HyperMD makes Markdown editor on web WYSIWYG, based on CodeMirror
 *
 * Homepage: http://laobubu.net/HyperMD/
 * Issues: https://github.com/laobubu/HyperMD/issues
 */
(function (global, factory) {
  (global = typeof globalThis !== "undefined" ? globalThis : global || self),
    factory((global.HyperMD = {}), global.CodeMirror);
})(commonjsGlobal, function (exports, CodeMirror) {

  /**
   * Provides some common PolyFill
   *
   * @internal Part of HyperMD core.
   *
   * You shall NOT import this file; please import "core" instead
   */
  if (typeof Object["assign"] != "function") {
    // Must be writable: true, enumerable: false, configurable: true
    Object.defineProperty(Object, "assign", {
      value: function assign(target, varArgs) {
        var arguments$1 = arguments;

        if (target == null) {
          // TypeError if undefined or null
          throw new TypeError("Cannot convert undefined or null to object");
        }
        var to = Object(target);
        for (var index = 1; index < arguments.length; index++) {
          var nextSource = arguments$1[index];
          if (nextSource != null) {
            // Skip over if undefined or null
            for (var nextKey in nextSource) {
              // Avoid bugs when hasOwnProperty is shadowed
              if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
                to[nextKey] = nextSource[nextKey];
              }
            }
          }
        }
        return to;
      },
      writable: true,
      configurable: true,
    });
  }

  /**
   * Provides some universal utils
   *
   * @internal Part of HyperMD core.
   *
   * You shall NOT import this file; please import "core" instead
   */
  /** Simple FlipFlop */
  var FlipFlop = /** @class */ (function () {
    /**
     * Simple FlipFlop
     *
     * @param {function} on_cb see FlipFlop.ON(callback)
     * @param {function} off_cb see FlipFlop.OFF(callback)
     * @param {T} [state] initial state. default: false (boolean)
     * @param {string} [subkey] if get an object, use this key to retrive status. default: "enabled"
     */
    function FlipFlop(on_cb, off_cb, state, subkey) {
      if (state === void 0) {
        state = false;
      }
      if (subkey === void 0) {
        subkey = "enabled";
      }
      this.on_cb = on_cb;
      this.off_cb = off_cb;
      this.state = state;
      this.subkey = subkey;
    }
    /** set a callback when state is changed and is **NOT** `null`, `false` etc. */
    FlipFlop.prototype.ON = function (callback) {
      this.on_cb = callback;
      return this;
    };
    /** set a callback when state is set to `null`, `false` etc. */
    FlipFlop.prototype.OFF = function (callback) {
      this.off_cb = callback;
      return this;
    };
    /**
     * Update FlipFlop status, and trig callback function if needed
     *
     * @param {T|object} state new status value. can be a object
     * @param {boolean} [toBool] convert retrived value to boolean. default: false
     */
    FlipFlop.prototype.set = function (state, toBool) {
      var newVal = typeof state === "object" && state ? state[this.subkey] : state;
      if (toBool) {
        newVal = !!newVal;
      }
      if (newVal === this.state) {
        return;
      }
      if ((this.state = newVal)) {
        this.on_cb && this.on_cb(newVal);
      } else {
        this.off_cb && this.off_cb(newVal);
      }
    };
    FlipFlop.prototype.setBool = function (state) {
      return this.set(state, true);
    };
    /**
     * Bind to a object's property with `Object.defineProperty`
     * so that you may set state with `obj.enable = true`
     */
    FlipFlop.prototype.bind = function (obj, key, toBool) {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      var _this = this;
      Object.defineProperty(obj, key, {
        get: function () {
          return _this.state;
        },
        set: function (v) {
          return _this.set(v, toBool);
        },
        configurable: true,
        enumerable: true,
      });
      return this;
    };
    return FlipFlop;
  })();
  /** async run a function, and retry up to N times until it returns true */
  function tryToRun(fn, times, onFailed) {
    times = ~~times || 5;
    var delayTime = 250;
    function nextCycle() {
      if (!times--) {
        if (onFailed) {
          onFailed();
        }
        return;
      }
      try {
        if (fn()) {
          return;
        }
      } catch (e) {}
      setTimeout(nextCycle, delayTime);
      delayTime *= 2;
    }
    setTimeout(nextCycle, 0);
  }
  /**
   * make a debounced function
   *
   * @param {Function} fn
   * @param {number} delay in ms
   */
  function debounce(fn, delay) {
    var deferTask = null;
    var notClearBefore = 0;
    var run = function () {
      fn();
      deferTask = 0;
    };
    var ans = function () {
      var nowTime = +new Date();
      if (deferTask) {
        if (nowTime < notClearBefore) {
          return;
        } else {
          clearTimeout(deferTask);
        }
      }
      deferTask = setTimeout(run, delay);
      notClearBefore = nowTime + 100; // allow 100ms error
    };
    ans.stop = function () {
      if (!deferTask) {
        return;
      }
      clearTimeout(deferTask);
      deferTask = 0;
    };
    return ans;
  }
  /**
   * addClass / removeClass etc.
   *
   * using CodeMirror's (although they're legacy API)
   */
  var addClass = CodeMirror.addClass;
  var rmClass = CodeMirror.rmClass;
  var contains = CodeMirror.contains;
  /**
   * a fallback for new Array(count).fill(data)
   */
  function repeat(item, count) {
    var ans = new Array(count);
    if (ans["fill"]) {
      ans["fill"](item);
    } else {
      for (var i = 0; i < count; i++) {
        ans[i] = item;
      }
    }
    return ans;
  }
  function repeatStr(item, count) {
    var ans = "";
    while (count-- > 0) {
      ans += item;
    }
    return ans;
  }
  /**
   * Visit element nodes and their children
   */
  function visitElements(seeds, handler) {
    var queue = [seeds],
      tmp;
    while ((tmp = queue.shift())) {
      for (var i = 0; i < tmp.length; i++) {
        var el = tmp[i];
        if (!el || el.nodeType != Node.ELEMENT_NODE) {
          continue;
        }
        handler(el);
        if (el.children && el.children.length > 0) {
          queue.push(el.children);
        }
      }
    }
  }
  /**
   * A lazy and simple Element size watcher. NOT WORK with animations
   */
  function watchSize(el, onChange, needPoll) {
    var _a = el.getBoundingClientRect(),
      width = _a.width,
      height = _a.height;
    /** check size and trig onChange */
    var check = debounce(function () {
      var rect = el.getBoundingClientRect();
      var newWidth = rect.width,
        newHeight = rect.height;
      if (width != newWidth || height != newHeight) {
        onChange(newWidth, newHeight, width, height);
        width = newWidth;
        height = newHeight;
        setTimeout(check, 200); // maybe changed again later?
      }
    }, 100);
    var nextTimer = null;
    function pollOnce() {
      if (nextTimer) {
        clearTimeout(nextTimer);
      }
      if (!stopped) {
        nextTimer = setTimeout(pollOnce, 200);
      }
      check();
    }
    var stopped = false;
    function stop() {
      stopped = true;
      check.stop();
      if (nextTimer) {
        clearTimeout(nextTimer);
        nextTimer = null;
      }
      for (var i = 0; i < eventBinded.length; i++) {
        eventBinded[i][0].removeEventListener(eventBinded[i][1], check, false);
      }
    }
    var eventBinded = [];
    function bindEvents(el) {
      var tagName = el.tagName;
      var computedStyle = getComputedStyle(el);
      var getStyle = function (name) {
        return computedStyle.getPropertyValue(name) || "";
      };
      if (getStyle("resize") != "none") {
        needPoll = true;
      }
      // size changes if loaded
      if (/^(?:img|video)$/i.test(tagName)) {
        el.addEventListener("load", check, false);
        el.addEventListener("error", check, false);
      } else if (/^(?:details|summary)$/i.test(tagName)) {
        el.addEventListener("click", check, false);
      }
    }
    if (!needPoll) {
      visitElements([el], bindEvents);
    }
    // bindEvents will update `needPoll`
    if (needPoll) {
      nextTimer = setTimeout(pollOnce, 200);
    }
    return {
      check: check,
      stop: stop,
    };
  }
  function makeSymbol(name) {
    if (typeof Symbol === "function") {
      return Symbol(name);
    }
    return "_\n" + name + "\n_" + Math.floor(Math.random() * 0xffff).toString(16);
  }

  /*! *****************************************************************************
  Copyright (c) Microsoft Corporation.

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  PERFORMANCE OF THIS SOFTWARE.
  ***************************************************************************** */

  var __assign = function () {
    __assign =
      Object.assign ||
      function __assign(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
          s = arguments[i];
          for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
        }
        return t;
      };
    return __assign.apply(this, arguments);
  };

  /**
   * Ready-to-use functions that powers up your Markdown editor
   *
   * @internal Part of HyperMD core.
   *
   * You shall NOT import this file; please import "core" instead
   */
  // if (HyperMD_Mark in editor), the editor was a HyperMD mode at least once
  var HyperMD_Mark = "__hypermd__";
  /**
   * The default configuration that used by `HyperMD.fromTextArea`
   *
   * Addons may update this object freely!
   */
  var suggestedEditorConfig = {
    lineNumbers: true,
    lineWrapping: true,
    theme: "light",
    mode: "text/x-hypermd",
    tabSize: 4,
    autoCloseBrackets: true,
    foldGutter: true,
    gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "HyperMD-goback"],
  };
  /**
   * Editor Options that disable HyperMD WYSIWYG visual effects.
   * These option will be applied when user invoke `switchToNormal`.
   *
   * Addons about visual effects, shall update this object!
   */
  var normalVisualConfig = {
    theme: "default",
  };
  /**
   * Initialize an editor from a <textarea>
   * Calling `CodeMirror.fromTextArea` with recommended HyperMD options
   *
   * @see CodeMirror.fromTextArea
   *
   * @param {HTMLTextAreaElement} textArea
   * @param {object} [config]
   * @returns {cm_t}
   */
  function fromTextArea(textArea, config) {
    var final_config = __assign(__assign({}, suggestedEditorConfig), config);
    var cm = CodeMirror.fromTextArea(textArea, final_config);
    cm[HyperMD_Mark] = true;
    return cm;
  }
  function switchToNormal(editor, options_or_theme) {
    // this CodeMirror editor has never been in HyperMD mode. `switchToNormal` is meanless
    if (!editor[HyperMD_Mark]) {
      return;
    }
    if (typeof options_or_theme === "string") {
      options_or_theme = { theme: options_or_theme };
    }
    var opt = __assign(
      __assign(__assign({}, normalVisualConfig), { theme: editor.getOption("theme") }),
      options_or_theme
    );
    for (var key in opt) {
      editor.setOption(key, opt[key]);
    }
  }
  function switchToHyperMD(editor, options_or_theme) {
    if (typeof options_or_theme === "string") {
      options_or_theme = { theme: options_or_theme };
    }
    var opt = {};
    if (HyperMD_Mark in editor) {
      // has been HyperMD mode once. Only modify visual-related options
      for (var key in normalVisualConfig) {
        opt[key] = suggestedEditorConfig[key];
      }
      Object.assign(opt, { theme: editor.getOption("theme") }, options_or_theme);
    } else {
      // this CodeMirror editor is new to HyperMD
      Object.assign(opt, suggestedEditorConfig, { theme: editor.getOption("theme") }, options_or_theme);
      editor[HyperMD_Mark] = true;
    }
    for (var key in opt) {
      editor.setOption(key, opt[key]);
    }
  }

  /**
    @internal DO NOT IMPORT THIS MODULE!
              If you want to use this module, import it from `core`:

                  import { cm_internal } from "../core"

    The following few functions are from CodeMirror's source code.

    MIT License

    Copyright (C) 2017 by Marijn Haverbeke <marijnh@gmail.com> and others

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.

    */
  /**
   * Find the view element corresponding to a given line. Return null when the line isn't visible.
   *
   * @see codemirror\src\measurement\position_measurement.js 5.37.0
   * @param n lineNo
   */
  function findViewIndex(cm, n) {
    if (n >= cm.display.viewTo) {
      return null;
    }
    n -= cm.display.viewFrom;
    if (n < 0) {
      return null;
    }
    var view = cm.display.view;
    for (var i = 0; i < view.length; i++) {
      n -= view[i].size;
      if (n < 0) {
        return i;
      }
    }
  }
  /**
   * Find a line view that corresponds to the given line number.
   *
   * @see codemirror\src\measurement\position_measurement.js 5.37.0
   */
  function findViewForLine(cm, lineN) {
    if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) {
      return cm.display.view[findViewIndex(cm, lineN)];
    }
    var ext = cm.display.externalMeasured;
    if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) {
      return ext;
    }
  }
  /**
   * Find a line map (mapping character offsets to text nodes) and a
   * measurement cache for the given line number. (A line view might
   * contain multiple lines when collapsed ranges are present.)
   *
   * @see codemirror\src\measurement\position_measurement.js 5.37.0
   */
  function mapFromLineView(lineView, line, lineN) {
    if (lineView.line == line) {
      return {
        map: lineView.measure.map,
        cache: lineView.measure.cache,
        before: false,
      };
    }
    if (!lineView.rest) return;
    for (var i = 0; i < lineView.rest.length; i++) {
      if (lineView.rest[i] == line) {
        return {
          map: lineView.measure.maps[i],
          cache: lineView.measure.caches[i],
          before: false,
        };
      }
    }
    for (var i = 0; i < lineView.rest.length; i++) {
      if (lineView.rest[i].lineNo() > lineN) {
        return {
          map: lineView.measure.maps[i],
          cache: lineView.measure.caches[i],
          before: true,
        };
      }
    }
  }

  var cm_internal = /*#__PURE__*/ Object.freeze({
    __proto__: null,
    findViewIndex: findViewIndex,
    findViewForLine: findViewForLine,
    mapFromLineView: mapFromLineView,
  });

  /**
   * CodeMirror-related utils
   *
   * @internal Part of HyperMD core.
   *
   * You shall NOT import this file; please import "core" instead
   */
  /**
   * Useful tool to seek for tokens
   *
   *     var seeker = new TokenSeeker(cm)
   *     seeker.setPos(0, 0) // set to line 0, char 0
   *     var ans = seeker.findNext(/fomratting-em/)
   *
   */
  var TokenSeeker = /** @class */ (function () {
    function TokenSeeker(cm) {
      this.cm = cm;
    }
    TokenSeeker.prototype.findNext = function (condition, varg, since) {
      var lineNo = this.lineNo;
      var tokens = this.lineTokens;
      var token = null;
      var i_token = this.i_token + 1;
      var maySpanLines = false;
      if (varg === true) {
        maySpanLines = true;
      } else if (typeof varg === "number") {
        i_token = varg;
      }
      if (since) {
        if (since.line > lineNo) {
          i_token = tokens.length; // just ignore current line
        } else if (since.line < lineNo);
        else {
          for (; i_token < tokens.length; i_token++) {
            if (tokens[i_token].start >= since.ch) {
              break;
            }
          }
        }
      }
      for (; i_token < tokens.length; i_token++) {
        var token_tmp = tokens[i_token];
        if (typeof condition === "function" ? condition(token_tmp, tokens, i_token) : condition.test(token_tmp.type)) {
          token = token_tmp;
          break;
        }
      }
      if (!token && maySpanLines) {
        var cm_1 = this.cm;
        var startLine = Math.max(since ? since.line : 0, lineNo + 1);
        cm_1.eachLine(startLine, cm_1.lastLine() + 1, function (line_i) {
          lineNo = line_i.lineNo();
          tokens = cm_1.getLineTokens(lineNo);
          i_token = 0;
          if (since && lineNo === since.line) {
            for (; i_token < tokens.length; i_token++) {
              if (tokens[i_token].start >= since.ch) {
                break;
              }
            }
          }
          for (; i_token < tokens.length; i_token++) {
            var token_tmp = tokens[i_token];
            if (
              typeof condition === "function" ? condition(token_tmp, tokens, i_token) : condition.test(token_tmp.type)
            ) {
              token = token_tmp;
              return true; // stop `eachLine`
            }
          }
        });
      }
      return token ? { lineNo: lineNo, token: token, i_token: i_token } : null;
    };
    TokenSeeker.prototype.findPrev = function (condition, varg, since) {
      var lineNo = this.lineNo;
      var tokens = this.lineTokens;
      var token = null;
      var i_token = this.i_token - 1;
      var maySpanLines = false;
      if (varg === true) {
        maySpanLines = true;
      } else if (typeof varg === "number") {
        i_token = varg;
      }
      if (since) {
        if (since.line < lineNo) {
          i_token = -1; // just ignore current line
        } else if (since.line > lineNo);
        else {
          for (; i_token < tokens.length; i_token++) {
            if (tokens[i_token].start >= since.ch) {
              break;
            }
          }
        }
      }
      if (i_token >= tokens.length) {
        i_token = tokens.length - 1;
      }
      for (; i_token >= 0; i_token--) {
        var token_tmp = tokens[i_token];
        if (typeof condition === "function" ? condition(token_tmp, tokens, i_token) : condition.test(token_tmp.type)) {
          token = token_tmp;
          break;
        }
      }
      if (!token && maySpanLines) {
        var cm = this.cm;
        var startLine = Math.min(since ? since.line : cm.lastLine(), lineNo - 1);
        var endLine = cm.firstLine();
        // cm.eachLine doesn't support reversed searching
        // use while... loop to iterate
        lineNo = startLine + 1;
        while (!token && endLine <= --lineNo) {
          cm.getLineHandle(lineNo);
          tokens = cm.getLineTokens(lineNo);
          i_token = 0;
          if (since && lineNo === since.line) {
            for (; i_token < tokens.length; i_token++) {
              if (tokens[i_token].start >= since.ch) {
                break;
              }
            }
          }
          if (i_token >= tokens.length) {
            i_token = tokens.length - 1;
          }
          for (; i_token >= 0; i_token--) {
            var token_tmp = tokens[i_token];
            if (
              typeof condition === "function" ? condition(token_tmp, tokens, i_token) : condition.test(token_tmp.type)
            ) {
              token = token_tmp;
              break; // FOUND token !
            }
          }
        }
      }
      return token ? { lineNo: lineNo, token: token, i_token: i_token } : null;
    };
    /**
     * return a range in which every token has the same style, or meet same condition
     */
    TokenSeeker.prototype.expandRange = function (style, maySpanLines) {
      var cm = this.cm;
      var isStyled;
      if (typeof style === "function") {
        isStyled = style;
      } else {
        if (typeof style === "string") {
          style = new RegExp("(?:^|\\s)" + style + "(?:\\s|$)");
        }
        isStyled = function (token) {
          return token ? style.test(token.type || "") : false;
        };
      }
      var from = {
        lineNo: this.lineNo,
        i_token: this.i_token,
        token: this.lineTokens[this.i_token],
      };
      var to = Object.assign({}, from);
      // find left
      var foundUnstyled = false,
        tokens = this.lineTokens,
        i = this.i_token;
      while (!foundUnstyled) {
        if (i >= tokens.length) {
          i = tokens.length - 1;
        }
        for (; i >= 0; i--) {
          var token = tokens[i];
          if (!isStyled(token, tokens, i)) {
            foundUnstyled = true;
            break;
          } else {
            from.i_token = i;
            from.token = token;
          }
        }
        if (foundUnstyled || !(maySpanLines && from.lineNo > cm.firstLine())) {
          break;
        } // found, or no more lines
        tokens = cm.getLineTokens(--from.lineNo);
        i = tokens.length - 1;
      }
      // find right
      var foundUnstyled = false,
        tokens = this.lineTokens,
        i = this.i_token;
      while (!foundUnstyled) {
        if (i < 0) {
          i = 0;
        }
        for (; i < tokens.length; i++) {
          var token = tokens[i];
          if (!isStyled(token, tokens, i)) {
            foundUnstyled = true;
            break;
          } else {
            to.i_token = i;
            to.token = token;
          }
        }
        if (foundUnstyled || !(maySpanLines && to.lineNo < cm.lastLine())) {
          break;
        } // found, or no more lines
        tokens = cm.getLineTokens(++to.lineNo);
        i = 0;
      }
      return { from: from, to: to };
    };
    TokenSeeker.prototype.setPos = function (line, ch, precise) {
      if (ch === void 0) {
        ch = line;
        line = this.line;
      } else if (typeof line === "number") {
        line = this.cm.getLineHandle(line);
      }
      var sameLine = line === this.line;
      var i_token = 0;
      if (precise || !sameLine) {
        this.line = line;
        if (!line) {
          // 👈 0xGG Team: This is sometimes null?
          return;
        }
        this.lineNo = line.lineNo();
        this.lineTokens = this.cm.getLineTokens(this.lineNo);
      } else {
        // try to speed-up seeking
        i_token = this.i_token;
        var token = this.lineTokens[i_token];
        if (token.start > ch) {
          i_token = 0;
        }
      }
      var tokens = this.lineTokens;
      for (; i_token < tokens.length; i_token++) {
        if (tokens[i_token].end > ch) {
          break;
        } // found
      }
      this.i_token = i_token;
    };
    /** get (current or idx-th) token */
    TokenSeeker.prototype.getToken = function (idx) {
      if (typeof idx !== "number") {
        idx = this.i_token;
      }
      return this.lineTokens[idx];
    };
    /** get (current or idx-th) token type. always return a string */
    TokenSeeker.prototype.getTokenType = function (idx) {
      if (typeof idx !== "number") {
        idx = this.i_token;
      }
      var t = this.lineTokens[idx];
      return (t && t.type) || "";
    };
    return TokenSeeker;
  })();
  /**
   * CodeMirror's `getLineTokens` might merge adjacent chars with same styles,
   * but this one won't.
   *
   * This one will consume more memory.
   *
   * @param {CodeMirror.LineHandle} line
   * @returns {string[]} every char's style
   */
  function getEveryCharToken(line) {
    var ans = new Array(line.text.length);
    var ss = line.styles;
    var i = 0;
    if (ss) {
      // CodeMirror already parsed this line. Use cache
      for (var j = 1; j < ss.length; j += 2) {
        var i_to = ss[j],
          s = ss[j + 1];
        while (i < i_to) {
          ans[i++] = s;
        }
      }
    } else {
      // Emmm... slow method
      var cm = line.parent.cm || line.parent.parent.cm || line.parent.parent.parent.cm;
      var ss_1 = cm.getLineTokens(line.lineNo());
      for (var j = 0; j < ss_1.length; j++) {
        var i_to = ss_1[j].end,
          s = ss_1[j].type;
        while (i < i_to) {
          ans[i++] = s;
        }
      }
    }
    return ans;
  }
  /**
   * return a range in which every char has the given style (aka. token type).
   * assuming char at `pos` already has the style.
   *
   * the result will NOT span lines.
   *
   * @param style aka. token type
   * @see TokenSeeker if you want to span lines
   */
  function expandRange(cm, pos, style) {
    var line = pos.line;
    var from = { line: line, ch: 0 };
    var to = { line: line, ch: pos.ch };
    var styleFn = typeof style === "function" ? style : false;
    var styleRE = !styleFn && new RegExp("(?:^|\\s)" + style + "(?:\\s|$)");
    var tokens = cm.getLineTokens(line);
    var iSince;
    for (iSince = 0; iSince < tokens.length; iSince++) {
      if (tokens[iSince].end >= pos.ch) {
        break;
      }
    }
    if (iSince === tokens.length) {
      return null;
    }
    for (var i = iSince; i < tokens.length; i++) {
      var token = tokens[i];
      if (styleFn ? styleFn(token) : styleRE.test(token.type)) {
        to.ch = token.end;
      } else {
        break;
      }
    }
    for (var i = iSince; i >= 0; i--) {
      var token = tokens[i];
      if (!(styleFn ? styleFn(token) : styleRE.test(token.type))) {
        from.ch = token.end;
        break;
      }
    }
    return { from: from, to: to };
  }
  /**
   * Get ordered range from `CodeMirror.Range`-like object or `[Position, Position]`
   *
   * In an ordered range, The first `Position` must NOT be after the second.
   */
  function orderedRange(range) {
    if ("anchor" in range) {
      range = [range.head, range.anchor];
    }
    if (CodeMirror.cmpPos(range[0], range[1]) > 0) {
      return [range[1], range[0]];
    } else {
      return [range[0], range[1]];
    }
  }
  /**
   * Check if two range has intersection.
   *
   * @param range1 ordered range 1  (start <= end)
   * @param range2 ordered range 2  (start <= end)
   */
  function rangesIntersect(range1, range2) {
    var from1 = range1[0],
      to1 = range1[1];
    var from2 = range2[0],
      to2 = range2[1];
    return !(CodeMirror.cmpPos(to1, from2) < 0 || CodeMirror.cmpPos(from1, to2) > 0);
  }

  /**
   * Post-process CodeMirror-mode-parsed lines, find the ranges
   *
   * for example, a parsed line `[**Hello** World](xxx.txt)` will gives you:
   *
   * 1. link from `[` to `)`
   * 2. bold text from `**` to another `**`
   */
  var LineSpanExtractor = /** @class */ (function () {
    function LineSpanExtractor(cm) {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      var _this = this;
      this.cm = cm;
      this.caches = []; // cache for each lines
      cm.on("change", function (cm, change) {
        var line = change.from.line;
        if (_this.caches.length > line) {
          _this.caches.splice(line);
        }
      });
    }
    LineSpanExtractor.prototype.getTokenTypes = function (token, prevToken) {
      var prevState = prevToken ? prevToken.state : {};
      var state = token.state;
      var styles = " " + token.type + " ";
      var ans = {
        // em
        em: state.em ? 1 /* IS_THIS_TYPE */ : prevState.em ? 2 /* LEAVING_THIS_TYPE */ : 0 /* NOTHING */,
        // strikethrough
        strikethrough: state.strikethrough
          ? 1 /* IS_THIS_TYPE */
          : prevState.strikethrough
          ? 2 /* LEAVING_THIS_TYPE */
          : 0 /* NOTHING */,
        // strong
        strong: state.strong ? 1 /* IS_THIS_TYPE */ : prevState.strong ? 2 /* LEAVING_THIS_TYPE */ : 0 /* NOTHING */,
        // mark
        mark: state.highlight
          ? 1 /* IS_THIS_TYPE */
          : prevState.highlight
          ? 2 /* LEAVING_THIS_TYPE */
          : 0 /* NOTHING */,
        // ins
        ins: state.ins ? 1 /* IS_THIS_TYPE */ : prevState.ins ? 2 /* LEAVING_THIS_TYPE */ : 0 /* NOTHING */,
        // sub
        sub: state.sub ? 1 /* IS_THIS_TYPE */ : prevState.sub ? 2 /* LEAVING_THIS_TYPE */ : 0 /* NOTHING */,
        // sup
        sup: state.sup ? 1 /* IS_THIS_TYPE */ : prevState.sup ? 2 /* LEAVING_THIS_TYPE */ : 0 /* NOTHING */,
        // code
        code: state.code ? 1 /* IS_THIS_TYPE */ : prevState.code ? 2 /* LEAVING_THIS_TYPE */ : 0 /* NOTHING */,
        // obsidian internal link
        internalLink:
          (token && token.type && token.type.contains("formatting-link-start")) ||
          (token && token.type && token.type.contains("hmd-internal-link"))
            ? 1
            : token && token.type && token.type.contains("formatting-link-end")
            ? 2
            : 0,
        // linkText
        linkText: state.linkText
          ? state.hmdLinkType === 3 /* NORMAL */ ||
            state.hmdLinkType === 7 /* BARELINK2 */ ||
            state.hmdLinkType === 4 /* WIKILINK */
            ? 1 /* IS_THIS_TYPE */
            : 0 /* NOTHING */
          : prevState.linkText
          ? 2 /* LEAVING_THIS_TYPE */
          : 0 /* NOTHING */,
        // linkHref
        linkHref:
          state.linkHref && !state.linkText
            ? 1 /* IS_THIS_TYPE */
            : !state.linkHref && !state.linkText && prevState.linkHref && !prevState.linkText
            ? 2 /* LEAVING_THIS_TYPE */
            : 0 /* NOTHING */,
        // task checkbox
        task:
          styles.indexOf(" formatting-task ") !== -1
            ? 1 /* IS_THIS_TYPE */ | 2 /* LEAVING_THIS_TYPE */
            : 0 /* NOTHING */,
        // hashtag
        hashtag: state.hmdHashtag
          ? 1 /* IS_THIS_TYPE */
          : prevState.hmdHashtag
          ? 2 /* LEAVING_THIS_TYPE */
          : 0 /* NOTHING */,
      };
      ans["highlight"] = ans["mark"]; // create a token alias
      return ans;
    };
    /** get spans from a line and update the cache */
    LineSpanExtractor.prototype.extract = function (lineNo, precise) {
      if (!precise) {
        // maybe cache is valid?
        var cc = this.caches[lineNo];
        if (cc) {
          return cc;
        }
      }
      var tokens = this.cm.getLineTokens(lineNo);
      var lineText = this.cm.getLine(lineNo);
      var lineLength = lineText.length;
      var ans = [];
      var unclosed = {};
      for (var i = 0; i < tokens.length; i++) {
        var token = tokens[i];
        var types = this.getTokenTypes(token, tokens[i - 1]);
        for (var type in types) {
          var span = unclosed[type];
          if (types[type] & 1 /* IS_THIS_TYPE */) {
            // style is active
            if (!span) {
              // create a new span if needed
              span = {
                type: type,
                begin: token.start,
                end: lineLength,
                head: token,
                head_i: i,
                tail: tokens[tokens.length - 1],
                tail_i: tokens.length - 1,
                text: lineText.slice(token.start),
              };
              ans.push(span);
              unclosed[type] = span;
            }
          }
          if (types[type] & 2 /* LEAVING_THIS_TYPE */) {
            // a style is exiting
            if (span) {
              // close an unclosed span
              span.tail = token;
              span.tail_i = i;
              span.end = token.end;
              span.text = span.text.slice(0, span.end - span.begin);
              unclosed[type] = null;
            }
          }
        }
      }
      this.caches[lineNo] = ans;
      return ans;
    };
    LineSpanExtractor.prototype.findSpansAt = function (pos) {
      var spans = this.extract(pos.line);
      var ch = pos.ch;
      var ans = [];
      for (var i = 0; i < spans.length; i++) {
        var span = spans[i];
        if (span.begin > ch) {
          break;
        }
        if (ch >= span.begin && span.end >= ch) {
          ans.push(span);
        }
      }
      return ans;
    };
    LineSpanExtractor.prototype.findSpanWithTypeAt = function (pos, type) {
      var spans = this.extract(pos.line);
      var ch = pos.ch;
      for (var i = 0; i < spans.length; i++) {
        var span = spans[i];
        if (span.begin > ch) {
          break;
        }
        if (ch >= span.begin && span.end >= ch && span.type === type) {
          return span;
        }
      }
      return null;
    };
    return LineSpanExtractor;
  })();
  var extractor_symbol = makeSymbol("LineSpanExtractor");
  /**
   * Get a `LineSpanExtractor` to extract spans from CodeMirror parsed lines
   *
   * for example, a parsed line `[**Hello** World](xxx.txt)` will gives you:
   *
   * 1. link from `[` to `)`
   * 2. bold text from `**` to another `**`
   */
  function getLineSpanExtractor(cm) {
    if (extractor_symbol in cm) {
      return cm[extractor_symbol];
    }
    var inst = (cm[extractor_symbol] = new LineSpanExtractor(cm));
    return inst;
  }

  function updateCursorDisplay(cm, skipCacheCleaning) {
    if (!skipCacheCleaning) {
      var lvs = cm.display.view; // LineView s
      for (var lineView of lvs) {
        if (lineView.measure) {
          lineView.measure.cache = {};
          lineView.measure.caches = [{}];
        }
      }
    }
    setTimeout(function () {
      cm.display.input.showSelection(cm.display.input.prepareSelection());
    }, 60); // wait for css style
  }

  /**
   * Utils for HyperMD addons
   *
   * @internal Part of HyperMD core.
   *
   * You shall NOT import this file; please import "core" instead
   */
  var Addon = /** @class */ (function () {
    // eslint-disable-next-line @typescript-eslint/no-empty-function
    function Addon(cm) {}
    return Addon;
  })();
  /** make a Singleton getter */
  function Getter(name, ClassCtor, defaultOption) {
    return function (cm) {
      if (!cm.hmd) {
        cm.hmd = {};
      }
      if (!cm.hmd[name]) {
        var inst = new ClassCtor(cm);
        cm.hmd[name] = inst;
        if (defaultOption) {
          for (var k in defaultOption) {
            inst[k] = defaultOption[k];
          }
        }
        return inst;
      }
      return cm.hmd[name];
    };
  }

  var addon = /*#__PURE__*/ Object.freeze({
    __proto__: null,
    Addon: Addon,
    Getter: Getter,
  });

  Object.defineProperty(exports, "cmpPos", {
    enumerable: true,
    get: function () {
      return CodeMirror.cmpPos;
    },
  });
  exports.Addon = addon;
  exports.FlipFlop = FlipFlop;
  exports.TokenSeeker = TokenSeeker;
  exports.addClass = addClass;
  exports.cm_internal = cm_internal;
  exports.contains = contains;
  exports.debounce = debounce;
  exports.updateCursorDisplay = updateCursorDisplay;
  exports.expandRange = expandRange;
  exports.fromTextArea = fromTextArea;
  exports.getEveryCharToken = getEveryCharToken;
  exports.getLineSpanExtractor = getLineSpanExtractor;
  exports.makeSymbol = makeSymbol;
  exports.normalVisualConfig = normalVisualConfig;
  exports.orderedRange = orderedRange;
  exports.rangesIntersect = rangesIntersect;
  exports.repeat = repeat;
  exports.repeatStr = repeatStr;
  exports.rmClass = rmClass;
  exports.suggestedEditorConfig = suggestedEditorConfig;
  exports.switchToHyperMD = switchToHyperMD;
  exports.switchToNormal = switchToNormal;
  exports.tryToRun = tryToRun;
  exports.visitElements = visitElements;
  exports.watchSize = watchSize;

  Object.defineProperty(exports, "__esModule", { value: true });
});
});

// HyperMD, copyright (c) by laobubu
// Distributed under an MIT license: http://laobubu.net/HyperMD/LICENSE
//
// DESCRIPTION: Click to open links / jump to footnotes / toggle TODOs, and more.
//
// With custom ClickHandler supported
//

(function (mod) {
  //[HyperMD] UMD patched!
  /*plain env*/ mod(null, (HyperMD.Click = HyperMD.Click || {}), CodeMirror, HyperMD);
})(function (require, exports, CodeMirror, core_1) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getAddon =
    exports.Click =
    exports.suggestedOption =
    exports.defaultOption =
    exports.defaultClickHandler =
      void 0;
  //#endregion
  /********************************************************************************** */
  //#region defaultClickHandler
  var defaultClickHandler = function (info, cm) {
    info.text;
      var type = info.type;
      info.url;
      var pos = info.pos;
    if (type === "todo") {
      var _a = core_1.expandRange(cm, pos, "formatting-task"),
        from = _a.from,
        to = _a.to;
      var text_1 = cm.getRange(from, to);
      text_1 = text_1 === "[ ]" ? "[x]" : "[ ]";
      cm.replaceRange(text_1, from, to);
    }
  };
  exports.defaultClickHandler = defaultClickHandler;

  exports.defaultOption = {
    enabled: false,
    handler: null,
  };
  exports.suggestedOption = {
    enabled: true,
  };
  core_1.suggestedEditorConfig.hmdClick = exports.suggestedOption;
  CodeMirror.defineOption("hmdClick", exports.defaultOption, function (cm, newVal) {
    ///// convert newVal's type to `Partial<Options>`, if it is not.
    if (!newVal || typeof newVal === "boolean") {
      newVal = { enabled: !!newVal };
    } else if (typeof newVal === "function") {
      newVal = { enabled: true, handler: newVal };
    }
    ///// apply config and write new values into cm
    var inst = exports.getAddon(cm);
    for (var k in exports.defaultOption) {
      inst[k] = k in newVal ? newVal[k] : exports.defaultOption[k];
    }
  });
  //#endregion
  /********************************************************************************** */
  //#region Addon Class
  var Click = /** @class */ (function () {
    function Click(cm) {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      var _this = this;
      this.cm = cm;
      /** remove modifier className to editor DOM */
      this._mouseMove_keyDetect = function (ev) {
        var el = _this.el;
        var className = el.className,
          newClassName = className;
        var metaClass = "HyperMD-with-meta";
        var altClass = "HyperMD-with-alt";
        var ctrlClass = "HyperMD-with-ctrl";
        if (!ev.altKey && className.indexOf(altClass) >= 0) {
          newClassName = className.replace(altClass, "");
        }
        if (!ev.ctrlKey && className.indexOf(ctrlClass) >= 0) {
          newClassName = className.replace(ctrlClass, "");
        }
        if (!ev.metaKey && className.indexOf(metaClass) >= 0) {
          newClassName = className.replace(metaClass, "");
        }
        if (!ev.altKey && !ev.ctrlKey && !ev.metaKey) {
          _this._KeyDetectorActive = false;
          el.removeEventListener("mousemove", _this._mouseMove_keyDetect, false);
        }
        if (className != newClassName) el.className = newClassName.trim();
      };
      /** add modifier className to editor DOM */
      this._keyDown = function (ev) {
        var kc = ev.keyCode || ev.which;
        var className = "";
        if (kc == 91 || kc == 92 || kc == 224) className = "HyperMD-with-meta";
        if (kc == 17) className = "HyperMD-with-ctrl";
        if (kc == 18) className = "HyperMD-with-alt";
        var el = _this.el;
        if (className && el.className.indexOf(className) == -1) {
          el.className += " " + className;
        }
        if (!_this._KeyDetectorActive) {
          _this._KeyDetectorActive = true;
          _this.el.addEventListener("mousemove", _this._mouseMove_keyDetect, false);
        }
      };
      /**
       * Unbind _mouseUp, then call ClickHandler if mouse not bounce
       */
      this._mouseUp = function (ev) {
        var cinfo = _this._cinfo;
        _this.lineDiv.removeEventListener("mouseup", _this._mouseUp, false);
        if (Math.abs(ev.clientX - cinfo.clientX) > 5 || Math.abs(ev.clientY - cinfo.clientY) > 5) return;
        if (typeof _this.handler === "function" && _this.handler(cinfo, _this.cm) === false) return;
        exports.defaultClickHandler(cinfo, _this.cm);
      };
      /**
       * Try to construct ClickInfo and bind _mouseUp
       */
      this._mouseDown = function (ev) {
        var button = ev.button,
          clientX = ev.clientX,
          clientY = ev.clientY,
          ctrlKey = ev.ctrlKey,
          altKey = ev.altKey,
          shiftKey = ev.shiftKey;
        var cm = _this.cm;
        if (ev.target.tagName === "PRE") return;
        var pos = cm.coordsChar({ left: clientX, top: clientY }, "window");
        var range;
        var token = cm.getTokenAt(pos);
        token.state;
        var styles = " " + token.type + " ";
        var type = null;
        var text, url;
        if (styles.match(/\sformatting-task\s/)) {
          ev.preventDefault(); // prevent the cursor from moving into the checkbox
          // TO-DO checkbox
          type = "todo";
          range = core_1.expandRange(cm, pos, "formatting-task");
          range.to.ch = cm.getLine(pos.line).length;
          text = cm.getRange(range.from, range.to);
          url = null;
        }
        if (type !== null) {
          _this._cinfo = {
            type: type,
            text: text,
            url: url,
            pos: pos,
            button: button,
            clientX: clientX,
            clientY: clientY,
            ctrlKey: ctrlKey,
            altKey: altKey,
            shiftKey: shiftKey,
          };
          _this.lineDiv.addEventListener("mouseup", _this._mouseUp, false);
        }
      };
      this.lineDiv = cm.display.lineDiv;
      var el = (this.el = cm.getWrapperElement());
      new core_1.FlipFlop(
        /* ON  */ function () {
          _this.lineDiv.addEventListener("mousedown", _this._mouseDown, false);
          el.addEventListener("keydown", _this._keyDown, false);
        },
        /* OFF */ function () {
          _this.lineDiv.removeEventListener("mousedown", _this._mouseDown, false);
          el.removeEventListener("keydown", _this._keyDown, false);
        }
      ).bind(this, "enabled", true);
    }
    return Click;
  })();
  exports.Click = Click;
  //#endregion
  /** ADDON GETTER (Singleton Pattern): a editor can have only one Click instance */
  exports.getAddon = core_1.Addon.Getter("Click", Click, exports.defaultOption /** if has options */);
});

// HyperMD, copyright (c) by laobubu
// Distributed under an MIT license: http://laobubu.net/HyperMD/LICENSE
//
// DESCRIPTION: Auto show/hide markdown tokens like `##` or `*`
//
// Only works with `hypermd` mode, require special CSS rules
//

(function (mod) {
  //[HyperMD] UMD patched!
  /*plain env*/ mod(null, {}, CodeMirror, HyperMD, null);
})(function (require, exports, CodeMirror, core_1) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getAddon = exports.HideToken = exports.suggestedOption = exports.defaultOption = void 0;
  //#region Internal Function...
  /** check if has the class and remove it */
  function rmClass(el, className) {
    var c = " " + el.className + " ",
      cnp = " " + className + " ";
    if (c.indexOf(cnp) === -1) return false;
    el.className = c.replace(cnp, "").trim();
    return true;
  }
  /** check if NOT has the class and add it */
  function addClass(el, className) {
    var c = " " + el.className + " ",
      cnp = " " + className + " ";
    if (c.indexOf(cnp) !== -1) return false;
    el.className = el.className + " " + className;
    return true;
  }
  exports.defaultOption = {
    enabled: false,
    line: true,
    // does not yet support ins, sub, sup
    tokenTypes: "em|strong|strikethrough|code|linkText|task|mark|internalLink|highlight".split("|"),
  };
  exports.suggestedOption = {
    enabled: true,
  };
  core_1.suggestedEditorConfig.hmdHideToken = exports.suggestedOption;
  core_1.normalVisualConfig.hmdHideToken = false;
  CodeMirror.defineOption("hmdHideToken", exports.defaultOption, function (cm, newVal) {
    ///// convert newVal's type to `Partial<Options>`, if it is not.
    if (!newVal || typeof newVal === "boolean") {
      newVal = { enabled: !!newVal };
    } else if (typeof newVal === "string") {
      newVal = { enabled: true, tokenTypes: newVal.split("|") };
    } else if (newVal instanceof Array) {
      newVal = { enabled: true, tokenTypes: newVal };
    }
    ///// apply config and write new values into cm
    var inst = exports.getAddon(cm);
    for (var k in exports.defaultOption) {
      inst[k] = k in newVal ? newVal[k] : exports.defaultOption[k];
    }
  });
  //#endregion
  /********************************************************************************** */
  //#region Addon Class
  var hideClassName = "hmd-hidden-token";
  var lineInactiveClassName = "hmd-inactive-line";
  var HideToken = /** @class */ (function () {
    function HideToken(cm) {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      var _this = this;
      this.cm = cm;
      this.styleEl = document.createElement("style");
      /**
       * Remeasure visible columns, update CSS style to make columns aligned
       *
       * (This is a debounced function)
       */
      this.updateStyle = core_1.debounce(function () {
        if (!_this.enabled) return;
        var css;
        if (_this.tokenTypes.indexOf("task") === -1) css = "";
        else
          css = `.hide-tokens.style-check-box .cm-s-obsidian span.cm-formatting-task {
          white-space: pre;
          display: inline-block;
          height: 1em;
          line-height: 1em;
          min-width: 1em;
          text-align: center;
          vertical-align: middle;
          background-repeat: no-repeat;
          background-position: center 0;
          cursor: pointer;
          color: rgba(0, 0, 0, 0.2);
          background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAwCAMAAAA8VkqRAAAAclBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACa4vOeAAAAJXRSTlMADcjpDswcLZOzsvOYBvWdbtvTX0D69+ORa1dRJCDtuaF7ZDkoQyuUXgAAAMhJREFUOMvt0reywjAUhOFjKxmcrgMZboL//V8Rm6GwkNUx0LClvhkVZ1fEZoqHqMwO7wuUSb0YxcJKxtLpxIt2SzJRykkQp5RgdAjaIKRJCEn6gWdA9OzRoqLVRscQnc9bdtXX/eyurOF7N3erLVDPwCGHxoVwamH1LwGUBfBbhrCvoLlMitL9DY8trLtJg7qoCj18VAN1OYE/YJBuDe1RJtBVo5wbqPb+GL5yWG1GLX0YZYw5iQ93yQ/yAHfZzu5qt/mxr97VFS15JGSVM0C6AAAAAElFTkSuQmCC");
          background-size: 1em;
        }
        .theme-dark.hide-tokens.style-check-box .cm-s-obsidian span.cm-formatting-task {
          filter: invert(1);
        }
        .hide-tokens.style-check-box .cm-s-obsidian span.cm-formatting-task.cm-property {
          background-position-y: -1em;
        }`;
        _this.styleEl.textContent = _this._lastCSS = css;
      }, 100);
      this.renderLineHandler = function (cm, line, el) {
        // TODO: if we procLine now, we can only get the outdated lineView, lineViewMeasure and lineViewMap. Calling procLine will be wasteful!
        _this.procLine(line, el);
      };
      this.cursorActivityHandler = function (/*doc: CodeMirror.Doc*/) {
        _this.update();
      };
      this.update = core_1.debounce(function () {
        return _this.updateImmediately();
      }, 100);
      /** Current user's selections, in each line */
      this._rangesInLine = {};
      new core_1.FlipFlop(
        /* ON  */ function () {
          cm.on("cursorActivity", _this.cursorActivityHandler);
          cm.on("renderLine", _this.renderLineHandler);
          cm.on("update", _this.updateStyle);
          // cm.on("update", _this.update);
          _this.update();
          cm.refresh();
          document.head.appendChild(_this.styleEl);
        },
        /* OFF */ function () {
          cm.off("cursorActivity", _this.cursorActivityHandler);
          cm.off("renderLine", _this.renderLineHandler);
          cm.off("update", _this.updateStyle);
          // cm.off("update", _this.update);
          _this.update.stop();
          document.head.removeChild(_this.styleEl);
          cm.refresh();
        }
      ).bind(this, "enabled", true);
    }
    /**
     * hide/show <span>s in one line, based on `this._rangesInLine`
     * @returns line changed or not
     */
    HideToken.prototype.procLine = function (line, pre) {
      var cm = this.cm;
      var lineNo = typeof line === "number" ? line : line.lineNo();
      if (typeof line === "number") line = cm.getLineHandle(line);
      var rangesInLine = this._rangesInLine[lineNo] || [];
      var lv = core_1.cm_internal.findViewForLine(cm, lineNo);
      if (!lv || lv.hidden || !lv.measure) return false;
      if (!pre) pre = lv.text;
      if (!pre) return false;
      var mapInfo = core_1.cm_internal.mapFromLineView(lv, line, lineNo);
      if (!mapInfo) return;
      var map = mapInfo.map;
      var nodeCount = map.length / 3;
      var changed = false;
      // change line status
      if (rangesInLine.length === 0) {
        // inactiveLine
        if (addClass(pre, lineInactiveClassName)) changed = true;
      } else {
        // activeLine
        if (rmClass(pre, lineInactiveClassName)) changed = true;
      }
      // show or hide tokens
      /**
       * @returns if there are Span Nodes changed
       */
      function changeVisibilityForSpan(span, shallHideTokens, iNodeHint) {
        var changed = false;
        iNodeHint = iNodeHint || 0;
        // iterate the map
        for (var i = iNodeHint; i < nodeCount; i++) {
          var begin = map[i * 3];
            map[i * 3 + 1];
          var domNode = map[i * 3 + 2];
          if (begin === span.head.start) {
            // find the leading token!
            if (/formatting-/.test(span.head.type) && domNode.nodeType === Node.TEXT_NODE) {
              // good. this token can be changed
              var domParent = domNode.parentElement;
              if (shallHideTokens ? addClass(domParent, hideClassName) : rmClass(domParent, hideClassName)) {
                changed = true;
              }
              if (domParent && domParent.classList && domParent.classList.contains("cm-formatting-task")) {
                if (!domParent.dataset.hasOwnProperty("task")) {
                  domParent.dataset.task = domNode.textContent.substring(1, 2);
                  changed = true;
                }
              }
              if (
                domParent.nextElementSibling &&
                domParent.nextElementSibling.classList.contains("cm-internal-link-url")
              ) {
                if (
                  shallHideTokens
                    ? addClass(domParent.nextElementSibling, hideClassName)
                    : rmClass(domParent.nextElementSibling, hideClassName)
                ) {
                  changed = true;
                }
              }
              if (
                domParent.nextElementSibling &&
                domParent.nextElementSibling.nextElementSibling &&
                domParent.nextElementSibling.nextElementSibling.classList.contains("cm-internal-link-ref")
              ) {
                if (
                  shallHideTokens
                    ? addClass(domParent.nextElementSibling.nextElementSibling, hideClassName)
                    : rmClass(domParent.nextElementSibling.nextElementSibling, hideClassName)
                ) {
                  changed = true;
                }
              }
            }
            //FIXME: if leading formatting token is separated into two, the latter will not be hidden/shown!
            // search for the tailing token
            if (span.tail && /formatting-/.test(span.tail.type)) {
              for (var j = i + 1; j < nodeCount; j++) {
                var begin_1 = map[j * 3];
                  map[j * 3 + 1];
                var domNode_1 = map[j * 3 + 2];
                if (begin_1 == span.tail.start) {
                  // if (DEBUG) console.log("TAIL DOM CHANGED", domNode)
                  if (domNode_1.nodeType === Node.TEXT_NODE) {
                    // good. this token can be changed
                    var domParent = domNode_1.parentElement;
                    if (shallHideTokens ? addClass(domParent, hideClassName) : rmClass(domParent, hideClassName)) {
                      changed = true;
                    }
                  }
                }
                if (begin_1 >= span.tail.end) break;
              }
            }
          }
          // whoops, next time we can start searching since here
          // return the hint value
          if (begin >= span.begin) break;
        }
        return changed;
      }
      var spans = core_1.getLineSpanExtractor(cm).extract(lineNo);
      // console.log('spans: ', spans)
      var iNodeHint = 0;
      for (var iSpan = 0; iSpan < spans.length; iSpan++) {
        var span = spans[iSpan];

        if (this.tokenTypes.indexOf(span.type) === -1) {
          continue; // not-interested span type
        }
        /* TODO: Use AST, instead of crafted Position */
        var spanRange = [
          { line: lineNo, ch: span.begin },
          { line: lineNo, ch: span.end },
        ];
        /* TODO: If use AST, compute `spanBeginCharInCurrentLine` in another way */
        var spanBeginCharInCurrentLine = span.begin;
        while (iNodeHint < nodeCount && map[iNodeHint * 3 + 1] < spanBeginCharInCurrentLine) iNodeHint++;
        var shallHideTokens = true;
        for (var iLineRange = 0; iLineRange < rangesInLine.length; iLineRange++) {
          var userRange = rangesInLine[iLineRange];
          if (core_1.rangesIntersect(spanRange, userRange)) {
            shallHideTokens = false;
            break;
          }
        }
        // console.log('changeVis', span, shallHideTokens)
        if (changeVisibilityForSpan(span, shallHideTokens, iNodeHint)) {
          changed = true;
        }
      }
      // finally clean the cache (if needed) and report the result
      if (changed) {
        // clean CodeMirror measure cache
        delete lv.measure.heights;
        lv.measure.cache = {};
      }
      return changed;
    };
    HideToken.prototype.updateImmediately = function () {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      var _this = this;
      this.update.stop();
      var cm = this.cm;
      var selections = cm.listSelections();
      var caretAtLines = {};
      var activedLines = {};
      cm.state.refreshCaretLine = null;
      var lastActivedLines = this._rangesInLine;
      for (var _i = 0, selections_1 = selections; _i < selections_1.length; _i++) {
        var selection = selections_1[_i];
        var oRange = core_1.orderedRange(selection);
        var line0 = oRange[0].line,
          line1 = oRange[1].line;
        caretAtLines[line0] = caretAtLines[line1] = true;
        for (var line = line0; line <= line1; line++) {
          if (!activedLines[line]) activedLines[line] = [oRange];
          else activedLines[line].push(oRange);
        }
      }
      this._rangesInLine = activedLines;
      cm.operation(function () {
        // adding "inactive" class
        for (var line in lastActivedLines) {
          if (activedLines[line]) {
            continue; // line is still active. do nothing
          }
          _this.procLine(~~line); // or, try adding "inactive" class to the <pre>s
        }
        var caretLineChanged = false;
        for (var line in activedLines) {
          var lineChanged = _this.procLine(~~line);
          if (!lineChanged) {
            // always force a cursor placement refresh if the cursor changed lines
            lastActivedLines.hasOwnProperty(line) ? (lineChanged = false) : (lineChanged = true);
          }
          if (lineChanged && caretAtLines[line]) caretLineChanged = true;
        }
        // refresh cursor position if needed
        if (caretLineChanged) {
          cm.getLineHandle(line);
          core_1.updateCursorDisplay(cm, false);
        }
      });
    };
    return HideToken;
  })();
  exports.HideToken = HideToken;
  //#endregion
  /** ADDON GETTER (Singleton Pattern): a editor can have only one HideToken instance */
  exports.getAddon = core_1.Addon.Getter("HideToken", HideToken, exports.defaultOption /** if has options */);
});

createCommonjsModule(function (module) {
// CodeMirror, copyright (c) by laobubu
// Distributed under an MIT license: http://codemirror.net/LICENSE
//
// This is a patch to markdown mode. Supports lots of new features
//
var __assign =
  (commonjsGlobal && commonjsGlobal.__assign) ||
  function () {
    __assign =
      Object.assign ||
      function (t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
          s = arguments[i];
          for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
        }
        return t;
      };
    return __assign.apply(this, arguments);
  };

(function (mod) {
  //[HyperMD] UMD patched!
  /*plain env*/ mod(null, (HyperMD.Mode = HyperMD.Mode || {}), CodeMirror);
})(function (require, exports, CodeMirror) {
  var _a;
  Object.defineProperty(exports, "__esModule", { value: true });
  /**
   * Markdown Extension Tokens
   *
   * - `$` Maybe a LaTeX
   * - `|` Maybe a Table Col Separator
   */
  var tokenBreakRE = /[^\\][$|]/;
  var listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/;
  var urlRE =
    /^((?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i; // from CodeMirror/mode/gfm
  var emailRE =
    /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  var url2RE = /^\.{0,2}\/[^\>\s]+/;
  var SimpleTableRE = /^\s*[^\|].*?\|.*[^|]\s*$/;
  var SimpleTableLooseRE = /^\s*[^\|].*\|/; // unfinished | row
  var NormalTableRE = /^\s*\|[^\|]+\|(.+\|)?\s*$/;
  var NormalTableLooseRE = /^\s*\|/; // | unfinished row
  var linkStyle =
    ((_a = {}),
    (_a[1 /* BARELINK */] = "hmd-barelink"),
    (_a[7 /* BARELINK2 */] = "hmd-barelink2"),
    (_a[4 /* WIKILINK */] = "hmd-internal-link"),
    (_a[2 /* FOOTREF */] = "hmd-barelink footref"),
    (_a[5 /* FOOTNOTE */] = "hmd-footnote line-HyperMD-footnote"),
    (_a[8 /* FOOTREF2 */] = "hmd-footref2"),
    (_a[9 /* FOOTREF2 */] = "hmd-embed hmd-internal-link"),
    _a);
  function resetTable(state) {
    state.hmdTable = 0 /* NONE */;
    state.hmdTableColumns = [];
    state.hmdTableID = null;
    state.hmdTableCol = state.hmdTableRow = 0;
  }
  var listInQuoteRE = /^\s+((\d+[).]|[-*+])\s+)?/;
  var defaultTokenTypeOverrides = {
    hr: "line-HyperMD-hr line-background-HyperMD-hr-bg hr",
    // HyperMD needs to know the level of header/indent. using tokenTypeOverrides is not enough
    // header: "line-HyperMD-header header",
    // quote: "line-HyperMD-quote quote",
    // Note: there are some list related process below
    list1: "list-1",
    list2: "list-2",
    list3: "list-3",
    code: "inline-code",
    hashtag: "hashtag meta",
  };
  CodeMirror.defineMode(
    "openmd",
    function (cmCfg, modeCfgUser) {
      var modeCfg = {
        front_matter: true,
        math: true,
        table: true,
        toc: true,
        orgModeMarkup: true,
        hashtag: true,
        fencedCodeBlockHighlighting: true,
        name: "markdown",
        highlightFormatting: true,
        taskLists: true,
        strikethrough: true,
        emoji: false,
        highlight: true,
        tokenTypeOverrides: defaultTokenTypeOverrides,
      };
      Object.assign(modeCfg, modeCfgUser);
      if (modeCfg.tokenTypeOverrides !== defaultTokenTypeOverrides) {
        modeCfg.tokenTypeOverrides = Object.assign({}, defaultTokenTypeOverrides, modeCfg.tokenTypeOverrides);
      }
      modeCfg["name"] = "markdown";
      /** functions from CodeMirror Markdown mode closure. Only for status checking */
      var rawClosure = {
        htmlBlock: null,
      };
      var rawMode = CodeMirror.getMode(cmCfg, modeCfg);
      var newMode = __assign({}, rawMode);
      newMode.startState = function () {
        var ans = rawMode.startState();
        resetTable(ans);
        ans.hmdOverride = null;
        ans.hmdInnerExitChecker = null;
        ans.hmdInnerMode = null;
        ans.hmdLinkType = 0 /* NONE */;
        ans.hmdNextMaybe = modeCfg.front_matter ? 1 /* FRONT_MATTER */ : 0 /* NONE */;
        ans.hmdNextState = null;
        ans.hmdNextStyle = null;
        ans.hmdNextPos = null;
        ans.templater = 0;
        ans.hmdImage = 0;
        ans.hmdHashtag = 0 /* NONE */;
        return ans;
      };
      newMode.copyState = function (s) {
        var ans = rawMode.copyState(s);
        var keys = [
          "hmdLinkType",
          "hmdNextMaybe",
          "hmdTable",
          "hmdTableID",
          "hmdTableCol",
          "hmdTableRow",
          "hmdOverride",
          "hmdInnerMode",
          "hmdInnerStyle",
          "hmdInnerExitChecker",
          "hmdNextPos",
          "hmdNextState",
          "hmdNextStyle",
          "hmdHashtag",
          "hmdImage",
          "templater",
          "comment",
        ];
        for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
          var key = keys_1[_i];
          ans[key] = s[key];
        }
        ans.hmdTableColumns = s.hmdTableColumns.slice(0);
        if (s.hmdInnerMode) ans.hmdInnerState = CodeMirror.copyState(s.hmdInnerMode, s.hmdInnerState);
        return ans;
      };
      newMode.blankLine = function (state) {
        var ans;
        var innerMode = state.hmdInnerMode;
        if (innerMode) {
          if (innerMode.blankLine) ans = innerMode.blankLine(state.hmdInnerState);
        } else {
          ans = rawMode.blankLine(state);
        }
        if (!ans) ans = "";
        if (state.code === -1) {
          ans += " line-HyperMD-codeblock line-background-HyperMD-codeblock-bg";
        }
        if (state.templater === 1) {
          ans += " line-background-templater-command-bg line-HyperMD-codeblock line-background-HyperMD-codeblock-bg";
        }
        resetTable(state);
        return ans.trim() || null;
      };
      newMode.indent = function (state, textAfter) {
        var mode = state.hmdInnerMode || rawMode;
        var f = mode.indent;
        if (typeof f === "function") return f.apply(mode, arguments);
        return CodeMirror.Pass;
      };
      newMode.innerMode = function (state) {
        if (state.hmdInnerMode) return { mode: state.hmdInnerMode, state: state.hmdInnerState };
        return rawMode.innerMode(state);
      };
      newMode.token = function (stream, state) {
        if (state.hmdOverride) return state.hmdOverride(stream, state);
        {
          // Only appears once for each Doc
          if (/^<%(.){0,1}$/.test(stream.string) && stream.peek() === "<") {
            state.templater = 1;
            stream.match(/^<%[^\s]*/, true);
            return "templater-opening-tag templater-command formatting line-HyperMD-codeblock formatting-templater line-background-HyperMD-codeblock-bg line-background-HyperMD-codeblock-begin-bg line-background-templater-start line-background-templater-command-bg";
          }
          if (state.templater === 1) {
            return enterMode(stream, state, "javascript", {
              style:
                "templater-command line-HyperMD-codeblock line-background-HyperMD-codeblock-bg line-background-templater-command-bg",
              skipFirstToken: false,
              fallbackMode: function () {
                return createDummyMode("<%");
              },
              exitChecker: function (stream, state) {
                if (/%>$/.test(stream.string)) {
                  // found the endline of front_matter
                  state.templater = -1 /* NONE */;
                  stream.backUp(1);
                  return { endPos: 0 };
                } else {
                  return null;
                }
              },
            });
          }
          if (state.templater === -1) {
            state.templater = 0 /* NONE */;
            stream.skipToEnd();
            return "templater-closing-tag formatting formatting-templater templater-command line-HyperMD-codeblock line-background-HyperMD-codeblock-bg line-background-HyperMD-codeblock-end-bg line-background-templater-end line-background-templater-command-bg";
          } else {
            state.templater = 0 /* NONE */;
          }
        }
        if (state.hmdNextMaybe === 1 /* FRONT_MATTER */) {
          // Only appears once for each Doc
          if (stream.string === "---") {
            state.hmdNextMaybe = 2 /* FRONT_MATTER_END */;
            return enterMode(stream, state, "yaml", {
              style: "hmd-frontmatter",
              fallbackMode: function () {
                return createDummyMode("---");
              },
              exitChecker: function (stream, state) {
                if (stream.string === "---") {
                  // found the endline of front_matter
                  state.hmdNextMaybe = 0 /* NONE */;
                  return { endPos: 3 };
                } else {
                  return null;
                }
              },
            });
          } else {
            state.hmdNextMaybe = 0 /* NONE */;
          }
        }
        var inInternalLink;
        var wasInHTML = state.f === rawClosure.htmlBlock;
        var wasInCodeFence = state.code === -1;
        var bol = stream.start === 0;
        var wasLinkText = state.linkText;
        var wasLinkHref = state.linkHref;
        var inMarkdown = !(wasInCodeFence || wasInHTML);
        var inMarkdownInline = inMarkdown && !(state.code || state.indentedCode || state.linkHref);
        var ans = "";
        var tmp;
        var findComment = null;
        var tmpPOS = -1;
        if (inMarkdown) {
          // now implement some extra features that require higher priority than CodeMirror's markdown
          // add support for headers in list items
          if (/#/.test(stream.peek())) {
            if (state.list && /- (#+)(?: |$)/.test(stream.string)) {
              state.list = false;
              var level = stream.match(/(#+)(?: |$)/, true);
              var depth = level && level.length > 0 ? level[1].length : 0;
              state.header = depth;
              return (ans += "formatting formatting-header formatting-header-" + depth + " header header-" + depth);
            }
          }
          // add support for templater code block syntax
          if ((tmp = stream.match(/^<%/, true))) {
            var endTag_1 = "%>";
            if (stream.string.slice(stream.pos).match(/%>/)) {
              ans = enterMode(stream, state, "javascript", {
                style: "templater-command",
                skipFirstToken: false,
                fallbackMode: function () {
                  return createDummyMode(endTag_1);
                },
                exitChecker: function (stream, state) {
                  const retInfo = {};
                  const endTag = "%>";
                  retInfo.style = "templater-closing-tag formatting formatting-templater line-templater-inline";
                  if (stream.string.substr(stream.start, endTag.length) === endTag) {
                    retInfo.endPos = stream.start + endTag.length;
                    return retInfo;
                  }
                  return null;
                },
              });
              ans += " templater-opening-tag templater-command formatting formatting-templater";
              return ans;
            }
          }
          //#region Math
          if (modeCfg.math && inMarkdownInline && (tmp = stream.match(/^\${1,2}/, false))) {
            var endTag_1 = tmp[0];
            var mathLevel = endTag_1.length;
            if (mathLevel === 2 || stream.string.slice(stream.pos).match(/[^\\\s-]\$(?![0-9])/)) {
              // $$ may span lines, $ must be paired
              var texMode = CodeMirror.getMode(cmCfg, {
                name: "stex",
              });
              var noTexMode = texMode["name"] !== "stex";
              var block = mathLevel > 1 ? "math-block" : "";
              ans += enterMode(stream, state, texMode, {
                style: "math",
                skipFirstToken: noTexMode,
                fallbackMode: function () {
                  return createDummyMode(endTag_1);
                },
                exitChecker: createSimpleInnerModeExitChecker(endTag_1, {
                  style: `formatting formatting-math formatting-math-end ${block} math-` + mathLevel,
                }),
              });
              if (noTexMode) stream.pos += tmp[0].length;
              ans += ` formatting formatting-math formatting-math-begin ${block} math-` + mathLevel;
              return ans;
            }
          }
          //#endregion
          //#region [OrgMode] markup
          if (bol && modeCfg.orgModeMarkup && (tmp = stream.match(/^\#\+(\w+\:?)\s*/))) {
            // Support #+TITLE: This is the title of the document
            if (!stream.eol()) {
              state.hmdOverride = function (stream, state) {
                stream.skipToEnd();
                state.hmdOverride = null;
                return "string hmd-orgmode-markup";
              };
            }
            return "meta formatting-hmd-orgmode-markup hmd-orgmode-markup line-HyperMD-orgmode-markup";
          }
          //#endregion
          //#region [TOC] in a single line
          if (bol && modeCfg.toc && stream.match(/^\[TOCM?\]\s*$/i)) {
            return "meta line-HyperMD-toc hmd-toc";
          }
          //#endregion
          //#region Extra markdown inline extenson
          if (inMarkdownInline) {
            // transform unformatted URL into link
            if (!state.hmdLinkType && (stream.match(urlRE) || stream.match(emailRE))) {
              return "url";
            }
            if (state.internalLink) {
              state.hmdLinkType = 4 /* INTERNAL */;
              state.internalLink = false;
            } else if (state.internalEmbed) {
              state.hmdLinkType = 9 /* EMBED */;
              state.internalEmbed = false;
            } else if ((inInternalLink = stream.match(/^(!?\[\[).+\]\]/, false))) {
              "!" === inInternalLink[1].charAt(0)
                ? ((ans += " formatting-link formatting-link-start formatting-embed"), (state.internalEmbed = true))
                : ((ans += " formatting-link formatting-link-start"), (state.internalLink = true)),
                (tmpPOS = stream.pos + inInternalLink[1].length);
            } else {
              (state.hmdLinkType !== 4 /* INTERNAL */ && state.hmdLinkType !== 9) /* EMBED */ ||
                !stream.match(/^\]\]/, false) ||
                ((state.hmdLinkType = 0) /* NONE */,
                (state.linkText = false),
                (tmpPOS = stream.pos + 2),
                (ans += " formatting-link formatting-link-end"));
            }
            // block refs
            if (stream.match(/^\^([a-zA-Z0-9\-]+)$/)) {
              ans += " blockid";
            }
            // handle comments
            let _pos = stream.pos;
            findComment = function (e) {
              var _match = stream.string.slice(_pos, e).match(/^(.+?)%%/);
              return _match ? _pos + _match[1].length : e;
            };
            if (state.comment) {
              ans += " comment";
              if (stream.match(/^%%/, false)) {
                state.comment = false;
                tmpPOS = stream.pos + 2;
              }
            } else {
              if (stream.match(/^%%/, false)) {
                state.comment = true;
                ans += " comment";
                tmpPOS = stream.pos + 2;
              }
            }
          }
          //#endregion
        }
        // now enter markdown
        if (state.hmdNextState) {
          stream.pos = state.hmdNextPos;
          ans += " " + (state.hmdNextStyle || "");
          Object.assign(state, state.hmdNextState);
          state.hmdNextState = null;
          state.hmdNextStyle = null;
          state.hmdNextPos = null;
        } else {
          ans += " " + (rawMode.token(stream, state) || "");
        }
        if (tmpPOS !== -1) {
          stream.pos = tmpPOS;
        }
        if (findComment) {
          stream.pos = findComment(stream.pos);
        }
        // add extra styles
        if (state.hmdHashtag !== 0 /* NONE */) {
          ans += " " + modeCfg.tokenTypeOverrides.hashtag;
        }
        /** Try to capture some internal functions from CodeMirror Markdown mode closure! */
        if (!rawClosure.htmlBlock && state.htmlState) rawClosure.htmlBlock = state.f;
        var inHTML = state.f === rawClosure.htmlBlock;
        var inCodeFence = state.code === -1;
        inMarkdown = inMarkdown && !(inHTML || inCodeFence);
        inMarkdownInline = inMarkdownInline && inMarkdown && !(state.code || state.indentedCode || state.linkHref);
        // If find a markdown extension token (which is not escaped),
        // break current parsed string into two parts and the first char of next part is the markdown extension token
        if (inMarkdownInline && (tmp = stream.current().match(tokenBreakRE))) {
          stream.pos = stream.start + tmp.index + 1; // rewind
        }
        var current = stream.current();
        if (inHTML != wasInHTML) {
          if (inHTML) {
            ans += " hmd-html-begin";
            rawClosure.htmlBlock = state.f;
          } else {
            ans += " hmd-html-end";
          }
        }
        if (wasInCodeFence || inCodeFence) {
          if (!state.localMode || !wasInCodeFence) ans = ans.replace("inline-code", "");
          ans += " line-HyperMD-codeblock line-background-HyperMD-codeblock-bg hmd-codeblock";
          if (inCodeFence !== wasInCodeFence) {
            if (!inCodeFence) ans += " line-HyperMD-codeblock-end line-background-HyperMD-codeblock-end-bg";
            else if (!wasInCodeFence) ans += " line-HyperMD-codeblock-begin line-background-HyperMD-codeblock-begin-bg";
          }
        }
        if (inMarkdown) {
          var tableType = state.hmdTable;
          //#region [Table] Reset
          if (bol && tableType) {
            var rowRE = tableType == 1 /* SIMPLE */ ? SimpleTableLooseRE : NormalTableLooseRE;
            if (rowRE.test(stream.string)) {
              // still in table
              state.hmdTableCol = 0;
              state.hmdTableRow++;
            } else {
              // end of a table
              resetTable(state);
            }
          }
          //#endregion
          //#region Header, indentedCode, quote

          if (bol && state.header) {
            if (/^(?:---+|===+)\s*$/.test(stream.string) && state.prevLine && state.prevLine.header) {
              ans += " line-HyperMD-header-line line-HyperMD-header-line-" + state.header;
            } else {
              ans += " line-HyperMD-header line-HyperMD-header-" + state.header;
            }
          }
          if (state.indentedCode) {
            ans += " hmd-indented-code";
          }
          if (state.quote) {
            // mess up as less as possible
            if (stream.eol()) {
              ans += " line-HyperMD-quote line-HyperMD-quote-" + state.quote;
              if (!/^ {0,3}\>/.test(stream.string)) ans += " line-HyperMD-quote-lazy"; // ">" is omitted
            }
            if (bol && (tmp = current.match(/^\s+/))) {
              stream.pos = tmp[0].length; // rewind
              ans += " hmd-indent-in-quote";
              return ans.trim();
            }
            // make indentation (and potential list bullet) monospaced
            if (/^>\s+$/.test(current) && stream.peek() != ">") {
              stream.pos = stream.start + 1; // rewind!
              current = ">";
              state.hmdOverride = function (stream, state) {
                stream.match(listInQuoteRE);
                state.hmdOverride = null;
                return "hmd-indent-in-quote line-HyperMD-quote line-HyperMD-quote-" + state.quote;
              };
            }
          }
          //#endregion
          //#region List
          var maxNonCodeIndentation = (state.listStack[state.listStack.length - 1] || 0) + 3;
          var tokenIsIndent =
            bol && /^\s+$/.test(current) && (state.list !== false || stream.indentation() <= maxNonCodeIndentation);
          var tokenIsListBullet = state.list && /formatting-list/.test(ans);
          if (tokenIsListBullet || (tokenIsIndent && (state.list !== false || stream.match(listRE, false)))) {
            var listLevel = (state.listStack && state.listStack.length) || 0;
            if (tokenIsIndent) {
              if (stream.match(listRE, false)) {
                // next token is 1. 2. or bullet
                if (state.list === false) listLevel++;
              } else {
                while (listLevel > 0 && stream.pos < state.listStack[listLevel - 1]) {
                  listLevel--; // find the real indent level
                }
                if (!listLevel) {
                  // not even a list
                  return ans.trim() || null;
                }
                ans += " line-HyperMD-list-line-nobullet line-HyperMD-list-line line-HyperMD-list-line-" + listLevel;
              }
              ans += " hmd-list-indent hmd-list-indent-" + listLevel;
            } else if (tokenIsListBullet) {
              // no space before bullet!
              ans += " line-HyperMD-list-line line-HyperMD-list-line-" + listLevel;
            }
          }
          //#endregion

          //#region Link, BareLink, Footnote, Wikilink etc
          if (stream.current() === "[" && stream.eat("[")) {
            current = "[[";
            // ans += " formatting-link";
          }
          if (stream.current() === "]" && stream.eat("]")) {
            current = "]]";
            // ans += " formatting-link";
          }
          if (wasLinkText !== state.linkText) {
            if (!wasLinkText) {
              if (current === "[[" || current === "]]") {
                // Check wiki link
                state.hmdLinkType = 4 /* WIKILINK */;
              } else {
                // entering a link
                tmp = stream.match(/^([^\]]+)\](\(| ?\[|\:)?/, false);
                if (!tmp) {
                  // maybe met a line-break in link text?
                  state.hmdLinkType = 1 /* BARELINK */;
                } else if (!tmp[2]) {
                  // barelink
                  if (tmp[1].charAt(0) === "^") {
                    state.hmdLinkType = 2 /* FOOTREF */;
                  } else {
                    state.hmdLinkType = 1 /* BARELINK */;
                  }
                } else if (tmp[2] === ":") {
                  // footnote
                  state.hmdLinkType = 5 /* FOOTNOTE */;
                } else if (
                  (tmp[2] === "[" || tmp[2] === " [") &&
                  stream.string.charAt(stream.pos + tmp[0].length) === "]"
                ) {
                  // [barelink2][]
                  state.hmdLinkType = 7 /* BARELINK2 */;
                } else {
                  state.hmdLinkType = 3 /* NORMAL */;
                }
              }
            } else {
              // leaving a link
              if (state.hmdLinkType in linkStyle) {
                if (current !== "[[" && current !== "]]") {
                  ans += " " + linkStyle[state.hmdLinkType];
                }
              }
              if (state.hmdLinkType === 5 /* FOOTNOTE */) {
                state.hmdLinkType = 6 /* MAYBE_FOOTNOTE_URL */;
              } else {
                state.hmdLinkType = 0 /* NONE */;
              }
            }
          }
          if (wasLinkHref !== state.linkHref) {
            if (!wasLinkHref) {
              // [link][doc] the [doc] part
              if (current === "[" && stream.peek() !== "]") {
                state.hmdLinkType = 8 /* FOOTREF2 */;
              }
            } else if (state.hmdLinkType) {
              // leaving a Href
              ans += " " + linkStyle[state.hmdLinkType];
              state.hmdLinkType = 0 /* NONE */;
            }
          }
          if (state.hmdLinkType !== 0 /* NONE */) {
            if (state.hmdLinkType in linkStyle) {
              if (current !== "[[" && current !== "]]") {
                ans += " " + linkStyle[state.hmdLinkType];
              }
            }
            if (
              (state.hmdLinkType === 4 || state.hmdLinkType === 9) /* WIKILINK */ &&
              current !== "[[" &&
              current !== "]]"
            ) {
              var eaten = false;
              // break out of link if templater syntax found
              if (stream.match(/^<%/, false)) {
                return;
              }
              while (stream.eat(/[^<|\]#]/)) {
                eaten = true;
              }
              if (stream.eat("%")) {
                stream.backUp(2);
                return;
              }
              if (eaten || (stream.peek() || "").match(/[\|\]#]/)) {
                if (stream.peek() === "#") {
                  // link has a ref
                  if (stream.match(/[^|\]]+\|[^\]]+\]\]/, false)) {
                    // link has an alias
                    ans += " " + "internal-link-url";
                  } else {
                    // no alias
                    ans += " " + "internal-link-name";
                  }
                } else if (stream.current().startsWith("#")) {
                  stream.eat("|");
                  ans += " " + "internal-link-ref";
                } else if (stream.peek() === "|") {
                  stream.eat("|");
                  // console.log(current);
                  if (/\.(jpe?g|png|gif|svg|bmp)/.test(stream.current())) {
                    state.hmdImage = 1;
                    ans += " " + "internal-link-name hmd-image";
                  } else {
                    ans += " " + "internal-link-url";
                  }
                } else if (!stream.current().startsWith("#")) {
                  if (state.hmdImage === 1) {
                    state.hmdImage = 0;
                    ans += " " + "internal-link-url";
                  } else {
                    ans += " " + "internal-link-name";
                  }
                } else ;
                current = stream.current();
              }
            }
            if (state.hmdLinkType === 6 /* MAYBE_FOOTNOTE_URL */) {
              if (!/^(?:\]\:)?\s*$/.test(current)) {
                // not spaces
                if (urlRE.test(current) || url2RE.test(current)) ans += " hmd-footnote-url";
                else ans = ans.replace("string url", "");
                state.hmdLinkType = 0 /* NONE */; // since then, can't be url anymore
              }
            }
          }
          //#endregion
          //#region start of an escaped char
          if (/formatting-escape/.test(ans) && current.length > 1) {
            // CodeMirror merge backslash and escaped char into one token, which is not good
            // Use hmdOverride to separate them
            var escapedLength_1 = current.length - 1;
            var escapedCharStyle_1 = ans.replace("formatting-escape", "escape") + " hmd-escape-char";
            state.hmdOverride = function (stream, state) {
              // one-time token() func
              stream.pos += escapedLength_1;
              state.hmdOverride = null;
              return escapedCharStyle_1.trim();
            };
            ans += " hmd-escape-backslash";
            stream.pos -= escapedLength_1;
            return ans;
          }
          //#endregion
          //#region [Table] Creating Table and style Table Separators
          if (!ans.trim() && modeCfg.table) {
            // string is unformatted
            var isTableSep = false;
            if (current.charAt(0) === "|") {
              // is "|xxxxxx", separate "|" and "xxxxxx"
              stream.pos = stream.start + 1; // rewind to end of "|"
              current = "|";
              isTableSep = true;
            }
            if (isTableSep) {
              // if not inside a table, try to construct one
              if (!tableType) {
                // check 1: current line meet the table format
                if (SimpleTableRE.test(stream.string)) tableType = 1 /* SIMPLE */;
                else if (NormalTableRE.test(stream.string)) tableType = 2 /* NORMAL */;
                // check 2: check every column's alignment style
                var rowStyles = void 0;
                if (tableType) {
                  var nextLine = stream.lookAhead(1);
                  if (tableType === 2 /* NORMAL */) {
                    if (!NormalTableRE.test(nextLine)) {
                      tableType = 0 /* NONE */;
                    } else {
                      // remove leading / tailing pipe char
                      nextLine = nextLine.replace(/^\s*\|/, "").replace(/\|\s*$/, "");
                    }
                  } else if (tableType === 1 /* SIMPLE */) {
                    if (!SimpleTableRE.test(nextLine)) {
                      tableType = 0 /* NONE */;
                    }
                  }
                  if (tableType) {
                    rowStyles = nextLine.split("|");
                    for (var i = 0; i < rowStyles.length; i++) {
                      var row = rowStyles[i];
                      if (/^\s*--+\s*:\s*$/.test(row)) row = "right";
                      else if (/^\s*:\s*--+\s*$/.test(row)) row = "left";
                      else if (/^\s*:\s*--+\s*:\s*$/.test(row)) row = "center";
                      else if (/^\s*--+\s*$/.test(row)) row = "default";
                      else {
                        // ouch, can't be a table
                        tableType = 0 /* NONE */;
                        break;
                      }
                      rowStyles[i] = row;
                    }
                  }
                }
                // step 3: made it
                if (tableType) {
                  // successfully made one
                  state.hmdTable = tableType;
                  state.hmdTableColumns = rowStyles;
                  state.hmdTableID = "T" + stream.lineOracle?.line;
                  state.hmdTableRow = state.hmdTableCol = 0;
                }
              }
              // then
              if (tableType) {
                var _dummy = false;
                var colUbound = state.hmdTableColumns.length - 1;
                if (
                  tableType === 2 /* NORMAL */ &&
                  ((state.hmdTableCol === 0 && /^\s*\|$/.test(stream.string.slice(0, stream.pos))) ||
                    stream.match(/^\s*$/, false))
                ) {
                  _dummy = true;
                  ans += " hmd-table-sep hmd-table-sep-dummy";
                }
                if (state.hmdTableCol <= colUbound) {
                  var row = state.hmdTableRow;
                  var col = state.hmdTableCol++;
                  if (col == 0) {
                    ans +=
                      " line-HyperMD-table_" +
                      state.hmdTableID +
                      " line-HyperMD-table-" +
                      tableType +
                      " line-HyperMD-table-row line-HyperMD-table-row-" +
                      row;
                  }
                  if (!_dummy) ans += " hmd-table-sep hmd-table-sep-" + col;
                }
              }
            }
          }
          //#endregion
          if (tableType && state.hmdTableRow === 1) {
            // fix a stupid problem:    :------: is not emoji
            if (/emoji/.test(ans)) ans = "";
          }
          //#region HTML Block
          //
          // See https://github.github.com/gfm/#html-blocks type3-5
          if (inMarkdownInline && current === "<") {
            var endTag = null;
            if (stream.match(/^\![A-Z]+/)) endTag = ">";
            else if (stream.match("?")) endTag = "?>";
            else if (stream.match("![CDATA[")) endTag = "]]>";
            if (endTag != null) {
              return enterMode(stream, state, null, {
                endTag: endTag,
                style: (ans + " comment hmd-cdata-html").trim(),
              });
            }
          }
          //#endregion
          //#region Hashtag
          if (modeCfg.hashtag && inMarkdownInline) {
            const hashTagRegExp = /^(?:[^\u2000-\u206F\u2E00-\u2E7F'!"#$%&()*+,.:;<=>?@^`{|}~\[\]\\\s])+/;
            if (state.hmdHashtag === 1) {
              var endHashTag = false;
              if (!/formatting/.test(ans) && !/^\s*$/.test(current)) {
                stream.eatWhile(hashTagRegExp);
                endHashTag = true;
              }
              if (
                (endHashTag || (endHashTag = stream.eol()),
                endHashTag || (endHashTag = !hashTagRegExp.test(stream.peek())),
                endHashTag)
              ) {
                ans +=
                  " hashtag-end " + (tagClass = "tag-" + (tagClass = stream.current()).replace(/[^_a-zA-Z0-9\-]/g, ""));
                state.hmdHashtag = 0;
              }
            } else if (
              "#" === current &&
              !state.linkText &&
              !state.image &&
              (bol || /^\s*$/.test(stream.string.charAt(stream.start - 1)))
            ) {
              var escape_removed_str = stream.string.slice(stream.pos).replace(/\\./g, "");
              tmp = hashTagRegExp.exec(escape_removed_str);
              if (tmp && /[^0-9]/.test(tmp[0])) {
                var tagClass = "tag-" + tmp[0].replace(/[^_a-zA-Z0-9\-]/g, "");
                state.hmdHashtag = 1;
                ans +=
                  " formatting formatting-hashtag hashtag-begin " + modeCfg.tokenTypeOverrides.hashtag + " " + tagClass;
              }
            }
          }
          //#endregion
        }
        return ans.trim() || null;
      };
      function modeOverride(stream, state) {
        var exit = state.hmdInnerExitChecker(stream, state);
        var extraStyle = state.hmdInnerStyle;
        var ans = ((!exit || !exit.skipInnerMode) && state.hmdInnerMode.token(stream, state.hmdInnerState)) || "";
        if (extraStyle) ans += " " + extraStyle;
        if (exit) {
          if (exit.style) ans += " " + exit.style;
          if (exit.endPos) stream.pos = exit.endPos;
          state.hmdInnerExitChecker = null;
          state.hmdInnerMode = null;
          state.hmdInnerState = null;
          state.hmdOverride = null;
        }
        return ans.trim() || null;
      }
      function createDummyMode(endTag) {
        return {
          token: function (stream) {
            var endTagSince = stream.string.indexOf(endTag, stream.start);
            if (endTagSince === -1) stream.skipToEnd();
            // endTag not in this line
            else if (endTagSince === 0) stream.pos += endTag.length;
            // current token is endTag
            else {
              stream.pos = endTagSince;
              if (stream.string.charAt(endTagSince - 1) === "\\") stream.pos++;
            }
            return null;
          },
        };
      }
      function createSimpleInnerModeExitChecker(endTag, retInfo) {
        if (!retInfo) retInfo = {};
        return function (stream, state) {
          if (stream.string.substr(stream.start, endTag.length) === endTag) {
            retInfo.endPos = stream.start + endTag.length;
            return retInfo;
          }
          return null;
        };
      }
      /**
       * switch to another mode
       *
       * After entering a mode, you can then set `hmdInnerExitStyle` and `hmdInnerState` of `state`
       *
       * @returns if `skipFirstToken` not set, returns `innerMode.token(stream, innerState)`, meanwhile, stream advances
       */
      function enterMode(stream, state, mode, opt) {
        if (typeof mode === "string") mode = CodeMirror.getMode(cmCfg, mode);
        if (!mode || mode["name"] === "null") {
          if ("endTag" in opt) mode = createDummyMode(opt.endTag);
          else mode = typeof opt.fallbackMode === "function" && opt.fallbackMode();
          if (!mode) throw new Error("no mode");
        }
        state.hmdInnerExitChecker = "endTag" in opt ? createSimpleInnerModeExitChecker(opt.endTag) : opt.exitChecker;
        state.hmdInnerStyle = opt.style;
        state.hmdInnerMode = mode;
        state.hmdOverride = modeOverride;
        state.hmdInnerState = CodeMirror.startState(mode);
        var ans = opt.style || "";
        if (!opt.skipFirstToken) {
          ans += " " + mode.token(stream, state.hmdInnerState);
        }
        return ans.trim();
      }
      return newMode;
    },
    "openmd"
  );
  CodeMirror.defineMIME("text/x-openmd", "openmd");
});
});

// HyperMD, copyright (c) by laobubu

var ___extends = (function () {
  var extendStatics = function (d, b) {
    extendStatics =
      Object.setPrototypeOf ||
      ({ __proto__: [] } instanceof Array &&
        function (d, b) {
          d.__proto__ = b;
        }) ||
      function (d, b) {
        for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
      };
    return extendStatics(d, b);
  };
  return function (d, b) {
    extendStatics(d, b);
    function __() {
      this.constructor = d;
    }
    d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new __());
  };
})();

(function (mod) {
  //[HyperMD] UMD patched!
  /*plain env*/ mod(null, (HyperMD.Fold = HyperMD.Fold || {}), CodeMirror, HyperMD, HyperMD.AttributesAddon);
})(function (require, exports, CodeMirror, core_1, index_1) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getAddon =
    exports.Fold =
    exports.parseAttributes =
    exports.suggestedOption =
    exports.defaultOption =
    exports.breakMark =
    exports.registerFolder =
    exports.folderRegistry =
    exports.RequestRangeResult =
      void 0;
  var FlagArray = typeof Uint8Array === "undefined" ? Array : Uint8Array;
  var RequestRangeResult;
  (function (RequestRangeResult) {
    // Use string values because in TypeScript, string enum members do not get a reverse mapping generated at all.
    // Otherwise the generated code looks ugly
    RequestRangeResult["OK"] = "ok";
    RequestRangeResult["CURSOR_INSIDE"] = "ci";
    RequestRangeResult["HAS_MARKERS"] = "hm";
  })((RequestRangeResult = exports.RequestRangeResult || (exports.RequestRangeResult = {})));
  //#endregion
  /********************************************************************************** */
  //#region FolderFunc Registry
  exports.folderRegistry = {};
  /**
   * Add a Folder to the System Folder Registry
   *
   * @param name eg. "math"  "html"  "image"  "link"
   * @param folder
   * @param suggested enable this folder in suggestedEditorConfig
   * @param force if a folder with same name is already exists, overwrite it. (dangerous)
   */
  function registerFolder(name, folder, suggested, force) {
    var registry = exports.folderRegistry;
    if (name in registry && !force) throw new Error("Folder " + name + " already registered");
    exports.defaultOption[name] = false;
    exports.suggestedOption[name] = !!suggested;
    registry[name] = folder;
  }
  exports.registerFolder = registerFolder;
  //#endregion
  /********************************************************************************** */
  //#region Utils
  /** break a TextMarker, move cursor to where marker is */
  function breakMark(cm, marker, chOffset) {
    // TODO: update this to support making a selection rather than placing the cursor
    cm.operation(function () {
      var fromPos = marker.find().from;
      fromPos = { line: fromPos.line, ch: fromPos.ch + ~~chOffset };
      var toPos = marker.find().to;
      toPos = { line: toPos.line, ch: toPos.ch + ~~chOffset };
      // need to clear before setting the cursor since some markers don't allow the
      // cursor to be placed next to them
      marker.clear();
      cm.setCursor(fromPos);
      // cm.setSelection(fromPos, toPos);
      cm.focus();
    });
  }
  exports.breakMark = breakMark;
  exports.defaultOption = {
    /* will be populated by registerFolder() */
  };
  exports.suggestedOption = {
    /* will be populated by registerFolder() */
  };
  core_1.suggestedEditorConfig.hmdFold = exports.suggestedOption;
  core_1.normalVisualConfig.hmdFold = false;
  CodeMirror.defineOption("hmdFold", exports.defaultOption, function (cm, newVal) {
    ///// convert newVal's type to `Record<string, boolean>`, if it is not.
    var inst = exports.getAddon(cm);
    if (!newVal || typeof newVal === "boolean") {
      newVal = newVal ? exports.suggestedOption : exports.defaultOption;
    }
    if ("customFolders" in newVal) {
      delete newVal["customFolders"];
    }
    ///// apply config
    for (var type in exports.folderRegistry) {
      inst.setStatus(cm, type, newVal[type]);
    }
    // then, folding task will be queued by setStatus()
  });
  Object.defineProperty(exports, "parseAttributes", {
    enumerable: true,
    get: function () {
      return index_1.parseAttributes;
    },
  });
  //#endregion
  /********************************************************************************** */
  //#region Addon Class
  var Fold = /** @class */ (function (_super) {
    ___extends(Fold, _super);
    function Fold(cm) {
      var _this = _super.call(this, cm) || this;
      _this.cm = cm;
      /**
       * stores Folder status for current editor
       * @private To enable/disable folders, use `setStatus()`
       */
      _this._enabled = {};
      /** Folder's output goes here */
      _this.folded = {};
      /// END OF APIS THAT EXPOSED TO FolderFunc
      ///////////////////////////////////////////////////////////////////////////////////////////
      /**
       * Fold everything! (This is a debounced, and `this`-binded version)
       */
      _this.startFold = core_1.debounce(_this.startFoldImmediately.bind(_this), 200);
      /** stores every affected lineNo */
      _this._quickFoldHint = [];
      this.registerEvents = function (enable) {
        if (enable) {
          cm.on("changes", _this.onChange);
          cm.on("viewportChange", _this.onViewportChange);
          cm.on("cursorActivity", _this.onCursorActivity);
          cm.on("gutterClick", _this.onGutterClick);
        } else {
          cm.off("changes", _this.onChange);
          cm.off("viewportChange", _this.onViewportChange);
          cm.off("cursorActivity", _this.onCursorActivity);
          cm.off("gutterClick", _this.onGutterClick);
        }
      };
      this.onViewportChange = function (cm, from, to) {
        _this.startFold(from, to);
      };
      this.onGutterClick = function (cm, line, gutter, clickEvent) {
        // check for widgets to render when lists or headers are expanded
        if (
          gutter === "CodeMirror-foldgutter" &&
          clickEvent.composedPath()[0]?.hasClass("CodeMirror-foldgutter-folded")
        ) {
          _this.startFoldImmediately(line, cm.getViewport().to + 1);
        }
      };
      this.checkForPreview = require$$0.debounce(
        function () {
          document.querySelector("#math-preview")?.addClass("float-win-hidden");
        },
        500,
        true
      );
      this.onChange = function (cm, changes) {
        var changedMarkers = [];
        for (var _i = 0, changes_1 = changes; _i < changes_1.length; _i++) {
          var change = changes_1[_i];
          if (change.removed && change.removed.filter(text => text.includes("$")).length) {
            _this.checkForPreview();
          }
          var markers = cm.findMarks(change.from, change.to);
          for (var _a = 0, markers_1 = markers; _a < markers_1.length; _a++) {
            var marker = markers_1[_a];
            if (marker._hmd_fold_type) changedMarkers.push(marker);
          }
        }
        for (var _b = 0, changedMarkers_1 = changedMarkers; _b < changedMarkers_1.length; _b++) {
          var m = changedMarkers_1[_b];
          var line = cm.getLine(changes[0].from.line);
          if (
            line[changes[0].from.ch - 1] === "`" &&
            line[changes[0].from.ch] === "@" &&
            line.slice(changes[0].from.ch).length > 1
          ) ; else {
            m.clear(); // TODO: add "changed" handler for FolderFunc
          }
        }
        var fromLine = 0,
          toLine = 0;
        var _changes = changes.map(change => {
          return { fromLine: change.from.line, toLine: change.to.line };
        });
        _changes.forEach(change => {
          fromLine = change.fromLine > fromLine ? change.fromLine : fromLine;
          toLine = change.toLine > toLine ? change.toLine : toLine;
        });
        _this.startFold(fromLine, toLine);
      };
      this.onCursorActivity = function (cm) {
        var lineStuff = {};
        function addPosition(pos) {
          var lineNo = pos.line;
          if (!(lineNo in lineStuff)) {
            var lh = cm.getLineHandle(pos.line);
            var ms = lh.markedSpans || [];
            var markers = [];
            for (var i = 0; i < ms.length; i++) {
              var marker = ms[i].marker;
              if ("_hmd_crange" in marker) {
                var from = marker._hmd_crange[0].line < lineNo ? 0 : marker._hmd_crange[0].ch;
                var to = marker._hmd_crange[1].line > lineNo ? lh.text.length : marker._hmd_crange[1].ch;
                markers.push([marker, from, to]);
              }
            }
            lineStuff[lineNo] = {
              lineNo: lineNo,
              ch: [pos.ch],
              markers: markers,
            };
          } else {
            lineStuff[lineNo].ch.push(pos.ch);
          }
        }
        cm.listSelections().forEach(function (selection) {
          addPosition(selection.anchor);
          addPosition(selection.head);
        });
        for (var tmp_id in lineStuff) {
          var lineData = lineStuff[tmp_id];
          if (!lineData.markers.length) continue;
          for (var i = 0; i < lineData.ch.length; i++) {
            var ch = lineData.ch[i];
            for (var j = 0; j < lineData.markers.length; j++) {
              var _a = lineData.markers[j],
                marker = _a[0],
                from = _a[1],
                to = _a[2];
              if (from <= ch && ch <= to) {
                marker.clear();
                lineData.markers.splice(j, 1);
                j--;
              }
            }
          }
        }
        _this.startQuickFold();
      };
      return _this;
    }
    /** enable/disable one kind of folder, in current editor */
    Fold.prototype.setStatus = function (cm, type, enabled) {
      // this logic will disable hmdFold completely if no folders are found in the registry
      var prevStatus;
      for (var _type in this._enabled) {
        if (this._enabled[_type]) {
          prevStatus = true;
          break;
        } else {
          prevStatus = false;
        }
      }
      if (!(type in exports.folderRegistry)) return;
      if (!this._enabled[type] !== !enabled) {
        this._enabled[type] = !!enabled;
        if (enabled) {
          this.startFold();
        } else this.clear(type);
      }
      var curStatus;
      for (var _type in this._enabled) {
        if (this._enabled[_type]) {
          curStatus = true;
          break;
        } else {
          curStatus = false;
        }
      }
      if (prevStatus && !curStatus) {
        this.registerEvents(false);
      } else if (!prevStatus && curStatus) {
        this.registerEvents(true);
      }
    };
    ///////////////////////////////////////////////////////////////////////////////////////////
    /// BEGIN OF APIS THAT EXPOSED TO FolderFunc
    /// @see FoldStream
    /**
     * Check if a range is foldable and update _quickFoldHint
     *
     * NOTE: this function is always called after `_quickFoldHint` reset by `startFoldImmediately`
     */
    Fold.prototype.requestRange = function (from, to, cfrom, cto) {
      if (!cto) cto = to;
      if (!cfrom) cfrom = from;
      var cm = this.cm;
      var markers = cm.findMarks(from, to);
      // nil: filter out any text selection markers so that we don't bug out the entire fold logic, ugh
      markers = markers.filter(marker => marker.className != "CodeMirror-selectedtext");
      if (markers.length !== 0) {
        return RequestRangeResult.HAS_MARKERS;
      }
      this._quickFoldHint.push(from.line);
      // store "crange" for the coming marker
      this._lastCRange = [cfrom, cto];
      var selections = cm.listSelections();
      for (var i = 0; i < selections.length; i++) {
        var oselection = core_1.orderedRange(selections[i]);
        // note that "crange" can be bigger or smaller than marked-text range.
        if (core_1.rangesIntersect(this._lastCRange, oselection) || core_1.rangesIntersect([from, to], oselection)) {
          return RequestRangeResult.CURSOR_INSIDE;
        }
      }
      this._quickFoldHint.push(cfrom.line);
      return RequestRangeResult.OK;
    };
    /**
     * Fold everything!
     *
     * @param toLine last line to fold. Inclusive
     */
    Fold.prototype.startFoldImmediately = function (fromLine, toLine) {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      var _this = this;
      var cm = this.cm;
      var viewPort = cm.getViewport();
      // nil: if no from/to is passed, only scan the visible viewport, rather than the entire file
      fromLine = fromLine >= 0 ? fromLine : viewPort.from; // cm.firstLine();
      toLine = (toLine >= 0 ? toLine : viewPort.to) + 1; // cm.lastLine()) + 1;
      this._quickFoldHint = [];
      this.setPos(fromLine, 0, true);
      cm.operation(function () {
        return cm.eachLine(fromLine, toLine, function (line) {
          var lineNo = line.lineNo();
          if (lineNo < _this.lineNo) return;
          // skip current line...
          else if (lineNo > _this.lineNo) _this.setPos(lineNo, 0); // hmmm... maybe last one is empty line
          // all the not-foldable chars are marked
          var charMarked = new FlagArray(line.text.length);
          {
            // populate charMarked array.
            // @see CodeMirror's findMarksAt
            var lineMarkers = line.markedSpans;
            if (lineMarkers) {
              // nil: filter out any text selection markers so that we don't bug out the entire fold logic, ugh
              lineMarkers = lineMarkers.filter(markedSpan => markedSpan.marker.className !== "CodeMirror-selectedtext");
              for (var i = 0; i < lineMarkers.length; ++i) {
                var span = lineMarkers[i];
                var spanFrom = span.from == null ? 0 : span.from;
                var spanTo = span.to == null ? charMarked.length : span.to;
                for (var j = spanFrom; j < spanTo; j++) charMarked[j] = 1;
              }
            }
          }
          var tokens = _this.lineTokens;
          while (_this.i_token < tokens.length) {
            var token = tokens[_this.i_token];
            var type;
            var marker = null;
            var tokenFoldable = true;
            {
              for (var i = token.start; i < token.end; i++) {
                if (charMarked[i]) {
                  tokenFoldable = false;
                  break;
                }
              }
            }
            if (tokenFoldable) {
              // try all enabled folders in registry
              for (type in exports.folderRegistry) {
                if (!_this._enabled[type]) continue;
                if ((marker = exports.folderRegistry[type](_this, token))) break;
              }
            }
            if (!marker) {
              // this token not folded. check next
              _this.i_token++;
            } else {
              var _a = marker.find(),
                from = _a.from,
                to = _a.to;
              (_this.folded[type] || (_this.folded[type] = [])).push(marker);
              marker._hmd_fold_type = type;
              marker._hmd_crange = _this._lastCRange;
              marker.on("clear", function (from, to) {
                var markers = _this.folded[type];
                var idx;
                if (markers && (idx = markers.indexOf(marker)) !== -1) markers.splice(idx, 1);
                _this._quickFoldHint.push(from.line);
              });
              // now let's update the pointer position
              if (from.line > lineNo || from.ch > token.start) {
                // there are some not-marked chars after current token, before the new marker
                // first, advance the pointer
                _this.i_token++;
                // then mark the hidden chars as "marked"
                var fromCh = from.line === lineNo ? from.ch : charMarked.length;
                var toCh = to.line === lineNo ? to.ch : charMarked.length;
                for (var i = fromCh; i < toCh; i++) charMarked[i] = 1;
              } else {
                // classical situation
                // new marker starts since current token
                if (to.line !== lineNo) {
                  _this.setPos(to.line, to.ch);
                  return; // nothing left in this line
                } else {
                  _this.setPos(to.ch); // i_token will be updated by this.setPos()
                }
              }
            }
          }
        });
      });
    };
    /**
     * Start a quick fold: only process recent `requestRange`-failed ranges
     */
    Fold.prototype.startQuickFold = function () {
      var hint = this._quickFoldHint;
      if (hint.length === 0) return;
      var from = hint[0],
        to = from;
      for (var _i = 0, hint_1 = hint; _i < hint_1.length; _i++) {
        var lineNo = hint_1[_i];
        if (from > lineNo) from = lineNo;
        if (to < lineNo) to = lineNo;
      }
      this.startFold.stop();
      this.startFoldImmediately(from, to);
    };
    /**
     * Clear one type of folded TextMarkers
     *
     * @param type builtin folder type ("image", "link" etc) or custom fold type
     */
    Fold.prototype.clear = function (type) {
      this.startFold.stop();
      var folded = this.folded[type];
      if (!folded || !folded.length) return;
      var marker;
      while ((marker = folded.pop())) marker.clear();
    };
    /**
     * Clear all folding result
     */
    Fold.prototype.clearAll = function () {
      this.startFold.stop();
      for (var type in this.folded) {
        var folded = this.folded[type];
        var marker;
        while ((marker = folded.pop())) marker.clear();
      }
    };
    return Fold;
  })(core_1.TokenSeeker);
  exports.Fold = Fold;
  //#endregion
  /** ADDON GETTER (Singleton Pattern): a editor can have only one Fold instance */
  exports.getAddon = core_1.Addon.Getter("Fold", Fold);
});

// HyperMD, copyright (c) by laobubu
// Distributed under an MIT license: http://laobubu.net/HyperMD/LICENSE
//
// DESCRIPTION: Fold URL of links `[text](url)`
//

(function (mod){ //[HyperMD] UMD patched!
  /*plain env*/ mod(null,  {}, HyperMD.Fold, HyperMD);
})(function (require, exports, fold_1, core_1) {
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.LinkFolder = void 0;
    var LinkFolder = function (stream, token) {
        var cm = stream.cm;
        // a valid beginning must be ...
        if (!((token.string === "[" && // the leading [
            token.state.linkText && // (double check) is link text
            !token.state.linkTitle && // (double check) not image's title
            !/\bimage\b/.test(token.type)) // and is not a image mark
        ))
            return null;
        var spanExtractor = core_1.getLineSpanExtractor(cm);
        // first, find the link text span
        var linkTextSpan = spanExtractor.findSpanWithTypeAt({ line: stream.lineNo, ch: token.start }, "linkText");
        if (!linkTextSpan)
            return null;
        // then find the link href span
        var linkHrefSpan = spanExtractor.findSpanWithTypeAt({ line: stream.lineNo, ch: linkTextSpan.end + 1 }, "linkHref");
        if (!linkHrefSpan)
            return null;
        // now compose the ranges
        var hrefFrom = { line: stream.lineNo, ch: linkHrefSpan.begin };
        var hrefTo = { line: stream.lineNo, ch: linkHrefSpan.end };
        var linkFrom = { line: stream.lineNo, ch: linkTextSpan.begin };
        // const linkTo: Position = { line: stream.lineNo, ch: linkTextSpan.end };
        // and check if the range is OK
        var rngReq = stream.requestRange(hrefFrom, hrefTo, linkFrom, hrefFrom);
        if (rngReq !== fold_1.RequestRangeResult.OK)
            return null;
        // everything is OK! make the widget
        var text = cm.getRange(hrefFrom, hrefTo);
        var _a = splitLink(text.substr(1, text.length - 2)), url = _a.url, title = _a.title;
        var imgElem = document.createElement("span");
        imgElem.setAttribute("class", "hmd-link-icon");
        imgElem.setAttribute("title", url + "\n" + title);
        imgElem.setAttribute("data-url", url);
        var marker = cm.markText(hrefFrom, hrefTo, {
            collapsed: true,
            replacedWith: imgElem,
        });
        imgElem.addEventListener("click", function () { return fold_1.breakMark(cm, marker); }, false);
        return marker;
    };
    function splitLink(content) {
        // remove title part (if exists)
        content = content.trim();
        var url = content, title = "";
        var mat = content.match(/^(\S+)\s+("(?:[^"\\]+|\\.)+"|[^"\s].*)/);
        if (mat) {
            url = mat[1];
            title = mat[2];
            if (title.charAt(0) === '"')
                title = title.substr(1, title.length - 2).replace(/\\"/g, '"');
        }
        return { url: url, title: title };
    }
    exports.LinkFolder = LinkFolder;
    fold_1.registerFolder("link", exports.LinkFolder, true);
});

// HyperMD, copyright (c) by laobubu
// Distributed under an MIT license: http://laobubu.net/HyperMD/LICENSE
//
// DESCRIPTION: Fold Image Markers `![](xxx)`
//

(function (mod) {
  mod(null, {}, CodeMirror, HyperMD.Fold, HyperMD.ReadLink);
})(function (require, exports, CodeMirror, fold_1) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.ImageFolder = void 0;
  var ImageFolder = function (stream, token) {
    var cm = stream.cm;
    var imgRE = /(\bimage-marker\b)|(\bformatting-embed\b)/;
    var extRE = /\.(jpe?g|png|gif|svg|bmp)/;
    var urlRE = /(\bformatting-link-string\b)|(\bformatting-link\b)/; // matches the parentheses
    if (imgRE.test(token.type) && (token.string === "!" || token.string === "![[")) {
      var lineNo = stream.lineNo;
      // find the begin and end of url part
      var since = { line: lineNo, ch: token.start };
      var url_begin = stream.findNext(urlRE, 0, since);
      if (!url_begin) {
        return null;
      }
      // var url_end = stream.findNext(urlRE, url_begin.i_token + 1);
      var url_end = stream.findNext(urlRE, url_begin.i_token + 1);
      var from = { line: lineNo, ch: token.start };
      var to = { line: lineNo, ch: url_end.token.end };
      var rngReq = stream.requestRange(from, to, from, from);
      if (rngReq === fold_1.RequestRangeResult.OK) {
        var url = void 0;
        var alt = void 0;
        var title = void 0;
        var dimensions = void 0;
        {
          // extract the URL
          var rawurl = cm.getRange(
            // get the URL or footnote name in the parentheses
            { line: lineNo, ch: url_begin.token.end },
            { line: lineNo, ch: url_end.token.start }
          );
          if (!extRE.test(rawurl)) return null;
          if (url_end.token.string === "]") {
            var tmp = cm.hmdReadLink(rawurl, lineNo);
            if (!tmp) return null; // Yup! bad URL?!
            rawurl = tmp.content;
          }
          var split = splitLink(rawurl);
          url = split.url;
          title = split.title;
          var _matches;
          if ((_matches = url.match(/^([^|]+)\|(.*)$/))) {
            url = _matches[1];
            dimensions = _matches[2];
          }
        }
        {
          // extract the alt
          alt = cm.getRange({ line: lineNo, ch: from.ch + 2 }, { line: lineNo, ch: url_begin.token.start - 1 });
        }
        var _altMatches;
        if ((_altMatches = alt.match(/^(?:([^|]*)\|)?([0-9x]+)$/))) {
          dimensions = _altMatches[2];
        }
        var img = document.createElement("img");
        var marker = cm.markText(from, to, {
          collapsed: true,
          clearOnEnter: true,
          replacedWith: img,
          // inclusiveLeft: true,
          // inclusiveRight: true,
        });
        img.addEventListener(
          "load",
          function () {
            img.classList.remove("hmd-image-loading");
            marker.changed();
          },
          false
        );
        img.addEventListener(
          "error",
          function () {
            img.classList.remove("hmd-image-loading");
            img.classList.add("hmd-image-error");
            marker.changed();
          },
          false
        );
        img.className = "hmd-image hmd-image-loading";
        img.addEventListener(
          "click",
          function () {
            return fold_1.breakMark(cm, marker);
            // CodeMirror.signal(cm, "imageClicked", {
            //   editor: cm,
            //   marker: marker,
            //   breakMark: fold_1.breakMark,
            //   element: img,
            // });
          },
          false
        );
        img.alt = alt;
        img.title = title;
        var _url, _resolvedUrl;
        if (/^(app|http|https):\/\//.test(url)) {
          _url = url;
        } else {
          _resolvedUrl = window.app.metadataCache.getFirstLinkpathDest(decodeURIComponent(url), "");
          if (_resolvedUrl) {
            _url = window.app.vault.getResourcePath(_resolvedUrl);
          } else {
            _url = "";
            img.alt = "⚠️";
          }
        }

        img.setAttribute("data-src", _url);
        if (_resolvedUrl && _resolvedUrl.path) img.setAttribute("data-path", _resolvedUrl.path);
        img.setAttribute("src", _url);
        if (dimensions) {
          var _dims = dimensions.match(/^([0-9]+)x?([0-9]+)?$/);
          var width = _dims[1] ? `width: ${_dims[1]}px;` : "";
          var height = _dims[2] ? `height: ${_dims[2]}px;` : "";
          img.setAttribute("style", `${width} ${height}`);
        }
        CodeMirror.signal(cm, "imageReadyToLoad", {
          editor: cm,
          marker: marker,
          breakMark: fold_1.breakMark,
          element: img,
        });
        return marker;
      }
    }
    return null;
  };
  function splitLink(content) {
    // support ![Alt](/path/to/img.jpg “image title”) syntax
    // remove title part (if exists)
    content = content.trim();
    var url = content,
      title = "";
    var mat = content.match(/^([^"]+)("(?:[^"\\]+|\\.)+"|[^"\s].*)?/);
    if (mat) {
      url = mat[1];
      title = mat[2] ? mat[2] : "";
      if (title.charAt(0) === '"') title = title.substr(1, title.length - 2).replace(/\\"/g, '"');
    }
    return { url: url?.trim(), title: title };
  }
  exports.ImageFolder = ImageFolder;
  fold_1.registerFolder("image", exports.ImageFolder, true);
});

// HyperMD, copyright (c) by laobubu

(function (mod) {
  mod(null, (HyperMD.FoldCode = HyperMD.FoldCode || {}), CodeMirror, HyperMD, HyperMD.Fold);
})(function (require, exports, CodeMirror, core_1, fold_1) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getAddon =
    exports.convertNumberToString =
    exports.FoldCode =
    exports.suggestedOption =
    exports.defaultOption =
    exports.CodeFolder =
    exports.registerRenderer =
    exports.rendererRegistry =
      void 0;
  exports.rendererRegistry = {};
  /**
   * Add a CodeRenderer to the System CodeRenderer Registry
   *
   * @param lang
   * @param folder
   * @param suggested enable this folder in suggestedEditorConfig
   * @param force if a folder with same name is already exists, overwrite it. (dangerous)
   */
  function registerRenderer(info, force) {
    if (!info || !info.name || !info.renderer) return;
    var name = info.name;
    var pattern = info.pattern;
    var registry = exports.rendererRegistry;
    if (name in registry) {
      if (!force) {
        throw new Error("CodeRenderer " + name + " already exists");
      }
    }
    if (typeof pattern === "string") {
      var t_1 = pattern.toLowerCase();
      pattern = function (lang) {
        return lang.toLowerCase() === t_1;
      };
    } else if (pattern instanceof RegExp) {
      pattern = function (lang) {
        return info.pattern.test(lang);
      };
    }
    var newInfo = {
      name: name,
      suggested: !!info.suggested,
      pattern: pattern,
      renderer: info.renderer,
    };
    registry[name] = newInfo;
    exports.defaultOption[name] = false;
    exports.suggestedOption[name] = newInfo.suggested;
  }
  exports.registerRenderer = registerRenderer;
  //#endregion
  //#region FolderFunc for Addon/Fold -----------------------------------------------------
  /** the FolderFunc for Addon/Fold */
  var CodeFolder = function (stream, token) {
    if (
      token.start !== 0 ||
      !token.type ||
      token.type.indexOf("HyperMD-codeblock-begin") === -1 ||
      !/([-\w]+)(\s*|\s+\{.+\}\s*)$/.test(token.string)
    ) {
      return null;
    }
    return exports.getAddon(stream.cm).fold(stream, token);
  };
  exports.CodeFolder = CodeFolder;
  fold_1.registerFolder("code", exports.CodeFolder, true);
  exports.defaultOption = {
    /* will be populated by registerRenderer() */
  };
  exports.suggestedOption = {
    /* will be populated by registerRenderer() */
  };
  core_1.suggestedEditorConfig.hmdFoldCode = exports.suggestedOption;
  CodeMirror.defineOption("hmdFoldCode", exports.defaultOption, function (cm, newVal) {
    ///// convert newVal's type to `Record<string, boolean>`, if it is not.
    if (!newVal || typeof newVal === "boolean") {
      newVal = newVal ? exports.suggestedOption : exports.defaultOption;
    }
    ///// apply config
    var inst = exports.getAddon(cm);
    for (var type in exports.rendererRegistry) {
      inst.setStatus(type, newVal[type]);
    }
    // then, folding task will be queued by setStatus()
  });
  var FoldCode = /** @class */ (function () {
    function FoldCode(cm) {
      this.cm = cm;
      /**
       * stores renderer status for current editor
       * @private To enable/disable renderer, use `setStatus()`
       */
      this._enabled = {};
      /** renderers' output goes here */
      this.folded = {};
    }
    /** enable/disable one kind of renderer, in current editor */
    FoldCode.prototype.setStatus = function (type, enabled) {
      if (!(type in exports.rendererRegistry)) return;
      if (!this._enabled[type] !== !enabled) {
        this._enabled[type] = !!enabled;
        if (enabled) fold_1.getAddon(this.cm).startFold();
        else this.clear(type);
      }
    };
    /** Clear one type of rendered TextMarkers */
    FoldCode.prototype.clear = function (type) {
      var folded = this.folded[type];
      if (!folded || !folded.length) return;
      var info;
      while ((info = folded.pop())) info.marker.clear();
    };
    FoldCode.prototype.clearAll = function () {
      fold_1.getAddon(this.cm).startFold.stop();
      for (var type in this.folded) {
        var folded = this.folded[type];
        var info;
        while ((info = folded.pop())) {
          info.marker.explicitlyCleared = false;
          info.marker.clear();
          info.marker = null;
          info = null;
        }
      }
    };
    FoldCode.prototype.fold = function (stream, token) {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      var _this = this;
      var debug = false;
      if (token.start !== 0 || !token.type || token.type.indexOf("HyperMD-codeblock-begin") === -1) {
        return null;
      }
      var tmp = /([-\w]+)(\s*|\s+\{.+\}\s*)$/.exec(token.string);
      var lang = tmp && tmp[1].toLowerCase();
      var attributesStr = tmp && tmp[2] && tmp[2].trim();
      var attributes = {};
      if (attributesStr && attributesStr.length) {
        attributes = fold_1.parseAttributes(attributesStr);
      }
      if (!lang) return null;
      var renderer;
      var type;
      var cm = this.cm,
        registry = exports.rendererRegistry,
        _enabled = this._enabled;
      for (var type_i in registry) {
        var r = registry[type_i];
        if (!_enabled[type_i]) continue;
        if (!r.pattern(lang)) continue;
        type = type_i;
        renderer = r.renderer;
        break;
      }
      if (!type) return null;
      var from = { line: stream.lineNo, ch: 0 };
      var to = null;
      // find the end of code block
      var lastLineCM = cm.lastLine();
      var endLine = stream.lineNo + 1;
      do {
        var s = cm.getTokenAt({ line: endLine, ch: 1 });
        if (s && s.type && s.type.indexOf("HyperMD-codeblock-end") !== -1) {
          //FOUND END!
          to = { line: endLine, ch: s.end };
          break;
        }
      } while (++endLine < lastLineCM);
      if (!to) return null;
      // request the range
      var rngReq = stream.requestRange(from, to);
      if (rngReq !== fold_1.RequestRangeResult.OK) return null;
      // now we can call renderer
      var code = cm.getRange({ line: from.line + 1, ch: 0 }, { line: to.line, ch: 0 });
      var info = {
        editor: cm,
        lang: lang,
        attributes: attributes,
        marker: null,
        lineWidget: null,
        el: null,
        break: undefined_function,
        changed: undefined_function,
      };
      var _a = renderer(code, info),
        element = _a.element,
        asyncRenderer = _a.asyncRenderer;
      info.el = element;
      var el = element;
      if (!el) {
        info.marker.clear();
        return null;
      }

      var $wrapper = document.createElement("div");
      $wrapper.className = contentClass + type;
      $wrapper.style.minHeight = "1em";
      $wrapper.appendChild(el);

      var lineWidget = (info.lineWidget = cm.addLineWidget(to.line, $wrapper, {
        above: false,
        coverGutter: false,
        handleMouseEvents: false,
        className: "rendered-code-block rendered-widget",
        noHScroll: false,
        showIfHidden: false,
      }));
      if (asyncRenderer) {
        asyncRenderer();
      }
      var wrapperLine = stream.lineNo;

      cm.addLineClass(wrapperLine, "wrap", "rendered-code-block-wrapper");
      cm.addLineClass(wrapperLine, "wrap", `rendered-${type}-wrapper`);
      // watch for any changes to the widget wrapper or its children
      // so that we can call widget.changed() to remeasure the element
      // and prevent any cursor placement issues
      // this allows our widget to shrink or grow to any size we want

      function updateWidget(widget) {
        try {
          widget.changed();
        } catch (err) {
        }
      }

      var widgetChanged = require$$0.debounce(updateWidget, 250);

      let observer = new ResizeObserver((mutations, observer) => {
        try {
          widgetChanged(lineWidget);
        } catch {}
      });

      observer.observe($wrapper);

      var $stub = document.createElement("span");
      $stub.className = stubClass + type;
      $stub.textContent = "<CODE>";
      var marker = (info.marker = cm.markText(from, to, {
        replacedWith: $stub,
        inclusiveLeft: true,
        inclusiveRight: true,
      }));

      info.changed = function () {
        try {
          lineWidget.changed();
        } catch (err) {
        }
      };
      info.break = function () {
        observer.disconnect();
        observer = null;
        fold_1.breakMark(cm, marker);
      };
      $stub.addEventListener("click", info.break, false);
      var redraw = info.redraw;
      if (redraw) {
        lineWidget.on("redraw", info.redraw);
      }
      function onCodeBlockClear() {
        if (redraw) {
          lineWidget.off("redraw", info.redraw);
        }
        marker.off("clear", onCodeBlockClear);
        $stub.removeEventListener("click", info.break);
        if (info.unload) {
          try {
            info.unload();
            info.unload = null;
            info = null;
            if (debug) ;
          } catch (err) {
          }
        }
        var markers = _this.folded[type];
        var idx;
        if (markers && (idx = markers.indexOf(info)) !== -1) markers.splice(idx, 1);
        cm.removeLineClass(wrapperLine, "wrap", `rendered-${type}-wrapper`);
        cm.removeLineClass(wrapperLine, "wrap", "rendered-code-block-wrapper");
        if (observer) observer.disconnect();
        lineWidget.clear();
        lineWidget = null;
        observer = null;
        marker.replacedWith = null;
        marker.widgetNode = null;
        marker = null;
      }
      marker.on("clear", onCodeBlockClear);
      if (!(type in this.folded)) this.folded[type] = [info];
      else this.folded[type].push(info);
      return marker;
    };
    return FoldCode;
  })();
  exports.FoldCode = FoldCode;
  //#endregion
  // End
  var contentClass = "hmd-fold-code-content hmd-fold-code-"; // + renderer_type
  var stubClass = "hmd-fold-code-stub hmd-fold-code-"; // + renderer_type
  // eslint-disable-next-line @typescript-eslint/no-empty-function
  var undefined_function = function () {};
  /** ADDON GETTER (Singleton Pattern): a editor can have only one FoldCode instance */
  exports.getAddon = core_1.Addon.Getter("FoldCode", FoldCode, exports.defaultOption /** if has options */);
});

// HyperMD, copyright (c) by laobubu
// Distributed under an MIT license: http://laobubu.net/HyperMD/LICENSE
//
// DESCRIPTION: Fold and render embedded HTML snippets

(function (mod) {
  //[HyperMD] UMD patched!
  /*plain env*/ mod(null, (HyperMD.FoldHTML = HyperMD.FoldHTML || {}), CodeMirror, HyperMD, HyperMD.Fold);
})(function (require, exports, CodeMirror, core_1, fold_1) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getAddon =
    exports.FoldHTML =
    exports.suggestedOption =
    exports.defaultOption =
    exports.HTMLFolder =
    exports.defaultRenderer =
    exports.defaultChecker =
      void 0;

  const purifySettings = {
    ALLOW_UNKNOWN_PROTOCOLS: true,
    IN_PLACE: true,
    // RETURN_DOM_FRAGMENT: true,
    // RETURN_DOM_IMPORT: true,
    FORBID_TAGS: ["style"],
    ADD_TAGS: ["iframe"],
    ADD_ATTR: ["frameborder", "allowfullscreen", "allow", "aria-label-position"],
  };
  // export type CheckerFunc = (html: string, pos: Position, cm: cm_t) => boolean;
  var defaultChecker = function (html) {
    // TODO: Remove this since we're now using DOMPurify?
    if (/^<(?:br)/i.test(html)) {
      return false; // check first element...
    }
    if (/<(?:script|style|link|meta|object|embed)/i.test(html)) {
      // TODO: dyamically add/remove iframe block
      return false; // don't allow some tags
    }
    if (/\son\w+\s*=/i.test(html)) {
      return false; // don't allow `onclick=` etc.
    }
    if (/(src|background|href)\s*=\s*["']?javascript:/i.test(html)) {
      return false; // don't allow `src="javascript:` etc.
    }
    return true;
  };
  exports.defaultChecker = defaultChecker;
  /**
   * Create HTMLElement from HTML string and do special process with HyperMD.ReadLink
   */
  var defaultRenderer = function (html, pos, cm) {
    var tagBegin = /^<(\w+)\s*/.exec(html);
    if (!tagBegin) return null;
    var tagName = tagBegin[1];
    var ans = document.createElement(tagName);
    var propRE = /([\w\:\-]+)(?:\s*=\s*((['"]).*?\3|\S+))?\s*/g;
    var propLastIndex = (propRE.lastIndex = tagBegin[0].length);
    var tmp;
    while ((tmp = propRE.exec(html))) {
      if (tmp.index > propLastIndex) break; // emmm
      var propName = tmp[1];
      var propValue = tmp[2]; // could be wrapped by " or '
      if (propValue && /^['"]/.test(propValue)) propValue = propValue.slice(1, -1);
      ans.setAttribute(propName, propValue);
      propLastIndex = propRE.lastIndex;
    }
    if ("innerHTML" in ans) {
      // node may contain innerHTML
      var startCh = html.indexOf(">", propLastIndex) + 1;
      var endCh = html.length;
      if ((tmp = new RegExp("</" + tagName + "\\s*>\\s*$", "i").exec(html))) {
        endCh = tmp.index;
      }
      var innerHTML = html.slice(startCh, endCh);
      if (innerHTML) {
        ans.innerHTML = innerHTML;
      }
      window.DOMPurify.sanitize(ans, purifySettings);
      // ans.replaceWith(cleanHTML);
      // resolve relative URLs and change default behavoirs
      core_1.visitElements([ans], function (el) {
        var tagName = el.tagName.toLowerCase();
        if (tagName === "a") {
          // for links, if target not set, add target="_blank"
          if (!el.getAttribute("target")) el.setAttribute("target", "_blank");
        }
        // Then, resovle relative URLs
        var urlAttrs = {
          a: ["href"],
          img: ["src"],
          iframe: ["src"],
        }[tagName];
        if (urlAttrs) {
          for (var i = 0; i < urlAttrs.length; i++) {
            var _url, _resolvedUrl;
            var attr = urlAttrs[i];
            var attrValue = el.getAttribute(attr);
            _resolvedUrl = window.app.metadataCache.getFirstLinkpathDest(decodeURI(attrValue), "");
            if (_resolvedUrl) {
              _url = window.app.vault.getResourcePath(_resolvedUrl);
            } else {
              _url = "";
            }
            if (_url) {
              el.setAttribute(attr, decodeURI(attrValue));
              el.addClass("internal-link");
            }
          }
        }
      });
    }
    return ans;
  };
  exports.defaultRenderer = defaultRenderer;
  /********************************************************************************** */
  var stubClass = "hmd-fold-html-stub";
  var stubClassOmittable = "hmd-fold-html-stub omittable";
  /********************************************************************************** */
  //#region Folder
  /**
   * Detect if a token is a beginning of HTML, and fold it!
   *
   * @see FolderFunc in ./fold.ts
   */
  var HTMLFolder = function (stream, token) {
    if (!token.type || !/ hmd-html-begin/.test(token.type)) return null;
    var endInfo = stream.findNext(/ hmd-html-\w+/, true); // find next html start/end token
    if (!endInfo || !/ hmd-html-end/.test(endInfo.token.type) || / hmd-html-unclosed/.test(endInfo.token.type))
      return null;
    var cm = stream.cm;
    var from = { line: stream.lineNo, ch: token.start };
    var to = { line: endInfo.lineNo, ch: endInfo.token.end };
    var inlineMode = from.ch != 0 || to.ch < cm.getLine(to.line).length;

    var addon = exports.getAddon(cm);
    var html = cm.getRange(from, to);

    var reqAns = stream.requestRange(from, to);
    if (reqAns !== fold_1.RequestRangeResult.OK) return null;

    // now we are ready to fold and render!
    var marker = addon.renderAndInsert(html, from, to, inlineMode);
    return marker;
  };
  exports.HTMLFolder = HTMLFolder;
  //#endregion
  fold_1.registerFolder("html", exports.HTMLFolder, false);
  exports.defaultOption = {
    checker: exports.defaultChecker,
    renderer: exports.defaultRenderer,
    stubText: "<HTML>",
    isolatedTagName: /^(?:div|pre|details|form|mark|table|iframe|ul|ol|input|textarea|p|summary|a)$/i,
  };
  exports.suggestedOption = {};
  core_1.suggestedEditorConfig.hmdFoldHTML = exports.suggestedOption;
  CodeMirror.defineOption("hmdFoldHTML", exports.defaultOption, function (cm, newVal) {
    ///// convert newVal's type to `Partial<Options>`, if it is not.
    if (!newVal) {
      newVal = {};
    } else if (typeof newVal == "function") {
      newVal = { checker: newVal };
    } else if (typeof newVal != "object") {
      console.warn("[HyperMD][FoldHTML] incorrect option value type");
      newVal = {};
    }
    ///// apply config and write new values into cm
    var inst = exports.getAddon(cm);
    for (var k in exports.defaultOption) {
      inst[k] = k in newVal ? newVal[k] : exports.defaultOption[k];
    }
    ///// Type Check
    if (inst.isolatedTagName && !(inst.isolatedTagName instanceof RegExp)) {
      if (window["ECHOMD_DEBUG"]) {
        console.error("[HyperMD][FoldHTML] option isolatedTagName only accepts RegExp");
      }
      inst.isolatedTagName = exports.defaultOption.isolatedTagName;
    }
  });
  //#endregion
  /********************************************************************************** */
  //#region Addon Class
  var FoldHTML = /** @class */ (function () {
    function FoldHTML(cm) {
      this.cm = cm;
      // options will be initialized to defaultOption when constructor is finished
    }
    /**
     * Render HTML, insert into editor and return the marker
     */
    FoldHTML.prototype.renderAndInsert = function (html, from, to, inlineMode) {
      var cm = this.cm;
      var stub = this.makeStub();
      var el = this.renderer(html, from, cm);
      var breakFn = function () {
        return fold_1.breakMark(cm, marker);
      };
      if (!el) return null;
      stub.addEventListener("click", breakFn, false);
      if (!el.tagName.match(this.isolatedTagName || /^$/)) el.addEventListener("click", breakFn, false);
      var replacedWith;
      var marker;
      var isBlock = false;
      function updateWidgetByEl(targetEl) {
        const found = cm.hmd.Fold.folded.html.filter(
          el => el.replacedWith?.contains(targetEl) || el.associatedLineWidget?.node?.contains(targetEl)
        );
        if (found.length) {
          found[0].changed();
          // console.log("html widget size change");
        }
      }
      if (inlineMode) {
        /** put HTML inline */
        stub.className = stubClassOmittable;

        var span = document.createElement("span");
        span.setAttribute("class", "hmd-fold-html rendered-widget");
        span.setAttribute("style", "display: inline-flex");
        span.appendChild(stub);
        span.appendChild(el);

        replacedWith = span;
        /** If element size changed, we notify CodeMirror */

        function watchInlineSize(w, h, el) {
          try {
            updateWidgetByEl(el);
          } catch (err) {}
        }

        const inlineObserverCallback = entries => {
          for (let entry of entries) {
            if (entry.contentRect) {
              var width = entry.contentRect.width,
                height = entry.contentRect.height;
              try {
                watchInlineSize(width, height, entry.target);
              } catch {}
              entry = null;
            }
          }
        };
        if (!cm.inlineHTMLObserver) {
          cm.inlineHTMLObserver = new ResizeObserver(inlineObserverCallback);
        }

        cm.inlineHTMLObserver.observe(el);

        function onInlineMarkClear() {
          cm.inlineHTMLObserver.unobserve(el);
          marker.off("clear", onInlineMarkClear);
          stub.removeEventListener("click", breakFn);
          el.removeEventListener("click", breakFn);
          stub = null;
          el = null;
          marker.replacedWith = null;
          marker.widgetNode = null;
          marker = null;
        }

        setTimeout(function () {
          marker.on("clear", onInlineMarkClear);
        }, 0);
      } else {
        isBlock = true;
        stub.className = stubClass;
        /** use lineWidget to insert element */
        replacedWith = stub;
        // this causes any text selection to immediately stop if the cursor is coming out of a block html element
        // without this, the line widget will get duplicated on cursor selection. see issue #51
        if (cm.state.selectingText) cm.state.selectingText();
        var lineWidget_1;
        if (!cm.getLineHandle(from.line).widgets || cm.getLineHandle(from.line).widgets?.length === 0) {
          lineWidget_1 = cm.addLineWidget(to.line, el, {
            above: false,
            coverGutter: false,
            className: "rendered-html rendered-html-block rendered-widget",
            noHScroll: false,
            showIfHidden: false,
          });
        } else if (cm.getLineHandle(from.line).widgets?.length) {
          lineWidget_1 = cm.getLineHandle(from.line).widgets[0];
        } else {
          return;
        }
        var wrapperLine = from.line;
        cm.addLineClass(wrapperLine, "wrap", "rendered-html-block-wrapper");

        const blockHTMLObserverCallback = entries => {
          for (let entry of entries) {
            if (entry.contentRect) {
              try {
                updateWidgetByEl(entry.target);
              } catch {}
            }
          }
        };
        if (!cm.blockHTMLObserver) {
          cm.blockHTMLObserver = new ResizeObserver(blockHTMLObserverCallback);
        }
        cm.blockHTMLObserver.observe(el);
        // Marker is not created yet. Bind events later
        function onBlockClear() {
          marker.off("clear", onBlockClear);
          cm.blockHTMLObserver.unobserve(el);
          stub.removeEventListener("click", breakFn);
          el.removeEventListener("click", breakFn);
          stub = null;
          el = null;
          lineWidget_1.clear();
          lineWidget_1 = null;
          cm.removeLineClass(wrapperLine, "wrap", "rendered-html-block-wrapper");
          marker.replacedWith = null;
          marker.widgetNode = null;
          marker.associatedLineWidget = null;
          marker = null;
        }
        setTimeout(function () {
          marker.on("clear", onBlockClear);
        }, 0);
      }
      marker = cm.markText(from, to, {
        replacedWith: replacedWith,
        atomic: false,
        inclusiveLeft: isBlock,
        inclusiveRight: isBlock,
      });
      marker.associatedLineWidget = lineWidget_1;

      return marker;
    };
    FoldHTML.prototype.makeStub = function () {
      var ans = document.createElement("span");
      ans.setAttribute("class", stubClass);
      ans.textContent = this.stubText || "<HTML>";
      return ans;
    };
    return FoldHTML;
  })();
  exports.FoldHTML = FoldHTML;
  //#endregion
  /** ADDON GETTER (Singleton Pattern): a editor can have only one FoldHTML instance */
  exports.getAddon = core_1.Addon.Getter("FoldHTML", FoldHTML, exports.defaultOption /** if has options */);
});

const debug = (
  typeof process === 'object' &&
  process.env &&
  process.env.NODE_DEBUG &&
  /\bsemver\b/i.test(process.env.NODE_DEBUG)
) ? (...args) => console.error('SEMVER', ...args)
  : () => {};

var debug_1 = debug;

// Note: this is the semver.org version of the spec that it implements
// Not necessarily the package version of this code.
const SEMVER_SPEC_VERSION = '2.0.0';

const MAX_LENGTH$1 = 256;
const MAX_SAFE_INTEGER$1 = Number.MAX_SAFE_INTEGER ||
  /* istanbul ignore next */ 9007199254740991;

// Max safe segment length for coercion.
const MAX_SAFE_COMPONENT_LENGTH = 16;

var constants = {
  SEMVER_SPEC_VERSION,
  MAX_LENGTH: MAX_LENGTH$1,
  MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1,
  MAX_SAFE_COMPONENT_LENGTH
};

var re_1 = createCommonjsModule(function (module, exports) {
const { MAX_SAFE_COMPONENT_LENGTH } = constants;

exports = module.exports = {};

// The actual regexps go on exports.re
const re = exports.re = [];
const src = exports.src = [];
const t = exports.t = {};
let R = 0;

const createToken = (name, value, isGlobal) => {
  const index = R++;
  debug_1(index, value);
  t[name] = index;
  src[index] = value;
  re[index] = new RegExp(value, isGlobal ? 'g' : undefined);
};

// The following Regular Expressions can be used for tokenizing,
// validating, and parsing SemVer version strings.

// ## Numeric Identifier
// A single `0`, or a non-zero digit followed by zero or more digits.

createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*');
createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+');

// ## Non-numeric Identifier
// Zero or more digits, followed by a letter or hyphen, and then zero or
// more letters, digits, or hyphens.

createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*');

// ## Main Version
// Three dot-separated numeric identifiers.

createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` +
                   `(${src[t.NUMERICIDENTIFIER]})\\.` +
                   `(${src[t.NUMERICIDENTIFIER]})`);

createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
                        `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
                        `(${src[t.NUMERICIDENTIFIERLOOSE]})`);

// ## Pre-release Version Identifier
// A numeric identifier, or a non-numeric identifier.

createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER]
}|${src[t.NONNUMERICIDENTIFIER]})`);

createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE]
}|${src[t.NONNUMERICIDENTIFIER]})`);

// ## Pre-release Version
// Hyphen, followed by one or more dot-separated pre-release version
// identifiers.

createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER]
}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`);

createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`);

// ## Build Metadata Identifier
// Any combination of digits, letters, or hyphens.

createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+');

// ## Build Metadata
// Plus sign, followed by one or more period-separated build metadata
// identifiers.

createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER]
}(?:\\.${src[t.BUILDIDENTIFIER]})*))`);

// ## Full Version String
// A main version, followed optionally by a pre-release version and
// build metadata.

// Note that the only major, minor, patch, and pre-release sections of
// the version string are capturing groups.  The build metadata is not a
// capturing group, because it should not ever be used in version
// comparison.

createToken('FULLPLAIN', `v?${src[t.MAINVERSION]
}${src[t.PRERELEASE]}?${
  src[t.BUILD]}?`);

createToken('FULL', `^${src[t.FULLPLAIN]}$`);

// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
// common in the npm registry.
createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE]
}${src[t.PRERELEASELOOSE]}?${
  src[t.BUILD]}?`);

createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`);

createToken('GTLT', '((?:<|>)?=?)');

// Something like "2.*" or "1.2.x".
// Note that "x.x" is a valid xRange identifer, meaning "any version"
// Only the first item is strictly required.
createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`);

createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` +
                   `(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
                   `(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
                   `(?:${src[t.PRERELEASE]})?${
                     src[t.BUILD]}?` +
                   `)?)?`);

createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` +
                        `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
                        `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
                        `(?:${src[t.PRERELEASELOOSE]})?${
                          src[t.BUILD]}?` +
                        `)?)?`);

createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`);
createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`);

// Coercion.
// Extract anything that could conceivably be a part of a valid semver
createToken('COERCE', `${'(^|[^\\d])' +
              '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` +
              `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
              `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
              `(?:$|[^\\d])`);
createToken('COERCERTL', src[t.COERCE], true);

// Tilde ranges.
// Meaning is "reasonably at or greater than"
createToken('LONETILDE', '(?:~>?)');

createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true);
exports.tildeTrimReplace = '$1~';

createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);
createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);

// Caret ranges.
// Meaning is "at least and backwards compatible with"
createToken('LONECARET', '(?:\\^)');

createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true);
exports.caretTrimReplace = '$1^';

createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);
createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);

// A simple gt/lt/eq thing, or just "" to indicate "any version"
createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`);
createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`);

// An expression to strip any whitespace between the gtlt and the thing
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);
exports.comparatorTrimReplace = '$1$2$3';

// Something like `1.2.3 - 1.2.4`
// Note that these all use the loose form, because they'll be
// checked against either the strict or loose comparator form
// later.
createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` +
                   `\\s+-\\s+` +
                   `(${src[t.XRANGEPLAIN]})` +
                   `\\s*$`);

createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
                        `\\s+-\\s+` +
                        `(${src[t.XRANGEPLAINLOOSE]})` +
                        `\\s*$`);

// Star ranges basically just allow anything at all.
createToken('STAR', '(<|>)?=?\\s*\\*');
// >=0.0.0 is like a star
createToken('GTE0', '^\\s*>=\\s*0\.0\.0\\s*$');
createToken('GTE0PRE', '^\\s*>=\\s*0\.0\.0-0\\s*$');
});

// parse out just the options we care about so we always get a consistent
// obj with keys in a consistent order.
const opts = ['includePrerelease', 'loose', 'rtl'];
const parseOptions = options =>
  !options ? {}
  : typeof options !== 'object' ? { loose: true }
  : opts.filter(k => options[k]).reduce((options, k) => {
    options[k] = true;
    return options
  }, {});
var parseOptions_1 = parseOptions;

const numeric = /^[0-9]+$/;
const compareIdentifiers$1 = (a, b) => {
  const anum = numeric.test(a);
  const bnum = numeric.test(b);

  if (anum && bnum) {
    a = +a;
    b = +b;
  }

  return a === b ? 0
    : (anum && !bnum) ? -1
    : (bnum && !anum) ? 1
    : a < b ? -1
    : 1
};

const rcompareIdentifiers = (a, b) => compareIdentifiers$1(b, a);

var identifiers = {
  compareIdentifiers: compareIdentifiers$1,
  rcompareIdentifiers
};

const { MAX_LENGTH, MAX_SAFE_INTEGER } = constants;
const { re, t } = re_1;


const { compareIdentifiers } = identifiers;
class SemVer {
  constructor (version, options) {
    options = parseOptions_1(options);

    if (version instanceof SemVer) {
      if (version.loose === !!options.loose &&
          version.includePrerelease === !!options.includePrerelease) {
        return version
      } else {
        version = version.version;
      }
    } else if (typeof version !== 'string') {
      throw new TypeError(`Invalid Version: ${version}`)
    }

    if (version.length > MAX_LENGTH) {
      throw new TypeError(
        `version is longer than ${MAX_LENGTH} characters`
      )
    }

    debug_1('SemVer', version, options);
    this.options = options;
    this.loose = !!options.loose;
    // this isn't actually relevant for versions, but keep it so that we
    // don't run into trouble passing this.options around.
    this.includePrerelease = !!options.includePrerelease;

    const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]);

    if (!m) {
      throw new TypeError(`Invalid Version: ${version}`)
    }

    this.raw = version;

    // these are actually numbers
    this.major = +m[1];
    this.minor = +m[2];
    this.patch = +m[3];

    if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
      throw new TypeError('Invalid major version')
    }

    if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
      throw new TypeError('Invalid minor version')
    }

    if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
      throw new TypeError('Invalid patch version')
    }

    // numberify any prerelease numeric ids
    if (!m[4]) {
      this.prerelease = [];
    } else {
      this.prerelease = m[4].split('.').map((id) => {
        if (/^[0-9]+$/.test(id)) {
          const num = +id;
          if (num >= 0 && num < MAX_SAFE_INTEGER) {
            return num
          }
        }
        return id
      });
    }

    this.build = m[5] ? m[5].split('.') : [];
    this.format();
  }

  format () {
    this.version = `${this.major}.${this.minor}.${this.patch}`;
    if (this.prerelease.length) {
      this.version += `-${this.prerelease.join('.')}`;
    }
    return this.version
  }

  toString () {
    return this.version
  }

  compare (other) {
    debug_1('SemVer.compare', this.version, this.options, other);
    if (!(other instanceof SemVer)) {
      if (typeof other === 'string' && other === this.version) {
        return 0
      }
      other = new SemVer(other, this.options);
    }

    if (other.version === this.version) {
      return 0
    }

    return this.compareMain(other) || this.comparePre(other)
  }

  compareMain (other) {
    if (!(other instanceof SemVer)) {
      other = new SemVer(other, this.options);
    }

    return (
      compareIdentifiers(this.major, other.major) ||
      compareIdentifiers(this.minor, other.minor) ||
      compareIdentifiers(this.patch, other.patch)
    )
  }

  comparePre (other) {
    if (!(other instanceof SemVer)) {
      other = new SemVer(other, this.options);
    }

    // NOT having a prerelease is > having one
    if (this.prerelease.length && !other.prerelease.length) {
      return -1
    } else if (!this.prerelease.length && other.prerelease.length) {
      return 1
    } else if (!this.prerelease.length && !other.prerelease.length) {
      return 0
    }

    let i = 0;
    do {
      const a = this.prerelease[i];
      const b = other.prerelease[i];
      debug_1('prerelease compare', i, a, b);
      if (a === undefined && b === undefined) {
        return 0
      } else if (b === undefined) {
        return 1
      } else if (a === undefined) {
        return -1
      } else if (a === b) {
        continue
      } else {
        return compareIdentifiers(a, b)
      }
    } while (++i)
  }

  compareBuild (other) {
    if (!(other instanceof SemVer)) {
      other = new SemVer(other, this.options);
    }

    let i = 0;
    do {
      const a = this.build[i];
      const b = other.build[i];
      debug_1('prerelease compare', i, a, b);
      if (a === undefined && b === undefined) {
        return 0
      } else if (b === undefined) {
        return 1
      } else if (a === undefined) {
        return -1
      } else if (a === b) {
        continue
      } else {
        return compareIdentifiers(a, b)
      }
    } while (++i)
  }

  // preminor will bump the version up to the next minor release, and immediately
  // down to pre-release. premajor and prepatch work the same way.
  inc (release, identifier) {
    switch (release) {
      case 'premajor':
        this.prerelease.length = 0;
        this.patch = 0;
        this.minor = 0;
        this.major++;
        this.inc('pre', identifier);
        break
      case 'preminor':
        this.prerelease.length = 0;
        this.patch = 0;
        this.minor++;
        this.inc('pre', identifier);
        break
      case 'prepatch':
        // If this is already a prerelease, it will bump to the next version
        // drop any prereleases that might already exist, since they are not
        // relevant at this point.
        this.prerelease.length = 0;
        this.inc('patch', identifier);
        this.inc('pre', identifier);
        break
      // If the input is a non-prerelease version, this acts the same as
      // prepatch.
      case 'prerelease':
        if (this.prerelease.length === 0) {
          this.inc('patch', identifier);
        }
        this.inc('pre', identifier);
        break

      case 'major':
        // If this is a pre-major version, bump up to the same major version.
        // Otherwise increment major.
        // 1.0.0-5 bumps to 1.0.0
        // 1.1.0 bumps to 2.0.0
        if (
          this.minor !== 0 ||
          this.patch !== 0 ||
          this.prerelease.length === 0
        ) {
          this.major++;
        }
        this.minor = 0;
        this.patch = 0;
        this.prerelease = [];
        break
      case 'minor':
        // If this is a pre-minor version, bump up to the same minor version.
        // Otherwise increment minor.
        // 1.2.0-5 bumps to 1.2.0
        // 1.2.1 bumps to 1.3.0
        if (this.patch !== 0 || this.prerelease.length === 0) {
          this.minor++;
        }
        this.patch = 0;
        this.prerelease = [];
        break
      case 'patch':
        // If this is not a pre-release version, it will increment the patch.
        // If it is a pre-release it will bump up to the same patch version.
        // 1.2.0-5 patches to 1.2.0
        // 1.2.0 patches to 1.2.1
        if (this.prerelease.length === 0) {
          this.patch++;
        }
        this.prerelease = [];
        break
      // This probably shouldn't be used publicly.
      // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
      case 'pre':
        if (this.prerelease.length === 0) {
          this.prerelease = [0];
        } else {
          let i = this.prerelease.length;
          while (--i >= 0) {
            if (typeof this.prerelease[i] === 'number') {
              this.prerelease[i]++;
              i = -2;
            }
          }
          if (i === -1) {
            // didn't increment anything
            this.prerelease.push(0);
          }
        }
        if (identifier) {
          // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
          // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
          if (this.prerelease[0] === identifier) {
            if (isNaN(this.prerelease[1])) {
              this.prerelease = [identifier, 0];
            }
          } else {
            this.prerelease = [identifier, 0];
          }
        }
        break

      default:
        throw new Error(`invalid increment argument: ${release}`)
    }
    this.format();
    this.raw = this.version;
    return this
  }
}

var semver = SemVer;

const compare = (a, b, loose) =>
  new semver(a, loose).compare(new semver(b, loose));

var compare_1 = compare;

const gte = (a, b, loose) => compare_1(a, b, loose) >= 0;
var gte_1 = gte;

// HyperMD, copyright (c) by laobubu

(function (mod) {
  mod(null, {}, CodeMirror, HyperMD.Fold, HyperMD.FoldCode);
})(function (require, exports, CodeMirror, fold_1, fold_code_1) {
  var dependencyCheck = function () {
    const plugin = window.app.plugins.getPlugin("obsidian-admonition");
    return plugin?._loaded && gte_1(plugin?.manifest.version, "6.3.6") ? true : false;
  };
  var AdmonitionRenderer = function (code, info) {
    const adType = info.lang.substring(3);
    var el = document.createElement("div");
    var asyncRenderer;
    var ctx = new require$$0.Component();
    ctx.sourcePath = info.editor.state.fileName;
    if (dependencyCheck()) {
      asyncRenderer = async () => {
        try {
          window.app.plugins.getPlugin("obsidian-admonition").postprocessor(adType, code, el, ctx);
          ctx.load();
        } catch (error) {
          el.innerText = "Failed to render Admonition: " + error;
        }
        function unload() {
          ctx._children[0].unload();
          ctx.unload();
          ctx._children[0] = null;
          ctx._children = null;
        }
        info.unload = unload;
      };
    } else {
      el.innerText = "Error: Unable to find the Admonitions plugin or Admonition version not 6.3.6 or higher";
    }
    return {
      element: el,
      asyncRenderer: asyncRenderer,
    };
  };
  exports.AdmonitionRenderer = AdmonitionRenderer;

  CodeMirror.defineOption("admonition", null, function (cm) {
    fold_code_1.getAddon(cm).clear("admonition");
    fold_1.getAddon(cm).startFold();
  });
  fold_code_1.registerRenderer({
    name: "admonition",
    pattern: /^ad-(?:[a-z]+)$/i,
    renderer: exports.AdmonitionRenderer,
    suggested: false,
  });
});

// HyperMD, copyright (c) by laobubu

(function (mod) {
  mod(null, {}, CodeMirror, HyperMD.Fold, HyperMD.FoldCode);
})(function (require, exports, CodeMirror, fold_1, fold_code_1) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.ChartRenderer = void 0;
  var dependencyCheck = function () {
    return window.app.plugins.getPlugin("obsidian-charts")?._loaded ? true : false;
  };
  var ChartRenderer = function (code, info) {
    var el = document.createElement("div");
    var ctx = new require$$0.Component();
    if (dependencyCheck()) {
      var asyncRenderer = () => {
        try {
          window.app.plugins.getPlugin("obsidian-charts").postprocessor(code, el, ctx);
          ctx.load();
          // el = ctx._children[0].containerEl;
        } catch (error) {
          el.innerText = "Failed to render Chart: " + error;
        }
      };
    } else {
      el.innerText = "Error: Unable to find the Obsidian Charts plugin";
    }
    // charts have an element detach listener that causes charts to disappear when they leave
    // the codemirror viewport. this redraw function forces them to redraw once they're back
    // in the visible viewport
    info.redraw = function () {
      try {
        ctx._children[0].chart.attached = true;
        ctx._children[0].chart.resize();
      } catch {}
    };
    function unload() {
      ctx._children[0].unload();
      ctx.unload();
      ctx._children[0] = null;
      ctx._children = null;
    }
    info.unload = unload;
    return {
      element: el,
      asyncRenderer: asyncRenderer,
    };
  };
  exports.ChartRenderer = ChartRenderer;
  {
    CodeMirror.defineOption("chart", null, function (cm) {
      fold_code_1.getAddon(cm).clear("chart");
      fold_1.getAddon(cm).startFold();
    });
    fold_code_1.registerRenderer({
      name: "chart",
      pattern: /^chart$/i,
      renderer: exports.ChartRenderer,
      suggested: true,
    });
  }
});

// HyperMD, copyright (c) by laobubu
// Distributed under an MIT license: http://laobubu.net/HyperMD/LICENSE
//
// POWERPACK for "addon/fold-code"
//
// This module provides `QueryRenderer` for FoldCode addon

(function (mod) {
  mod(null, {}, CodeMirror, HyperMD.Fold, HyperMD.FoldCode);
})(function (require, exports, CodeMirror, fold_1, fold_code_1) {
  var dependencyCheck = function () {
    return window.app.internalPlugins.getPluginById("global-search")?._loaded;
  };
  const purifySettings = {
    ALLOW_UNKNOWN_PROTOCOLS: true,
    IN_PLACE: true,
    // RETURN_DOM_FRAGMENT: true,
    // RETURN_DOM_IMPORT: true,
    FORBID_TAGS: ["style"],
    ADD_TAGS: ["iframe"],
    ADD_ATTR: ["frameborder", "allowfullscreen", "allow", "aria-label-position"],
  };
  var QueryRenderer = function (code, info) {
    // Welcome to the very hacky query renderer code
    // Here we pretend to be a preview mode section and steal the rendered element
    var queryEl = document.createElement("div");
    if (dependencyCheck()) {
      var promises = [];
      const previewMode = window.app.workspace.activeLeaf.view.previewMode,
        renderer = previewMode.renderer;
      queryEl.innerHTML = `<pre><code class="language-query">${code}</code></pre>`;
      // Sanitize the HTML to make sure there's no funny business
      window.DOMPurify.sanitize(queryEl, purifySettings);
      renderer.owner.postProcess({ el: queryEl }, promises, renderer.frontmatter);
      var targetChild;
      Array.from(renderer.owner._children).forEach(child => {
        if (child.containerEl === queryEl.firstChild) {
          targetChild = child;
        }
      });
      // But wait... we have to clean up after ourselves so that we don't cause a memory leak
      // We do so by removing the node we just created from the preview mode's child list
      function unload() {
        previewMode.removeChild(targetChild);
        renderer.owner._children.remove(targetChild);
        targetChild.unload();
        targetChild = null;
      }
      info.unload = unload;
      // we naively wait here because search query results are async
      // if we clean up too fast, we don't get results
    } else {
      queryEl.innerText = "Error: Unable to find the Global Search plugin";
    }
    return {
      element: queryEl,
      asyncRenderer: null,
    };
  };
  exports.QueryRenderer = QueryRenderer;

  CodeMirror.defineOption("query", null, function (cm) {
    fold_code_1.getAddon(cm).clear("query");
    fold_1.getAddon(cm).startFold();
  });
  fold_code_1.registerRenderer({
    name: "query",
    pattern: /^query$/i,
    renderer: exports.QueryRenderer,
    suggested: false,
  });
});

// HyperMD, copyright (c) by laobubu

(function (mod) {
  mod(null, {}, CodeMirror, HyperMD.Fold, HyperMD.FoldCode);
})(function (require, exports, CodeMirror, fold_1, fold_code_1) {
  var dependencyCheck = function () {
    const plugin = window.app.plugins.getPlugin("dataview");
    return plugin?._loaded && gte_1(plugin?.manifest.version, "0.4.17") ? true : false;
  };
  var DataviewRenderer = function (code, info) {
    var el = document.createElement("div");
    var ctx = new require$$0.Component();
    ctx.sourcePath = info.editor.state.fileName;
    if (dependencyCheck()) {
      if (info.lang === "dataview") {
        window.app.plugins.getPlugin("dataview").dataview(code, el, ctx, ctx.sourcePath);
      } else if (info.lang === "dataviewjs") {
        window.app.plugins.getPlugin("dataview").dataviewjs(code, el, ctx, ctx.sourcePath);
      }
      ctx.load();
      el = ctx._children[0].containerEl;
      function unload() {
        ctx._children[0].unload();
        ctx.unload();
        ctx._children[0] = null;
        ctx._children = null;
      }
      info.unload = unload;
      return {
        element: el,
        asyncRenderer: null,
      };
    } else {
      el.innerText = "Error: Unable to find the Dataview plugin or version not 0.4.17 or greater";
    }

    return {
      element: el,
      asyncRenderer: null,
    };
  };
  exports.DataviewRenderer = DataviewRenderer;
  CodeMirror.defineOption("dataview", null, function (cm) {
    fold_code_1.getAddon(cm).clear("dataview");
    fold_1.getAddon(cm).startFold();
  });
  fold_code_1.registerRenderer({
    name: "dataview",
    pattern: /^dataview(js)?$/i,
    renderer: exports.DataviewRenderer,
    suggested: false,
  });
});

// HyperMD, copyright (c) by laobubu

(function (mod) {
  mod(null, {}, CodeMirror, HyperMD.Fold, HyperMD.FoldCode);
})(function (require, exports, CodeMirror, fold_1, fold_code_1) {
  var dependencyCheck = function () {
    const plugin = window.app.plugins.getPlugin("obsidian-tasks-plugin");
    return plugin?._loaded && gte_1(plugin?.manifest.version, "1.4.0") ? true : false;
  };
  var TasksRenderer = function (code, info) {
    var el = document.createElement("div");
    var ctx = new require$$0.Component();
    ctx.sourcePath = info.editor.filePath;
    if (dependencyCheck()) {
      const renderer = window.app.plugins.getPlugin("obsidian-tasks-plugin").queryRenderer.addQueryRenderChild;
      renderer(code, el, ctx);
      ctx.load();
      el = ctx._children[0].containerEl;
      function unload() {
        ctx._children[0].unload();
        ctx.unload();
        ctx._children[0] = null;
        ctx._children = null;
      }
      info.unload = unload;
      return {
        element: el,
        asyncRenderer: null,
      };
    } else {
      el.innerText = "Error: Unable to find the Tasks plugin or version not 1.4.0 or greater";
    }

    return {
      element: el,
      asyncRenderer: null,
    };
  };
  exports.TasksRenderer = TasksRenderer;
  CodeMirror.defineOption("tasks", null, function (cm) {
    fold_code_1.getAddon(cm).clear("tasks");
    fold_1.getAddon(cm).startFold();
  });
  fold_code_1.registerRenderer({
    name: "tasks",
    pattern: /^tasks$/i,
    renderer: exports.TasksRenderer,
    suggested: false,
  });
});

// HyperMD, copyright (c) by laobubu

(function (mod) {
  mod(null, {}, CodeMirror, HyperMD.Fold, HyperMD.ReadLink);
})(function (require, exports, CodeMirror, fold_1) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.EmbedFolder = void 0;
  var debug = false;
  var EmbedFolder = function (stream, token) {
    var cm = stream.cm;
    var embedRE = /(\bformatting-embed\b)/;
    var extRE = /\.(jpe?g|png|gif|svg|bmp)/;
    var urlRE = /(\bformatting-link-string\b)|(\bformatting-link\b)/; // matches the parentheses
    if (embedRE.test(token.type) && (token.string === "!" || token.string === "![[")) {
      var replacedWith;
      var lineNo = stream.lineNo;
      // find the begin and end of url part
      var since = { line: lineNo, ch: token.start };
      var url_begin = stream.findNext(urlRE, 0, since);
      if (!url_begin) {
        return null;
      }
      var url_end = stream.findNext(urlRE, url_begin.i_token + 1);
      var rawurl = cm.getRange({ line: lineNo, ch: url_begin.token.end }, { line: lineNo, ch: url_end.token.start });
      // bail if the embed is an image
      if (extRE.test(rawurl)) return null;
      var from = { line: lineNo, ch: token.start };
      var to = { line: lineNo, ch: url_end.token.end };
      var inlineMode = from.ch != 0 || to.ch < cm.getLine(to.line).length;
      var rngReq = stream.requestRange(from, to, from, from);
      var stubClassOmittable = "hmd-fold-embed-stub omittable";
      if (rngReq === fold_1.RequestRangeResult.OK) {
        var info = {
          editor: cm,
          lang: "embed",
          attributes: null,
          marker: null,
          lineWidget: null,
          el: null,
          break: undefined_function,
          changed: undefined_function,
        };
        var breakFn = function () {
          return fold_1.breakMark(cm, marker);
        };
        // Renderer
        var code = cm.getRange(from, to);
        var el = document.createElement("div");
        var ctx = new require$$0.Component();
        ctx.sourcePath = cm.state.fileName;
        const previewMode = window.app.workspace.activeLeaf.view.previewMode,
          renderer = previewMode.renderer;
        try {
          // process the markdown
          require$$0.MarkdownRenderer.renderMarkdown(code, el, cm.state.fileName, ctx);
          // kick off the preview mode process that renders the embed
          renderer.owner.postProcess({ el: el }, [], renderer.frontmatter);
          var targetChild;
          Array.from(renderer.owner._children).forEach(child => {
            if (child.containerEl === el.querySelector(".markdown-embed-content")) {
              targetChild = child;
            }
          });
        } catch (error) {
          el.innerText = "Failed to render embed: " + error;
        }
        function unload() {
          previewMode.removeChild(targetChild);
          renderer.owner._children.remove(targetChild);
          targetChild.unload();
          targetChild = null;
        }
        info.unload = unload;
        var type = "embed";
        var stub = document.createElement("span");
        stub.className = stubClass;
        stub.textContent = "<EMBED>";
        stub.addEventListener("click", breakFn, false);
        var marker, lineWidget;
        function updateWidgetByEl(targetEl) {
          const found = cm.hmd.Fold.folded.embed?.filter(
            el => el.replacedWith?.contains(targetEl) || el.associatedLineWidget?.node?.contains(targetEl)
          );
          if (found?.length) {
            found[0].changed();
          }
        }
        var updateWidgetByElDebounced = require$$0.debounce(updateWidgetByEl, 250);
        function watchInlineSize(w, h, el) {
          try {
            if (debug) ;
            updateWidgetByElDebounced(el);
          } catch (err) {
          }
        }

        const embedObserverCallback = entries => {
          for (let entry of entries) {
            if (entry.contentRect) {
              var width = entry.contentRect.width,
                height = entry.contentRect.height;
              try {
                watchInlineSize(width, height, entry.target);
              } catch (err) {
              }
              entry = null;
            }
          }
        };

        if (!cm.embedObserver) {
          cm.embedObserver = new ResizeObserver(embedObserverCallback);
        }

        if (inlineMode) {
          stub.className = stubClassOmittable;

          var displayType, embedType;
          var span = document.createElement("span");
          if (code.contains("^")) {
            displayType = "inline";
            embedType = "block";
          } else if (code.contains("#")) {
            displayType = "flex";
            embedType = "header";
          } else {
            displayType = "flex";
            embedType = "page";
          }
          span.setAttribute("class", "rendered-inline-embed rendered-widget embed-type-" + embedType);
          span.setAttribute("style", `display: ${displayType};`);
          if (token.start < 7) {
            stub.addClass("flip-stub");
          }
          span.appendChild(stub);
          span.appendChild(el);
          var targetFile = rawurl.match(/^([^#]*)#/);
          if (targetFile && targetFile.length > 1 && targetFile[1]) {
            targetFile = targetFile[1];
          } else {
            targetFile = cm.state.fileName?.replace(/\.md$/, "");
          }
          span.setAttribute("aria-label", targetFile);
          el.onClickEvent = function (e, t) {
            this.addEventListener("click", e, t), this.addEventListener("auxclick", e, t);
          };
          el.onClickEvent(function (e) {
            if (e.composedPath()[0].className === "internal-link") return;
            (0 !== e.button && 1 !== e.button) ||
              (e.preventDefault(), window.app.workspace.openLinkText(rawurl, cm.state.fileName, false));
          });

          replacedWith = span;

          cm.embedObserver.observe(span);
          info.changed = function () {
            try {
              marker.changed();
            } catch (err) {
            }
          };
          info.break = function () {
            fold_1.breakMark(cm, marker);
          };
          function onInlineMarkClear() {
            cm.embedObserver.unobserve(span);
            if (info.unload) {
              try {
                info.unload();
                if (debug) ;
              } catch (err) {
              }
            }
            // var markers = cm.hmd.Fold.folded.embed;
            // var idx;
            // if (markers && (idx = markers.indexOf(marker)) !== -1) {
            //   if (debug) console.log("found inline marker in registry", markers, marker);
            //   markers.splice(idx, 1);
            // } else {
            //   if (debug) console.log("unable to find inline wiget in fold registry", markers, marker);
            // }
            marker.off("clear", onInlineMarkClear);
            stub.removeEventListener("click", breakFn);
            el.removeEventListener("click", breakFn);
            stub = null;
            el = null;
            marker.replacedWith = null;
            marker.widgetNode = null;
            marker = null;
            info = null;
          }

          setTimeout(function () {
            marker.on("clear", onInlineMarkClear);
          }, 100);
        } else {
          // Block Placement
          var $wrapper = document.createElement("div");
          $wrapper.className = contentClass;
          $wrapper.style.minHeight = "1em";
          $wrapper.appendChild(el);
          if (code.contains("^")) {
            displayType = "inline";
            embedType = "block";
          } else if (code.contains("#")) {
            displayType = "flex";
            embedType = "header";
          } else {
            displayType = "flex";
            embedType = "page";
          }
          $wrapper.setAttribute("class", "rendered-embed rendered-widget embed-type-" + embedType);
          if (!cm.getLineHandle(lineNo).widgets || cm.getLineHandle(lineNo).widgets?.length === 0) {
            lineWidget = cm.addLineWidget(to.line, $wrapper, {
              above: false,
              coverGutter: false,
              handleMouseEvents: false,
              className: "rendered-block-embed rendered-widget",
              noHScroll: false,
              showIfHidden: false,
            });
          } else if (cm.getLineHandle(lineNo).widgets?.length) {
            lineWidget = cm.getLineHandle(lineNo).widgets[0];
          } else {
            return;
          }

          var wrapperLine = stream.lineNo;
          cm.addLineClass(wrapperLine, "wrap", `rendered-${type}-wrapper`);

          cm.embedObserver.observe($wrapper);

          replacedWith = stub;

          info.changed = function () {
            try {
              lineWidget.changed();
            } catch (err) {
            }
          };
          info.break = function () {
            cm.embedObserver.unobserve($wrapper);
            fold_1.breakMark(cm, marker);
          };
          stub.addEventListener("click", info.break, false);
          var redraw = info.redraw;
          if (redraw) {
            lineWidget.on("redraw", info.redraw);
          }
          function onCodeBlockClear() {
            cm.embedObserver.unobserve($wrapper);
            if (redraw) {
              lineWidget.off("redraw", info.redraw);
            }
            marker.off("clear", onCodeBlockClear);
            stub.removeEventListener("click", info.break);
            if (info.unload) {
              try {
                info.unload();
                if (debug) ;
              } catch (err) {
              }
            }
            var markers = cm.hmd.Fold.folded.embed;
            var idx;
            if (markers && (idx = markers.indexOf(marker)) !== -1) {
              markers.splice(idx, 1);
            }
            cm.removeLineClass(wrapperLine, "wrap", `rendered-${type}-wrapper`);
            cm.removeLineClass(wrapperLine, "wrap", "rendered-code-block-wrapper");
            lineWidget.clear();
            lineWidget = null;
            marker.replacedWith = null;
            marker.widgetNode = null;
            marker = null;
            info.unload = null;
            info = null;
          }
          setTimeout(function () {
            marker.on("clear", onCodeBlockClear);
          }, 0);
        }
        marker = cm.markText(from, to, {
          replacedWith: replacedWith,
          inclusiveLeft: false,
          inclusiveRight: false,
        });
        marker.associatedLineWidget = lineWidget;
        setTimeout(() => {
          marker.changed();
        }, 0);
        return marker;
      }
    }
    return null;
  };
  var contentClass = "hmd-fold-embed-content hmd-fold-embed"; // + renderer_type
  var stubClass = "hmd-fold-embed-stub hmd-fold-embed"; // + renderer_type
  // eslint-disable-next-line @typescript-eslint/no-empty-function
  var undefined_function = function () {};
  exports.EmbedFolder = EmbedFolder;
  fold_1.registerFolder("embed", exports.EmbedFolder, true);
});

var lib = createCommonjsModule(function (module, exports) {
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source visit the plugins github repository
*/

var t=Object.create;var o=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var r=n=>o(n,"__esModule",{value:!0});var g=(n,e)=>{r(n);for(var i in e)o(n,i,{get:e[i],enumerable:!0});},c=(n,e,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of p(e))!l.call(n,s)&&s!=="default"&&o(n,s,{get:()=>e[s],enumerable:!(i=a(e,s))||i.enumerable});return n},u=n=>c(r(o(n!=null?t(d(n)):{},"default",n&&n.__esModule&&"default"in n?{get:()=>n.default,enumerable:!0}:{value:n,enumerable:!0})),n);g(exports,{getApi:()=>P,isPluginEnabled:()=>f});u(require$$0__default["default"]);var P=n=>{var e;return n?(e=n.app.plugins.plugins["obsidian-icon-shortcodes"])==null?void 0:e.api:window.IconSCAPIv0},f=n=>n.app.plugins.enabledPlugins.has("obsidian-icon-shortcodes");
});

createCommonjsModule(function (module) {
// HyperMD, copyright (c) by laobubu
// Distributed under an MIT license: http://laobubu.net/HyperMD/LICENSE
//
// DESCRIPTION: Fold and render emoji :smile:
//
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { getApi } = lib;
(function (mod) {
  //[HyperMD] UMD patched!
  /*plain env*/ mod(
    null,
    (HyperMD.FoldEmoji = HyperMD.FoldEmoji || {}),
    CodeMirror,
    HyperMD,
    HyperMD.Fold
  );
})(function (require, exports, CodeMirror, core_1, fold_1) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.defaultDict =
    exports.defaultChecker =
    exports.defaultRenderer =
    exports.suggestedOption =
    exports.EmojiFolder =
    exports.getAddon =
    exports.defaultOption =
    exports.FoldEmoji =
      void 0;
  /********************************************************************************** */
  //#region Folder
  /**
   * Detect if a token is emoji and fold it
   *
   * @see FolderFunc in ./fold.ts
   */
  const EmojiPattern = /\+1|-1|[\w-]+/,
    AllowedChar = /^[\w-+]+$/;

  exports.EmojiFolder = function (stream, token) {
    if (token.string !== ":") return;
    const nextColon = stream.findNext((t) => t.string === ":", false),
      nextToken = stream.findNext(() => true);

    // if nearest colon is next token, it's not an emoji
    if (!nextToken || !nextColon || nextColon.i_token <= nextToken.i_token)
      return;

    const tokenType = token.type;
    let name = "";
    for (let i = stream.i_token + 1; i < nextColon.i_token; i++) {
      const t = stream.lineTokens[i];
      // if type of warpped tokens not the same as leading colon,
      // it's not an emoji
      if (t.type !== tokenType || !AllowedChar.test(t.string)) return;
      name += t.string;
    }
    // filter text that is too long to be shortcode
    if (name.length > 55) return;
    // filter using common shortcode pattern
    if (!EmojiPattern.test(name)) return;

    var cm = stream.cm;
    var addon = exports.getAddon(cm);
    if (!addon.isEmoji(name)) return null;

    var from = {
      line: stream.lineNo,
      ch: token.start,
    };
    var end = nextColon.token.end;
    var to = { line: stream.lineNo, ch: end };

    var reqAns = stream.requestRange(from, to);
    if (reqAns !== fold_1.RequestRangeResult.OK) return null;
    // now we are ready to fold and render!
    var marker = addon.foldEmoji(name, from, to);
    return marker;
  };
  //#endregion
  fold_1.registerFolder("emoji", exports.EmojiFolder, true);
  exports.defaultRenderer = (text) => {
    const icon = getApi()?.getIcon(text);
    if (!icon) {
      return null;
    } else if (typeof icon === "string") {
      return createSpan({ text: icon });
    } else {
      return icon;
    }
  };
  exports.defaultChecker = (text) => getApi()?.hasIcon(text) === true;
  exports.defaultOption = {
    myEmoji: {},
    emojiRenderer: exports.defaultRenderer,
    emojiChecker: exports.defaultChecker,
  };
  exports.suggestedOption = {};
  core_1.suggestedEditorConfig.hmdFoldEmoji = exports.suggestedOption;
  CodeMirror.defineOption(
    "hmdFoldEmoji",
    exports.defaultOption,
    function (cm, newVal) {
      ///// convert newVal's type to `Partial<Options>`, if it is not.
      if (!newVal) {
        newVal = {};
      }
      ///// apply config and write new values into cm
      var inst = exports.getAddon(cm);
      for (var k in exports.defaultOption) {
        inst[k] = k in newVal ? newVal[k] : exports.defaultOption[k];
      }
    }
  );
  //#endregion
  /********************************************************************************** */
  //#region Addon Class
  var FoldEmoji = /** @class */ (function (str) {
    function FoldEmoji(cm) {
      this.cm = cm;
      // options will be initialized to defaultOption when constructor is finished
    }
    FoldEmoji.prototype.isEmoji = function (text) {
      return text in this.myEmoji || this.emojiChecker(text);
    };
    FoldEmoji.prototype.foldEmoji = function (text, from, to) {
      var cm = this.cm;
      var el =
        (text in this.myEmoji && this.myEmoji[text](text)) ||
        this.emojiRenderer(text);
      if (!el || !el.tagName) return null;
      if (el.className.indexOf("hmd-emoji") === -1)
        el.className += " hmd-emoji";
      var marker = cm.markText(from, to, {
        replacedWith: el,
      });
      el.addEventListener(
        "click",
        fold_1.breakMark.bind(this, cm, marker, 1),
        false
      );
      if (el.tagName.toLowerCase() === "img") {
        el.addEventListener(
          "load",
          function () {
            return marker.changed();
          },
          false
        );
        el.addEventListener(
          "dragstart",
          function (ev) {
            return ev.preventDefault();
          },
          false
        );
      }
      return marker;
    };
    return FoldEmoji;
  })();
  exports.FoldEmoji = FoldEmoji;
  //#endregion
  /** ADDON GETTER (Singleton Pattern): a editor can have only one FoldEmoji instance */
  exports.getAddon = core_1.Addon.Getter(
    "FoldEmoji",
    FoldEmoji,
    exports.defaultOption /** if has options */
  );
});
//#endregion
});

// HyperMD, copyright (c) by laobubu

(function (mod) {
  mod(null, (HyperMD.FoldMath = HyperMD.FoldMath || {}), CodeMirror, HyperMD, HyperMD.Fold);
})(function (require, exports, CodeMirror, core_1, fold_1) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getAddon =
    exports.FoldMath =
    exports.suggestedOption =
    exports.defaultOption =
    // exports.DumbRenderer =
    exports.insertMathMark =
    exports.MathFolder =
      void 0;
  /********************************************************************************** */
  //#region Exports
  /**
   * Detect if a token is a beginning of Math, and fold it!
   *
   * @see FolderFunc in ./fold.ts
   */
  var MathFolder = function (stream, token) {
    var mathBeginRE = /formatting-math-begin\b/;
    if (!mathBeginRE.test(token.type)) return null;
    var cm = stream.cm;
    var line = stream.lineNo;
    var maySpanLines = /math-block\b/.test(token.type); // $$ may span lines!
    var tokenLength = maySpanLines ? 2 : 1; // "$$" or "$"
    // CodeMirror GFM mode split "$$" into two tokens, so do a extra check.
    if (tokenLength == 2 && token.string.length == 1) {
      var nextToken = stream.lineTokens[stream.i_token + 1];
      if (!nextToken || !mathBeginRE.test(nextToken.type)) return null;
    }
    // Find the position of the "$" tail and compose a range
    var end_info = stream.findNext(/formatting-math-end\b/, maySpanLines);
    var from = { line: line, ch: token.start };
    var to;
    var noEndingToken = false;
    if (end_info) {
      to = { line: end_info.lineNo, ch: end_info.token.start + tokenLength };
    } else if (maySpanLines) {
      // end not found, but this is a multi-line math block.
      // fold to the end of doc
      var lastLineNo = cm.lastLine();
      to = { line: lastLineNo, ch: cm.getLine(lastLineNo).length };
      noEndingToken = true;
    } else {
      // Hmm... corrupted math ?
      return null;
    }
    // Range is ready. request the range
    var expr_from = { line: from.line, ch: from.ch + tokenLength };
    var expr_to = {
      line: to.line,
      ch: to.ch - (noEndingToken ? 0 : tokenLength),
    };
    var expr = cm.getRange(expr_from, expr_to).trim();
    var foldMathAddon = exports.getAddon(cm);
    var reqAns = stream.requestRange(from, to);
    if (reqAns !== fold_1.RequestRangeResult.OK) {
      if (reqAns === fold_1.RequestRangeResult.CURSOR_INSIDE) foldMathAddon.editingExpr = expr; // try to trig preview event
      return null;
    }
    // Now let's make a math widget!
    var isDisplayMode = tokenLength > 1; // && from.ch == 0 && (noEndingToken || to.ch >= cm.getLine(to.line).length);
    var marker = insertMathMark(cm, from, to, expr, tokenLength, isDisplayMode);
    foldMathAddon.editingExpr = null; // try to hide preview
    return marker;
  };
  exports.MathFolder = MathFolder;
  /**
   * Insert a TextMarker, and try to render it with configured MathRenderer.
   */
  function insertMathMark(cm, p1, p2, expression, tokenLength, isDisplayMode) {
    var span = document.createElement("span");
    span.setAttribute("class", "hmd-fold-math math-" + (isDisplayMode ? 2 : 1));
    span.setAttribute("title", expression);
    var mathPlaceholder = document.createElement("span");
    mathPlaceholder.setAttribute("class", "hmd-fold-math-placeholder");
    mathPlaceholder.textContent = expression;
    span.appendChild(mathPlaceholder);
    var marker = cm.markText(p1, p2, {
      replacedWith: span,
    });
    span.addEventListener(
      "click",
      function () {
        return fold_1.breakMark(cm, marker, tokenLength);
      },
      false
    );
    var foldMathAddon = exports.getAddon(cm);
    var mathRenderer = foldMathAddon.createRenderer(span, isDisplayMode ? "display" : "");
    mathRenderer.onChanged = function () {
      //   if (mathPlaceholder) {
      //     span.removeChild(mathPlaceholder);
      //     mathPlaceholder = null;
      //   }
      marker.changed();
    };
    marker.on("clear", function () {
      mathRenderer.clear();
    });
    marker["mathRenderer"] = mathRenderer;
    core_1.tryToRun(
      function () {
        if (!mathRenderer.isReady()) return false;
        mathRenderer.startRender(expression);
        return true;
      },
      5,
      function () {
        // if failed 5 times...
        marker.clear();
      }
    );
    return marker;
  }
  exports.insertMathMark = insertMathMark;
  //#endregion
  fold_1.registerFolder("math", exports.MathFolder, true);
  /********************************************************************************** */
  //#region Mathjax Renderer
  var MathjaxRenderer = /** @class */ (function () {
    function MathjaxRenderer(container, mode) {
      this.container = container;
      this.container.empty();
      this.isDisplay = mode === "display";
      var elClass = "hmd-math-mathjax";
      if (mode) elClass += " hmd-math-mathjax-" + mode;
      var errorEl = (this.errorEl = document.createElement("span"));
      errorEl.setAttribute("style", "white-space: pre-wrap; font-size: 90%; border: 1px solid #900; color: #C00");
      var el = (this.el = document.createElement("span"));
      el.className = elClass;
      container.appendChild(el);
    }
    MathjaxRenderer.prototype.dependencyCheck = function () {
      return gte_1(electron.ipcRenderer.sendSync("version"), "0.12.16") ? true : false;
    };
    MathjaxRenderer.prototype.startRender = function (expr) {
      var el = this.el,
        errorEl = this.errorEl;
      try {
        if (!this.dependencyCheck()) {
          el.innerHTML = '<span class="mod-warning">Obsidian v0.12.16+ is needed to render Mathjax</span>';
        } else {
          el.innerHTML =  require$$0.renderMath(expr, this.isDisplay).outerHTML;
          require$$0.finishRenderMath();
          // this.container.appendChild(this.el);
        }
      } catch (err) {
        // failed to render!
        errorEl.textContent = err && err.message;
        if (errorEl.parentElement !== el) {
          el.textContent = "";
          el.appendChild(errorEl);
          el.className += " hmd-math-mathjax-error";
        }
      }
      var onChanged = this.onChanged;
      if (onChanged) setTimeout(onChanged.bind(this, expr), 0);
    };
    MathjaxRenderer.prototype.clear = function () {
      this.container.removeChild(this.el);
    };
    /** indicate that if the Renderer is ready to execute */
    MathjaxRenderer.prototype.isReady = function () {
      return true; // I'm always ready!
    };
    return MathjaxRenderer;
  })();
  //   exports.DumbRenderer = DumbRenderer;
  exports.defaultOption = {
    renderer: MathjaxRenderer,
    onPreview: null,
    onPreviewEnd: null,
  };
  exports.suggestedOption = {};
  core_1.suggestedEditorConfig.hmdFoldMath = exports.suggestedOption;
  CodeMirror.defineOption("hmdFoldMath", exports.defaultOption, function (cm, newVal) {
    ///// convert newVal's type to `Partial<Options>`, if it is not.
    if (!newVal) {
      newVal = {};
    } else if (newVal === true) {
      newVal = { renderer: MathjaxRenderer, onPreview: null, onPreviewEnd: null };
    } else if (typeof newVal === "function") {
      newVal = { renderer: newVal };
    }
    ///// apply config and write new values into cm
    var inst = exports.getAddon(cm);
    for (var k in exports.defaultOption) {
      inst[k] = k in newVal ? newVal[k] : exports.defaultOption[k];
    }
  });
  //#endregion
  /********************************************************************************** */
  //#region Addon Class
  var FoldMath = /** @class */ (function () {
    function FoldMath(cm) {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      var _this = this;
      this.cm = cm;
      new core_1.FlipFlop(
        /** CHANGED */ function (expr) {
          _this.onPreview && _this.onPreview(expr);
        },
        /** HIDE    */ function () {
          _this.onPreviewEnd && _this.onPreviewEnd();
        },
        null
      ).bind(this, "editingExpr");
    }
    FoldMath.prototype.createRenderer = function (container, mode) {
      var RendererClass = this.renderer || MathjaxRenderer;
      return new RendererClass(container, mode);
    };
    return FoldMath;
  })();
  exports.FoldMath = FoldMath;
  //#endregion
  /** ADDON GETTER (Singleton Pattern): a editor can have only one FoldMath instance */
  exports.getAddon = core_1.Addon.Getter("FoldMath", FoldMath, exports.defaultOption /** if has options */);
});

// HyperMD, copyright (c) by laobubu
// Distributed under an MIT license: http://laobubu.net/HyperMD/LICENSE
//
// DESCRIPTION: Align Table Columns
//


(function (mod) {
  mod(null, (HyperMD.TableAlign = HyperMD.TableAlign || {}), CodeMirror, HyperMD);
})(function (require, exports, CodeMirror, core_1) {
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.getAddon = exports.TableAlign = exports.suggestedOption = exports.defaultOption = void 0;
  // CodeMirror = __importStar(CodeMirror);
  exports.defaultOption = {
    enabled: false,
  };
  exports.suggestedOption = {
    enabled: true,
  };
  core_1.suggestedEditorConfig.hmdTableAlign = exports.suggestedOption;
  core_1.normalVisualConfig.hmdTableAlign = false;
  CodeMirror.defineOption("hmdTableAlign", exports.defaultOption, function (cm, newVal) {
    var enabled = !!newVal;
    ///// convert newVal's type to `Partial<Options>`, if it is not.
    if (!enabled || typeof newVal === "boolean") {
      newVal = { enabled: enabled };
    }
    ///// apply config and write new values into cm
    var inst = exports.getAddon(cm);
    for (var k in exports.defaultOption) {
      inst[k] = k in newVal ? newVal[k] : exports.defaultOption[k];
    }
  });
  //#endregion
  /********************************************************************************** */
  //#region Addon Class
  var TableAlign = /** @class */ (function () {
    function TableAlign(cm) {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      var _this = this;
      this.cm = cm;
      this.styleEl = document.createElement("style");
      /**
       * Remeasure visible columns, update CSS style to make columns aligned
       *
       * (This is a debounced function)
       */
      this.updateStyle = core_1.debounce(function () {
        if (!_this.enabled) return;
        var cm = _this.cm;
        var measures = _this.measure();
        var css = _this.makeCSS(measures);
        if (css === _this._lastCSS) return;
        _this.styleEl.textContent = _this._lastCSS = css;
        core_1.updateCursorDisplay(cm, false);
        // cm.refresh();
      }, 100);
      /** CodeMirror renderLine event handler */
      this._procLine = function (cm, line, el) {
        if (!el.querySelector(".cm-hmd-table-sep")) return;
        var lineSpan = el.firstElementChild;
        var lineSpanChildren = Array.prototype.slice.call(lineSpan.childNodes, 0);
        var eolState = cm.getStateAfter(line.lineNo());
        var columnStyles = eolState.hmdTableColumns;
        if (!columnStyles.length) return;
        var tableID = eolState.hmdTableID;
        var columnIdx = eolState.hmdTable === 2 /* NORMAL */ ? -1 : 0;
        var columnSpan = _this.makeColumn(columnIdx, columnStyles[columnIdx] || "dummy", tableID);
        var columnContentSpan = columnSpan.firstElementChild;
        for (var _i = 0, lineSpanChildren_1 = lineSpanChildren; _i < lineSpanChildren_1.length; _i++) {
          var el_1 = lineSpanChildren_1[_i];
          var elClass = (el_1.nodeType === Node.ELEMENT_NODE && el_1.className) || "";
          if (/cm-hmd-table-sep/.test(elClass)) {
            // found a "|", and a column is finished
            columnIdx++;
            columnSpan.appendChild(columnContentSpan);
            lineSpan.appendChild(columnSpan);
            lineSpan.appendChild(el_1);
            columnSpan = _this.makeColumn(columnIdx, columnStyles[columnIdx] || "dummy", tableID);
            columnContentSpan = columnSpan.firstElementChild;
          } else {
            columnContentSpan.appendChild(el_1);
          }
        }
        columnSpan.appendChild(columnContentSpan);
        lineSpan.appendChild(columnSpan);
      };
      new core_1.FlipFlop(
        /* ON  */ function () {
          cm.on("renderLine", _this._procLine);
          cm.on("update", _this.updateStyle);
          cm.refresh();
          document.head.appendChild(_this.styleEl);
        },
        /* OFF */ function () {
          cm.off("renderLine", _this._procLine);
          cm.off("update", _this.updateStyle);
          document.head.removeChild(_this.styleEl);
          cm.refresh();
        }
      ).bind(this, "enabled", true);
    }
    /**
     * create a <span> container as column,
     * note that put content into column.firstElementChild
     */
    TableAlign.prototype.makeColumn = function (index, style, tableID) {
      var span = document.createElement("span");
      span.className = "hmd-table-column hmd-table-column-" + index + " hmd-table-column-" + style;
      span.setAttribute("data-column", "" + index);
      span.setAttribute("data-table-id", tableID);
      var span2 = document.createElement("span");
      span2.className = "hmd-table-column-content";
      span2.setAttribute("data-column", "" + index);
      span.appendChild(span2);
      return span;
    };
    /** Measure all visible tables and columns */
    TableAlign.prototype.measure = function () {
      var cm = this.cm;
      var lineDiv = cm.display.lineDiv; // contains every <pre> line
      var contentSpans = lineDiv.querySelectorAll(".hmd-table-column-content");
      /** every table's every column's width in px */
      var ans = {};
      for (var i = 0; i < contentSpans.length; i++) {
        var contentSpan = contentSpans[i];
        var column = contentSpan.parentElement;
        var tableID = column.getAttribute("data-table-id");
        var columnIdx = ~~column.getAttribute("data-column");
        var width = contentSpan.offsetWidth + 1; // +1 because browsers turn 311.3 into 312
        if (!(tableID in ans)) ans[tableID] = [];
        var columnWidths = ans[tableID];
        while (columnWidths.length <= columnIdx) columnWidths.push(0);
        if (columnWidths[columnIdx] < width) columnWidths[columnIdx] = width;
      }
      return ans;
    };
    /** Generate CSS */
    TableAlign.prototype.makeCSS = function (measures) {
      var rules = [];
      for (var tableID in measures) {
        var columnWidths = measures[tableID];
        var rulePrefix = "pre.HyperMD-table-row.HyperMD-table_" + tableID + " .hmd-table-column-";
        for (var columnIdx = 0; columnIdx < columnWidths.length; columnIdx++) {
          var width = columnWidths[columnIdx];
          rules.push("" + rulePrefix + columnIdx + " { min-width: " + (width + 0.5) + "px }");
        }
      }
      return rules.join("\n");
    };
    return TableAlign;
  })();
  exports.TableAlign = TableAlign;
  //#endregion
  /** ADDON GETTER (Singleton Pattern): a editor can have only one TableAlign instance */
  exports.getAddon = core_1.Addon.Getter("TableAlign", TableAlign, exports.defaultOption);
});

function onRenderLine(cm, line, el) {
    const parentElement = el.parentElement;
    if (!parentElement)
        el.addEventListener("DOMNodeInserted", (event) => procLine(cm, line, el, event.relatedNode, this), { once: true });
}
function procLine(cm, line, el, parentEl, plugin) {
    var _a, _b, _c, _d, _e;
    // for some reason, codemirror or hmd skips putting elements in a wrapping div
    // unsure what causes this to happen but try and account for it by falling back
    // if the parent is the root codemirror-code element
    if (parentEl.className === "CodeMirror-code")
        parentEl = el;
    // clear existing data keys
    clearDataKeys(parentEl.dataset);
    // split child classes
    const childClasses = (_b = (_a = line.styleClasses) === null || _a === void 0 ? void 0 : _a.textClass) === null || _b === void 0 ? void 0 : _b.split(" ");
    // line.styles is an array of multi-class strings
    // we combine all of the styles into a single string and then dedupe it
    const childElementClasses = (_c = line.styles) === null || _c === void 0 ? void 0 : _c.filter((style) => typeof style === "string").join(" ").split(" ").filter((v, i, a) => a.indexOf(v) === i);
    // raise yaml frontmatter attributes up as CSS vars and attrs
    if (childElementClasses.contains("hmd-frontmatter") && line.text !== "---") {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        //@ts-ignore
        const display = cm.display;
        const viewEl = (_e = (_d = display === null || display === void 0 ? void 0 : display.wrapper) === null || _d === void 0 ? void 0 : _d.parentElement) === null || _e === void 0 ? void 0 : _e.parentElement;
        const approvedAttrs = plugin.settings.allowedYamlKeys.split(",").map(item => item.trim());
        if (plugin.settings.renderBanner) {
            approvedAttrs.push("banner_x", "banner_y", "banner", "banner-height", "banner-style");
        }
        // try and parse the frontmatter into yaml key/value pairs
        let kv;
        try {
            const parsedYaml = require$$0.parseYaml(line.text);
            kv = Object.entries(parsedYaml).map(([key, value]) => ({ key, value }));
        }
        catch (_f) {
            kv = [];
        }
        kv.forEach(item => {
            // if the key is not registered, skip
            if (!approvedAttrs.includes(item.key))
                return;
            // if the value looks like a file, try and resolve the full path
            if (/\.(jpg|jpeg|md|png|gif)$/.test(item.value)) {
                let file, filePath;
                try {
                    (file = plugin.app.metadataCache.getFirstLinkpathDest(decodeURIComponent(item.value), "")) &&
                        (filePath = plugin.app.vault.getResourcePath(file));
                }
                catch (_a) { }
                if (file && filePath) {
                    viewEl.style.setProperty(`--${item.key}`, `url(${filePath})`);
                }
                else {
                    viewEl.style.setProperty(`--${item.key}`, `${item.value}`);
                }
            }
            else {
                // special handling for the banner plugin to turn decimals into percents
                if (/^banner_[xy]$/.test(item.key)) {
                    item.value = `${item.value * 100}%`;
                }
                viewEl.style.setProperty(`--${item.key}`, `${item.value}`);
            }
            try {
                viewEl.setAttribute(`data-${item.key}`, item.value);
            }
            catch (_b) { }
        });
    }
    // look for anything labeled as a header
    // extract its full text value (minus the initial hash)
    if (childClasses === null || childClasses === void 0 ? void 0 : childClasses.includes("HyperMD-header")) {
        const _match = line.text.match(/^[#]+[\s]+(.+)/);
        parentEl.dataset["heading"] = (_match === null || _match === void 0 ? void 0 : _match.length) > 0 ? line.text.match(/^[#]+[\s]+(.+)/)[1].trim() : "";
    }
    // check line for any hashtags and add them to a new data key
    const tokens = cm.getLineTokens(line.lineNo());
    const parsedTokens = parseLineTokens(tokens);
    if (parsedTokens)
        parentEl.dataset["hashtags"] = parseLineTokens(tokens);
    // infer html tag type based on style classes
    const htmlTag = childElementClasses ? lookupTag(childElementClasses) : null;
    if (htmlTag) {
        parentEl.dataset["tagName"] = htmlTag;
    }
}
function clearDataKeys(keys) {
    if (keys) {
        Object.keys(keys).forEach(dataKey => {
            delete keys[dataKey];
        });
    }
}
function parseLineTokens(tokens) {
    tokens = tokens.filter((token) => { var _a; return (_a = token.type) === null || _a === void 0 ? void 0 : _a.includes("hashtag-end"); });
    if (tokens.length) {
        const hashtags = tokens.map((token) => token.string).join(" ");
        if (hashtags.length) {
            return tokens.map((token) => token.string).join(" ");
        }
    }
}
function lookupTag(classes) {
    let htmlTag;
    for (const className of classes) {
        switch (className) {
            case "formatting-list-ol":
                htmlTag = "ol";
                break;
            case "formatting-list-ul":
                htmlTag = "ul";
                break;
            case "header-1":
                htmlTag = "h1";
                break;
            case "header-2":
                htmlTag = "h2";
                break;
            case "header-3":
                htmlTag = "h3";
                break;
            case "header-4":
                htmlTag = "h4";
                break;
            case "header-5":
                htmlTag = "h5";
                break;
            case "header-6":
                htmlTag = "h6";
                break;
            case "hmd-codeblock":
                htmlTag = "code";
                break;
            case "hr":
                htmlTag = "hr";
                break;
            case "hmd-frontmatter":
                htmlTag = "frontmatter";
                break;
        }
    }
    return htmlTag;
}

function around(obj, factories) {
    const removers = Object.keys(factories).map(key => around1(obj, key, factories[key]));
    return removers.length === 1 ? removers[0] : function () { removers.forEach(r => r()); };
}
function around1(obj, method, createWrapper) {
    const original = obj[method], hadOwn = obj.hasOwnProperty(method);
    let current = createWrapper(original);
    // Let our wrapper inherit static props from the wrapping method,
    // and the wrapping method, props from the original method
    if (original)
        Object.setPrototypeOf(current, original);
    Object.setPrototypeOf(wrapper, current);
    obj[method] = wrapper;
    // Return a callback to allow safe removal
    return remove;
    function wrapper(...args) {
        // If we have been deactivated and are no longer wrapped, remove ourselves
        if (current === original && obj[method] === wrapper)
            remove();
        return current.apply(this, args);
    }
    function remove() {
        // If no other patches, just do a direct removal
        if (obj[method] === wrapper) {
            if (hadOwn)
                obj[method] = original;
            else
                delete obj[method];
        }
        if (current === original)
            return;
        // Else pass future calls through, and remove wrapper from the prototype chain
        current = original;
        Object.setPrototypeOf(wrapper, original || Function);
    }
}

class ObsidianCodeMirrorOptionsPlugin extends require$$0.Plugin {
    constructor() {
        super(...arguments);
        this.onImageContextMenu = (event, target) => {
            // the "editor-menu" event does not include the MouseEvent or the target HTMLElement
            // so instead, we create this stanadard context menu event handler and hook it into
            // the "editor-menu" event temporarily
            const boundFunc = this.onEditorMenu.bind(this, target);
            this.app.workspace.on("editor-menu", boundFunc);
            setTimeout(() => {
                this.app.workspace.off("editor-menu", boundFunc);
            }, 100);
        };
        this.onEditorMenu = (target, menu) => {
            let file;
            if (target.dataset.path) {
                file = this.app.vault.getAbstractFileByPath(target.dataset.path);
                if (!(file instanceof require$$0.TFile))
                    return;
            }
            else if (/^http/i.test(target.getAttribute("src"))) {
                file = target.getAttribute("src");
            }
            if (file)
                this.addContextMenuItem(menu, file);
        };
        this.addContextMenuItem = (menu, imageFile) => {
            menu.addItem(menuItem => {
                menuItem.setTitle("Copy Image to Clipboard");
                menuItem.setIcon("image-file");
                menuItem.onClick(() => __awaiter(this, void 0, void 0, function* () {
                    let blob;
                    if (imageFile instanceof require$$0.TFile) {
                        const buffer = yield this.app.vault.adapter.readBinary(imageFile.path);
                        const arr = new Uint8Array(buffer);
                        blob = new Blob([arr], { type: "image/png" });
                    }
                    else {
                        blob = yield (yield fetch(imageFile)).blob();
                    }
                    //@ts-ignore
                    const item = new ClipboardItem({ "image/png": blob });
                    //@ts-ignore
                    window.navigator.clipboard.write([item]);
                }));
            });
        };
        this.onFileLoad = (file, contentEl, editor, leaf) => {
            editor.state.fileName = file.path;
            if (this.settings.showBacklinks) {
                this.addBackLinks(file, editor, leaf);
            }
        };
        this.onFileUnload = (file, contentEl, editor, leaf) => {
            try {
                this.resetCodeMirrorState(file, contentEl, editor);
                editor.doc.clearHistory();
                editor.clearGutter("CodeMirror-foldgutter");
                this.hideMathPreview();
            }
            catch (_a) {
                // console.log("unable to clear editor");
            }
        };
        this.onEditorClose = (file, contentEl, editor, leaf) => {
            this.removeBackLinks(editor);
            this.unsetCodeMirrorOptions(editor);
            setTimeout(() => {
                var _a, _b;
                try {
                    editor.display.renderedView = [];
                    (_a = editor.display.lineDiv) === null || _a === void 0 ? void 0 : _a.empty();
                    (_b = editor.display.currentWheelTarget) === null || _b === void 0 ? void 0 : _b.empty();
                    editor.display = null;
                    editor.blockHTMLObserver.disconnect();
                    editor.blockHTMLObserver = null;
                    Object.keys(editor._handlers).forEach(handler => (editor._handlers[handler] = null));
                }
                catch (_c) { }
            }, 500);
        };
        this.mdProcessor = (el) => __awaiter(this, void 0, void 0, function* () {
            setTimeout(() => {
                this.injectCM(el);
            }, 100);
        });
        this.onRenderLineBound = onRenderLine.bind(this);
        this.onImageClick = args => {
            args.breakMark(args.editor, args.marker);
        };
        this.updateCodeMirrorOption = require$$0.debounce((optionKey, optionValue, refresh = false) => {
            this.app.workspace.iterateCodeMirrors(cm => {
                if (cm && cm.getOption(optionKey) != optionValue) {
                    cm.setOption(optionKey, optionValue);
                    if (refresh)
                        cm.refresh();
                }
            });
        }, 400, true);
        this.updateCodeMirrorHandlers = require$$0.debounce((eventType, callback, enable = true, refresh = false) => {
            this.app.workspace.iterateCodeMirrors(cm => {
                if (enable)
                    cm.on(eventType, callback);
                else
                    cm.off(eventType, callback);
                if (refresh)
                    cm.refresh();
            });
        }, 0, true);
    }
    onload() {
        return __awaiter(this, void 0, void 0, function* () {
            // patch the default Obsidian methods, ASAP
            //@ts-ignore
            if (this.app.vault.getConfig("legacyEditor"))
                this.applyMonkeyPatches();
            // load settings
            yield this.loadSettings();
            // add the settings tab
            this.addSettingTab(new ObsidianCodeMirrorOptionsSettingsTab(this.app, this));
            //@ts-ignore
            if (this.app.vault.getConfig("legacyEditor")) {
                // initial-file-load is a custom event emitted by a patched MarkdownView.onLoadFile
                this.registerEvent(this.app.workspace.on("initial-file-load", this.onFileLoad));
                // file-unload is a custom event emitted by a patched MarkdownView.onUnloadFile
                this.registerEvent(this.app.workspace.on("file-unload", this.onFileUnload));
                // editor-close is a custom event emitted by a patched MarkdownView.onClose
                this.registerEvent(this.app.workspace.on("editor-close", this.onEditorClose));
                this.app.workspace.onLayoutReady(() => {
                    this.registerCodeMirrorSettings();
                    this.registerCommands();
                    setTimeout(() => {
                        // workaround to ensure our plugin registers properly with Style Settings
                        this.app.workspace.trigger("css-change");
                    }, 1000);
                });
                document.on("contextmenu", `img.hmd-image`, this.onImageContextMenu, false);
                document.on("contextmenu", `.rendered-widget img:not(.hmd-image)`, this.onImageContextMenu, false);
            }
            this.app.workspace.onLayoutReady(() => {
                this.applyBodyClasses();
                setTimeout(() => {
                    // workaround to ensure our plugin registers properly with Style Settings
                    this.app.workspace.trigger("css-change");
                }, 1000);
            });
        });
    }
    loadSettings() {
        return __awaiter(this, void 0, void 0, function* () {
            this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
        });
    }
    resetCodeMirrorState(file, contentEl, editor) {
        // remove any attributes and styles created by the Container Attributes feature
        if (contentEl) {
            Object.keys(contentEl.dataset).forEach(el => contentEl.removeAttribute("data-" + el));
            contentEl.style = null;
        }
        // add the current file path to the CodeMirror state for access by native CM methods
        editor.hmd.Fold.clearAll();
        editor.hmd.FoldCode.clearAll();
    }
    removeBackLinks(editor) {
        if (editor.backlinksWidget) {
            editor.backlinksWidget.unload();
            editor.display.lineDiv.parentElement.removeChild(editor.backlinksWidget.contentEl);
            editor.backlinksWidget = null;
        }
    }
    removeBacklinksImmediately() {
        try {
            //@ts-ignore
            this.app.workspace.iterateRootLeaves(leaf => this.removeBackLinks(leaf.view.editor.cm));
        }
        catch (err) {
            // console.log(err);
        }
    }
    addBacklinksImmediately() {
        try {
            //@ts-ignore
            this.app.workspace.iterateRootLeaves(leaf => this.addBackLinks(leaf.view.file, leaf.view.editor.cm, leaf));
        }
        catch (_a) { }
    }
    addBackLinks(file, editor, leaf) {
        if (!editor.backlinksWidget) {
            //@ts-ignore
            editor.backlinksWidget = this.app.viewRegistry.getViewCreatorByType("backlink")(leaf);
            editor.backlinksWidget.contentEl.setAttribute("cm-ignore-events", "true");
            editor.display.lineDiv.parentElement.appendChild(editor.backlinksWidget.contentEl);
        }
        editor.backlinksWidget.backlink.update = function () {
            const e = file;
            this.backlinkFile !== e && this.recomputeBacklink(e), this.unlinkedFile !== e && this.recomputeUnlinked(e);
            this.updateHeaderTooltip(this.backlinkHeaderEl, this.backlinkCollapsed),
                this.updateHeaderTooltip(this.unlinkedHeaderEl, this.unlinkedCollapsed);
        };
        if (!editor.backlinksWidget._loaded) {
            editor.backlinksWidget.load();
        }
    }
    hideMathPreview() {
        const previewEl = document.querySelector("#math-preview");
        if (previewEl && !previewEl.hasClass("float-win-hidden")) {
            previewEl.addClass("float-win-hidden");
        }
    }
    applyMonkeyPatches() {
        // patching onLoadFile to clear CM specific state in order to avoid fold related memory leaks
        // we also add the current file name to the CM state so that CM native actions have a reference
        const patchFileLifecycle = around(require$$0.MarkdownView.prototype, {
            onLoadFile(old) {
                return function (file) {
                    try {
                        this.app.workspace.trigger("initial-file-load", file, this.contentEl, this.editor.cm, this.leaf);
                    }
                    catch (_a) { }
                    return old.call(this, file);
                };
            },
            // @ts-ignore
            onUnloadFile(old) {
                return function (file) {
                    const result = old.call(this);
                    try {
                        this.app.workspace.trigger("file-unload", this.file, this.contentEl, this.editor.cm, this.leaf);
                    }
                    catch (_a) { }
                    return result;
                };
            },
            // @ts-ignore
            onClose(old) {
                return function () {
                    try {
                        this.app.workspace.trigger("editor-close", this.file, this.contentEl, this.editor.cm, this.leaf);
                    }
                    catch (_a) { }
                    return old.call(this);
                };
            },
        });
        this.register(patchFileLifecycle);
        // patch the preview mode click handlers so that we get preview context menus on edit mode rendered widgets
        const patchSourceView = around(require$$0.MarkdownSourceView.prototype, {
            attachDomEvents(old) {
                return function () {
                    // eslint-disable-next-line @typescript-eslint/no-this-alias
                    const _this = this, editorEl = this.editorEl;
                    editorEl.addEventListener("mousedown", this.onCodeMirrorMousedown.bind(this)),
                        editorEl.addEventListener("contextmenu", function (event) {
                            if (event &&
                                event.path.length &&
                                event.path.filter(el => el.hasClass && el.hasClass("rendered-widget")).length &&
                                event.path[0].tagName !== "IMG") {
                                return;
                            }
                            return _this.clipboardManager.onContextMenu(event);
                        }, { capture: true }),
                        editorEl.on("mouseover", ".cm-hmd-internal-link", this.onInternalLinkMouseover.bind(this));
                };
            },
        });
        this.register(patchSourceView);
        const patchRenderer = around(require$$0.MarkdownPreviewRenderer.prototype, {
            onInternalLinkContextMenu(old) {
                return function (event, el) {
                    const href = this.getInternalLinkHref(el);
                    href && this.owner.onInternalLinkRightClick(event, el, href);
                };
            },
            onResize(old) {
                return function () {
                    setTimeout(() => {
                        var _a, _b, _c;
                        const editor = (_c = (_b = (_a = this.owner.app.workspace.activeLeaf) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.sourceMode) === null || _c === void 0 ? void 0 : _c.editorEl;
                        if (editor && !this.widgetHandlersRegistered && this.owner.type === "preview") {
                            this.widgetHandlersRegistered = true;
                            editor.on("click", ".rendered-widget a.internal-link", this.onInternalLinkClick.bind(this));
                            editor.on("auxclick", ".rendered-widget a.internal-link", this.onInternalLinkClick.bind(this));
                            editor.on("contextmenu", ".rendered-widget a.internal-link", this.onInternalLinkContextMenu.bind(this));
                            // editor.on("mouseover", ".rendered-widget a.internal-link", this.onInternalLinkMouseover.bind(this));
                            editor.on("click", ".rendered-widget a.external-link", this.onExternalLinkClick.bind(this));
                            editor.on("click", ".rendered-widget a.footnote-link", this.onFootnoteLinkClick.bind(this));
                            editor.on("click", ".rendered-widget .task-list-item-checkbox", this.onCheckboxClick.bind(this));
                            editor.on("click", ".rendered-widget a.tag", this.onTagClick.bind(this));
                            editor.on("click", ".rendered-widget a.internal-query", this.onInternalQueryClick.bind(this));
                            editor.on("click", ".rendered-widget .heading-collapse-indicator", this.onHeadingCollapseClick.bind(this));
                            editor.on("click", ".rendered-widget li > .list-collapse-indicator", this.onListCollapseClick.bind(this));
                            // editor.on("click", ".rendered-widget img", this.onImageClick.bind(this));
                        }
                    }, 100);
                    return old.call(this);
                };
            },
            belongsToMe(old) {
                return function (el) {
                    // save the original element so we can pass it to the original method
                    const _el = el;
                    // check to see if the element is a sibling of a rendered widget
                    for (; el;) {
                        if (el.hasClass("rendered-widget") && el.tagName !== "IMG") {
                            return true;
                        }
                        const parentEl = el.parentElement;
                        if (!parentEl)
                            return old.call(this, _el);
                        el = parentEl;
                    }
                };
            },
        });
        this.register(patchRenderer);
    }
    getHmdOptions(type) {
        switch (type) {
            case "hmdFold":
                return {
                    image: this.settings.foldImages,
                    link: this.settings.foldLinks,
                    html: this.settings.renderHTML,
                    code: this.settings.renderCode,
                    math: this.settings.renderMath,
                    embed: this.settings.renderEmbeds,
                    emoji: this.settings.renderEmoji,
                };
            case "hmdFoldCode":
                return {
                    admonition: this.settings.renderAdmonition,
                    chart: this.settings.renderChart,
                    query: this.settings.renderQuery,
                    dataview: this.settings.renderDataview,
                    tasks: this.settings.renderTasks,
                };
            default:
                assertNever(type);
        }
    }
    updateHmdOptions(type) {
        return this.updateCodeMirrorOption(type, this.getHmdOptions(type));
    }
    registerCommands() {
        this.addCommand({
            id: "toggle-openmd",
            name: "Toggle OpenMD Mode",
            callback: () => {
                this.settings.enableOpenMD = !this.settings.enableOpenMD;
                this.saveData(this.settings);
                this.updateCodeMirrorOption("mode", this.settings.enableOpenMD ? "openmd" : "hypermd");
            },
        });
        this.addCommand({
            id: "toggle-hide-tokens",
            name: "Toggle Hide Markdown Tokens",
            callback: () => {
                this.settings.editModeHideTokens = !this.settings.editModeHideTokens;
                this.saveData(this.settings);
                this.updateCodeMirrorOption("hmdHideToken", this.settings.editModeHideTokens ? this.settings.tokenList : false);
                this.applyBodyClasses();
            },
        });
        this.addCommand({
            id: "toggle-click-handler",
            name: "Toggle Edit Mode Click Handler",
            callback: () => {
                this.settings.editModeClickHandler = !this.settings.editModeClickHandler;
                this.saveData(this.settings);
                this.updateCodeMirrorOption("hmdClick", this.settings.editModeClickHandler);
            },
        });
        this.addCommand({
            id: "toggle-collapse-links",
            name: "Toggle Collapse External Links",
            callback: () => {
                this.settings.foldLinks = !this.settings.foldLinks;
                this.saveData(this.settings);
                this.applyBodyClasses();
                this.updateHmdOptions("hmdFold");
            },
        });
        this.addCommand({
            id: "toggle-render-images-inline",
            name: "Toggle Render Images Inline",
            callback: () => {
                this.settings.foldImages = !this.settings.foldImages;
                this.saveData(this.settings);
                this.applyBodyClasses();
                this.updateHmdOptions("hmdFold");
            },
        });
        this.addCommand({
            id: "toggle-render-html",
            name: "Toggle Render HTML",
            callback: () => {
                this.settings.renderHTML = !this.settings.renderHTML;
                this.saveData(this.settings);
                this.applyBodyClasses();
                this.updateHmdOptions("hmdFold");
            },
        });
        this.addCommand({
            id: "toggle-render-embeds",
            name: "Toggle Render Embeds",
            callback: () => {
                this.settings.renderEmbeds = !this.settings.renderEmbeds;
                this.saveData(this.settings);
                this.applyBodyClasses();
                this.updateHmdOptions("hmdFold");
            },
        });
        this.addCommand({
            id: "toggle-render-math",
            name: "Toggle Render Math",
            callback: () => {
                this.settings.renderMath = !this.settings.renderMath;
                this.saveData(this.settings);
                this.applyBodyClasses();
                this.updateHmdOptions("hmdFold");
            },
        });
        this.addCommand({
            id: "toggle-render-math-preview",
            name: "Toggle Render Math Preview",
            callback: () => {
                this.settings.renderMathPreview = !this.settings.renderMathPreview;
                this.saveData(this.settings);
                this.applyBodyClasses();
                if (this.settings.renderMathPreview) {
                    this.app.workspace.iterateCodeMirrors(cm => {
                        init_math_preview(cm);
                    });
                }
                else {
                    const previewEl = document.querySelector("#math-preview");
                    if (previewEl) {
                        document.querySelector("#math-preview").detach();
                    }
                    this.app.workspace.iterateCodeMirrors(cm => {
                        unload_math_preview(cm);
                    });
                }
            },
        });
        this.addCommand({
            id: "toggle-render-code",
            name: "Toggle Render Code",
            callback: () => {
                this.settings.renderCode = !this.settings.renderCode;
                this.saveData(this.settings);
                this.applyBodyClasses();
                this.updateHmdOptions("hmdFold");
            },
        });
        this.addCommand({
            id: "toggle-render-dataview",
            name: "Toggle Render Dataview",
            callback: () => {
                this.settings.renderDataview = !this.settings.renderDataview;
                this.saveData(this.settings);
                this.applyBodyClasses();
                this.updateHmdOptions("hmdFoldCode");
            },
        });
        this.addCommand({
            id: "toggle-render-chart",
            name: "Toggle Render Charts",
            callback: () => {
                this.settings.renderChart = !this.settings.renderChart;
                this.saveData(this.settings);
                this.applyBodyClasses();
                this.updateHmdOptions("hmdFoldCode");
            },
        });
        this.addCommand({
            id: "toggle-render-admonition",
            name: "Toggle Render Admonitions",
            callback: () => {
                this.settings.renderAdmonition = !this.settings.renderAdmonition;
                this.saveData(this.settings);
                this.applyBodyClasses();
                this.updateHmdOptions("hmdFoldCode");
            },
        });
        this.addCommand({
            id: "toggle-render-query",
            name: "Toggle Render Search Queries",
            callback: () => {
                this.settings.renderQuery = !this.settings.renderQuery;
                this.saveData(this.settings);
                this.applyBodyClasses();
                this.updateHmdOptions("hmdFoldCode");
            },
        });
        this.addCommand({
            id: "toggle-render-tasks",
            name: "Toggle Render Tasks",
            callback: () => {
                this.settings.renderTasks = !this.settings.renderTasks;
                this.saveData(this.settings);
                this.applyBodyClasses();
                this.updateHmdOptions("hmdFoldCode");
            },
        });
        this.addCommand({
            id: "toggle-backlinks-in-editor",
            name: "Toggle Backlinks in Editor",
            callback: () => {
                this.settings.showBacklinks = !this.settings.showBacklinks;
                this.saveData(this.settings);
                this.settings.showBacklinks ? this.addBacklinksImmediately() : this.removeBacklinksImmediately();
            },
        });
        this.addCommand({
            id: "toggle-container-attributes",
            name: "Toggle Container Attributes",
            callback: () => {
                this.settings.containerAttributes = !this.settings.containerAttributes;
                this.saveData(this.settings);
                this.updateCodeMirrorHandlers("renderLine", this.onRenderLineBound, this.settings.containerAttributes, true);
            },
        });
        this.addCommand({
            id: "toggle-dynamic-cursor-size",
            name: "Toggle Dynamic Cursor Size",
            callback: () => {
                this.settings.dynamicCursor = !this.settings.dynamicCursor;
                this.saveData(this.settings);
                this.updateCodeMirrorOption("singleCursorHeightPerLine", !this.settings.dynamicCursor);
            },
        });
        this.addCommand({
            id: "toggle-style-active-selection",
            name: "Toggle Style Active Selection",
            callback: () => {
                this.settings.markSelection = !this.settings.markSelection;
                this.saveData(this.settings);
                this.updateCodeMirrorOption("styleSelectedText", this.settings.markSelection);
                this.applyBodyClasses();
            },
        });
        this.addCommand({
            id: "toggle-retain-active-line",
            name: "Toggle Retain Active Line on Selection",
            callback: () => {
                this.settings.activeLineOnSelect = !this.settings.activeLineOnSelect;
                this.saveData(this.settings);
                this.updateCodeMirrorOption("styleActiveLine", this.settings.activeLineOnSelect ? { nonEmpty: true } : true);
            },
        });
        this.addCommand({
            id: "toggle-edit-mode-syntax",
            name: "Toggle Edit Mode Syntax Highlighting",
            callback: () => {
                this.settings.syntaxHighlighting = !this.settings.syntaxHighlighting;
                this.saveData(this.settings);
                this.applyBodyClasses(true);
            },
        });
        this.addCommand({
            id: "toggle-preview-mode-syntax",
            name: "Toggle Preview Mode Syntax Highlighting",
            callback: () => {
                this.settings.enablePrismJSStyling = !this.settings.enablePrismJSStyling;
                this.saveData(this.settings);
                this.applyBodyClasses(true);
            },
        });
        this.addCommand({
            id: "toggle-codemirror-in-preview-mode",
            name: "Toggle CodeMirror in Preview Mode",
            callback: () => {
                this.settings.enableCMinPreview = !this.settings.enableCMinPreview;
                this.saveData(this.settings);
                this.applyBodyClasses(true);
            },
        });
        this.addCommand({
            id: "toggle-cm-line-numbers-in-preview-mode",
            name: "Toggle CM Line Numbers in Preview Mode",
            callback: () => {
                this.settings.showLineNums = !this.settings.showLineNums;
                this.saveData(this.settings);
                this.applyBodyClasses(true);
            },
        });
        this.addCommand({
            id: "toggle-cm-copy-button-in-preview-mode",
            name: "Toggle Copy Button in Preview Mode",
            callback: () => {
                this.settings.copyButton = !this.settings.copyButton;
                this.saveData(this.settings);
                this.applyBodyClasses(true);
            },
        });
        this.addCommand({
            id: "toggle-auto-align-table",
            name: "Toggle Auto Align Tables",
            callback: () => {
                this.settings.autoAlignTables = !this.settings.autoAlignTables;
                this.saveData(this.settings);
                this.updateCodeMirrorOption("hmdTableAlign", this.settings.autoAlignTables);
            },
        });
    }
    injectCM(el) {
        var _a;
        // only get code block elements with a language but not any that have already been colorized
        const preElement = el.firstChild;
        const codeElement = (_a = el.firstChild) === null || _a === void 0 ? void 0 : _a.firstChild;
        if (!codeElement)
            return;
        if (codeElement.tagName !== "CODE")
            return;
        // TODO: Add an option to configure excluded languages
        if (codeElement.hasClass("language-mermaid"))
            return;
        if (!codeElement.classList.value.includes("language-")) {
            if (this.settings.copyButtonOnPRE) {
                this.addCopyButton(preElement);
            }
            return;
        }
        if (preElement.classList.value.includes("cm-s-obsidian"))
            return;
        codeElement.classList.forEach((className) => {
            if (className.startsWith("language-")) {
                // set data-lang to the code block language for easier colorize usage
                let language = className.replace("language-", "");
                switch (language) {
                    case "html":
                        language = "htmlmixed";
                        break;
                    case "js":
                        language = "javascript";
                        break;
                    case "json":
                        language = "javascript";
                        break;
                }
                codeElement.setAttribute("data-lang", language);
            }
        });
        //@ts-ignore
        CodeMirror.colorize([codeElement], null, this.settings.showLineNums);
        preElement.querySelector(".copy-code-button").remove();
        this.addCopyButton(preElement);
    }
    addCopyButton(element) {
        if (this.settings.copyButton) {
            const codeBlock = element;
            const copyButton = document.createElement("button");
            copyButton.className = "copy";
            copyButton.type = "button";
            // copyButton.ariaLabel = 'Copy code to clipboard';
            copyButton.innerText = "Copy";
            codeBlock.append(copyButton);
            copyButton.addEventListener("click", function () {
                // exclude line numbers when copying code to clipboard
                const code = codeBlock.querySelector("code");
                const clone = code.cloneNode(true);
                clone.findAll("span.cm-linenumber").forEach(e => e.remove());
                const codeText = clone.textContent.trim();
                window.navigator.clipboard.writeText(codeText);
                copyButton.innerText = "Copied";
                setTimeout(function () {
                    copyButton.innerText = "Copy";
                }, 4000);
            });
        }
    }
    registerCodeMirrorSettings() {
        this.registerCodeMirror(cm => {
            cm.setOption("styleSelectedText", this.settings.markSelection);
            cm.setOption("singleCursorHeightPerLine", !this.settings.dynamicCursor);
            cm.setOption("styleActiveLine", this.settings.activeLineOnSelect ? { nonEmpty: true } : true);
            if (this.settings.enableOpenMD)
                cm.setOption("mode", "openmd");
            cm.setOption("hmdHideToken", this.settings.editModeHideTokens ? this.settings.tokenList : false);
            cm.setOption("hmdClick", this.settings.editModeClickHandler);
            cm.setOption("hmdTableAlign", this.settings.autoAlignTables);
            cm.setOption("cursorBlinkRate", this.settings.cursorBlinkRate);
            cm.setOption("hmdFold", this.getHmdOptions("hmdFold"));
            cm.setOption("hmdFoldCode", this.getHmdOptions("hmdFoldCode"));
            if (this.settings.renderMathPreview)
                init_math_preview(cm);
            if (this.settings.containerAttributes)
                this.updateCodeMirrorHandlers("renderLine", this.onRenderLineBound, true, true);
        });
    }
    applyBodyClasses(refresh = false) {
        this.settings.editModeHideTokens
            ? !document.body.hasClass("hide-tokens")
                ? document.body.addClass("hide-tokens")
                : null
            : document.body.removeClass("hide-tokens");
        this.settings.styleCheckBox
            ? !document.body.hasClass("style-check-box")
                ? document.body.addClass("style-check-box")
                : null
            : document.body.removeClass("style-check-box");
        this.settings.markSelection
            ? !document.body.hasClass("style-active-selection")
                ? document.body.addClass("style-active-selection")
                : null
            : document.body.removeClass("style-active-selection");
        this.settings.enablePrismJSStyling
            ? !document.body.hasClass("fallback-highlighting")
                ? document.body.addClass("fallback-highlighting")
                : null
            : document.body.removeClass("fallback-highlighting");
        this.settings.showLineNums
            ? !document.body.hasClass("cm-show-line-nums")
                ? document.body.addClass("cm-show-line-nums")
                : null
            : document.body.removeClass("cm-show-line-nums");
        this.settings.copyButtonOnPRE
            ? !document.body.hasClass("cm-show-copy-button-on-pre")
                ? document.body.addClass("cm-show-copy-button-on-pre")
                : null
            : document.body.removeClass("cm-show-copy-button-on-pre");
        this.settings.syntaxHighlighting
            ? !document.body.hasClass("unified-cm-highlighting")
                ? document.body.addClass("unified-cm-highlighting")
                : null
            : document.body.removeClass("unified-cm-highlighting");
        this.settings.foldImages
            ? !document.body.hasClass("cm-render-images-inline")
                ? document.body.addClass("cm-render-images-inline")
                : null
            : document.body.removeClass("cm-render-images-inline");
        this.settings.foldLinks
            ? !document.body.hasClass("cm-collapse-external-links")
                ? document.body.addClass("cm-collapse-external-links")
                : null
            : document.body.removeClass("cm-collapse-external-links");
        this.settings.renderBanner
            ? !document.body.hasClass("cm-render-banners")
                ? document.body.addClass("cm-render-banners")
                : null
            : document.body.removeClass("cm-render-banners");
        this.settings.enableCMinPreview
            ? this.registerMarkdownPostProcessor(this.mdProcessor)
            : require$$0.MarkdownPreviewRenderer.unregisterPostProcessor(this.mdProcessor);
        if (refresh)
            this.refreshPanes();
    }
    unsetCodeMirrorOptions(cm) {
        cm.setOption("styleSelectedText", false);
        cm.setOption("singleCursorHeightPerLine", true);
        cm.setOption("styleActiveLine", true);
        cm.setOption("mode", "hypermd");
        cm.setOption("hmdHideToken", false);
        cm.setOption("hmdFold", { image: false, link: false, html: false, code: false, math: false, emoji: false });
        cm.setOption("hmdTableAlign", false);
        cm.setOption("hmdClick", false);
        cm.setOption("cursorBlinkRate", 530);
        cm.off("renderLine", this.onRenderLineBound);
        unload_math_preview(cm);
        // cm.off("imageClicked", this.onImageClick);
        cm.refresh();
    }
    unsetAllCodeMirrorOptions() {
        this.app.workspace.iterateCodeMirrors(cm => {
            // revert CodeMirror options back to the CM/Obsidian defaults
            try {
                //@ts-ignore
                cm.hmd.Fold.clearAll();
                //@ts-ignore
                cm.hmd.FoldCode.clearAll();
            }
            catch (_a) { }
            this.unsetCodeMirrorOptions(cm);
        });
        document.body.classList.remove("style-active-selection", "style-check-box", "hide-tokens", "fallback-highlighting");
        document.body.classList.remove("cm-render-banners", "cm-collapse-external-links", "cm-render-images-inline");
        document.body.classList.remove("unified-cm-highlighting", "cm-show-copy-button-on-pre", "cm-show-line-nums");
    }
    refreshPanes() {
        this.app.workspace.getLeavesOfType("markdown").forEach(leaf => {
            if (leaf.view instanceof require$$0.MarkdownView) {
                leaf.view.previewMode.rerender(true);
            }
        });
    }
    getActiveCmEditor() {
        var _a;
        const view = this.app.workspace.getActiveViewOfType(require$$0.MarkdownView);
        //@ts-ignore
        if (view)
            return (_a = view.sourceMode) === null || _a === void 0 ? void 0 : _a.cmEditor;
        return null;
    }
    onunload() {
        this.unsetAllCodeMirrorOptions();
        require$$0.MarkdownPreviewRenderer.unregisterPostProcessor(this.mdProcessor);
        this.refreshPanes();
        document.off("contextmenu", `img.hmd-image`, this.onImageContextMenu, false);
        document.off("contextmenu", `.rendered-widget img:not(.hmd-image)`, this.onImageContextMenu, false);
    }
}

module.exports = ObsidianCodeMirrorOptionsPlugin;
